1*67e74705SXin Li // RUN: %clang_cc1 -analyze -analyzer-checker=core,unix.Malloc,unix.MismatchedDeallocator,cplusplus.NewDelete -std=c++11 -verify %s
2*67e74705SXin Li // RUN: %clang_cc1 -analyze -analyzer-checker=core,unix.Malloc,unix.MismatchedDeallocator,cplusplus.NewDelete,cplusplus.NewDeleteLeaks -DLEAKS -std=c++11 -verify %s
3*67e74705SXin Li
4*67e74705SXin Li #include "Inputs/system-header-simulator-for-malloc.h"
5*67e74705SXin Li
6*67e74705SXin Li //--------------------------------------------------
7*67e74705SXin Li // Check that unix.Malloc catches all types of bugs.
8*67e74705SXin Li //--------------------------------------------------
testMallocDoubleFree()9*67e74705SXin Li void testMallocDoubleFree() {
10*67e74705SXin Li int *p = (int *)malloc(sizeof(int));
11*67e74705SXin Li free(p);
12*67e74705SXin Li free(p); // expected-warning{{Attempt to free released memory}}
13*67e74705SXin Li }
14*67e74705SXin Li
testMallocLeak()15*67e74705SXin Li void testMallocLeak() {
16*67e74705SXin Li int *p = (int *)malloc(sizeof(int));
17*67e74705SXin Li } // expected-warning{{Potential leak of memory pointed to by 'p'}}
18*67e74705SXin Li
testMallocUseAfterFree()19*67e74705SXin Li void testMallocUseAfterFree() {
20*67e74705SXin Li int *p = (int *)malloc(sizeof(int));
21*67e74705SXin Li free(p);
22*67e74705SXin Li int j = *p; // expected-warning{{Use of memory after it is freed}}
23*67e74705SXin Li }
24*67e74705SXin Li
testMallocBadFree()25*67e74705SXin Li void testMallocBadFree() {
26*67e74705SXin Li int i;
27*67e74705SXin Li free(&i); // expected-warning{{Argument to free() is the address of the local variable 'i', which is not memory allocated by malloc()}}
28*67e74705SXin Li }
29*67e74705SXin Li
testMallocOffsetFree()30*67e74705SXin Li void testMallocOffsetFree() {
31*67e74705SXin Li int *p = (int *)malloc(sizeof(int));
32*67e74705SXin Li free(++p); // expected-warning{{Argument to free() is offset by 4 bytes from the start of memory allocated by malloc()}}
33*67e74705SXin Li }
34*67e74705SXin Li
35*67e74705SXin Li //-----------------------------------------------------------------
36*67e74705SXin Li // Check that unix.MismatchedDeallocator catches all types of bugs.
37*67e74705SXin Li //-----------------------------------------------------------------
testMismatchedDeallocator()38*67e74705SXin Li void testMismatchedDeallocator() {
39*67e74705SXin Li int *x = (int *)malloc(sizeof(int));
40*67e74705SXin Li delete x; // expected-warning{{Memory allocated by malloc() should be deallocated by free(), not 'delete'}}
41*67e74705SXin Li }
42*67e74705SXin Li
43*67e74705SXin Li //----------------------------------------------------------------
44*67e74705SXin Li // Check that alpha.cplusplus.NewDelete catches all types of bugs.
45*67e74705SXin Li //----------------------------------------------------------------
testNewDoubleFree()46*67e74705SXin Li void testNewDoubleFree() {
47*67e74705SXin Li int *p = new int;
48*67e74705SXin Li delete p;
49*67e74705SXin Li delete p; // expected-warning{{Attempt to free released memory}}
50*67e74705SXin Li }
51*67e74705SXin Li
testNewLeak()52*67e74705SXin Li void testNewLeak() {
53*67e74705SXin Li int *p = new int;
54*67e74705SXin Li }
55*67e74705SXin Li #ifdef LEAKS
56*67e74705SXin Li // expected-warning@-2 {{Potential leak of memory pointed to by 'p'}}
57*67e74705SXin Li #endif
58*67e74705SXin Li
testNewUseAfterFree()59*67e74705SXin Li void testNewUseAfterFree() {
60*67e74705SXin Li int *p = (int *)operator new(0);
61*67e74705SXin Li delete p;
62*67e74705SXin Li int j = *p; // expected-warning{{Use of memory after it is freed}}
63*67e74705SXin Li }
64*67e74705SXin Li
testNewBadFree()65*67e74705SXin Li void testNewBadFree() {
66*67e74705SXin Li int i;
67*67e74705SXin Li delete &i; // expected-warning{{Argument to 'delete' is the address of the local variable 'i', which is not memory allocated by 'new'}}
68*67e74705SXin Li }
69*67e74705SXin Li
testNewOffsetFree()70*67e74705SXin Li void testNewOffsetFree() {
71*67e74705SXin Li int *p = new int;
72*67e74705SXin Li operator delete(++p); // expected-warning{{Argument to operator delete is offset by 4 bytes from the start of memory allocated by 'new'}}
73*67e74705SXin Li }
74*67e74705SXin Li
75*67e74705SXin Li //----------------------------------------------------------------
76*67e74705SXin Li // Test that we check for free errors on escaped pointers.
77*67e74705SXin Li //----------------------------------------------------------------
78*67e74705SXin Li void changePtr(int **p);
79*67e74705SXin Li static int *globalPtr;
80*67e74705SXin Li void changePointee(int *p);
81*67e74705SXin Li
testMismatchedChangePtrThroughCall()82*67e74705SXin Li void testMismatchedChangePtrThroughCall() {
83*67e74705SXin Li int *p = (int*)malloc(sizeof(int)*4);
84*67e74705SXin Li changePtr(&p);
85*67e74705SXin Li delete p; // no-warning the value of the pointer might have changed
86*67e74705SXin Li }
87*67e74705SXin Li
testMismatchedChangePointeeThroughCall()88*67e74705SXin Li void testMismatchedChangePointeeThroughCall() {
89*67e74705SXin Li int *p = (int*)malloc(sizeof(int)*4);
90*67e74705SXin Li changePointee(p);
91*67e74705SXin Li delete p; // expected-warning{{Memory allocated by malloc() should be deallocated by free(), not 'delete'}}
92*67e74705SXin Li }
93*67e74705SXin Li
testShouldReportDoubleFreeNotMismatched()94*67e74705SXin Li void testShouldReportDoubleFreeNotMismatched() {
95*67e74705SXin Li int *p = (int*)malloc(sizeof(int)*4);
96*67e74705SXin Li globalPtr = p;
97*67e74705SXin Li free(p);
98*67e74705SXin Li delete globalPtr; // expected-warning {{Attempt to free released memory}}
99*67e74705SXin Li }
allocIntArray(unsigned c)100*67e74705SXin Li int *allocIntArray(unsigned c) {
101*67e74705SXin Li return new int[c];
102*67e74705SXin Li }
testMismatchedChangePointeeThroughAssignment()103*67e74705SXin Li void testMismatchedChangePointeeThroughAssignment() {
104*67e74705SXin Li int *arr = allocIntArray(4);
105*67e74705SXin Li globalPtr = arr;
106*67e74705SXin Li delete arr; // expected-warning{{Memory allocated by 'new[]' should be deallocated by 'delete[]', not 'delete'}}
107*67e74705SXin Li }
108