diff mbox

[C++] PR 70501, ICE in verify ctor sanity

Message ID 5702A3C5.20103@acm.org
State New
Headers show

Commit Message

Nathan Sidwell April 4, 2016, 5:26 p.m. UTC
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=70501

This fixes 70501.  The cause is an omission in typeck when converting a scalar 
operand to a vector.  We use build_vector_from_val, which can return a 
CONSTRUCTOR.  We fail to wrap that CONSTRUCTOR in a TARGET_EXPR.

The ICE arises because at the point we meet that CONSTRUCTOR during the 
constexpr processing, the currently active object under construction is that for 
the result of the <= operator, which has type vector-of-bool, rather than 
vector-of-int. (thus this  problem arises in other vector  ops, but mostly 
undetected because the result type is the same  as the operand type)

ok?

nathan

Comments

Jason Merrill April 5, 2016, 7:40 p.m. UTC | #1
On 04/04/2016 01:26 PM, Nathan Sidwell wrote:
> https://gcc.gnu.org/bugzilla/show_bug.cgi?id=70501
>
> This fixes 70501.  The cause is an omission in typeck when converting a
> scalar operand to a vector.  We use build_vector_from_val, which can
> return a CONSTRUCTOR.  We fail to wrap that CONSTRUCTOR in a TARGET_EXPR.
>
> The ICE arises because at the point we meet that CONSTRUCTOR during the
> constexpr processing, the currently active object under construction is
> that for the result of the <= operator, which has type vector-of-bool,
> rather than vector-of-int. (thus this  problem arises in other vector
> ops, but mostly undetected because the result type is the same  as the
> operand type)

It's not clear to me that we really need a TARGET_EXPR for vector 
values.  Since one element of a vector can't refer to another, we don't 
need the ctx->ctor handling.  Perhaps we should handle vectors like we 
do PMF types in cxx_eval_bare_aggregate?

Jason
Nathan Sidwell April 5, 2016, 9:21 p.m. UTC | #2
On 04/05/16 12:40, Jason Merrill wrote:

> It's not clear to me that we really need a TARGET_EXPR for vector values.  Since
> one element of a vector can't refer to another, we don't need the ctx->ctor
> handling.  Perhaps we should handle vectors like we do PMF types in
> cxx_eval_bare_aggregate?

That may be abstractly better, but we do currently wrap constructors in 
target_exprs for vector compound_literals (which is what I was following).  See 
the get_target_expr_sfinae  calls in finish_compound_literal for instance.  That 
happens for  the '(v4si){(0, 0)}' subexpression of the testcase.

nathan
Jason Merrill April 6, 2016, 2:49 p.m. UTC | #3
On 04/05/2016 05:21 PM, Nathan Sidwell wrote:
> On 04/05/16 12:40, Jason Merrill wrote:
>
>> It's not clear to me that we really need a TARGET_EXPR for vector values.  Since
>> one element of a vector can't refer to another, we don't need the ctx->ctor
>> handling.  Perhaps we should handle vectors like we do PMF types in
>> cxx_eval_bare_aggregate?
>
> That may be abstractly better, but we do currently wrap constructors in
> target_exprs for vector compound_literals (which is what I was
> following).  See the get_target_expr_sfinae  calls in
> finish_compound_literal for instance.  That happens for  the '(v4si){(0,
> 0)}' subexpression of the testcase.

Sure, but that also seems unnecessary; vector rvalues don't have object 
identity the way class and array rvalues do.

Jason
Nathan Sidwell April 6, 2016, 3:06 p.m. UTC | #4
On 04/06/16 07:49, Jason Merrill wrote:
> On 04/05/2016 05:21 PM, Nathan Sidwell wrote:
>> On 04/05/16 12:40, Jason Merrill wrote:
>>
>>> It's not clear to me that we really need a TARGET_EXPR for vector values.  Since
>>> one element of a vector can't refer to another, we don't need the ctx->ctor
>>> handling.  Perhaps we should handle vectors like we do PMF types in
>>> cxx_eval_bare_aggregate?
>>
>> That may be abstractly better, but we do currently wrap constructors in
>> target_exprs for vector compound_literals (which is what I was
>> following).  See the get_target_expr_sfinae  calls in
>> finish_compound_literal for instance.  That happens for  the '(v4si){(0,
>> 0)}' subexpression of the testcase.
>
> Sure, but that also seems unnecessary; vector rvalues don't have object identity
> the way class and array rvalues do.

I'll investigate further.  At least we have a fallback now.

nathan
diff mbox

Patch

2016-04-04  Nathan Sidwell  <nathan@acm.org>

	PR c++/70501
	* typeck.c (cp_build_binary_op): Wrap vector constructors in
	target_exprs.

	* g++.dg/init/pr70501.C: New.

Index: cp/typeck.c
===================================================================
--- cp/typeck.c	(revision 234715)
+++ cp/typeck.c	(working copy)
@@ -4196,6 +4196,8 @@  cp_build_binary_op (location_t location,
               op0 = convert (TREE_TYPE (type1), op0);
 	      op0 = save_expr (op0);
               op0 = build_vector_from_val (type1, op0);
+	      if (TREE_CODE (op0) == CONSTRUCTOR)
+		op0 = get_target_expr (op0);
               type0 = TREE_TYPE (op0);
               code0 = TREE_CODE (type0);
               converted = 1;
@@ -4206,6 +4208,8 @@  cp_build_binary_op (location_t location,
               op1 = convert (TREE_TYPE (type0), op1);
 	      op1 = save_expr (op1);
               op1 = build_vector_from_val (type0, op1);
+	      if (TREE_CODE (op1) == CONSTRUCTOR)
+		op1 = get_target_expr (op1);
               type1 = TREE_TYPE (op1);
               code1 = TREE_CODE (type1);
               converted = 1;
Index: testsuite/g++.dg/init/pr70501.C
===================================================================
--- testsuite/g++.dg/init/pr70501.C	(nonexistent)
+++ testsuite/g++.dg/init/pr70501.C	(working copy)
@@ -0,0 +1,11 @@ 
+/* { dg-options "" } Not pedantic */
+
+typedef int v4si __attribute__ ((vector_size (16)));
+
+struct S { v4si v; };
+
+void
+fn2 (int i, int j)
+{
+  struct S s = { .v = i <= j + (v4si){(1, 2)} };
+}