Author: george.karpenkov Date: Wed Dec 5 10:34:54 2018 New Revision: 348396
URL: http://llvm.org/viewvc/llvm-project?rev=348396&view=rev Log: [analyzer] Attribute for RetainCountChecker for OSObject should propagate with inheritance rdar://46388388 Differential Revision: https://reviews.llvm.org/D55154 Modified: cfe/trunk/lib/StaticAnalyzer/Core/RetainSummaryManager.cpp cfe/trunk/test/Analysis/osobject-retain-release.cpp Modified: cfe/trunk/lib/StaticAnalyzer/Core/RetainSummaryManager.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/RetainSummaryManager.cpp?rev=348396&r1=348395&r2=348396&view=diff ============================================================================== --- cfe/trunk/lib/StaticAnalyzer/Core/RetainSummaryManager.cpp (original) +++ cfe/trunk/lib/StaticAnalyzer/Core/RetainSummaryManager.cpp Wed Dec 5 10:34:54 2018 @@ -686,9 +686,59 @@ RetainSummaryManager::getRetEffectFromAn return RetEffect::MakeNotOwned(RetEffect::Generalized); } + if (const auto *MD = dyn_cast<CXXMethodDecl>(D)) + for (const auto *PD : MD->overridden_methods()) + if (auto RE = getRetEffectFromAnnotations(RetTy, PD)) + return RE; + return None; } +/// Apply the annotation of {@code pd} in function {@code FD} +/// to the resulting summary stored in out-parameter {@code Template}. +/// Return whether an annotation was applied. +bool applyFunctionParamAnnotationEffect(const ParmVarDecl *pd, + unsigned parm_idx, + const FunctionDecl *FD, + ArgEffects::Factory &AF, + RetainSummaryTemplate &Template) { + if (pd->hasAttr<NSConsumedAttr>()) { + Template->addArg(AF, parm_idx, DecRefMsg); + return true; + } else if (pd->hasAttr<CFConsumedAttr>() || pd->hasAttr<OSConsumedAttr>() || + hasRCAnnotation(pd, "rc_ownership_consumed")) { + Template->addArg(AF, parm_idx, DecRef); + return true; + } else if (pd->hasAttr<CFReturnsRetainedAttr>() || + hasRCAnnotation(pd, "rc_ownership_returns_retained")) { + QualType PointeeTy = pd->getType()->getPointeeType(); + if (!PointeeTy.isNull()) { + if (coreFoundation::isCFObjectRef(PointeeTy)) { + Template->addArg(AF, parm_idx, RetainedOutParameter); + return true; + } + } + } else if (pd->hasAttr<CFReturnsNotRetainedAttr>()) { + QualType PointeeTy = pd->getType()->getPointeeType(); + if (!PointeeTy.isNull()) { + if (coreFoundation::isCFObjectRef(PointeeTy)) { + Template->addArg(AF, parm_idx, UnretainedOutParameter); + return true; + } + } + } else { + if (const auto *MD = dyn_cast<CXXMethodDecl>(FD)) { + for (const auto *OD : MD->overridden_methods()) { + const ParmVarDecl *OP = OD->parameters()[parm_idx]; + if (applyFunctionParamAnnotationEffect(OP, parm_idx, MD, AF, Template)) + return true; + } + } + } + + return false; +} + void RetainSummaryManager::updateSummaryFromAnnotations(const RetainSummary *&Summ, const FunctionDecl *FD) { @@ -703,24 +753,7 @@ RetainSummaryManager::updateSummaryFromA for (auto pi = FD->param_begin(), pe = FD->param_end(); pi != pe; ++pi, ++parm_idx) { const ParmVarDecl *pd = *pi; - if (pd->hasAttr<NSConsumedAttr>()) { - Template->addArg(AF, parm_idx, DecRefMsg); - } else if (pd->hasAttr<CFConsumedAttr>() || - pd->hasAttr<OSConsumedAttr>() || - hasRCAnnotation(pd, "rc_ownership_consumed")) { - Template->addArg(AF, parm_idx, DecRef); - } else if (pd->hasAttr<CFReturnsRetainedAttr>() || - hasRCAnnotation(pd, "rc_ownership_returns_retained")) { - QualType PointeeTy = pd->getType()->getPointeeType(); - if (!PointeeTy.isNull()) - if (coreFoundation::isCFObjectRef(PointeeTy)) - Template->addArg(AF, parm_idx, RetainedOutParameter); - } else if (pd->hasAttr<CFReturnsNotRetainedAttr>()) { - QualType PointeeTy = pd->getType()->getPointeeType(); - if (!PointeeTy.isNull()) - if (coreFoundation::isCFObjectRef(PointeeTy)) - Template->addArg(AF, parm_idx, UnretainedOutParameter); - } + applyFunctionParamAnnotationEffect(pd, parm_idx, FD, AF, Template); } QualType RetTy = FD->getReturnType(); 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=348396&r1=348395&r2=348396&view=diff ============================================================================== --- cfe/trunk/test/Analysis/osobject-retain-release.cpp (original) +++ cfe/trunk/test/Analysis/osobject-retain-release.cpp Wed Dec 5 10:34:54 2018 @@ -21,12 +21,13 @@ struct OSObject { unsigned int foo() { return 42; } + virtual OS_RETURNS_NOT_RETAINED OSObject *identity(); + static OSObject *generateObject(int); static OSObject *getObject(); static OSObject *GetObject(); - static void * operator new(size_t size); static const OSMetaClass * const metaClass; @@ -40,6 +41,12 @@ struct OSIterator : public OSObject { struct OSArray : public OSObject { unsigned int getCount(); + OSIterator * getIterator(); + + OSObject *identity() override; + + virtual void consumeReference(OS_CONSUME OSArray *other); + static OSArray *generateArrayHasCode() { return new OSArray; } @@ -51,14 +58,18 @@ struct OSArray : public OSObject { return nullptr; } - OSIterator * getIterator(); - static OS_RETURNS_NOT_RETAINED OSArray *MaskedGetter(); static OS_RETURNS_RETAINED OSArray *getOoopsActuallyCreate(); static const OSMetaClass * const metaClass; }; +struct MyArray : public OSArray { + void consumeReference(OSArray *other) override; + + OSObject *identity() override; +}; + struct OtherStruct { static void doNothingToArray(OSArray *array); OtherStruct(OSArray *arr); @@ -68,6 +79,27 @@ struct OSMetaClassBase { static OSObject *safeMetaCast(const OSObject *inst, const OSMetaClass *meta); }; +void check_param_attribute_propagation(MyArray *parent) { + OSArray *arr = new OSArray; + parent->consumeReference(arr); +} + +unsigned int check_attribute_propagation(OSArray *arr) { + OSObject *other = arr->identity(); + OSArray *casted = OSDynamicCast(OSArray, other); + if (casted) + return casted->getCount(); + return 0; +} + +unsigned int check_attribute_indirect_propagation(MyArray *arr) { + OSObject *other = arr->identity(); + OSArray *casted = OSDynamicCast(OSArray, other); + if (casted) + return casted->getCount(); + return 0; +} + void check_free_no_error() { OSArray *arr = OSArray::withCapacity(10); arr->retain(); _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits