This revision was automatically updated to reflect the committed changes.
Closed by commit rG61d1cce2f835: PR45881: Properly use CXXThisOverride for
templated lambda (authored by ychen).
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D102531/new/
https://reviews.llvm.org/D102531
Files:
clang/lib/Sema/SemaExprCXX.cpp
clang/lib/Sema/SemaTemplate.cpp
clang/lib/Sema/SemaTemplateDeduction.cpp
clang/test/SemaCXX/cxx1z-lambda-star-this.cpp
clang/test/SemaCXX/cxx20-lambda-decltype-this.cpp
Index: clang/test/SemaCXX/cxx20-lambda-decltype-this.cpp
===================================================================
--- /dev/null
+++ 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
Index: clang/test/SemaCXX/cxx1z-lambda-star-this.cpp
===================================================================
--- clang/test/SemaCXX/cxx1z-lambda-star-this.cpp
+++ clang/test/SemaCXX/cxx1z-lambda-star-this.cpp
@@ -298,3 +298,13 @@
} // 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
Index: clang/lib/Sema/SemaTemplateDeduction.cpp
===================================================================
--- clang/lib/Sema/SemaTemplateDeduction.cpp
+++ clang/lib/Sema/SemaTemplateDeduction.cpp
@@ -2858,9 +2858,24 @@
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()) {
Index: clang/lib/Sema/SemaTemplate.cpp
===================================================================
--- clang/lib/Sema/SemaTemplate.cpp
+++ clang/lib/Sema/SemaTemplate.cpp
@@ -5110,7 +5110,11 @@
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());
Index: clang/lib/Sema/SemaExprCXX.cpp
===================================================================
--- clang/lib/Sema/SemaExprCXX.cpp
+++ clang/lib/Sema/SemaExprCXX.cpp
@@ -1137,11 +1137,10 @@
}
}
- // 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 "
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits