[clang] 98062d8 - Revert "[Clang] Add captures to the instantiation scope of lambda call operators"
Corentin Jabot via cfe-commits
cfe-commits at lists.llvm.org
Thu Sep 7 00:51:41 PDT 2023
Author: Corentin Jabot
Date: 2023-09-07T09:50:25+02:00
New Revision: 98062d8fefbd3539a63e7e6a85ff12a41543357c
URL: https://github.com/llvm/llvm-project/commit/98062d8fefbd3539a63e7e6a85ff12a41543357c
DIFF: https://github.com/llvm/llvm-project/commit/98062d8fefbd3539a63e7e6a85ff12a41543357c.diff
LOG: Revert "[Clang] Add captures to the instantiation scope of lambda call operators"
The change causes some libcxx regressions
This reverts commit eaf725bc9371a6699902d67d97662caaa3332799.
Added:
Modified:
clang/docs/ReleaseNotes.rst
clang/include/clang/Sema/Sema.h
clang/lib/Sema/SemaConcept.cpp
clang/lib/Sema/SemaDecl.cpp
clang/lib/Sema/SemaLambda.cpp
clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
clang/lib/Sema/TreeTransform.h
clang/test/SemaCXX/lambda-capture-type-deduction.cpp
Removed:
################################################################################
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 5b2a6349a5b15b..acce35e231e714 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -268,11 +268,6 @@ Bug Fixes to C++ Support
- Fix crash when parsing the requires clause of some generic lambdas.
(`#64689 <https://github.com/llvm/llvm-project/issues/64689>`_)
-- Fix crash when the trailing return type of a generic and dependent
- lambda refers to an init-capture.
- (`#65067 <https://github.com/llvm/llvm-project/issues/65067>`_) and
- (`#63675 <https://github.com/llvm/llvm-project/issues/63675>`_).
-
Bug Fixes to AST Handling
^^^^^^^^^^^^^^^^^^^^^^^^^
- Fixed an import failure of recursive friend class template.
diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index 4fd0e6bd5982a7..5fdca93c66ab5c 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -7352,14 +7352,6 @@ class Sema final {
sema::LambdaScopeInfo *RebuildLambdaScopeInfo(CXXMethodDecl *CallOperator);
- class LambdaScopeForCallOperatorInstantiationRAII
- : private FunctionScopeRAII {
- public:
- LambdaScopeForCallOperatorInstantiationRAII(
- Sema &SemasRef, FunctionDecl *FD, MultiLevelTemplateArgumentList MLTAL,
- LocalInstantiationScope &Scope);
- };
-
/// Check whether the given expression is a valid constraint expression.
/// A diagnostic is emitted if it is not, false is returned, and
/// PossibleNonPrimary will be set to true if the failure might be due to a
diff --git a/clang/lib/Sema/SemaConcept.cpp b/clang/lib/Sema/SemaConcept.cpp
index d1fa8e7831225b..fa3dadf68229ee 100644
--- a/clang/lib/Sema/SemaConcept.cpp
+++ b/clang/lib/Sema/SemaConcept.cpp
@@ -600,6 +600,11 @@ bool Sema::SetupConstraintScope(
if (addInstantiatedParametersToScope(FD, FromMemTempl->getTemplatedDecl(),
Scope, MLTAL))
return true;
+ // Make sure the captures are also added to the instantiation scope.
+ if (isLambdaCallOperator(FD) &&
+ addInstantiatedCapturesToScope(FD, FromMemTempl->getTemplatedDecl(),
+ Scope, MLTAL))
+ return true;
}
return false;
@@ -624,6 +629,11 @@ bool Sema::SetupConstraintScope(
// child-function.
if (addInstantiatedParametersToScope(FD, InstantiatedFrom, Scope, MLTAL))
return true;
+
+ // Make sure the captures are also added to the instantiation scope.
+ if (isLambdaCallOperator(FD) &&
+ addInstantiatedCapturesToScope(FD, InstantiatedFrom, Scope, MLTAL))
+ return true;
}
return false;
@@ -702,8 +712,20 @@ bool Sema::CheckFunctionConstraints(const FunctionDecl *FD,
}
CXXThisScopeRAII ThisScope(*this, Record, ThisQuals, Record != nullptr);
- LambdaScopeForCallOperatorInstantiationRAII LambdaScope(
- *this, const_cast<FunctionDecl *>(FD), *MLTAL, Scope);
+ // When checking the constraints of a lambda, we need to restore a
+ // LambdaScopeInfo populated with correct capture information so that the type
+ // of a variable referring to a capture is correctly const-adjusted.
+ FunctionScopeRAII FuncScope(*this);
+ if (isLambdaCallOperator(FD)) {
+ LambdaScopeInfo *LSI = RebuildLambdaScopeInfo(
+ const_cast<CXXMethodDecl *>(cast<CXXMethodDecl>(FD)));
+ // Constraints are checked from the parent context of the lambda, so we set
+ // AfterParameterList to false, so that `tryCaptureVariable` finds
+ // explicit captures in the appropriate context.
+ LSI->AfterParameterList = false;
+ } else {
+ FuncScope.disable();
+ }
return CheckConstraintSatisfaction(
FD, {FD->getTrailingRequiresClause()}, *MLTAL,
@@ -891,10 +913,15 @@ bool Sema::CheckInstantiatedFunctionTemplateConstraints(
ThisQuals = Method->getMethodQualifiers();
Record = Method->getParent();
}
-
CXXThisScopeRAII ThisScope(*this, Record, ThisQuals, Record != nullptr);
- LambdaScopeForCallOperatorInstantiationRAII LambdaScope(
- *this, const_cast<FunctionDecl *>(Decl), *MLTAL, Scope);
+ FunctionScopeRAII FuncScope(*this);
+
+ if (isLambdaCallOperator(Decl)) {
+ LambdaScopeInfo *LSI = RebuildLambdaScopeInfo(cast<CXXMethodDecl>(Decl));
+ LSI->AfterParameterList = false;
+ } else {
+ FuncScope.disable();
+ }
llvm::SmallVector<Expr *, 1> Converted;
return CheckConstraintSatisfaction(Template, TemplateAC, Converted, *MLTAL,
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index d6e090ee496eb3..d94366dac102a2 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -15380,10 +15380,6 @@ LambdaScopeInfo *Sema::RebuildLambdaScopeInfo(CXXMethodDecl *CallOperator) {
LSI->CallOperator = CallOperator;
LSI->Lambda = LambdaClass;
LSI->ReturnType = CallOperator->getReturnType();
- // This function in calls in situation where the context of the call operator
- // is not entered, so we set AfterParameterList to false, so that
- // `tryCaptureVariable` finds explicit captures in the appropriate context.
- LSI->AfterParameterList = false;
const LambdaCaptureDefault LCD = LambdaClass->getLambdaCaptureDefault();
if (LCD == LCD_None)
diff --git a/clang/lib/Sema/SemaLambda.cpp b/clang/lib/Sema/SemaLambda.cpp
index 1702ddb3ee0fbf..5256d91a19a0d0 100644
--- a/clang/lib/Sema/SemaLambda.cpp
+++ b/clang/lib/Sema/SemaLambda.cpp
@@ -20,7 +20,6 @@
#include "clang/Sema/ScopeInfo.h"
#include "clang/Sema/SemaInternal.h"
#include "clang/Sema/SemaLambda.h"
-#include "clang/Sema/Template.h"
#include "llvm/ADT/STLExtras.h"
#include <optional>
using namespace clang;
@@ -2255,34 +2254,3 @@ ExprResult Sema::BuildBlockForLambdaConversion(SourceLocation CurrentLocation,
return BuildBlock;
}
-
-Sema::LambdaScopeForCallOperatorInstantiationRAII::
- LambdaScopeForCallOperatorInstantiationRAII(
- Sema &SemasRef, FunctionDecl *FD, MultiLevelTemplateArgumentList MLTAL,
- LocalInstantiationScope &Scope)
- : FunctionScopeRAII(SemasRef) {
- if (!isLambdaCallOperator(FD)) {
- FunctionScopeRAII::disable();
- return;
- }
-
- if (FD->isTemplateInstantiation() && FD->getPrimaryTemplate()) {
- FunctionTemplateDecl *PrimaryTemplate = FD->getPrimaryTemplate();
- if (const auto *FromMemTempl =
- PrimaryTemplate->getInstantiatedFromMemberTemplate()) {
- SemasRef.addInstantiatedCapturesToScope(
- FD, FromMemTempl->getTemplatedDecl(), Scope, MLTAL);
- }
- }
-
- else if (FD->getTemplatedKind() == FunctionDecl::TK_MemberSpecialization ||
- FD->getTemplatedKind() == FunctionDecl::TK_DependentNonTemplate) {
- FunctionDecl *InstantiatedFrom =
- FD->getTemplatedKind() == FunctionDecl::TK_MemberSpecialization
- ? FD->getInstantiatedFromMemberFunction()
- : FD->getInstantiatedFromDecl();
- SemasRef.addInstantiatedCapturesToScope(FD, InstantiatedFrom, Scope, MLTAL);
- }
-
- SemasRef.RebuildLambdaScopeInfo(cast<CXXMethodDecl>(FD));
-}
diff --git a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
index 37a7d6204413a3..63f022d5c2ff09 100644
--- a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
+++ b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
@@ -2426,9 +2426,6 @@ Decl *TemplateDeclInstantiator::VisitCXXMethodDecl(
cast<Decl>(Owner)->isDefinedOutsideFunctionOrMethod());
LocalInstantiationScope Scope(SemaRef, MergeWithParentScope);
- Sema::LambdaScopeForCallOperatorInstantiationRAII LambdaScope(
- SemaRef, const_cast<CXXMethodDecl *>(D), TemplateArgs, Scope);
-
// Instantiate enclosing template arguments for friends.
SmallVector<TemplateParameterList *, 4> TempParamLists;
unsigned NumTempParamLists = 0;
diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h
index a075ade1adb7bb..7323140bc336bc 100644
--- a/clang/lib/Sema/TreeTransform.h
+++ b/clang/lib/Sema/TreeTransform.h
@@ -12325,7 +12325,7 @@ TreeTransform<Derived>::TransformCXXNullPtrLiteralExpr(
template<typename Derived>
ExprResult
TreeTransform<Derived>::TransformCXXThisExpr(CXXThisExpr *E) {
- QualType T = getDerived().TransformType(E->getType());
+ QualType T = getSema().getCurrentThisType();
if (!getDerived().AlwaysRebuild() && T == E->getType()) {
// Mark it referenced in the new context regardless.
diff --git a/clang/test/SemaCXX/lambda-capture-type-deduction.cpp b/clang/test/SemaCXX/lambda-capture-type-deduction.cpp
index 7bf36a6a9cab73..9855122c962722 100644
--- a/clang/test/SemaCXX/lambda-capture-type-deduction.cpp
+++ b/clang/test/SemaCXX/lambda-capture-type-deduction.cpp
@@ -260,40 +260,3 @@ void f(int) {
void test() { f<int>(0); }
}
-
-namespace GH65067 {
-
-template <typename> class a {
-public:
- template <typename b> void c(b f) { d<int>(f)(0); }
- template <typename, typename b> auto d(b f) {
- return [f = f](auto arg) -> a<decltype(f(arg))> { return {}; };
- }
-};
-a<void> e;
-auto fn1() {
- e.c([](int) {});
-}
-
-}
-
-namespace GH63675 {
-
-template <class _Tp> _Tp __declval();
-struct __get_tag {
- template <class _Tag> void operator()(_Tag);
-};
-template <class _ImplFn> struct __basic_sender {
- using __tag_t = decltype(__declval<_ImplFn>()(__declval<__get_tag>()));
- _ImplFn __impl_;
-};
-auto __make_basic_sender = []<class... _Children>(
- _Children... __children) {
- return __basic_sender{[... __children = __children]<class _Fun>(
- _Fun __fun) -> decltype(__fun(__children...)) {}};
-};
-void __trans_tmp_1() {
- __make_basic_sender(__trans_tmp_1);
-}
-
-}
More information about the cfe-commits
mailing list