diff options
| author | Anna Zaks <ganna@apple.com> | 2013-04-03 19:28:19 +0000 |
|---|---|---|
| committer | Anna Zaks <ganna@apple.com> | 2013-04-03 19:28:19 +0000 |
| commit | c610bcacdea31a03104a7456cff63b37aca62c54 (patch) | |
| tree | 15fe6a3addcfcfdf8c145b1e7fc75f121220672b /clang/lib/StaticAnalyzer | |
| parent | b5d2fe8a1d94bfd0a44c3de6f32d4afc1786eb11 (diff) | |
| download | bcm5719-llvm-c610bcacdea31a03104a7456cff63b37aca62c54.tar.gz bcm5719-llvm-c610bcacdea31a03104a7456cff63b37aca62c54.zip | |
[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.
llvm-svn: 178686
Diffstat (limited to 'clang/lib/StaticAnalyzer')
| -rw-r--r-- | clang/lib/StaticAnalyzer/Checkers/CallAndMessageChecker.cpp | 31 |
1 files changed, 19 insertions, 12 deletions
diff --git a/clang/lib/StaticAnalyzer/Checkers/CallAndMessageChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/CallAndMessageChecker.cpp index 75c7df8734f..4965d229961 100644 --- a/clang/lib/StaticAnalyzer/Checkers/CallAndMessageChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/CallAndMessageChecker.cpp @@ -366,17 +366,23 @@ void CallAndMessageChecker::emitNilReceiverBug(CheckerContext &C, 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::HandleNilReceiver(CheckerContext &C, 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; |

