From: Larisse Voufo Date: Fri, 29 Aug 2014 21:08:16 +0000 (+0000) Subject: Fix for PR20660, where unexpanded parameter pack in function parameter clause causes... X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=486ef7cc535c3baac0df9baa76597963837dc917;p=clang Fix for PR20660, where unexpanded parameter pack in function parameter clause causes clang to crash. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@216778 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Sema/SemaTemplateVariadic.cpp b/lib/Sema/SemaTemplateVariadic.cpp index 6e317d573b..79c0666480 100644 --- a/lib/Sema/SemaTemplateVariadic.cpp +++ b/lib/Sema/SemaTemplateVariadic.cpp @@ -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(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()) diff --git a/test/CXX/dcl.decl/dcl.meaning/dcl.fct/p13.cpp b/test/CXX/dcl.decl/dcl.meaning/dcl.fct/p13.cpp index 19a5f23e3f..93c246bdd7 100644 --- a/test/CXX/dcl.decl/dcl.meaning/dcl.fct/p13.cpp +++ b/test/CXX/dcl.decl/dcl.meaning/dcl.fct/p13.cpp @@ -46,3 +46,30 @@ struct X2 { template 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 +void a(T[] ... x); // expected-error{{expected ')'}} expected-note{{to match this '('}} + +template +void b(T[] ...); + +template +void c(T ... []); // expected-error{{type 'T []' of function parameter pack does not contain any unexpanded parameter packs}} + +template +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. + + + + diff --git a/test/SemaCXX/crashes.cpp b/test/SemaCXX/crashes.cpp index 1570d12eeb..6ae476f708 100644 --- a/test/SemaCXX/crashes.cpp +++ b/test/SemaCXX/crashes.cpp @@ -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}} +} +