r178686 - [analyzer] Warn when nil receiver results in forming null reference
Anna Zaks
ganna at apple.com
Wed Apr 3 12:28:19 PDT 2013
Author: zaks
Date: Wed Apr 3 14:28:19 2013
New Revision: 178686
URL: http://llvm.org/viewvc/llvm-project?rev=178686&view=rev
Log:
[analyzer] Warn when nil receiver results in forming null reference
This also allows us to ensure IDC/return null suppression gets triggered in such cases.
Added:
cfe/trunk/test/Analysis/reference.mm
Modified:
cfe/trunk/lib/StaticAnalyzer/Checkers/CallAndMessageChecker.cpp
Modified: cfe/trunk/lib/StaticAnalyzer/Checkers/CallAndMessageChecker.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/CallAndMessageChecker.cpp?rev=178686&r1=178685&r2=178686&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Checkers/CallAndMessageChecker.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Checkers/CallAndMessageChecker.cpp Wed Apr 3 14:28:19 2013
@@ -366,17 +366,23 @@ void CallAndMessageChecker::emitNilRecei
if (!BT_msg_ret)
BT_msg_ret.reset(
- new BuiltinBug("Receiver in message expression is "
- "'nil' and returns a garbage value"));
+ new BuiltinBug("Receiver in message expression is 'nil'"));
const ObjCMessageExpr *ME = msg.getOriginExpr();
+ QualType ResTy = msg.getResultType();
+
SmallString<200> buf;
llvm::raw_svector_ostream os(buf);
os << "The receiver of message '" << ME->getSelector().getAsString()
- << "' is nil and returns a value of type '";
- msg.getResultType().print(os, C.getLangOpts());
- os << "' that will be garbage";
+ << "' is nil";
+ if (ResTy->isReferenceType()) {
+ os << ", which results in forming a null reference";
+ } else {
+ os << " and returns a value of type '";
+ msg.getResultType().print(os, C.getLangOpts());
+ os << "' that will be garbage";
+ }
BugReport *report = new BugReport(*BT_msg_ret, os.str(), N);
report->addRange(ME->getReceiverRange());
@@ -419,13 +425,14 @@ void CallAndMessageChecker::HandleNilRec
const uint64_t voidPtrSize = Ctx.getTypeSize(Ctx.VoidPtrTy);
const uint64_t returnTypeSize = Ctx.getTypeSize(CanRetTy);
- if (voidPtrSize < returnTypeSize &&
- !(supportsNilWithFloatRet(Ctx.getTargetInfo().getTriple()) &&
- (Ctx.FloatTy == CanRetTy ||
- Ctx.DoubleTy == CanRetTy ||
- Ctx.LongDoubleTy == CanRetTy ||
- Ctx.LongLongTy == CanRetTy ||
- Ctx.UnsignedLongLongTy == CanRetTy))) {
+ if (CanRetTy.getTypePtr()->isReferenceType()||
+ (voidPtrSize < returnTypeSize &&
+ !(supportsNilWithFloatRet(Ctx.getTargetInfo().getTriple()) &&
+ (Ctx.FloatTy == CanRetTy ||
+ Ctx.DoubleTy == CanRetTy ||
+ Ctx.LongDoubleTy == CanRetTy ||
+ Ctx.LongLongTy == CanRetTy ||
+ Ctx.UnsignedLongLongTy == CanRetTy)))) {
if (ExplodedNode *N = C.generateSink(state, 0 , &Tag))
emitNilReceiverBug(C, Msg, N);
return;
Added: cfe/trunk/test/Analysis/reference.mm
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/reference.mm?rev=178686&view=auto
==============================================================================
--- cfe/trunk/test/Analysis/reference.mm (added)
+++ cfe/trunk/test/Analysis/reference.mm Wed Apr 3 14:28:19 2013
@@ -0,0 +1,17 @@
+// RUN: %clang_cc1 -analyze -analyzer-checker=core -verify -Wno-null-dereference %s
+
+ at interface Foo
+- (int &)ref;
+ at end
+
+Foo *getFoo() { return 0; }
+
+void testNullPointerSuppression() {
+ getFoo().ref = 1;
+}
+
+void testPositiveNullReference() {
+ Foo *x = 0;
+ x.ref = 1; // expected-warning {{The receiver of message 'ref' is nil, which results in forming a null reference}}
+}
+
More information about the cfe-commits
mailing list