• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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