https://gcc.gnu.org/bugzilla/show_bug.cgi?id=117512
--- Comment #9 from GCC Commits <cvs-commit at gcc dot gnu.org> --- The releases/gcc-14 branch has been updated by Marek Polacek <mpola...@gcc.gnu.org>: https://gcc.gnu.org/g:a27b24c9f4ee7fc12d077ea111200223e4a95c7d commit r14-11406-ga27b24c9f4ee7fc12d077ea111200223e4a95c7d Author: Marek Polacek <pola...@redhat.com> Date: Wed Mar 12 14:49:53 2025 -0400 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 <ja...@redhat.com> (cherry picked from commit 3dd7b598065ea0280fc65ce656c575c5142fa4fc)