blob: 0c69aa10a9cb717366c17ea2c8b3ce6156ff4857 [file] [log] [blame]
Jordan Rosee449edc2013-04-05 17:55:07 +00001// RUN: %clang_cc1 -analyze -analyzer-checker=core,cplusplus.NewDelete -std=c++11 -fblocks -verify %s
2// RUN: %clang_cc1 -analyze -analyzer-checker=core,cplusplus.NewDelete,alpha.cplusplus.NewDeleteLeaks -DLEAKS -std=c++11 -fblocks -verify %s
Anton Yartsev2de19ed2013-03-25 01:35:45 +00003#include "Inputs/system-header-simulator-cxx.h"
Anton Yartsev2de19ed2013-03-25 01:35:45 +00004
5typedef __typeof__(sizeof(int)) size_t;
6extern "C" void *malloc(size_t);
Anton Yartsev2de19ed2013-03-25 01:35:45 +00007int *global;
8
9//------------------
10// check for leaks
11//------------------
12
Anton Yartsev69746282013-03-28 16:10:38 +000013//----- Standard non-placement operators
14void testGlobalOpNew() {
Anton Yartsev2de19ed2013-03-25 01:35:45 +000015 void *p = operator new(0);
Jordan Rosee85deb32013-04-05 17:55:00 +000016}
17#ifdef LEAKS
18// expected-warning@-2{{Memory is never released; potential leak}}
19#endif
Anton Yartsev2de19ed2013-03-25 01:35:45 +000020
Anton Yartsev69746282013-03-28 16:10:38 +000021void testGlobalOpNewArray() {
22 void *p = operator new[](0);
Jordan Rosee85deb32013-04-05 17:55:00 +000023}
24#ifdef LEAKS
25// expected-warning@-2{{Memory is never released; potential leak}}
26#endif
Anton Yartsev69746282013-03-28 16:10:38 +000027
28void testGlobalNewExpr() {
Anton Yartsev2de19ed2013-03-25 01:35:45 +000029 int *p = new int;
Jordan Rosee85deb32013-04-05 17:55:00 +000030}
31#ifdef LEAKS
32// expected-warning@-2{{Memory is never released; potential leak}}
33#endif
Anton Yartsev2de19ed2013-03-25 01:35:45 +000034
Anton Yartsev69746282013-03-28 16:10:38 +000035void testGlobalNewExprArray() {
36 int *p = new int[0];
Jordan Rosee85deb32013-04-05 17:55:00 +000037}
38#ifdef LEAKS
39// expected-warning@-2{{Memory is never released; potential leak}}
40#endif
Anton Yartsev2de19ed2013-03-25 01:35:45 +000041
Anton Yartsev69746282013-03-28 16:10:38 +000042//----- Standard nothrow placement operators
43void testGlobalNoThrowPlacementOpNewBeforeOverload() {
44 void *p = operator new(0, std::nothrow);
Jordan Rosee85deb32013-04-05 17:55:00 +000045}
46#ifdef LEAKS
47// expected-warning@-2{{Memory is never released; potential leak}}
48#endif
Anton Yartsev69746282013-03-28 16:10:38 +000049
50void testGlobalNoThrowPlacementExprNewBeforeOverload() {
51 int *p = new(std::nothrow) int;
Jordan Rosee85deb32013-04-05 17:55:00 +000052}
53#ifdef LEAKS
54// expected-warning@-2{{Memory is never released; potential leak}}
55#endif
Anton Yartsev69746282013-03-28 16:10:38 +000056
57
58//----- Standard pointer placement operators
59void testGlobalPointerPlacementNew() {
Anton Yartsev2de19ed2013-03-25 01:35:45 +000060 int i;
Anton Yartsev2de19ed2013-03-25 01:35:45 +000061
Anton Yartsev69746282013-03-28 16:10:38 +000062 void *p1 = operator new(0, &i); // no warn
Anton Yartsev2de19ed2013-03-25 01:35:45 +000063
Anton Yartsev69746282013-03-28 16:10:38 +000064 void *p2 = operator new[](0, &i); // no warn
Anton Yartsev2de19ed2013-03-25 01:35:45 +000065
Anton Yartsev69746282013-03-28 16:10:38 +000066 int *p3 = new(&i) int; // no warn
Anton Yartsev2de19ed2013-03-25 01:35:45 +000067
Anton Yartsev69746282013-03-28 16:10:38 +000068 int *p4 = new(&i) int[0]; // no warn
Anton Yartsev2de19ed2013-03-25 01:35:45 +000069}
70
Anton Yartsev69746282013-03-28 16:10:38 +000071//----- Other cases
72void testNewMemoryIsInHeap() {
73 int *p = new int;
74 if (global != p) // condition is always true as 'p' wraps a heap region that
75 // is different from a region wrapped by 'global'
76 global = p; // pointer escapes
Anton Yartsev2de19ed2013-03-25 01:35:45 +000077}
78
Anton Yartsev69746282013-03-28 16:10:38 +000079struct PtrWrapper {
80 int *x;
Anton Yartsev2de19ed2013-03-25 01:35:45 +000081
Anton Yartsev69746282013-03-28 16:10:38 +000082 PtrWrapper(int *input) : x(input) {}
83};
Anton Yartsev2de19ed2013-03-25 01:35:45 +000084
Anton Yartsev69746282013-03-28 16:10:38 +000085void testNewInvalidationPlacement(PtrWrapper *w) {
86 // Ensure that we don't consider this a leak.
87 new (w) PtrWrapper(new int); // no warn
Anton Yartsev2de19ed2013-03-25 01:35:45 +000088}
89
90//---------------
91// other checks
92//---------------
93
94void f(int *);
95
96void testUseAfterDelete() {
97 int *p = new int;
98 delete p;
99 f(p); // expected-warning{{Use of memory after it is freed}}
100}
101
102void testDeleteAlloca() {
103 int *p = (int *)__builtin_alloca(sizeof(int));
Anton Yartsev849c7bf2013-03-28 17:05:19 +0000104 delete p; // expected-warning{{Memory allocated by alloca() should not be deallocated}}
Anton Yartsev2de19ed2013-03-25 01:35:45 +0000105}
106
107void testDoubleDelete() {
108 int *p = new int;
109 delete p;
110 delete p; // expected-warning{{Attempt to free released memory}}
111}
112
113void testExprDeleteArg() {
114 int i;
Anton Yartsev849c7bf2013-03-28 17:05:19 +0000115 delete &i; // expected-warning{{Argument to 'delete' is the address of the local variable 'i', which is not memory allocated by 'new'}}
116}
Anton Yartsev2de19ed2013-03-25 01:35:45 +0000117
118void testExprDeleteArrArg() {
119 int i;
Anton Yartsev849c7bf2013-03-28 17:05:19 +0000120 delete[] &i; // expected-warning{{Argument to 'delete[]' is the address of the local variable 'i', which is not memory allocated by 'new[]'}}
121}
Anton Yartsev2de19ed2013-03-25 01:35:45 +0000122
123void testAllocDeallocNames() {
124 int *p = new(std::nothrow) int[1];
Anton Yartsev849c7bf2013-03-28 17:05:19 +0000125 delete[] (++p); // expected-warning{{Argument to 'delete[]' is offset by 4 bytes from the start of memory allocated by 'new[]'}}
126}
Anton Yartsev2de19ed2013-03-25 01:35:45 +0000127
Anna Zaks41988f32013-03-28 23:15:29 +0000128//--------------------------------
129// Test escape of newed const pointer. Note, a const pointer can be deleted.
130//--------------------------------
131struct StWithConstPtr {
132 const int *memp;
133};
134void escape(const int &x);
135void escapeStruct(const StWithConstPtr &x);
136void escapePtr(const StWithConstPtr *x);
137void escapeVoidPtr(const void *x);
138
139void testConstEscape() {
140 int *p = new int(1);
141 escape(*p);
142} // no-warning
143
144void testConstEscapeStruct() {
145 StWithConstPtr *St = new StWithConstPtr();
146 escapeStruct(*St);
147} // no-warning
148
149void testConstEscapeStructPtr() {
150 StWithConstPtr *St = new StWithConstPtr();
151 escapePtr(St);
152} // no-warning
153
154void testConstEscapeMember() {
155 StWithConstPtr St;
156 St.memp = new int(2);
157 escapeVoidPtr(St.memp);
158} // no-warning
159
160void testConstEscapePlacementNew() {
161 int *x = (int *)malloc(sizeof(int));
162 void *y = new (x) int;
163 escapeVoidPtr(y);
164} // no-warning