containers.cpp revision c63a460d78a7625ff38d2b3580f78030c44f07db
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
82
83class MySet {
84  int *storage;
85  unsigned size;
86public:
87  MySet() : storage(0), size(0) {
88    clang_analyzer_checkInlined(true);
89#if INLINE
90    // expected-warning@-2 {{TRUE}}
91#endif
92  }
93
94  MySet(unsigned n) : storage(new int[n]), size(n) {
95    clang_analyzer_checkInlined(true);
96#if INLINE
97    // expected-warning@-2 {{TRUE}}
98#endif
99  }
100
101  ~MySet() { delete[] storage; }
102
103  bool isEmpty() {
104    clang_analyzer_checkInlined(true); // expected-warning {{TRUE}}
105    return size == 0;
106  }
107
108  struct iterator {
109    int *impl;
110
111    iterator(int *p) : impl(p) {}
112  };
113
114  iterator begin() {
115    clang_analyzer_checkInlined(true); // expected-warning {{TRUE}}
116    return iterator(storage);
117  }
118
119  iterator end() {
120    clang_analyzer_checkInlined(true); // expected-warning {{TRUE}}
121    return iterator(storage+size);
122  }
123
124  typedef int *raw_iterator;
125
126  raw_iterator raw_begin() {
127    clang_analyzer_checkInlined(true); // expected-warning {{TRUE}}
128    return storage;
129  }
130  raw_iterator raw_end() {
131    clang_analyzer_checkInlined(true); // expected-warning {{TRUE}}
132    return storage + size;
133  }
134};
135
136class MySetSubclass : public MySet {
137public:
138  MySetSubclass() {
139    clang_analyzer_checkInlined(true);
140#if INLINE
141    // expected-warning@-2 {{TRUE}}
142#endif
143  }
144
145  void useIterator(iterator i) {
146    clang_analyzer_checkInlined(true); // expected-warning {{TRUE}}
147  }
148};
149
150class BeginOnlySet {
151  MySet impl;
152public:
153  struct IterImpl {
154    MySet::iterator impl;
155    IterImpl(MySet::iterator i) : impl(i) {
156      clang_analyzer_checkInlined(true); // expected-warning {{TRUE}}
157    }
158  };
159
160  BeginOnlySet() {
161    clang_analyzer_checkInlined(true);
162#if INLINE
163    // expected-warning@-2 {{TRUE}}
164#endif
165  }
166
167  typedef IterImpl wrapped_iterator;
168
169  wrapped_iterator begin() {
170    clang_analyzer_checkInlined(true); // expected-warning {{TRUE}}
171    return IterImpl(impl.begin());
172  }
173};
174
175class IteratorTypedefOnlySet {
176  MySet impl;
177public:
178
179  IteratorTypedefOnlySet() {
180    clang_analyzer_checkInlined(true);
181#if INLINE
182    // expected-warning@-2 {{TRUE}}
183#endif
184  }
185
186  typedef MySet::iterator iterator;
187
188  iterator start() {
189    clang_analyzer_checkInlined(true); // expected-warning {{TRUE}}
190    return impl.begin();
191  }
192};
193
194class IteratorUsingOnlySet {
195  MySet impl;
196public:
197
198  IteratorUsingOnlySet() {
199    clang_analyzer_checkInlined(true);
200#if INLINE
201    // expected-warning@-2 {{TRUE}}
202#endif
203  }
204
205  using iterator = MySet::iterator;
206
207  iterator start() {
208    clang_analyzer_checkInlined(true); // expected-warning {{TRUE}}
209    return impl.begin();
210  }
211};
212
213class IteratorStructOnlySet {
214  MySet impl;
215public:
216
217  IteratorStructOnlySet() {
218    clang_analyzer_checkInlined(true);
219#if INLINE
220    // expected-warning@-2 {{TRUE}}
221#endif
222  }
223
224  struct iterator {
225    int *impl;
226  };
227
228  iterator start() {
229    clang_analyzer_checkInlined(true); // expected-warning {{TRUE}}
230    return iterator{impl.begin().impl};
231  }
232};
233
234#endif
235