[clang] [clang][bytecode][NFC] Check conditional op condition for ConstantExprs (PR #130425)
Timm Baeder via cfe-commits
cfe-commits at lists.llvm.org
Sat Mar 8 09:02:34 PST 2025
https://github.com/tbaederr created https://github.com/llvm/llvm-project/pull/130425
Same thing we now do in if statements. Check the condition of a conditional operator for a statically known true/false value.
>From 6543c75f7b5ea03b6061637f18b8a97c3ce48410 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Timm=20B=C3=A4der?= <tbaeder at redhat.com>
Date: Sat, 8 Mar 2025 18:00:38 +0100
Subject: [PATCH] [clang][bytecode][NFC] Check conditional op condition for
ConstantExprs
Same thing we now do in if statements. Check the condition of a
conditional operator for a statically known true/false value.
---
clang/lib/AST/ByteCode/Compiler.cpp | 48 +++++++++++++++++------------
1 file changed, 29 insertions(+), 19 deletions(-)
diff --git a/clang/lib/AST/ByteCode/Compiler.cpp b/clang/lib/AST/ByteCode/Compiler.cpp
index d192b8b91c72e..9a52dd4105437 100644
--- a/clang/lib/AST/ByteCode/Compiler.cpp
+++ b/clang/lib/AST/ByteCode/Compiler.cpp
@@ -25,6 +25,16 @@ using APSInt = llvm::APSInt;
namespace clang {
namespace interp {
+static std::optional<bool> getBoolValue(const Expr *E) {
+ if (const auto *CE = dyn_cast_if_present<ConstantExpr>(E);
+ CE && CE->hasAPValueResult() &&
+ CE->getResultAPValueKind() == APValue::ValueKind::Int) {
+ return CE->getResultAsAPSInt().getBoolValue();
+ }
+
+ return std::nullopt;
+}
+
/// Scope used to handle temporaries in toplevel variable declarations.
template <class Emitter> class DeclScope final : public LocalScope<Emitter> {
public:
@@ -2286,6 +2296,19 @@ bool Compiler<Emitter>::VisitAbstractConditionalOperator(
const Expr *TrueExpr = E->getTrueExpr();
const Expr *FalseExpr = E->getFalseExpr();
+ auto visitChildExpr = [&](const Expr *E) -> bool {
+ LocalScope<Emitter> S(this);
+ if (!this->delegate(E))
+ return false;
+ return S.destroyLocals();
+ };
+
+ if (std::optional<bool> BoolValue = getBoolValue(Condition)) {
+ if (BoolValue)
+ return visitChildExpr(TrueExpr);
+ return visitChildExpr(FalseExpr);
+ }
+
LabelTy LabelEnd = this->getLabel(); // Label after the operator.
LabelTy LabelFalse = this->getLabel(); // Label for the false expr.
@@ -2295,26 +2318,16 @@ bool Compiler<Emitter>::VisitAbstractConditionalOperator(
if (!this->jumpFalse(LabelFalse))
return false;
- {
- LocalScope<Emitter> S(this);
- if (!this->delegate(TrueExpr))
- return false;
- if (!S.destroyLocals())
- return false;
- }
+ if (!visitChildExpr(TrueExpr))
+ return false;
if (!this->jump(LabelEnd))
return false;
this->emitLabel(LabelFalse);
- {
- LocalScope<Emitter> S(this);
- if (!this->delegate(FalseExpr))
- return false;
- if (!S.destroyLocals())
- return false;
- }
+ if (!visitChildExpr(FalseExpr))
+ return false;
this->fallthrough(LabelEnd);
this->emitLabel(LabelEnd);
@@ -5207,11 +5220,8 @@ template <class Emitter> bool Compiler<Emitter>::visitIfStmt(const IfStmt *IS) {
// stataically known to be either true or false. We could look at more cases
// here, but I think all the ones that actually happen are using a
// ConstantExpr.
- if (const auto *CE = dyn_cast_if_present<ConstantExpr>(IS->getCond());
- CE && CE->hasAPValueResult() &&
- CE->getResultAPValueKind() == APValue::ValueKind::Int) {
- APSInt Value = CE->getResultAsAPSInt();
- if (Value.getBoolValue())
+ if (std::optional<bool> BoolValue = getBoolValue(IS->getCond())) {
+ if (*BoolValue)
return visitChildStmt(IS->getThen());
else if (const Stmt *Else = IS->getElse())
return visitChildStmt(Else);
More information about the cfe-commits
mailing list