Move all logic for the null dereference checker from GRExprEngineInternalChecks.cpp to a separate .cpp file.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@85595 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/include/clang/Analysis/PathSensitive/NullDerefChecker.h b/include/clang/Analysis/PathSensitive/NullDerefChecker.h
index 05c4b36..6905d68 100644
--- a/include/clang/Analysis/PathSensitive/NullDerefChecker.h
+++ b/include/clang/Analysis/PathSensitive/NullDerefChecker.h
@@ -1,4 +1,4 @@
-//== NullDerefChecker - Null dereference checker ----------------*- C++ -*--==//
+//== NullDerefChecker.h - Null dereference checker --------------*- C++ -*--==//
//
// The LLVM Compiler Infrastructure
//
@@ -6,6 +6,11 @@
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
+//
+// This defines NullDerefChecker, a builtin check in GRExprEngine that performs
+// checks for null pointers at loads and stores.
+//
+//===----------------------------------------------------------------------===//
#ifndef LLVM_CLANG_NULLDEREFCHECKER
#define LLVM_CLANG_NULLDEREFCHECKER
@@ -17,31 +22,16 @@
class ExplodedNode;
-class NullDeref : public BuiltinBug {
-public:
- NullDeref()
- : BuiltinBug(0, "Null dereference", "Dereference of null pointer") {}
-
- void registerInitialVisitors(BugReporterContext& BRC,
- const ExplodedNode* N,
- BuiltinBugReport *R);
-};
-
class NullDerefChecker : public Checker {
- NullDeref *BT;
+ BuiltinBug *BT;
llvm::SmallVector<ExplodedNode*, 2> ImplicitNullDerefNodes;
public:
-
NullDerefChecker() : BT(0) {}
ExplodedNode *CheckLocation(const Stmt *S, ExplodedNode *Pred,
const GRState *state, SVal V,GRExprEngine &Eng);
- static void *getTag() {
- static int x = 0;
- return &x;
- }
-
+ static void *getTag();
typedef llvm::SmallVectorImpl<ExplodedNode*>::iterator iterator;
iterator implicit_nodes_begin() { return ImplicitNullDerefNodes.begin(); }
iterator implicit_nodes_end() { return ImplicitNullDerefNodes.end(); }
diff --git a/lib/Analysis/CMakeLists.txt b/lib/Analysis/CMakeLists.txt
index 89c1783..d3bf42b 100644
--- a/lib/Analysis/CMakeLists.txt
+++ b/lib/Analysis/CMakeLists.txt
@@ -28,6 +28,7 @@
GRState.cpp
LiveVariables.cpp
MemRegion.cpp
+ NullDerefChecker.cpp
PathDiagnostic.cpp
RangeConstraintManager.cpp
RegionStore.cpp
diff --git a/lib/Analysis/GRExprEngineInternalChecks.cpp b/lib/Analysis/GRExprEngineInternalChecks.cpp
index 526bc93..81b465e 100644
--- a/lib/Analysis/GRExprEngineInternalChecks.cpp
+++ b/lib/Analysis/GRExprEngineInternalChecks.cpp
@@ -66,11 +66,6 @@
for (; I != E; ++I) BR.EmitReport(new BuiltinBugReport(*this, desc.c_str(),
GetNode(I)));
}
-void NullDeref::registerInitialVisitors(BugReporterContext& BRC,
- const ExplodedNode* N,
- BuiltinBugReport *R) {
- registerTrackNullOrUndefValue(BRC, bugreporter::GetDerefExpr(N), N);
-}
class VISIBILITY_HIDDEN NilReceiverStructRet : public BuiltinBug {
public:
@@ -794,48 +789,8 @@
return Pred;
}
-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 NullDeref();
- BR.EmitReport(new BuiltinBugReport(*BT,BT->getDescription().c_str(),N));
- return 0;
- } else // Implicit null case.
- ImplicitNullDerefNodes.push_back(N);
- }
- }
-
- if (!NotNullState)
- return 0;
- return Builder.generateNode(S, NotNullState, Pred,
- ProgramPoint::PostLocationChecksSucceedKind);
-}
} // end clang namespace
+
//===----------------------------------------------------------------------===//
// Check registration.
//===----------------------------------------------------------------------===//
diff --git a/lib/Analysis/NullDerefChecker.cpp b/lib/Analysis/NullDerefChecker.cpp
new file mode 100644
index 0000000..2a899d2
--- /dev/null
+++ b/lib/Analysis/NullDerefChecker.cpp
@@ -0,0 +1,76 @@
+//== 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/NullDerefChecker.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);
+}