MallocChecker.cpp 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736
  1. //=== MallocChecker.cpp - A malloc/free checker -------------------*- C++ -*--//
  2. //
  3. // The LLVM Compiler Infrastructure
  4. //
  5. // This file is distributed under the University of Illinois Open Source
  6. // License. See LICENSE.TXT for details.
  7. //
  8. //===----------------------------------------------------------------------===//
  9. //
  10. // This file defines malloc/free checker, which checks for potential memory
  11. // leaks, double free, and use-after-free problems.
  12. //
  13. //===----------------------------------------------------------------------===//
  14. #include "GRExprEngineExperimentalChecks.h"
  15. #include "clang/Checker/BugReporter/BugType.h"
  16. #include "clang/Checker/PathSensitive/CheckerVisitor.h"
  17. #include "clang/Checker/PathSensitive/GRState.h"
  18. #include "clang/Checker/PathSensitive/GRStateTrait.h"
  19. #include "clang/Checker/PathSensitive/SymbolManager.h"
  20. #include "llvm/ADT/ImmutableMap.h"
  21. using namespace clang;
  22. namespace {
  23. class RefState {
  24. enum Kind { AllocateUnchecked, AllocateFailed, Released, Escaped,
  25. Relinquished } K;
  26. const Stmt *S;
  27. public:
  28. RefState(Kind k, const Stmt *s) : K(k), S(s) {}
  29. bool isAllocated() const { return K == AllocateUnchecked; }
  30. //bool isFailed() const { return K == AllocateFailed; }
  31. bool isReleased() const { return K == Released; }
  32. //bool isEscaped() const { return K == Escaped; }
  33. //bool isRelinquished() const { return K == Relinquished; }
  34. bool operator==(const RefState &X) const {
  35. return K == X.K && S == X.S;
  36. }
  37. static RefState getAllocateUnchecked(const Stmt *s) {
  38. return RefState(AllocateUnchecked, s);
  39. }
  40. static RefState getAllocateFailed() {
  41. return RefState(AllocateFailed, 0);
  42. }
  43. static RefState getReleased(const Stmt *s) { return RefState(Released, s); }
  44. static RefState getEscaped(const Stmt *s) { return RefState(Escaped, s); }
  45. static RefState getRelinquished(const Stmt *s) {
  46. return RefState(Relinquished, s);
  47. }
  48. void Profile(llvm::FoldingSetNodeID &ID) const {
  49. ID.AddInteger(K);
  50. ID.AddPointer(S);
  51. }
  52. };
  53. class RegionState {};
  54. class MallocChecker : public CheckerVisitor<MallocChecker> {
  55. BuiltinBug *BT_DoubleFree;
  56. BuiltinBug *BT_Leak;
  57. BuiltinBug *BT_UseFree;
  58. BuiltinBug *BT_UseRelinquished;
  59. BuiltinBug *BT_BadFree;
  60. IdentifierInfo *II_malloc, *II_free, *II_realloc, *II_calloc;
  61. public:
  62. MallocChecker()
  63. : BT_DoubleFree(0), BT_Leak(0), BT_UseFree(0), BT_UseRelinquished(0),
  64. BT_BadFree(0),
  65. II_malloc(0), II_free(0), II_realloc(0), II_calloc(0) {}
  66. static void *getTag();
  67. bool EvalCallExpr(CheckerContext &C, const CallExpr *CE);
  68. void EvalDeadSymbols(CheckerContext &C, SymbolReaper &SymReaper);
  69. void EvalEndPath(GREndPathNodeBuilder &B, void *tag, GRExprEngine &Eng);
  70. void PreVisitReturnStmt(CheckerContext &C, const ReturnStmt *S);
  71. const GRState *EvalAssume(const GRState *state, SVal Cond, bool Assumption,
  72. bool *respondsToCallback);
  73. void VisitLocation(CheckerContext &C, const Stmt *S, SVal l);
  74. virtual void PreVisitBind(CheckerContext &C, const Stmt *StoreE,
  75. SVal location, SVal val);
  76. private:
  77. void MallocMem(CheckerContext &C, const CallExpr *CE);
  78. void MallocMemReturnsAttr(CheckerContext &C, const CallExpr *CE,
  79. const OwnershipAttr* Att);
  80. const GRState *MallocMemAux(CheckerContext &C, const CallExpr *CE,
  81. const Expr *SizeEx, SVal Init,
  82. const GRState *state) {
  83. return MallocMemAux(C, CE, state->getSVal(SizeEx), Init, state);
  84. }
  85. const GRState *MallocMemAux(CheckerContext &C, const CallExpr *CE,
  86. SVal SizeEx, SVal Init,
  87. const GRState *state);
  88. void FreeMem(CheckerContext &C, const CallExpr *CE);
  89. void FreeMemAttr(CheckerContext &C, const CallExpr *CE,
  90. const OwnershipAttr* Att);
  91. const GRState *FreeMemAux(CheckerContext &C, const CallExpr *CE,
  92. const GRState *state, unsigned Num, bool Hold);
  93. void ReallocMem(CheckerContext &C, const CallExpr *CE);
  94. void CallocMem(CheckerContext &C, const CallExpr *CE);
  95. bool SummarizeValue(llvm::raw_ostream& os, SVal V);
  96. bool SummarizeRegion(llvm::raw_ostream& os, const MemRegion *MR);
  97. void ReportBadFree(CheckerContext &C, SVal ArgVal, SourceRange range);
  98. };
  99. } // end anonymous namespace
  100. typedef llvm::ImmutableMap<SymbolRef, RefState> RegionStateTy;
  101. namespace clang {
  102. template <>
  103. struct GRStateTrait<RegionState>
  104. : public GRStatePartialTrait<RegionStateTy> {
  105. static void *GDMIndex() { return MallocChecker::getTag(); }
  106. };
  107. }
  108. void clang::RegisterMallocChecker(GRExprEngine &Eng) {
  109. Eng.registerCheck(new MallocChecker());
  110. }
  111. void *MallocChecker::getTag() {
  112. static int x;
  113. return &x;
  114. }
  115. bool MallocChecker::EvalCallExpr(CheckerContext &C, const CallExpr *CE) {
  116. const GRState *state = C.getState();
  117. const Expr *Callee = CE->getCallee();
  118. SVal L = state->getSVal(Callee);
  119. const FunctionDecl *FD = L.getAsFunctionDecl();
  120. if (!FD)
  121. return false;
  122. ASTContext &Ctx = C.getASTContext();
  123. if (!II_malloc)
  124. II_malloc = &Ctx.Idents.get("malloc");
  125. if (!II_free)
  126. II_free = &Ctx.Idents.get("free");
  127. if (!II_realloc)
  128. II_realloc = &Ctx.Idents.get("realloc");
  129. if (!II_calloc)
  130. II_calloc = &Ctx.Idents.get("calloc");
  131. if (FD->getIdentifier() == II_malloc) {
  132. MallocMem(C, CE);
  133. return true;
  134. }
  135. if (FD->getIdentifier() == II_free) {
  136. FreeMem(C, CE);
  137. return true;
  138. }
  139. if (FD->getIdentifier() == II_realloc) {
  140. ReallocMem(C, CE);
  141. return true;
  142. }
  143. if (FD->getIdentifier() == II_calloc) {
  144. CallocMem(C, CE);
  145. return true;
  146. }
  147. // Check all the attributes, if there are any.
  148. // There can be multiple of these attributes.
  149. bool rv = false;
  150. if (FD->hasAttrs()) {
  151. for (specific_attr_iterator<OwnershipAttr>
  152. i = FD->specific_attr_begin<OwnershipAttr>(),
  153. e = FD->specific_attr_end<OwnershipAttr>();
  154. i != e; ++i) {
  155. switch ((*i)->getOwnKind()) {
  156. case OwnershipAttr::Returns: {
  157. MallocMemReturnsAttr(C, CE, *i);
  158. rv = true;
  159. break;
  160. }
  161. case OwnershipAttr::Takes:
  162. case OwnershipAttr::Holds: {
  163. FreeMemAttr(C, CE, *i);
  164. rv = true;
  165. break;
  166. }
  167. default:
  168. break;
  169. }
  170. }
  171. }
  172. return rv;
  173. }
  174. void MallocChecker::MallocMem(CheckerContext &C, const CallExpr *CE) {
  175. const GRState *state = MallocMemAux(C, CE, CE->getArg(0), UndefinedVal(),
  176. C.getState());
  177. C.addTransition(state);
  178. }
  179. void MallocChecker::MallocMemReturnsAttr(CheckerContext &C, const CallExpr *CE,
  180. const OwnershipAttr* Att) {
  181. if (Att->getModule() != "malloc")
  182. return;
  183. OwnershipAttr::args_iterator I = Att->args_begin(), E = Att->args_end();
  184. if (I != E) {
  185. const GRState *state =
  186. MallocMemAux(C, CE, CE->getArg(*I), UndefinedVal(), C.getState());
  187. C.addTransition(state);
  188. return;
  189. }
  190. const GRState *state = MallocMemAux(C, CE, UnknownVal(), UndefinedVal(),
  191. C.getState());
  192. C.addTransition(state);
  193. }
  194. const GRState *MallocChecker::MallocMemAux(CheckerContext &C,
  195. const CallExpr *CE,
  196. SVal Size, SVal Init,
  197. const GRState *state) {
  198. unsigned Count = C.getNodeBuilder().getCurrentBlockCount();
  199. ValueManager &ValMgr = C.getValueManager();
  200. // Set the return value.
  201. SVal RetVal = ValMgr.getConjuredSymbolVal(NULL, CE, CE->getType(), Count);
  202. state = state->BindExpr(CE, RetVal);
  203. // Fill the region with the initialization value.
  204. state = state->bindDefault(RetVal, Init);
  205. // Set the region's extent equal to the Size parameter.
  206. const SymbolicRegion *R = cast<SymbolicRegion>(RetVal.getAsRegion());
  207. DefinedOrUnknownSVal Extent = R->getExtent(ValMgr);
  208. DefinedOrUnknownSVal DefinedSize = cast<DefinedOrUnknownSVal>(Size);
  209. SValuator &SVator = ValMgr.getSValuator();
  210. DefinedOrUnknownSVal ExtentMatchesSize =
  211. SVator.EvalEQ(state, Extent, DefinedSize);
  212. state = state->Assume(ExtentMatchesSize, true);
  213. SymbolRef Sym = RetVal.getAsLocSymbol();
  214. assert(Sym);
  215. // Set the symbol's state to Allocated.
  216. return state->set<RegionState>(Sym, RefState::getAllocateUnchecked(CE));
  217. }
  218. void MallocChecker::FreeMem(CheckerContext &C, const CallExpr *CE) {
  219. const GRState *state = FreeMemAux(C, CE, C.getState(), 0, false);
  220. if (state)
  221. C.addTransition(state);
  222. }
  223. void MallocChecker::FreeMemAttr(CheckerContext &C, const CallExpr *CE,
  224. const OwnershipAttr* Att) {
  225. if (Att->getModule() != "malloc")
  226. return;
  227. for (OwnershipAttr::args_iterator I = Att->args_begin(), E = Att->args_end();
  228. I != E; ++I) {
  229. const GRState *state = FreeMemAux(C, CE, C.getState(), *I,
  230. Att->getOwnKind() == OwnershipAttr::Holds);
  231. if (state)
  232. C.addTransition(state);
  233. }
  234. }
  235. const GRState *MallocChecker::FreeMemAux(CheckerContext &C, const CallExpr *CE,
  236. const GRState *state, unsigned Num,
  237. bool Hold) {
  238. const Expr *ArgExpr = CE->getArg(Num);
  239. SVal ArgVal = state->getSVal(ArgExpr);
  240. DefinedOrUnknownSVal location = cast<DefinedOrUnknownSVal>(ArgVal);
  241. // Check for null dereferences.
  242. if (!isa<Loc>(location))
  243. return state;
  244. // FIXME: Technically using 'Assume' here can result in a path
  245. // bifurcation. In such cases we need to return two states, not just one.
  246. const GRState *notNullState, *nullState;
  247. llvm::tie(notNullState, nullState) = state->Assume(location);
  248. // The explicit NULL case, no operation is performed.
  249. if (nullState && !notNullState)
  250. return nullState;
  251. assert(notNullState);
  252. // Unknown values could easily be okay
  253. // Undefined values are handled elsewhere
  254. if (ArgVal.isUnknownOrUndef())
  255. return notNullState;
  256. const MemRegion *R = ArgVal.getAsRegion();
  257. // Nonlocs can't be freed, of course.
  258. // Non-region locations (labels and fixed addresses) also shouldn't be freed.
  259. if (!R) {
  260. ReportBadFree(C, ArgVal, ArgExpr->getSourceRange());
  261. return NULL;
  262. }
  263. R = R->StripCasts();
  264. // Blocks might show up as heap data, but should not be free()d
  265. if (isa<BlockDataRegion>(R)) {
  266. ReportBadFree(C, ArgVal, ArgExpr->getSourceRange());
  267. return NULL;
  268. }
  269. const MemSpaceRegion *MS = R->getMemorySpace();
  270. // Parameters, locals, statics, and globals shouldn't be freed.
  271. if (!(isa<UnknownSpaceRegion>(MS) || isa<HeapSpaceRegion>(MS))) {
  272. // FIXME: at the time this code was written, malloc() regions were
  273. // represented by conjured symbols, which are all in UnknownSpaceRegion.
  274. // This means that there isn't actually anything from HeapSpaceRegion
  275. // that should be freed, even though we allow it here.
  276. // Of course, free() can work on memory allocated outside the current
  277. // function, so UnknownSpaceRegion is always a possibility.
  278. // False negatives are better than false positives.
  279. ReportBadFree(C, ArgVal, ArgExpr->getSourceRange());
  280. return NULL;
  281. }
  282. const SymbolicRegion *SR = dyn_cast<SymbolicRegion>(R);
  283. // Various cases could lead to non-symbol values here.
  284. // For now, ignore them.
  285. if (!SR)
  286. return notNullState;
  287. SymbolRef Sym = SR->getSymbol();
  288. const RefState *RS = state->get<RegionState>(Sym);
  289. // If the symbol has not been tracked, return. This is possible when free() is
  290. // called on a pointer that does not get its pointee directly from malloc().
  291. // Full support of this requires inter-procedural analysis.
  292. if (!RS)
  293. return notNullState;
  294. // Check double free.
  295. if (RS->isReleased()) {
  296. if (ExplodedNode *N = C.GenerateSink()) {
  297. if (!BT_DoubleFree)
  298. BT_DoubleFree
  299. = new BuiltinBug("Double free",
  300. "Try to free a memory block that has been released");
  301. // FIXME: should find where it's freed last time.
  302. BugReport *R = new BugReport(*BT_DoubleFree,
  303. BT_DoubleFree->getDescription(), N);
  304. C.EmitReport(R);
  305. }
  306. return NULL;
  307. }
  308. // Normal free.
  309. if (Hold)
  310. return notNullState->set<RegionState>(Sym, RefState::getRelinquished(CE));
  311. return notNullState->set<RegionState>(Sym, RefState::getReleased(CE));
  312. }
  313. bool MallocChecker::SummarizeValue(llvm::raw_ostream& os, SVal V) {
  314. if (nonloc::ConcreteInt *IntVal = dyn_cast<nonloc::ConcreteInt>(&V))
  315. os << "an integer (" << IntVal->getValue() << ")";
  316. else if (loc::ConcreteInt *ConstAddr = dyn_cast<loc::ConcreteInt>(&V))
  317. os << "a constant address (" << ConstAddr->getValue() << ")";
  318. else if (loc::GotoLabel *Label = dyn_cast<loc::GotoLabel>(&V))
  319. os << "the address of the label '"
  320. << Label->getLabel()->getID()->getName()
  321. << "'";
  322. else
  323. return false;
  324. return true;
  325. }
  326. bool MallocChecker::SummarizeRegion(llvm::raw_ostream& os,
  327. const MemRegion *MR) {
  328. switch (MR->getKind()) {
  329. case MemRegion::FunctionTextRegionKind: {
  330. const FunctionDecl *FD = cast<FunctionTextRegion>(MR)->getDecl();
  331. if (FD)
  332. os << "the address of the function '" << FD << "'";
  333. else
  334. os << "the address of a function";
  335. return true;
  336. }
  337. case MemRegion::BlockTextRegionKind:
  338. os << "block text";
  339. return true;
  340. case MemRegion::BlockDataRegionKind:
  341. // FIXME: where the block came from?
  342. os << "a block";
  343. return true;
  344. default: {
  345. const MemSpaceRegion *MS = MR->getMemorySpace();
  346. switch (MS->getKind()) {
  347. case MemRegion::StackLocalsSpaceRegionKind: {
  348. const VarRegion *VR = dyn_cast<VarRegion>(MR);
  349. const VarDecl *VD;
  350. if (VR)
  351. VD = VR->getDecl();
  352. else
  353. VD = NULL;
  354. if (VD)
  355. os << "the address of the local variable '" << VD->getName() << "'";
  356. else
  357. os << "the address of a local stack variable";
  358. return true;
  359. }
  360. case MemRegion::StackArgumentsSpaceRegionKind: {
  361. const VarRegion *VR = dyn_cast<VarRegion>(MR);
  362. const VarDecl *VD;
  363. if (VR)
  364. VD = VR->getDecl();
  365. else
  366. VD = NULL;
  367. if (VD)
  368. os << "the address of the parameter '" << VD->getName() << "'";
  369. else
  370. os << "the address of a parameter";
  371. return true;
  372. }
  373. case MemRegion::NonStaticGlobalSpaceRegionKind:
  374. case MemRegion::StaticGlobalSpaceRegionKind: {
  375. const VarRegion *VR = dyn_cast<VarRegion>(MR);
  376. const VarDecl *VD;
  377. if (VR)
  378. VD = VR->getDecl();
  379. else
  380. VD = NULL;
  381. if (VD) {
  382. if (VD->isStaticLocal())
  383. os << "the address of the static variable '" << VD->getName() << "'";
  384. else
  385. os << "the address of the global variable '" << VD->getName() << "'";
  386. } else
  387. os << "the address of a global variable";
  388. return true;
  389. }
  390. default:
  391. return false;
  392. }
  393. }
  394. }
  395. }
  396. void MallocChecker::ReportBadFree(CheckerContext &C, SVal ArgVal,
  397. SourceRange range) {
  398. if (ExplodedNode *N = C.GenerateSink()) {
  399. if (!BT_BadFree)
  400. BT_BadFree = new BuiltinBug("Bad free");
  401. llvm::SmallString<100> buf;
  402. llvm::raw_svector_ostream os(buf);
  403. const MemRegion *MR = ArgVal.getAsRegion();
  404. if (MR) {
  405. while (const ElementRegion *ER = dyn_cast<ElementRegion>(MR))
  406. MR = ER->getSuperRegion();
  407. // Special case for alloca()
  408. if (isa<AllocaRegion>(MR))
  409. os << "Argument to free() was allocated by alloca(), not malloc()";
  410. else {
  411. os << "Argument to free() is ";
  412. if (SummarizeRegion(os, MR))
  413. os << ", which is not memory allocated by malloc()";
  414. else
  415. os << "not memory allocated by malloc()";
  416. }
  417. } else {
  418. os << "Argument to free() is ";
  419. if (SummarizeValue(os, ArgVal))
  420. os << ", which is not memory allocated by malloc()";
  421. else
  422. os << "not memory allocated by malloc()";
  423. }
  424. EnhancedBugReport *R = new EnhancedBugReport(*BT_BadFree, os.str(), N);
  425. R->addRange(range);
  426. C.EmitReport(R);
  427. }
  428. }
  429. void MallocChecker::ReallocMem(CheckerContext &C, const CallExpr *CE) {
  430. const GRState *state = C.getState();
  431. const Expr *Arg0 = CE->getArg(0);
  432. DefinedOrUnknownSVal Arg0Val=cast<DefinedOrUnknownSVal>(state->getSVal(Arg0));
  433. ValueManager &ValMgr = C.getValueManager();
  434. SValuator &SVator = C.getSValuator();
  435. DefinedOrUnknownSVal PtrEQ = SVator.EvalEQ(state, Arg0Val, ValMgr.makeNull());
  436. // If the ptr is NULL, the call is equivalent to malloc(size).
  437. if (const GRState *stateEqual = state->Assume(PtrEQ, true)) {
  438. // Hack: set the NULL symbolic region to released to suppress false warning.
  439. // In the future we should add more states for allocated regions, e.g.,
  440. // CheckedNull, CheckedNonNull.
  441. SymbolRef Sym = Arg0Val.getAsLocSymbol();
  442. if (Sym)
  443. stateEqual = stateEqual->set<RegionState>(Sym, RefState::getReleased(CE));
  444. const GRState *stateMalloc = MallocMemAux(C, CE, CE->getArg(1),
  445. UndefinedVal(), stateEqual);
  446. C.addTransition(stateMalloc);
  447. }
  448. if (const GRState *stateNotEqual = state->Assume(PtrEQ, false)) {
  449. const Expr *Arg1 = CE->getArg(1);
  450. DefinedOrUnknownSVal Arg1Val =
  451. cast<DefinedOrUnknownSVal>(stateNotEqual->getSVal(Arg1));
  452. DefinedOrUnknownSVal SizeZero = SVator.EvalEQ(stateNotEqual, Arg1Val,
  453. ValMgr.makeIntValWithPtrWidth(0, false));
  454. if (const GRState *stateSizeZero = stateNotEqual->Assume(SizeZero, true)) {
  455. const GRState *stateFree = FreeMemAux(C, CE, stateSizeZero, 0, false);
  456. if (stateFree)
  457. C.addTransition(stateFree->BindExpr(CE, UndefinedVal(), true));
  458. }
  459. if (const GRState *stateSizeNotZero=stateNotEqual->Assume(SizeZero,false)) {
  460. const GRState *stateFree = FreeMemAux(C, CE, stateSizeNotZero, 0, false);
  461. if (stateFree) {
  462. // FIXME: We should copy the content of the original buffer.
  463. const GRState *stateRealloc = MallocMemAux(C, CE, CE->getArg(1),
  464. UnknownVal(), stateFree);
  465. C.addTransition(stateRealloc);
  466. }
  467. }
  468. }
  469. }
  470. void MallocChecker::CallocMem(CheckerContext &C, const CallExpr *CE) {
  471. const GRState *state = C.getState();
  472. ValueManager &ValMgr = C.getValueManager();
  473. SValuator &SVator = C.getSValuator();
  474. SVal Count = state->getSVal(CE->getArg(0));
  475. SVal EleSize = state->getSVal(CE->getArg(1));
  476. SVal TotalSize = SVator.EvalBinOp(state, BO_Mul, Count, EleSize,
  477. ValMgr.getContext().getSizeType());
  478. SVal Zero = ValMgr.makeZeroVal(ValMgr.getContext().CharTy);
  479. state = MallocMemAux(C, CE, TotalSize, Zero, state);
  480. C.addTransition(state);
  481. }
  482. void MallocChecker::EvalDeadSymbols(CheckerContext &C,SymbolReaper &SymReaper) {
  483. if (!SymReaper.hasDeadSymbols())
  484. return;
  485. const GRState *state = C.getState();
  486. RegionStateTy RS = state->get<RegionState>();
  487. RegionStateTy::Factory &F = state->get_context<RegionState>();
  488. for (RegionStateTy::iterator I = RS.begin(), E = RS.end(); I != E; ++I) {
  489. if (SymReaper.isDead(I->first)) {
  490. if (I->second.isAllocated()) {
  491. if (ExplodedNode *N = C.GenerateNode()) {
  492. if (!BT_Leak)
  493. BT_Leak = new BuiltinBug("Memory leak",
  494. "Allocated memory never released. Potential memory leak.");
  495. // FIXME: where it is allocated.
  496. BugReport *R = new BugReport(*BT_Leak, BT_Leak->getDescription(), N);
  497. C.EmitReport(R);
  498. }
  499. }
  500. // Remove the dead symbol from the map.
  501. RS = F.Remove(RS, I->first);
  502. }
  503. }
  504. state = state->set<RegionState>(RS);
  505. C.GenerateNode(state);
  506. }
  507. void MallocChecker::EvalEndPath(GREndPathNodeBuilder &B, void *tag,
  508. GRExprEngine &Eng) {
  509. SaveAndRestore<bool> OldHasGen(B.HasGeneratedNode);
  510. const GRState *state = B.getState();
  511. RegionStateTy M = state->get<RegionState>();
  512. for (RegionStateTy::iterator I = M.begin(), E = M.end(); I != E; ++I) {
  513. RefState RS = I->second;
  514. if (RS.isAllocated()) {
  515. ExplodedNode *N = B.generateNode(state, tag, B.getPredecessor());
  516. if (N) {
  517. if (!BT_Leak)
  518. BT_Leak = new BuiltinBug("Memory leak",
  519. "Allocated memory never released. Potential memory leak.");
  520. BugReport *R = new BugReport(*BT_Leak, BT_Leak->getDescription(), N);
  521. Eng.getBugReporter().EmitReport(R);
  522. }
  523. }
  524. }
  525. }
  526. void MallocChecker::PreVisitReturnStmt(CheckerContext &C, const ReturnStmt *S) {
  527. const Expr *RetE = S->getRetValue();
  528. if (!RetE)
  529. return;
  530. const GRState *state = C.getState();
  531. SymbolRef Sym = state->getSVal(RetE).getAsSymbol();
  532. if (!Sym)
  533. return;
  534. const RefState *RS = state->get<RegionState>(Sym);
  535. if (!RS)
  536. return;
  537. // FIXME: check other cases.
  538. if (RS->isAllocated())
  539. state = state->set<RegionState>(Sym, RefState::getEscaped(S));
  540. C.addTransition(state);
  541. }
  542. const GRState *MallocChecker::EvalAssume(const GRState *state, SVal Cond,
  543. bool Assumption,
  544. bool * /* respondsToCallback */) {
  545. // If a symblic region is assumed to NULL, set its state to AllocateFailed.
  546. // FIXME: should also check symbols assumed to non-null.
  547. RegionStateTy RS = state->get<RegionState>();
  548. for (RegionStateTy::iterator I = RS.begin(), E = RS.end(); I != E; ++I) {
  549. if (state->getSymVal(I.getKey()))
  550. state = state->set<RegionState>(I.getKey(),RefState::getAllocateFailed());
  551. }
  552. return state;
  553. }
  554. // Check if the location is a freed symbolic region.
  555. void MallocChecker::VisitLocation(CheckerContext &C, const Stmt *S, SVal l) {
  556. SymbolRef Sym = l.getLocSymbolInBase();
  557. if (Sym) {
  558. const RefState *RS = C.getState()->get<RegionState>(Sym);
  559. if (RS && RS->isReleased()) {
  560. if (ExplodedNode *N = C.GenerateNode()) {
  561. if (!BT_UseFree)
  562. BT_UseFree = new BuiltinBug("Use dynamically allocated memory after"
  563. " it is freed.");
  564. BugReport *R = new BugReport(*BT_UseFree, BT_UseFree->getDescription(),
  565. N);
  566. C.EmitReport(R);
  567. }
  568. }
  569. }
  570. }
  571. void MallocChecker::PreVisitBind(CheckerContext &C,
  572. const Stmt *StoreE,
  573. SVal location,
  574. SVal val) {
  575. // The PreVisitBind implements the same algorithm as already used by the
  576. // Objective C ownership checker: if the pointer escaped from this scope by
  577. // assignment, let it go. However, assigning to fields of a stack-storage
  578. // structure does not transfer ownership.
  579. const GRState *state = C.getState();
  580. DefinedOrUnknownSVal l = cast<DefinedOrUnknownSVal>(location);
  581. // Check for null dereferences.
  582. if (!isa<Loc>(l))
  583. return;
  584. // Before checking if the state is null, check if 'val' has a RefState.
  585. // Only then should we check for null and bifurcate the state.
  586. SymbolRef Sym = val.getLocSymbolInBase();
  587. if (Sym) {
  588. if (const RefState *RS = state->get<RegionState>(Sym)) {
  589. // If ptr is NULL, no operation is performed.
  590. const GRState *notNullState, *nullState;
  591. llvm::tie(notNullState, nullState) = state->Assume(l);
  592. // Generate a transition for 'nullState' to record the assumption
  593. // that the state was null.
  594. if (nullState)
  595. C.addTransition(nullState);
  596. if (!notNullState)
  597. return;
  598. if (RS->isAllocated()) {
  599. // Something we presently own is being assigned somewhere.
  600. const MemRegion *AR = location.getAsRegion();
  601. if (!AR)
  602. return;
  603. AR = AR->StripCasts()->getBaseRegion();
  604. do {
  605. // If it is on the stack, we still own it.
  606. if (AR->hasStackNonParametersStorage())
  607. break;
  608. // If the state can't represent this binding, we still own it.
  609. if (notNullState == (notNullState->bindLoc(cast<Loc>(location),
  610. UnknownVal())))
  611. break;
  612. // We no longer own this pointer.
  613. notNullState =
  614. notNullState->set<RegionState>(Sym,
  615. RefState::getRelinquished(StoreE));
  616. }
  617. while (false);
  618. }
  619. C.addTransition(notNullState);
  620. }
  621. }
  622. }