mirror of
https://github.com/Gericom/teak-llvm.git
synced 2025-06-25 06:18:56 -04:00

Previously, MallocChecker's pointer escape check and its post-call state update for Objective-C method calls had a fair amount duplicated logic and not-entirely-consistent checks. This commit restructures all this to be more consistent and possibly allow us to be more aggressive in warning about double-frees. New policy (applies to system header methods only): (1) If this is a method we know about, model it as taking/holding ownership of the passed-in buffer. (1a) ...unless there's a "freeWhenDone:" parameter with a zero (NO) value. (2) If there's a "freeWhenDone:" parameter (but it's not a method we know about), treat the buffer as escaping if the value is non-zero (YES) and non-escaping if it's zero (NO). (3) If the first selector piece ends with "NoCopy" (but it's not a method we know about and there's no "freeWhenDone:" parameter), treat the buffer as escaping. The reason that (2) and (3) don't explicitly model the ownership transfer is because we can't be sure that they will actually free the memory using free(), and we wouldn't want to emit a spurious "mismatched allocator" warning (coming in Anton's upcoming patch). In the future, we may have an idea of a "generic deallocation", i.e. we assume that the deallocator is correct but still continue tracking the region so that we can warn about double-frees. Patch by Anton Yartsev, with modifications from me. llvm-svn: 176744
35 lines
1.0 KiB
Objective-C
35 lines
1.0 KiB
Objective-C
// Like the compiler, the static analyzer treats some functions differently if
|
|
// they come from a system header -- for example, it is assumed that system
|
|
// functions do not arbitrarily free() their parameters, and that some bugs
|
|
// found in system headers cannot be fixed by the user and should be
|
|
// suppressed.
|
|
#pragma clang system_header
|
|
|
|
typedef __typeof(sizeof(int)) size_t;
|
|
void *malloc(size_t);
|
|
void *calloc(size_t, size_t);
|
|
void free(void *);
|
|
|
|
|
|
#if __OBJC__
|
|
|
|
#import "system-header-simulator-objc.h"
|
|
|
|
@interface Wrapper : NSData
|
|
- (id)initWithBytesNoCopy:(void *)bytes length:(NSUInteger)len;
|
|
@end
|
|
|
|
@implementation Wrapper
|
|
- (id)initWithBytesNoCopy:(void *)bytes length:(NSUInteger)len {
|
|
return [self initWithBytesNoCopy:bytes length:len freeWhenDone:1]; // no-warning
|
|
}
|
|
@end
|
|
|
|
@interface CustomData : NSData
|
|
+ (id)somethingNoCopy:(char *)bytes;
|
|
+ (id)somethingNoCopy:(void *)bytes length:(NSUInteger)length freeWhenDone:(BOOL)freeBuffer;
|
|
+ (id)something:(char *)bytes freeWhenDone:(BOOL)freeBuffer;
|
|
@end
|
|
|
|
#endif
|