summaryrefslogtreecommitdiffstats
path: root/lib/StaticAnalyzer/Checkers/StackAddrEscapeChecker.cpp
diff options
context:
space:
mode:
authordim <dim@FreeBSD.org>2011-07-17 15:40:56 +0000
committerdim <dim@FreeBSD.org>2011-07-17 15:40:56 +0000
commit611ba3ea3300b71eb95dc4e45f20eee5dddd32e1 (patch)
tree2097d084eb235c0b12c0bff3445f4ec7bbaa8a12 /lib/StaticAnalyzer/Checkers/StackAddrEscapeChecker.cpp
parentc49018d9cce52d8c9f34b44865ec3ba8e89a1488 (diff)
downloadFreeBSD-src-611ba3ea3300b71eb95dc4e45f20eee5dddd32e1.zip
FreeBSD-src-611ba3ea3300b71eb95dc4e45f20eee5dddd32e1.tar.gz
Vendor import of clang trunk r135360:
http://llvm.org/svn/llvm-project/cfe/trunk@135360
Diffstat (limited to 'lib/StaticAnalyzer/Checkers/StackAddrEscapeChecker.cpp')
-rw-r--r--lib/StaticAnalyzer/Checkers/StackAddrEscapeChecker.cpp20
1 files changed, 16 insertions, 4 deletions
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 @@ void StackAddrEscapeChecker::checkPreStmt(const ReturnStmt *RS,
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 @@ void StackAddrEscapeChecker::checkEndPath(EndOfFunctionNodeBuilder &B,
// 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 @@ void StackAddrEscapeChecker::checkEndPath(EndOfFunctionNodeBuilder &B,
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 @@ void StackAddrEscapeChecker::checkEndPath(EndOfFunctionNodeBuilder &B,
}
};
- CallBack cb(B.getPredecessor()->getLocationContext());
+ CallBack cb(Eng, B.getPredecessor()->getLocationContext());
state->getStateManager().getStoreManager().iterBindings(state->getStore(),cb);
if (cb.V.empty())
OpenPOWER on IntegriCloud