[clang] 994501a - [Clang] Fix evaluation context of lambdas appearing in discarded statements (#146857)
via cfe-commits
cfe-commits at lists.llvm.org
Thu Jul 3 10:59:21 PDT 2025
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 <tbaeder at 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 at -1 {{address of lambda function pointer conversion operator will always evaluate to 'true'}}
+ }
+}
+
+}
+
+
#endif
More information about the cfe-commits
mailing list