]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
c++: fix ICE with designated initializer [PR110114]
authorMarek Polacek <polacek@redhat.com>
Wed, 19 Jul 2023 12:47:29 +0000 (08:47 -0400)
committerMarek Polacek <polacek@redhat.com>
Thu, 20 Jul 2023 14:32:48 +0000 (10:32 -0400)
r13-1227 added an assert checking that the index in a CONSTRUCTOR
is a FIELD_DECL.  That's a reasonable assumption but in this case
we never called reshape_init due to the type being incomplete, and
so the index remained an identifier node: get_class_binding never
got around to looking up the FIELD_DECL.

We can avoid the crash by returning early in implicit_conversion_1; we'd
return NULL anyway due to:

  if (i < CONSTRUCTOR_NELTS (ctor))
    return NULL;

in build_aggr_conv.

PR c++/110114

gcc/cp/ChangeLog:

* call.cc (implicit_conversion_1): Return early if the type isn't
complete.

gcc/testsuite/ChangeLog:

* g++.dg/cpp0x/initlist100.C: Adjust expected diagnostic.
* g++.dg/cpp2a/desig28.C: New test.
* g++.dg/cpp2a/desig29.C: New test.

gcc/cp/call.cc
gcc/testsuite/g++.dg/cpp0x/initlist100.C
gcc/testsuite/g++.dg/cpp2a/desig28.C [new file with mode: 0644]
gcc/testsuite/g++.dg/cpp2a/desig29.C [new file with mode: 0644]

index b55230d98aae42eede13eabda647bc8c5ce8629c..673ec91d60e0c14a9138d4b8201986f8df0acc05 100644 (file)
@@ -2059,15 +2059,18 @@ implicit_conversion_1 (tree to, tree from, tree expr, bool c_cast_p,
   complain &= ~tf_error;
 
   /* Call reshape_init early to remove redundant braces.  */
-  if (expr && BRACE_ENCLOSED_INITIALIZER_P (expr)
-      && CLASS_TYPE_P (to)
-      && COMPLETE_TYPE_P (complete_type (to))
-      && !CLASSTYPE_NON_AGGREGATE (to))
+  if (expr && BRACE_ENCLOSED_INITIALIZER_P (expr) && CLASS_TYPE_P (to))
     {
-      expr = reshape_init (to, expr, complain);
-      if (expr == error_mark_node)
-       return NULL;
-      from = TREE_TYPE (expr);
+      to = complete_type (to);
+      if (!COMPLETE_TYPE_P (to))
+       return nullptr;
+      if (!CLASSTYPE_NON_AGGREGATE (to))
+       {
+         expr = reshape_init (to, expr, complain);
+         if (expr == error_mark_node)
+           return nullptr;
+         from = TREE_TYPE (expr);
+       }
     }
 
   if (TYPE_REF_P (to))
index 9d80a004c173f2a1f35d96ffe5d2b94d547e0a3e..6865d34a6f974e85e03469b84f0ad679d4492825 100644 (file)
@@ -2,9 +2,9 @@
 // { dg-do compile { target c++11 } }
 
 namespace std {
-template <class> class initializer_list;  // { dg-message "declaration" }
+template <class> class initializer_list;
 }
 
 template <typename T> struct B { B (std::initializer_list<T>); };
 struct C { virtual int foo (); };
-struct D : C {} d { B<C> { D {} } };  // { dg-error "incomplete|no matching" }
+struct D : C {} d { B<C> { D {} } };  // { dg-error "no matching" }
diff --git a/gcc/testsuite/g++.dg/cpp2a/desig28.C b/gcc/testsuite/g++.dg/cpp2a/desig28.C
new file mode 100644 (file)
index 0000000..b63265f
--- /dev/null
@@ -0,0 +1,17 @@
+// PR c++/110114
+// { dg-do compile { target c++20 } }
+
+struct A {
+    int a,b;
+};
+
+struct B;
+
+void foo(const A &) {}
+void foo(const B &) {}
+
+int
+main ()
+{
+  foo({.a=0});
+}
diff --git a/gcc/testsuite/g++.dg/cpp2a/desig29.C b/gcc/testsuite/g++.dg/cpp2a/desig29.C
new file mode 100644 (file)
index 0000000..bd1a82b
--- /dev/null
@@ -0,0 +1,10 @@
+// PR c++/110114
+// { dg-do compile { target c++20 } }
+
+struct B;
+
+void foo(const B &) {}
+
+int main() {
+    foo({.a=0}); // { dg-error "invalid" }
+}