Author: Corentin Jabot Date: 2025-07-03T20:59:18+03:00 New Revision: 994501abe75c2a2d244785c0d0cf177858ac6eaf
URL: https://github.com/llvm/llvm-project/commit/994501abe75c2a2d244785c0d0cf177858ac6eaf DIFF: https://github.com/llvm/llvm-project/commit/994501abe75c2a2d244785c0d0cf177858ac6eaf.diff LOG: [Clang] Fix evaluation context of lambdas appearing in discarded statements (#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 --------- Co-authored-by: Timm Baeder <tbae...@redhat.com> Added: Modified: clang/lib/Sema/SemaExpr.cpp clang/lib/Sema/TreeTransform.h clang/test/CXX/stmt.stmt/stmt.select/stmt.if/p2.cpp Removed: ################################################################################ diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index 03dca6f7cb878..aedaf5d1f6b1a 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