Clang Project

clang_source_code/test/Analysis/inlining/containers.cpp
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
8void clang_analyzer_eval(bool);
9void clang_analyzer_checkInlined(bool);
10
11#define HEADER
12#include "containers.cpp"
13#undef HEADER
14
15void 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
40void testSubclass(MySetSubclass &sub) {
41  sub.useIterator(sub.begin());
42
43  MySetSubclass local;
44}
45
46void 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
87class MySet {
88  int *storage;
89  unsigned size;
90public:
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
155class MySetSubclass : public MySet {
156public:
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
172class BeginOnlySet {
173  MySet impl;
174public:
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
205class IteratorTypedefOnlySet {
206  MySet impl;
207public:
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
227class IteratorUsingOnlySet {
228  MySet impl;
229public:
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
249class IteratorStructOnlySet {
250  MySet impl;
251public:
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