blob: 417e9770b84daf649fa5cc1295e45b098bd5cccd [file] [log] [blame]
Anton Yartsev2de19ed2013-03-25 01:35:45 +00001// RUN: %clang_cc1 -analyze -analyzer-checker=core,cplusplus.NewDelete -analyzer-store region -std=c++11 -fblocks -verify %s
2#include "Inputs/system-header-simulator-cxx.h"
3#include "Inputs/system-header-simulator-objc.h"
4
5typedef __typeof__(sizeof(int)) size_t;
6extern "C" void *malloc(size_t);
7extern "C" void free(void *);
8int *global;
9
10//------------------
11// check for leaks
12//------------------
13
14void testGlobalExprNewBeforeOverload1() {
15 int *p = new int;
16} // expected-warning{{Memory is never released; potential leak}}
17
18void testGlobalExprNewBeforeOverload2() {
19 int *p = ::new int;
20} // expected-warning{{Memory is never released; potential leak}}
21
22void testGlobalOpNewBeforeOverload() {
23 void *p = operator new(0);
24} // expected-warning{{Memory is never released; potential leak}}
25
26void testMemIsOnHeap() {
27 int *p = new int;
28 if (global != p)
29 global = p;
30} // expected-warning{{Memory is never released; potential leak}}
31//FIXME: currently a memory region for 'new' is not a heap region, that lead to
32//false-positive 'memory leak' ('global != p' is not evaluated to true and 'p'
33//does not escape)
34
35void *operator new(std::size_t);
36void *operator new(std::size_t, double d);
37void *operator new[](std::size_t);
38void *operator new[](std::size_t, double d);
39
40void testExprPlacementNew() {
41 int i;
42 int *p1 = new(&i) int; // no warn - standard placement new
43
44 int *p2 = new(1.0) int; // no warn - overloaded placement new
45
46 int *p3 = new (std::nothrow) int;
47} // expected-warning{{Memory is never released; potential leak}}
48
49void testExprPlacementNewArray() {
50 int i;
51 int *p1 = new(&i) int[1]; // no warn - standard placement new[]
52
53 int *p2 = new(1.0) int[1]; // no warn - overloaded placement new[]
54
55 int *p3 = new (std::nothrow) int[1];
56} // expected-warning{{Memory is never released; potential leak}}
57
58void testCustomOpNew() {
59 void *p = operator new(0); // no warn - call to a custom new
60}
61
62void testGlobalExprNew() {
63 void *p = ::new int; // no warn - call to a custom new
64}
65
66void testCustomExprNew() {
67 int *p = new int; // no warn - call to a custom new
68}
69
70void testGlobalExprNewArray() {
71 void *p = ::new int[1]; // no warn - call to a custom new
72}
73
74void testOverloadedExprNewArray() {
75 int *p = new int[1]; // no warn - call to a custom new
76}
77
78//---------------
79// other checks
80//---------------
81
82void f(int *);
83
84void testUseAfterDelete() {
85 int *p = new int;
86 delete p;
87 f(p); // expected-warning{{Use of memory after it is freed}}
88}
89
90void testDeleteAlloca() {
91 int *p = (int *)__builtin_alloca(sizeof(int));
92 delete p; // expected-warning{{Argument to free() was allocated by alloca(), not malloc()}}
93}
94
95void testDoubleDelete() {
96 int *p = new int;
97 delete p;
98 delete p; // expected-warning{{Attempt to free released memory}}
99}
100
101void testExprDeleteArg() {
102 int i;
103 delete &i; // expected-warning{{Argument to free() is the address of the local variable 'i', which is not memory allocated by malloc()}}
104} // FIXME: 'free()' -> 'delete'; 'malloc()' -> 'new'
105
106void testExprDeleteArrArg() {
107 int i;
108 delete[] &i; // expected-warning{{Argument to free() is the address of the local variable 'i', which is not memory allocated by malloc()}}
109} // FIXME: 'free()' -> 'delete[]'; 'malloc()' -> 'new[]'
110
111void testAllocDeallocNames() {
112 int *p = new(std::nothrow) int[1];
113 delete[] (++p); // expected-warning{{Argument to free() is offset by 4 bytes from the start of memory allocated by malloc()}}
114} // FIXME: 'free()' -> 'delete[]'; 'malloc()' -> 'new[]'
115
116//----------------------------------------------------------------------------
117// Check for intersections with unix.Malloc and unix.MallocWithAnnotations
118// checkers bounded with cplusplus.NewDelete.
119//----------------------------------------------------------------------------
120
121// malloc()/free() are subjects of unix.Malloc and unix.MallocWithAnnotations
122void testMallocFreeNoWarn() {
123 int i;
124 free(&i); // no-warning
125
126 int *p1 = (int *)malloc(sizeof(int));
127 free(++p1); // no-warning
128
129 int *p2 = (int *)malloc(sizeof(int));
130 free(p2);
131 free(p2); // no-warning
132
133 int *p3 = (int *)malloc(sizeof(int)); // no-warning
134}
135
136void testFreeNewed() {
137 int *p = new int;
138 free(p); // pointer escaped, no-warning
139}
140
141void testObjcFreeNewed() {
142 int *p = new int;
143 NSData *nsdata = [NSData dataWithBytesNoCopy:p length:sizeof(int) freeWhenDone:1]; // pointer escaped, no-warning
144}
145
146void testFreeAfterDelete() {
147 int *p = new int;
148 delete p;
149 free(p); // expected-warning{{Use of memory after it is freed}}
150}
151
152void testStandardPlacementNewAfterDelete() {
153 int *p = new int;
154 delete p;
155 p = new(p) int; // expected-warning{{Use of memory after it is freed}}
156}