Automatic Reference Counting.
Language-design credit goes to a lot of people, but I particularly want
to single out Blaine Garst and Patrick Beard for their contributions.
Compiler implementation credit goes to Argyrios, Doug, Fariborz, and myself,
in no particular order.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@133103 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/StaticAnalyzer/Checkers/StackAddrEscapeChecker.cpp b/lib/StaticAnalyzer/Checkers/StackAddrEscapeChecker.cpp
index 07de870..73ce359 100644
--- a/lib/StaticAnalyzer/Checkers/StackAddrEscapeChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/StackAddrEscapeChecker.cpp
@@ -121,6 +121,11 @@
return;
if (R->hasStackStorage()) {
+ // Automatic reference counting automatically copies blocks.
+ if (C.getASTContext().getLangOptions().ObjCAutoRefCount &&
+ isa<BlockDataRegion>(R))
+ return;
+
EmitStackError(C, R, RetE);
return;
}
@@ -135,12 +140,13 @@
// a memory region in the stack space.
class CallBack : public StoreManager::BindingsHandler {
private:
+ ExprEngine &Eng;
const StackFrameContext *CurSFC;
public:
llvm::SmallVector<std::pair<const MemRegion*, const MemRegion*>, 10> V;
- CallBack(const LocationContext *LCtx)
- : CurSFC(LCtx->getCurrentStackFrame()) {}
+ CallBack(ExprEngine &Eng, const LocationContext *LCtx)
+ : Eng(Eng), CurSFC(LCtx->getCurrentStackFrame()) {}
bool HandleBinding(StoreManager &SMgr, Store store,
const MemRegion *region, SVal val) {
@@ -151,7 +157,13 @@
const MemRegion *vR = val.getAsRegion();
if (!vR)
return true;
-
+
+ // Under automated retain release, it is okay to assign a block
+ // directly to a global variable.
+ if (Eng.getContext().getLangOptions().ObjCAutoRefCount &&
+ isa<BlockDataRegion>(vR))
+ return true;
+
if (const StackSpaceRegion *SSR =
dyn_cast<StackSpaceRegion>(vR->getMemorySpace())) {
// If the global variable holds a location in the current stack frame,
@@ -164,7 +176,7 @@
}
};
- CallBack cb(B.getPredecessor()->getLocationContext());
+ CallBack cb(Eng, B.getPredecessor()->getLocationContext());
state->getStateManager().getStoreManager().iterBindings(state->getStore(),cb);
if (cb.V.empty())