From b26bc34e3a77cab8b2773c69f27198f77f993090 Mon Sep 17 00:00:00 2001 From: Richard Smith Date: Mon, 26 Aug 2019 22:51:28 +0000 Subject: 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 --- clang/lib/Sema/SemaLambda.cpp | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) (limited to 'clang/lib/Sema/SemaLambda.cpp') 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()) + bool IsInitCapturePack = false; + if (auto PETL = TSI->getTypeLoc().getAs()) { 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(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()) - 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); -- cgit v1.2.3