blob: 802243088e9b9d05878c2cd16ef67fa0ef3e89c2 [file] [log] [blame]
Jordan Rose89e5aaf2012-07-16 23:38:09 +00001// RUN: %clang_cc1 -analyze -analyzer-checker=core,unix.Malloc,debug.ExprInspection -analyzer-store region -std=c++11 -verify %s
Anton Yartsev2de19ed2013-03-25 01:35:45 +00002#include "Inputs/system-header-simulator-cxx.h"
Zhongxing Xu40ab43b2010-04-20 05:48:57 +00003
Jordan Rosee38c1c22012-06-20 01:32:01 +00004void clang_analyzer_eval(bool);
5
Jordan Rose89e5aaf2012-07-16 23:38:09 +00006typedef __typeof__(sizeof(int)) size_t;
Jordan Rosee38c1c22012-06-20 01:32:01 +00007extern "C" void *malloc(size_t);
Anton Yartsev2de19ed2013-03-25 01:35:45 +00008extern "C" void free(void *);
Jordan Rosee38c1c22012-06-20 01:32:01 +00009
Jordan Roseee681112012-06-25 20:48:28 +000010int someGlobal;
11void testImplicitlyDeclaredGlobalNew() {
12 if (someGlobal != 0)
13 return;
14
15 // This used to crash because the global operator new is being implicitly
16 // declared and it does not have a valid source location. (PR13090)
17 void *x = ::operator new(0);
18 ::operator delete(x);
19
20 // Check that the new/delete did not invalidate someGlobal;
21 clang_analyzer_eval(someGlobal == 0); // expected-warning{{TRUE}}
22}
23
Jordan Rosee38c1c22012-06-20 01:32:01 +000024void *testPlacementNew() {
25 int *x = (int *)malloc(sizeof(int));
26 *x = 1;
27 clang_analyzer_eval(*x == 1); // expected-warning{{TRUE}};
28
29 void *y = new (x) int;
30 clang_analyzer_eval(x == y); // expected-warning{{TRUE}};
31 clang_analyzer_eval(*x == 1); // expected-warning{{UNKNOWN}};
32
33 return y;
34}
35
36void *operator new(size_t, size_t, int *);
37void *testCustomNew() {
38 int x[1] = {1};
39 clang_analyzer_eval(*x == 1); // expected-warning{{TRUE}};
40
41 void *y = new (0, x) int;
42 clang_analyzer_eval(*x == 1); // expected-warning{{UNKNOWN}};
43
44 return y; // no-warning
Zhongxing Xu40ab43b2010-04-20 05:48:57 +000045}
46
Jordan Rose70cbf3c2012-07-02 22:21:47 +000047void *operator new(size_t, void *, void *);
48void *testCustomNewMalloc() {
49 int *x = (int *)malloc(sizeof(int));
50
51 // Should be no-warning (the custom allocator could have freed x).
52 void *y = new (0, x) int; // no-warning
53
54 return y;
55}
56
Jordan Rose89e5aaf2012-07-16 23:38:09 +000057void testScalarInitialization() {
58 int *n = new int(3);
59 clang_analyzer_eval(*n == 3); // expected-warning{{TRUE}}
60
61 new (n) int();
62 clang_analyzer_eval(*n == 0); // expected-warning{{TRUE}}
63
64 new (n) int{3};
65 clang_analyzer_eval(*n == 3); // expected-warning{{TRUE}}
66
67 new (n) int{};
68 clang_analyzer_eval(*n == 0); // expected-warning{{TRUE}}
69}
70
Jordan Rosec210cb72012-08-27 17:50:07 +000071struct PtrWrapper {
72 int *x;
73
74 PtrWrapper(int *input) : x(input) {}
75};
76
77PtrWrapper *testNewInvalidation() {
78 // Ensure that we don't consider this a leak.
Jordan Roseb0617202013-03-27 18:10:35 +000079 return new PtrWrapper(static_cast<int *>(malloc(4))); // no-warning
80}
81
82void testNewInvalidationPlacement(PtrWrapper *w) {
83 // Ensure that we don't consider this a leak.
84 new (w) PtrWrapper(static_cast<int *>(malloc(4))); // no-warning
85}
86
87int **testNewInvalidationScalar() {
88 // Ensure that we don't consider this a leak.
89 return new (int *)(static_cast<int *>(malloc(4))); // no-warning
90}
91
92void testNewInvalidationScalarPlacement(int **p) {
93 // Ensure that we don't consider this a leak.
94 new (p) (int *)(static_cast<int *>(malloc(4))); // no-warning
Jordan Rosec210cb72012-08-27 17:50:07 +000095}
96
Jordan Rosee6f2bf82013-03-30 01:31:42 +000097void testCacheOut(PtrWrapper w) {
98 extern bool coin();
99 if (coin())
100 w.x = 0;
101 new (&w.x) (int*)(0); // we cache out here; don't crash
102}
103
104
Anton Yartsev2de19ed2013-03-25 01:35:45 +0000105//--------------------------------------------------------------------
106// Check for intersection with other checkers from MallocChecker.cpp
107// bounded with unix.Malloc
108//--------------------------------------------------------------------
109
110// new/delete oparators are subjects of cplusplus.NewDelete.
111void testNewDeleteNoWarn() {
112 int i;
113 delete &i; // no-warning
114
115 int *p1 = new int;
116 delete ++p1; // no-warning
117
118 int *p2 = new int;
119 delete p2;
120 delete p2; // no-warning
121
122 int *p3 = new int; // no-warning
123}
124
125// unix.Malloc does not know about operators new/delete.
126void testDeleteMallocked() {
127 int *x = (int *)malloc(sizeof(int));
128 delete x; // FIXME: Shoud detect pointer escape and keep silent after 'delete' is modeled properly.
Anna Zaks68eb4c22013-04-06 00:41:36 +0000129} // expected-warning{{Potential leak of memory pointed to by 'x'}}
Anton Yartsev2de19ed2013-03-25 01:35:45 +0000130
131void testDeleteOpAfterFree() {
132 int *p = (int *)malloc(sizeof(int));
133 free(p);
134 operator delete(p); // expected-warning{{Use of memory after it is freed}}
135}
136
137void testDeleteAfterFree() {
138 int *p = (int *)malloc(sizeof(int));
139 free(p);
140 delete p; // expected-warning{{Use of memory after it is freed}}
141}
142
143void testStandardPlacementNewAfterFree() {
144 int *p = (int *)malloc(sizeof(int));
145 free(p);
146 p = new(p) int; // expected-warning{{Use of memory after it is freed}}
147}
148
149void testCustomPlacementNewAfterFree() {
150 int *p = (int *)malloc(sizeof(int));
151 free(p);
152 p = new(0, p) int; // expected-warning{{Use of memory after it is freed}}
153}
Jordan Rosec210cb72012-08-27 17:50:07 +0000154
Jordan Rose3c4e76d2012-06-20 05:34:32 +0000155//--------------------------------
156// Incorrectly-modelled behavior
157//--------------------------------
158
Jordan Rose89e5aaf2012-07-16 23:38:09 +0000159int testNoInitialization() {
Jordan Rose3c4e76d2012-06-20 05:34:32 +0000160 int *n = new int;
161
162 // Should warn that *n is uninitialized.
163 if (*n) { // no-warning
Anton Yartsev2de19ed2013-03-25 01:35:45 +0000164 delete n;
Jordan Rose89e5aaf2012-07-16 23:38:09 +0000165 return 0;
Jordan Rose3c4e76d2012-06-20 05:34:32 +0000166 }
Anton Yartsev2de19ed2013-03-25 01:35:45 +0000167 delete n;
Jordan Rose89e5aaf2012-07-16 23:38:09 +0000168 return 1;
Jordan Rose3c4e76d2012-06-20 05:34:32 +0000169}
170
Jordan Rose89e5aaf2012-07-16 23:38:09 +0000171int testNoInitializationPlacement() {
172 int n;
173 new (&n) int;
Jordan Rose3c4e76d2012-06-20 05:34:32 +0000174
Jordan Rose89e5aaf2012-07-16 23:38:09 +0000175 // Should warn that n is uninitialized.
176 if (n) { // no-warning
177 return 0;
178 }
179 return 1;
Jordan Rose3c4e76d2012-06-20 05:34:32 +0000180}