[clang] 37adc4f - [clang] set templates as invalid when any of the parameters are invalid

Matheus Izvekov via cfe-commits cfe-commits at lists.llvm.org
Fri Sep 24 19:04:55 PDT 2021


Author: Matheus Izvekov
Date: 2021-09-25T04:04:47+02:00
New Revision: 37adc4f957c2383a625e2e593ba1d18a25d92b91

URL: https://github.com/llvm/llvm-project/commit/37adc4f957c2383a625e2e593ba1d18a25d92b91
DIFF: https://github.com/llvm/llvm-project/commit/37adc4f957c2383a625e2e593ba1d18a25d92b91.diff

LOG: [clang] set templates as invalid when any of the parameters are invalid

See PR51872 for the original repro.

This fixes a crash when converting a templated constructor into a deduction
guide, in case any of the template parameters were invalid.

Signed-off-by: Matheus Izvekov <mizvekov at gmail.com>

Reviewed By: rsmith

Differential Revision: https://reviews.llvm.org/D110460

Added: 
    

Modified: 
    clang/lib/AST/DeclTemplate.cpp
    clang/test/SemaTemplate/deduction-crash.cpp

Removed: 
    


################################################################################
diff  --git a/clang/lib/AST/DeclTemplate.cpp b/clang/lib/AST/DeclTemplate.cpp
index a25185067b9c5..fa73c53866490 100644
--- a/clang/lib/AST/DeclTemplate.cpp
+++ b/clang/lib/AST/DeclTemplate.cpp
@@ -165,14 +165,20 @@ unsigned TemplateParameterList::getDepth() const {
     return cast<TemplateTemplateParmDecl>(FirstParm)->getDepth();
 }
 
-static void AdoptTemplateParameterList(TemplateParameterList *Params,
+static bool AdoptTemplateParameterList(TemplateParameterList *Params,
                                        DeclContext *Owner) {
+  bool Invalid = false;
   for (NamedDecl *P : *Params) {
     P->setDeclContext(Owner);
 
     if (const auto *TTP = dyn_cast<TemplateTemplateParmDecl>(P))
-      AdoptTemplateParameterList(TTP->getTemplateParameters(), Owner);
+      if (AdoptTemplateParameterList(TTP->getTemplateParameters(), Owner))
+        Invalid = true;
+
+    if (P->isInvalidDecl())
+      Invalid = true;
   }
+  return Invalid;
 }
 
 void TemplateParameterList::
@@ -339,14 +345,15 @@ void RedeclarableTemplateDecl::addSpecializationImpl(
 // FunctionTemplateDecl Implementation
 //===----------------------------------------------------------------------===//
 
-FunctionTemplateDecl *FunctionTemplateDecl::Create(ASTContext &C,
-                                                   DeclContext *DC,
-                                                   SourceLocation L,
-                                                   DeclarationName Name,
-                                               TemplateParameterList *Params,
-                                                   NamedDecl *Decl) {
-  AdoptTemplateParameterList(Params, cast<DeclContext>(Decl));
-  return new (C, DC) FunctionTemplateDecl(C, DC, L, Name, Params, Decl);
+FunctionTemplateDecl *
+FunctionTemplateDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation L,
+                             DeclarationName Name,
+                             TemplateParameterList *Params, NamedDecl *Decl) {
+  bool Invalid = AdoptTemplateParameterList(Params, cast<DeclContext>(Decl));
+  auto *TD = new (C, DC) FunctionTemplateDecl(C, DC, L, Name, Params, Decl);
+  if (Invalid)
+    TD->setInvalidDecl();
+  return TD;
 }
 
 FunctionTemplateDecl *FunctionTemplateDecl::CreateDeserialized(ASTContext &C,
@@ -438,15 +445,16 @@ void FunctionTemplateDecl::mergePrevDecl(FunctionTemplateDecl *Prev) {
 // ClassTemplateDecl Implementation
 //===----------------------------------------------------------------------===//
 
-ClassTemplateDecl *ClassTemplateDecl::Create(ASTContext &C,
-                                             DeclContext *DC,
+ClassTemplateDecl *ClassTemplateDecl::Create(ASTContext &C, DeclContext *DC,
                                              SourceLocation L,
                                              DeclarationName Name,
                                              TemplateParameterList *Params,
                                              NamedDecl *Decl) {
-  AdoptTemplateParameterList(Params, cast<DeclContext>(Decl));
-
-  return new (C, DC) ClassTemplateDecl(C, DC, L, Name, Params, Decl);
+  bool Invalid = AdoptTemplateParameterList(Params, cast<DeclContext>(Decl));
+  auto *TD = new (C, DC) ClassTemplateDecl(C, DC, L, Name, Params, Decl);
+  if (Invalid)
+    TD->setInvalidDecl();
+  return TD;
 }
 
 ClassTemplateDecl *ClassTemplateDecl::CreateDeserialized(ASTContext &C,
@@ -1005,8 +1013,11 @@ ConceptDecl *ConceptDecl::Create(ASTContext &C, DeclContext *DC,
                                  SourceLocation L, DeclarationName Name,
                                  TemplateParameterList *Params,
                                  Expr *ConstraintExpr) {
-  AdoptTemplateParameterList(Params, DC);
-  return new (C, DC) ConceptDecl(DC, L, Name, Params, ConstraintExpr);
+  bool Invalid = AdoptTemplateParameterList(Params, DC);
+  auto *TD = new (C, DC) ConceptDecl(DC, L, Name, Params, ConstraintExpr);
+  if (Invalid)
+    TD->setInvalidDecl();
+  return TD;
 }
 
 ConceptDecl *ConceptDecl::CreateDeserialized(ASTContext &C,
@@ -1039,7 +1050,8 @@ ClassTemplatePartialSpecializationDecl(ASTContext &Context, TagKind TK,
                                       SpecializedTemplate, Args, PrevDecl),
       TemplateParams(Params), ArgsAsWritten(ArgInfos),
       InstantiatedFromMember(nullptr, false) {
-  AdoptTemplateParameterList(Params, this);
+  if (AdoptTemplateParameterList(Params, this))
+    setInvalidDecl();
 }
 
 ClassTemplatePartialSpecializationDecl *
@@ -1097,14 +1109,15 @@ FriendTemplateDecl *FriendTemplateDecl::CreateDeserialized(ASTContext &C,
 // TypeAliasTemplateDecl Implementation
 //===----------------------------------------------------------------------===//
 
-TypeAliasTemplateDecl *TypeAliasTemplateDecl::Create(ASTContext &C,
-                                                     DeclContext *DC,
-                                                     SourceLocation L,
-                                                     DeclarationName Name,
-                                                  TemplateParameterList *Params,
-                                                     NamedDecl *Decl) {
-  AdoptTemplateParameterList(Params, DC);
-  return new (C, DC) TypeAliasTemplateDecl(C, DC, L, Name, Params, Decl);
+TypeAliasTemplateDecl *
+TypeAliasTemplateDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation L,
+                              DeclarationName Name,
+                              TemplateParameterList *Params, NamedDecl *Decl) {
+  bool Invalid = AdoptTemplateParameterList(Params, DC);
+  auto *TD = new (C, DC) TypeAliasTemplateDecl(C, DC, L, Name, Params, Decl);
+  if (Invalid)
+    TD->setInvalidDecl();
+  return TD;
 }
 
 TypeAliasTemplateDecl *TypeAliasTemplateDecl::CreateDeserialized(ASTContext &C,
@@ -1151,8 +1164,11 @@ VarTemplateDecl *VarTemplateDecl::Create(ASTContext &C, DeclContext *DC,
                                          SourceLocation L, DeclarationName Name,
                                          TemplateParameterList *Params,
                                          VarDecl *Decl) {
-  AdoptTemplateParameterList(Params, DC);
-  return new (C, DC) VarTemplateDecl(C, DC, L, Name, Params, Decl);
+  bool Invalid = AdoptTemplateParameterList(Params, DC);
+  auto *TD = new (C, DC) VarTemplateDecl(C, DC, L, Name, Params, Decl);
+  if (Invalid)
+    TD->setInvalidDecl();
+  return TD;
 }
 
 VarTemplateDecl *VarTemplateDecl::CreateDeserialized(ASTContext &C,
@@ -1334,8 +1350,8 @@ VarTemplatePartialSpecializationDecl::VarTemplatePartialSpecializationDecl(
                                     TInfo, S, Args),
       TemplateParams(Params), ArgsAsWritten(ArgInfos),
       InstantiatedFromMember(nullptr, false) {
-  // TODO: The template parameters should be in DC by now. Verify.
-  // AdoptTemplateParameterList(Params, DC);
+  if (AdoptTemplateParameterList(Params, DC))
+    setInvalidDecl();
 }
 
 VarTemplatePartialSpecializationDecl *

diff  --git a/clang/test/SemaTemplate/deduction-crash.cpp b/clang/test/SemaTemplate/deduction-crash.cpp
index 2c58fefa065fd..86ec9f7980a7d 100644
--- a/clang/test/SemaTemplate/deduction-crash.cpp
+++ b/clang/test/SemaTemplate/deduction-crash.cpp
@@ -161,3 +161,13 @@ evaluateSelectionRequirement<void>(InputT &&Value) { // expected-error {{cannot
 }
 
 }
+
+namespace PR51872_part1 {
+  template<int> class T1 { template <struct U1> T1(); };
+  // expected-error at -1 {{non-type template parameter has incomplete type 'struct U1'}}
+  // expected-note at -2  {{forward declaration of 'PR51872_part1::U1'}}
+
+  T1 t1 = 0;
+  // expected-error at -1 {{no viable constructor or deduction guide for deduction of template arguments of 'T1'}}
+  // expected-note at -6  {{candidate template ignored: could not match 'T1<>' against 'int'}}
+}


        


More information about the cfe-commits mailing list