aboutsummaryrefslogtreecommitdiff
path: root/lib/Checker/MallocChecker.cpp
diff options
context:
space:
mode:
authorZhongxing Xu <xuzhongxing@gmail.com>2010-03-10 04:58:55 +0000
committerZhongxing Xu <xuzhongxing@gmail.com>2010-03-10 04:58:55 +0000
commitc8023788ace75cf0a0417b9b88e643ceebae91e2 (patch)
tree7bde59db56a5957fab4186340d9145f2d9e8b8df /lib/Checker/MallocChecker.cpp
parentdd8f569f84a73c0b0e1449475f333d101e6c9401 (diff)
Add use-after-free check to MallocChecker.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@98136 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Checker/MallocChecker.cpp')
-rw-r--r--lib/Checker/MallocChecker.cpp24
1 files changed, 23 insertions, 1 deletions
diff --git a/lib/Checker/MallocChecker.cpp b/lib/Checker/MallocChecker.cpp
index 4ff98642e1..a08afc4b79 100644
--- a/lib/Checker/MallocChecker.cpp
+++ b/lib/Checker/MallocChecker.cpp
@@ -57,17 +57,20 @@ class RegionState {};
class MallocChecker : public CheckerVisitor<MallocChecker> {
BuiltinBug *BT_DoubleFree;
BuiltinBug *BT_Leak;
+ BuiltinBug *BT_UseFree;
IdentifierInfo *II_malloc, *II_free, *II_realloc;
public:
MallocChecker()
- : BT_DoubleFree(0), BT_Leak(0), II_malloc(0), II_free(0), II_realloc(0) {}
+ : BT_DoubleFree(0), BT_Leak(0), BT_UseFree(0),
+ II_malloc(0), II_free(0), II_realloc(0) {}
static void *getTag();
bool EvalCallExpr(CheckerContext &C, const CallExpr *CE);
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);
+ void VisitLocation(CheckerContext &C, const Stmt *S, SVal l);
private:
void MallocMem(CheckerContext &C, const CallExpr *CE);
@@ -339,3 +342,22 @@ const GRState *MallocChecker::EvalAssume(const GRState *state, SVal Cond,
return state;
}
+
+// Check if the location is a freed symbolic region.
+void MallocChecker::VisitLocation(CheckerContext &C, const Stmt *S, SVal l) {
+ SymbolRef Sym = l.getLocSymbolInBase();
+ if (Sym) {
+ const RefState *RS = C.getState()->get<RegionState>(Sym);
+ if (RS)
+ if (RS->isReleased()) {
+ ExplodedNode *N = C.GenerateSink();
+ if (!BT_UseFree)
+ BT_UseFree = new BuiltinBug("Use dynamically allocated memory after"
+ " it is freed.");
+
+ BugReport *R = new BugReport(*BT_UseFree, BT_UseFree->getDescription(),
+ N);
+ C.EmitReport(R);
+ }
+ }
+}