[clang] e4fe22a - [clang][bytecode][NFC] Check conditional op condition for ConstantExprs (#130425)

via cfe-commits cfe-commits at lists.llvm.org
Sat Mar 8 09:29:23 PST 2025


Author: Timm Baeder
Date: 2025-03-08T18:29:19+01:00
New Revision: e4fe22a8bd1853331d4811546ac038252baee79d

URL: https://github.com/llvm/llvm-project/commit/e4fe22a8bd1853331d4811546ac038252baee79d
DIFF: https://github.com/llvm/llvm-project/commit/e4fe22a8bd1853331d4811546ac038252baee79d.diff

LOG: [clang][bytecode][NFC] Check conditional op condition for ConstantExprs (#130425)

Same thing we now do in if statements. Check the condition of a
conditional operator for a statically known true/false value.

Added: 
    

Modified: 
    clang/lib/AST/ByteCode/Compiler.cpp

Removed: 
    


################################################################################
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