From 463b7266987fd124cac64819c55510a116537989 Mon Sep 17 00:00:00 2001 From: Ted Kremenek Date: Fri, 25 Jan 2008 18:28:28 +0000 Subject: [PATCH] When adding assignment expressions to the set of block-level expressions, only include the assignment expressions whose result (as in the value of the expression) is used by other expressions. llvm-svn: 46361 --- clang/AST/CFG.cpp | 43 +++++++++++++++++++++++++++++++++++-------- 1 file changed, 35 insertions(+), 8 deletions(-) diff --git a/clang/AST/CFG.cpp b/clang/AST/CFG.cpp index 7a13ac187a2a..15e8f407fe7f 100644 --- a/clang/AST/CFG.cpp +++ b/clang/AST/CFG.cpp @@ -991,26 +991,53 @@ namespace { typedef llvm::DenseMap BlkExprMapTy; } +static void FindSubExprAssignments(Stmt* S, llvm::SmallPtrSet& Set) { + for (Stmt::child_iterator I=S->child_begin(), E=S->child_end(); I!=E; ++I) { + 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; }