diff options
author | Marek Polacek <polacek@redhat.com> | 2025-03-12 14:49:53 -0400 |
---|---|---|
committer | Marek Polacek <polacek@redhat.com> | 2025-03-12 17:31:55 -0400 |
commit | 3dd7b598065ea0280fc65ce656c575c5142fa4fc (patch) | |
tree | d9ca86d09334d0aa4cf6bd1c4189c30055617407 /gcc/testsuite/g++.dg/cpp0x | |
parent | cfb20f17bd17e1cd98ccd8a4517ff3e925cf731c (diff) | |
download | gcc-3dd7b598065ea0280fc65ce656c575c5142fa4fc.zip gcc-3dd7b598065ea0280fc65ce656c575c5142fa4fc.tar.gz gcc-3dd7b598065ea0280fc65ce656c575c5142fa4fc.tar.bz2 |
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>
Diffstat (limited to 'gcc/testsuite/g++.dg/cpp0x')
-rw-r--r-- | gcc/testsuite/g++.dg/cpp0x/alignas23.C | 15 |
1 files changed, 15 insertions, 0 deletions
diff --git a/gcc/testsuite/g++.dg/cpp0x/alignas23.C b/gcc/testsuite/g++.dg/cpp0x/alignas23.C new file mode 100644 index 0000000..3c218a3 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/alignas23.C @@ -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; +} |