From e305d573c6237f4442886d1c4f267382c2281fc5 Mon Sep 17 00:00:00 2001 From: Matheus Izvekov Date: Thu, 2 Oct 2025 23:11:46 -0300 Subject: [PATCH] [clang] fix lambda dependency issue with late parse attributes This fixes a regression introduced in #147835 When parsing a lambda where the call operator has a late parsed attribute, we would try to build a 'this' type for the lambda, but in a lambda 'this' never refers to the lambda class itself. This late parsed attribute can be added implicitly by the -ftrapping-math flag. This patch patch makes it so CXXThisScopeRAII ignores lambdas. This became observable in #147835 because that made clang lazily create tag types, and it removed a workaround for a lambda dependency bug where any previously created tag type for the lambda is dicarded after its dependency is recalculated. But the 'this' scope created above would defeat this laziness and create the lambda type too soon, before its dependency was updated. Since this regression was never released, there are no release notes. Fixes #161657 --- clang/lib/Sema/SemaExprCXX.cpp | 4 ++++ clang/test/SemaTemplate/GH161657.cpp | 11 +++++++++++ 2 files changed, 15 insertions(+) create mode 100644 clang/test/SemaTemplate/GH161657.cpp diff --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp index 779ccf5f1e888..576eb326e6529 100644 --- a/clang/lib/Sema/SemaExprCXX.cpp +++ b/clang/lib/Sema/SemaExprCXX.cpp @@ -1251,6 +1251,10 @@ Sema::CXXThisScopeRAII::CXXThisScopeRAII(Sema &S, else Record = cast(ContextDecl); + // 'this' never refers to the lambda class itself. + if (Record->isLambda()) + return; + QualType T = S.Context.getCanonicalTagType(Record); T = S.getASTContext().getQualifiedType(T, CXXThisTypeQuals); diff --git a/clang/test/SemaTemplate/GH161657.cpp b/clang/test/SemaTemplate/GH161657.cpp new file mode 100644 index 0000000000000..6ec793115db12 --- /dev/null +++ b/clang/test/SemaTemplate/GH161657.cpp @@ -0,0 +1,11 @@ +// RUN: %clang_cc1 -fsyntax-only -std=c++20 -ffp-exception-behavior=strict -verify %s +// expected-no-diagnostics + +template struct S { + template using type1 = decltype([] { return U{}; }); +}; + +void foo() { + using T1 = S::type1; + int x = T1()(); +}