diff options
Diffstat (limited to 'docs/analyzer/checkers')
-rw-r--r-- | docs/analyzer/checkers/callandmessage_example.c | 66 | ||||
-rw-r--r-- | docs/analyzer/checkers/dealloc_example.m | 49 | ||||
-rw-r--r-- | docs/analyzer/checkers/dividezero_example.c | 9 | ||||
-rw-r--r-- | docs/analyzer/checkers/mismatched_deallocator_example.cpp | 56 | ||||
-rw-r--r-- | docs/analyzer/checkers/newdelete_example.cpp | 41 | ||||
-rw-r--r-- | docs/analyzer/checkers/seckeychainapi_example.m | 64 | ||||
-rw-r--r-- | docs/analyzer/checkers/unix_api_example.c | 37 | ||||
-rw-r--r-- | docs/analyzer/checkers/unix_malloc_example.c | 30 |
8 files changed, 352 insertions, 0 deletions
diff --git a/docs/analyzer/checkers/callandmessage_example.c b/docs/analyzer/checkers/callandmessage_example.c new file mode 100644 index 0000000000..7e14fbe464 --- /dev/null +++ b/docs/analyzer/checkers/callandmessage_example.c @@ -0,0 +1,66 @@ +//C +void test() { + void (*foo)(void); + foo = 0; + foo(); // warn: function pointer is null + } + + // C++ + class C { + public: + void f(); + }; + + void test() { + C *pc; + pc->f(); // warn: object pointer is uninitialized + } + + // C++ + class C { + public: + void f(); + }; + + void test() { + C *pc = 0; + pc->f(); // warn: object pointer is null + } + + // Objective-C + @interface MyClass : NSObject + @property (readwrite,assign) id x; + - (long double)longDoubleM; + @end + + void test() { + MyClass *obj1; + long double ld1 = [obj1 longDoubleM]; + // warn: receiver is uninitialized + } + + // Objective-C + @interface MyClass : NSObject + @property (readwrite,assign) id x; + - (long double)longDoubleM; + @end + + void test() { + MyClass *obj1; + id i = obj1.x; // warn: uninitialized object pointer + } + + // Objective-C + @interface Subscriptable : NSObject + - (id)objectAtIndexedSubscript:(unsigned int)index; + @end + + @interface MyClass : Subscriptable + @property (readwrite,assign) id x; + - (long double)longDoubleM; + @end + + void test() { + MyClass *obj1; + id i = obj1[0]; // warn: uninitialized object pointer + } diff --git a/docs/analyzer/checkers/dealloc_example.m b/docs/analyzer/checkers/dealloc_example.m new file mode 100644 index 0000000000..ac51911aff --- /dev/null +++ b/docs/analyzer/checkers/dealloc_example.m @@ -0,0 +1,49 @@ + + +@interface MyObject : NSObject { + id _myproperty; +} +@end + +@implementation MyObject // warn: lacks 'dealloc' +@end + +@interface MyObject : NSObject {} +@property(assign) id myproperty; +@end + +@implementation MyObject // warn: does not send 'dealloc' to super +- (void)dealloc { + self.myproperty = 0; +} +@end + +@interface MyObject : NSObject { + id _myproperty; +} +@property(retain) id myproperty; +@end + +@implementation MyObject +@synthesize myproperty = _myproperty; + // warn: var was retained but wasn't released +- (void)dealloc { + [super dealloc]; +} +@end + +@interface MyObject : NSObject { + id _myproperty; +} +@property(assign) id myproperty; +@end + +@implementation MyObject +@synthesize myproperty = _myproperty; + // warn: var wasn't retained but was released +- (void)dealloc { + [_myproperty release]; + [super dealloc]; +} +@end + diff --git a/docs/analyzer/checkers/dividezero_example.c b/docs/analyzer/checkers/dividezero_example.c new file mode 100644 index 0000000000..00ffaac491 --- /dev/null +++ b/docs/analyzer/checkers/dividezero_example.c @@ -0,0 +1,9 @@ +void test(int z) { + if (z == 0) + int x = 1 / z; // warn +} + +void test() { + int x = 1; + int y = x % 0; // warn +} diff --git a/docs/analyzer/checkers/mismatched_deallocator_example.cpp b/docs/analyzer/checkers/mismatched_deallocator_example.cpp new file mode 100644 index 0000000000..2a4103240f --- /dev/null +++ b/docs/analyzer/checkers/mismatched_deallocator_example.cpp @@ -0,0 +1,56 @@ +// C, C++ +void test() { + int *p = (int *)malloc(sizeof(int)); + delete p; // warn +} + +// C, C++ +void __attribute((ownership_returns(malloc))) *user_malloc(size_t); + +void test() { + int *p = (int *)user_malloc(sizeof(int)); + delete p; // warn +} + +// C, C++ +void test() { + int *p = new int; + free(p); // warn +} + +// C, C++ +void test() { + int *p = new int[1]; + realloc(p, sizeof(long)); // warn +} + +// C, C++ +template <typename T> +struct SimpleSmartPointer { + T *ptr; + + explicit SimpleSmartPointer(T *p = 0) : ptr(p) {} + ~SimpleSmartPointer() { + delete ptr; // warn + } +}; + +void test() { + SimpleSmartPointer<int> a((int *)malloc(4)); +} + +// C++ +void test() { + int *p = (int *)operator new(0); + delete[] p; // warn +} + +// Objective-C, C++ +void test(NSUInteger dataLength) { + int *p = new int; + NSData *d = [NSData dataWithBytesNoCopy:p + length:sizeof(int) freeWhenDone:1]; + // warn +dataWithBytesNoCopy:length:freeWhenDone: cannot take + // ownership of memory allocated by 'new' +} + diff --git a/docs/analyzer/checkers/newdelete_example.cpp b/docs/analyzer/checkers/newdelete_example.cpp new file mode 100644 index 0000000000..b26ddcb3d9 --- /dev/null +++ b/docs/analyzer/checkers/newdelete_example.cpp @@ -0,0 +1,41 @@ +void f(int *p); + +void testUseMiddleArgAfterDelete(int *p) { + delete p; + f(p); // warn: use after free +} + +class SomeClass { +public: + void f(); +}; + +void test() { + SomeClass *c = new SomeClass; + delete c; + c->f(); // warn: use after free +} + +void test() { + int *p = (int *)__builtin_alloca(sizeof(int)); + delete p; // warn: deleting memory allocated by alloca +} + +void test() { + int *p = new int; + delete p; + delete p; // warn: attempt to free released +} + +void test() { + int i; + delete &i; // warn: delete address of local +} + +void test() { + int *p = new int[1]; + delete[] (++p); + // warn: argument to 'delete[]' is offset by 4 bytes + // from the start of memory allocated by 'new[]' +} + diff --git a/docs/analyzer/checkers/seckeychainapi_example.m b/docs/analyzer/checkers/seckeychainapi_example.m new file mode 100644 index 0000000000..979a5d97c7 --- /dev/null +++ b/docs/analyzer/checkers/seckeychainapi_example.m @@ -0,0 +1,64 @@ + + +void test() { + unsigned int *ptr = 0; + UInt32 length; + + SecKeychainItemFreeContent(ptr, &length); + // warn: trying to free data which has not been allocated +} + +void test() { + unsigned int *ptr = 0; + UInt32 *length = 0; + void *outData; + + OSStatus st = + SecKeychainItemCopyContent(2, ptr, ptr, length, outData); + // warn: data is not released +} + +void test() { + unsigned int *ptr = 0; + UInt32 *length = 0; + void *outData; + + OSStatus st = + SecKeychainItemCopyContent(2, ptr, ptr, length, &outData); + + SecKeychainItemFreeContent(ptr, outData); + // warn: only call free if a non-NULL buffer was returned +} + +void test() { + unsigned int *ptr = 0; + UInt32 *length = 0; + void *outData; + + OSStatus st = + SecKeychainItemCopyContent(2, ptr, ptr, length, &outData); + + st = SecKeychainItemCopyContent(2, ptr, ptr, length, &outData); + // warn: release data before another call to the allocator + + if (st == noErr) + SecKeychainItemFreeContent(ptr, outData); +} + +void test() { + SecKeychainItemRef itemRef = 0; + SecKeychainAttributeInfo *info = 0; + SecItemClass *itemClass = 0; + SecKeychainAttributeList *attrList = 0; + UInt32 *length = 0; + void *outData = 0; + + OSStatus st = + SecKeychainItemCopyAttributesAndData(itemRef, info, + itemClass, &attrList, + length, &outData); + + SecKeychainItemFreeContent(attrList, outData); + // warn: deallocator doesn't match the allocator +} + diff --git a/docs/analyzer/checkers/unix_api_example.c b/docs/analyzer/checkers/unix_api_example.c new file mode 100644 index 0000000000..66ed56fd86 --- /dev/null +++ b/docs/analyzer/checkers/unix_api_example.c @@ -0,0 +1,37 @@ + +// Currently the check is performed for apple targets only. +void test(const char *path) { + int fd = open(path, O_CREAT); + // warn: call to 'open' requires a third argument when the + // 'O_CREAT' flag is set +} + +void f(); + +void test() { + pthread_once_t pred = {0x30B1BCBA, {0}}; + pthread_once(&pred, f); + // warn: call to 'pthread_once' uses the local variable +} + +void test() { + void *p = malloc(0); // warn: allocation size of 0 bytes +} + +void test() { + void *p = calloc(0, 42); // warn: allocation size of 0 bytes +} + +void test() { + void *p = malloc(1); + p = realloc(p, 0); // warn: allocation size of 0 bytes +} + +void test() { + void *p = alloca(0); // warn: allocation size of 0 bytes +} + +void test() { + void *p = valloc(0); // warn: allocation size of 0 bytes +} + diff --git a/docs/analyzer/checkers/unix_malloc_example.c b/docs/analyzer/checkers/unix_malloc_example.c new file mode 100644 index 0000000000..68c5a4a8f1 --- /dev/null +++ b/docs/analyzer/checkers/unix_malloc_example.c @@ -0,0 +1,30 @@ + +void test() { + int *p = malloc(1); + free(p); + free(p); // warn: attempt to free released memory +} + +void test() { + int *p = malloc(sizeof(int)); + free(p); + *p = 1; // warn: use after free +} + +void test() { + int *p = malloc(1); + if (p) + return; // warn: memory is never released +} + +void test() { + int a[] = { 1 }; + free(a); // warn: argument is not allocated by malloc +} + +void test() { + int *p = malloc(sizeof(char)); + p = p - 1; + free(p); // warn: argument to free() is offset by -4 bytes +} + |