summaryrefslogtreecommitdiffstats
path: root/lib/Analysis/DereferenceChecker.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Analysis/DereferenceChecker.cpp')
-rw-r--r--lib/Analysis/DereferenceChecker.cpp112
1 files changed, 112 insertions, 0 deletions
diff --git a/lib/Analysis/DereferenceChecker.cpp b/lib/Analysis/DereferenceChecker.cpp
new file mode 100644
index 0000000..33c85d5
--- /dev/null
+++ b/lib/Analysis/DereferenceChecker.cpp
@@ -0,0 +1,112 @@
+//== NullDerefChecker.cpp - Null dereference checker ------------*- C++ -*--==//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This defines NullDerefChecker, a builtin check in GRExprEngine that performs
+// checks for null pointers at loads and stores.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Analysis/PathSensitive/Checkers/DereferenceChecker.h"
+#include "clang/Analysis/PathSensitive/GRExprEngine.h"
+#include "clang/Analysis/PathSensitive/BugReporter.h"
+
+using namespace clang;
+
+void *NullDerefChecker::getTag() {
+ static int x = 0;
+ return &x;
+}
+
+ExplodedNode *NullDerefChecker::CheckLocation(const Stmt *S, ExplodedNode *Pred,
+ const GRState *state, SVal V,
+ GRExprEngine &Eng) {
+ Loc *LV = dyn_cast<Loc>(&V);
+
+ // If the value is not a location, don't touch the node.
+ if (!LV)
+ return Pred;
+
+ const GRState *NotNullState = state->Assume(*LV, true);
+ const GRState *NullState = state->Assume(*LV, false);
+
+ GRStmtNodeBuilder &Builder = Eng.getBuilder();
+ BugReporter &BR = Eng.getBugReporter();
+
+ // The explicit NULL case.
+ if (NullState) {
+ // Use the GDM to mark in the state what lval was null.
+ const SVal *PersistentLV = Eng.getBasicVals().getPersistentSVal(*LV);
+ NullState = NullState->set<GRState::NullDerefTag>(PersistentLV);
+
+ ExplodedNode *N = Builder.generateNode(S, NullState, Pred,
+ ProgramPoint::PostNullCheckFailedKind);
+ if (N) {
+ N->markAsSink();
+
+ if (!NotNullState) { // Explicit null case.
+ if (!BT)
+ BT = new BuiltinBug(NULL, "Null dereference",
+ "Dereference of null pointer");
+
+ EnhancedBugReport *R =
+ new EnhancedBugReport(*BT, BT->getDescription().c_str(), N);
+
+ R->addVisitorCreator(bugreporter::registerTrackNullOrUndefValue,
+ bugreporter::GetDerefExpr(N));
+
+ BR.EmitReport(R);
+
+ return 0;
+ } else // Implicit null case.
+ ImplicitNullDerefNodes.push_back(N);
+ }
+ }
+
+ if (!NotNullState)
+ return 0;
+
+ return Builder.generateNode(S, NotNullState, Pred,
+ ProgramPoint::PostLocationChecksSucceedKind);
+}
+
+
+void *UndefDerefChecker::getTag() {
+ static int x = 0;
+ return &x;
+}
+
+ExplodedNode *UndefDerefChecker::CheckLocation(const Stmt *S,
+ ExplodedNode *Pred,
+ const GRState *state, SVal V,
+ GRExprEngine &Eng) {
+ GRStmtNodeBuilder &Builder = Eng.getBuilder();
+ BugReporter &BR = Eng.getBugReporter();
+
+ if (V.isUndef()) {
+ ExplodedNode *N = Builder.generateNode(S, state, Pred,
+ ProgramPoint::PostUndefLocationCheckFailedKind);
+ if (N) {
+ N->markAsSink();
+
+ if (!BT)
+ BT = new BuiltinBug(0, "Undefined dereference",
+ "Dereference of undefined pointer value");
+
+ EnhancedBugReport *R =
+ new EnhancedBugReport(*BT, BT->getDescription().c_str(), N);
+ R->addVisitorCreator(bugreporter::registerTrackNullOrUndefValue,
+ bugreporter::GetDerefExpr(N));
+ BR.EmitReport(R);
+ }
+ return 0;
+ }
+
+ return Pred;
+}
+
OpenPOWER on IntegriCloud