diff options
Diffstat (limited to 'clang/lib/Analysis')
-rw-r--r-- | clang/lib/Analysis/LiveVariables.cpp | 18 |
1 files changed, 18 insertions, 0 deletions
diff --git a/clang/lib/Analysis/LiveVariables.cpp b/clang/lib/Analysis/LiveVariables.cpp index b43892a3093..1583fcb3de0 100644 --- a/clang/lib/Analysis/LiveVariables.cpp +++ b/clang/lib/Analysis/LiveVariables.cpp @@ -212,6 +212,8 @@ class TransferFunctions : public StmtVisitor<TransferFunctions> { LiveVariables::LivenessValues &val; LiveVariables::Observer *observer; const CFGBlock *currentBlock; + + void markLogicalExprLeaves(const Expr *E); public: TransferFunctions(LiveVariablesImpl &im, LiveVariables::LivenessValues &Val, @@ -368,7 +370,23 @@ void TransferFunctions::VisitBinaryOperator(BinaryOperator *B) { if (observer) observer->observerKill(DR); } + } else if (B->isLogicalOp()) { + // Leaf expressions in the logical operator tree are live until we reach the + // outermost logical operator. Static analyzer relies on this behaviour. + markLogicalExprLeaves(B->getLHS()->IgnoreParens()); + markLogicalExprLeaves(B->getRHS()->IgnoreParens()); + } +} + +void TransferFunctions::markLogicalExprLeaves(const Expr *E) { + const BinaryOperator *B = dyn_cast<BinaryOperator>(E); + if (!B || !B->isLogicalOp()) { + val.liveStmts = LV.SSetFact.add(val.liveStmts, E); + return; } + + markLogicalExprLeaves(B->getLHS()->IgnoreParens()); + markLogicalExprLeaves(B->getRHS()->IgnoreParens()); } void TransferFunctions::VisitBlockExpr(BlockExpr *BE) { |