From nobody Mon Dec 11 17:42:36 2023 X-Original-To: dev-commits-ports-all@mlmmj.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mlmmj.nyi.freebsd.org (Postfix) with ESMTP id 4Sppws1Tsbz53t0k; Mon, 11 Dec 2023 17:42:37 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "R3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4Sppws1Kdlz4S9V; Mon, 11 Dec 2023 17:42:37 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1702316557; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=En34gpgQr3QtJwWU2cLNbNUjJe4LaSmWLXT89wRrD0w=; b=r+sQnlHWUrC/+T4eV1djG0rN7mklEs5s4FhP06OX1+kKkjQWxfo64SdrxETa+EHiV256Go 98CkUHgHyKuj22IVAW8yRY8UB3cmZ8xmsDdY7L+xT3kZ8id91KeK55nX2bJ51q6cpS9Ua+ 3wzn0OVngqepeO0+nUv4guktor+vRkUs5Paid6cq23i5+rDAxC/qYjS2f+Wkj1txXoz5XI cMG/M+ZcwX3lQCBj0b7HHak1wA2GbFY0qetS7p1T5TddGctzMtRNksux1cceHhPh3aWVII 4vyBI4+bpS5iiBf4gFOpnY0KRGjQtk+V/7OJbk1gINC0lPlzLfv5/75KFq8a0g== ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1702316557; a=rsa-sha256; cv=none; b=vaDr1FfosGxpIxrOH5J3tKmkw0LzuzzUQVuXuORXMG1d1KIDmqdSIy/qgxku0JBQ4i9gQj zsrxWabhP7/efxXMph4cBhtOicFFCQQ4+w2iBROP63hzzWQ2XLeiyOB1jhlW2G/okwSH1e RD21vuqcweMydkzjcslX5RV4ASbqQQki2c7MLv0n9GO6YAPAzmN+OvSmNUZSYSF27xtQoe jGP5FTSyOuh1lo6qtAYK2TT7nPmTW6bMTEyGCn5u5YX+fLARKyDTY+L/z3bXGi5hiEwrtY aKNFFS3lp6AVRUhgiNIPq4gBVGLlP75aFVQps+wnRS2rbYiwAqb4qVBb2iFDgg== ARC-Authentication-Results: i=1; mx1.freebsd.org; none ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1702316557; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=En34gpgQr3QtJwWU2cLNbNUjJe4LaSmWLXT89wRrD0w=; b=qrucIQD8tRjopmQNLpdXERmFecvOJTdL6l69vmalQhW/Lfd1EMSRieH97cbpvsNrmZFtpB 1VDPu/u+XGbl5/UwBY1WVFFRIxdKr4njm7sdd2CECnvX5qmGFoJOD75+uF6jo1m3XGXFXp SDL0vb1JH8Z2sDq6rp8Pfpur4jtBDUibphQDvUwz3bxZFn8LbNP+9DoI4swxss2cf5cq1f //WMFi/8fYwz7+EVvk3/czIqm4zAtICi1voE86yd3eYtmlaxphpps2zlNsBCFoZja4swg1 2TWy6JQ9vTvCCGpmtb1bTxF6KKTWeuDs2SOj4JEMRFiMgwbFbnRwzCjOiwZ9qg== Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 4Sppws08jKzgtT; Mon, 11 Dec 2023 17:42:37 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org ([127.0.1.44]) by gitrepo.freebsd.org (8.17.1/8.17.1) with ESMTP id 3BBHgaE1022290; Mon, 11 Dec 2023 17:42:36 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.17.1/8.17.1/Submit) id 3BBHga38022287; Mon, 11 Dec 2023 17:42:36 GMT (envelope-from git) Date: Mon, 11 Dec 2023 17:42:36 GMT Message-Id: <202312111742.3BBHga38022287@gitrepo.freebsd.org> To: ports-committers@FreeBSD.org, dev-commits-ports-all@FreeBSD.org, dev-commits-ports-main@FreeBSD.org From: Brooks Davis Subject: git: 6d4bc09d9ce4 - main - devel/llvm17: merge upstream llvm fixes List-Id: Commit messages for all branches of the ports repository List-Archive: https://lists.freebsd.org/archives/dev-commits-ports-all List-Help: List-Post: List-Subscribe: List-Unsubscribe: Sender: owner-dev-commits-ports-all@freebsd.org X-BeenThere: dev-commits-ports-all@freebsd.org MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: brooks X-Git-Repository: ports X-Git-Refname: refs/heads/main X-Git-Reftype: branch X-Git-Commit: 6d4bc09d9ce42807965de65e0b0739b6308d96b3 Auto-Submitted: auto-generated The branch main has been updated by brooks: URL: https://cgit.FreeBSD.org/ports/commit/?id=6d4bc09d9ce42807965de65e0b0739b6308d96b3 commit 6d4bc09d9ce42807965de65e0b0739b6308d96b3 Author: Brooks Davis AuthorDate: 2023-12-08 23:58:56 +0000 Commit: Brooks Davis CommitDate: 2023-12-11 17:42:26 +0000 devel/llvm17: merge upstream llvm fixes These fixes were merged to the base LLVM compiler: 158f4f30adb4 [Clang] Do not change the type of captured vars when checking lambda constraints 3ed9e9e3ace6 [Clang] Add captures to the instantiation scope of lambda call operators --- devel/llvm17/Makefile | 2 +- devel/llvm17/files/patch-backport-158f4f30adb4 | 211 +++++++++++++++ devel/llvm17/files/patch-backport-3ed9e9e3ace6 | 342 +++++++++++++++++++++++++ 3 files changed, 554 insertions(+), 1 deletion(-) diff --git a/devel/llvm17/Makefile b/devel/llvm17/Makefile index b3b68f775d0f..914dc58793b4 100644 --- a/devel/llvm17/Makefile +++ b/devel/llvm17/Makefile @@ -1,6 +1,6 @@ PORTNAME= llvm DISTVERSION= 17.0.6 -PORTREVISION= 1 +PORTREVISION= 2 CATEGORIES= devel lang MASTER_SITES= https://github.com/llvm/llvm-project/releases/download/llvmorg-${DISTVERSION:S/rc/-rc/}/ \ https://${PRE_}releases.llvm.org/${LLVM_RELEASE}${RCDIR}/ diff --git a/devel/llvm17/files/patch-backport-158f4f30adb4 b/devel/llvm17/files/patch-backport-158f4f30adb4 new file mode 100644 index 000000000000..c7b31bdab7e6 --- /dev/null +++ b/devel/llvm17/files/patch-backport-158f4f30adb4 @@ -0,0 +1,211 @@ +commit 158f4f30adb4bfd390057742a32934e4344e8fd3 +Author: Corentin Jabot +Date: Mon Aug 21 18:07:43 2023 +0200 + + [Clang] Do not change the type of captured vars when checking lambda constraints + + When checking the constraint of a lambda, we need to respect the constness + of the call operator when establishing the type of capture variables. + + In D124351, this was done by adding const to the captured variable... + However, that would change the type of the variable outside of the scope + of the lambda, which is clearly not the desired outcome. + + Instead, to ensure const-correctness, we need to populate + a LambdaScopeInfo with the capture variables before checking the + constraints of a generic lambda. + + There is no changelog as I'd like to tentatively propose we backport + this change to RC3 as it is a regression introduced in the Clang 17 + cycle. + + Fixes #61267 + + Reviewed By: aaron.ballman, #clang-language-wg + + Differential Revision: https://reviews.llvm.org/D158433 + +diff --git clang/include/clang/Sema/Sema.h clang/include/clang/Sema/Sema.h +index c992e8763057..807a52886ccb 100644 +--- clang/include/clang/Sema/Sema.h ++++ clang/include/clang/Sema/Sema.h +@@ -7343,6 +7343,8 @@ public: + CXXConversionDecl *Conv, + Expr *Src); + ++ sema::LambdaScopeInfo *RebuildLambdaScopeInfo(CXXMethodDecl *CallOperator); ++ + /// 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 clang/lib/Sema/SemaConcept.cpp clang/lib/Sema/SemaConcept.cpp +index f24b549dd2ef..fa3dadf68229 100644 +--- clang/lib/Sema/SemaConcept.cpp ++++ clang/lib/Sema/SemaConcept.cpp +@@ -13,12 +13,14 @@ + #include "clang/Sema/SemaConcept.h" + #include "TreeTransform.h" + #include "clang/AST/ASTLambda.h" ++#include "clang/AST/DeclCXX.h" + #include "clang/AST/ExprConcepts.h" + #include "clang/AST/RecursiveASTVisitor.h" + #include "clang/Basic/OperatorPrecedence.h" + #include "clang/Sema/EnterExpressionEvaluationContext.h" + #include "clang/Sema/Initialization.h" + #include "clang/Sema/Overload.h" ++#include "clang/Sema/ScopeInfo.h" + #include "clang/Sema/Sema.h" + #include "clang/Sema/SemaDiagnostic.h" + #include "clang/Sema/SemaInternal.h" +@@ -540,11 +542,6 @@ bool Sema::addInstantiatedCapturesToScope( + auto AddSingleCapture = [&](const ValueDecl *CapturedPattern, + unsigned Index) { + ValueDecl *CapturedVar = LambdaClass->getCapture(Index)->getCapturedVar(); +- if (cast(Function)->isConst()) { +- QualType T = CapturedVar->getType(); +- T.addConst(); +- CapturedVar->setType(T); +- } + if (CapturedVar->isInitCapture()) + Scope.InstantiatedLocal(CapturedPattern, CapturedVar); + }; +@@ -714,6 +711,22 @@ bool Sema::CheckFunctionConstraints(const FunctionDecl *FD, + Record = const_cast(Method->getParent()); + } + CXXThisScopeRAII ThisScope(*this, Record, ThisQuals, Record != nullptr); ++ ++ // 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(cast(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, + SourceRange(UsageLoc.isValid() ? UsageLoc : FD->getLocation()), +@@ -902,10 +915,13 @@ bool Sema::CheckInstantiatedFunctionTemplateConstraints( + } + CXXThisScopeRAII ThisScope(*this, Record, ThisQuals, Record != nullptr); + FunctionScopeRAII FuncScope(*this); +- if (isLambdaCallOperator(Decl)) +- PushLambdaScope(); +- else ++ ++ if (isLambdaCallOperator(Decl)) { ++ LambdaScopeInfo *LSI = RebuildLambdaScopeInfo(cast(Decl)); ++ LSI->AfterParameterList = false; ++ } else { + FuncScope.disable(); ++ } + + llvm::SmallVector Converted; + return CheckConstraintSatisfaction(Template, TemplateAC, Converted, *MLTAL, +diff --git clang/lib/Sema/SemaDecl.cpp clang/lib/Sema/SemaDecl.cpp +index 3925e2a7f338..0d5f696bf040 100644 +--- clang/lib/Sema/SemaDecl.cpp ++++ clang/lib/Sema/SemaDecl.cpp +@@ -15289,11 +15289,10 @@ Sema::CheckForFunctionRedefinition(FunctionDecl *FD, + FD->setInvalidDecl(); + } + +-static void RebuildLambdaScopeInfo(CXXMethodDecl *CallOperator, +- Sema &S) { +- CXXRecordDecl *const LambdaClass = CallOperator->getParent(); ++LambdaScopeInfo *Sema::RebuildLambdaScopeInfo(CXXMethodDecl *CallOperator) { ++ CXXRecordDecl *LambdaClass = CallOperator->getParent(); + +- LambdaScopeInfo *LSI = S.PushLambdaScope(); ++ LambdaScopeInfo *LSI = PushLambdaScope(); + LSI->CallOperator = CallOperator; + LSI->Lambda = LambdaClass; + LSI->ReturnType = CallOperator->getReturnType(); +@@ -15317,7 +15316,7 @@ static void RebuildLambdaScopeInfo(CXXMethodDecl *CallOperator, + if (C.capturesVariable()) { + ValueDecl *VD = C.getCapturedVar(); + if (VD->isInitCapture()) +- S.CurrentInstantiationScope->InstantiatedLocal(VD, VD); ++ CurrentInstantiationScope->InstantiatedLocal(VD, VD); + const bool ByRef = C.getCaptureKind() == LCK_ByRef; + LSI->addCapture(VD, /*IsBlock*/false, ByRef, + /*RefersToEnclosingVariableOrCapture*/true, C.getLocation(), +@@ -15334,6 +15333,7 @@ static void RebuildLambdaScopeInfo(CXXMethodDecl *CallOperator, + } + ++I; + } ++ return LSI; + } + + Decl *Sema::ActOnStartOfFunctionDef(Scope *FnBodyScope, Decl *D, +@@ -15437,7 +15437,7 @@ Decl *Sema::ActOnStartOfFunctionDef(Scope *FnBodyScope, Decl *D, + assert(inTemplateInstantiation() && + "There should be an active template instantiation on the stack " + "when instantiating a generic lambda!"); +- RebuildLambdaScopeInfo(cast(D), *this); ++ RebuildLambdaScopeInfo(cast(D)); + } else { + // Enter a new function scope + PushFunctionScope(); +diff --git clang/lib/Sema/SemaExpr.cpp clang/lib/Sema/SemaExpr.cpp +index 34284a8d9381..ac6c3ba6b357 100644 +--- clang/lib/Sema/SemaExpr.cpp ++++ clang/lib/Sema/SemaExpr.cpp +@@ -19722,13 +19722,6 @@ bool Sema::tryCaptureVariable( + FunctionScopesIndex == MaxFunctionScopesIndex && VarDC == DC) + return true; + +- // When evaluating some attributes (like enable_if) we might refer to a +- // function parameter appertaining to the same declaration as that +- // attribute. +- if (const auto *Parm = dyn_cast(Var); +- Parm && Parm->getDeclContext() == DC) +- return true; +- + // Only block literals, captured statements, and lambda expressions can + // capture; other scopes don't work. + DeclContext *ParentDC = +@@ -19756,6 +19749,14 @@ bool Sema::tryCaptureVariable( + CSI->getCapture(Var).markUsed(BuildAndDiagnose); + break; + } ++ ++ // When evaluating some attributes (like enable_if) we might refer to a ++ // function parameter appertaining to the same declaration as that ++ // attribute. ++ if (const auto *Parm = dyn_cast(Var); ++ Parm && Parm->getDeclContext() == DC) ++ return true; ++ + // If we are instantiating a generic lambda call operator body, + // we do not want to capture new variables. What was captured + // during either a lambdas transformation or initial parsing +diff --git clang/test/SemaCXX/lambda-capture-type-deduction.cpp clang/test/SemaCXX/lambda-capture-type-deduction.cpp +index e524d3bc20ab..9855122c9627 100644 +--- clang/test/SemaCXX/lambda-capture-type-deduction.cpp ++++ clang/test/SemaCXX/lambda-capture-type-deduction.cpp +@@ -246,3 +246,17 @@ void check_params_tpl() { + static_assert(is_same); + }; + } ++ ++namespace GH61267 { ++template concept C = true; ++ ++template ++void f(int) { ++ int i; ++ [i](P) {}(0); ++ i = 4; ++} ++ ++void test() { f(0); } ++ ++} diff --git a/devel/llvm17/files/patch-backport-3ed9e9e3ace6 b/devel/llvm17/files/patch-backport-3ed9e9e3ace6 new file mode 100644 index 000000000000..420be920ab90 --- /dev/null +++ b/devel/llvm17/files/patch-backport-3ed9e9e3ace6 @@ -0,0 +1,342 @@ +commit 3ed9e9e3ace6f9ce320cf4e75cffa04a7c7241b5 +Author: Corentin Jabot +Date: Tue Aug 29 19:53:19 2023 +0200 + + [Clang] Add captures to the instantiation scope of lambda call operators + + Like concepts checking, a trailing return type of a lambda + in a dependent context may refer to captures in which case + they may need to be rebuilt, so the map of local decl + should include captures. + + This patch reveal a pre-existing issue. + `this` is always recomputed by TreeTransform. + + `*this` (like all captures) only become `const` + after the parameter list. + + However, if try to recompute the value of `this` (in a parameter) + during template instantiation while determining the type of the call operator, + we will determine it to be const (unless the lambda is mutable). + + There is no good way to know at that point that we are in a parameter + or not, the easiest/best solution is to transform the type of this. + + Note that doing so break a handful of HLSL tests. + So this is a prototype at this point. + + Fixes #65067 + Fixes #63675 + + Reviewed By: erichkeane + + Differential Revision: https://reviews.llvm.org/D159126 + +diff --git clang/docs/ReleaseNotes.rst clang/docs/ReleaseNotes.rst +index 2d0302c399fb..6a3a6bb8ad42 100644 +--- clang/docs/ReleaseNotes.rst ++++ clang/docs/ReleaseNotes.rst +@@ -270,6 +270,11 @@ Bug Fixes to C++ Support + - Fix crash when parsing the requires clause of some generic lambdas. + (`#64689 `_) + ++- Fix crash when the trailing return type of a generic and dependent ++ lambda refers to an init-capture. ++ (`#65067 `_` and ++ `#63675 `_`) ++ + Bug Fixes to AST Handling + ^^^^^^^^^^^^^^^^^^^^^^^^^ + - Fixed an import failure of recursive friend class template. +diff --git clang/include/clang/Sema/Sema.h clang/include/clang/Sema/Sema.h +index 1bb096c667e3..566655818a85 100644 +--- clang/include/clang/Sema/Sema.h ++++ clang/include/clang/Sema/Sema.h +@@ -7365,6 +7365,14 @@ public: + + 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 clang/lib/Sema/SemaConcept.cpp clang/lib/Sema/SemaConcept.cpp +index fa3dadf68229..d1fa8e783122 100644 +--- clang/lib/Sema/SemaConcept.cpp ++++ clang/lib/Sema/SemaConcept.cpp +@@ -600,11 +600,6 @@ 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; +@@ -629,11 +624,6 @@ 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; +@@ -712,20 +702,8 @@ bool Sema::CheckFunctionConstraints(const FunctionDecl *FD, + } + CXXThisScopeRAII ThisScope(*this, Record, ThisQuals, Record != nullptr); + +- // 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(cast(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(); +- } ++ LambdaScopeForCallOperatorInstantiationRAII LambdaScope( ++ *this, const_cast(FD), *MLTAL, Scope); + + return CheckConstraintSatisfaction( + FD, {FD->getTrailingRequiresClause()}, *MLTAL, +@@ -913,15 +891,10 @@ bool Sema::CheckInstantiatedFunctionTemplateConstraints( + ThisQuals = Method->getMethodQualifiers(); + Record = Method->getParent(); + } +- CXXThisScopeRAII ThisScope(*this, Record, ThisQuals, Record != nullptr); +- FunctionScopeRAII FuncScope(*this); + +- if (isLambdaCallOperator(Decl)) { +- LambdaScopeInfo *LSI = RebuildLambdaScopeInfo(cast(Decl)); +- LSI->AfterParameterList = false; +- } else { +- FuncScope.disable(); +- } ++ CXXThisScopeRAII ThisScope(*this, Record, ThisQuals, Record != nullptr); ++ LambdaScopeForCallOperatorInstantiationRAII LambdaScope( ++ *this, const_cast(Decl), *MLTAL, Scope); + + llvm::SmallVector Converted; + return CheckConstraintSatisfaction(Template, TemplateAC, Converted, *MLTAL, +diff --git clang/lib/Sema/SemaDecl.cpp clang/lib/Sema/SemaDecl.cpp +index 027c6c3e4222..998060542609 100644 +--- clang/lib/Sema/SemaDecl.cpp ++++ clang/lib/Sema/SemaDecl.cpp +@@ -15382,6 +15382,10 @@ 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 clang/lib/Sema/SemaLambda.cpp clang/lib/Sema/SemaLambda.cpp +index 5256d91a19a0..1702ddb3ee0f 100644 +--- clang/lib/Sema/SemaLambda.cpp ++++ clang/lib/Sema/SemaLambda.cpp +@@ -20,6 +20,7 @@ + #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 + using namespace clang; +@@ -2254,3 +2255,34 @@ 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(FD)); ++} +diff --git clang/lib/Sema/SemaTemplateInstantiateDecl.cpp clang/lib/Sema/SemaTemplateInstantiateDecl.cpp +index 63f022d5c2ff..37a7d6204413 100644 +--- clang/lib/Sema/SemaTemplateInstantiateDecl.cpp ++++ clang/lib/Sema/SemaTemplateInstantiateDecl.cpp +@@ -2426,6 +2426,9 @@ Decl *TemplateDeclInstantiator::VisitCXXMethodDecl( + cast(Owner)->isDefinedOutsideFunctionOrMethod()); + LocalInstantiationScope Scope(SemaRef, MergeWithParentScope); + ++ Sema::LambdaScopeForCallOperatorInstantiationRAII LambdaScope( ++ SemaRef, const_cast(D), TemplateArgs, Scope); ++ + // Instantiate enclosing template arguments for friends. + SmallVector TempParamLists; + unsigned NumTempParamLists = 0; +diff --git clang/lib/Sema/TreeTransform.h clang/lib/Sema/TreeTransform.h +index 7323140bc336..603a23275889 100644 +--- clang/lib/Sema/TreeTransform.h ++++ clang/lib/Sema/TreeTransform.h +@@ -12325,7 +12325,16 @@ TreeTransform::TransformCXXNullPtrLiteralExpr( + template + ExprResult + TreeTransform::TransformCXXThisExpr(CXXThisExpr *E) { +- QualType T = getSema().getCurrentThisType(); ++ ++ // In lambdas, the qualifiers of the type depends of where in ++ // the call operator `this` appear, and we do not have a good way to ++ // rebuild this information, so we transform the type. ++ // ++ // In other contexts, the type of `this` may be overrided ++ // for type deduction, so we need to recompute it. ++ QualType T = getSema().getCurLambda() ? ++ getDerived().TransformType(E->getType()) ++ : getSema().getCurrentThisType(); + + if (!getDerived().AlwaysRebuild() && T == E->getType()) { + // Mark it referenced in the new context regardless. +diff --git clang/test/SemaCXX/lambda-capture-type-deduction.cpp clang/test/SemaCXX/lambda-capture-type-deduction.cpp +index 9855122c9627..7bf36a6a9cab 100644 +--- clang/test/SemaCXX/lambda-capture-type-deduction.cpp ++++ clang/test/SemaCXX/lambda-capture-type-deduction.cpp +@@ -260,3 +260,40 @@ void f(int) { + void test() { f(0); } + + } ++ ++namespace GH65067 { ++ ++template class a { ++public: ++ template void c(b f) { d(f)(0); } ++ template auto d(b f) { ++ return [f = f](auto arg) -> a { return {}; }; ++ } ++}; ++a e; ++auto fn1() { ++ e.c([](int) {}); ++} ++ ++} ++ ++namespace GH63675 { ++ ++template _Tp __declval(); ++struct __get_tag { ++ template void operator()(_Tag); ++}; ++template struct __basic_sender { ++ using __tag_t = decltype(__declval<_ImplFn>()(__declval<__get_tag>())); ++ _ImplFn __impl_; ++}; ++auto __make_basic_sender = []( ++ _Children... __children) { ++ return __basic_sender{[... __children = __children]( ++ _Fun __fun) -> decltype(__fun(__children...)) {}}; ++}; ++void __trans_tmp_1() { ++ __make_basic_sender(__trans_tmp_1); ++} ++ ++} +diff --git clang/test/SemaCXX/this-type-deduction-concept.cpp clang/test/SemaCXX/this-type-deduction-concept.cpp +new file mode 100644 +index 000000000000..a0c1f605ccef +--- /dev/null ++++ clang/test/SemaCXX/this-type-deduction-concept.cpp +@@ -0,0 +1,54 @@ ++ ++// This test case came up in the review of ++// https://reviews.llvm.org/D159126 ++// when transforming `this` within a ++// requires expression, we need to make sure ++// the type of this (and its qualifiers) is respected. ++namespace D159126 { ++ ++template ++concept __member_begin = requires(_Tp __t) { ++ __t.begin(); ++}; ++ ++struct { ++ template ++ requires __member_begin<_Tp> ++ auto operator()(_Tp &&) {} ++} inline begin; ++ ++template ++concept range = requires { ++ begin; ++}; ++ ++template ++concept __can_compare_begin = requires(_Tp __t) { ++ begin(__t); ++}; ++ ++struct { ++ template <__can_compare_begin _Tp> void operator()(_Tp &&); ++} empty; ++ ++template struct owning_view { ++ _Rp __r_; ++public: ++ void empty() const requires requires { empty(__r_); }; ++}; ++ ++template ++concept HasEmpty = requires(T t) { ++ t.empty(); ++}; ++ ++struct ComparableIters { ++ void begin(); ++}; ++ ++static_assert(HasEmpty>); ++static_assert(HasEmpty>); ++static_assert(!HasEmpty>); ++static_assert(!HasEmpty>); ++ ++}