namespace bugreporter {
-BugReporterVisitor *getTrackNullOrUndefValueVisitor(const ExplodedNode *N,
- const Stmt *S,
- BugReport *R);
+void addTrackNullOrUndefValueVisitor(const ExplodedNode *N, const Stmt *S,
+ BugReport *R);
const Stmt *GetDerefExpr(const ExplodedNode *N);
const Stmt *GetDenomExpr(const ExplodedNode *N);
// Highlight the range of the argument that was null.
R->addRange(Call.getArgSourceRange(idx));
if (const Expr *ArgE = Call.getArgExpr(idx))
- R->addVisitor(bugreporter::getTrackNullOrUndefValueVisitor(errorNode,
- ArgE, R));
+ bugreporter::addTrackNullOrUndefValueVisitor(errorNode, ArgE, R);
// Emit the bug report.
C.EmitReport(R);
}
BugReport *report = new BugReport(*BT, description, N);
report->addRange(Arg->getSourceRange());
- report->addVisitor(bugreporter::getTrackNullOrUndefValueVisitor(N, Arg,
- report));
+ bugreporter::addTrackNullOrUndefValueVisitor(N, Arg, report);
C.EmitReport(report);
return;
}
BugReport *report = new BugReport(*BT, os.str(), N);
report->addRange(S->getSourceRange());
- report->addVisitor(bugreporter::getTrackNullOrUndefValueVisitor(N, S,
- report));
+ bugreporter::addTrackNullOrUndefValueVisitor(N, S, report);
C.EmitReport(report);
return NULL;
}
BugReport *R = new BugReport(*BT, BT->getName(), N);
if (BadE) {
R->addRange(BadE->getSourceRange());
- R->addVisitor(bugreporter::getTrackNullOrUndefValueVisitor(N, BadE, R));
+ bugreporter::addTrackNullOrUndefValueVisitor(N, BadE, R);
}
C.EmitReport(R);
}
BugReport *R = new BugReport(*BT, Desc, N);
R->addRange(argRange);
if (argEx)
- R->addVisitor(bugreporter::getTrackNullOrUndefValueVisitor(N, argEx,
- R));
+ bugreporter::addTrackNullOrUndefValueVisitor(N, argEx, R);
C.EmitReport(R);
}
return true;
// FIXME: getTrackNullOrUndefValueVisitor can't handle "super" yet.
if (const Expr *ReceiverE = ME->getInstanceReceiver())
- R->addVisitor(bugreporter::getTrackNullOrUndefValueVisitor(N,
- ReceiverE,
- R));
+ bugreporter::addTrackNullOrUndefValueVisitor(N, ReceiverE, R);
C.EmitReport(R);
}
return;
report->addRange(ME->getReceiverRange());
// FIXME: This won't track "self" in messages to super.
if (const Expr *receiver = ME->getInstanceReceiver()) {
- report->addVisitor(bugreporter::getTrackNullOrUndefValueVisitor(N,
- receiver,
- report));
+ bugreporter::addTrackNullOrUndefValueVisitor(N, receiver, report);
}
C.EmitReport(report);
}
buf.empty() ? BT_null->getDescription() : buf.str(),
N);
- report->addVisitor(
- bugreporter::getTrackNullOrUndefValueVisitor(N,
- bugreporter::GetDerefExpr(N),
- report));
+ bugreporter::addTrackNullOrUndefValueVisitor(N, bugreporter::GetDerefExpr(N),
+ report);
for (SmallVectorImpl<SourceRange>::iterator
I = Ranges.begin(), E = Ranges.end(); I!=E; ++I)
BugReport *report =
new BugReport(*BT_undef, BT_undef->getDescription(), N);
- report->addVisitor(bugreporter::getTrackNullOrUndefValueVisitor(N,
- bugreporter::GetDerefExpr(N), report));
+ bugreporter::addTrackNullOrUndefValueVisitor(N,
+ bugreporter::GetDerefExpr(N),
+ report);
report->disablePathPruning();
C.EmitReport(report);
}
BugReport *R =
new BugReport(*BT, Msg, N);
- R->addVisitor(bugreporter::getTrackNullOrUndefValueVisitor(N,
- bugreporter::GetDenomExpr(N), R));
+ bugreporter::addTrackNullOrUndefValueVisitor(N,
+ bugreporter::GetDenomExpr(N),
+ R);
C.EmitReport(R);
}
}
"for @synchronized"));
BugReport *report =
new BugReport(*BT_undef, BT_undef->getDescription(), N);
- report->addVisitor(bugreporter::getTrackNullOrUndefValueVisitor(N, Ex,
- report));
+ bugreporter::addTrackNullOrUndefValueVisitor(N, Ex, report);
C.EmitReport(report);
}
return;
"(no synchronization will occur)"));
BugReport *report =
new BugReport(*BT_null, BT_null->getDescription(), N);
- report->addVisitor(bugreporter::getTrackNullOrUndefValueVisitor(N, Ex,
- report));
+ bugreporter::addTrackNullOrUndefValueVisitor(N, Ex, report);
C.EmitReport(report);
return;
report->disablePathPruning();
report->addRange(RetE->getSourceRange());
- report->addVisitor(bugreporter::getTrackNullOrUndefValueVisitor(N, RetE,
- report));
+ bugreporter::addTrackNullOrUndefValueVisitor(N, RetE, report);
C.EmitReport(report);
}
// Emit the bug report.
BugReport *R = new BugReport(*BT, BT->getDescription(), N);
- R->addVisitor(bugreporter::getTrackNullOrUndefValueVisitor(N, Ex, R));
+ bugreporter::addTrackNullOrUndefValueVisitor(N, Ex, R);
R->addRange(Ex->getSourceRange());
R->disablePathPruning();
BugReport *report = new BugReport(*BT, OS.str(), N);
if (Ex) {
report->addRange(Ex->getSourceRange());
- report->addVisitor(bugreporter::getTrackNullOrUndefValueVisitor(N, Ex,
- report));
+ bugreporter::addTrackNullOrUndefValueVisitor(N, Ex, report);
}
else
- report->addVisitor(bugreporter::getTrackNullOrUndefValueVisitor(N, B,
- report));
+ bugreporter::addTrackNullOrUndefValueVisitor(N, B, report);
report->disablePathPruning();
C.EmitReport(report);
// Generate a report for this bug.
BugReport *R = new BugReport(*BT, BT->getName(), N);
R->addRange(A->getIdx()->getSourceRange());
- R->addVisitor(bugreporter::getTrackNullOrUndefValueVisitor(N,
- A->getIdx(),
- R));
+ bugreporter::addTrackNullOrUndefValueVisitor(N, A->getIdx(), R);
C.EmitReport(R);
}
}
BugReport *R = new BugReport(*BT, str, N);
if (ex) {
R->addRange(ex->getSourceRange());
- R->addVisitor(bugreporter::getTrackNullOrUndefValueVisitor(N, ex, R));
+ bugreporter::addTrackNullOrUndefValueVisitor(N, ex, R);
}
R->disablePathPruning();
C.EmitReport(R);
BugReport *report = new BugReport(*BT_mallocZero, os.str(), N);
report->addRange(arg->getSourceRange());
- report->addVisitor(bugreporter::getTrackNullOrUndefValueVisitor(N, arg,
- report));
+ bugreporter::addTrackNullOrUndefValueVisitor(N, arg, report);
C.EmitReport(report);
return true;
BugReport *report = new BugReport(*BT, os.str(), N);
report->addRange(SizeE->getSourceRange());
- report->addVisitor(bugreporter::getTrackNullOrUndefValueVisitor(N, SizeE,
- report));
+ bugreporter::addTrackNullOrUndefValueVisitor(N, SizeE, report);
C.EmitReport(report);
return;
}
os << "declared without an initial value";
}
}
+ else {
+ os << "initialized here";
+ }
}
}
<< " is assigned to ";
}
else
- return NULL;
+ os << "Value assigned to ";
if (const VarRegion *VR = dyn_cast<VarRegion>(R)) {
os << '\'' << *VR->getDecl() << '\'';
return NULL;
}
-BugReporterVisitor *
-bugreporter::getTrackNullOrUndefValueVisitor(const ExplodedNode *N,
- const Stmt *S,
- BugReport *report) {
+void bugreporter::addTrackNullOrUndefValueVisitor(const ExplodedNode *N,
+ const Stmt *S,
+ BugReport *report) {
if (!S || !N)
- return 0;
+ return;
ProgramStateManager &StateMgr = N->getState()->getStateManager();
}
if (!N)
- return 0;
+ return;
ProgramStateRef state = N->getState();
SVal V = state->getRawSVal(loc::MemRegionVal(R));
report->markInteresting(R);
report->markInteresting(V);
- return new FindLastStoreBRVisitor(V, R);
+
+ if (V.getAsLocSymbol()) {
+ BugReporterVisitor *ConstraintTracker
+ = new TrackConstraintBRVisitor(cast<loc::MemRegionVal>(V), false);
+ report->addVisitor(ConstraintTracker);
+ }
+
+ report->addVisitor(new FindLastStoreBRVisitor(V, R));
+ return;
}
}
}
if (R) {
report->markInteresting(R);
- return new TrackConstraintBRVisitor(loc::MemRegionVal(R), false);
+ report->addVisitor(new TrackConstraintBRVisitor(loc::MemRegionVal(R),
+ false));
}
}
-
- return 0;
}
BugReporterVisitor *
// The receiver was nil, and hence the method was skipped.
// Register a BugReporterVisitor to issue a message telling us how
// the receiver was null.
- BR.addVisitor(bugreporter::getTrackNullOrUndefValueVisitor(N, Receiver, &BR));
+ bugreporter::addTrackNullOrUndefValueVisitor(N, Receiver, &BR);
// Issue a message saying that the method was skipped.
PathDiagnosticLocation L(Receiver, BRC.getSourceManager(),
N->getLocationContext());
// expected-note@-2 {{Returning from 'zero'}}
*a = 1; // expected-warning{{Dereference of null pointer}}
// expected-note@-1 {{Dereference of null pointer (loaded from variable 'a')}}
-}
\ No newline at end of file
+}
+
+
+void check(int *p) {
+ if (p) {
+ // expected-note@-1 + {{Assuming 'p' is null}}
+ // expected-note@-2 + {{Assuming pointer value is null}}
+ // expected-note@-3 + {{Taking false branch}}
+ return;
+ }
+ return;
+}
+
+void testCheck(int *a) {
+ check(a);
+ // expected-note@-1 {{Calling 'check'}}
+ // expected-note@-2 {{Returning from 'check'}}
+ *a = 1; // expected-warning{{Dereference of null pointer}}
+ // expected-note@-1 {{Dereference of null pointer (loaded from variable 'a')}}
+}
+
+
+int *getPointer();
+
+void testInitCheck() {
+ int *a = getPointer();
+ // expected-note@-1 {{Variable 'a' initialized here}}
+ check(a);
+ // expected-note@-1 {{Calling 'check'}}
+ // expected-note@-2 {{Returning from 'check'}}
+ *a = 1; // expected-warning{{Dereference of null pointer}}
+ // expected-note@-1 {{Dereference of null pointer (loaded from variable 'a')}}
+}
+
+void testStoreCheck(int *a) {
+ a = getPointer();
+ // expected-note@-1 {{Value assigned to 'a'}}
+ check(a);
+ // expected-note@-1 {{Calling 'check'}}
+ // expected-note@-2 {{Returning from 'check'}}
+ *a = 1; // expected-warning{{Dereference of null pointer}}
+ // expected-note@-1 {{Dereference of null pointer (loaded from variable 'a')}}
+}
}
void test_ic_null(TestInstanceCall *p) {
- if (!p) // expected-note {{Taking true branch}}
+ if (!p) // expected-note {{Assuming pointer value is null}} expected-note {{Taking true branch}}
p->foo(); // expected-warning {{Called C++ object pointer is null}} expected-note{{Called C++ object pointer is null}}
}