Hi!

The following testcase shows that declaring std::initializer_list<T>
with bases can lead to ICEs, right now we were just testing that
it is a class template, not a union, and contains one pointer member
and one size_t member.

Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?

2026-06-09  Jakub Jelinek  <[email protected]>

        PR c++/125647
        * class.cc (finish_struct): Reject std::initializer_list template
        with bases.

        * g++.dg/cpp0x/initlist134.C: New test.

--- gcc/cp/class.cc.jj  2026-06-02 08:15:04.582141780 +0200
+++ gcc/cp/class.cc     2026-06-09 12:09:17.352024884 +0200
@@ -8370,6 +8370,8 @@ finish_struct (tree t, tree attributes)
        }
       /* It also cannot be a union.  */
       ok &= NON_UNION_CLASS_TYPE_P (t);
+      if (BINFO_N_BASE_BINFOS (TYPE_BINFO (t)))
+       ok = false;
       if (!ok)
        fatal_error (input_location, "definition of %qD does not match "
                     "%<#include <initializer_list>%>", TYPE_NAME (t));
--- gcc/testsuite/g++.dg/cpp0x/initlist134.C.jj 2026-06-09 12:14:39.307861068 
+0200
+++ gcc/testsuite/g++.dg/cpp0x/initlist134.C    2026-06-09 12:19:58.905734199 
+0200
@@ -0,0 +1,18 @@
+// PR c++/125647
+// { dg-do compile { target c++11 } }
+
+struct A { int a; };
+namespace std {
+  template <class T>
+  class initializer_list : A { T *d; decltype (sizeof 0) s; }; // { dg-error 
"definition of 'class std::initializer_list<T>' does not match '#include 
<initializer_list>'" }
+}
+
+void foo (std::initializer_list <int>);
+
+void
+bar ()
+{
+  foo ({ 1, 2, 3 });
+}
+
+// { dg-prune-output "compilation terminated" }

        Jakub

Reply via email to