Skip to content

Commit 994501a

Browse files
cor3ntintbaederr
andauthored
[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@redhat.com>
1 parent d66254e commit 994501a

File tree

3 files changed

+30
-7
lines changed

3 files changed

+30
-7
lines changed

clang/lib/Sema/SemaExpr.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18252,6 +18252,11 @@ static bool isImplicitlyDefinableConstexprFunction(FunctionDecl *Func) {
1825218252

1825318253
if (Func->isImplicitlyInstantiable() || !Func->isUserProvided())
1825418254
return true;
18255+
18256+
// Lambda conversion operators are never user provided.
18257+
if (CXXConversionDecl *Conv = dyn_cast<CXXConversionDecl>(Func))
18258+
return isLambdaConversionOperator(Conv);
18259+
1825518260
auto *CCD = dyn_cast<CXXConstructorDecl>(Func);
1825618261
return CCD && CCD->getInheritedConstructor();
1825718262
}

clang/lib/Sema/TreeTransform.h

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -15723,13 +15723,9 @@ TreeTransform<Derived>::TransformLambdaExpr(LambdaExpr *E) {
1572315723

1572415724
// FIXME: Sema's lambda-building mechanism expects us to push an expression
1572515725
// evaluation context even if we're not transforming the function body.
15726-
getSema().PushExpressionEvaluationContext(
15727-
E->getCallOperator()->isConsteval() ?
15728-
Sema::ExpressionEvaluationContext::ImmediateFunctionContext :
15729-
Sema::ExpressionEvaluationContext::PotentiallyEvaluated);
15730-
getSema().currentEvaluationContext().InImmediateEscalatingFunctionContext =
15731-
getSema().getLangOpts().CPlusPlus20 &&
15732-
E->getCallOperator()->isImmediateEscalating();
15726+
getSema().PushExpressionEvaluationContextForFunction(
15727+
Sema::ExpressionEvaluationContext::PotentiallyEvaluated,
15728+
E->getCallOperator());
1573315729

1573415730
Sema::CodeSynthesisContext C;
1573515731
C.Kind = clang::Sema::CodeSynthesisContext::LambdaExpressionSubstitution;

clang/test/CXX/stmt.stmt/stmt.select/stmt.if/p2.cpp

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -218,4 +218,26 @@ void regression() {
218218

219219
}
220220

221+
namespace GH146063 {
222+
template <typename>
223+
struct A {
224+
static_assert([]() constexpr { return true; }());
225+
};
226+
227+
void f1() {
228+
if constexpr (false) {
229+
A<int> a;
230+
}
231+
}
232+
233+
void f2() {
234+
if constexpr (false) {
235+
static_assert([]{});
236+
// expected-warning@-1 {{address of lambda function pointer conversion operator will always evaluate to 'true'}}
237+
}
238+
}
239+
240+
}
241+
242+
221243
#endif

0 commit comments

Comments
 (0)