Skip to content

Conversation

@Backl1ght
Copy link
Member

@Backl1ght Backl1ght commented Oct 25, 2025

Fixes #163837

We should return true here

if (IsInScopeDeclarationContext &&
FunctionScopesIndex == MaxFunctionScopesIndex && VarDC == DC)
return true;
, but we won't currently due to mismatch of VarDC and DC while DC is instantiated version of VarDC.

The reason of mismatch is that FindInstantiatedDecl to result returns uninstantiated version incorrectly here

if (!ParentDependsOnArgs)
return D;

We should return instantiated version if we can find one.

@github-actions
Copy link

github-actions bot commented Oct 25, 2025

✅ With the latest revision this PR passed the C/C++ code formatter.

@Backl1ght Backl1ght changed the title [WIP] fix gh163837 [clang] Fix a wrong diagnostic about a local variable inside a lambda in unevaluated contexts need capture Oct 25, 2025
@Backl1ght Backl1ght changed the title [clang] Fix a wrong diagnostic about a local variable inside a lambda in unevaluated contexts need capture [Clang] Fix a wrong diagnostic about a local variable inside a lambda in unevaluated contexts need capture Oct 25, 2025
@Backl1ght Backl1ght marked this pull request as ready for review October 25, 2025 15:39
@llvmbot llvmbot added clang Clang issues not falling into any other category clang:frontend Language frontend issues, e.g. anything involving "Sema" labels Oct 25, 2025
@llvmbot
Copy link
Member

llvmbot commented Oct 25, 2025

@llvm/pr-subscribers-clang

Author: Zhikai Zeng (Backl1ght)

Changes

Fixes #163837

We should return true here

if (IsInScopeDeclarationContext &&
FunctionScopesIndex == MaxFunctionScopesIndex && VarDC == DC)
return true;
, but we won't currently due to mismatch of VarDC and DC while DC is instantiated version of VarDC.

The reason of mismatch is that FindInstantiatedDecl to result returns uninstantiated version incorrectly here

if (!ParentDependsOnArgs)
return D;

We should return instantiated version if we can find one.


Full diff: https://github.com/llvm/llvm-project/pull/165098.diff

3 Files Affected:

  • (modified) clang/docs/ReleaseNotes.rst (+2)
  • (modified) clang/lib/Sema/SemaTemplateInstantiateDecl.cpp (+8-1)
  • (modified) clang/test/SemaCXX/lambda-unevaluated.cpp (+19)
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index e6e33e7a9a280..dd7206ba2b253 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -429,6 +429,8 @@ Bug Fixes in This Version - Fixed a failed assertion with empty filename arguments in ``__has_embed``. (#GH159898) - Fixed a failed assertion with empty filename in ``#embed`` directive. (#GH162951) - Fixed a crash triggered by unterminated ``__has_embed``. (#GH162953) +- Fixed a wrong diagnostic about a local variable inside a lambda in unevaluated + contexts need capture. (#GH163837) Bug Fixes to Compiler Builtins ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp index 28925cca8f956..439a5317f06f1 100644 --- a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp +++ b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp @@ -7061,8 +7061,15 @@ NamedDecl *Sema::FindInstantiatedDecl(SourceLocation Loc, NamedDecl *D, // anonymous unions in class templates). } - if (!ParentDependsOnArgs) + if (!ParentDependsOnArgs) { + if (auto Found = + CurrentInstantiationScope + ? CurrentInstantiationScope->getInstantiationOfIfExists(D) + : nullptr) { + return cast<NamedDecl>(Found->dyn_cast<Decl *>()); + } return D; + } ParentDC = FindInstantiatedContext(Loc, ParentDC, TemplateArgs); if (!ParentDC) diff --git a/clang/test/SemaCXX/lambda-unevaluated.cpp b/clang/test/SemaCXX/lambda-unevaluated.cpp index 9289fc9ec1243..4b0e1abdb38f0 100644 --- a/clang/test/SemaCXX/lambda-unevaluated.cpp +++ b/clang/test/SemaCXX/lambda-unevaluated.cpp @@ -282,3 +282,22 @@ static_assert(__is_same_as(int, helper<int>)); } // namespace GH138018 + +namespace GH163837 { + +template<int N> +void f(); + +template<class> +struct X { + using type = decltype([](auto) { + f<[]{ + int result = 0; + return result; + }()>(); + }(0)); +}; + +X<void> l; + +} // namespace GH163837 
@Backl1ght Backl1ght changed the title [Clang] Fix a wrong diagnostic about a local variable inside a lambda in unevaluated contexts need capture [Clang] Fix a wrong diagnostic about a local variable inside a lambda in unevaluated context need capture Oct 25, 2025
Copy link
Contributor

@zyn0217 zyn0217 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

FYI @mizvekov is working on a large patch that resolves a lot of lambda context related bugs and aims to remove these workarounds in the end.

Copy link
Contributor

@Fznamznon Fznamznon left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nits in case this patch goes in before the mentioned patch

Comment on lines +7065 to +7068
if (auto Found =
CurrentInstantiationScope
? CurrentInstantiationScope->getInstantiationOfIfExists(D)
: nullptr) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I find ternary operator inside of an if uncommon, can we simply do

Suggested change
if (auto Found =
CurrentInstantiationScope
? CurrentInstantiationScope->getInstantiationOfIfExists(D)
: nullptr) {
if (CurrentInstantiationScope) {
llvm::PointerUnion<... > * Found = CurrentInstantiationScope->getInstantiationOfIfExists(D)
...

and spell out the type?

CurrentInstantiationScope
? CurrentInstantiationScope->getInstantiationOfIfExists(D)
: nullptr) {
return cast<NamedDecl>(Found->dyn_cast<Decl *>());
Copy link
Contributor

@Fznamznon Fznamznon Oct 27, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using of dyn_cast is strange here IMO, since the outer cast doesn't expect null. If that is always a Decl there, we probably need to use get instead.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

clang:frontend Language frontend issues, e.g. anything involving "Sema" clang Clang issues not falling into any other category

4 participants