Author: george.karpenkov Date: Tue Jan 22 11:51:00 2019 New Revision: 351865
URL: http://llvm.org/viewvc/llvm-project?rev=351865&view=rev Log: [analyzer] Insert notes in RetainCountChecker where our dynamic cast modeling assumes 'null' output rdar://47397214 Differential Revision: https://reviews.llvm.org/D56952 Modified: cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.cpp cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.h cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountDiagnostics.cpp cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountDiagnostics.h cfe/trunk/test/Analysis/osobject-retain-release.cpp Modified: cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.cpp?rev=351865&r1=351864&r2=351865&view=diff ============================================================================== --- cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.cpp (original) +++ cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.cpp Tue Jan 22 11:51:00 2019 @@ -575,7 +575,6 @@ void RetainCountChecker::checkSummary(co // Helper tag for providing diagnostics: indicate whether dealloc was sent // at this location. - static CheckerProgramPointTag DeallocSentTag(this, DeallocTagDescription); bool DeallocSent = false; for (unsigned idx = 0, e = CallOrMsg.getNumArgs(); idx != e; ++idx) { @@ -903,8 +902,7 @@ bool RetainCountChecker::evalCall(const // Assume that output is zero on the other branch. NullOutputState = NullOutputState->BindExpr( CE, LCtx, C.getSValBuilder().makeNull(), /*Invalidate=*/false); - - C.addTransition(NullOutputState); + C.addTransition(NullOutputState, &CastFailTag); // And on the original branch assume that both input and // output are non-zero. Modified: cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.h?rev=351865&r1=351864&r2=351865&view=diff ============================================================================== --- cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.h (original) +++ cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.h Tue Jan 22 11:51:00 2019 @@ -260,9 +260,11 @@ class RetainCountChecker RefCountBug leakWithinFunction{this, RefCountBug::LeakWithinFunction}; RefCountBug leakAtReturn{this, RefCountBug::LeakAtReturn}; + CheckerProgramPointTag DeallocSentTag{this, "DeallocSent"}; + CheckerProgramPointTag CastFailTag{this, "DynamicCastFail"}; + mutable std::unique_ptr<RetainSummaryManager> Summaries; public: - static constexpr const char *DeallocTagDescription = "DeallocSent"; /// Track Objective-C and CoreFoundation objects. bool TrackObjCAndCFObjects = false; @@ -361,6 +363,14 @@ public: CheckerContext &Ctx, ExplodedNode *Pred = nullptr) const; + const CheckerProgramPointTag &getDeallocSentTag() const { + return DeallocSentTag; + } + + const CheckerProgramPointTag &getCastFailTag() const { + return CastFailTag; + } + private: /// Perform the necessary checks and state adjustments at the end of the /// function. Modified: cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountDiagnostics.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountDiagnostics.cpp?rev=351865&r1=351864&r2=351865&view=diff ============================================================================== --- cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountDiagnostics.cpp (original) +++ cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountDiagnostics.cpp Tue Jan 22 11:51:00 2019 @@ -66,7 +66,7 @@ StringRef RefCountBug::getDescription() RefCountBug::RefCountBug(const CheckerBase *Checker, RefCountBugType BT) : BugType(Checker, bugTypeToName(BT), categories::MemoryRefCount, /*SupressOnSink=*/BT == LeakWithinFunction || BT == LeakAtReturn), - BT(BT) {} + BT(BT), Checker(Checker) {} static bool isNumericLiteralExpression(const Expr *E) { // FIXME: This set of cases was copied from SemaExprObjC. @@ -423,6 +423,8 @@ RefCountReportVisitor::VisitNode(const E BugReporterContext &BRC, BugReport &BR) { const auto &BT = static_cast<const RefCountBug&>(BR.getBugType()); + const auto *Checker = + static_cast<const RetainCountChecker *>(BT.getChecker()); bool IsFreeUnowned = BT.getBugType() == RefCountBug::FreeNotOwned || BT.getBugType() == RefCountBug::DeallocNotOwned; @@ -509,8 +511,12 @@ RefCountReportVisitor::VisitNode(const E bool DeallocSent = false; const ProgramPointTag *Tag = N->getLocation().getTag(); - if (Tag && Tag->getTagDescription().contains( - RetainCountChecker::DeallocTagDescription)) { + + if (Tag == &Checker->getCastFailTag()) { + os << "Assuming dynamic cast returns null due to type mismatch"; + } + + if (Tag == &Checker->getDeallocSentTag()) { // We only have summaries attached to nodes after evaluating CallExpr and // ObjCMessageExprs. const Stmt *S = N->getLocation().castAs<StmtPoint>().getStmt(); Modified: cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountDiagnostics.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountDiagnostics.h?rev=351865&r1=351864&r2=351865&view=diff ============================================================================== --- cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountDiagnostics.h (original) +++ cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountDiagnostics.h Tue Jan 22 11:51:00 2019 @@ -37,12 +37,18 @@ public: }; RefCountBug(const CheckerBase *checker, RefCountBugType BT); StringRef getDescription() const; + RefCountBugType getBugType() const { return BT; } + const CheckerBase *getChecker() const { + return Checker; + } + private: RefCountBugType BT; + const CheckerBase *Checker; static StringRef bugTypeToName(RefCountBugType BT); }; Modified: cfe/trunk/test/Analysis/osobject-retain-release.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/osobject-retain-release.cpp?rev=351865&r1=351864&r2=351865&view=diff ============================================================================== --- cfe/trunk/test/Analysis/osobject-retain-release.cpp (original) +++ cfe/trunk/test/Analysis/osobject-retain-release.cpp Tue Jan 22 11:51:00 2019 @@ -488,7 +488,7 @@ unsigned int check_dynamic_cast_no_null_ void check_dynamic_cast_null_branch(OSObject *obj) { OSArray *arr1 = OSArray::withCapacity(10); // expected-note{{Call to method 'OSArray::withCapacity' returns an OSObject}} - OSArray *arr = OSDynamicCast(OSArray, obj); + OSArray *arr = OSDynamicCast(OSArray, obj); // expected-note{{Assuming dynamic cast returns null due to type mismatch}} if (!arr) // expected-note{{Taking true branch}} return; // expected-warning{{Potential leak of an object stored into 'arr1'}} // expected-note@-1{{Object leaked}} @@ -499,6 +499,7 @@ void check_dynamic_cast_null_check() { OSArray *arr = OSDynamicCast(OSArray, OSObject::generateObject(1)); // expected-note{{Call to method 'OSObject::generateObject' returns an OSObject}} // expected-warning@-1{{Potential leak of an object}} // expected-note@-2{{Object leaked}} + // expected-note@-3{{Assuming dynamic cast returns null due to type mismatch}} if (!arr) return; arr->release(); _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits