r216778 - Fix for PR20660, where unexpanded parameter pack in function parameter clause causes clang to crash.

Larisse Voufo lvoufo at google.com
Fri Aug 29 14:08:16 PDT 2014


Author: lvoufo
Date: Fri Aug 29 16:08:16 2014
New Revision: 216778

URL: http://llvm.org/viewvc/llvm-project?rev=216778&view=rev
Log:
Fix for PR20660, where unexpanded parameter pack in function parameter clause causes clang to crash.

Modified:
    cfe/trunk/lib/Sema/SemaTemplateVariadic.cpp
    cfe/trunk/test/CXX/dcl.decl/dcl.meaning/dcl.fct/p13.cpp
    cfe/trunk/test/SemaCXX/crashes.cpp

Modified: cfe/trunk/lib/Sema/SemaTemplateVariadic.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplateVariadic.cpp?rev=216778&r1=216777&r2=216778&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplateVariadic.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplateVariadic.cpp Fri Aug 29 16:08:16 2014
@@ -747,24 +747,48 @@ bool Sema::containsUnexpandedParameterPa
   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())

Modified: cfe/trunk/test/CXX/dcl.decl/dcl.meaning/dcl.fct/p13.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/dcl.decl/dcl.meaning/dcl.fct/p13.cpp?rev=216778&r1=216777&r2=216778&view=diff
==============================================================================
--- cfe/trunk/test/CXX/dcl.decl/dcl.meaning/dcl.fct/p13.cpp (original)
+++ cfe/trunk/test/CXX/dcl.decl/dcl.meaning/dcl.fct/p13.cpp Fri Aug 29 16:08:16 2014
@@ -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.
+
+
+
+

Modified: cfe/trunk/test/SemaCXX/crashes.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/crashes.cpp?rev=216778&r1=216777&r2=216778&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/crashes.cpp (original)
+++ cfe/trunk/test/SemaCXX/crashes.cpp Fri Aug 29 16:08:16 2014
@@ -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}}
+}
+





More information about the cfe-commits mailing list