Message ID | 5702A3C5.20103@acm.org |
---|---|
State | New |
Headers | show |
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
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
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
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
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)} }; +}