Fix: <rdar://problem/6893565> False positive: don't flag leaks for return types that cannot be determined to be CF types

llvm-svn: 71921
This commit is contained in:
Ted Kremenek 2009-05-16 01:38:01 +00:00
parent a28565ac62
commit e4302ee3bb
2 changed files with 47 additions and 19 deletions

View File

@ -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) {

View File

@ -631,6 +631,25 @@ void test_RDar6859457(RDar6859457 *x, void *bytes, NSUInteger dataLength) {
return [[NSString alloc] init]; // expected-warning{{leak}}
}
//===----------------------------------------------------------------------===//
// <rdar://problem/6893565> don't flag leaks for return types that cannot be
// determined to be CF types
//===----------------------------------------------------------------------===//
// We don't know if 'struct s6893565' represents a Core Foundation type, so
// we shouldn't emit an error here.
typedef struct s6893565* TD6893565;
@interface RDar6893565 {}
-(TD6893565)newThing;
@end
@implementation RDar6893565
-(TD6893565)newThing {
return (TD6893565) [[NSString alloc] init]; // no-warning
}
@end
//===----------------------------------------------------------------------===//
// Tests of ownership attributes.
//===----------------------------------------------------------------------===//