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?= <tbae...@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); _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits