https://gcc.gnu.org/bugzilla/show_bug.cgi?id=116424

--- Comment #16 from GCC Commits <cvs-commit at gcc dot gnu.org> ---
The releases/gcc-13 branch has been updated by Marek Polacek
<mpola...@gcc.gnu.org>:

https://gcc.gnu.org/g:5eca4dc76ded61a959447bd11d1edf6d4030a51d

commit r13-9251-g5eca4dc76ded61a959447bd11d1edf6d4030a51d
Author: Marek Polacek <pola...@redhat.com>
Date:   Tue Aug 27 18:25:17 2024 -0400

    c++: ICE with ()-init and TARGET_EXPR eliding [PR116424]

    Here we crash on a cp_gimplify_expr/TARGET_EXPR assert:

          gcc_checking_assert (!TARGET_EXPR_ELIDING_P (*expr_p)
                               || !TREE_ADDRESSABLE (TREE_TYPE (*expr_p)));

    We cannot elide the TARGET_EXPR because we're taking its address.

    It is set as eliding in massage_init_elt.  I've tried to not set
    TARGET_EXPR_ELIDING_P when the context is not direct-initialization.
    That didn't work: even when it's not direct-initialization now, it
    can become one later, for instance, after split_nonconstant_init.
    One problem is that replace_placeholders_for_class_temp_r will replace
    placeholders in non-eliding TARGET_EXPRs with the slot, but if we then
    elide the TARGET_EXPR, we end up with a "stray" VAR_DECL and crash.
    (Only some TARGET_EXPRs are handled by replace_decl.)

    I thought I'd have to go back to
    <https://gcc.gnu.org/pipermail/gcc-patches/2024-May/651163.html> but
    then I realized that this problem occurrs only with ()-init but not
    {}-init.  With {}-init, there is no problem, because we are clearing
    TARGET_EXPR_ELIDING_P in process_init_constructor_record:

           /* We can't actually elide the temporary when initializing a
              potentially-overlapping field from a function that returns by
              value.  */
           if (ce->index
               && TREE_CODE (next) == TARGET_EXPR
               && unsafe_copy_elision_p (ce->index, next))
             TARGET_EXPR_ELIDING_P (next) = false;

    But that does not happen for ()-init because we have no ce->index.
    ()-init doesn't allow brace elision so we don't really reshape them.

    But I can just move the clearing a few lines down and then it handles
    both ()-init and {}-init.

            PR c++/116424

    gcc/cp/ChangeLog:

            * typeck2.cc (process_init_constructor_record): Move the clearing
of
            TARGET_EXPR_ELIDING_P down.

    gcc/testsuite/ChangeLog:

            * g++.dg/cpp2a/paren-init38.C: New test.

    (cherry picked from commit 15f857af2943a4aa282d04ff71f860352ad3291b)
  • [Bug c++/116424] [13 Regression... cvs-commit at gcc dot gnu.org via Gcc-bugs

Reply via email to