[gcc r17-3019] c++: Reject std::initializer_list with bases [PR125647]

Jakub Jelinek via Gcc-cvs <[email protected]> Thu, 6 Aug 2026 09:35:37 +0000 (GMT)
Newsgroups gmane.comp.gcc.cvs
Message-ID <[email protected]>
https://gcc.gnu.org/g:d2b8724451f52a656d10f7d34f6a4e3d7602ed28

commit r17-3019-gd2b8724451f52a656d10f7d34f6a4e3d7602ed28
Author: Jakub Jelinek <[email protected]>
Date:   Thu Aug 6 11:30:20 2026 +0200

    c++: Reject std::initializer_list with bases [PR125647]
    
    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.
    
    2026-08-06  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.
    
    Reviewed-by: Jason Merrill <[email protected]>

Diff:
---
 gcc/cp/class.cc                          |  2 ++
 gcc/testsuite/g++.dg/cpp0x/initlist134.C | 18 ++++++++++++++++++
 2 files changed, 20 insertions(+)

diff --git a/gcc/cp/class.cc b/gcc/cp/class.cc
index 2fcaa6cd81bd..fac5815390f0 100644
--- a/gcc/cp/class.cc
+++ b/gcc/cp/class.cc
@@ -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));
diff --git a/gcc/testsuite/g++.dg/cpp0x/initlist134.C b/gcc/testsuite/g++.dg/cpp0x/initlist134.C
new file mode 100644
index 000000000000..955617799c60
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/initlist134.C
@@ -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" }