Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions clang/lib/Sema/SemaExpr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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();
}
Expand Down
10 changes: 3 additions & 7 deletions clang/lib/Sema/TreeTransform.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
22 changes: 22 additions & 0 deletions clang/test/CXX/stmt.stmt/stmt.select/stmt.if/p2.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
Loading