summaryrefslogtreecommitdiffstats
path: root/docs/analyzer/checkers
diff options
context:
space:
mode:
Diffstat (limited to 'docs/analyzer/checkers')
-rw-r--r--docs/analyzer/checkers/callandmessage_example.c66
-rw-r--r--docs/analyzer/checkers/dealloc_example.m49
-rw-r--r--docs/analyzer/checkers/dividezero_example.c9
-rw-r--r--docs/analyzer/checkers/mismatched_deallocator_example.cpp56
-rw-r--r--docs/analyzer/checkers/newdelete_example.cpp41
-rw-r--r--docs/analyzer/checkers/seckeychainapi_example.m64
-rw-r--r--docs/analyzer/checkers/unix_api_example.c37
-rw-r--r--docs/analyzer/checkers/unix_malloc_example.c30
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
+}
+