]> granicus.if.org Git - clang/commitdiff
Fix for PR20660, where unexpanded parameter pack in function parameter clause causes...
authorLarisse Voufo <lvoufo@google.com>
Fri, 29 Aug 2014 21:08:16 +0000 (21:08 +0000)
committerLarisse Voufo <lvoufo@google.com>
Fri, 29 Aug 2014 21:08:16 +0000 (21:08 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@216778 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Sema/SemaTemplateVariadic.cpp
test/CXX/dcl.decl/dcl.meaning/dcl.fct/p13.cpp
test/SemaCXX/crashes.cpp

index 6e317d573b36acec966fe8798963be622e69fde7..79c066648028c18c9acd7e7389e0599b0caef7bf 100644 (file)
@@ -747,24 +747,48 @@ bool Sema::containsUnexpandedParameterPacks(Declarator &D) {
   case TST_error:
     break;
   }
-  
+
   for (unsigned I = 0, N = D.getNumTypeObjects(); I != N; ++I) {
     const DeclaratorChunk &Chunk = D.getTypeObject(I);
     switch (Chunk.Kind) {
     case DeclaratorChunk::Pointer:
     case DeclaratorChunk::Reference:
     case DeclaratorChunk::Paren:
+    case DeclaratorChunk::BlockPointer:
       // These declarator chunks cannot contain any parameter packs.
       break;
         
     case DeclaratorChunk::Array:
+      if (Chunk.Arr.NumElts &&
+          Chunk.Arr.NumElts->containsUnexpandedParameterPack())
+        return true;
+      break;
     case DeclaratorChunk::Function:
-    case DeclaratorChunk::BlockPointer:
-      // Syntactically, these kinds of declarator chunks all come after the
-      // declarator-id (conceptually), so the parser should not invoke this
-      // routine at this time.
-      llvm_unreachable("Could not have seen this kind of declarator chunk");
-        
+      for (unsigned i = 0, e = Chunk.Fun.NumParams; i != e; ++i) {
+        ParmVarDecl *Param = cast<ParmVarDecl>(Chunk.Fun.Params[i].Param);
+        QualType ParamTy = Param->getType();
+        assert(!ParamTy.isNull() && "Couldn't parse type?");
+        if (ParamTy->containsUnexpandedParameterPack()) return true;
+      }
+
+      if (Chunk.Fun.getExceptionSpecType() == EST_Dynamic) {
+        for (unsigned i = 0; i != Chunk.Fun.NumExceptions; ++i) {
+          if (Chunk.Fun.Exceptions[i]
+                  .Ty.get()
+                  ->containsUnexpandedParameterPack())
+            return true;
+        }
+      } else if (Chunk.Fun.getExceptionSpecType() == EST_ComputedNoexcept &&
+                 Chunk.Fun.NoexceptExpr->containsUnexpandedParameterPack())
+        return true;
+
+      if (Chunk.Fun.hasTrailingReturnType() &&
+          Chunk.Fun.getTrailingReturnType()
+              .get()
+              ->containsUnexpandedParameterPack())
+        return true;
+      break;
+
     case DeclaratorChunk::MemberPointer:
       if (Chunk.Mem.Scope().getScopeRep() &&
           Chunk.Mem.Scope().getScopeRep()->containsUnexpandedParameterPack())
index 19a5f23e3f17c1acca0a38b71d63f80194e8370c..93c246bdd7957d098875cde8626f27c8f53bb94c 100644 (file)
@@ -46,3 +46,30 @@ struct X2 {
 template<typename T>
 void f4(T ...args); // expected-error{{type 'T' of function parameter pack does not contain any unexpanded parameter packs}}
 
+void f4i(int ... x); // expected-error{{type 'int' of function parameter pack does not contain any unexpanded parameter packs}}
+void f4i0(int ...);
+
+namespace array_type {
+template<typename T>
+void a(T[] ... x); // expected-error{{expected ')'}} expected-note{{to match this '('}}
+
+template<typename T>
+void b(T[] ...);
+
+template<typename T>
+void c(T ... []); // expected-error{{type 'T []' of function parameter pack does not contain any unexpanded parameter packs}}
+
+template<typename T>
+void d(T ... x[]); // expected-error{{type 'T []' of function parameter pack does not contain any unexpanded parameter packs}}
+
+void ai(int[] ... x); // expected-error{{expected ')'}} expected-note{{to match this '('}}
+void bi(int[] ...);
+void ci(int ... []); // expected-error{{type 'int []' of function parameter pack does not contain any unexpanded parameter packs}}
+void di(int ... x[]); // expected-error{{type 'int []' of function parameter pack does not contain any unexpanded parameter packs}}
+}
+
+// FIXME: Expand for function and member pointer types.
+
+
+
+
index 1570d12eeb2fb53c0624ee9ee666f4a194380f7a..6ae476f7080c561a12f72fbb55f3b385c9340ec9 100644 (file)
@@ -231,3 +231,9 @@ namespace pr16989 {
   };
   void C2::f() {}
 }
+
+namespace pr20660 {
+ appendList(int[]...);     // expected-error {{C++ requires a type specifier for all declarations}}
+ appendList(int[]...) { }  // expected-error {{C++ requires a type specifier for all declarations}}
+}
+