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

Reply via email to