diff mbox series

[pushed] c++: zero-init and class nttp [PR94568]

Message ID 20240806170403.1194160-1-jason@redhat.com
State New
Headers show
Series [pushed] c++: zero-init and class nttp [PR94568] | expand

Commit Message

Jason Merrill Aug. 6, 2024, 5:03 p.m. UTC
Tested x86_64-pc-linux-gnu, applying to trunk.

-- 8< --

A zero-initializer should not reflect the constness of what it's
initializing, as it does not for initializers with different syntax.

This does have mangling implications for rare C++20 code, but it seems
infeasable to make the mangling depend on -fabi-version while fixing the
semantic bug, and C++20 is still experimental anyway.

	PR c++/94568

gcc/cp/ChangeLog:

	* init.cc (build_zero_init_1): Call cv_unqualified.

gcc/testsuite/ChangeLog:

	* g++.dg/cpp2a/nontype-class36.C: Remove xfail.
	* g++.dg/cpp2a/nontype-class37.C: Remove xfail.
	* g++.dg/cpp1z/nontype-auto26.C: New test.
---
 gcc/cp/init.cc                               |  3 ++
 gcc/testsuite/g++.dg/cpp1z/nontype-auto26.C  | 29 ++++++++++++++++++++
 gcc/testsuite/g++.dg/cpp2a/nontype-class36.C |  2 +-
 gcc/testsuite/g++.dg/cpp2a/nontype-class37.C |  2 +-
 4 files changed, 34 insertions(+), 2 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/cpp1z/nontype-auto26.C


base-commit: 69093fd8aa682a1b906e80b3c5f10956e692b7c4
diff mbox series

Patch

diff --git a/gcc/cp/init.cc b/gcc/cp/init.cc
index de82152bd1d..20373d26988 100644
--- a/gcc/cp/init.cc
+++ b/gcc/cp/init.cc
@@ -173,6 +173,9 @@  build_zero_init_1 (tree type, tree nelts, bool static_storage_p,
 
   gcc_assert (nelts == NULL_TREE || TREE_CODE (nelts) == INTEGER_CST);
 
+  /* An initializer is unqualified.  */
+  type = cv_unqualified (type);
+
   if (type == error_mark_node)
     ;
   else if (static_storage_p && zero_init_p (type))
diff --git a/gcc/testsuite/g++.dg/cpp1z/nontype-auto26.C b/gcc/testsuite/g++.dg/cpp1z/nontype-auto26.C
new file mode 100644
index 00000000000..9abe54ed974
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp1z/nontype-auto26.C
@@ -0,0 +1,29 @@ 
+// PR c++/94568
+// { dg-do compile { target c++20 } }
+
+struct A;
+typedef int A::*MemPtr;
+
+struct B { MemPtr p; };
+
+static constexpr MemPtr mp { };
+
+template <B> struct X { };
+
+typedef X<B{{MemPtr{ }}}> XB;
+typedef X<B{{mp}}>        XB;
+
+struct C { int a[2]; };
+template <C> struct D { };
+
+constexpr const int i0 = 0;
+constexpr const int i_{ };
+
+static_assert (i0 == i_);
+
+// typedef D<C{ { 0, 1 } }>   DC01;
+// typedef D<C{ { i0, 1 } }>  DC01;
+typedef D<C{ { i_, 1 } }>  DC01;
+
+// { dg-final { scan-assembler "_Z1f1DIXtl1CtlA2_iLi0ELi1EEEEE" } }
+void f(DC01) {}
diff --git a/gcc/testsuite/g++.dg/cpp2a/nontype-class36.C b/gcc/testsuite/g++.dg/cpp2a/nontype-class36.C
index 8371eb96621..2e6d76cd43a 100644
--- a/gcc/testsuite/g++.dg/cpp2a/nontype-class36.C
+++ b/gcc/testsuite/g++.dg/cpp2a/nontype-class36.C
@@ -59,7 +59,7 @@  typedef X<B{ nullptr, nullptr, mpi }>         XB00p;
 typedef X<B{ MemPtr{ }, MemPtr{ }, mpi }>     XB00p;
 typedef X<B{ mp0, MemPtr{ }, mpi }>           XB00p;
 typedef X<B{ mpn, mpn, mpi }>                 XB00p;
-typedef X<B{ mpn, mp_, mpi }>                 XB00p;  // { dg-bogus "conflicting declaration" "pr94568" { xfail *-*-* } }
+typedef X<B{ mpn, mp_, mpi }>                 XB00p;  // { dg-bogus "conflicting declaration" "pr94568" }
 
 static const constexpr MemFuncPtr mfp0 = { 0 };
 static const constexpr MemFuncPtr mfpn = { nullptr };
diff --git a/gcc/testsuite/g++.dg/cpp2a/nontype-class37.C b/gcc/testsuite/g++.dg/cpp2a/nontype-class37.C
index f5e9826d243..dc054a9939a 100644
--- a/gcc/testsuite/g++.dg/cpp2a/nontype-class37.C
+++ b/gcc/testsuite/g++.dg/cpp2a/nontype-class37.C
@@ -77,4 +77,4 @@  typedef D<C{ { 0, 1 } }>            DC01;
 typedef D<C{ { 0, 1, 0 } }>         DC01;
 typedef D<C{ { 0, 1, 0, 0 } }>      DC01;
 typedef D<C{ { 0, i1, 0, 0 } }>     DC01;
-typedef D<C{ { i0, i1, i0, i0 } }>  DC01;   // { dg-bogus "conflicting declaration" "pr94567" { xfail *-*-* } }
+typedef D<C{ { i0, i1, i0, i0 } }>  DC01;   // { dg-bogus "conflicting declaration" "pr94568" }