[Concepts] Add missing CXXThisScope to function template constraint substitution

We did not have a CXXThisScope around constraint checking of functions and
function template specializations, causing a crash when checking a constraint
that had a 'this' (bug 44689).

Recommit after fixing test.
This commit is contained in:
Saar Raz 2020-02-05 00:51:40 +02:00
parent a5f1fff9dd
commit 6c23244156
3 changed files with 24 additions and 2 deletions

View File

@ -329,6 +329,13 @@ bool Sema::CheckFunctionConstraints(const FunctionDecl *FD,
Satisfaction.IsSatisfied = true;
return false;
}
Qualifiers ThisQuals;
CXXRecordDecl *Record = nullptr;
if (auto *Method = dyn_cast<CXXMethodDecl>(FD)) {
ThisQuals = Method->getMethodQualifiers();
Record = const_cast<CXXRecordDecl *>(Method->getParent());
}
CXXThisScopeRAII ThisScope(*this, Record, ThisQuals, Record != nullptr);
// We substitute with empty arguments in order to rebuild the atomic
// constraint in a constant-evaluated context.
// FIXME: Should this be a dedicated TreeTransform?

View File

@ -4271,7 +4271,13 @@ bool Sema::CheckInstantiatedFunctionTemplateConstraints(
Scope, MLTAL))
return true;
}
Qualifiers ThisQuals;
CXXRecordDecl *Record = nullptr;
if (auto *Method = dyn_cast<CXXMethodDecl>(Decl)) {
ThisQuals = Method->getMethodQualifiers();
Record = Method->getParent();
}
CXXThisScopeRAII ThisScope(*this, Record, ThisQuals, Record != nullptr);
return CheckConstraintSatisfaction(Template, TemplateAC, TemplateArgs,
PointOfInstantiation, Satisfaction);
}

View File

@ -57,4 +57,13 @@ struct S3 {
static constexpr void f(Args...) { }
};
static_assert((S3<int>::f(), true));
static_assert((S3<int>::f(), true));
template<typename T>
struct S4 {
template<typename>
constexpr void foo() requires (*this, true) { }
constexpr void goo() requires (*this, true) { }
};
static_assert((S4<int>{}.foo<int>(), S4<int>{}.goo(), true));