On Sat, Nov 12, 2022 at 12:23:56PM +0100, Jakub Jelinek wrote: > The following patch implements CWG2635. > > So far tested on > GXX_TESTSUITE_STDS=98,11,14,17,20,2b make check-g++ > RUNTESTFLAGS="dg.exp=decomp*" > ok for trunk if it passes full bootstrap/regtest and it is voted in?
Here is another version of the patch that passed bootstrap/regtest, the only change are tweaks to 2 further testcases. 2022-11-13 Jakub Jelinek <ja...@redhat.com> * decl.cc (grokdeclarator): Implement CWG2635 - Constrained structured bindings. Diagnose constrained auto type. * g++.dg/cpp2a/decomp5.C: New test. * g++.dg/cpp2a/concepts-placeholder7.C: Adjust expected diagnostics. * g++.dg/cpp2a/concepts-placeholder8.C: Likewise. --- gcc/cp/decl.cc.jj 2022-11-11 17:14:33.103869977 +0100 +++ gcc/cp/decl.cc 2022-11-12 12:13:52.217239729 +0100 @@ -12660,7 +12660,8 @@ grokdeclarator (const cp_declarator *dec gcc_unreachable (); } if (TREE_CODE (type) != TEMPLATE_TYPE_PARM - || TYPE_IDENTIFIER (type) != auto_identifier) + || TYPE_IDENTIFIER (type) != auto_identifier + || PLACEHOLDER_TYPE_CONSTRAINTS_INFO (type)) { if (type != error_mark_node) { --- gcc/testsuite/g++.dg/cpp2a/decomp5.C.jj 2022-11-12 12:17:21.024392082 +0100 +++ gcc/testsuite/g++.dg/cpp2a/decomp5.C 2022-11-12 12:20:00.700214521 +0100 @@ -0,0 +1,20 @@ +// CWG2635 - Constrained structured bindings +// { dg-do compile { target c++20 } } + +namespace std { + template<typename T> struct tuple_size; + template<int, typename> struct tuple_element; +} + +struct A { + int i; + A(int x) : i(x) {} + template <int I> int& get() { return i; } +}; + +template<> struct std::tuple_size<A> { static const int value = 2; }; +template<int I> struct std::tuple_element<I,A> { using type = int; }; + +template<class T> concept C = true; +C auto [x, y] = A{1}; // { dg-error "structured binding declaration cannot have type 'auto \\\[requires ::C<<placeholder>, >\\\]'" } + // { dg-message "type must be cv-qualified 'auto' or reference to cv-qualified 'auto'" "" { target *-*-* } .-1 } --- gcc/testsuite/g++.dg/cpp2a/concepts-placeholder7.C.jj 2021-04-06 23:49:08.288882716 +0200 +++ gcc/testsuite/g++.dg/cpp2a/concepts-placeholder7.C 2022-11-13 12:17:38.570047510 +0100 @@ -7,16 +7,16 @@ template <class> void f() { int x[] = {1,2}; int y[] = {3}; - C1 auto [a,b] = x; - C1 auto [c] = y; // { dg-error "constraints" } + C1 auto [a,b] = x; // { dg-error "structured binding declaration cannot have type 'auto \\\[requires ::C1<<placeholder>, >\\\]'" } + C1 auto [c] = y; // { dg-error "structured binding declaration cannot have type 'auto \\\[requires ::C1<<placeholder>, >\\\]'" } } template <class T> void g() { T x[] = {1,2}; T y[] = {3}; - C1 auto [a,b] = x; - C1 auto [c] = y; // { dg-error "constraints" } + C1 auto [a,b] = x; // { dg-error "structured binding declaration cannot have type 'auto \\\[requires ::C1<<placeholder>, >\\\]'" } + C1 auto [c] = y; // { dg-error "structured binding declaration cannot have type 'auto \\\[requires ::C1<<placeholder>, >\\\]'" } } template void g<int>(); @@ -27,6 +27,6 @@ struct S { int a, b; } s; template <class T> void h() { - const C2<T> auto& [a, b] = s; + const C2<T> auto& [a, b] = s; // { dg-error "structured binding declaration cannot have type 'const auto \\\[requires ::C2<<placeholder>, >\\\]'" } } template void h<int>(); --- gcc/testsuite/g++.dg/cpp2a/concepts-placeholder8.C.jj 2021-04-06 23:49:08.288882716 +0200 +++ gcc/testsuite/g++.dg/cpp2a/concepts-placeholder8.C 2022-11-13 12:19:17.034684881 +0100 @@ -5,6 +5,6 @@ template <class T> concept is_const = __ void f() { int x[] = {1,2}; const int y[] = {3}; - const is_const auto [a,b] = x; // { dg-error "constraints" } - const is_const auto [c] = y; + const is_const auto [a,b] = x; // { dg-error "structured binding declaration cannot have type 'const auto \\\[requires ::is_const<<placeholder>, >\\\]'" } + const is_const auto [c] = y; // { dg-error "structured binding declaration cannot have type 'const auto \\\[requires ::is_const<<placeholder>, >\\\]'" } } Jakub