зеркало из https://github.com/microsoft/clang-1.git
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:
Родитель
a970c57771
Коммит
a49c6b7da5
|
@ -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)));
|
||||||
|
|
Загрузка…
Ссылка в новой задаче