diff options
author | Patrick Palka <ppalka@redhat.com> | 2020-03-28 08:56:59 -0400 |
---|---|---|
committer | Patrick Palka <ppalka@redhat.com> | 2020-03-28 08:56:59 -0400 |
commit | a7ea3d2ced786c4544fa625f34f515d89ed074fe (patch) | |
tree | 5d72578ca8e5a5be0fbb57cbd820e4bb2f1a175b /gcc/testsuite/g++.dg/concepts | |
parent | cd68edf894d6b72e5bc37ac205deef9d237ab70b (diff) | |
download | gcc-a7ea3d2ced786c4544fa625f34f515d89ed074fe.zip gcc-a7ea3d2ced786c4544fa625f34f515d89ed074fe.tar.gz gcc-a7ea3d2ced786c4544fa625f34f515d89ed074fe.tar.bz2 |
c++: requires-expression outside of a template is misevaluated [PR94252]
This PR shows that a REQUIRES_EXPR outside of a template can sometimes be
misevaluated. This happens because the evaluation routine tsubst_requires_expr
(and diagnose_requires_expr) assumes the REQUIRES_EXPR's subtrees are templated
trees and that therefore it's safe to call tsubst_expr on them. But this
assumption isn't valid when we've parsed a REQUIRES_EXPR outside of a template
context. In order to make this assumption valid here, this patch sets
processing_template_decl to non-zero before parsing the body of a REQUIRES_EXPR
so that its subtrees are indeed always templated trees.
gcc/cp/ChangeLog:
PR c++/94252
* constraint.cc (tsubst_compound_requirement): Always suppress errors
from type_deducible_p and expression_convertible_p, as they're not
substitution errors.
(diagnose_atomic_constraint) <case INTEGER_CST>: Remove this case so
that we diagnose INTEGER_CST expressions of non-bool type via the
default case.
* cp-gimplify.c (cp_genericize_r) <case REQUIRES_EXPR>: New case.
* parser.c (cp_parser_requires_expression): Always parse the requirement
body as if we're processing a template, by temporarily incrementing
processing_template_decl. Afterwards, if we're not actually in a
template context, perform semantic processing to diagnose any invalid
types and expressions.
* pt.c (tsubst_copy_and_build) <case REQUIRES_EXPR>: Remove dead code.
* semantics.c (finish_static_assert): Explain an assertion failure
when the condition is a REQUIRES_EXPR like we do when it is a concept
check.
gcc/testsuite/ChangeLog:
PR c++/94252
* g++.dg/concepts/diagnostic7.C: New test.
* g++.dg/concepts/pr94252.C: New test.
* g++.dg/cpp2a/concepts-requires18.C: Adjust to expect an additional
diagnostic.
Diffstat (limited to 'gcc/testsuite/g++.dg/concepts')
-rw-r--r-- | gcc/testsuite/g++.dg/concepts/diagnostic7.C | 11 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/concepts/pr94252.C | 27 |
2 files changed, 38 insertions, 0 deletions
diff --git a/gcc/testsuite/g++.dg/concepts/diagnostic7.C b/gcc/testsuite/g++.dg/concepts/diagnostic7.C new file mode 100644 index 0000000..3761b2b --- /dev/null +++ b/gcc/testsuite/g++.dg/concepts/diagnostic7.C @@ -0,0 +1,11 @@ +// { dg-do compile { target c++2a } } + +template<typename A, typename B> + concept same_as = __is_same(A, B); + +void f(); + +static_assert(requires { { f() } noexcept -> same_as<int>; }); +// { dg-error "static assertion failed" "" { target *-*-* } .-1 } +// { dg-message "not .noexcept." "" { target *-*-* } .-2 } +// { dg-message "return-type-requirement" "" { target *-*-* } .-3 } diff --git a/gcc/testsuite/g++.dg/concepts/pr94252.C b/gcc/testsuite/g++.dg/concepts/pr94252.C new file mode 100644 index 0000000..56ce5f8 --- /dev/null +++ b/gcc/testsuite/g++.dg/concepts/pr94252.C @@ -0,0 +1,27 @@ +// PR c++/94252 +// { dg-do compile { target c++2a } } + +auto f = []{ return 0; }; +static_assert(requires { f(); }); +static_assert(requires { requires requires { f(); }; }); + +template<typename A, typename B> + concept same_as = __is_same(A, B); + +struct S { int f(int) noexcept; }; +static_assert(requires(S o, int i) { + o.f(i); + { o.f(i) } noexcept -> same_as<int>; +}); + +template<typename T> + concept c = requires (T t) { requires (T)5; }; // { dg-error "has type .int." } + +int +foo() +{ + requires { requires c<int>; }; + requires { { 5 } -> same_as<bool>; }; + requires { requires !requires { { 5 } -> same_as<bool>; }; }; + return requires { requires 5; }; // { dg-error "has type .int." } +} |