aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/StaticAnalyzer/Checkers/CallAndMessageChecker.cpp24
-rw-r--r--lib/StaticAnalyzer/Core/CallEvent.cpp16
2 files changed, 16 insertions, 24 deletions
diff --git a/lib/StaticAnalyzer/Checkers/CallAndMessageChecker.cpp b/lib/StaticAnalyzer/Checkers/CallAndMessageChecker.cpp
index 439b92064f..70b6241dea 100644
--- a/lib/StaticAnalyzer/Checkers/CallAndMessageChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/CallAndMessageChecker.cpp
@@ -51,7 +51,7 @@ private:
bool IsFirstArgument, bool checkUninitFields,
const CallEvent &Call, OwningPtr<BugType> &BT);
- static void EmitBadCall(BugType *BT, CheckerContext &C, const CallExpr *CE);
+ static void emitBadCall(BugType *BT, CheckerContext &C, const Expr *BadE);
void emitNilReceiverBug(CheckerContext &C, const ObjCMethodCall &msg,
ExplodedNode *N) const;
@@ -66,15 +66,17 @@ private:
};
} // end anonymous namespace
-void CallAndMessageChecker::EmitBadCall(BugType *BT, CheckerContext &C,
- const CallExpr *CE) {
+void CallAndMessageChecker::emitBadCall(BugType *BT, CheckerContext &C,
+ const Expr *BadE) {
ExplodedNode *N = C.generateSink();
if (!N)
return;
BugReport *R = new BugReport(*BT, BT->getName(), N);
- R->addVisitor(bugreporter::getTrackNullOrUndefValueVisitor(N,
- bugreporter::GetCalleeExpr(N), R));
+ if (BadE) {
+ R->addRange(BadE->getSourceRange());
+ R->addVisitor(bugreporter::getTrackNullOrUndefValueVisitor(N, BadE, R));
+ }
C.EmitReport(R);
}
@@ -227,7 +229,7 @@ void CallAndMessageChecker::checkPreStmt(const CallExpr *CE,
if (!BT_call_undef)
BT_call_undef.reset(new BuiltinBug("Called function pointer is an "
"uninitalized pointer value"));
- EmitBadCall(BT_call_undef.get(), C, CE);
+ emitBadCall(BT_call_undef.get(), C, Callee);
return;
}
@@ -235,7 +237,7 @@ void CallAndMessageChecker::checkPreStmt(const CallExpr *CE,
if (!BT_call_null)
BT_call_null.reset(
new BuiltinBug("Called function pointer is null (null dereference)"));
- EmitBadCall(BT_call_null.get(), C, CE);
+ emitBadCall(BT_call_null.get(), C, Callee);
}
}
@@ -243,22 +245,20 @@ void CallAndMessageChecker::checkPreCall(const CallEvent &Call,
CheckerContext &C) const {
// If this is a call to a C++ method, check if the callee is null or
// undefined.
- // FIXME: Generalize this to CXXInstanceCall once it supports
- // getCXXThisVal().
- if (const CXXMemberCall *CC = dyn_cast<CXXMemberCall>(&Call)) {
+ if (const CXXInstanceCall *CC = dyn_cast<CXXInstanceCall>(&Call)) {
SVal V = CC->getCXXThisVal();
if (V.isUndef()) {
if (!BT_cxx_call_undef)
BT_cxx_call_undef.reset(new BuiltinBug("Called C++ object pointer is "
"uninitialized"));
- EmitBadCall(BT_cxx_call_undef.get(), C, CC->getOriginExpr());
+ emitBadCall(BT_cxx_call_undef.get(), C, CC->getCXXThisExpr());
return;
}
if (V.isZeroConstant()) {
if (!BT_cxx_call_null)
BT_cxx_call_null.reset(new BuiltinBug("Called C++ object pointer "
"is null"));
- EmitBadCall(BT_cxx_call_null.get(), C, CC->getOriginExpr());
+ emitBadCall(BT_cxx_call_null.get(), C, CC->getCXXThisExpr());
return;
}
}
diff --git a/lib/StaticAnalyzer/Core/CallEvent.cpp b/lib/StaticAnalyzer/Core/CallEvent.cpp
index fb00a226a2..05147670c1 100644
--- a/lib/StaticAnalyzer/Core/CallEvent.cpp
+++ b/lib/StaticAnalyzer/Core/CallEvent.cpp
@@ -419,21 +419,13 @@ void CXXInstanceCall::getInitialStackFrameContents(
-SVal CXXMemberCall::getCXXThisVal() const {
- const Expr *Base = getOriginExpr()->getImplicitObjectArgument();
-
- // FIXME: Will eventually need to cope with member pointers. This is
- // a limitation in getImplicitObjectArgument().
- if (!Base)
- return UnknownVal();
-
- return getSVal(Base);
+const Expr *CXXMemberCall::getCXXThisExpr() const {
+ return getOriginExpr()->getImplicitObjectArgument();
}
-SVal CXXMemberOperatorCall::getCXXThisVal() const {
- const Expr *Base = getOriginExpr()->getArg(0);
- return getSVal(Base);
+const Expr *CXXMemberOperatorCall::getCXXThisExpr() const {
+ return getOriginExpr()->getArg(0);
}