aboutsummaryrefslogtreecommitdiff
path: root/gcc/cp/constraint.cc
diff options
context:
space:
mode:
authorPatrick Palka <ppalka@redhat.com>2020-03-28 08:56:59 -0400
committerPatrick Palka <ppalka@redhat.com>2020-03-28 08:56:59 -0400
commita7ea3d2ced786c4544fa625f34f515d89ed074fe (patch)
tree5d72578ca8e5a5be0fbb57cbd820e4bb2f1a175b /gcc/cp/constraint.cc
parentcd68edf894d6b72e5bc37ac205deef9d237ab70b (diff)
downloadgcc-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/cp/constraint.cc')
-rw-r--r--gcc/cp/constraint.cc10
1 files changed, 4 insertions, 6 deletions
diff --git a/gcc/cp/constraint.cc b/gcc/cp/constraint.cc
index 571c7cb..9c21ce8 100644
--- a/gcc/cp/constraint.cc
+++ b/gcc/cp/constraint.cc
@@ -1981,15 +1981,17 @@ tsubst_compound_requirement (tree t, tree args, subst_info info)
if (type == error_mark_node)
return error_mark_node;
+ subst_info quiet (tf_none, info.in_decl);
+
/* Check expression against the result type. */
if (type)
{
if (tree placeholder = type_uses_auto (type))
{
- if (!type_deducible_p (expr, type, placeholder, args, info))
+ if (!type_deducible_p (expr, type, placeholder, args, quiet))
return error_mark_node;
}
- else if (!expression_convertible_p (expr, type, info))
+ else if (!expression_convertible_p (expr, type, quiet))
return error_mark_node;
}
@@ -3443,10 +3445,6 @@ diagnose_atomic_constraint (tree t, tree map, tree result, subst_info info)
case REQUIRES_EXPR:
diagnose_requires_expr (expr, map, info.in_decl);
break;
- case INTEGER_CST:
- /* This must be either 0 or false. */
- inform (loc, "%qE is never satisfied", expr);
- break;
default:
tree a = copy_node (t);
ATOMIC_CONSTR_MAP (a) = map;