c++: ICE with aligned member and trivial assign op [PR117512]
build_over_call has: t = build2 (MODIFY_EXPR, void_type_node, build2 (MEM_REF, array_type, arg0, alias_set), build2 (MEM_REF, array_type, arg, alias_set)); val = build2 (COMPOUND_EXPR, TREE_TYPE (to), t, to); which creates an expression that can look like: d = MEM <unsigned char[4]> [(struct A *)&TARGET_EXPR <D.2894, foo()] = MEM <unsigned char[4]> [(struct A *)(const struct A &) &e], TARGET_EXPR <D.2894, foo()> that is, a COMPOUND_EXPR where a TARGET_EXPR is used twice, and its address is taken in the left-hand side operand, so it can't be elided. But set_target_expr_eliding simply recurses on the second operand of a COMPOUND_EXPR and marks the TARGET_EXPR as eliding. This then causes a crash. cp_build_indirect_ref_1 should not be changing the value category. While *&TARGET_EXPR is an lvalue, folding it into TARGET_EXPR would render is a prvalue of class type. PR c++/117512 gcc/cp/ChangeLog: * typeck.cc (cp_build_indirect_ref_1): Only do the *&e -> e folding if the result would be an lvalue. gcc/testsuite/ChangeLog: * g++.dg/cpp0x/alignas23.C: New test. * g++.dg/ext/align3.C: New test. * g++.dg/ext/align4.C: New test. * g++.dg/ext/align5.C: New test. Reviewed-by: Jason Merrill <jason@redhat.com>
This commit is contained in:
parent
cfb20f17bd
commit
3dd7b59806
5 changed files with 66 additions and 1 deletions
|
@ -3870,7 +3870,11 @@ cp_build_indirect_ref_1 (location_t loc, tree ptr, ref_operator errorstring,
|
|||
return error_mark_node;
|
||||
}
|
||||
else if (do_fold && TREE_CODE (pointer) == ADDR_EXPR
|
||||
&& same_type_p (t, TREE_TYPE (TREE_OPERAND (pointer, 0))))
|
||||
&& same_type_p (t, TREE_TYPE (TREE_OPERAND (pointer, 0)))
|
||||
/* Don't let this change the value category. '*&TARGET_EXPR'
|
||||
is an lvalue, but folding it into 'TARGET_EXPR' would turn
|
||||
it into a prvalue of class type. */
|
||||
&& lvalue_p (TREE_OPERAND (pointer, 0)))
|
||||
/* The POINTER was something like `&x'. We simplify `*&x' to
|
||||
`x'. */
|
||||
return TREE_OPERAND (pointer, 0);
|
||||
|
|
15
gcc/testsuite/g++.dg/cpp0x/alignas23.C
Normal file
15
gcc/testsuite/g++.dg/cpp0x/alignas23.C
Normal file
|
@ -0,0 +1,15 @@
|
|||
// PR c++/117512
|
||||
// { dg-do compile { target c++11 } }
|
||||
|
||||
struct A {
|
||||
alignas(sizeof (long long)) int b;
|
||||
~A ();
|
||||
};
|
||||
A foo (int);
|
||||
|
||||
void
|
||||
bar ()
|
||||
{
|
||||
A e = { 0 };
|
||||
A d = foo (0) = e;
|
||||
}
|
14
gcc/testsuite/g++.dg/ext/align3.C
Normal file
14
gcc/testsuite/g++.dg/ext/align3.C
Normal file
|
@ -0,0 +1,14 @@
|
|||
// PR c++/117512
|
||||
|
||||
struct A {
|
||||
__attribute__((aligned)) int b;
|
||||
~A ();
|
||||
};
|
||||
A foo (int);
|
||||
|
||||
void
|
||||
bar ()
|
||||
{
|
||||
A e = { 0 };
|
||||
A d = foo (0) = e;
|
||||
}
|
14
gcc/testsuite/g++.dg/ext/align4.C
Normal file
14
gcc/testsuite/g++.dg/ext/align4.C
Normal file
|
@ -0,0 +1,14 @@
|
|||
// PR c++/117512
|
||||
|
||||
struct __attribute__((aligned (2 * sizeof (int)))) A {
|
||||
int b;
|
||||
~A ();
|
||||
};
|
||||
A foo (int);
|
||||
|
||||
void
|
||||
bar ()
|
||||
{
|
||||
A e = { 0 };
|
||||
A d = foo (0) = e;
|
||||
}
|
18
gcc/testsuite/g++.dg/ext/align5.C
Normal file
18
gcc/testsuite/g++.dg/ext/align5.C
Normal file
|
@ -0,0 +1,18 @@
|
|||
// PR c++/117512
|
||||
// { dg-do run }
|
||||
|
||||
struct A {
|
||||
__attribute__((aligned(2 * sizeof (int)))) int i;
|
||||
~A() {}
|
||||
};
|
||||
|
||||
A foo () { A a = { 19 }; return a; }
|
||||
|
||||
int
|
||||
main ()
|
||||
{
|
||||
A a = { 42 };
|
||||
A r = foo () = a;
|
||||
if (r.i != 42)
|
||||
__builtin_abort ();
|
||||
}
|
Loading…
Add table
Reference in a new issue