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