@@ -25,6 +25,16 @@ using APSInt = llvm::APSInt;
2525namespace clang {
2626namespace interp {
2727
28+ static std::optional<bool > getBoolValue (const Expr *E) {
29+ if (const auto *CE = dyn_cast_if_present<ConstantExpr>(E);
30+ CE && CE->hasAPValueResult () &&
31+ CE->getResultAPValueKind () == APValue::ValueKind::Int) {
32+ return CE->getResultAsAPSInt ().getBoolValue ();
33+ }
34+
35+ return std::nullopt ;
36+ }
37+
2838// / Scope used to handle temporaries in toplevel variable declarations.
2939template <class Emitter > class DeclScope final : public LocalScope<Emitter> {
3040public:
@@ -2286,6 +2296,19 @@ bool Compiler<Emitter>::VisitAbstractConditionalOperator(
22862296 const Expr *TrueExpr = E->getTrueExpr ();
22872297 const Expr *FalseExpr = E->getFalseExpr ();
22882298
2299+ auto visitChildExpr = [&](const Expr *E) -> bool {
2300+ LocalScope<Emitter> S (this );
2301+ if (!this ->delegate (E))
2302+ return false ;
2303+ return S.destroyLocals ();
2304+ };
2305+
2306+ if (std::optional<bool > BoolValue = getBoolValue (Condition)) {
2307+ if (BoolValue)
2308+ return visitChildExpr (TrueExpr);
2309+ return visitChildExpr (FalseExpr);
2310+ }
2311+
22892312 LabelTy LabelEnd = this ->getLabel (); // Label after the operator.
22902313 LabelTy LabelFalse = this ->getLabel (); // Label for the false expr.
22912314
@@ -2295,26 +2318,16 @@ bool Compiler<Emitter>::VisitAbstractConditionalOperator(
22952318 if (!this ->jumpFalse (LabelFalse))
22962319 return false ;
22972320
2298- {
2299- LocalScope<Emitter> S (this );
2300- if (!this ->delegate (TrueExpr))
2301- return false ;
2302- if (!S.destroyLocals ())
2303- return false ;
2304- }
2321+ if (!visitChildExpr (TrueExpr))
2322+ return false ;
23052323
23062324 if (!this ->jump (LabelEnd))
23072325 return false ;
23082326
23092327 this ->emitLabel (LabelFalse);
23102328
2311- {
2312- LocalScope<Emitter> S (this );
2313- if (!this ->delegate (FalseExpr))
2314- return false ;
2315- if (!S.destroyLocals ())
2316- return false ;
2317- }
2329+ if (!visitChildExpr (FalseExpr))
2330+ return false ;
23182331
23192332 this ->fallthrough (LabelEnd);
23202333 this ->emitLabel (LabelEnd);
@@ -5207,11 +5220,8 @@ template <class Emitter> bool Compiler<Emitter>::visitIfStmt(const IfStmt *IS) {
52075220 // stataically known to be either true or false. We could look at more cases
52085221 // here, but I think all the ones that actually happen are using a
52095222 // ConstantExpr.
5210- if (const auto *CE = dyn_cast_if_present<ConstantExpr>(IS->getCond ());
5211- CE && CE->hasAPValueResult () &&
5212- CE->getResultAPValueKind () == APValue::ValueKind::Int) {
5213- APSInt Value = CE->getResultAsAPSInt ();
5214- if (Value.getBoolValue ())
5223+ if (std::optional<bool > BoolValue = getBoolValue (IS->getCond ())) {
5224+ if (*BoolValue)
52155225 return visitChildStmt (IS->getThen ());
52165226 else if (const Stmt *Else = IS->getElse ())
52175227 return visitChildStmt (Else);
0 commit comments