diff options
author | Gabor Horvath <xazax.hun@gmail.com> | 2015-08-27 18:49:07 +0000 |
---|---|---|
committer | Gabor Horvath <xazax.hun@gmail.com> | 2015-08-27 18:49:07 +0000 |
commit | 8d3ad6b6171531f258d26a250ccf26ecdea96430 (patch) | |
tree | 8d885a3884955b1610a412cf8cd6aa7d2167077b /clang/lib | |
parent | 8251f978d37608441f3270957f3c44caaf2cc2ba (diff) | |
download | bcm5719-llvm-8d3ad6b6171531f258d26a250ccf26ecdea96430.tar.gz bcm5719-llvm-8d3ad6b6171531f258d26a250ccf26ecdea96430.zip |
[Static Analyzer] Make NonNullParamChecker emit implicit null dereference events.
Differential Revision: http://reviews.llvm.org/D11433
llvm-svn: 246182
Diffstat (limited to 'clang/lib')
3 files changed, 34 insertions, 21 deletions
diff --git a/clang/lib/StaticAnalyzer/Checkers/DereferenceChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/DereferenceChecker.cpp index cf9d9f74385..07be5a59e51 100644 --- a/clang/lib/StaticAnalyzer/Checkers/DereferenceChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/DereferenceChecker.cpp @@ -220,7 +220,8 @@ void DereferenceChecker::checkLocation(SVal l, bool isLoad, const Stmt* S, // null or not-null. Record the error node as an "implicit" null // dereference. if (ExplodedNode *N = C.generateSink(nullState)) { - ImplicitNullDerefEvent event = { l, isLoad, N, &C.getBugReporter() }; + ImplicitNullDerefEvent event = {l, isLoad, N, &C.getBugReporter(), + /*IsDirectDereference=*/false}; dispatchEvent(event); } } @@ -257,8 +258,9 @@ void DereferenceChecker::checkBind(SVal L, SVal V, const Stmt *S, // At this point the value could be either null or non-null. // Record this as an "implicit" null dereference. if (ExplodedNode *N = C.generateSink(StNull)) { - ImplicitNullDerefEvent event = { V, /*isLoad=*/true, N, - &C.getBugReporter() }; + ImplicitNullDerefEvent event = {V, /*isLoad=*/true, N, + &C.getBugReporter(), + /*IsDirectDereference=*/false}; dispatchEvent(event); } } diff --git a/clang/lib/StaticAnalyzer/Checkers/NonNullParamChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/NonNullParamChecker.cpp index 73f8087fd3c..a7586c412af 100644 --- a/clang/lib/StaticAnalyzer/Checkers/NonNullParamChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/NonNullParamChecker.cpp @@ -28,7 +28,7 @@ using namespace ento; 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,34 @@ void NonNullParamChecker::checkPreCall(const CallEvent &Call, 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(), + /*IsDirectDereference=*/haveRefTypeParam}; + dispatchEvent(event); + } } // If a pointer value passed the check we should assume that it is diff --git a/clang/lib/StaticAnalyzer/Checkers/NullabilityChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/NullabilityChecker.cpp index f488b5f8567..ceb437d12f0 100644 --- a/clang/lib/StaticAnalyzer/Checkers/NullabilityChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/NullabilityChecker.cpp @@ -335,7 +335,10 @@ void NullabilityChecker::checkEvent(ImplicitNullDerefEvent Event) const { if (Filter.CheckNullableDereferenced && TrackedNullability->getValue() == Nullability::Nullable) { BugReporter &BR = *Event.BR; - reportBug(ErrorKind::NullableDereferenced, Event.SinkNode, Region, BR); + if (Event.IsDirectDereference) + reportBug(ErrorKind::NullableDereferenced, Event.SinkNode, Region, BR); + else + reportBug(ErrorKind::NullablePassedToNonnull, Event.SinkNode, Region, BR); } } |