From: Ted Kremenek Date: Sat, 26 Jan 2008 00:03:27 +0000 (+0000) Subject: Added back logic in patch r46361 (http://llvm.org/viewvc/llvm-project?rev=46361&view... X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=33d4aab80f31bd06257526fe2883ea920529456b;p=clang 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 --- 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 BlkExprMapTy; } +static void FindSubExprAssignments(Stmt* S, llvm::SmallPtrSet& 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(*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 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(*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(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(*BI)) { + + if (BinaryOperator* B = dyn_cast(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(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*>(this)->Visit(E); + bool x = static_cast*>(this)->Visit(E); + if (AD.isTracked(E)) V(E,AD) = x; + return x; } } // end anonymous namespace