1 // RUN: %clang_cc1 -analyze -analyzer-checker=core,unix.Malloc,unix.MismatchedDeallocator,cplusplus.NewDelete -std=c++11 -verify %s
2 // RUN: %clang_cc1 -analyze -analyzer-checker=core,unix.Malloc,unix.MismatchedDeallocator,cplusplus.NewDelete,alpha.cplusplus.NewDeleteLeaks -DLEAKS -std=c++11 -verify %s
4 #include "Inputs/system-header-simulator-for-malloc.h"
6 //--------------------------------------------------
7 // Check that unix.Malloc catches all types of bugs.
8 //--------------------------------------------------
9 void testMallocDoubleFree() {
10 int *p = (int *)malloc(sizeof(int));
12 free(p); // expected-warning{{Attempt to free released memory}}
15 void testMallocLeak() {
16 int *p = (int *)malloc(sizeof(int));
17 } // expected-warning{{Potential leak of memory pointed to by 'p'}}
19 void testMallocUseAfterFree() {
20 int *p = (int *)malloc(sizeof(int));
22 int j = *p; // expected-warning{{Use of memory after it is freed}}
25 void testMallocBadFree() {
27 free(&i); // expected-warning{{Argument to free() is the address of the local variable 'i', which is not memory allocated by malloc()}}
30 void testMallocOffsetFree() {
31 int *p = (int *)malloc(sizeof(int));
32 free(++p); // expected-warning{{Argument to free() is offset by 4 bytes from the start of memory allocated by malloc()}}
35 //-----------------------------------------------------------------
36 // Check that unix.MismatchedDeallocator catches all types of bugs.
37 //-----------------------------------------------------------------
38 void testMismatchedDeallocator() {
39 int *x = (int *)malloc(sizeof(int));
40 delete x; // expected-warning{{Memory allocated by malloc() should be deallocated by free(), not 'delete'}}
43 //----------------------------------------------------------------
44 // Check that alpha.cplusplus.NewDelete catches all types of bugs.
45 //----------------------------------------------------------------
46 void testNewDoubleFree() {
49 delete p; // expected-warning{{Attempt to free released memory}}
56 // expected-warning@-2 {{Potential leak of memory pointed to by 'p'}}
59 void testNewUseAfterFree() {
60 int *p = (int *)operator new(0);
62 int j = *p; // expected-warning{{Use of memory after it is freed}}
65 void testNewBadFree() {
67 delete &i; // expected-warning{{Argument to 'delete' is the address of the local variable 'i', which is not memory allocated by 'new'}}
70 void testNewOffsetFree() {
72 operator delete(++p); // expected-warning{{Argument to operator delete is offset by 4 bytes from the start of memory allocated by 'new'}}
75 //----------------------------------------------------------------
76 // Test that we check for free errors on escaped pointers.
77 //----------------------------------------------------------------
78 void changePtr(int **p);
79 static int *globalPtr;
80 void changePointee(int *p);
82 void testMismatchedChangePtrThroughCall() {
83 int *p = (int*)malloc(sizeof(int)*4);
85 delete p; // no-warning the value of the pointer might have changed
88 void testMismatchedChangePointeeThroughCall() {
89 int *p = (int*)malloc(sizeof(int)*4);
91 delete p; // expected-warning{{Memory allocated by malloc() should be deallocated by free(), not 'delete'}}
94 void testShouldReportDoubleFreeNotMismatched() {
95 int *p = (int*)malloc(sizeof(int)*4);
98 delete globalPtr; // expected-warning {{Attempt to free released memory}}
101 void testMismatchedChangePointeeThroughAssignment() {
102 int *arr = new int[4];
104 delete arr; // expected-warning{{Memory allocated by 'new[]' should be deallocated by 'delete[]', not 'delete'}}