1 // RUN: %clang_analyze_cc1 -analyzer-checker=core,unix.Malloc,unix.MismatchedDeallocator,cplusplus.NewDelete -std=c++11 -verify %s
2 // RUN: %clang_analyze_cc1 -analyzer-checker=core,unix.Malloc,unix.MismatchedDeallocator,cplusplus.NewDelete,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}}
100 int *allocIntArray(unsigned c
) {
103 void testMismatchedChangePointeeThroughAssignment() {
104 int *arr
= allocIntArray(4);
106 delete arr
; // expected-warning{{Memory allocated by 'new[]' should be deallocated by 'delete[]', not 'delete'}}