diff options
author | Jordy Rose <jediknil@belkadan.com> | 2011-08-24 09:02:37 +0000 |
---|---|---|
committer | Jordy Rose <jediknil@belkadan.com> | 2011-08-24 09:02:37 +0000 |
commit | 0fe62f8a8c6d9f75842cd8f8349ca7b80952f785 (patch) | |
tree | f995ffffe830b1e83b27e0913956eb722a4a9ee5 /lib/StaticAnalyzer/Core/CFRefCount.cpp | |
parent | 35c869593677e89fb531c069f7b66eb53e0e5084 (diff) |
[analyzer] Fix potential crasher with RAII. No functionality change. (No test because this particular circumstance requires an impossible series of events, but this is future-proofing.)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@138430 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/StaticAnalyzer/Core/CFRefCount.cpp')
-rw-r--r-- | lib/StaticAnalyzer/Core/CFRefCount.cpp | 88 |
1 files changed, 50 insertions, 38 deletions
diff --git a/lib/StaticAnalyzer/Core/CFRefCount.cpp b/lib/StaticAnalyzer/Core/CFRefCount.cpp index 11d240c31e..8a7d3acbbd 100644 --- a/lib/StaticAnalyzer/Core/CFRefCount.cpp +++ b/lib/StaticAnalyzer/Core/CFRefCount.cpp @@ -854,6 +854,37 @@ public: } }; +// Used to avoid allocating long-term (BPAlloc'd) memory for default retain +// summaries. If a function or method looks like it has a default summary, but +// it has annotations, the annotations are added to the stack-based template +// and then copied into managed memory. +class RetainSummaryTemplate { + RetainSummaryManager &Manager; + RetainSummary *&RealSummary; + RetainSummary ScratchSummary; + bool Accessed; +public: + RetainSummaryTemplate(RetainSummary *&real, const RetainSummary &base, + RetainSummaryManager &manager) + : Manager(manager), RealSummary(real), ScratchSummary(base), Accessed(false) + {} + + ~RetainSummaryTemplate() { + if (!RealSummary && Accessed) + RealSummary = Manager.copySummary(&ScratchSummary); + } + + RetainSummary &operator*() { + Accessed = true; + return RealSummary ? *RealSummary : ScratchSummary; + } + + RetainSummary *operator->() { + Accessed = true; + return RealSummary ? RealSummary : &ScratchSummary; + } +}; + } // end anonymous namespace //===----------------------------------------------------------------------===// @@ -1166,9 +1197,7 @@ RetainSummaryManager::updateSummaryFromAnnotations(RetainSummary *&Summ, if (!FD) return; - RetainSummary BasedOnDefault(DefaultSummary); - if (!Summ) - Summ = &BasedOnDefault; + RetainSummaryTemplate Template(Summ, DefaultSummary, *this); // Effects on the parameters. unsigned parm_idx = 0; @@ -1177,10 +1206,10 @@ RetainSummaryManager::updateSummaryFromAnnotations(RetainSummary *&Summ, const ParmVarDecl *pd = *pi; if (pd->getAttr<NSConsumedAttr>()) { if (!GCEnabled) { - Summ->addArg(AF, parm_idx, DecRef); + Template->addArg(AF, parm_idx, DecRef); } } else if (pd->getAttr<CFConsumedAttr>()) { - Summ->addArg(AF, parm_idx, DecRef); + Template->addArg(AF, parm_idx, DecRef); } } @@ -1189,32 +1218,25 @@ RetainSummaryManager::updateSummaryFromAnnotations(RetainSummary *&Summ, // Determine if there is a special return effect for this method. if (cocoa::isCocoaObjectRef(RetTy)) { if (FD->getAttr<NSReturnsRetainedAttr>()) { - Summ->setRetEffect(ObjCAllocRetE); + Template->setRetEffect(ObjCAllocRetE); } else if (FD->getAttr<CFReturnsRetainedAttr>()) { - Summ->setRetEffect(RetEffect::MakeOwned(RetEffect::CF, true)); + Template->setRetEffect(RetEffect::MakeOwned(RetEffect::CF, true)); } else if (FD->getAttr<NSReturnsNotRetainedAttr>()) { - Summ->setRetEffect(RetEffect::MakeNotOwned(RetEffect::ObjC)); + Template->setRetEffect(RetEffect::MakeNotOwned(RetEffect::ObjC)); } else if (FD->getAttr<CFReturnsNotRetainedAttr>()) { - Summ->setRetEffect(RetEffect::MakeNotOwned(RetEffect::CF)); + Template->setRetEffect(RetEffect::MakeNotOwned(RetEffect::CF)); } } else if (RetTy->getAs<PointerType>()) { if (FD->getAttr<CFReturnsRetainedAttr>()) { - Summ->setRetEffect(RetEffect::MakeOwned(RetEffect::CF, true)); + Template->setRetEffect(RetEffect::MakeOwned(RetEffect::CF, true)); } else if (FD->getAttr<CFReturnsNotRetainedAttr>()) { - Summ->setRetEffect(RetEffect::MakeNotOwned(RetEffect::CF)); + Template->setRetEffect(RetEffect::MakeNotOwned(RetEffect::CF)); } } - - if (Summ == &BasedOnDefault) { - if (!(*Summ == DefaultSummary)) - Summ = copySummary(Summ); - else - Summ = 0; - } } void @@ -1223,16 +1245,14 @@ RetainSummaryManager::updateSummaryFromAnnotations(RetainSummary *&Summ, if (!MD) return; - RetainSummary BasedOnDefault = DefaultSummary; - if (!Summ) - Summ = &BasedOnDefault; + RetainSummaryTemplate Template(Summ, DefaultSummary, *this); bool isTrackedLoc = false; // Effects on the receiver. if (MD->getAttr<NSConsumesSelfAttr>()) { if (!GCEnabled) - Summ->setReceiverEffect(DecRefMsg); + Template->setReceiverEffect(DecRefMsg); } // Effects on the parameters. @@ -1242,42 +1262,34 @@ RetainSummaryManager::updateSummaryFromAnnotations(RetainSummary *&Summ, const ParmVarDecl *pd = *pi; if (pd->getAttr<NSConsumedAttr>()) { if (!GCEnabled) - Summ->addArg(AF, parm_idx, DecRef); + Template->addArg(AF, parm_idx, DecRef); } else if(pd->getAttr<CFConsumedAttr>()) { - Summ->addArg(AF, parm_idx, DecRef); + 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<NSReturnsRetainedAttr>()) { - Summ->setRetEffect(ObjCAllocRetE); + Template->setRetEffect(ObjCAllocRetE); return; } if (MD->getAttr<NSReturnsNotRetainedAttr>()) { - Summ->setRetEffect(RetEffect::MakeNotOwned(RetEffect::ObjC)); + Template->setRetEffect(RetEffect::MakeNotOwned(RetEffect::ObjC)); return; } isTrackedLoc = true; - } - - if (!isTrackedLoc) + } else { isTrackedLoc = MD->getResultType()->getAs<PointerType>() != NULL; + } if (isTrackedLoc) { if (MD->getAttr<CFReturnsRetainedAttr>()) - Summ->setRetEffect(RetEffect::MakeOwned(RetEffect::CF, true)); + Template->setRetEffect(RetEffect::MakeOwned(RetEffect::CF, true)); else if (MD->getAttr<CFReturnsNotRetainedAttr>()) - Summ->setRetEffect(RetEffect::MakeNotOwned(RetEffect::CF)); - } - - if (Summ == &BasedOnDefault) { - if (!(*Summ == DefaultSummary)) - Summ = copySummary(Summ); - else - Summ = 0; + Template->setRetEffect(RetEffect::MakeNotOwned(RetEffect::CF)); } } |