r351864 - [analyzer] Model another special-case kind of cast for OSObject RetainCountChecker
George Karpenkov via cfe-commits
cfe-commits at lists.llvm.org
Tue Jan 22 11:50:47 PST 2019
Author: george.karpenkov
Date: Tue Jan 22 11:50:47 2019
New Revision: 351864
URL: http://llvm.org/viewvc/llvm-project?rev=351864&view=rev
Log:
[analyzer] Model another special-case kind of cast for OSObject RetainCountChecker
Differential Revision: https://reviews.llvm.org/D56951
Modified:
cfe/trunk/include/clang/StaticAnalyzer/Core/RetainSummaryManager.h
cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.cpp
cfe/trunk/lib/StaticAnalyzer/Core/RetainSummaryManager.cpp
cfe/trunk/test/Analysis/os_object_base.h
cfe/trunk/test/Analysis/osobject-retain-release.cpp
Modified: cfe/trunk/include/clang/StaticAnalyzer/Core/RetainSummaryManager.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/StaticAnalyzer/Core/RetainSummaryManager.h?rev=351864&r1=351863&r2=351864&view=diff
==============================================================================
--- cfe/trunk/include/clang/StaticAnalyzer/Core/RetainSummaryManager.h (original)
+++ cfe/trunk/include/clang/StaticAnalyzer/Core/RetainSummaryManager.h Tue Jan 22 11:50:47 2019
@@ -677,6 +677,9 @@ public:
// Function returns the first argument.
Identity,
+ // Function returns "this" argument.
+ IdentityThis,
+
// Function either returns zero, or the input parameter.
IdentityOrZero
};
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=351864&r1=351863&r2=351864&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.cpp Tue Jan 22 11:50:47 2019
@@ -849,7 +849,6 @@ void RetainCountChecker::processNonLeakE
//===----------------------------------------------------------------------===//
bool RetainCountChecker::evalCall(const CallExpr *CE, CheckerContext &C) const {
- // Get the callee. We're only interested in simple C functions.
ProgramStateRef state = C.getState();
const FunctionDecl *FD = C.getCalleeDecl(CE);
if (!FD)
@@ -874,18 +873,27 @@ bool RetainCountChecker::evalCall(const
// Bind the return value.
if (BSmr == BehaviorSummary::Identity ||
- BSmr == BehaviorSummary::IdentityOrZero) {
- SVal RetVal = state->getSVal(CE->getArg(0), LCtx);
+ BSmr == BehaviorSummary::IdentityOrZero ||
+ BSmr == BehaviorSummary::IdentityThis) {
+
+ const Expr *BindReturnTo =
+ (BSmr == BehaviorSummary::IdentityThis)
+ ? cast<CXXMemberCallExpr>(CE)->getImplicitObjectArgument()
+ : CE->getArg(0);
+ SVal RetVal = state->getSVal(BindReturnTo, LCtx);
// If the receiver is unknown or the function has
// 'rc_ownership_trusted_implementation' annotate attribute, conjure a
// return value.
+ // FIXME: this branch is very strange.
if (RetVal.isUnknown() ||
(hasTrustedImplementationAnnotation && !ResultTy.isNull())) {
SValBuilder &SVB = C.getSValBuilder();
RetVal =
SVB.conjureSymbolVal(nullptr, CE, LCtx, ResultTy, C.blockCount());
}
+
+ // Bind the value.
state = state->BindExpr(CE, LCtx, RetVal, /*Invalidate=*/false);
if (BSmr == BehaviorSummary::IdentityOrZero) {
Modified: cfe/trunk/lib/StaticAnalyzer/Core/RetainSummaryManager.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/RetainSummaryManager.cpp?rev=351864&r1=351863&r2=351864&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Core/RetainSummaryManager.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/RetainSummaryManager.cpp Tue Jan 22 11:50:47 2019
@@ -152,6 +152,10 @@ static bool isOSObjectDynamicCast(String
return S == "safeMetaCast";
}
+static bool isOSObjectThisCast(StringRef S) {
+ return S == "metaCast";
+}
+
static bool isOSIteratorSubclass(const Decl *D) {
return isSubclass(D, "OSIterator");
}
@@ -219,13 +223,13 @@ RetainSummaryManager::getSummaryForOSObj
const CXXRecordDecl *PD = RetTy->getPointeeType()->getAsCXXRecordDecl();
if (PD && isOSObjectSubclass(PD)) {
if (const IdentifierInfo *II = FD->getIdentifier()) {
- if (isOSObjectDynamicCast(II->getName()))
+ StringRef FuncName = II->getName();
+ if (isOSObjectDynamicCast(FuncName) || isOSObjectThisCast(FuncName))
return getDefaultSummary();
// All objects returned with functions *not* starting with
// get, or iterators, are returned at +1.
- if ((!II->getName().startswith("get") &&
- !II->getName().startswith("Get")) ||
+ if ((!FuncName.startswith("get") && !FuncName.startswith("Get")) ||
isOSIteratorSubclass(PD)) {
return getOSSummaryCreateRule(FD);
} else {
@@ -703,8 +707,13 @@ RetainSummaryManager::canEval(const Call
// the input was non-zero),
// or that it returns zero (when the cast failed, or the input
// was zero).
- if (TrackOSObjects && isOSObjectDynamicCast(FName)) {
- return BehaviorSummary::IdentityOrZero;
+ if (TrackOSObjects) {
+ if (isOSObjectDynamicCast(FName) && FD->param_size() >= 1) {
+ return BehaviorSummary::IdentityOrZero;
+ } else if (isOSObjectThisCast(FName) && isa<CXXMethodDecl>(FD) &&
+ !cast<CXXMethodDecl>(FD)->isStatic()) {
+ return BehaviorSummary::IdentityThis;
+ }
}
const FunctionDecl* FDD = FD->getDefinition();
Modified: cfe/trunk/test/Analysis/os_object_base.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/os_object_base.h?rev=351864&r1=351863&r2=351864&view=diff
==============================================================================
--- cfe/trunk/test/Analysis/os_object_base.h (original)
+++ cfe/trunk/test/Analysis/os_object_base.h Tue Jan 22 11:50:47 2019
@@ -23,6 +23,8 @@ struct OSMetaClassBase {
static OSMetaClassBase *safeMetaCast(const OSMetaClassBase *inst,
const OSMetaClass *meta);
+ OSMetaClassBase *metaCast(const char *toMeta);
+
virtual void retain() const;
virtual void release() const;
virtual void free();
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=351864&r1=351863&r2=351864&view=diff
==============================================================================
--- cfe/trunk/test/Analysis/osobject-retain-release.cpp (original)
+++ cfe/trunk/test/Analysis/osobject-retain-release.cpp Tue Jan 22 11:50:47 2019
@@ -54,6 +54,9 @@ struct OtherStruct {
OtherStruct(OSArray *arr);
};
+bool test_meta_cast_no_leak(OSMetaClassBase *arg) {
+ return arg && arg->metaCast("blah") != nullptr;
+}
void escape(void *);
void escape_with_source(void *p) {}
More information about the cfe-commits
mailing list