summaryrefslogtreecommitdiffstats
path: root/clang/lib/Sema
diff options
context:
space:
mode:
authorSaar Raz <saar@raz.email>2020-02-06 23:19:18 +0200
committerSaar Raz <saar@raz.email>2020-02-06 23:30:34 +0200
commit96ed02ddeebfd18265ef687fce80e7e148ec261c (patch)
tree70606c7b9906f51d377ecfd04ee05ca0243c9014 /clang/lib/Sema
parentc0c5ab30179897944cf44efac1c743e5344924db (diff)
downloadbcm5719-llvm-96ed02ddeebfd18265ef687fce80e7e148ec261c.tar.gz
bcm5719-llvm-96ed02ddeebfd18265ef687fce80e7e148ec261c.zip
[Concepts] Fix incorrect check when instantiating abbreviated template type-constraints
We would incorrectly check whether the type-constraint had already been initialized, causing us to ignore the invented template type constraints entirely. Also, TemplateParameterList would store incorrect information about invented type parameters when it observed them before their type-constraint was initialized, so we recreate it after initializing the function type of an abbreviated template. (cherry picked from commit 38fd69995fc5a6f16e0aa132a46e5ccdbc2eebb3)
Diffstat (limited to 'clang/lib/Sema')
-rw-r--r--clang/lib/Sema/SemaTemplateInstantiate.cpp4
-rwxr-xr-xclang/lib/Sema/SemaTemplateInstantiateDecl.cpp34
2 files changed, 36 insertions, 2 deletions
diff --git a/clang/lib/Sema/SemaTemplateInstantiate.cpp b/clang/lib/Sema/SemaTemplateInstantiate.cpp
index a9357ede700..568f5404dc0 100644
--- a/clang/lib/Sema/SemaTemplateInstantiate.cpp
+++ b/clang/lib/Sema/SemaTemplateInstantiate.cpp
@@ -2290,12 +2290,12 @@ ParmVarDecl *Sema::SubstParmVarDecl(ParmVarDecl *OldParm,
if (TemplateTypeParmDecl *TTP =
GetContainedInventedTypeParmVisitor().Visit(OldDI->getType())) {
if (const TypeConstraint *TC = TTP->getTypeConstraint()) {
- auto *Inst = cast<TemplateTypeParmDecl>(
+ auto *Inst = cast_or_null<TemplateTypeParmDecl>(
FindInstantiatedDecl(TTP->getLocation(), TTP, TemplateArgs));
// We will first get here when instantiating the abbreviated function
// template's described function, but we might also get here later.
// Make sure we do not instantiate the TypeConstraint more than once.
- if (Inst && !Inst->hasTypeConstraint()) {
+ if (Inst && !Inst->getTypeConstraint()) {
// TODO: Concepts: do not instantiate the constraint (delayed constraint
// substitution)
const ASTTemplateArgumentListInfo *TemplArgInfo
diff --git a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
index 7094462e74c..37dace3bee7 100755
--- a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
+++ b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
@@ -1837,6 +1837,23 @@ Decl *TemplateDeclInstantiator::VisitFunctionDecl(
return nullptr;
QualType T = adjustFunctionTypeForInstantiation(SemaRef.Context, D, TInfo);
+ if (TemplateParams && TemplateParams->size()) {
+ auto *LastParam =
+ dyn_cast<TemplateTypeParmDecl>(TemplateParams->asArray().back());
+ if (LastParam && LastParam->isImplicit() &&
+ LastParam->hasTypeConstraint()) {
+ // In abbreviated templates, the type-constraints of invented template
+ // type parameters are instantiated with the function type, invalidating
+ // the TemplateParameterList which relied on the template type parameter
+ // not having a type constraint. Recreate the TemplateParameterList with
+ // the updated parameter list.
+ TemplateParams = TemplateParameterList::Create(
+ SemaRef.Context, TemplateParams->getTemplateLoc(),
+ TemplateParams->getLAngleLoc(), TemplateParams->asArray(),
+ TemplateParams->getRAngleLoc(), TemplateParams->getRequiresClause());
+ }
+ }
+
NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc();
if (QualifierLoc) {
QualifierLoc = SemaRef.SubstNestedNameSpecifierLoc(QualifierLoc,
@@ -2177,6 +2194,23 @@ Decl *TemplateDeclInstantiator::VisitCXXMethodDecl(
return nullptr;
QualType T = adjustFunctionTypeForInstantiation(SemaRef.Context, D, TInfo);
+ if (TemplateParams && TemplateParams->size()) {
+ auto *LastParam =
+ dyn_cast<TemplateTypeParmDecl>(TemplateParams->asArray().back());
+ if (LastParam && LastParam->isImplicit() &&
+ LastParam->hasTypeConstraint()) {
+ // In abbreviated templates, the type-constraints of invented template
+ // type parameters are instantiated with the function type, invalidating
+ // the TemplateParameterList which relied on the template type parameter
+ // not having a type constraint. Recreate the TemplateParameterList with
+ // the updated parameter list.
+ TemplateParams = TemplateParameterList::Create(
+ SemaRef.Context, TemplateParams->getTemplateLoc(),
+ TemplateParams->getLAngleLoc(), TemplateParams->asArray(),
+ TemplateParams->getRAngleLoc(), TemplateParams->getRequiresClause());
+ }
+ }
+
NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc();
if (QualifierLoc) {
QualifierLoc = SemaRef.SubstNestedNameSpecifierLoc(QualifierLoc,
OpenPOWER on IntegriCloud