llvmorg-github-actions[bot] wrote:

<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-clang

Author: Corentin Jabot (cor3ntin)

<details>
<summary>Changes</summary>

There were a few issues here:
 - Names that are not templates were not diagnosed and led to a crash (in part 
because clang think they can be template names that will be later resolved by 
ADL)
 - Names that refer to a variable template decl, etc also led to a crash.

Fixes #<!-- -->220502

---
Full diff: https://github.com/llvm/llvm-project/pull/222328.diff


3 Files Affected:

- (modified) clang/lib/Parse/ParseDeclCXX.cpp (+14-6) 
- (modified) clang/lib/Sema/SemaTemplateVariadic.cpp (+5) 
- (modified) clang/test/SemaCXX/cxx2d-pack-indexing-template.cpp (+18-2) 


``````````diff
diff --git a/clang/lib/Parse/ParseDeclCXX.cpp b/clang/lib/Parse/ParseDeclCXX.cpp
index d701cbaa43bdd..14adeeaad7a4d 100644
--- a/clang/lib/Parse/ParseDeclCXX.cpp
+++ b/clang/lib/Parse/ParseDeclCXX.cpp
@@ -1251,8 +1251,13 @@ bool 
Parser::AnnotatePackIndexingTemplateName(CXXScopeSpec &SS,
 
   TemplateName Indexed = Actions.ActOnPackIndexingTemplateName(
       Template.get(), NameLoc, IndexExpr.get());
+
+  // If we are unable to index a template name, treat is as a non
+  // template and recover by eating the arguments and producing a
+  // TypeError annotation.
   if (Indexed.isNull())
-    return true;
+    TNK = TNK_Non_template;
+
   Template = TemplateTy::make(Indexed);
 
   // C++29 [temp.names]p7:
@@ -1273,11 +1278,14 @@ bool 
Parser::AnnotatePackIndexingTemplateName(CXXScopeSpec &SS,
   // C++29 [dcl.type.simple]p1:
   //   A type specifier is a placeholder for a deduced class type if [...] it
   //   is of the form typename pack-index-template-name.
-  if ((TNK == TNK_Type_template || TNK == TNK_Dependent_template_name) &&
-      getLangOpts().CPlusPlus17) {
+  if (Indexed.isNull() ||
+      ((TNK == TNK_Type_template || TNK == TNK_Dependent_template_name) &&
+       getLangOpts().CPlusPlus17)) {
     TypeResult Type =
-        Actions.ActOnPackIndexingDeducedTemplateSpecializationType(Indexed,
-                                                                   NameLoc);
+        Indexed.isNull()
+            ? TypeError()
+            : Actions.ActOnPackIndexingDeducedTemplateSpecializationType(
+                  Indexed, NameLoc);
     Tok.setKind(tok::annot_typename);
     setTypeAnnotation(Tok, Type);
   } else {
@@ -1292,7 +1300,7 @@ bool 
Parser::AnnotatePackIndexingTemplateName(CXXScopeSpec &SS,
   Tok.setLocation(NameLoc);
   Tok.setAnnotationEndLoc(T.getCloseLocation());
   PP.AnnotateCachedTokens(Tok);
-  return false;
+  return Indexed.isNull();
 }
 
 void Parser::AnnotateExistingIndexedTypeNamePack(ParsedType T,
diff --git a/clang/lib/Sema/SemaTemplateVariadic.cpp 
b/clang/lib/Sema/SemaTemplateVariadic.cpp
index fb03591f70583..9b30832dc9d12 100644
--- a/clang/lib/Sema/SemaTemplateVariadic.cpp
+++ b/clang/lib/Sema/SemaTemplateVariadic.cpp
@@ -1406,6 +1406,11 @@ TemplateName 
Sema::ActOnPackIndexingTemplateName(TemplateName Pattern,
   // C++29 [temp.names]p3:
   //   The simple-template-name P in a pack-index-template-name shall denote a
   //   pack.
+  if (!Pattern.getAsTemplateTemplateParmDecl()) {
+    Diag(NameLoc, diag::err_expected_name_of_pack) << Pattern;
+    return TemplateName();
+  }
+
   bool DenotesPack = Pattern.containsUnexpandedParameterPack();
   if (!DenotesPack)
     Diag(NameLoc, diag::err_expected_name_of_pack) << Pattern;
diff --git a/clang/test/SemaCXX/cxx2d-pack-indexing-template.cpp 
b/clang/test/SemaCXX/cxx2d-pack-indexing-template.cpp
index 0298be66b1a86..3ccdcb9bb59b9 100644
--- a/clang/test/SemaCXX/cxx2d-pack-indexing-template.cpp
+++ b/clang/test/SemaCXX/cxx2d-pack-indexing-template.cpp
@@ -18,6 +18,24 @@ template <template <class> auto VV>
 constexpr int X = VV...[0]<int>; // expected-error {{'VV' does not refer to 
the name of a parameter pack}}
 }
 
+namespace GH220502 {
+void fn() {}
+void nontemplate(fn...[0]) {} // expected-error {{'fn' does not refer to the 
name of a parameter pack}}
+
+template <class T> concept Concept = true;
+template <class T> constexpr int Variable = 0;
+template <class T> void Function();
+template <class T> void Overloaded(T);
+template <class T> void Overloaded(T *);
+
+void f() {
+  (void)Concept...[0]<int>;  // expected-error {{'Concept' does not refer to 
the name of a parameter pack}}
+  (void)Variable...[0]<int>; // expected-error {{'Variable' does not refer to 
the name of a parameter pack}}
+  Function...[0]<int>();     // expected-error {{'Function' does not refer to 
the name of a parameter pack}}
+  Overloaded...[0]<int>(0);  // expected-error {{'Overloaded' does not refer 
to the name of a parameter pack}}
+}
+}
+
 namespace index {
 template <template <class> class... TT>
 struct S {
@@ -32,12 +50,10 @@ using E1 = OutOfBounds<A, B>;      // expected-note {{in 
instantiation of templa
 template <template <class> class... TT>
 using Negative = TT...[-1]<int>;
 // expected-error@-1 {{pack index evaluates to -1, which cannot be narrowed to 
type '__size_t'}}
-// expected-error@-2 {{expected ';' after alias declaration}}
 
 template <template <class> class... TT>
 using Narrowing = TT...[1.0]<int>;
 // expected-error@-1 {{conversion from 'double' to '__size_t' (aka 'unsigned 
long') is not allowed in a converted constant expression}}
-// expected-error@-2 {{expected ';' after alias declaration}}
 
 template <template <class> class... TT>
 using NonConstant = TT...[x]<int>;

``````````

</details>


https://github.com/llvm/llvm-project/pull/222328
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to