blob: 4500dff6dcf21a064dfd7ee7618af210c4b75b1e [file] [log] [blame]
Jordan Rosee189b862013-04-02 00:26:35 +00001// 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