From 44405b7aacdb869be129430313a7bcb050336aa4 Mon Sep 17 00:00:00 2001 From: Jordan Rose Date: Thu, 4 Apr 2013 22:31:48 +0000 Subject: [PATCH] [analyzer] RetainCountChecker: refactor annotation handling. ...and add a new test case. I thought this was broken, but it isn't; refactoring and reformatting anyway so that I don't make the same mistake again. No functionality change. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@178799 91177308-0d34-0410-b5e6-96231b3b80d8 --- .../Checkers/RetainCountChecker.cpp | 104 +++++++----------- test/Analysis/retain-release.m | 15 +++ 2 files changed, 56 insertions(+), 63 deletions(-) diff --git a/lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp b/lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp index 32a0852ee3..79409e85bd 100644 --- a/lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp +++ b/lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp @@ -782,6 +782,10 @@ public: const RetainSummary *getStandardMethodSummary(const ObjCMethodDecl *MD, Selector S, QualType RetTy); + /// Determine if there is a special return effect for this function or method. + Optional getRetEffectFromAnnotations(QualType RetTy, + const Decl *D); + void updateSummaryFromAnnotations(const RetainSummary *&Summ, const ObjCMethodDecl *MD); @@ -1271,6 +1275,30 @@ RetainSummaryManager::getCFSummaryGetRule(const FunctionDecl *FD) { // Summary creation for Selectors. //===----------------------------------------------------------------------===// +Optional +RetainSummaryManager::getRetEffectFromAnnotations(QualType RetTy, + const Decl *D) { + if (cocoa::isCocoaObjectRef(RetTy)) { + if (D->getAttr()) + return ObjCAllocRetE; + + if (D->getAttr() || + D->getAttr()) + return RetEffect::MakeNotOwned(RetEffect::ObjC); + + } else if (!RetTy->isPointerType()) { + return None; + } + + if (D->getAttr()) + return RetEffect::MakeOwned(RetEffect::CF, true); + + if (D->getAttr()) + return RetEffect::MakeNotOwned(RetEffect::CF); + + return None; +} + void RetainSummaryManager::updateSummaryFromAnnotations(const RetainSummary *&Summ, const FunctionDecl *FD) { @@ -1285,40 +1313,15 @@ RetainSummaryManager::updateSummaryFromAnnotations(const RetainSummary *&Summ, for (FunctionDecl::param_const_iterator pi = FD->param_begin(), pe = FD->param_end(); pi != pe; ++pi, ++parm_idx) { const ParmVarDecl *pd = *pi; - if (pd->getAttr()) { - if (!GCEnabled) { - Template->addArg(AF, parm_idx, DecRef); - } - } else if (pd->getAttr()) { + if (pd->getAttr()) + Template->addArg(AF, parm_idx, DecRefMsg); + else if (pd->getAttr()) Template->addArg(AF, parm_idx, DecRef); - } } QualType RetTy = FD->getResultType(); - - // Determine if there is a special return effect for this method. - if (cocoa::isCocoaObjectRef(RetTy)) { - if (FD->getAttr()) { - Template->setRetEffect(ObjCAllocRetE); - } - else if (FD->getAttr()) { - Template->setRetEffect(RetEffect::MakeOwned(RetEffect::CF, true)); - } - else if (FD->getAttr() || - FD->getAttr()) { - Template->setRetEffect(RetEffect::MakeNotOwned(RetEffect::ObjC)); - } - else if (FD->getAttr()) - Template->setRetEffect(RetEffect::MakeNotOwned(RetEffect::CF)); - } - else if (RetTy->getAs()) { - if (FD->getAttr()) { - Template->setRetEffect(RetEffect::MakeOwned(RetEffect::CF, true)); - } - else if (FD->getAttr()) { - Template->setRetEffect(RetEffect::MakeNotOwned(RetEffect::CF)); - } - } + if (Optional RetE = getRetEffectFromAnnotations(RetTy, FD)) + Template->setRetEffect(*RetE); } void @@ -1329,13 +1332,10 @@ RetainSummaryManager::updateSummaryFromAnnotations(const RetainSummary *&Summ, assert(Summ && "Must have a valid summary to add annotations to"); RetainSummaryTemplate Template(Summ, *this); - bool isTrackedLoc = false; // Effects on the receiver. - if (MD->getAttr()) { - if (!GCEnabled) - Template->setReceiverEffect(DecRefMsg); - } + if (MD->getAttr()) + Template->setReceiverEffect(DecRefMsg); // Effects on the parameters. unsigned parm_idx = 0; @@ -1343,38 +1343,16 @@ RetainSummaryManager::updateSummaryFromAnnotations(const RetainSummary *&Summ, pi=MD->param_begin(), pe=MD->param_end(); pi != pe; ++pi, ++parm_idx) { const ParmVarDecl *pd = *pi; - if (pd->getAttr()) { - if (!GCEnabled) - Template->addArg(AF, parm_idx, DecRef); - } - else if(pd->getAttr()) { + if (pd->getAttr()) + Template->addArg(AF, parm_idx, DecRefMsg); + else if (pd->getAttr()) { Template->addArg(AF, parm_idx, DecRef); } } - // Determine if there is a special return effect for this method. - if (cocoa::isCocoaObjectRef(MD->getResultType())) { - if (MD->getAttr()) { - Template->setRetEffect(ObjCAllocRetE); - return; - } - if (MD->getAttr() || - MD->getAttr()) { - Template->setRetEffect(RetEffect::MakeNotOwned(RetEffect::ObjC)); - return; - } - - isTrackedLoc = true; - } else { - isTrackedLoc = MD->getResultType()->getAs() != NULL; - } - - if (isTrackedLoc) { - if (MD->getAttr()) - Template->setRetEffect(RetEffect::MakeOwned(RetEffect::CF, true)); - else if (MD->getAttr()) - Template->setRetEffect(RetEffect::MakeNotOwned(RetEffect::CF)); - } + QualType RetTy = MD->getResultType(); + if (Optional RetE = getRetEffectFromAnnotations(RetTy, MD)) + Template->setRetEffect(*RetE); } const RetainSummary * diff --git a/test/Analysis/retain-release.m b/test/Analysis/retain-release.m index 9de6cedaf0..5841650a1d 100644 --- a/test/Analysis/retain-release.m +++ b/test/Analysis/retain-release.m @@ -1967,6 +1967,21 @@ void test_drain() { [obj release]; // no-warning } +//===----------------------------------------------------------------------===// +// Allow cf_returns_retained and cf_returns_not_retained to mark a return +// value as tracked, even if the object isn't a known CF type. +//===----------------------------------------------------------------------===// + +MyCFType getCustom() __attribute__((cf_returns_not_retained)); +MyCFType makeCustom() __attribute__((cf_returns_retained)); + +void testCustomReturnsRetained() { + MyCFType obj = makeCustom(); // expected-warning {{leak of an object stored into 'obj'}} +} + +void testCustomReturnsNotRetained() { + CFRelease(getCustom()); // expected-warning {{Incorrect decrement of the reference count of an object that is not owned at this point by the caller}} +} // CHECK: diagnostics -- 2.40.0