c++: Implement CWG2635 - Constrained structured bindings

The following patch implements CWG2635.

2022-11-18  Jakub Jelinek  <jakub@redhat.com>

	* decl.cc (grokdeclarator): Implement
	CWG2635 - Constrained structured bindings.  Emit a pedwarn on
	constrained auto type.  Add auto_diagnostic_group for error_at
	and inform for non-auto type on structured bindings declaration.

	* g++.dg/cpp2a/decomp5.C: New test.
	* g++.dg/cpp2a/decomp6.C: New test.
	* g++.dg/cpp2a/decomp7.C: New test.
	* g++.dg/cpp2a/concepts-placeholder7.C: Adjust expected diagnostics.
	* g++.dg/cpp2a/concepts-placeholder8.C: Likewise.
	* g++.dg/cpp2a/concepts-placeholder9.C: New test.
	* g++.dg/cpp2a/concepts-placeholder10.C: New test.
This commit is contained in:
Jakub Jelinek 2022-11-18 09:04:16 +01:00
parent c5df8392c5
commit e5049dfbe2
8 changed files with 118 additions and 7 deletions

View File

@ -12664,6 +12664,7 @@ grokdeclarator (const cp_declarator *declarator,
{
if (type != error_mark_node)
{
auto_diagnostic_group d;
error_at (loc, "structured binding declaration cannot have "
"type %qT", type);
inform (loc,
@ -12673,6 +12674,10 @@ grokdeclarator (const cp_declarator *declarator,
type = build_qualified_type (make_auto (), type_quals);
declspecs->type = type;
}
else if (PLACEHOLDER_TYPE_CONSTRAINTS_INFO (type))
pedwarn (loc, OPT_Wpedantic,
"structured binding declaration cannot have constrained "
"%<auto%> type %qT", type);
inlinep = 0;
typedef_p = 0;
constexpr_p = 0;

View File

@ -0,0 +1,11 @@
// { dg-do compile { target c++20 } }
// { dg-options "-Wno-pedantic" }
template <class T> concept is_const = __is_same(T, const T);
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;
}

View File

@ -7,16 +7,18 @@ 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 constrained 'auto' type 'auto \\\[requires ::C1<<placeholder>, >\\\]'" }
C1 auto [c] = y; // { dg-error "structured binding declaration cannot have constrained 'auto' type 'auto \\\[requires ::C1<<placeholder>, >\\\]'" }
// { dg-error "constraints" "" { target *-*-* } .-1 }
}
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 constrained 'auto' type 'auto \\\[requires ::C1<<placeholder>, >\\\]'" }
C1 auto [c] = y; // { dg-error "structured binding declaration cannot have constrained 'auto' type 'auto \\\[requires ::C1<<placeholder>, >\\\]'" }
// { dg-error "constraints" "" { target *-*-* } .-1 }
}
template void g<int>();
@ -27,6 +29,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 constrained 'auto' type 'const auto \\\[requires ::C2<<placeholder>, >\\\]'" }
}
template void h<int>();

View File

@ -5,6 +5,7 @@ template <class T> concept is_const = __is_same(T, const T);
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 constrained 'auto' type 'const auto \\\[requires ::is_const<<placeholder>, >\\\]'" }
// { dg-error "constraints" "" { target *-*-* } .-1 }
const is_const auto [c] = y; // { dg-error "structured binding declaration cannot have constrained 'auto' type 'const auto \\\[requires ::is_const<<placeholder>, >\\\]'" }
}

View File

@ -0,0 +1,33 @@
// PR c++/99899
// { dg-do compile { target c++20 } }
// { dg-options "-Wno-pedantic" }
template <class T> concept C1 = sizeof(T) > sizeof(int[1]);
template <class>
void f() {
int x[] = {1,2};
int y[] = {3};
C1 auto [a,b] = x;
C1 auto [c] = y; // { dg-error "constraints" }
}
template <class T>
void g() {
T x[] = {1,2};
T y[] = {3};
C1 auto [a,b] = x;
C1 auto [c] = y; // { dg-error "constraints" }
}
template void g<int>();
template <class... Ts> concept C2 = sizeof...(Ts) > 1;
struct S { int a, b; } s;
template <class T>
void h() {
const C2<T> auto& [a, b] = s;
}
template void h<int>();

View File

@ -0,0 +1,19 @@
// 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 constrained 'auto' type 'auto \\\[requires ::C<<placeholder>, >\\\]'" }

View File

@ -0,0 +1,20 @@
// CWG2635 - Constrained structured bindings
// { dg-do compile { target c++20 } }
// { dg-options "-pedantic" }
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-warning "structured binding declaration cannot have constrained 'auto' type 'auto \\\[requires ::C<<placeholder>, >\\\]'" }

View File

@ -0,0 +1,20 @@
// CWG2635 - Constrained structured bindings
// { dg-do compile { target c++20 } }
// { dg-options "-Wno-pedantic" }
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-bogus "structured binding declaration cannot have constrained 'auto' type 'auto \\\[requires ::C<<placeholder>, >\\\]'" }