containers.cpp revision 776d3bb65c90278b9c65544b235d2ac40aea1d6e
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); // expected-warning {{TRUE}}
107    return size == 0;
108  }
109
110  struct iterator {
111    int *impl;
112
113    iterator(int *p) : impl(p) {}
114  };
115
116  iterator begin() {
117    clang_analyzer_checkInlined(true); // expected-warning {{TRUE}}
118    return iterator(storage);
119  }
120
121  iterator end() {
122    clang_analyzer_checkInlined(true); // expected-warning {{TRUE}}
123    return iterator(storage+size);
124  }
125
126  typedef int *raw_iterator;
127
128  raw_iterator raw_begin() {
129    clang_analyzer_checkInlined(true); // expected-warning {{TRUE}}
130    return storage;
131  }
132  raw_iterator raw_end() {
133    clang_analyzer_checkInlined(true); // expected-warning {{TRUE}}
134    return storage + size;
135  }
136};
137
138class MySetSubclass : public MySet {
139public:
140  MySetSubclass() {
141    clang_analyzer_checkInlined(true);
142#if INLINE
143    // expected-warning@-2 {{TRUE}}
144#endif
145  }
146
147  void useIterator(iterator i) {
148    clang_analyzer_checkInlined(true); // expected-warning {{TRUE}}
149  }
150};
151
152class BeginOnlySet {
153  MySet impl;
154public:
155  struct IterImpl {
156    MySet::iterator impl;
157    typedef std::forward_iterator_tag iterator_category;
158
159    IterImpl(MySet::iterator i) : impl(i) {
160      clang_analyzer_checkInlined(true);
161#if INLINE
162      // expected-warning@-2 {{TRUE}}
163#endif
164    }
165  };
166
167  BeginOnlySet() {
168    clang_analyzer_checkInlined(true);
169#if INLINE
170    // expected-warning@-2 {{TRUE}}
171#endif
172  }
173
174  typedef IterImpl wrapped_iterator;
175
176  wrapped_iterator begin() {
177    clang_analyzer_checkInlined(true); // expected-warning {{TRUE}}
178    return IterImpl(impl.begin());
179  }
180};
181
182class IteratorTypedefOnlySet {
183  MySet impl;
184public:
185
186  IteratorTypedefOnlySet() {
187    clang_analyzer_checkInlined(true);
188#if INLINE
189    // expected-warning@-2 {{TRUE}}
190#endif
191  }
192
193  typedef MySet::iterator iterator;
194
195  iterator start() {
196    clang_analyzer_checkInlined(true); // expected-warning {{TRUE}}
197    return impl.begin();
198  }
199};
200
201class IteratorUsingOnlySet {
202  MySet impl;
203public:
204
205  IteratorUsingOnlySet() {
206    clang_analyzer_checkInlined(true);
207#if INLINE
208    // expected-warning@-2 {{TRUE}}
209#endif
210  }
211
212  using iterator = MySet::iterator;
213
214  iterator start() {
215    clang_analyzer_checkInlined(true); // expected-warning {{TRUE}}
216    return impl.begin();
217  }
218};
219
220class IteratorStructOnlySet {
221  MySet impl;
222public:
223
224  IteratorStructOnlySet() {
225    clang_analyzer_checkInlined(true);
226#if INLINE
227    // expected-warning@-2 {{TRUE}}
228#endif
229  }
230
231  struct iterator {
232    int *impl;
233  };
234
235  iterator start() {
236    clang_analyzer_checkInlined(true); // expected-warning {{TRUE}}
237    return iterator{impl.begin().impl};
238  }
239};
240
241#endif // HEADER
242