From c7bb84decbe7190a1409351b7817f97829b0c814 Mon Sep 17 00:00:00 2001 From: rfm Date: Sat, 12 Feb 2011 06:51:42 +0000 Subject: [PATCH] Attempts to prevent leak warnings from static analyser git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@32090 72102866-910b-0410-8b05-ffd578937521 --- ChangeLog | 12 ++++++++++++ Source/Additions/NSObject+GNUstepBase.m | 5 +++++ Source/GSPrivate.h | 7 +++++++ Source/NSLocale.m | 11 ++++++++--- Source/NSNotificationCenter.m | 10 ++++++++++ Source/NSPortCoder.m | 21 +++++++++++++++++++++ Source/NSSerializer.m | 20 ++++++++++++++++++++ Source/NSThread.m | 12 ++++++++++++ Source/NSUserDefaults.m | 5 +++-- 9 files changed, 98 insertions(+), 5 deletions(-) diff --git a/ChangeLog b/ChangeLog index 605079d01..674c35e6d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,15 @@ +2011-02-12 Richard Frith-Macdonald + + * Source/NSLocale.m: fix memory leak + * Source/NSThread.m: + * Source/NSNotificationCenter.m: + * Source/NSPortCoder.m: + * Source/NSSerializer.m: + * Source/NSUserDefaults.m: + * Source/GSPrivate.h: + * Source/Additions/NSObject+GNUstepBase.m: + Add code to try to prevent clang static analyser false warnings. + 2011-02-12 Richard Frith-Macdonald * Source/GSPrivate.h: diff --git a/Source/Additions/NSObject+GNUstepBase.m b/Source/Additions/NSObject+GNUstepBase.m index 46da2321a..7a799dfad 100644 --- a/Source/Additions/NSObject+GNUstepBase.m +++ b/Source/Additions/NSObject+GNUstepBase.m @@ -122,3 +122,8 @@ @end +#ifdef __clang__ +#import "GSPrivate.h" +id gsPrivateDummy; +#endif + diff --git a/Source/GSPrivate.h b/Source/GSPrivate.h index bfc72a41c..b3f259c26 100644 --- a/Source/GSPrivate.h +++ b/Source/GSPrivate.h @@ -543,5 +543,12 @@ GSPrivateIsCollectable(const void *ptr) GS_ATTRIB_PRIVATE; NSZone* GSAtomicMallocZone (void); +/* A global location to which we can assign objects in order to prevent + * the clang static analyser thinking we have leaked them when we haven't + */ +#ifdef __clang__ +extern id gsPrivateDummy GS_ATTRIB_PRIVATE; +#endif + #endif /* _GSPrivate_h_ */ diff --git a/Source/NSLocale.m b/Source/NSLocale.m index fd3dcc40a..32d01e674 100644 --- a/Source/NSLocale.m +++ b/Source/NSLocale.m @@ -135,13 +135,17 @@ static NSLocaleLanguageDirection _ICUToNSLocaleOrientation (ULayoutType layout) static NSArray *_currencyCodesWithType (uint32_t currType) { NSArray *result; - NSMutableArray *currencies = [[NSMutableArray alloc] initWithCapacity: 10]; + NSMutableArray *currencies; UErrorCode err = U_ZERO_ERROR; const char *currCode; - UEnumeration *codes = ucurr_openISOCurrencies (currType, &err); + UEnumeration *codes; + + codes = ucurr_openISOCurrencies (currType, &err); if (U_FAILURE(err)) return nil; + currencies = [[NSMutableArray alloc] initWithCapacity: 10]; + do { int strLength; @@ -151,6 +155,7 @@ static NSArray *_currencyCodesWithType (uint32_t currType) if (U_FAILURE(err)) { uenum_close (codes); + [currencies release]; return nil; } if (currCode == NULL) @@ -160,7 +165,7 @@ static NSArray *_currencyCodesWithType (uint32_t currType) uenum_close (codes); result = [NSArray arrayWithArray: currencies]; - RELEASE (currencies); + [currencies release]; return result; } #endif diff --git a/Source/NSNotificationCenter.m b/Source/NSNotificationCenter.m index a529ada70..0f4412194 100644 --- a/Source/NSNotificationCenter.m +++ b/Source/NSNotificationCenter.m @@ -790,6 +790,16 @@ static NSNotificationCenter *default_center = nil; */ name = [name copyWithZone: NSDefaultMallocZone()]; GSIMapAddPair(NAMED, (GSIMapKey)(id)name, (GSIMapVal)(void*)m); +#ifdef __clang__ +{ + /* We store the object in 'dummy' for no other purpose than to silence + * the clang static analyser's warning that we are leaking memory, which + * occurs because it doesn't realise that the object was already stored + * later deallocation. + */ + gsPrivateDummy = name; +} +#endif } else { diff --git a/Source/NSPortCoder.m b/Source/NSPortCoder.m index ffa900cac..a5cddfd20 100644 --- a/Source/NSPortCoder.m +++ b/Source/NSPortCoder.m @@ -616,6 +616,17 @@ static IMP _xRefImp; /* Serialize a crossref. */ obj = rep; GSIArraySetItemAtIndex(_objAry, (GSIArrayItem)obj, xref); } +#ifdef __clang__ +{ + /* We store the object in 'dummy' for no other purpose than to silence + * the clang static analyser's warning that we are leaking memory, which + * occurs because it doesn't realise that the object was already stored + * later deallocation. + */ + gsPrivateDummy = rep; +} +#endif + } } *(id*)address = obj; @@ -723,6 +734,16 @@ static IMP _xRefImp; /* Serialize a crossref. */ */ address = &dummy; (*_dTagImp)(_src, dTagSel, &info, &xref, &_cursor); +#ifdef __clang__ +{ + /* We store the object in 'dummy' for no other purpose than to silence + * the clang static analyser's warning that we are leaking memory, which + * occurs because it doesn't realise that the object was already stored + * later deallocation. + */ + gsPrivateDummy = classInfo; +} +#endif } if (info != _GSC_NONE) { diff --git a/Source/NSSerializer.m b/Source/NSSerializer.m index 1dce86a79..b86d1d5b8 100644 --- a/Source/NSSerializer.m +++ b/Source/NSSerializer.m @@ -577,6 +577,16 @@ deserializeFromInfo(_NSDeserializerInfo* info) { GSIArrayAddItem(&info->array, (GSIArrayItem)((id)s)); } +#ifdef __clang__ +{ + /* We store the object in 'dummy' for no other purpose than to silence + * the clang static analyser's warning that we are leaking memory, which + * occurs because it doesn't realise that the object was already stored + * later deallocation. + */ + gsPrivateDummy = s; +} +#endif return s; } @@ -613,6 +623,16 @@ deserializeFromInfo(_NSDeserializerInfo* info) { GSIArrayAddItem(&info->array, (GSIArrayItem)((id)s)); } +#ifdef __clang__ +{ + /* We store the object in 'dummy' for no other purpose than to silence + * the clang static analyser's warning that we are leaking memory, which + * occurs because it doesn't realise that the object was already stored + * later deallocation. + */ + gsPrivateDummy = rep; +} +#endif return s; } diff --git a/Source/NSThread.m b/Source/NSThread.m index ba9a8eebc..8f82fce07 100644 --- a/Source/NSThread.m +++ b/Source/NSThread.m @@ -460,6 +460,18 @@ unregisterActiveThread(NSThread *thread) t = [self new]; t->_active = YES; pthread_setspecific(thread_object_key, t); + +#ifdef __clang__ +{ + /* We store the thread in 'dummy' for no other purpose than to silence + * the clang static analyser's warning that we are leaking memory, which + * occurs because it doesn't realise that pthread_setspecific() stores + * the thread for later deallocation. + */ + gsPrivateDummy = t; +} +#endif + return YES; } return NO; diff --git a/Source/NSUserDefaults.m b/Source/NSUserDefaults.m index a513d3492..b22f3c43f 100644 --- a/Source/NSUserDefaults.m +++ b/Source/NSUserDefaults.m @@ -1925,7 +1925,7 @@ NSLog(@"Creating empty user defaults database"); enumerator = [_searchList reverseObjectEnumerator]; nImp = [enumerator methodForSelector: nextObjectSel]; - dictRep = [NSMutableDictionaryClass allocWithZone: NSDefaultMallocZone()]; + dictRep = [NSMutableDictionaryClass alloc]; dictRep = [dictRep initWithCapacity: 512]; addImp = [dictRep methodForSelector: addSel]; @@ -1937,7 +1937,8 @@ NSLog(@"Creating empty user defaults database"); (*addImp)(dictRep, addSel, dict); } } - _dictionaryRep = [dictRep makeImmutableCopyOnFail: NO]; + [dictRep makeImmutableCopyOnFail: NO]; + _dictionaryRep = dictRep; } rep = [[_dictionaryRep retain] autorelease]; [_lock unlock];