[Concepts] Add ExpressionEvaluationContexts to instantiation of constraints

Proper ExpressionEvaluationContext were not being entered when instantiating constraint
expressions, which caused assertion failures in certain cases, including bug #44614.
This commit is contained in:
Saar Raz 2020-01-23 23:24:56 +02:00
parent 9c2eb220ed
commit 4d33a8dfcf
2 changed files with 20 additions and 0 deletions

View File

@ -1848,6 +1848,8 @@ Decl *TemplateDeclInstantiator::VisitFunctionDecl(
// FIXME: Concepts: Do not substitute into constraint expressions
Expr *TrailingRequiresClause = D->getTrailingRequiresClause();
if (TrailingRequiresClause) {
EnterExpressionEvaluationContext ConstantEvaluated(
SemaRef, Sema::ExpressionEvaluationContext::ConstantEvaluated);
ExprResult SubstRC = SemaRef.SubstExpr(TrailingRequiresClause,
TemplateArgs);
if (SubstRC.isInvalid())
@ -2186,6 +2188,8 @@ Decl *TemplateDeclInstantiator::VisitCXXMethodDecl(
// FIXME: Concepts: Do not substitute into constraint expressions
Expr *TrailingRequiresClause = D->getTrailingRequiresClause();
if (TrailingRequiresClause) {
EnterExpressionEvaluationContext ConstantEvaluated(
SemaRef, Sema::ExpressionEvaluationContext::ConstantEvaluated);
ExprResult SubstRC = SemaRef.SubstExpr(TrailingRequiresClause,
TemplateArgs);
if (SubstRC.isInvalid())
@ -2525,6 +2529,8 @@ Decl *TemplateDeclInstantiator::VisitTemplateTypeParmDecl(
TemplateArgumentListInfo InstArgs;
if (TemplArgInfo) {
EnterExpressionEvaluationContext ConstantEvaluated(
SemaRef, Sema::ExpressionEvaluationContext::ConstantEvaluated);
InstArgs.setLAngleLoc(TemplArgInfo->LAngleLoc);
InstArgs.setRAngleLoc(TemplArgInfo->RAngleLoc);
if (SemaRef.Subst(TemplArgInfo->getTemplateArgs(),
@ -3729,6 +3735,8 @@ TemplateDeclInstantiator::SubstTemplateParams(TemplateParameterList *L) {
// checking satisfaction.
Expr *InstRequiresClause = nullptr;
if (Expr *E = L->getRequiresClause()) {
EnterExpressionEvaluationContext ConstantEvaluated(
SemaRef, Sema::ExpressionEvaluationContext::ConstantEvaluated);
ExprResult Res = SemaRef.SubstExpr(E, TemplateArgs);
if (Res.isInvalid() || !Res.isUsable()) {
return nullptr;

View File

@ -39,3 +39,15 @@ struct S {
};
static_assert(S<void>::f(1));
constexpr auto value = 0;
template<typename T>
struct S2 {
template<typename = void> requires(value, true)
static constexpr auto f() requires(value, true) {
}
};
static_assert((S2<int>::f(), true));