diff options
author | Patrick Palka <ppalka@redhat.com> | 2021-04-12 22:54:55 -0400 |
---|---|---|
committer | Patrick Palka <ppalka@redhat.com> | 2021-04-12 22:54:55 -0400 |
commit | 59d9aa6d2efe7c52b6a986eb3e1977c1fb3c5753 (patch) | |
tree | 1d4c31e21078391baa8efb51ede1013c6034918c /gcc | |
parent | 07b27384de56ce2f6a93007d018743ef9d5c8cc4 (diff) | |
download | gcc-59d9aa6d2efe7c52b6a986eb3e1977c1fb3c5753.zip gcc-59d9aa6d2efe7c52b6a986eb3e1977c1fb3c5753.tar.gz gcc-59d9aa6d2efe7c52b6a986eb3e1977c1fb3c5753.tar.bz2 |
c++: constraints are unevaluated operands [PR99961]
According to [temp.concept]/6 and [temp.pre]/9, a concept definition and
a requires clause are both unevaluated contexts, and hence satisfaction
deals only with unevaluated operands, so we should set cp_unevaluated in
these three situations.
gcc/cp/ChangeLog:
PR c++/99961
PR c++/99994
* constraint.cc (satisfy_normalized_constraints): Set
cp_unevaluated.
* parser.c (cp_parser_concept_definition): Likewise.
(cp_parser_requires_clause_opt): Likewise.
gcc/testsuite/ChangeLog:
PR c++/99961
PR c++/99994
* g++.dg/cpp2a/concepts-uneval1.C: New test.
* g++.dg/cpp2a/concepts-uneval2.C: New test.
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/cp/constraint.cc | 3 | ||||
-rw-r--r-- | gcc/cp/parser.c | 6 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp2a/concepts-uneval1.C | 10 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp2a/concepts-uneval2.C | 8 |
4 files changed, 27 insertions, 0 deletions
diff --git a/gcc/cp/constraint.cc b/gcc/cp/constraint.cc index 0ddb299..0709695 100644 --- a/gcc/cp/constraint.cc +++ b/gcc/cp/constraint.cc @@ -3066,6 +3066,9 @@ satisfy_normalized_constraints (tree t, tree args, sat_info info) /* We need to check access during satisfaction. */ deferring_access_check_sentinel acs (dk_no_deferred); + /* Constraints are unevaluated operands. */ + cp_unevaluated u; + return satisfy_constraint_r (t, args, info); } diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index b6f94bd..8b7801b 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -28353,6 +28353,9 @@ cp_parser_label_declaration (cp_parser* parser) static tree cp_parser_concept_definition (cp_parser *parser) { + /* A concept definition is an unevaluated context. */ + cp_unevaluated u; + gcc_assert (cp_lexer_next_token_is_keyword (parser->lexer, RID_CONCEPT)); cp_lexer_consume_token (parser->lexer); @@ -28714,6 +28717,9 @@ cp_parser_constraint_expression (cp_parser *parser) static tree cp_parser_requires_clause_opt (cp_parser *parser, bool lambda_p) { + /* A requires clause is an unevaluated context. */ + cp_unevaluated u; + cp_token *tok = cp_lexer_peek_token (parser->lexer); if (tok->keyword != RID_REQUIRES) { diff --git a/gcc/testsuite/g++.dg/cpp2a/concepts-uneval1.C b/gcc/testsuite/g++.dg/cpp2a/concepts-uneval1.C new file mode 100644 index 0000000..4c5f1b5 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp2a/concepts-uneval1.C @@ -0,0 +1,10 @@ +// PR c++/99961 +// { dg-do compile { target c++20 } } + +struct A { static const int x = 42; bool y; }; + +void f(auto a) requires (a.x == 42) { } +template void f(A); + +template <bool V> concept C = V || A::y; +static_assert(C<true>); diff --git a/gcc/testsuite/g++.dg/cpp2a/concepts-uneval2.C b/gcc/testsuite/g++.dg/cpp2a/concepts-uneval2.C new file mode 100644 index 0000000..4793bd6 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp2a/concepts-uneval2.C @@ -0,0 +1,8 @@ +// PR c++/99994 +// { dg-do compile { target c++20 } } + +int main() { + auto f = [](int) { return true; }; + int n = [&](auto i) requires (f(sizeof(i))) { return 99; }(12); + int m = [](auto i) requires (f(sizeof(i))) { return 99; }(12); +} |