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

2021-09-24 Thread Matheus Izvekov via Phabricator via cfe-commits
This revision was landed with ongoing or failed builds.
This revision was automatically updated to reflect the committed changes.
Closed by commit rG37adc4f957c2: [clang] set templates as invalid when any of 
the parameters are invalid (authored by mizvekov).

Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D110460/new/

https://reviews.llvm.org/D110460

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

Index: clang/test/SemaTemplate/deduction-crash.cpp
===
--- clang/test/SemaTemplate/deduction-crash.cpp
+++ clang/test/SemaTemplate/deduction-crash.cpp
@@ -161,3 +161,13 @@
 }
 
 }
+
+namespace PR51872_part1 {
+  template class T1 { template  T1(); };
+  // expected-error@-1 {{non-type template parameter has incomplete type 'struct U1'}}
+  // expected-note@-2  {{forward declaration of 'PR51872_part1::U1'}}
+
+  T1 t1 = 0;
+  // expected-error@-1 {{no viable constructor or deduction guide for deduction of template arguments of 'T1'}}
+  // expected-note@-6  {{candidate template ignored: could not match 'T1<>' against 'int'}}
+}
Index: clang/lib/AST/DeclTemplate.cpp
===
--- clang/lib/AST/DeclTemplate.cpp
+++ clang/lib/AST/DeclTemplate.cpp
@@ -165,14 +165,20 @@
 return cast(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(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 @@
 // FunctionTemplateDecl Implementation
 //===--===//
 
-FunctionTemplateDecl *FunctionTemplateDecl::Create(ASTContext &C,
-   DeclContext *DC,
-   SourceLocation L,
-   DeclarationName Name,
-   TemplateParameterList *Params,
-   NamedDecl *Decl) {
-  AdoptTemplateParameterList(Params, cast(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(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 @@
 // 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(Decl));
-
-  return new (C, DC) ClassTemplateDecl(C, DC, L, Name, Params, Decl);
+  bool Invalid = AdoptTemplateParameterList(Params, cast(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 @@
  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 @@
   SpecializedTemplate, Args, PrevDecl),
   Templat

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

2021-09-24 Thread Matheus Izvekov via Phabricator via cfe-commits
mizvekov created this revision.
mizvekov published this revision for review.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

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 


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D110460

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

Index: clang/test/SemaTemplate/deduction-crash.cpp
===
--- clang/test/SemaTemplate/deduction-crash.cpp
+++ clang/test/SemaTemplate/deduction-crash.cpp
@@ -161,3 +161,13 @@
 }
 
 }
+
+namespace PR51872_part1 {
+  template class T1 { template  T1(); };
+  // expected-error@-1 {{non-type template parameter has incomplete type 'struct U1'}}
+  // expected-note@-2  {{forward declaration of 'PR51872_part1::U1'}}
+
+  T1 t1 = 0;
+  // expected-error@-1 {{no viable constructor or deduction guide for deduction of template arguments of 'T1'}}
+  // expected-note@-6  {{candidate template ignored: could not match 'T1<>' against 'int'}}
+}
Index: clang/lib/AST/DeclTemplate.cpp
===
--- clang/lib/AST/DeclTemplate.cpp
+++ clang/lib/AST/DeclTemplate.cpp
@@ -165,14 +165,20 @@
 return cast(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(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 @@
 // FunctionTemplateDecl Implementation
 //===--===//
 
-FunctionTemplateDecl *FunctionTemplateDecl::Create(ASTContext &C,
-   DeclContext *DC,
-   SourceLocation L,
-   DeclarationName Name,
-   TemplateParameterList *Params,
-   NamedDecl *Decl) {
-  AdoptTemplateParameterList(Params, cast(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(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 @@
 // 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(Decl));
-
-  return new (C, DC) ClassTemplateDecl(C, DC, L, Name, Params, Decl);
+  bool Invalid = AdoptTemplateParameterList(Params, cast(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 @@
  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 @@
   SpecializedTemplate, Ar