[cfe-commits] r49818 - in /cfe/trunk: include/clang/AST/CFG.h include/clang/Analysis/FlowSensitive/DataflowSolver.h lib/AST/CFG.cpp lib/Analysis/LiveVariables.cpp lib/Analysis/UninitializedValues.cpp

Ted Kremenek kremenek at apple.com
Wed Apr 16 14:10:48 PDT 2008


Author: kremenek
Date: Wed Apr 16 16:10:48 2008
New Revision: 49818

URL: http://llvm.org/viewvc/llvm-project?rev=49818&view=rev
Log:
Added CFGBlock::getTerminatorCondition() to get the Expr* of the condition a block's terminator.
Refactored LiveVariables to use getTerminatorCondition() in VisitTerminator().

Bug fix: CFG now computes Block-level expression numbers using information
from block terminators.  This fixes <rdar://problem/5868189>.

Modified:
    cfe/trunk/include/clang/AST/CFG.h
    cfe/trunk/include/clang/Analysis/FlowSensitive/DataflowSolver.h
    cfe/trunk/lib/AST/CFG.cpp
    cfe/trunk/lib/Analysis/LiveVariables.cpp
    cfe/trunk/lib/Analysis/UninitializedValues.cpp

Modified: cfe/trunk/include/clang/AST/CFG.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/CFG.h?rev=49818&r1=49817&r2=49818&view=diff

==============================================================================
--- cfe/trunk/include/clang/AST/CFG.h (original)
+++ cfe/trunk/include/clang/AST/CFG.h Wed Apr 16 16:10:48 2008
@@ -152,6 +152,12 @@
   Stmt* getTerminator() { return Terminator; }
   const Stmt* getTerminator() const { return Terminator; }
   
+  Expr* getTerminatorCondition();
+  
+  const Expr* getTerminatorCondition() const {
+    return const_cast<CFGBlock*>(this)->getTerminatorCondition();
+  }
+  
   Stmt* getLabel() { return Label; }
   const Stmt* getLabel() const { return Label; }
   

Modified: cfe/trunk/include/clang/Analysis/FlowSensitive/DataflowSolver.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Analysis/FlowSensitive/DataflowSolver.h?rev=49818&r1=49817&r2=49818&view=diff

==============================================================================
--- cfe/trunk/include/clang/Analysis/FlowSensitive/DataflowSolver.h (original)
+++ cfe/trunk/include/clang/Analysis/FlowSensitive/DataflowSolver.h Wed Apr 16 16:10:48 2008
@@ -259,13 +259,13 @@
     for (StmtItr I=ItrTraits::StmtBegin(B), E=ItrTraits::StmtEnd(B); I!=E;++I)
       ProcessStmt(*I, recordStmtValues, AnalysisDirTag());
     
-    if (Stmt* Term = (Stmt*) B->getTerminator()) TF.VisitTerminator(Term);  
+    TF.VisitTerminator(const_cast<CFGBlock*>(B));  
   }
   
   void ProcessBlock(const CFGBlock* B, bool recordStmtValues,
                     dataflow::backward_analysis_tag) {
     
-    if (Stmt* Term = (Stmt*) B->getTerminator()) TF.VisitTerminator(Term);
+    TF.VisitTerminator(const_cast<CFGBlock*>(B));
 
     for (StmtItr I=ItrTraits::StmtBegin(B), E=ItrTraits::StmtEnd(B); I!=E;++I)
       ProcessStmt(*I, recordStmtValues, AnalysisDirTag());

Modified: cfe/trunk/lib/AST/CFG.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/CFG.cpp?rev=49818&r1=49817&r2=49818&view=diff

==============================================================================
--- cfe/trunk/lib/AST/CFG.cpp (original)
+++ cfe/trunk/lib/AST/CFG.cpp Wed Apr 16 16:10:48 2008
@@ -108,30 +108,30 @@
   CFGBlock* VisitDoStmt(DoStmt* D);
   CFGBlock* VisitContinueStmt(ContinueStmt* C);
   CFGBlock* VisitBreakStmt(BreakStmt* B);
-  CFGBlock* VisitSwitchStmt(SwitchStmt* S);
-  CFGBlock* VisitCaseStmt(CaseStmt* S);
+  CFGBlock* VisitSwitchStmt(SwitchStmt* Terminator);
+  CFGBlock* VisitCaseStmt(CaseStmt* Terminator);
   CFGBlock* VisitDefaultStmt(DefaultStmt* D);
   CFGBlock* VisitIndirectGotoStmt(IndirectGotoStmt* I);
   
   // FIXME: Add support for ObjC-specific control-flow structures.
   
-  CFGBlock* VisitObjCForCollectionStmt(ObjCForCollectionStmt* S) {
+  CFGBlock* VisitObjCForCollectionStmt(ObjCForCollectionStmt* Terminator) {
     badCFG = true;
     return Block;
   }
   
-  CFGBlock* VisitObjCAtTryStmt(ObjCAtTryStmt* S) {
+  CFGBlock* VisitObjCAtTryStmt(ObjCAtTryStmt* Terminator) {
     badCFG = true;
     return Block;
   }
   
 private:
   CFGBlock* createBlock(bool add_successor = true);
-  CFGBlock* addStmt(Stmt* S);
-  CFGBlock* WalkAST(Stmt* S, bool AlwaysAddStmt);
-  CFGBlock* WalkAST_VisitChildren(Stmt* S);
+  CFGBlock* addStmt(Stmt* Terminator);
+  CFGBlock* WalkAST(Stmt* Terminator, bool AlwaysAddStmt);
+  CFGBlock* WalkAST_VisitChildren(Stmt* Terminator);
   CFGBlock* WalkAST_VisitDeclSubExprs(StmtIterator& I);
-  CFGBlock* WalkAST_VisitStmtExpr(StmtExpr* S);
+  CFGBlock* WalkAST_VisitStmtExpr(StmtExpr* Terminator);
   void FinishBlock(CFGBlock* B);
   
   bool badCFG;
@@ -236,18 +236,18 @@
 ///  the necessary blocks for such expressions.  It returns the "topmost" block
 ///  of the created blocks, or the original value of "Block" when this method
 ///  was called if no additional blocks are created.
-CFGBlock* CFGBuilder::addStmt(Stmt* S) {
+CFGBlock* CFGBuilder::addStmt(Stmt* Terminator) {
   if (!Block) Block = createBlock();
-  return WalkAST(S,true);
+  return WalkAST(Terminator,true);
 }
 
 /// WalkAST - Used by addStmt to walk the subtree of a statement and
 ///   add extra blocks for ternary operators, &&, and ||.  We also
 ///   process "," and DeclStmts (which may contain nested control-flow).
-CFGBlock* CFGBuilder::WalkAST(Stmt* S, bool AlwaysAddStmt = false) {    
-  switch (S->getStmtClass()) {
+CFGBlock* CFGBuilder::WalkAST(Stmt* Terminator, bool AlwaysAddStmt = false) {    
+  switch (Terminator->getStmtClass()) {
     case Stmt::ConditionalOperatorClass: {
-      ConditionalOperator* C = cast<ConditionalOperator>(S);
+      ConditionalOperator* C = cast<ConditionalOperator>(Terminator);
 
       // Create the confluence block that will "merge" the results
       // of the ternary expression.
@@ -299,7 +299,7 @@
     }
     
     case Stmt::ChooseExprClass: {
-      ChooseExpr* C = cast<ChooseExpr>(S);      
+      ChooseExpr* C = cast<ChooseExpr>(Terminator);      
       
       CFGBlock* ConfluenceBlock = (Block) ? Block : createBlock();  
       ConfluenceBlock->appendStmt(C);
@@ -323,32 +323,32 @@
     }
 
     case Stmt::DeclStmtClass: {
-      ScopedDecl* D = cast<DeclStmt>(S)->getDecl();
-      Block->appendStmt(S);
+      ScopedDecl* D = cast<DeclStmt>(Terminator)->getDecl();
+      Block->appendStmt(Terminator);
       
       StmtIterator I(D);
       return WalkAST_VisitDeclSubExprs(I);
     }
       
     case Stmt::AddrLabelExprClass: {
-      AddrLabelExpr* A = cast<AddrLabelExpr>(S);
+      AddrLabelExpr* A = cast<AddrLabelExpr>(Terminator);
       AddressTakenLabels.insert(A->getLabel());
       
-      if (AlwaysAddStmt) Block->appendStmt(S);
+      if (AlwaysAddStmt) Block->appendStmt(Terminator);
       return Block;
     }
     
     case Stmt::StmtExprClass:
-      return WalkAST_VisitStmtExpr(cast<StmtExpr>(S));
+      return WalkAST_VisitStmtExpr(cast<StmtExpr>(Terminator));
 
     case Stmt::UnaryOperatorClass: {
-      UnaryOperator* U = cast<UnaryOperator>(S);
+      UnaryOperator* U = cast<UnaryOperator>(Terminator);
       
       // sizeof(expressions).  For such expressions,
       // the subexpression is not really evaluated, so
       // we don't care about control-flow within the sizeof.
       if (U->getOpcode() == UnaryOperator::SizeOf) {
-        Block->appendStmt(S);
+        Block->appendStmt(Terminator);
         return Block;
       }
       
@@ -356,7 +356,7 @@
     }
       
     case Stmt::BinaryOperatorClass: {
-      BinaryOperator* B = cast<BinaryOperator>(S);
+      BinaryOperator* B = cast<BinaryOperator>(Terminator);
 
       if (B->isLogicalOp()) { // && or ||
         CFGBlock* ConfluenceBlock = (Block) ? Block : createBlock();  
@@ -397,14 +397,14 @@
     }
       
     case Stmt::ParenExprClass:
-      return WalkAST(cast<ParenExpr>(S)->getSubExpr(), AlwaysAddStmt);
+      return WalkAST(cast<ParenExpr>(Terminator)->getSubExpr(), AlwaysAddStmt);
     
     default:
       break;
   };
       
-  if (AlwaysAddStmt) Block->appendStmt(S);
-  return WalkAST_VisitChildren(S);
+  if (AlwaysAddStmt) Block->appendStmt(Terminator);
+  return WalkAST_VisitChildren(Terminator);
 }
 
 /// WalkAST_VisitDeclSubExprs - Utility method to handle Decls contained in
@@ -416,13 +416,13 @@
   if (I == StmtIterator())
     return Block;
   
-  Stmt* S = *I;
+  Stmt* Terminator = *I;
   ++I;
   WalkAST_VisitDeclSubExprs(I);
     
   // Optimization: Don't create separate block-level statements for literals.
   
-  switch (S->getStmtClass()) {
+  switch (Terminator->getStmtClass()) {
     case Stmt::IntegerLiteralClass:
     case Stmt::CharacterLiteralClass:
     case Stmt::StringLiteralClass:
@@ -431,7 +431,7 @@
       // All other cases.
       
     default:
-      Block = addStmt(S);
+      Block = addStmt(Terminator);
   }
   
   return Block;
@@ -439,9 +439,9 @@
 
 /// WalkAST_VisitChildren - Utility method to call WalkAST on the
 ///  children of a Stmt.
-CFGBlock* CFGBuilder::WalkAST_VisitChildren(Stmt* S) {
+CFGBlock* CFGBuilder::WalkAST_VisitChildren(Stmt* Terminator) {
   CFGBlock* B = Block;
-  for (Stmt::child_iterator I = S->child_begin(), E = S->child_end() ;
+  for (Stmt::child_iterator I = Terminator->child_begin(), E = Terminator->child_end() ;
        I != E; ++I)
     if (*I) B = WalkAST(*I);
   
@@ -450,9 +450,9 @@
 
 /// WalkAST_VisitStmtExpr - Utility method to handle (nested) statement
 ///  expressions (a GCC extension).
-CFGBlock* CFGBuilder::WalkAST_VisitStmtExpr(StmtExpr* S) {
-  Block->appendStmt(S);
-  return VisitCompoundStmt(S->getSubStmt());  
+CFGBlock* CFGBuilder::WalkAST_VisitStmtExpr(StmtExpr* Terminator) {
+  Block->appendStmt(Terminator);
+  return VisitCompoundStmt(Terminator->getSubStmt());  
 }
 
 /// VisitStmt - Handle statements with no branching control flow.
@@ -900,7 +900,7 @@
   return Block;  
 }
 
-CFGBlock* CFGBuilder::VisitSwitchStmt(SwitchStmt* S) {
+CFGBlock* CFGBuilder::VisitSwitchStmt(SwitchStmt* Terminator) {
   // "switch" is a control-flow statement.  Thus we stop processing the
   // current block.    
   CFGBlock* SwitchSuccessor = NULL;
@@ -932,9 +932,9 @@
   // When visiting the body, the case statements should automatically get
   // linked up to the switch.  We also don't keep a pointer to the body,
   // since all control-flow from the switch goes to case/default statements.
-  assert (S->getBody() && "switch must contain a non-NULL body");
+  assert (Terminator->getBody() && "switch must contain a non-NULL body");
   Block = NULL;
-  CFGBlock *BodyBlock = Visit(S->getBody());
+  CFGBlock *BodyBlock = Visit(Terminator->getBody());
   if (Block) FinishBlock(BodyBlock);
 
   // If we have no "default:" case, the default transition is to the
@@ -942,24 +942,24 @@
   SwitchTerminatedBlock->addSuccessor(DefaultCaseBlock);
   
   // Add the terminator and condition in the switch block.
-  SwitchTerminatedBlock->setTerminator(S);
-  assert (S->getCond() && "switch condition must be non-NULL");
+  SwitchTerminatedBlock->setTerminator(Terminator);
+  assert (Terminator->getCond() && "switch condition must be non-NULL");
   Block = SwitchTerminatedBlock;
   
-  return addStmt(S->getCond());
+  return addStmt(Terminator->getCond());
 }
 
-CFGBlock* CFGBuilder::VisitCaseStmt(CaseStmt* S) {
+CFGBlock* CFGBuilder::VisitCaseStmt(CaseStmt* Terminator) {
   // CaseStmts are essentially labels, so they are the
   // first statement in a block.      
 
-  if (S->getSubStmt()) Visit(S->getSubStmt());
+  if (Terminator->getSubStmt()) Visit(Terminator->getSubStmt());
   CFGBlock* CaseBlock = Block;
   if (!CaseBlock) CaseBlock = createBlock();  
     
   // Cases statements partition blocks, so this is the top of
   // the basic block we were processing (the "case XXX:" is the label).
-  CaseBlock->setLabel(S);
+  CaseBlock->setLabel(Terminator);
   FinishBlock(CaseBlock);
   
   // Add this block to the list of successors for the block with the
@@ -976,14 +976,14 @@
   return CaseBlock;
 }
   
-CFGBlock* CFGBuilder::VisitDefaultStmt(DefaultStmt* S) {
-  if (S->getSubStmt()) Visit(S->getSubStmt());
+CFGBlock* CFGBuilder::VisitDefaultStmt(DefaultStmt* Terminator) {
+  if (Terminator->getSubStmt()) Visit(Terminator->getSubStmt());
   DefaultCaseBlock = Block;
   if (!DefaultCaseBlock) DefaultCaseBlock = createBlock();  
   
   // Default statements partition blocks, so this is the top of
   // the basic block we were processing (the "default:" is the label).
-  DefaultCaseBlock->setLabel(S);
+  DefaultCaseBlock->setLabel(Terminator);
   FinishBlock(DefaultCaseBlock);
 
   // Unlike case statements, we don't add the default block to the
@@ -1059,11 +1059,11 @@
   typedef llvm::DenseMap<const Stmt*,unsigned> BlkExprMapTy;
 }
 
-static void FindSubExprAssignments(Stmt* S, llvm::SmallPtrSet<Expr*,50>& Set) {
-  if (!S)
+static void FindSubExprAssignments(Stmt* Terminator, llvm::SmallPtrSet<Expr*,50>& Set) {
+  if (!Terminator)
     return;
   
-  for (Stmt::child_iterator I=S->child_begin(), E=S->child_end(); I!=E; ++I) {
+  for (Stmt::child_iterator I=Terminator->child_begin(), E=Terminator->child_end(); I!=E; ++I) {
     if (!*I) continue;
     
     if (BinaryOperator* B = dyn_cast<BinaryOperator>(*I))
@@ -1077,30 +1077,34 @@
   BlkExprMapTy* M = new BlkExprMapTy();
   
   // Look for assignments that are used as subexpressions.  These are the
-  // only assignments that we want to register as a block-level expression.
+  // only assignments that we want to *possibly* register as a block-level
+  // expression.  Basically, if an assignment occurs both in a subexpression
+  // and at the block-level, it is a block-level expression.
   llvm::SmallPtrSet<Expr*,50> SubExprAssignments;
   
   for (CFG::iterator I=cfg.begin(), E=cfg.end(); I != E; ++I)
     for (CFGBlock::iterator BI=I->begin(), EI=I->end(); BI != EI; ++BI)
       FindSubExprAssignments(*BI, SubExprAssignments);
 
-  // Iterate over the statements again on identify the Expr* and Stmt* at
-  // the block-level that are block-level expressions.
-  for (CFG::iterator I=cfg.begin(), E=cfg.end(); I != E; ++I)
+  for (CFG::iterator I=cfg.begin(), E=cfg.end(); I != E; ++I) {
+    
+    // Iterate over the statements again on identify the Expr* and Stmt* at
+    // the block-level that are block-level expressions.
+
     for (CFGBlock::iterator BI=I->begin(), EI=I->end(); BI != EI; ++BI)
-      if (Expr* E = dyn_cast<Expr>(*BI)) {
+      if (Expr* Exp = dyn_cast<Expr>(*BI)) {
         
-        if (BinaryOperator* B = dyn_cast<BinaryOperator>(E)) {
+        if (BinaryOperator* B = dyn_cast<BinaryOperator>(Exp)) {
           // Assignment expressions that are not nested within another
           // expression are really "statements" whose value is never
           // used by another expression.
-          if (B->isAssignmentOp() && !SubExprAssignments.count(E))
+          if (B->isAssignmentOp() && !SubExprAssignments.count(Exp))
             continue;
         }
-        else if (const StmtExpr* S = dyn_cast<StmtExpr>(E)) {
+        else if (const StmtExpr* Terminator = dyn_cast<StmtExpr>(Exp)) {
           // Special handling for statement expressions.  The last statement
           // in the statement expression is also a block-level expr.
-          const CompoundStmt* C = S->getSubStmt();
+          const CompoundStmt* C = Terminator->getSubStmt();
           if (!C->body_empty()) {
             unsigned x = M->size();
             (*M)[C->body_back()] = x;
@@ -1108,9 +1112,19 @@
         }
 
         unsigned x = M->size();
-        (*M)[E] = x;
+        (*M)[Exp] = x;
       }
     
+    // Look at terminators.  The condition is a block-level expression.
+    
+    Expr* Exp = I->getTerminatorCondition();
+    
+    if (Exp && M->find(Exp) == M->end()) {
+        unsigned x = M->size();
+        (*M)[Exp] = x;
+    }
+  }
+    
   return M;
 }
 
@@ -1182,9 +1196,9 @@
   void setBlockID(signed i) { CurrentBlock = i; }
   void setStmtID(unsigned i) { CurrentStmt = i; }
   
-  virtual bool handledStmt(Stmt* S, std::ostream& OS) {
+  virtual bool handledStmt(Stmt* Terminator, std::ostream& OS) {
     
-    StmtMapTy::iterator I = StmtMap.find(S);
+    StmtMapTy::iterator I = StmtMap.find(Terminator);
 
     if (I == StmtMap.end())
       return false;
@@ -1213,7 +1227,7 @@
   }
   
   // Default case.
-  void VisitStmt(Stmt* S) { S->printPretty(OS); }
+  void VisitStmt(Stmt* Terminator) { Terminator->printPretty(OS); }
   
   void VisitForStmt(ForStmt* F) {
     OS << "for (" ;
@@ -1235,9 +1249,9 @@
     if (Stmt* C = D->getCond()) C->printPretty(OS,Helper);
   }
   
-  void VisitSwitchStmt(SwitchStmt* S) {
+  void VisitSwitchStmt(SwitchStmt* Terminator) {
     OS << "switch ";
-    S->getCond()->printPretty(OS,Helper);
+    Terminator->getCond()->printPretty(OS,Helper);
   }
   
   void VisitConditionalOperator(ConditionalOperator* C) {
@@ -1282,10 +1296,10 @@
 };
   
   
-void print_stmt(std::ostream&OS, StmtPrinterHelper* Helper, Stmt* S) {    
+void print_stmt(std::ostream&OS, StmtPrinterHelper* Helper, Stmt* Terminator) {    
   if (Helper) {
     // special printing for statement-expressions.
-    if (StmtExpr* SE = dyn_cast<StmtExpr>(S)) {
+    if (StmtExpr* SE = dyn_cast<StmtExpr>(Terminator)) {
       CompoundStmt* Sub = SE->getSubStmt();
       
       if (Sub->child_begin() != Sub->child_end()) {
@@ -1297,7 +1311,7 @@
     }
     
     // special printing for comma expressions.
-    if (BinaryOperator* B = dyn_cast<BinaryOperator>(S)) {
+    if (BinaryOperator* B = dyn_cast<BinaryOperator>(Terminator)) {
       if (B->getOpcode() == BinaryOperator::Comma) {
         OS << "... , ";
         Helper->handledStmt(B->getRHS(),OS);
@@ -1307,10 +1321,10 @@
     }  
   }
   
-  S->printPretty(OS, Helper);
+  Terminator->printPretty(OS, Helper);
   
   // Expressions need a newline.
-  if (isa<Expr>(S)) OS << '\n';
+  if (isa<Expr>(Terminator)) OS << '\n';
 }
   
 void print_block(std::ostream& OS, const CFG* cfg, const CFGBlock& B,
@@ -1331,14 +1345,14 @@
     OS << " ]\n";
  
   // Print the label of this block.
-  if (Stmt* S = const_cast<Stmt*>(B.getLabel())) {
+  if (Stmt* Terminator = const_cast<Stmt*>(B.getLabel())) {
 
     if (print_edges)
       OS << "    ";
   
-    if (LabelStmt* L = dyn_cast<LabelStmt>(S))
+    if (LabelStmt* L = dyn_cast<LabelStmt>(Terminator))
       OS << L->getName();
-    else if (CaseStmt* C = dyn_cast<CaseStmt>(S)) {
+    else if (CaseStmt* C = dyn_cast<CaseStmt>(Terminator)) {
       OS << "case ";
       C->getLHS()->printPretty(OS);
       if (C->getRHS()) {
@@ -1346,7 +1360,7 @@
         C->getRHS()->printPretty(OS);
       }
     }  
-    else if (isa<DefaultStmt>(S))
+    else if (isa<DefaultStmt>(Terminator))
       OS << "default";
     else
       assert(false && "Invalid label statement in CFGBlock.");
@@ -1461,6 +1475,57 @@
   TPrinter.Visit(const_cast<Stmt*>(getTerminator()));
 }
 
+Expr* CFGBlock::getTerminatorCondition() {
+  
+  if (!Terminator)
+    return NULL;
+  
+  Expr* E = NULL;
+  
+  switch (Terminator->getStmtClass()) {
+    default:
+      break;
+      
+    case Stmt::ForStmtClass:
+      E = cast<ForStmt>(Terminator)->getCond();
+      break;
+      
+    case Stmt::WhileStmtClass:
+      E = cast<WhileStmt>(Terminator)->getCond();
+      break;
+      
+    case Stmt::DoStmtClass:
+      E = cast<DoStmt>(Terminator)->getCond();
+      break;
+      
+    case Stmt::IfStmtClass:
+      E = cast<IfStmt>(Terminator)->getCond();
+      break;
+      
+    case Stmt::ChooseExprClass:
+      E = cast<ChooseExpr>(Terminator)->getCond();
+      break;
+      
+    case Stmt::IndirectGotoStmtClass:
+      E = cast<IndirectGotoStmt>(Terminator)->getTarget();
+      break;
+      
+    case Stmt::SwitchStmtClass:
+      E = cast<SwitchStmt>(Terminator)->getCond();
+      break;
+      
+    case Stmt::ConditionalOperatorClass:
+      E = cast<ConditionalOperator>(Terminator)->getCond();
+      break;
+      
+    case Stmt::BinaryOperatorClass: // '&&' and '||'
+      E = cast<BinaryOperator>(Terminator)->getLHS();
+      break;      
+  }
+  
+  return E ? E->IgnoreParens() : NULL;
+}
+
 
 //===----------------------------------------------------------------------===//
 // CFG Graphviz Visualization

Modified: cfe/trunk/lib/Analysis/LiveVariables.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/LiveVariables.cpp?rev=49818&r1=49817&r2=49818&view=diff

==============================================================================
--- cfe/trunk/lib/Analysis/LiveVariables.cpp (original)
+++ cfe/trunk/lib/Analysis/LiveVariables.cpp Wed Apr 16 16:10:48 2008
@@ -119,7 +119,7 @@
   void VisitDeclStmt(DeclStmt* DS);
   void VisitUnaryOperator(UnaryOperator* U);
   void Visit(Stmt *S);  
-  void VisitTerminator(Stmt* S); 
+  void VisitTerminator(CFGBlock* B); 
   
   void SetTopValue(LiveVariables::ValTy& V) {
     V = AD.AlwaysLive;    
@@ -142,56 +142,13 @@
     LiveState(S,AD) = Alive;
 }
   
-void TransferFuncs::VisitTerminator(Stmt* S) {
-  
-  Expr* E = NULL;
-  
-  switch (S->getStmtClass()) {
-    default:
-      return;
-      
-    case Stmt::ForStmtClass:
-      E = cast<ForStmt>(S)->getCond();
-      break;
-      
-    case Stmt::WhileStmtClass:
-      E = cast<WhileStmt>(S)->getCond();
-      break;
-      
-    case Stmt::DoStmtClass:
-      E = cast<DoStmt>(S)->getCond();
-      break;
-      
-    case Stmt::IfStmtClass:
-      E = cast<IfStmt>(S)->getCond();
-      break;
-      
-    case Stmt::ChooseExprClass:
-      E = cast<ChooseExpr>(S)->getCond();
-      break;
-      
-    case Stmt::IndirectGotoStmtClass:
-      E = cast<IndirectGotoStmt>(S)->getTarget();
-      break;
-      
-    case Stmt::SwitchStmtClass:
-      E = cast<SwitchStmt>(S)->getCond();
-      break;
-      
-    case Stmt::ConditionalOperatorClass:
-      E = cast<ConditionalOperator>(S)->getCond();
-      break;
-      
-    case Stmt::BinaryOperatorClass: // '&&' and '||'
-      E = cast<BinaryOperator>(S)->getLHS();
-      break;      
-  }
-  
+void TransferFuncs::VisitTerminator(CFGBlock* B) {
+    
+  const Expr* E = B->getTerminatorCondition();
+
   if (!E)
     return;
   
-  E = E->IgnoreParens();
-  
   assert (getCFG().isBlkExpr(E));
   LiveState(E, AD) = Alive;
 }

Modified: cfe/trunk/lib/Analysis/UninitializedValues.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/UninitializedValues.cpp?rev=49818&r1=49817&r2=49818&view=diff

==============================================================================
--- cfe/trunk/lib/Analysis/UninitializedValues.cpp (original)
+++ cfe/trunk/lib/Analysis/UninitializedValues.cpp Wed Apr 16 16:10:48 2008
@@ -78,7 +78,7 @@
   bool Visit(Stmt *S);
   bool BlockStmt_VisitExpr(Expr* E);
     
-  void VisitTerminator(Stmt* T) { }
+  void VisitTerminator(CFGBlock* B) { }
 };
   
 static const bool Initialized = true;





More information about the cfe-commits mailing list