[cfe-commits] r92342 - in /cfe/trunk: include/clang/Analysis/PathSensitive/Checker.h include/clang/Analysis/PathSensitive/GRExprEngine.h include/clang/Analysis/PathSensitive/GRState.h lib/Analysis/GRExprEngine.cpp lib/Analysis/MallocChecker.cpp lib/Analysis/SimpleConstraintManager.cpp lib/Frontend/AnalysisConsumer.cpp test/Analysis/malloc.c
Zhongxing Xu
xuzhongxing at gmail.com
Wed Dec 30 22:13:07 PST 2009
Author: zhongxingxu
Date: Thu Dec 31 00:13:07 2009
New Revision: 92342
URL: http://llvm.org/viewvc/llvm-project?rev=92342&view=rev
Log:
Let constraint manager inform checkers that some assumption logic has happend.
Add new states for symbolic regions tracked by malloc checker. This enables us
to do malloc checking more accurately. See test case.
Based on Lei Zhang's patch and discussion.
Modified:
cfe/trunk/include/clang/Analysis/PathSensitive/Checker.h
cfe/trunk/include/clang/Analysis/PathSensitive/GRExprEngine.h
cfe/trunk/include/clang/Analysis/PathSensitive/GRState.h
cfe/trunk/lib/Analysis/GRExprEngine.cpp
cfe/trunk/lib/Analysis/MallocChecker.cpp
cfe/trunk/lib/Analysis/SimpleConstraintManager.cpp
cfe/trunk/lib/Frontend/AnalysisConsumer.cpp
cfe/trunk/test/Analysis/malloc.c
Modified: cfe/trunk/include/clang/Analysis/PathSensitive/Checker.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Analysis/PathSensitive/Checker.h?rev=92342&r1=92341&r2=92342&view=diff
==============================================================================
--- cfe/trunk/include/clang/Analysis/PathSensitive/Checker.h (original)
+++ cfe/trunk/include/clang/Analysis/PathSensitive/Checker.h Thu Dec 31 00:13:07 2009
@@ -269,6 +269,11 @@
virtual bool EvalCallExpr(CheckerContext &C, const CallExpr *CE) {
return false;
}
+
+ virtual const GRState *EvalAssume(const GRState *state, SVal Cond,
+ bool Assumption) {
+ return state;
+ }
};
} // end clang namespace
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=92342&r1=92341&r2=92342&view=diff
==============================================================================
--- cfe/trunk/include/clang/Analysis/PathSensitive/GRExprEngine.h (original)
+++ cfe/trunk/include/clang/Analysis/PathSensitive/GRExprEngine.h Thu Dec 31 00:13:07 2009
@@ -80,7 +80,7 @@
typedef llvm::DenseMap<void *, unsigned> CheckerMap;
CheckerMap CheckerM;
- typedef std::vector<std::pair<void *, Checker*> >CheckersOrdered;
+ typedef std::vector<std::pair<void *, Checker*> > CheckersOrdered;
CheckersOrdered Checkers;
/// BR - The BugReporter associated with this engine. It is important that
@@ -111,10 +111,10 @@
GRStmtNodeBuilder &getBuilder() { assert(Builder); return *Builder; }
/// setTransferFunctions
- void setTransferFunctions(GRTransferFuncs* tf);
+ void setTransferFunctionsAndCheckers(GRTransferFuncs* tf);
void setTransferFunctions(GRTransferFuncs& tf) {
- setTransferFunctions(&tf);
+ setTransferFunctionsAndCheckers(&tf);
}
/// ViewGraph - Visualize the ExplodedGraph created by executing the
Modified: cfe/trunk/include/clang/Analysis/PathSensitive/GRState.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Analysis/PathSensitive/GRState.h?rev=92342&r1=92341&r2=92342&view=diff
==============================================================================
--- cfe/trunk/include/clang/Analysis/PathSensitive/GRState.h (original)
+++ cfe/trunk/include/clang/Analysis/PathSensitive/GRState.h Thu Dec 31 00:13:07 2009
@@ -41,6 +41,7 @@
class GRStateManager;
class GRTransferFuncs;
+class Checker;
typedef ConstraintManager* (*ConstraintManagerCreator)(GRStateManager&);
typedef StoreManager* (*StoreManagerCreator)(GRStateManager&);
@@ -160,6 +161,9 @@
SymbolManager &getSymbolManager() const;
GRTransferFuncs &getTransferFuncs() const;
+ std::vector<std::pair<void *, Checker *> >::iterator checker_begin() const;
+ std::vector<std::pair<void *, Checker *> >::iterator checker_end() const;
+
//==---------------------------------------------------------------------==//
// Constraints on values.
//==---------------------------------------------------------------------==//
@@ -418,6 +422,9 @@
/// for manipulating and creating SVals.
GRTransferFuncs* TF;
+ /// Reference to all checkers in GRExprEngine.
+ std::vector<std::pair<void *, Checker*> > *Checkers;
+
public:
GRStateManager(ASTContext& Ctx,
@@ -441,6 +448,8 @@
GRTransferFuncs& getTransferFuncs() { return *TF; }
+ std::vector<std::pair<void *, Checker *> > &getCheckers() { return *Checkers;}
+
BasicValueFactory &getBasicVals() {
return ValueMgr.getBasicValueFactory();
}
@@ -697,6 +706,16 @@
return getStateManager().getTransferFuncs();
}
+inline std::vector<std::pair<void *, Checker *> >::iterator
+GRState::checker_begin() const {
+ return getStateManager().getCheckers().begin();
+}
+
+inline std::vector<std::pair<void *, Checker *> >::iterator
+GRState::checker_end() const {
+ return getStateManager().getCheckers().end();
+}
+
template<typename T>
const GRState *GRState::add(typename GRStateTrait<T>::key_type K) const {
return getStateManager().add<T>(this, K, get_context<T>());
Modified: cfe/trunk/lib/Analysis/GRExprEngine.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/GRExprEngine.cpp?rev=92342&r1=92341&r2=92342&view=diff
==============================================================================
--- cfe/trunk/lib/Analysis/GRExprEngine.cpp (original)
+++ cfe/trunk/lib/Analysis/GRExprEngine.cpp Thu Dec 31 00:13:07 2009
@@ -330,8 +330,9 @@
// Utility methods.
//===----------------------------------------------------------------------===//
-void GRExprEngine::setTransferFunctions(GRTransferFuncs* tf) {
+void GRExprEngine::setTransferFunctionsAndCheckers(GRTransferFuncs* tf) {
StateMgr.TF = tf;
+ StateMgr.Checkers = &Checkers;
tf->RegisterChecks(*this);
tf->RegisterPrinters(getStateManager().Printers);
}
Modified: cfe/trunk/lib/Analysis/MallocChecker.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/MallocChecker.cpp?rev=92342&r1=92341&r2=92342&view=diff
==============================================================================
--- cfe/trunk/lib/Analysis/MallocChecker.cpp (original)
+++ cfe/trunk/lib/Analysis/MallocChecker.cpp Thu Dec 31 00:13:07 2009
@@ -23,13 +23,13 @@
namespace {
class RefState {
- enum Kind { Allocated, Released, Escaped } K;
+ enum Kind { AllocateUnchecked, AllocateFailed, Released, Escaped } K;
const Stmt *S;
public:
RefState(Kind k, const Stmt *s) : K(k), S(s) {}
- bool isAllocated() const { return K == Allocated; }
+ bool isAllocated() const { return K == AllocateUnchecked; }
bool isReleased() const { return K == Released; }
bool isEscaped() const { return K == Escaped; }
@@ -37,7 +37,12 @@
return K == X.K && S == X.S;
}
- static RefState getAllocated(const Stmt *s) { return RefState(Allocated, s); }
+ static RefState getAllocateUnchecked(const Stmt *s) {
+ return RefState(AllocateUnchecked, s);
+ }
+ static RefState getAllocateFailed() {
+ return RefState(AllocateFailed, 0);
+ }
static RefState getReleased(const Stmt *s) { return RefState(Released, s); }
static RefState getEscaped(const Stmt *s) { return RefState(Escaped, s); }
@@ -62,6 +67,8 @@
void EvalDeadSymbols(CheckerContext &C,const Stmt *S,SymbolReaper &SymReaper);
void EvalEndPath(GREndPathNodeBuilder &B, void *tag, GRExprEngine &Eng);
void PreVisitReturnStmt(CheckerContext &C, const ReturnStmt *S);
+ const GRState *EvalAssume(const GRState *state, SVal Cond, bool Assumption);
+
private:
void MallocMem(CheckerContext &C, const CallExpr *CE);
const GRState *MallocMemAux(CheckerContext &C, const CallExpr *CE,
@@ -74,6 +81,8 @@
};
} // end anonymous namespace
+typedef llvm::ImmutableMap<SymbolRef, RefState> RegionStateTy;
+
namespace clang {
template <>
struct GRStateTrait<RegionState>
@@ -144,7 +153,7 @@
SymbolRef Sym = RetVal.getAsLocSymbol();
assert(Sym);
// Set the symbol's state to Allocated.
- return state->set<RegionState>(Sym, RefState::getAllocated(CE));
+ return state->set<RegionState>(Sym, RefState::getAllocateUnchecked(CE));
}
void MallocChecker::FreeMem(CheckerContext &C, const CallExpr *CE) {
@@ -298,3 +307,18 @@
C.addTransition(state);
}
+
+const GRState *MallocChecker::EvalAssume(const GRState *state, SVal Cond,
+ bool Assumption) {
+ // If a symblic region is assumed to NULL, set its state to AllocateFailed.
+ // FIXME: should also check symbols assumed to non-null.
+
+ RegionStateTy RS = state->get<RegionState>();
+
+ for (RegionStateTy::iterator I = RS.begin(), E = RS.end(); I != E; ++I) {
+ if (state->getSymVal(I.getKey()))
+ state = state->set<RegionState>(I.getKey(),RefState::getAllocateFailed());
+ }
+
+ return state;
+}
Modified: cfe/trunk/lib/Analysis/SimpleConstraintManager.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/SimpleConstraintManager.cpp?rev=92342&r1=92341&r2=92342&view=diff
==============================================================================
--- cfe/trunk/lib/Analysis/SimpleConstraintManager.cpp (original)
+++ cfe/trunk/lib/Analysis/SimpleConstraintManager.cpp Thu Dec 31 00:13:07 2009
@@ -15,6 +15,7 @@
#include "SimpleConstraintManager.h"
#include "clang/Analysis/PathSensitive/GRExprEngine.h"
#include "clang/Analysis/PathSensitive/GRState.h"
+#include "clang/Analysis/PathSensitive/Checker.h"
namespace clang {
@@ -72,8 +73,17 @@
// EvalAssume is used to call into the GRTransferFunction object to perform
// any checker-specific update of the state based on this assumption being
// true or false.
- return state ? state->getTransferFuncs().EvalAssume(state, Cond, Assumption)
- : NULL;
+
+ if (!state)
+ return 0;
+
+ std::vector<std::pair<void *, Checker*> >::iterator
+ I = state->checker_begin(), E = state->checker_end();
+
+ for (; I != E; ++I) {
+ state = I->second->EvalAssume(state, Cond, Assumption);
+ }
+ return state->getTransferFuncs().EvalAssume(state, Cond, Assumption);
}
const GRState *SimpleConstraintManager::AssumeAux(const GRState *state,
@@ -128,8 +138,18 @@
// EvalAssume is used to call into the GRTransferFunction object to perform
// any checker-specific update of the state based on this assumption being
// true or false.
- return state ? state->getTransferFuncs().EvalAssume(state, Cond, Assumption)
- : NULL;
+
+ if (!state)
+ return 0;
+
+ std::vector<std::pair<void *, Checker*> >::iterator
+ I = state->checker_begin(), E = state->checker_end();
+
+ for (; I != E; ++I) {
+ state = I->second->EvalAssume(state, Cond, Assumption);
+ }
+
+ return state->getTransferFuncs().EvalAssume(state, Cond, Assumption);
}
const GRState *SimpleConstraintManager::AssumeAux(const GRState *state,
Modified: cfe/trunk/lib/Frontend/AnalysisConsumer.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/AnalysisConsumer.cpp?rev=92342&r1=92341&r2=92342&view=diff
==============================================================================
--- cfe/trunk/lib/Frontend/AnalysisConsumer.cpp (original)
+++ cfe/trunk/lib/Frontend/AnalysisConsumer.cpp Thu Dec 31 00:13:07 2009
@@ -373,7 +373,7 @@
if (C.Opts.EnableExperimentalChecks)
RegisterExperimentalChecks(Eng);
- Eng.setTransferFunctions(tf);
+ Eng.setTransferFunctionsAndCheckers(tf);
// Set the graph auditor.
llvm::OwningPtr<ExplodedNode::Auditor> Auditor;
@@ -506,7 +506,7 @@
// Make a fake transfer function. The GRTransferFunc interface will be
// removed.
- Eng.setTransferFunctions(new GRTransferFuncs());
+ Eng.setTransferFunctionsAndCheckers(new GRTransferFuncs());
// Register call inliner as the last checker.
RegisterCallInliner(Eng);
Modified: cfe/trunk/test/Analysis/malloc.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/malloc.c?rev=92342&r1=92341&r2=92342&view=diff
==============================================================================
--- cfe/trunk/test/Analysis/malloc.c (original)
+++ cfe/trunk/test/Analysis/malloc.c Thu Dec 31 00:13:07 2009
@@ -43,3 +43,11 @@
q = realloc(q, 20);
return q; // no-warning
}
+
+void f6() {
+ int *p = malloc(10);
+ if (!p)
+ return; // no-warning
+ else
+ free(p);
+}
More information about the cfe-commits
mailing list