[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