https://github.com/cor3ntin created https://github.com/llvm/llvm-project/pull/146857
Fixes 2 bugs reported in #146063 - The body of a lambda appearing in a discarded statement was sometimes considered discarded itself - A lambda conversion operator that was not odr-used was sometimes not defined even if it was needed Fixes #146063 >From 4ee72df191e9792be38195b00b0f6422de3a767a Mon Sep 17 00:00:00 2001 From: Corentin Jabot <corentinja...@gmail.com> Date: Thu, 3 Jul 2025 13:00:46 +0200 Subject: [PATCH] [Clang] Fix evaluation context of lambdas appearing in discarded statements Fixes 2 bugs reported in #146063 - The body of a lambda appearing in a discarded statement was sometimes considered discarded itself - A lambda conversion operator that was not odr-used was sometimes not defined even if it was needed Fixes #146063 --- clang/lib/Sema/SemaExpr.cpp | 5 +++++ clang/lib/Sema/TreeTransform.h | 10 +++------ .../CXX/stmt.stmt/stmt.select/stmt.if/p2.cpp | 22 +++++++++++++++++++ 3 files changed, 30 insertions(+), 7 deletions(-) diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index 437df742d572b..a23497afddefe 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -18252,6 +18252,11 @@ static bool isImplicitlyDefinableConstexprFunction(FunctionDecl *Func) { if (Func->isImplicitlyInstantiable() || !Func->isUserProvided()) return true; + + // Lambda conversion operators are never user provided + if (CXXConversionDecl *Conv = dyn_cast<CXXConversionDecl>(Func)) + return isLambdaConversionOperator(Conv); + auto *CCD = dyn_cast<CXXConstructorDecl>(Func); return CCD && CCD->getInheritedConstructor(); } diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h index 0d58587cb8a99..2f57672375a01 100644 --- a/clang/lib/Sema/TreeTransform.h +++ b/clang/lib/Sema/TreeTransform.h @@ -15723,13 +15723,9 @@ TreeTransform<Derived>::TransformLambdaExpr(LambdaExpr *E) { // FIXME: Sema's lambda-building mechanism expects us to push an expression // evaluation context even if we're not transforming the function body. - getSema().PushExpressionEvaluationContext( - E->getCallOperator()->isConsteval() ? - Sema::ExpressionEvaluationContext::ImmediateFunctionContext : - Sema::ExpressionEvaluationContext::PotentiallyEvaluated); - getSema().currentEvaluationContext().InImmediateEscalatingFunctionContext = - getSema().getLangOpts().CPlusPlus20 && - E->getCallOperator()->isImmediateEscalating(); + getSema().PushExpressionEvaluationContextForFunction( + Sema::ExpressionEvaluationContext::PotentiallyEvaluated, + E->getCallOperator()); Sema::CodeSynthesisContext C; C.Kind = clang::Sema::CodeSynthesisContext::LambdaExpressionSubstitution; diff --git a/clang/test/CXX/stmt.stmt/stmt.select/stmt.if/p2.cpp b/clang/test/CXX/stmt.stmt/stmt.select/stmt.if/p2.cpp index ac21e36daf870..abb42447d3e0b 100644 --- a/clang/test/CXX/stmt.stmt/stmt.select/stmt.if/p2.cpp +++ b/clang/test/CXX/stmt.stmt/stmt.select/stmt.if/p2.cpp @@ -218,4 +218,26 @@ void regression() { } +namespace GH146063 { +template <typename> +struct A { + static_assert([]() constexpr { return true; }()); +}; + +void f1() { + if constexpr (false) { + A<int> a; + } +} + +void f2() { + if constexpr (false) { + static_assert([]{}); + // expected-warning@-1 {{address of lambda function pointer conversion operator will always evaluate to 'true'}} + } +} + +} + + #endif _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits