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)

Reply via email to