From: Marek Polacek Date: Wed, 12 Feb 2025 18:33:37 +0000 (-0500) Subject: c++: P2308, Template parameter initialization (tests) [PR113800] X-Git-Tag: basepoints/gcc-16~2046 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=84f19ecb01958fa791b9213dbd80331474fca9f0;p=thirdparty%2Fgcc.git c++: P2308, Template parameter initialization (tests) [PR113800] This proposal was implemented a long time ago by my r9-5271, but it took me this long to verify that it still works as per P2308. This patch adds assorted tests, both from clang and from [temp.arg.nontype]. Fortunately I did not discover any issues in the compiler. PR c++/113800 DR 2450 gcc/testsuite/ChangeLog: * g++.dg/cpp26/pack-indexing15.C: New test. * g++.dg/cpp2a/nontype-class68.C: New test. * g++.dg/cpp2a/nontype-class69.C: New test. * g++.dg/cpp2a/nontype-class70.C: New test. * g++.dg/cpp2a/nontype-class71.C: New test. * g++.dg/cpp2a/nontype-class72.C: New test. Reviewed-by: Jason Merrill --- diff --git a/gcc/testsuite/g++.dg/cpp26/pack-indexing15.C b/gcc/testsuite/g++.dg/cpp26/pack-indexing15.C new file mode 100644 index 00000000000..3f8382b12cd --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp26/pack-indexing15.C @@ -0,0 +1,20 @@ +// PR c++/113800 +// { dg-do compile { target c++26 } } +// From LLVM's temp_arg_nontype_cxx2c.cpp. + +template +concept C = sizeof(T...[1]) == 1; + +struct A {}; + +template auto = A{}> struct Set {}; + +template +void +foo () +{ + Set u; +} + +Set sb; +Set sf; // { dg-error "placeholder constraints not satisfied" } diff --git a/gcc/testsuite/g++.dg/cpp2a/nontype-class68.C b/gcc/testsuite/g++.dg/cpp2a/nontype-class68.C new file mode 100644 index 00000000000..ade646e391b --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp2a/nontype-class68.C @@ -0,0 +1,24 @@ +// PR c++/113800 +// { dg-do compile { target c++20 } } +// From [temp.arg.nontype]. + +template struct B { /* ... */ }; +B<5> b1; // OK, template parameter type is int +B<'a'> b2; // OK, template parameter type is char +B<2.5> b3; // OK, template parameter type is double +B b4; // { dg-error ".void. is not a valid type for a template non-type parameter" } + +template struct C { /* ... */ }; +C<{ 42 }> c1; // OK + +struct J1 { + J1 *self = this; +}; +B j1; // { dg-error "not a constant expression" } + +struct J2 { + J2 *self = this; + constexpr J2() {} + constexpr J2(const J2&) {} +}; +B j2; // { dg-error "not a constant expression" } diff --git a/gcc/testsuite/g++.dg/cpp2a/nontype-class69.C b/gcc/testsuite/g++.dg/cpp2a/nontype-class69.C new file mode 100644 index 00000000000..08b0a5ef73c --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp2a/nontype-class69.C @@ -0,0 +1,27 @@ +// PR c++/113800 +// { dg-do compile { target c++20 } } + +// DR 2450 +struct S { int a; }; + +template +void +f () +{ +} + +void +test () +{ + f<{0}>(); + f<{.a= 0}>(); +} + +// DR 2459 +struct A { + constexpr A (float) {} +}; + +template +struct X {}; +X<1> x; diff --git a/gcc/testsuite/g++.dg/cpp2a/nontype-class70.C b/gcc/testsuite/g++.dg/cpp2a/nontype-class70.C new file mode 100644 index 00000000000..0e50847e440 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp2a/nontype-class70.C @@ -0,0 +1,47 @@ +// PR c++/113800 +// P2308R1 - Template parameter initialization +// { dg-do compile { target c++20 } } + +struct S { + int a = 0; + int b = 42; +}; + +template +struct A { + static constexpr auto a = t.a; + static constexpr auto b = t.b; +}; + +static_assert(A<{}>::a == 0); +static_assert(A<{}>::b == 42); +static_assert(A<{.a = 3}>::a == 3); +static_assert(A<{.b = 4}>::b == 4); + +template +struct D1 {}; + +template +struct D2 {}; + +template +struct D3 {}; + +struct E {}; + +struct I { + constexpr I(E) {}; +}; + +template +struct W {}; + +void +g () +{ + D1<> d1; + D2<> d2; + D3<> d3; + + W w; +} diff --git a/gcc/testsuite/g++.dg/cpp2a/nontype-class71.C b/gcc/testsuite/g++.dg/cpp2a/nontype-class71.C new file mode 100644 index 00000000000..36ce5b16dee --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp2a/nontype-class71.C @@ -0,0 +1,19 @@ +// PR c++/113800 +// { dg-do compile { target c++20 } } +// From LLVM's temp_arg_nontype_cxx2c.cpp. + +template +struct A { + T x[I]; +}; + +template +A(T, U...) -> A; + +template void foo() { } + +void +bar () +{ + foo<{1}>(); +} diff --git a/gcc/testsuite/g++.dg/cpp2a/nontype-class72.C b/gcc/testsuite/g++.dg/cpp2a/nontype-class72.C new file mode 100644 index 00000000000..1c48ff57add --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp2a/nontype-class72.C @@ -0,0 +1,41 @@ +// PR c++/113800 +// P2308R1 - Template parameter initialization +// { dg-do compile { target c++20 } } +// Invalid cases. + +namespace std { +template class initializer_list { + const T *_M_array; + decltype (sizeof 0) _M_len; +}; +} + +template +struct X {}; + +struct A { + int i; +}; + +template +struct B { }; + +struct E {}; + +struct I { // { dg-message "not literal" } + I(E) {}; +}; + +template +struct W {}; + +void +g () +{ + X<{0}> x; // { dg-error "unable to deduce" } + + int i = 42; // { dg-message "not const" } + B<{i}> b; // { dg-error "not usable" } + + W w; // { dg-error "not a valid type for a template non-type parameter" } +}