aboutsummaryrefslogtreecommitdiff
path: root/lib/Analysis/CFRefCount.cpp
diff options
context:
space:
mode:
authorTed Kremenek <kremenek@apple.com>2009-01-29 22:45:13 +0000
committerTed Kremenek <kremenek@apple.com>2009-01-29 22:45:13 +0000
commit6818928f39603e8c97f04ec0c3f467084e22ac85 (patch)
tree6228c8f9abf62a717f1f1a101e3aaf3c94ec6eb6 /lib/Analysis/CFRefCount.cpp
parent59ebd28462cfb6249a3db1fad5d81f0328fb9787 (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.cpp27
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);
}
}
}