c++: requires-expression outside of a template is misevaluated [PR94252]
authorPatrick Palka <ppalka@redhat.com>
Sat, 28 Mar 2020 12:56:59 +0000 (08:56 -0400)
committerPatrick Palka <ppalka@redhat.com>
Sat, 28 Mar 2020 12:56:59 +0000 (08:56 -0400)
commita7ea3d2ced786c4544fa625f34f515d89ed074fe
tree5d72578ca8e5a5be0fbb57cbd820e4bb2f1a175b
parentcd68edf894d6b72e5bc37ac205deef9d237ab70b
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.
gcc/cp/ChangeLog
gcc/cp/constraint.cc
gcc/cp/cp-gimplify.c
gcc/cp/parser.c
gcc/cp/pt.c
gcc/cp/semantics.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/concepts/diagnostic7.C [new file with mode: 0644]
gcc/testsuite/g++.dg/concepts/pr94252.C [new file with mode: 0644]
gcc/testsuite/g++.dg/cpp2a/concepts-requires18.C