[cfe-commits] r47586 - in /cfe/trunk: Analysis/GRExprEngine.cpp Analysis/RValues.cpp Analysis/SymbolManager.cpp Analysis/ValueState.cpp include/clang/Analysis/PathSensitive/GRExprEngine.h include/clang/Analysis/PathSensitive/RValues.h include/clang/Analysis/PathSensitive/SymbolManager.h
Ted Kremenek
kremenek at apple.com
Mon Feb 25 18:15:56 PST 2008
Author: kremenek
Date: Mon Feb 25 20:15:56 2008
New Revision: 47586
URL: http://llvm.org/viewvc/llvm-project?rev=47586&view=rev
Log:
Added lazy "symbolication" of parameter variables and global variables.
Added recording of divide-by-zero and divide-by-uninitialized nodes.
Modified:
cfe/trunk/Analysis/GRExprEngine.cpp
cfe/trunk/Analysis/RValues.cpp
cfe/trunk/Analysis/SymbolManager.cpp
cfe/trunk/Analysis/ValueState.cpp
cfe/trunk/include/clang/Analysis/PathSensitive/GRExprEngine.h
cfe/trunk/include/clang/Analysis/PathSensitive/RValues.h
cfe/trunk/include/clang/Analysis/PathSensitive/SymbolManager.h
Modified: cfe/trunk/Analysis/GRExprEngine.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/Analysis/GRExprEngine.cpp?rev=47586&r1=47585&r2=47586&view=diff
==============================================================================
--- cfe/trunk/Analysis/GRExprEngine.cpp (original)
+++ cfe/trunk/Analysis/GRExprEngine.cpp Mon Feb 25 20:15:56 2008
@@ -396,6 +396,22 @@
void GRExprEngine::VisitDeclRefExpr(DeclRefExpr* D, NodeTy* Pred, NodeSet& Dst){
+ if (VarDecl* VD = dyn_cast<VarDecl>(D->getDecl()))
+ if (VD->hasGlobalStorage() || isa<ParmVarDecl>(VD)) {
+
+ StateTy StOld = Pred->getState();
+ StateTy St = Symbolicate(StOld, VD);
+
+ if (!(St == StOld)) {
+ if (D != CurrentStmt)
+ Nodify(Dst, D, Pred, St);
+ else
+ Nodify(Dst, D, Pred, SetRVal(St, D, GetRVal(St, D)));
+
+ return;
+ }
+ }
+
if (D != CurrentStmt) {
Dst.Add(Pred); // No-op. Simply propagate the current state unchanged.
return;
@@ -796,7 +812,20 @@
Ex = Ex->IgnoreParens();
- if (isa<DeclRefExpr>(Ex)) {
+ if (DeclRefExpr* DR = dyn_cast<DeclRefExpr>(Ex)) {
+
+ if (VarDecl* VD = dyn_cast<VarDecl>(DR->getDecl()))
+ if (VD->hasGlobalStorage() || isa<ParmVarDecl>(VD)) {
+
+ StateTy StOld = Pred->getState();
+ StateTy St = Symbolicate(StOld, VD);
+
+ if (!(St == StOld)) {
+ Nodify(Dst, Ex, Pred, St);
+ return;
+ }
+ }
+
Dst.Add(Pred);
return;
}
@@ -857,20 +886,33 @@
if ((Op == BinaryOperator::Div || Op == BinaryOperator::Rem)
&& RHS->getType()->isIntegerType()) {
+
+ // Check if the denominator is uninitialized.
- // Check for divide/remaindner-by-zero.
-
- // First, "assume" that the denominator is 0.
+ if (RightV.isUninit()) {
+ NodeTy* DivUninit = Builder->generateNode(B, St, N2);
+
+ if (DivUninit) {
+ DivUninit->markAsSink();
+ BadDivides.insert(DivUninit);
+ }
+
+ continue;
+ }
+
+ // Check for divide/remainder-by-zero.
+ //
+ // First, "assume" that the denominator is 0 or uninitialized.
bool isFeasible = false;
- StateTy ZeroSt = Assume(St, RightV, false, isFeasible);
+ StateTy ZeroSt = Assume(St, RightV, false,isFeasible);
if (isFeasible) {
NodeTy* DivZeroNode = Builder->generateNode(B, ZeroSt, N2);
if (DivZeroNode) {
DivZeroNode->markAsSink();
- DivZeroes.insert(DivZeroNode);
+ BadDivides.insert(DivZeroNode);
}
}
@@ -1003,8 +1045,19 @@
if ((Op == BinaryOperator::Div || Op == BinaryOperator::Rem)
&& RHS->getType()->isIntegerType()) {
- // Check for divide/remainder-by-zero.
-
+ // Check if the denominator is uninitialized.
+
+ if (RightV.isUninit()) {
+ NodeTy* DivUninit = Builder->generateNode(B, St, N2);
+
+ if (DivUninit) {
+ DivUninit->markAsSink();
+ BadDivides.insert(DivUninit);
+ }
+
+ continue;
+ }
+
// First, "assume" that the denominator is 0.
bool isFeasible = false;
@@ -1015,7 +1068,7 @@
if (DivZeroNode) {
DivZeroNode->markAsSink();
- DivZeroes.insert(DivZeroNode);
+ BadDivides.insert(DivZeroNode);
}
}
Modified: cfe/trunk/Analysis/RValues.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/Analysis/RValues.cpp?rev=47586&r1=47585&r2=47586&view=diff
==============================================================================
--- cfe/trunk/Analysis/RValues.cpp (original)
+++ cfe/trunk/Analysis/RValues.cpp Mon Feb 25 20:15:56 2008
@@ -214,7 +214,7 @@
return nonlval::ConcreteInt(ValMgr.getTruthValue(b));
}
-RVal RVal::GetSymbolValue(SymbolManager& SymMgr, ParmVarDecl* D) {
+RVal RVal::GetSymbolValue(SymbolManager& SymMgr, VarDecl* D) {
QualType T = D->getType();
Modified: cfe/trunk/Analysis/SymbolManager.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/Analysis/SymbolManager.cpp?rev=47586&r1=47585&r2=47586&view=diff
==============================================================================
--- cfe/trunk/Analysis/SymbolManager.cpp (original)
+++ cfe/trunk/Analysis/SymbolManager.cpp Mon Feb 25 20:15:56 2008
@@ -16,17 +16,24 @@
using namespace clang;
-SymbolID SymbolManager::getSymbol(ParmVarDecl* D) {
+SymbolID SymbolManager::getSymbol(VarDecl* D) {
+
+ assert (isa<ParmVarDecl>(D) || D->hasGlobalStorage());
+
SymbolID& X = DataToSymbol[getKey(D)];
if (!X.isInitialized()) {
X = SymbolToData.size();
- SymbolToData.push_back(SymbolDataParmVar(D));
+
+ if (ParmVarDecl* VD = dyn_cast<ParmVarDecl>(D))
+ SymbolToData.push_back(SymbolDataParmVar(VD));
+ else
+ SymbolToData.push_back(SymbolDataGlobalVar(D));
}
return X;
-}
-
+}
+
SymbolID SymbolManager::getContentsOfSymbol(SymbolID sym) {
SymbolID& X = DataToSymbol[getKey(sym)];
@@ -45,6 +52,9 @@
case ParmKind:
return cast<SymbolDataParmVar>(this)->getDecl()->getType();
+
+ case GlobalKind:
+ return cast<SymbolDataGlobalVar>(this)->getDecl()->getType();
case ContentsOfKind: {
SymbolID x = cast<SymbolDataContentsOf>(this)->getSymbol();
Modified: cfe/trunk/Analysis/ValueState.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/Analysis/ValueState.cpp?rev=47586&r1=47585&r2=47586&view=diff
==============================================================================
--- cfe/trunk/Analysis/ValueState.cpp (original)
+++ cfe/trunk/Analysis/ValueState.cpp Mon Feb 25 20:15:56 2008
@@ -78,8 +78,16 @@
// Iterate over the variable bindings.
for (ValueState::vb_iterator I = St.vb_begin(), E = St.vb_end(); I!=E ; ++I)
- if (Liveness.isLive(Loc, I.getKey()))
+ if (Liveness.isLive(Loc, I.getKey())) {
WList.push_back(I.getKey());
+
+ RVal X = I.getData();
+
+ for (RVal::symbol_iterator SI = X.symbol_begin(), SE = X.symbol_end();
+ SI != SE; ++SI) {
+ MarkedSymbols.insert(*SI);
+ }
+ }
// Perform the mark-and-sweep.
Modified: cfe/trunk/include/clang/Analysis/PathSensitive/GRExprEngine.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Analysis/PathSensitive/GRExprEngine.h?rev=47586&r1=47585&r2=47586&view=diff
==============================================================================
--- cfe/trunk/include/clang/Analysis/PathSensitive/GRExprEngine.h (original)
+++ cfe/trunk/include/clang/Analysis/PathSensitive/GRExprEngine.h Mon Feb 25 20:15:56 2008
@@ -135,9 +135,9 @@
/// taking a dereference on an uninitialized value.
BadDerefTy UninitDeref;
- /// DivZeroes - Nodes in the ExplodedGraph that result from evaluating
- /// a divide-by-zero.
- DivZerosTy DivZeroes;
+ /// BadDivides - Nodes in the ExplodedGraph that result from evaluating
+ /// a divide-by-zero or divide-by-uninitialized.
+ DivZerosTy BadDivides;
bool StateCleaned;
@@ -172,20 +172,7 @@
/// getInitialState - Return the initial state used for the root vertex
/// in the ExplodedGraph.
- StateTy getInitialState() {
- StateTy St = StateMgr.getInitialState();
-
- // Iterate the parameters.
- FunctionDecl& F = G.getFunctionDecl();
-
- for (FunctionDecl::param_iterator I = F.param_begin(), E = F.param_end();
- I != E; ++I) {
- St = SetRVal(St, lval::DeclVal(*I),
- RVal::GetSymbolValue(SymMgr, *I));
- }
-
- return St;
- }
+ StateTy getInitialState() { return StateMgr.getInitialState(); }
bool isUninitControlFlow(const NodeTy* N) const {
return N->isSink() && UninitBranches.count(const_cast<NodeTy*>(N)) != 0;
@@ -207,6 +194,10 @@
return N->isSink() && UninitDeref.count(const_cast<NodeTy*>(N)) != 0;
}
+ bool isBadDivide(const NodeTy* N) const {
+ return N->isSink() && BadDivides.count(const_cast<NodeTy*>(N)) != 0;
+ }
+
typedef BadDerefTy::iterator null_iterator;
null_iterator null_begin() { return ExplicitNullDeref.begin(); }
null_iterator null_end() { return ExplicitNullDeref.end(); }
@@ -271,6 +262,15 @@
return StateMgr.GetLVal(St, Ex);
}
+ StateTy Symbolicate(StateTy St, VarDecl* VD) {
+ lval::DeclVal X(VD);
+
+ if (GetRVal(St, X).isUnknown()) {
+ return SetRVal(St, lval::DeclVal(VD), RVal::GetSymbolValue(SymMgr, VD));
+ }
+ else return St;
+ }
+
inline NonLVal MakeConstantVal(uint64_t X, Expr* Ex) {
return NonLVal::MakeVal(ValMgr, X, Ex->getType(), Ex->getLocStart());
}
Modified: cfe/trunk/include/clang/Analysis/PathSensitive/RValues.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Analysis/PathSensitive/RValues.h?rev=47586&r1=47585&r2=47586&view=diff
==============================================================================
--- cfe/trunk/include/clang/Analysis/PathSensitive/RValues.h (original)
+++ cfe/trunk/include/clang/Analysis/PathSensitive/RValues.h Mon Feb 25 20:15:56 2008
@@ -65,7 +65,7 @@
return !(*this == R);
}
- static RVal GetSymbolValue(SymbolManager& SymMgr, ParmVarDecl *D);
+ static RVal GetSymbolValue(SymbolManager& SymMgr, VarDecl *D);
inline bool isUnknown() const {
return getRawKind() == UnknownKind;
Modified: cfe/trunk/include/clang/Analysis/PathSensitive/SymbolManager.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Analysis/PathSensitive/SymbolManager.h?rev=47586&r1=47585&r2=47586&view=diff
==============================================================================
--- cfe/trunk/include/clang/Analysis/PathSensitive/SymbolManager.h (original)
+++ cfe/trunk/include/clang/Analysis/PathSensitive/SymbolManager.h Mon Feb 25 20:15:56 2008
@@ -49,7 +49,7 @@
class SymbolData {
public:
- enum Kind { UninitKind, ParmKind, ContentsOfKind };
+ enum Kind { UninitKind, ParmKind, GlobalKind, ContentsOfKind };
private:
uintptr_t Data;
@@ -95,6 +95,18 @@
return D->getKind() == ParmKind;
}
};
+
+class SymbolDataGlobalVar : public SymbolData {
+public:
+ SymbolDataGlobalVar(VarDecl* VD) : SymbolData(VD, GlobalKind) {}
+
+ VarDecl* getDecl() const { return (VarDecl*) getPtr(); }
+
+ // Implement isa<T> support.
+ static inline bool classof(const SymbolData* D) {
+ return D->getKind() == GlobalKind;
+ }
+};
class SymbolDataContentsOf : public SymbolData {
public:
@@ -157,7 +169,7 @@
SymbolManager();
~SymbolManager();
- SymbolID getSymbol(ParmVarDecl* D);
+ SymbolID getSymbol(VarDecl* D);
SymbolID getContentsOfSymbol(SymbolID sym);
inline const SymbolData& getSymbolData(SymbolID ID) const {
More information about the cfe-commits
mailing list