1 // RUN: %clang_cc1 -analyze -std=c++11 -analyzer-checker=core,unix.Malloc,debug.ExprInspection -analyzer-config c++-inlining=destructors -analyzer-config c++-container-inlining=false -verify %s
2 // RUN: %clang_cc1 -analyze -std=c++11 -analyzer-checker=core,unix.Malloc,debug.ExprInspection -analyzer-config c++-inlining=destructors -analyzer-config c++-container-inlining=true -DINLINE=1 -verify %s
3
4 #ifndef HEADER
5
6 void clang_analyzer_eval(bool);
7 void clang_analyzer_checkInlined(bool);
8
9 #define HEADER
10 #include "containers.cpp"
11 #undef HEADER
12
test()13 void test() {
14 MySet set(0);
15
16 clang_analyzer_eval(set.isEmpty());
17 #if INLINE
18 // expected-warning@-2 {{TRUE}}
19 #else
20 // expected-warning@-4 {{UNKNOWN}}
21 #endif
22
23 clang_analyzer_eval(set.raw_begin() == set.raw_end());
24 #if INLINE
25 // expected-warning@-2 {{TRUE}}
26 #else
27 // expected-warning@-4 {{UNKNOWN}}
28 #endif
29
30 clang_analyzer_eval(set.begin().impl == set.end().impl);
31 #if INLINE
32 // expected-warning@-2 {{TRUE}}
33 #else
34 // expected-warning@-4 {{UNKNOWN}}
35 #endif
36 }
37
testSubclass(MySetSubclass & sub)38 void testSubclass(MySetSubclass &sub) {
39 sub.useIterator(sub.begin());
40
41 MySetSubclass local;
42 }
43
testWrappers(BeginOnlySet & w1,IteratorStructOnlySet & w2,IteratorTypedefOnlySet & w3,IteratorUsingOnlySet & w4)44 void testWrappers(BeginOnlySet &w1, IteratorStructOnlySet &w2,
45 IteratorTypedefOnlySet &w3, IteratorUsingOnlySet &w4) {
46 BeginOnlySet local1;
47 IteratorStructOnlySet local2;
48 IteratorTypedefOnlySet local3;
49 IteratorUsingOnlySet local4;
50
51 clang_analyzer_eval(w1.begin().impl.impl == w1.begin().impl.impl);
52 #if INLINE
53 // expected-warning@-2 {{TRUE}}
54 #else
55 // expected-warning@-4 {{UNKNOWN}}
56 #endif
57
58 clang_analyzer_eval(w2.start().impl == w2.start().impl);
59 #if INLINE
60 // expected-warning@-2 {{TRUE}}
61 #else
62 // expected-warning@-4 {{UNKNOWN}}
63 #endif
64
65 clang_analyzer_eval(w3.start().impl == w3.start().impl);
66 #if INLINE
67 // expected-warning@-2 {{TRUE}}
68 #else
69 // expected-warning@-4 {{UNKNOWN}}
70 #endif
71
72 clang_analyzer_eval(w4.start().impl == w4.start().impl);
73 #if INLINE
74 // expected-warning@-2 {{TRUE}}
75 #else
76 // expected-warning@-4 {{UNKNOWN}}
77 #endif
78 }
79
80
81 #else // HEADER
82
83 #include "../Inputs/system-header-simulator-cxx.h"
84
85 class MySet {
86 int *storage;
87 unsigned size;
88 public:
MySet()89 MySet() : storage(0), size(0) {
90 clang_analyzer_checkInlined(true);
91 #if INLINE
92 // expected-warning@-2 {{TRUE}}
93 #endif
94 }
95
MySet(unsigned n)96 MySet(unsigned n) : storage(new int[n]), size(n) {
97 clang_analyzer_checkInlined(true);
98 #if INLINE
99 // expected-warning@-2 {{TRUE}}
100 #endif
101 }
102
~MySet()103 ~MySet() { delete[] storage; }
104
isEmpty()105 bool isEmpty() {
106 clang_analyzer_checkInlined(true);
107 #if INLINE
108 // expected-warning@-2 {{TRUE}}
109 #endif
110 return size == 0;
111 }
112
113 struct iterator {
114 int *impl;
115
iteratorMySet::iterator116 iterator(int *p) : impl(p) {}
117 };
118
begin()119 iterator begin() {
120 clang_analyzer_checkInlined(true);
121 #if INLINE
122 // expected-warning@-2 {{TRUE}}
123 #endif
124 return iterator(storage);
125 }
126
end()127 iterator end() {
128 clang_analyzer_checkInlined(true);
129 #if INLINE
130 // expected-warning@-2 {{TRUE}}
131 #endif
132 return iterator(storage+size);
133 }
134
135 typedef int *raw_iterator;
136
raw_begin()137 raw_iterator raw_begin() {
138 clang_analyzer_checkInlined(true);
139 #if INLINE
140 // expected-warning@-2 {{TRUE}}
141 #endif
142 return storage;
143 }
raw_end()144 raw_iterator raw_end() {
145 clang_analyzer_checkInlined(true);
146 #if INLINE
147 // expected-warning@-2 {{TRUE}}
148 #endif
149 return storage + size;
150 }
151 };
152
153 class MySetSubclass : public MySet {
154 public:
MySetSubclass()155 MySetSubclass() {
156 clang_analyzer_checkInlined(true);
157 #if INLINE
158 // expected-warning@-2 {{TRUE}}
159 #endif
160 }
161
useIterator(iterator i)162 void useIterator(iterator i) {
163 clang_analyzer_checkInlined(true);
164 #if INLINE
165 // expected-warning@-2 {{TRUE}}
166 #endif
167 }
168 };
169
170 class BeginOnlySet {
171 MySet impl;
172 public:
173 struct IterImpl {
174 MySet::iterator impl;
175 typedef std::forward_iterator_tag iterator_category;
176
IterImplBeginOnlySet::IterImpl177 IterImpl(MySet::iterator i) : impl(i) {
178 clang_analyzer_checkInlined(true);
179 #if INLINE
180 // expected-warning@-2 {{TRUE}}
181 #endif
182 }
183 };
184
BeginOnlySet()185 BeginOnlySet() {
186 clang_analyzer_checkInlined(true);
187 #if INLINE
188 // expected-warning@-2 {{TRUE}}
189 #endif
190 }
191
192 typedef IterImpl wrapped_iterator;
193
begin()194 wrapped_iterator begin() {
195 clang_analyzer_checkInlined(true);
196 #if INLINE
197 // expected-warning@-2 {{TRUE}}
198 #endif
199 return IterImpl(impl.begin());
200 }
201 };
202
203 class IteratorTypedefOnlySet {
204 MySet impl;
205 public:
206
IteratorTypedefOnlySet()207 IteratorTypedefOnlySet() {
208 clang_analyzer_checkInlined(true);
209 #if INLINE
210 // expected-warning@-2 {{TRUE}}
211 #endif
212 }
213
214 typedef MySet::iterator iterator;
215
start()216 iterator start() {
217 clang_analyzer_checkInlined(true);
218 #if INLINE
219 // expected-warning@-2 {{TRUE}}
220 #endif
221 return impl.begin();
222 }
223 };
224
225 class IteratorUsingOnlySet {
226 MySet impl;
227 public:
228
IteratorUsingOnlySet()229 IteratorUsingOnlySet() {
230 clang_analyzer_checkInlined(true);
231 #if INLINE
232 // expected-warning@-2 {{TRUE}}
233 #endif
234 }
235
236 using iterator = MySet::iterator;
237
start()238 iterator start() {
239 clang_analyzer_checkInlined(true);
240 #if INLINE
241 // expected-warning@-2 {{TRUE}}
242 #endif
243 return impl.begin();
244 }
245 };
246
247 class IteratorStructOnlySet {
248 MySet impl;
249 public:
250
IteratorStructOnlySet()251 IteratorStructOnlySet() {
252 clang_analyzer_checkInlined(true);
253 #if INLINE
254 // expected-warning@-2 {{TRUE}}
255 #endif
256 }
257
258 struct iterator {
259 int *impl;
260 };
261
start()262 iterator start() {
263 clang_analyzer_checkInlined(true);
264 #if INLINE
265 // expected-warning@-2 {{TRUE}}
266 #endif
267 return iterator{impl.begin().impl};
268 }
269 };
270
271 #endif // HEADER
272