Skip to content

Commit e4fe22a

Browse files
authored
[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.
1 parent a22a646 commit e4fe22a

File tree

1 file changed

+29
-19
lines changed

1 file changed

+29
-19
lines changed

clang/lib/AST/ByteCode/Compiler.cpp

Lines changed: 29 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,16 @@ using APSInt = llvm::APSInt;
2525
namespace clang {
2626
namespace 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.
2939
template <class Emitter> class DeclScope final : public LocalScope<Emitter> {
3040
public:
@@ -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

Comments
 (0)