Malloc+MismatchedDeallocator+NewDelete.cpp revision 648cb71625a2ab3164b2cacac9e9cb3d22b03bd7
1// RUN: %clang_cc1 -analyze -analyzer-checker=core,unix.Malloc,unix.MismatchedDeallocator,alpha.cplusplus.NewDelete -analyzer-store region -std=c++11 -verify %s
2
3typedef __typeof(sizeof(int)) size_t;
4void *malloc(size_t);
5void free(void *);
6
7//--------------------------------------------------
8// Check that unix.Malloc catches all types of bugs.
9//--------------------------------------------------
10void testMallocDoubleFree() {
11  int *p = (int *)malloc(sizeof(int));
12  free(p);
13  free(p); // expected-warning{{Attempt to free released memory}}
14}
15
16void testMallocLeak() {
17  int *p = (int *)malloc(sizeof(int));
18} // expected-warning{{Memory is never released; potential leak of memory pointed to by 'p'}}
19
20void testMallocUseAfterFree() {
21  int *p = (int *)malloc(sizeof(int));
22  free(p);
23  int j = *p; // expected-warning{{Use of memory after it is freed}}
24}
25
26void testMallocBadFree() {
27  int i;
28  free(&i); // expected-warning{{Argument to free() is the address of the local variable 'i', which is not memory allocated by malloc()}}
29}
30
31void testMallocOffsetFree() {
32  int *p = (int *)malloc(sizeof(int));
33  free(++p); // expected-warning{{Argument to free() is offset by 4 bytes from the start of memory allocated by malloc()}}
34}
35
36//-----------------------------------------------------------------
37// Check that unix.MismatchedDeallocator catches all types of bugs.
38//-----------------------------------------------------------------
39void testMismatchedDeallocator() {
40  int *x = (int *)malloc(sizeof(int));
41  delete x; // expected-warning{{Memory allocated by malloc() should be deallocated by free(), not 'delete'}}
42}
43
44//----------------------------------------------------------------
45// Check that alpha.cplusplus.NewDelete catches all types of bugs.
46//----------------------------------------------------------------
47void testNewDoubleFree() {
48  int *p = new int;
49  delete p;
50  delete p; // expected-warning{{Attempt to free released memory}}
51}
52
53void testNewLeak() {
54  int *p = new int;
55} // expected-warning{{Memory is never released; potential leak of memory pointed to by 'p'}}
56
57void testNewUseAfterFree() {
58  int *p = (int *)operator new(0);
59  delete p;
60  int j = *p; // expected-warning{{Use of memory after it is freed}}
61}
62
63void testNewBadFree() {
64  int i;
65  delete &i; // expected-warning{{Argument to 'delete' is the address of the local variable 'i', which is not memory allocated by 'new'}}
66}
67
68void testNewOffsetFree() {
69  int *p = new int;
70  operator delete(++p); // expected-warning{{Argument to operator delete is offset by 4 bytes from the start of memory allocated by 'new'}}
71}
72