forked from OSchip/llvm-project
[clang] Fix incorrect constant folding of `if consteval`
Fixes https://github.com/llvm/llvm-project/issues/55638. `if consteval` was evaluated incorrectly when in a non-constant context that could be constant-folded. Reviewed By: aaron.ballman Differential Revision: https://reviews.llvm.org/D130437
This commit is contained in:
parent
0ba128f7c8
commit
c68baa73eb
|
@ -194,6 +194,8 @@ Bug Fixes
|
|||
move assignment operator. Fixes `Issue 56456 <https://github.com/llvm/llvm-project/issues/56456>`_.
|
||||
- Fixed a crash when a variable with a bool enum type that has no definition
|
||||
used in comparison operators. Fixes `Issue 56560 <https://github.com/llvm/llvm-project/issues/56560>`_.
|
||||
- Fix that ``if consteval`` could evaluate to ``true`` at runtime because it was incorrectly
|
||||
constant folded. Fixes `Issue 55638 <https://github.com/llvm/llvm-project/issues/55638>`_.
|
||||
|
||||
Improvements to Clang's diagnostics
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
|
@ -5266,10 +5266,14 @@ static EvalStmtResult EvaluateStmt(StmtResult &Result, EvalInfo &Info,
|
|||
}
|
||||
}
|
||||
bool Cond;
|
||||
if (IS->isConsteval())
|
||||
if (IS->isConsteval()) {
|
||||
Cond = IS->isNonNegatedConsteval();
|
||||
else if (!EvaluateCond(Info, IS->getConditionVariable(), IS->getCond(),
|
||||
Cond))
|
||||
// If we are not in a constant context, if consteval should not evaluate
|
||||
// to true.
|
||||
if (!Info.InConstantContext)
|
||||
Cond = !Cond;
|
||||
} else if (!EvaluateCond(Info, IS->getConditionVariable(), IS->getCond(),
|
||||
Cond))
|
||||
return ESR_Failed;
|
||||
|
||||
if (const Stmt *SubStmt = Cond ? IS->getThen() : IS->getElse()) {
|
||||
|
|
|
@ -26,3 +26,30 @@ constexpr void f() {
|
|||
void g() {
|
||||
f();
|
||||
}
|
||||
|
||||
namespace GH55638 {
|
||||
|
||||
constexpr bool is_constant_evaluated() noexcept {
|
||||
if consteval { return true; } else { return false; }
|
||||
}
|
||||
|
||||
constexpr int compiletime(int) {
|
||||
return 2;
|
||||
}
|
||||
|
||||
constexpr int runtime(int) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
constexpr int test(int x) {
|
||||
if(is_constant_evaluated())
|
||||
return compiletime(x); // CHECK-NOT: call {{.*}}compiletime
|
||||
return runtime(x); // CHECK: call {{.*}}runtime
|
||||
}
|
||||
|
||||
int f(int x) {
|
||||
x = test(x);
|
||||
return x;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue