summaryrefslogtreecommitdiffstats
path: root/clang/test/Analysis/malloc.c
diff options
context:
space:
mode:
authorAnna Zaks <ganna@apple.com>2013-02-07 23:05:47 +0000
committerAnna Zaks <ganna@apple.com>2013-02-07 23:05:47 +0000
commitc89ad07d39a435a4069f890417747487f4b3abbf (patch)
tree802d570dd3c71cb8526b933cdeca91435b61c515 /clang/test/Analysis/malloc.c
parentacdc13cb00591e2ab2b168c7924d7eb57fa4808e (diff)
downloadbcm5719-llvm-c89ad07d39a435a4069f890417747487f4b3abbf.tar.gz
bcm5719-llvm-c89ad07d39a435a4069f890417747487f4b3abbf.zip
[analyzer] Report bugs when freeing memory with offset pointer
The malloc checker will now catch the case when a previously malloc'ed region is freed, but the pointer passed to free does not point to the start of the allocated memory. For example: int *p1 = malloc(sizeof(int)); p1++; free(p1); // warn From the "memory.LeakPtrValChanged enhancement to unix.Malloc" entry in the list of potential checkers. A patch by Branden Archer! llvm-svn: 174678
Diffstat (limited to 'clang/test/Analysis/malloc.c')
-rw-r--r--clang/test/Analysis/malloc.c100
1 files changed, 100 insertions, 0 deletions
diff --git a/clang/test/Analysis/malloc.c b/clang/test/Analysis/malloc.c
index 9dc17e630fc..29f5aa69ca5 100644
--- a/clang/test/Analysis/malloc.c
+++ b/clang/test/Analysis/malloc.c
@@ -1090,4 +1090,104 @@ void testPassToSystemHeaderFunctionIndirectlyStruct() {
fakeSystemHeaderCall(&ss);
} // missing leak
+int *testOffsetAllocate(size_t size) {
+ int *memoryBlock = (int *)malloc(size + sizeof(int));
+ return &memoryBlock[1]; // no-warning
+}
+
+void testOffsetDeallocate(int *memoryBlock) {
+ free(&memoryBlock[-1]); // no-warning
+}
+
+void testOffsetOfRegionFreed() {
+ __int64_t * array = malloc(sizeof(__int64_t)*2);
+ array += 1;
+ free(&array[0]); // expected-warning{{Argument to free() is offset by 8 bytes from the start of memory allocated by malloc()}}
+}
+
+void testOffsetOfRegionFreed2() {
+ __int64_t *p = malloc(sizeof(__int64_t)*2);
+ p += 1;
+ free(p); // expected-warning{{Argument to free() is offset by 8 bytes from the start of memory allocated by malloc()}}
+}
+
+void testOffsetOfRegionFreed3() {
+ char *r = malloc(sizeof(char));
+ r = r - 10;
+ free(r); // expected-warning {{Argument to free() is offset by -10 bytes from the start of memory allocated by malloc()}}
+}
+
+void testOffsetOfRegionFreedAfterFunctionCall() {
+ int *p = malloc(sizeof(int)*2);
+ p += 1;
+ myfoo(p);
+ free(p); // no-warning
+}
+
+void testFixManipulatedPointerBeforeFree() {
+ int * array = malloc(sizeof(int)*2);
+ array += 1;
+ free(&array[-1]); // no-warning
+}
+
+void testFixManipulatedPointerBeforeFree2() {
+ char *r = malloc(sizeof(char));
+ r = r + 10;
+ free(r-10); // no-warning
+}
+
+void freeOffsetPointerPassedToFunction() {
+ __int64_t *p = malloc(sizeof(__int64_t)*2);
+ p[1] = 0;
+ p += 1;
+ myfooint(*p); // not passing the pointer, only a value pointed by pointer
+ free(p); // expected-warning {{Argument to free() is offset by 8 bytes from the start of memory allocated by malloc()}}
+}
+
+int arbitraryInt();
+void freeUnknownOffsetPointer() {
+ char *r = malloc(sizeof(char));
+ r = r + arbitraryInt(); // unable to reason about what the offset might be
+ free(r); // no-warning
+}
+
+void testFreeNonMallocPointerWithNoOffset() {
+ char c;
+ char *r = &c;
+ r = r + 10;
+ free(r-10); // expected-warning {{Argument to free() is the address of the local variable 'c', which is not memory allocated by malloc()}}
+}
+
+void testFreeNonMallocPointerWithOffset() {
+ char c;
+ char *r = &c;
+ free(r+1); // expected-warning {{Argument to free() is the address of the local variable 'c', which is not memory allocated by malloc()}}
+}
+
+void testOffsetZeroDoubleFree() {
+ int *array = malloc(sizeof(int)*2);
+ int *p = &array[0];
+ free(p);
+ free(&array[0]); // expected-warning{{Attempt to free released memory}}
+}
+
+void testOffsetPassedToStrlen() {
+ char * string = malloc(sizeof(char)*10);
+ string += 1;
+ int length = strlen(string); // expected-warning {{Memory is never released; potential leak of memory pointed to by 'string'}}
+}
+
+void testOffsetPassedToStrlenThenFree() {
+ char * string = malloc(sizeof(char)*10);
+ string += 1;
+ int length = strlen(string);
+ free(string); // expected-warning {{Argument to free() is offset by 1 byte from the start of memory allocated by malloc()}}
+}
+
+void testOffsetPassedAsConst() {
+ char * string = malloc(sizeof(char)*10);
+ string += 1;
+ passConstPtr(string);
+ free(string); // expected-warning {{Argument to free() is offset by 1 byte from the start of memory allocated by malloc()}}
+}
OpenPOWER on IntegriCloud