diff options
author | Jason Merrill <jason@redhat.com> | 2024-08-05 15:04:05 -0400 |
---|---|---|
committer | Jason Merrill <jason@redhat.com> | 2024-08-06 13:04:13 -0400 |
commit | 352c21c8a22a48d34cbd2fbfe398ee12c0a1d681 (patch) | |
tree | 71b24db8d9d49c3dd683a3d2b538901ef024bd84 | |
parent | 2f759fa9f4dd78ae8d86482ccda72a335aaac404 (diff) | |
download | gcc-352c21c8a22a48d34cbd2fbfe398ee12c0a1d681.zip gcc-352c21c8a22a48d34cbd2fbfe398ee12c0a1d681.tar.gz gcc-352c21c8a22a48d34cbd2fbfe398ee12c0a1d681.tar.bz2 |
c++: zero-init and class nttp [PR94568]
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.
-rw-r--r-- | gcc/cp/init.cc | 3 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp1z/nontype-auto26.C | 29 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp2a/nontype-class36.C | 2 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp2a/nontype-class37.C | 2 |
4 files changed, 34 insertions, 2 deletions
diff --git a/gcc/cp/init.cc b/gcc/cp/init.cc index de82152..20373d2 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 0000000..9abe54e --- /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 8371eb9..2e6d76c 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 f5e9826..dc054a9 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" } |