r351865 - [analyzer] Insert notes in RetainCountChecker where our dynamic cast modeling assumes 'null' output
George Karpenkov via cfe-commits
cfe-commits at lists.llvm.org
Tue Jan 22 11:51:00 PST 2019
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 at -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 at -1{{Potential leak of an object}}
// expected-note at -2{{Object leaked}}
+ // expected-note at -3{{Assuming dynamic cast returns null due to type mismatch}}
if (!arr)
return;
arr->release();
More information about the cfe-commits
mailing list