Author: george.karpenkov Date: Fri Dec 7 17:18:40 2018 New Revision: 348675
URL: http://llvm.org/viewvc/llvm-project?rev=348675&view=rev Log: Stop tracking retain count of OSObject after escape to void * / other primitive types Escaping to void * / uint64_t / others non-OSObject * should stop tracking, as such functions can have heterogeneous semantics depending on context, and can not always be annotated. rdar://46439133 Differential Revision: https://reviews.llvm.org/D55465 Modified: cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.cpp 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=348675&r1=348674&r2=348675&view=diff ============================================================================== --- cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.cpp (original) +++ cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.cpp Fri Dec 7 17:18:40 2018 @@ -574,6 +574,25 @@ static ProgramStateRef updateOutParamete return State; } +static bool isPointerToObject(QualType QT) { + QualType PT = QT->getPointeeType(); + if (!PT.isNull()) + if (PT->getAsCXXRecordDecl()) + return true; + return false; +} + +/// Whether the tracked value should be escaped on a given call. +/// OSObjects are escaped when passed to void * / etc. +static bool shouldEscapeArgumentOnCall(const CallEvent &CE, unsigned ArgIdx, + const RefVal *TrackedValue) { + if (TrackedValue->getObjKind() != RetEffect::OS) + return false; + if (ArgIdx >= CE.parameters().size()) + return false; + return !isPointerToObject(CE.parameters()[ArgIdx]->getType()); +} + void RetainCountChecker::checkSummary(const RetainSummary &Summ, const CallEvent &CallOrMsg, CheckerContext &C) const { @@ -592,6 +611,10 @@ void RetainCountChecker::checkSummary(co state = updateOutParameter(state, V, Effect); } else if (SymbolRef Sym = V.getAsLocSymbol()) { if (const RefVal *T = getRefBinding(state, Sym)) { + + if (shouldEscapeArgumentOnCall(CallOrMsg, idx, T)) + Effect = StopTrackingHard; + state = updateSymbol(state, Sym, *T, Effect, hasErr, C); if (hasErr) { ErrorRange = CallOrMsg.getArgSourceRange(idx); 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=348675&r1=348674&r2=348675&view=diff ============================================================================== --- cfe/trunk/test/Analysis/osobject-retain-release.cpp (original) +++ cfe/trunk/test/Analysis/osobject-retain-release.cpp Fri Dec 7 17:18:40 2018 @@ -89,6 +89,13 @@ struct OSMetaClassBase { static OSObject *safeMetaCast(const OSObject *inst, const OSMetaClass *meta); }; +void escape(void *); + +void test_escaping_into_voidstar() { + OSObject *obj = new OSObject; + escape(obj); +} + void test_no_infinite_check_recursion(MyArray *arr) { OSObject *input = new OSObject; OSObject *o = arr->generateObject(input); _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits