comex created this revision. comex added reviewers: rsmith, faisalv, Mordante. Herald added a project: clang. Herald added a subscriber: cfe-commits.
When first parsing a lambda expression, `BuildDeclRefExpr` is called on the parameter declarations with the lambda scope already pushed. But when transforming a lambda expression as part of instantiating an outer template, `BuildDeclRefExpr` is called again without the scope pushed. This causes `tryCaptureVariable` to get confused when a lambda parameter references an earlier parameter, e.g.: [](auto c, int x = sizeof(decltype(c))) {} Fix this by moving up the call to `PushLambdaScope` in `TreeTransform::TransformLambdaExpr` to match `Parser::ParseLambdaExpressionAfterIntroducer`. (Note: I do not have commit access.) Repository: rC Clang https://reviews.llvm.org/D66067 Files: clang/lib/Sema/TreeTransform.h clang/test/SemaTemplate/default-arguments-cxx0x.cpp Index: clang/test/SemaTemplate/default-arguments-cxx0x.cpp =================================================================== --- clang/test/SemaTemplate/default-arguments-cxx0x.cpp +++ clang/test/SemaTemplate/default-arguments-cxx0x.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -fsyntax-only -std=c++11 -verify %s +// RUN: %clang_cc1 -fsyntax-only -std=c++14 -verify %s // expected-no-diagnostics // Test default template arguments for function templates. @@ -114,3 +114,13 @@ S<int> _a{}; }; } + +namespace lambda { +template <class T> +void bar() { + (void) [](auto c, int x = sizeof(decltype(c))) {}; +} +void foo() { + bar<int>(); +} +} // namespace lambda Index: clang/lib/Sema/TreeTransform.h =================================================================== --- clang/lib/Sema/TreeTransform.h +++ clang/lib/Sema/TreeTransform.h @@ -11318,6 +11318,10 @@ } } + LambdaScopeInfo *LSI = getSema().PushLambdaScope(); + Sema::FunctionScopeRAII FuncScopeCleanup(getSema()); + LSI->GLTemplateParameterList = TPL; + // Transform the template parameters, and add them to the current // instantiation scope. The null case is handled correctly. auto TPL = getDerived().TransformTemplateParameterList( @@ -11348,10 +11352,6 @@ NewCallOpType); } - LambdaScopeInfo *LSI = getSema().PushLambdaScope(); - Sema::FunctionScopeRAII FuncScopeCleanup(getSema()); - LSI->GLTemplateParameterList = TPL; - // Create the local class that will describe the lambda. CXXRecordDecl *OldClass = E->getLambdaClass(); CXXRecordDecl *Class
Index: clang/test/SemaTemplate/default-arguments-cxx0x.cpp =================================================================== --- clang/test/SemaTemplate/default-arguments-cxx0x.cpp +++ clang/test/SemaTemplate/default-arguments-cxx0x.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -fsyntax-only -std=c++11 -verify %s +// RUN: %clang_cc1 -fsyntax-only -std=c++14 -verify %s // expected-no-diagnostics // Test default template arguments for function templates. @@ -114,3 +114,13 @@ S<int> _a{}; }; } + +namespace lambda { +template <class T> +void bar() { + (void) [](auto c, int x = sizeof(decltype(c))) {}; +} +void foo() { + bar<int>(); +} +} // namespace lambda Index: clang/lib/Sema/TreeTransform.h =================================================================== --- clang/lib/Sema/TreeTransform.h +++ clang/lib/Sema/TreeTransform.h @@ -11318,6 +11318,10 @@ } } + LambdaScopeInfo *LSI = getSema().PushLambdaScope(); + Sema::FunctionScopeRAII FuncScopeCleanup(getSema()); + LSI->GLTemplateParameterList = TPL; + // Transform the template parameters, and add them to the current // instantiation scope. The null case is handled correctly. auto TPL = getDerived().TransformTemplateParameterList( @@ -11348,10 +11352,6 @@ NewCallOpType); } - LambdaScopeInfo *LSI = getSema().PushLambdaScope(); - Sema::FunctionScopeRAII FuncScopeCleanup(getSema()); - LSI->GLTemplateParameterList = TPL; - // Create the local class that will describe the lambda. CXXRecordDecl *OldClass = E->getLambdaClass(); CXXRecordDecl *Class
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits