Completely evaluate malloc/free in MallocChecker.cpp.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@91100 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Zhongxing Xu 2009-12-11 03:09:01 +00:00
Родитель a970c57771
Коммит a49c6b7da5
1 изменённых файлов: 20 добавлений и 8 удалений

Просмотреть файл

@ -58,7 +58,7 @@ class MallocChecker : public CheckerVisitor<MallocChecker> {
public: public:
MallocChecker() : BT_DoubleFree(0), BT_Leak(0), II_malloc(0), II_free(0) {} MallocChecker() : BT_DoubleFree(0), BT_Leak(0), II_malloc(0), II_free(0) {}
static void *getTag(); static void *getTag();
void PostVisitCallExpr(CheckerContext &C, const CallExpr *CE); bool EvalCallExpr(CheckerContext &C, const CallExpr *CE);
void EvalDeadSymbols(CheckerContext &C,const Stmt *S,SymbolReaper &SymReaper); void EvalDeadSymbols(CheckerContext &C,const Stmt *S,SymbolReaper &SymReaper);
void EvalEndPath(GREndPathNodeBuilder &B, void *tag, GRExprEngine &Eng); void EvalEndPath(GREndPathNodeBuilder &B, void *tag, GRExprEngine &Eng);
void PreVisitReturnStmt(CheckerContext &C, const ReturnStmt *S); void PreVisitReturnStmt(CheckerContext &C, const ReturnStmt *S);
@ -85,10 +85,14 @@ void *MallocChecker::getTag() {
return &x; return &x;
} }
void MallocChecker::PostVisitCallExpr(CheckerContext &C, const CallExpr *CE) { bool MallocChecker::EvalCallExpr(CheckerContext &C, const CallExpr *CE) {
const FunctionDecl *FD = CE->getDirectCallee(); const GRState *state = C.getState();
const Expr *Callee = CE->getCallee();
SVal L = state->getSVal(Callee);
const FunctionDecl *FD = L.getAsFunctionDecl();
if (!FD) if (!FD)
return; return false;
ASTContext &Ctx = C.getASTContext(); ASTContext &Ctx = C.getASTContext();
if (!II_malloc) if (!II_malloc)
@ -98,19 +102,27 @@ void MallocChecker::PostVisitCallExpr(CheckerContext &C, const CallExpr *CE) {
if (FD->getIdentifier() == II_malloc) { if (FD->getIdentifier() == II_malloc) {
MallocMem(C, CE); MallocMem(C, CE);
return; return true;
} }
if (FD->getIdentifier() == II_free) { if (FD->getIdentifier() == II_free) {
FreeMem(C, CE); FreeMem(C, CE);
return; return true;
} }
return false;
} }
void MallocChecker::MallocMem(CheckerContext &C, const CallExpr *CE) { void MallocChecker::MallocMem(CheckerContext &C, const CallExpr *CE) {
unsigned Count = C.getNodeBuilder().getCurrentBlockCount();
ValueManager &ValMgr = C.getValueManager();
SVal RetVal = ValMgr.getConjuredSymbolVal(NULL, CE, CE->getType(), Count);
const GRState *state = C.getState(); const GRState *state = C.getState();
SVal CallVal = state->getSVal(CE); state = state->BindExpr(CE, RetVal);
SymbolRef Sym = CallVal.getAsLocSymbol();
SymbolRef Sym = RetVal.getAsLocSymbol();
assert(Sym); assert(Sym);
// Set the symbol's state to Allocated. // Set the symbol's state to Allocated.
C.addTransition(state->set<RegionState>(Sym, RefState::getAllocated(CE))); C.addTransition(state->set<RegionState>(Sym, RefState::getAllocated(CE)));