aboutsummaryrefslogtreecommitdiff
path: root/lib/Analysis/CFRefCount.cpp
diff options
context:
space:
mode:
authorTed Kremenek <kremenek@apple.com>2009-05-16 01:38:01 +0000
committerTed Kremenek <kremenek@apple.com>2009-05-16 01:38:01 +0000
commitfae664ac57991485a6235c2e27eaf089d5f54846 (patch)
treedfed84a52f32825f64a2a879ef33c1ad70596a4f /lib/Analysis/CFRefCount.cpp
parent938332c657390d1e782e0adc03b092993edae962 (diff)
Fix: <rdar://problem/6893565> False positive: don't flag leaks for return types that cannot be determined to be CF types
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@71921 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Analysis/CFRefCount.cpp')
-rw-r--r--lib/Analysis/CFRefCount.cpp47
1 files changed, 28 insertions, 19 deletions
diff --git a/lib/Analysis/CFRefCount.cpp b/lib/Analysis/CFRefCount.cpp
index 215be47086..fbe9582516 100644
--- a/lib/Analysis/CFRefCount.cpp
+++ b/lib/Analysis/CFRefCount.cpp
@@ -894,11 +894,18 @@ bool RetainSummaryManager::isTrackedObjCObjectType(QualType Ty) {
if (!OT)
return true;
- // Does the interface subclass NSObject?
- // FIXME: We can memoize here if this gets too expensive.
- IdentifierInfo* NSObjectII = &Ctx.Idents.get("NSObject");
+ // Does the interface subclass NSObject?
+ // FIXME: We can memoize here if this gets too expensive.
ObjCInterfaceDecl* ID = OT->getDecl();
+ // Assume that anything declared with a forward declaration and no
+ // @interface subclasses NSObject.
+ if (ID->isForwardDecl())
+ return true;
+
+ IdentifierInfo* NSObjectII = &Ctx.Idents.get("NSObject");
+
+
for ( ; ID ; ID = ID->getSuperClass())
if (ID->getIdentifier() == NSObjectII)
return true;
@@ -3142,22 +3149,24 @@ void CFRefCount::EvalReturn(ExplodedNodeSet<GRState>& Dst,
RetEffect RE = Summ.getRetEffect();
bool hasError = false;
- if (isGCEnabled() && RE.getObjKind() == RetEffect::ObjC) {
- // Things are more complicated with garbage collection. If the
- // returned object is suppose to be an Objective-C object, we have
- // a leak (as the caller expects a GC'ed object) because no
- // method should return ownership unless it returns a CF object.
- X = X ^ RefVal::ErrorGCLeakReturned;
-
- // Keep this false until this is properly tested.
- hasError = true;
- }
- else if (!RE.isOwned()) {
- // Either we are using GC and the returned object is a CF type
- // or we aren't using GC. In either case, we expect that the
- // enclosing method is expected to return ownership.
- hasError = true;
- X = X ^ RefVal::ErrorLeakReturned;
+ if (RE.getKind() != RetEffect::NoRet) {
+ if (isGCEnabled() && RE.getObjKind() == RetEffect::ObjC) {
+ // Things are more complicated with garbage collection. If the
+ // returned object is suppose to be an Objective-C object, we have
+ // a leak (as the caller expects a GC'ed object) because no
+ // method should return ownership unless it returns a CF object.
+ X = X ^ RefVal::ErrorGCLeakReturned;
+
+ // Keep this false until this is properly tested.
+ hasError = true;
+ }
+ else if (!RE.isOwned()) {
+ // Either we are using GC and the returned object is a CF type
+ // or we aren't using GC. In either case, we expect that the
+ // enclosing method is expected to return ownership.
+ hasError = true;
+ X = X ^ RefVal::ErrorLeakReturned;
+ }
}
if (hasError) {