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) {} _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits