xazax.hun created this revision.
xazax.hun added reviewers: zaks.anna, krememek, jordan_rose, dcoughlin.
xazax.hun added a subscriber: cfe-commits.
For most of the implicit null pointer dereferences (when a pointer is
dereferenced and the static analyzer can not prove that the pointer is non
null, and can not prove that the pointer is null either) the DereferenceChecker
will emit an event. However in some cases (e.g. binding such pointers to
references in function parameters) no event will be emitted. This patch
addresses this problem by extending NonNullParamChecker to emit an event in
such cases. Future checkers (listening to these events) will profit from this
change. For example I am working on a checker for nullability qualifiers that
depend on this patch.
http://reviews.llvm.org/D11433
Files:
lib/StaticAnalyzer/Checkers/NonNullParamChecker.cpp
Index: lib/StaticAnalyzer/Checkers/NonNullParamChecker.cpp
===================================================================
--- lib/StaticAnalyzer/Checkers/NonNullParamChecker.cpp
+++ lib/StaticAnalyzer/Checkers/NonNullParamChecker.cpp
@@ -28,7 +28,7 @@
namespace {
class NonNullParamChecker
- : public Checker< check::PreCall > {
+ : public Checker< check::PreCall, EventDispatcher<ImplicitNullDerefEvent> > {
mutable std::unique_ptr<BugType> BTAttrNonNull;
mutable std::unique_ptr<BugType> BTNullRefArg;
@@ -139,26 +139,32 @@
ProgramStateRef stateNotNull, stateNull;
std::tie(stateNotNull, stateNull) = CM.assumeDual(state, *DV);
- if (stateNull && !stateNotNull) {
- // Generate an error node. Check for a null node in case
- // we cache out.
- if (ExplodedNode *errorNode = C.generateSink(stateNull)) {
+ if (stateNull) {
+ if (!stateNotNull){
+ // Generate an error node. Check for a null node in case
+ // we cache out.
+ if (ExplodedNode *errorNode = C.generateSink(stateNull)) {
- std::unique_ptr<BugReport> R;
- if (haveAttrNonNull)
- R = genReportNullAttrNonNull(errorNode, ArgE);
- else if (haveRefTypeParam)
- R = genReportReferenceToNullPointer(errorNode, ArgE);
+ std::unique_ptr<BugReport> R;
+ if (haveAttrNonNull)
+ R = genReportNullAttrNonNull(errorNode, ArgE);
+ else if (haveRefTypeParam)
+ R = genReportReferenceToNullPointer(errorNode, ArgE);
- // Highlight the range of the argument that was null.
- R->addRange(Call.getArgSourceRange(idx));
+ // Highlight the range of the argument that was null.
+ R->addRange(Call.getArgSourceRange(idx));
- // Emit the bug report.
- C.emitReport(std::move(R));
- }
+ // Emit the bug report.
+ C.emitReport(std::move(R));
+ }
- // Always return. Either we cached out or we just emitted an error.
- return;
+ // Always return. Either we cached out or we just emitted an error.
+ return;
+ }
+ if (ExplodedNode *N = C.generateSink(stateNull)) {
+ ImplicitNullDerefEvent event = { V, false, N, &C.getBugReporter() };
+ dispatchEvent(event);
+ }
}
// If a pointer value passed the check we should assume that it is
Index: lib/StaticAnalyzer/Checkers/NonNullParamChecker.cpp
===================================================================
--- lib/StaticAnalyzer/Checkers/NonNullParamChecker.cpp
+++ lib/StaticAnalyzer/Checkers/NonNullParamChecker.cpp
@@ -28,7 +28,7 @@
namespace {
class NonNullParamChecker
- : public Checker< check::PreCall > {
+ : public Checker< check::PreCall, EventDispatcher<ImplicitNullDerefEvent> > {
mutable std::unique_ptr<BugType> BTAttrNonNull;
mutable std::unique_ptr<BugType> BTNullRefArg;
@@ -139,26 +139,32 @@
ProgramStateRef stateNotNull, stateNull;
std::tie(stateNotNull, stateNull) = CM.assumeDual(state, *DV);
- if (stateNull && !stateNotNull) {
- // Generate an error node. Check for a null node in case
- // we cache out.
- if (ExplodedNode *errorNode = C.generateSink(stateNull)) {
+ if (stateNull) {
+ if (!stateNotNull){
+ // Generate an error node. Check for a null node in case
+ // we cache out.
+ if (ExplodedNode *errorNode = C.generateSink(stateNull)) {
- std::unique_ptr<BugReport> R;
- if (haveAttrNonNull)
- R = genReportNullAttrNonNull(errorNode, ArgE);
- else if (haveRefTypeParam)
- R = genReportReferenceToNullPointer(errorNode, ArgE);
+ std::unique_ptr<BugReport> R;
+ if (haveAttrNonNull)
+ R = genReportNullAttrNonNull(errorNode, ArgE);
+ else if (haveRefTypeParam)
+ R = genReportReferenceToNullPointer(errorNode, ArgE);
- // Highlight the range of the argument that was null.
- R->addRange(Call.getArgSourceRange(idx));
+ // Highlight the range of the argument that was null.
+ R->addRange(Call.getArgSourceRange(idx));
- // Emit the bug report.
- C.emitReport(std::move(R));
- }
+ // Emit the bug report.
+ C.emitReport(std::move(R));
+ }
- // Always return. Either we cached out or we just emitted an error.
- return;
+ // Always return. Either we cached out or we just emitted an error.
+ return;
+ }
+ if (ExplodedNode *N = C.generateSink(stateNull)) {
+ ImplicitNullDerefEvent event = { V, false, N, &C.getBugReporter() };
+ dispatchEvent(event);
+ }
}
// If a pointer value passed the check we should assume that it is
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits