Author: Yuanfang Chen Date: 2021-09-07T17:02:24-07:00 New Revision: 61d1cce2f83571c00f76144d42a2dea2cb3ab1ca
URL: https://github.com/llvm/llvm-project/commit/61d1cce2f83571c00f76144d42a2dea2cb3ab1ca DIFF: https://github.com/llvm/llvm-project/commit/61d1cce2f83571c00f76144d42a2dea2cb3ab1ca.diff LOG: PR45881: Properly use CXXThisOverride for templated lambda - `this` used in lambda expression parameter declarations needs no capture. - Set up CXXThisOverride for default template arguments of a lambda. A similar fix to this is c3d2ebb60f604. Reviewed By: aaron.ballman Differential Revision: https://reviews.llvm.org/D102531 Added: clang/test/SemaCXX/cxx20-lambda-decltype-this.cpp Modified: clang/lib/Sema/SemaExprCXX.cpp clang/lib/Sema/SemaTemplate.cpp clang/lib/Sema/SemaTemplateDeduction.cpp clang/test/SemaCXX/cxx1z-lambda-star-this.cpp Removed: ################################################################################ diff --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp index ba2e17c4a6313..e30e1bb7df786 100644 --- a/clang/lib/Sema/SemaExprCXX.cpp +++ b/clang/lib/Sema/SemaExprCXX.cpp @@ -1137,11 +1137,10 @@ static QualType adjustCVQualifiersForCXXThisWithinLambda( } } - // 2) We've run out of ScopeInfos but check if CurDC is a lambda (which can - // happen during instantiation of its nested generic lambda call operator) - if (isLambdaCallOperator(CurDC)) { - assert(CurLSI && "While computing 'this' capture-type for a generic " - "lambda, we must have a corresponding LambdaScopeInfo"); + // 2) We've run out of ScopeInfos but check 1. if CurDC is a lambda (which + // can happen during instantiation of its nested generic lambda call + // operator); 2. if we're in a lambda scope (lambda body). + if (CurLSI && isLambdaCallOperator(CurDC)) { assert(isGenericLambdaCallOperatorSpecialization(CurLSI->CallOperator) && "While computing 'this' capture-type for a generic lambda, when we " "run out of enclosing LSI's, yet the enclosing DC is a " diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp index 5d26f2d2c11a5..6682b17f4e146 100644 --- a/clang/lib/Sema/SemaTemplate.cpp +++ b/clang/lib/Sema/SemaTemplate.cpp @@ -5110,7 +5110,11 @@ SubstDefaultTemplateArgument(Sema &SemaRef, for (unsigned i = 0, e = Param->getDepth(); i != e; ++i) TemplateArgLists.addOuterTemplateArguments(None); - Sema::ContextRAII SavedContext(SemaRef, Template->getDeclContext()); + bool ForLambdaCallOperator = false; + if (const auto *Rec = dyn_cast<CXXRecordDecl>(Template->getDeclContext())) + ForLambdaCallOperator = Rec->isLambda(); + Sema::ContextRAII SavedContext(SemaRef, Template->getDeclContext(), + !ForLambdaCallOperator); ArgType = SemaRef.SubstType(ArgType, TemplateArgLists, Param->getDefaultArgumentLoc(), Param->getDeclName()); diff --git a/clang/lib/Sema/SemaTemplateDeduction.cpp b/clang/lib/Sema/SemaTemplateDeduction.cpp index 5d93a17922269..f0a9e820c028c 100644 --- a/clang/lib/Sema/SemaTemplateDeduction.cpp +++ b/clang/lib/Sema/SemaTemplateDeduction.cpp @@ -2858,9 +2858,24 @@ static Sema::TemplateDeductionResult ConvertDeducedTemplateArguments( return Sema::TDK_Incomplete; } - TemplateArgumentLoc DefArg = S.SubstDefaultTemplateArgumentIfAvailable( - TD, TD->getLocation(), TD->getSourceRange().getEnd(), Param, Builder, - HasDefaultArg); + TemplateArgumentLoc DefArg; + { + Qualifiers ThisTypeQuals; + CXXRecordDecl *ThisContext = nullptr; + if (auto *Rec = dyn_cast<CXXRecordDecl>(TD->getDeclContext())) + if (Rec->isLambda()) + if (auto *Method = dyn_cast<CXXMethodDecl>(Rec->getDeclContext())) { + ThisContext = Method->getParent(); + ThisTypeQuals = Method->getMethodQualifiers(); + } + + Sema::CXXThisScopeRAII ThisScope(S, ThisContext, ThisTypeQuals, + S.getLangOpts().CPlusPlus17); + + DefArg = S.SubstDefaultTemplateArgumentIfAvailable( + TD, TD->getLocation(), TD->getSourceRange().getEnd(), Param, Builder, + HasDefaultArg); + } // If there was no default argument, deduction is incomplete. if (DefArg.getArgument().isNull()) { diff --git a/clang/test/SemaCXX/cxx1z-lambda-star-this.cpp b/clang/test/SemaCXX/cxx1z-lambda-star-this.cpp index 2426e8f5a207f..5a471fd6b6940 100644 --- a/clang/test/SemaCXX/cxx1z-lambda-star-this.cpp +++ b/clang/test/SemaCXX/cxx1z-lambda-star-this.cpp @@ -298,3 +298,13 @@ class A { } // namespace PR32831 +namespace PR45881 { +struct A { + void f(); +}; +int id(A*); +void A::f() { + auto z = [*this](auto z2, decltype(z2(this)) z3){}; + z(id,3); +} +} // namespace PR45881 diff --git a/clang/test/SemaCXX/cxx20-lambda-decltype-this.cpp b/clang/test/SemaCXX/cxx20-lambda-decltype-this.cpp new file mode 100644 index 0000000000000..161a2bcb25d72 --- /dev/null +++ b/clang/test/SemaCXX/cxx20-lambda-decltype-this.cpp @@ -0,0 +1,31 @@ +// RUN: %clang_cc1 -std=c++2a -fsyntax-only -emit-llvm-only %s +// RUN: %clang_cc1 -std=c++2a -fsyntax-only -fdelayed-template-parsing %s +// RUN: %clang_cc1 -std=c++2a -fsyntax-only -fms-extensions %s +// RUN: %clang_cc1 -std=c++2a -fsyntax-only -fdelayed-template-parsing -fms-extensions %s + +namespace PR45881 { +struct A { + void f(); +}; +int id(A*); +void A::f() { + auto z = [*this](auto z2, decltype(z2(this)) z3){}; + z(id,3); +} + +struct B { + void f(); +}; +void B::f() { + auto z = []<typename TT, typename TTT=decltype(TT()(this))>(){return 0;}; + z.template operator()<int(*)(B*)>(); +} + +struct C { + void f(); +}; +void C::f() { + auto z = []<typename TT, decltype(TT()(this)) n>(){return 0;}; + z.template operator()<int(*)(C*), 8>(); +} +} // namespace PR45881 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits