diff options
author | Ted Kremenek <kremenek@apple.com> | 2009-01-29 22:45:13 +0000 |
---|---|---|
committer | Ted Kremenek <kremenek@apple.com> | 2009-01-29 22:45:13 +0000 |
commit | 6818928f39603e8c97f04ec0c3f467084e22ac85 (patch) | |
tree | 6228c8f9abf62a717f1f1a101e3aaf3c94ec6eb6 /lib/Analysis/CFRefCount.cpp | |
parent | 59ebd28462cfb6249a3db1fad5d81f0328fb9787 (diff) |
retain/release checker: When generating summaries for CF/CG functions, allow arguments to "escape" if they are passed to a function containing the terms "InsertValue", "SetValue", or "AddValue". This fixes <rdar://problem/6539791>.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@63341 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Analysis/CFRefCount.cpp')
-rw-r--r-- | lib/Analysis/CFRefCount.cpp | 27 |
1 files changed, 21 insertions, 6 deletions
diff --git a/lib/Analysis/CFRefCount.cpp b/lib/Analysis/CFRefCount.cpp index 35b7ee7b80..ab9d409dd2 100644 --- a/lib/Analysis/CFRefCount.cpp +++ b/lib/Analysis/CFRefCount.cpp @@ -809,12 +809,27 @@ RetainSummary* RetainSummaryManager::getSummary(FunctionDecl* FD) { if (isRelease(FD, FName+2)) S = getUnarySummary(FT, cfrelease); else { - // For CoreFoundation and CoreGraphics functions we assume they - // follow the ownership idiom strictly and thus do not cause - // ownership to "escape". - assert (ScratchArgs.empty()); - S = getPersistentSummary(RetEffect::MakeNoRet(), DoNothing, - DoNothing); + assert (ScratchArgs.empty()); + // Remaining CoreFoundation and CoreGraphics functions. + // We use to assume that they all strictly followed the ownership idiom + // and that ownership cannot be transferred. While this is technically + // correct, many methods allow a tracked object to escape. For example: + // + // CFMutableDictionaryRef x = CFDictionaryCreateMutable(...); + // CFDictionaryAddValue(y, key, x); + // CFRelease(x); + // ... it is okay to use 'x' since 'y' has a reference to it + // + // We handle this and similar cases with the follow heuristic. If the + // function name contains "InsertValue", "SetValue" or "AddValue" then + // we assume that arguments may "escape." + // + ArgEffect E = (CStrInCStrNoCase(FName, "InsertValue") || + CStrInCStrNoCase(FName, "AddValue") || + CStrInCStrNoCase(FName, "SetValue")) + ? MayEscape : DoNothing; + + S = getPersistentSummary(RetEffect::MakeNoRet(), DoNothing, E); } } } |