diff options
author | Richard Smith <richard-llvm@metafoo.co.uk> | 2019-08-26 22:51:28 +0000 |
---|---|---|
committer | Richard Smith <richard-llvm@metafoo.co.uk> | 2019-08-26 22:51:28 +0000 |
commit | b26bc34e3a77cab8b2773c69f27198f77f993090 (patch) | |
tree | 196fc6c3e4e111c21deb21f5a7837de86caf4199 /clang/lib/Sema/SemaLambda.cpp | |
parent | f837bb4a3443b374b29336a9058035c15a240b9c (diff) | |
download | bcm5719-llvm-b26bc34e3a77cab8b2773c69f27198f77f993090.tar.gz bcm5719-llvm-b26bc34e3a77cab8b2773c69f27198f77f993090.zip |
PR42587: diagnose unexpanded uses of a pack parameter of a generic
lambda from within the lambda-declarator.
Instead of trying to reconstruct whether a parameter pack was declared
inside a lambda (which we can't do correctly in general because we might
not have attached parameters to their declaration contexts yet), track
the set of parameter packs introduced in each live lambda scope, and
require only those parameters to be immediately expanded when they
appear inside that lambda.
In passing, fix incorrect disambiguation of a lambda-expression starting
with an init-capture pack in a braced-init-list. We previously
incorrectly parsed that as a designated initializer.
llvm-svn: 369985
Diffstat (limited to 'clang/lib/Sema/SemaLambda.cpp')
-rw-r--r-- | clang/lib/Sema/SemaLambda.cpp | 15 |
1 files changed, 10 insertions, 5 deletions
diff --git a/clang/lib/Sema/SemaLambda.cpp b/clang/lib/Sema/SemaLambda.cpp index e7c51a3e3d9..a808854ed98 100644 --- a/clang/lib/Sema/SemaLambda.cpp +++ b/clang/lib/Sema/SemaLambda.cpp @@ -824,8 +824,11 @@ VarDecl *Sema::createLambdaInitCaptureVarDecl(SourceLocation Loc, // FIXME: Retain the TypeSourceInfo from buildLambdaInitCaptureInitialization // rather than reconstructing it here. TypeSourceInfo *TSI = Context.getTrivialTypeSourceInfo(InitCaptureType, Loc); - if (auto PETL = TSI->getTypeLoc().getAs<PackExpansionTypeLoc>()) + bool IsInitCapturePack = false; + if (auto PETL = TSI->getTypeLoc().getAs<PackExpansionTypeLoc>()) { PETL.setEllipsisLoc(EllipsisLoc); + IsInitCapturePack = true; + } // Create a dummy variable representing the init-capture. This is not actually // used as a variable, and only exists as a way to name and refer to the @@ -839,6 +842,8 @@ VarDecl *Sema::createLambdaInitCaptureVarDecl(SourceLocation Loc, NewVD->setInitStyle(static_cast<VarDecl::InitializationStyle>(InitStyle)); NewVD->markUsed(Context); NewVD->setInit(Init); + if (NewVD->isParameterPack()) + getCurLambda()->LocalPacks.push_back(NewVD); return NewVD; } @@ -928,12 +933,12 @@ void Sema::ActOnStartOfLambdaDefinition(LambdaIntroducer &Intro, // Check for unexpanded parameter packs in the method type. if (MethodTyInfo->getType()->containsUnexpandedParameterPack()) - ContainsUnexpandedParameterPack = true; + DiagnoseUnexpandedParameterPack(Intro.Range.getBegin(), MethodTyInfo, + UPPC_DeclarationType); } CXXRecordDecl *Class = createLambdaClosureType(Intro.Range, MethodTyInfo, KnownDependent, Intro.Default); - CXXMethodDecl *Method = startLambdaDefinition(Class, Intro.Range, MethodTyInfo, EndLoc, Params, ParamInfo.getDeclSpec().getConstexprSpecifier()); @@ -1053,7 +1058,7 @@ void Sema::ActOnStartOfLambdaDefinition(LambdaIntroducer &Intro, if (C->Init.get()->containsUnexpandedParameterPack() && !C->InitCaptureType.get()->getAs<PackExpansionType>()) - ContainsUnexpandedParameterPack = true; + DiagnoseUnexpandedParameterPack(C->Init.get(), UPPC_Initializer); unsigned InitStyle; switch (C->InitKind) { @@ -1184,7 +1189,7 @@ void Sema::ActOnStartOfLambdaDefinition(LambdaIntroducer &Intro, } finishLambdaExplicitCaptures(LSI); - LSI->ContainsUnexpandedParameterPack = ContainsUnexpandedParameterPack; + LSI->ContainsUnexpandedParameterPack |= ContainsUnexpandedParameterPack; // Add lambda parameters into scope. addLambdaParameters(Intro.Captures, Method, CurScope); |