[Clang] Ensure `if consteval` consititute an immediate function context (#91939)

We did not set the correct evaluation context for the compound statement
of an ``if consteval`` statement
in a templated entity in TreeTransform.

Fixes #91509
This commit is contained in:
cor3ntin 2024-05-13 16:04:20 +02:00 committed by GitHub
parent 4445ed4244
commit c4e9e41199
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 37 additions and 0 deletions

View File

@ -707,6 +707,7 @@ Bug Fixes to C++ Support
initialized, rather than evaluating them as a part of the larger manifestly constant evaluated
expression.
- Fix a bug in access control checking due to dealyed checking of friend declaration. Fixes (#GH12361).
- Correctly treat the compound statement of an ``if consteval`` as an immediate context. Fixes (#GH91509).
Bug Fixes to AST Handling
^^^^^^^^^^^^^^^^^^^^^^^^^

View File

@ -7964,6 +7964,11 @@ TreeTransform<Derived>::TransformIfStmt(IfStmt *S) {
// Transform the "then" branch.
StmtResult Then;
if (!ConstexprConditionValue || *ConstexprConditionValue) {
EnterExpressionEvaluationContext Ctx(
getSema(), Sema::ExpressionEvaluationContext::ImmediateFunctionContext,
nullptr, Sema::ExpressionEvaluationContextRecord::EK_Other,
S->isNonNegatedConsteval());
Then = getDerived().TransformStmt(S->getThen());
if (Then.isInvalid())
return StmtError();
@ -7978,6 +7983,11 @@ TreeTransform<Derived>::TransformIfStmt(IfStmt *S) {
// Transform the "else" branch.
StmtResult Else;
if (!ConstexprConditionValue || !*ConstexprConditionValue) {
EnterExpressionEvaluationContext Ctx(
getSema(), Sema::ExpressionEvaluationContext::ImmediateFunctionContext,
nullptr, Sema::ExpressionEvaluationContextRecord::EK_Other,
S->isNegatedConsteval());
Else = getDerived().TransformStmt(S->getElse());
if (Else.isInvalid())
return StmtError();

View File

@ -420,3 +420,29 @@ int f = *fn().value + fn2(); // expected-error {{call to consteval function 'lv
// expected-note {{pointer to heap-allocated object}}
}
#endif
#if __cplusplus >= 202302L
namespace GH91509 {
consteval int f(int) { return 0; }
template<typename T>
constexpr int g(int x) {
if consteval {
return f(x);
}
if !consteval {}
else {
return f(x);
}
return 1;
}
int h(int x) {
return g<void>(x);
}
}
#endif