diff --git a/clang/lib/Analysis/LiveVariables.cpp b/clang/lib/Analysis/LiveVariables.cpp index 7896bfcfb0a6..feba80d69556 100644 --- a/clang/lib/Analysis/LiveVariables.cpp +++ b/clang/lib/Analysis/LiveVariables.cpp @@ -143,22 +143,59 @@ void TransferFuncs::Visit(Stmt *S) { } void TransferFuncs::VisitTerminator(Stmt* S) { - return; - for (Stmt::child_iterator I = S->child_begin(), E = S->child_end(); - I != E; ++I) { - - Stmt* Child = *I; - if (!Child) continue; - - if (getCFG().isBlkExpr(Child)) { - LiveState(Child, AD) = Alive; - return; // Only one "condition" expression. - } + Expr* E = NULL; + + switch (S->getStmtClass()) { + default: + return; + + case Stmt::ForStmtClass: + E = cast(S)->getCond(); + break; + + case Stmt::WhileStmtClass: + E = cast(S)->getCond(); + break; + + case Stmt::DoStmtClass: + E = cast(S)->getCond(); + break; + + case Stmt::IfStmtClass: + E = cast(S)->getCond(); + break; + + case Stmt::ChooseExprClass: + E = cast(S)->getCond(); + break; + + case Stmt::IndirectGotoStmtClass: + E = cast(S)->getTarget(); + break; + + case Stmt::SwitchStmtClass: + E = cast(S)->getCond(); + break; + + case Stmt::ConditionalOperatorClass: + E = cast(S)->getCond(); + break; + + case Stmt::BinaryOperatorClass: // '&&' and '||' + E = cast(S)->getLHS(); + break; } + + if (!E) + return; + + E = E->IgnoreParens(); + + assert (getCFG().isBlkExpr(E)); + LiveState(E, AD) = Alive; } - void TransferFuncs::VisitDeclRefExpr(DeclRefExpr* DR) { if (VarDecl* V = dyn_cast(DR->getDecl())) LiveState(V,AD) = Alive;