[cfe-commits] r46143 - in /cfe/trunk: AST/CFG.cpp Analysis/LiveVariables.cpp include/clang/AST/CFG.h include/clang/Analysis/Analyses/LiveVariables.h include/clang/Analysis/FlowSensitive/DataflowSolver.h include/clang/Analysis/FlowSensitive/DataflowValues.h include/clang/Analysis/Support/ExprDeclBitVector.h include/clang/Analysis/Visitors/CFGStmtVisitor.h
Ted Kremenek
kremenek at apple.com
Thu Jan 17 12:48:38 PST 2008
Author: kremenek
Date: Thu Jan 17 14:48:37 2008
New Revision: 46143
URL: http://llvm.org/viewvc/llvm-project?rev=46143&view=rev
Log:
Modified the notion of "Block-level expressions" in CFGs to include Stmt*. This
is because GNU-style Statement-expressions cause the last statement in the
statement-expression to act like an expression.
We now have two notions: block-level statements and block-level expressions.
The former are all Stmt* that appear in the list of statements in CFGBlocks. The
latter is the subset of the former; these block-level statements are used as
subexpressions somewhere in the AST. CFG::isBlockExpr() returns true for the
latter, not the former (previously isBlockExpr() always returned true for
non-Expr Stmt*).
Modified the LiveVariables analysis to also track liveness state for block-level
expressions (using the updated definition of block-level expressions).
Modified the dataflow solver so that when it records values for block-level
statements, it records the dataflow value *before* the transfer function for a
Stmt* is evaluated (not after). This is more in sync in what clients will want.
Modified CFGStmtVisitor to record the current block-level statement.
Modified:
cfe/trunk/AST/CFG.cpp
cfe/trunk/Analysis/LiveVariables.cpp
cfe/trunk/include/clang/AST/CFG.h
cfe/trunk/include/clang/Analysis/Analyses/LiveVariables.h
cfe/trunk/include/clang/Analysis/FlowSensitive/DataflowSolver.h
cfe/trunk/include/clang/Analysis/FlowSensitive/DataflowValues.h
cfe/trunk/include/clang/Analysis/Support/ExprDeclBitVector.h
cfe/trunk/include/clang/Analysis/Visitors/CFGStmtVisitor.h
Modified: cfe/trunk/AST/CFG.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/AST/CFG.cpp?rev=46143&r1=46142&r2=46143&view=diff
==============================================================================
--- cfe/trunk/AST/CFG.cpp (original)
+++ cfe/trunk/AST/CFG.cpp Thu Jan 17 14:48:37 2008
@@ -988,7 +988,7 @@
//===----------------------------------------------------------------------===//
namespace {
- typedef llvm::DenseMap<const Expr*,unsigned> BlkExprMapTy;
+ typedef llvm::DenseMap<const Stmt*,unsigned> BlkExprMapTy;
}
static BlkExprMapTy* PopulateBlkExprMap(CFG& cfg) {
@@ -999,23 +999,27 @@
if (const Expr* E = dyn_cast<Expr>(*BI)) {
unsigned x = M->size();
(*M)[E] = x;
+
+ // 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)) {
+ const CompoundStmt* C = S->getSubStmt();
+ if (!C->body_empty()) {
+ x = M->size();
+ (*M)[C->body_back()] = x;
+ }
+ }
}
-
- return M;
-}
-bool CFG::isBlkExpr(const Stmt* S) {
- assert (S != NULL);
- if (const Expr* E = dyn_cast<Expr>(S)) return getBlkExprNum(E);
- else return true; // Statements are by default "block-level expressions."
+ return M;
}
-CFG::BlkExprNumTy CFG::getBlkExprNum(const Expr* E) {
- assert(E != NULL);
+CFG::BlkExprNumTy CFG::getBlkExprNum(const Stmt* S) {
+ assert(S != NULL);
if (!BlkExprMap) { BlkExprMap = (void*) PopulateBlkExprMap(*this); }
BlkExprMapTy* M = reinterpret_cast<BlkExprMapTy*>(BlkExprMap);
- BlkExprMapTy::iterator I = M->find(E);
+ BlkExprMapTy::iterator I = M->find(S);
if (I == M->end()) return CFG::BlkExprNumTy();
else return CFG::BlkExprNumTy(I->second);
Modified: cfe/trunk/Analysis/LiveVariables.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/Analysis/LiveVariables.cpp?rev=46143&r1=46142&r2=46143&view=diff
==============================================================================
--- cfe/trunk/Analysis/LiveVariables.cpp (original)
+++ cfe/trunk/Analysis/LiveVariables.cpp Thu Jan 17 14:48:37 2008
@@ -77,7 +77,16 @@
if (AD.Observer)
AD.Observer->ObserveStmt(S,AD,LiveState);
- static_cast<CFGStmtVisitor<TransferFuncs>*>(this)->Visit(S);
+
+ if (S == getCurrentBlkStmt()) {
+ StmtVisitor<TransferFuncs,void>::Visit(S);
+ if (getCFG().isBlkExpr(S)) LiveState(S,AD) = Dead;
+ }
+ else if (!getCFG().isBlkExpr(S))
+ StmtVisitor<TransferFuncs,void>::Visit(S);
+ else
+ // For block-level expressions, mark that they are live.
+ LiveState(S,AD) = Alive;
}
void TransferFuncs::VisitDeclRefExpr(DeclRefExpr* DR) {
@@ -186,6 +195,10 @@
return Live(D,getAnalysisData());
}
+bool LiveVariables::isLive(const Stmt* Loc, const Stmt* StmtVal) const {
+ return getStmtData(Loc)(StmtVal,getAnalysisData());
+}
+
//===----------------------------------------------------------------------===//
// printing liveness state for debugging
//
Modified: cfe/trunk/include/clang/AST/CFG.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/CFG.h?rev=46143&r1=46142&r2=46143&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/CFG.h (original)
+++ cfe/trunk/include/clang/AST/CFG.h Thu Jan 17 14:48:37 2008
@@ -255,9 +255,8 @@
operator unsigned() const { assert(Idx >=0); return (unsigned) Idx; }
};
- bool isBlkExpr(const Stmt* S);
- bool isBlkExpr(const Expr* E) { return getBlkExprNum(E); }
- BlkExprNumTy getBlkExprNum(const Expr* E);
+ bool isBlkExpr(const Stmt* S) { return getBlkExprNum(S); }
+ BlkExprNumTy getBlkExprNum(const Stmt* S);
unsigned getNumBlkExprs();
unsigned getNumBlockIDs() const { return NumBlockIDs; }
Modified: cfe/trunk/include/clang/Analysis/Analyses/LiveVariables.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Analysis/Analyses/LiveVariables.h?rev=46143&r1=46142&r2=46143&view=diff
==============================================================================
--- cfe/trunk/include/clang/Analysis/Analyses/LiveVariables.h (original)
+++ cfe/trunk/include/clang/Analysis/Analyses/LiveVariables.h Thu Jan 17 14:48:37 2008
@@ -30,11 +30,10 @@
// We need to keep track of both declarations and CFGBlock-level expressions,
- // (so that we don't explore such expressions twice), but we only need
- // liveness information for declarations (hence
- // ValTy = DeclBitVector_Types::ValTy instead of
- // ValTy = ExprDeclBitVector_Types::ValTy).
-
+ // (so that we don't explore such expressions twice). We also want
+ // to compute liveness information for block-level expressions, since these
+ // act as "temporary" values.
+
struct AnalysisDataTy : public ExprDeclBitVector_Types::AnalysisDataTy {
ObserverTy* Observer;
@@ -42,7 +41,7 @@
};
// We only keep actual dataflow state for declarations.
- typedef DeclBitVector_Types::ValTy ValTy;
+ typedef ExprDeclBitVector_Types::ValTy ValTy;
//===-----------------------------------------------------===//
// ObserverTy - Observer for uninitialized values queries.
@@ -76,6 +75,10 @@
/// has been recorded at the statement level (see runOnAllBlocks), and
/// only returns liveness information for block-level expressions.
bool isLive(const Stmt* S, const VarDecl* D) const;
+
+ /// IsLive - Returns true the block-level expression "value" is live
+ /// before the given block-level expression (see runOnAllBlocks).
+ bool isLive(const Stmt* Loc, const Stmt* StmtVal) const;
/// IsLive - Return true if a variable is live according to the
/// provided livness bitvector.
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=46143&r1=46142&r2=46143&view=diff
==============================================================================
--- cfe/trunk/include/clang/Analysis/FlowSensitive/DataflowSolver.h (original)
+++ cfe/trunk/include/clang/Analysis/FlowSensitive/DataflowSolver.h Thu Jan 17 14:48:37 2008
@@ -236,8 +236,8 @@
/// ProcessBlock - Process the transfer functions for a given block.
void ProcessBlock(const CFGBlock* B, bool recordStmtValues) {
for (StmtItr I=ItrTraits::StmtBegin(B), E=ItrTraits::StmtEnd(B); I!=E;++I) {
- TF.BlockStmt_Visit(const_cast<Stmt*>(*I));
if (recordStmtValues) D.getStmtDataMap()[*I] = TF.getVal();
+ TF.BlockStmt_Visit(const_cast<Stmt*>(*I));
}
}
Modified: cfe/trunk/include/clang/Analysis/FlowSensitive/DataflowValues.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Analysis/FlowSensitive/DataflowValues.h?rev=46143&r1=46142&r2=46143&view=diff
==============================================================================
--- cfe/trunk/include/clang/Analysis/FlowSensitive/DataflowValues.h (original)
+++ cfe/trunk/include/clang/Analysis/FlowSensitive/DataflowValues.h Thu Jan 17 14:48:37 2008
@@ -110,9 +110,9 @@
/// getStmtData - Retrieves the dataflow values associated with a
/// specified Stmt. If the dataflow analysis is a forward analysis,
- /// this data corresponds to the point immediately after a Stmt.
+ /// this data corresponds to the point immediately before a Stmt.
/// If the analysis is a backwards analysis, it is associated with
- /// the point before a Stmt. This data is only computed for block-level
+ /// the point after a Stmt. This data is only computed for block-level
/// expressions, and only when requested when the analysis is executed.
ValTy& getStmtData(const Stmt* S) {
assert (StmtDataMap && "Dataflow values were not computed for statements.");
Modified: cfe/trunk/include/clang/Analysis/Support/ExprDeclBitVector.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Analysis/Support/ExprDeclBitVector.h?rev=46143&r1=46142&r2=46143&view=diff
==============================================================================
--- cfe/trunk/include/clang/Analysis/Support/ExprDeclBitVector.h (original)
+++ cfe/trunk/include/clang/Analysis/Support/ExprDeclBitVector.h Thu Jan 17 14:48:37 2008
@@ -139,11 +139,11 @@
void setCFG(CFG* c) { cfg = c; }
CFG& getCFG() { assert(cfg && "CFG should not be NULL."); return *cfg; }
- bool isTracked(const Expr* E) { return cfg->isBlkExpr(E); }
+ bool isTracked(const Stmt* S) { return cfg->isBlkExpr(S); }
using DeclBitVector_Types::AnalysisDataTy::isTracked;
- unsigned getIdx(const Expr* E) const {
- CFG::BlkExprNumTy I = cfg->getBlkExprNum(E);
+ unsigned getIdx(const Stmt* S) const {
+ CFG::BlkExprNumTy I = cfg->getBlkExprNum(S);
assert(I && "expression not tracked for bitvector.");
return I;
}
@@ -187,12 +187,12 @@
}
llvm::BitVector::reference
- operator()(const Expr* E, const AnalysisDataTy& AD) {
- return ExprBV[AD.getIdx(E)];
+ operator()(const Stmt* S, const AnalysisDataTy& AD) {
+ return ExprBV[AD.getIdx(S)];
}
const llvm::BitVector::reference
- operator()(const Expr* E, const AnalysisDataTy& AD) const {
- return const_cast<ValTy&>(*this)(E,AD);
+ operator()(const Stmt* S, const AnalysisDataTy& AD) const {
+ return const_cast<ValTy&>(*this)(S,AD);
}
using DeclBitVector_Types::ValTy::operator();
Modified: cfe/trunk/include/clang/Analysis/Visitors/CFGStmtVisitor.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Analysis/Visitors/CFGStmtVisitor.h?rev=46143&r1=46142&r2=46143&view=diff
==============================================================================
--- cfe/trunk/include/clang/Analysis/Visitors/CFGStmtVisitor.h (original)
+++ cfe/trunk/include/clang/Analysis/Visitors/CFGStmtVisitor.h Thu Jan 17 14:48:37 2008
@@ -33,7 +33,7 @@
template <typename ImplClass, typename RetTy=void>
class CFGStmtVisitor : public StmtVisitor<ImplClass,RetTy> {
- Stmt* CurrentBlkExpr;
+ Stmt* CurrentBlkStmt;
struct NullifyStmt {
Stmt*& S;
@@ -42,11 +42,13 @@
~NullifyStmt() { S = NULL; }
};
-public:
- CFGStmtVisitor() : CurrentBlkExpr(NULL) {}
+public:
+ CFGStmtVisitor() : CurrentBlkStmt(NULL) {}
+
+ Stmt* getCurrentBlkStmt() const { return CurrentBlkStmt; }
RetTy Visit(Stmt* S) {
- if (S == CurrentBlkExpr ||
+ if (S == CurrentBlkStmt ||
!static_cast<ImplClass*>(this)->getCFG().isBlkExpr(S))
return StmtVisitor<ImplClass,RetTy>::Visit(S);
else
@@ -59,8 +61,8 @@
/// is no implementation provided for a BlockStmt_XXX method, we default
/// to using StmtVisitor's Visit method.
RetTy BlockStmt_Visit(Stmt* S) {
- CurrentBlkExpr = S;
- NullifyStmt cleanup(CurrentBlkExpr);
+ CurrentBlkStmt = S;
+ NullifyStmt cleanup(CurrentBlkStmt);
switch (S->getStmtClass()) {
DISPATCH_CASE(CallExpr)
More information about the cfe-commits
mailing list