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
6void clang_analyzer_eval(bool);
7void clang_analyzer_checkInlined(bool);
8
9#define HEADER
10#include "containers.cpp"
11#undef HEADER
12
13void 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
38void testSubclass(MySetSubclass &sub) {
39  sub.useIterator(sub.begin());
40
41  MySetSubclass local;
42}
43
44void 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
85class MySet {
86  int *storage;
87  unsigned size;
88public:
89  MySet() : storage(0), size(0) {
90    clang_analyzer_checkInlined(true);
91#if INLINE
92    // expected-warning@-2 {{TRUE}}
93#endif
94  }
95
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
103  ~MySet() { delete[] storage; }
104
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
116    iterator(int *p) : impl(p) {}
117  };
118
119  iterator begin() {
120    clang_analyzer_checkInlined(true);
121    #if INLINE
122        // expected-warning@-2 {{TRUE}}
123    #endif
124    return iterator(storage);
125  }
126
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
137  raw_iterator raw_begin() {
138    clang_analyzer_checkInlined(true);
139    #if INLINE
140        // expected-warning@-2 {{TRUE}}
141    #endif
142    return storage;
143  }
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
153class MySetSubclass : public MySet {
154public:
155  MySetSubclass() {
156    clang_analyzer_checkInlined(true);
157#if INLINE
158    // expected-warning@-2 {{TRUE}}
159#endif
160  }
161
162  void useIterator(iterator i) {
163    clang_analyzer_checkInlined(true);
164    #if INLINE
165        // expected-warning@-2 {{TRUE}}
166    #endif
167  }
168};
169
170class BeginOnlySet {
171  MySet impl;
172public:
173  struct IterImpl {
174    MySet::iterator impl;
175    typedef std::forward_iterator_tag iterator_category;
176
177    IterImpl(MySet::iterator i) : impl(i) {
178      clang_analyzer_checkInlined(true);
179#if INLINE
180      // expected-warning@-2 {{TRUE}}
181#endif
182    }
183  };
184
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
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
203class IteratorTypedefOnlySet {
204  MySet impl;
205public:
206
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
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
225class IteratorUsingOnlySet {
226  MySet impl;
227public:
228
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
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
247class IteratorStructOnlySet {
248  MySet impl;
249public:
250
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
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