Add special warning about returning a retained object where a GC'ed object is expected.

llvm-svn: 71397
This commit is contained in:
Ted Kremenek 2009-05-10 16:52:15 +00:00
parent 004192bde3
commit 1f8e4346fa
2 changed files with 14 additions and 8 deletions

View File

@ -2517,9 +2517,10 @@ CFRefLeakReport::getEndPath(BugReporterContext& BRC,
else if (RV->getKind() == RefVal::ErrorGCLeakReturned) { else if (RV->getKind() == RefVal::ErrorGCLeakReturned) {
ObjCMethodDecl& MD = cast<ObjCMethodDecl>(BRC.getCodeDecl()); ObjCMethodDecl& MD = cast<ObjCMethodDecl>(BRC.getCodeDecl());
os << " and returned from method '" << MD.getSelector().getAsString() os << " and returned from method '" << MD.getSelector().getAsString()
<< "' is potentially leaked when using garbage collection. Callers" << "' is potentially leaked when using garbage collection. Callers "
" of this method do not expect a +1 retain count since the return" "of this method do not expect a returned object with a +1 retain "
" type is an Objective-C object reference"; "count since they expect the object to be managed by the garbage "
"collector";
} }
else else
os << " is no longer referenced after this point and has a retain count of" os << " is no longer referenced after this point and has a retain count of"
@ -3073,11 +3074,12 @@ void CFRefCount::EvalReturn(ExplodedNodeSet<GRState>& Dst,
if (isGCEnabled() && RE.getObjKind() == RetEffect::ObjC) { if (isGCEnabled() && RE.getObjKind() == RetEffect::ObjC) {
// Things are more complicated with garbage collection. If the // Things are more complicated with garbage collection. If the
// returned object is suppose to be an Objective-C object, we have // returned object is suppose to be an Objective-C object, we have
// a leak (as the caller expects a GC'ed object). // 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; X = X ^ RefVal::ErrorGCLeakReturned;
// Keep this false until this is properly tested. // Keep this false until this is properly tested.
hasError = false; hasError = true;
} }
else if (!RE.isOwned()) { else if (!RE.isOwned()) {
// Either we are using GC and the returned object is a CF type // Either we are using GC and the returned object is a CF type

View File

@ -128,13 +128,17 @@ void f3() {
// is expected. // is expected.
@interface TestReturnNotOwnedWhenExpectedOwned @interface TestReturnNotOwnedWhenExpectedOwned
- (NSString*)newString; - (NSString*)newString;
- (CFMutableArrayRef)newArray;
@end @end
@implementation TestReturnNotOwnedWhenExpectedOwned @implementation TestReturnNotOwnedWhenExpectedOwned
- (NSString*)newString { - (NSString*)newString {
NSString *s = [NSString stringWithUTF8String:"hello"]; NSString *s = [NSString stringWithUTF8String:"hello"]; // expected-warning{{Potential leak (when using garbage collection) of an object allocated on line 136 and stored into 's'}}
// FIXME: Should this be an error anyway? CFRetain(s);
return s; // no-warning return s;
}
- (CFMutableArrayRef)newArray{
return CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks); // no-warning
} }
@end @end