aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTed Kremenek <kremenek@apple.com>2008-01-26 00:03:27 +0000
committerTed Kremenek <kremenek@apple.com>2008-01-26 00:03:27 +0000
commit33d4aab80f31bd06257526fe2883ea920529456b (patch)
tree209a452acefaf19029b2d437f49360a26b159acb
parent5c1e262a1092183f3fb8986cf99fdc584c479b15 (diff)
Added back logic in patch r46361 (http://llvm.org/viewvc/llvm-project?rev=46361&view=rev) with the addition of
some previously missing NULL pointer checks. Modified the UninitializedValues analysis to not expect that every Expr* at the block-level is a block-level expression (we probably need to change the name of such expressions to something truer to their meaning). git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@46380 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--AST/CFG.cpp48
-rw-r--r--Analysis/UninitializedValues.cpp6
2 files changed, 43 insertions, 11 deletions
diff --git a/AST/CFG.cpp b/AST/CFG.cpp
index 7a13ac187a..8e2d95017c 100644
--- a/AST/CFG.cpp
+++ b/AST/CFG.cpp
@@ -991,26 +991,58 @@ namespace {
typedef llvm::DenseMap<const Stmt*,unsigned> BlkExprMapTy;
}
+static void FindSubExprAssignments(Stmt* S, llvm::SmallPtrSet<Expr*,50>& Set) {
+ if (!S)
+ return;
+
+ for (Stmt::child_iterator I=S->child_begin(), E=S->child_end(); I!=E; ++I) {
+ if (!*I) continue;
+
+ if (BinaryOperator* B = dyn_cast<BinaryOperator>(*I))
+ if (B->isAssignmentOp()) Set.insert(B);
+
+ FindSubExprAssignments(*I, Set);
+ }
+}
+
static BlkExprMapTy* PopulateBlkExprMap(CFG& cfg) {
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.
+ 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)
- if (const Expr* E = dyn_cast<Expr>(*BI)) {
- unsigned x = M->size();
- (*M)[E] = x;
+ FindSubExprAssignments(*BI, SubExprAssignments);
- // Special handling for statement expressions. The last statement
- // in the statement expression is also a block-level expr.
- if (const StmtExpr* S = dyn_cast<StmtExpr>(E)) {
+ // 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 (CFGBlock::iterator BI=I->begin(), EI=I->end(); BI != EI; ++BI)
+ if (Expr* E = dyn_cast<Expr>(*BI)) {
+
+ if (BinaryOperator* B = dyn_cast<BinaryOperator>(E)) {
+ // 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))
+ continue;
+ }
+ else if (const StmtExpr* S = dyn_cast<StmtExpr>(E)) {
+ // Special handling for statement expressions. The last statement
+ // in the statement expression is also a block-level expr.
const CompoundStmt* C = S->getSubStmt();
if (!C->body_empty()) {
- x = M->size();
+ unsigned x = M->size();
(*M)[C->body_back()] = x;
}
}
- }
+ unsigned x = M->size();
+ (*M)[E] = x;
+ }
+
return M;
}
diff --git a/Analysis/UninitializedValues.cpp b/Analysis/UninitializedValues.cpp
index 25bcb86b54..25a5ecb483 100644
--- a/Analysis/UninitializedValues.cpp
+++ b/Analysis/UninitializedValues.cpp
@@ -201,9 +201,9 @@ bool TransferFuncs::Visit(Stmt *S) {
}
bool TransferFuncs::BlockStmt_VisitExpr(Expr* E) {
- assert (AD.isTracked(E));
- return V(E,AD) =
- static_cast<CFGStmtVisitor<TransferFuncs,bool>*>(this)->Visit(E);
+ bool x = static_cast<CFGStmtVisitor<TransferFuncs,bool>*>(this)->Visit(E);
+ if (AD.isTracked(E)) V(E,AD) = x;
+ return x;
}
} // end anonymous namespace