https://gcc.gnu.org/g:1a05332bbac98a4c002bef3fb45a3ad9d56b3a71

commit r15-523-g1a05332bbac98a4c002bef3fb45a3ad9d56b3a71
Author: Marek Polacek <pola...@redhat.com>
Date:   Wed May 8 15:43:58 2024 -0400

    c++: ICE with reference NSDMI [PR114854]
    
    Here we crash on a cp_gimplify_expr/TARGET_EXPR assert:
    
          /* A TARGET_EXPR that expresses direct-initialization should have been
             elided by cp_gimplify_init_expr.  */
          gcc_checking_assert (!TARGET_EXPR_DIRECT_INIT_P (*expr_p));
    
    the TARGET_EXPR in question is created for the NSDMI in:
    
      class Vector { int m_size; };
      struct S {
        const Vector &vec{};
      };
    
    where we first need to create a Vector{} temporary, and then bind the
    vec reference to it.  The temporary is represented by a TARGET_EXPR
    and it cannot be elided.  When we create an object of type S, we get
    
      D.2848 = {.vec=(const struct Vector &) &TARGET_EXPR <D.2840, {.m_size=0}>}
    
    where the TARGET_EXPR is no longer direct-initializing anything.
    
    Fixed by not setting TARGET_EXPR_DIRECT_INIT_P in 
convert_like_internal/ck_user.
    
            PR c++/114854
    
    gcc/cp/ChangeLog:
    
            * call.cc (convert_like_internal) <case ck_user>: Don't set
            TARGET_EXPR_DIRECT_INIT_P.
    
    gcc/testsuite/ChangeLog:
    
            * g++.dg/cpp1y/nsdmi-aggr22.C: New test.

Diff:
---
 gcc/cp/call.cc                            |  6 +-----
 gcc/testsuite/g++.dg/cpp1y/nsdmi-aggr22.C | 12 ++++++++++++
 2 files changed, 13 insertions(+), 5 deletions(-)

diff --git a/gcc/cp/call.cc b/gcc/cp/call.cc
index e058da7735fa..ed68eb3c5684 100644
--- a/gcc/cp/call.cc
+++ b/gcc/cp/call.cc
@@ -8597,16 +8597,12 @@ convert_like_internal (conversion *convs, tree expr, 
tree fn, int argnum,
            && TYPE_HAS_DEFAULT_CONSTRUCTOR (totype)
            && !processing_template_decl)
          {
-           bool direct = CONSTRUCTOR_IS_DIRECT_INIT (expr);
            if (abstract_virtuals_error (NULL_TREE, totype, complain))
              return error_mark_node;
            expr = build_value_init (totype, complain);
            expr = get_target_expr (expr, complain);
            if (expr != error_mark_node)
-             {
-               TARGET_EXPR_LIST_INIT_P (expr) = true;
-               TARGET_EXPR_DIRECT_INIT_P (expr) = direct;
-             }
+             TARGET_EXPR_LIST_INIT_P (expr) = true;
            return expr;
          }
 
diff --git a/gcc/testsuite/g++.dg/cpp1y/nsdmi-aggr22.C 
b/gcc/testsuite/g++.dg/cpp1y/nsdmi-aggr22.C
new file mode 100644
index 000000000000..a4f9ae19ca9d
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp1y/nsdmi-aggr22.C
@@ -0,0 +1,12 @@
+// PR c++/114854
+// { dg-do compile { target c++14 } }
+
+struct Vector {
+  int m_size;
+};
+struct S {
+  const Vector &vec{};
+};
+
+void spawn(S);
+void test() { spawn({}); }

Reply via email to