diff options
author | Douglas Gregor <dgregor@apple.com> | 2012-06-15 16:59:29 +0000 |
---|---|---|
committer | Douglas Gregor <dgregor@apple.com> | 2012-06-15 16:59:29 +0000 |
commit | 03f1eb031b84e93415b792c4b45d8da71c88e92d (patch) | |
tree | 7c8a1c559c93d606eafc678fc1e05d7b74ea9f0f /lib/Sema | |
parent | 111684eea03ea162897134f6371a2ea06cd3e456 (diff) |
Check the parameter lists and return type of both blocks and lambdas
for unexpanded parameter packs. Fixes the crash-on-invalid in
PR13117.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@158525 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema')
-rw-r--r-- | lib/Sema/SemaExpr.cpp | 15 | ||||
-rw-r--r-- | lib/Sema/SemaLambda.cpp | 19 |
2 files changed, 32 insertions, 2 deletions
diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp index 0ca46d0505..bc0188f10b 100644 --- a/lib/Sema/SemaExpr.cpp +++ b/lib/Sema/SemaExpr.cpp @@ -9086,7 +9086,8 @@ void Sema::ActOnBlockStart(SourceLocation CaretLoc, Scope *CurScope) { PushExpressionEvaluationContext(PotentiallyEvaluated); } -void Sema::ActOnBlockArguments(Declarator &ParamInfo, Scope *CurScope) { +void Sema::ActOnBlockArguments(SourceLocation CaretLoc, Declarator &ParamInfo, + Scope *CurScope) { assert(ParamInfo.getIdentifier()==0 && "block-id should have no identifier!"); assert(ParamInfo.getContext() == Declarator::BlockLiteralContext); BlockScopeInfo *CurBlock = getCurBlock(); @@ -9094,6 +9095,18 @@ void Sema::ActOnBlockArguments(Declarator &ParamInfo, Scope *CurScope) { TypeSourceInfo *Sig = GetTypeForDeclarator(ParamInfo, CurScope); QualType T = Sig->getType(); + // FIXME: We should allow unexpanded parameter packs here, but that would, + // in turn, make the block expression contain unexpanded parameter packs. + if (DiagnoseUnexpandedParameterPack(CaretLoc, Sig, UPPC_Block)) { + // Drop the parameters. + FunctionProtoType::ExtProtoInfo EPI; + EPI.HasTrailingReturn = false; + EPI.TypeQuals |= DeclSpec::TQ_const; + T = Context.getFunctionType(Context.DependentTy, /*Args=*/0, /*NumArgs=*/0, + EPI); + Sig = Context.getTrivialTypeSourceInfo(T); + } + // GetTypeForDeclarator always produces a function type for a block // literal signature. Furthermore, it is always a FunctionProtoType // unless the function was written with a typedef. diff --git a/lib/Sema/SemaLambda.cpp b/lib/Sema/SemaLambda.cpp index f64be51744..07ee890562 100644 --- a/lib/Sema/SemaLambda.cpp +++ b/lib/Sema/SemaLambda.cpp @@ -269,9 +269,26 @@ void Sema::ActOnStartOfLambdaDefinition(LambdaIntroducer &Intro, FunctionProtoTypeLoc Proto = cast<FunctionProtoTypeLoc>(TL); Params = llvm::ArrayRef<ParmVarDecl *>(Proto.getParmArray(), Proto.getNumArgs()); + + // Check for unexpanded parameter packs in the method type. + // FIXME: We should allow unexpanded parameter packs here, but that would, + // in turn, make the lambda expression contain unexpanded parameter packs. + if (DiagnoseUnexpandedParameterPack(Intro.Range.getBegin(), MethodTyInfo, + UPPC_Lambda)) { + // Drop the parameters. + Params = llvm::ArrayRef<ParmVarDecl *>(); + FunctionProtoType::ExtProtoInfo EPI; + EPI.HasTrailingReturn = false; + EPI.TypeQuals |= DeclSpec::TQ_const; + QualType MethodTy = Context.getFunctionType(Context.DependentTy, + /*Args=*/0, /*NumArgs=*/0, EPI); + MethodTyInfo = Context.getTrivialTypeSourceInfo(MethodTy); + ExplicitParams = false; + ExplicitResultType = false; + } } - CXXMethodDecl *Method = startLambdaDefinition(Class, Intro.Range, + CXXMethodDecl *Method = startLambdaDefinition(Class, Intro.Range, MethodTyInfo, EndLoc, Params); if (ExplicitParams) |