diff options
author | Ted Kremenek <kremenek@apple.com> | 2012-02-18 20:53:30 +0000 |
---|---|---|
committer | Ted Kremenek <kremenek@apple.com> | 2012-02-18 20:53:30 +0000 |
commit | e98d63a823f02aa920e9cd4889c303f8e2ad7592 (patch) | |
tree | c982a9a24eabfbc62997b59002754698fa292185 /clang/lib/StaticAnalyzer/Checkers/CallAndMessageChecker.cpp | |
parent | c7cf23e4bf45918a045c7df5c8511a17e86556ad (diff) | |
download | bcm5719-llvm-e98d63a823f02aa920e9cd4889c303f8e2ad7592.tar.gz bcm5719-llvm-e98d63a823f02aa920e9cd4889c303f8e2ad7592.zip |
Adopt ExprEngine and checkers to ObjC property refactoring. Everything was working, but now diagnostics are aware of message expressions implied by uses of properties. Fixes <rdar://problem/9241180>.
llvm-svn: 150888
Diffstat (limited to 'clang/lib/StaticAnalyzer/Checkers/CallAndMessageChecker.cpp')
-rw-r--r-- | clang/lib/StaticAnalyzer/Checkers/CallAndMessageChecker.cpp | 25 |
1 files changed, 18 insertions, 7 deletions
diff --git a/clang/lib/StaticAnalyzer/Checkers/CallAndMessageChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/CallAndMessageChecker.cpp index 88a3be4139c..3a4c15f0d20 100644 --- a/clang/lib/StaticAnalyzer/Checkers/CallAndMessageChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/CallAndMessageChecker.cpp @@ -32,6 +32,7 @@ class CallAndMessageChecker mutable OwningPtr<BugType> BT_call_undef; mutable OwningPtr<BugType> BT_call_arg; mutable OwningPtr<BugType> BT_msg_undef; + mutable OwningPtr<BugType> BT_objc_prop_undef; mutable OwningPtr<BugType> BT_msg_arg; mutable OwningPtr<BugType> BT_msg_ret; public: @@ -228,11 +229,21 @@ void CallAndMessageChecker::checkPreObjCMessage(ObjCMessage msg, SVal recVal = state->getSVal(receiver, LCtx); if (recVal.isUndef()) { if (ExplodedNode *N = C.generateSink()) { - if (!BT_msg_undef) - BT_msg_undef.reset(new BuiltinBug("Receiver in message expression is " - "an uninitialized value")); + BugType *BT = 0; + if (msg.isPureMessageExpr()) { + if (!BT_msg_undef) + BT_msg_undef.reset(new BuiltinBug("Receiver in message expression " + "is an uninitialized value")); + BT = BT_msg_undef.get(); + } + else { + if (!BT_objc_prop_undef) + BT_objc_prop_undef.reset(new BuiltinBug("Property access on an " + "uninitialized object pointer")); + BT = BT_objc_prop_undef.get(); + } BugReport *R = - new BugReport(*BT_msg_undef, BT_msg_undef->getName(), N); + new BugReport(*BT, BT->getName(), N); R->addRange(receiver->getSourceRange()); R->addVisitor(bugreporter::getTrackNullOrUndefValueVisitor(N, receiver)); @@ -306,13 +317,13 @@ void CallAndMessageChecker::HandleNilReceiver(CheckerContext &C, if (CanRetTy->isStructureOrClassType()) { // Structure returns are safe since the compiler zeroes them out. SVal V = C.getSValBuilder().makeZeroVal(msg.getType(Ctx)); - C.addTransition(state->BindExpr(msg.getOriginExpr(), LCtx, V)); + C.addTransition(state->BindExpr(msg.getMessageExpr(), LCtx, V)); return; } // Other cases: check if sizeof(return type) > sizeof(void*) if (CanRetTy != Ctx.VoidTy && C.getLocationContext()->getParentMap() - .isConsumedExpr(msg.getOriginExpr())) { + .isConsumedExpr(msg.getMessageExpr())) { // Compute: sizeof(void *) and sizeof(return type) const uint64_t voidPtrSize = Ctx.getTypeSize(Ctx.VoidPtrTy); const uint64_t returnTypeSize = Ctx.getTypeSize(CanRetTy); @@ -343,7 +354,7 @@ void CallAndMessageChecker::HandleNilReceiver(CheckerContext &C, // of this case unless we have *a lot* more knowledge. // SVal V = C.getSValBuilder().makeZeroVal(msg.getType(Ctx)); - C.addTransition(state->BindExpr(msg.getOriginExpr(), LCtx, V)); + C.addTransition(state->BindExpr(msg.getMessageExpr(), LCtx, V)); return; } |