blob: be786be541e6d5c2d5d11fd3db9566bf4f12ca35 [file] [log] [blame]
Artem Dergachev9d3a7d82018-03-30 19:21:18 +00001// RUN: %clang_analyze_cc1 -analyzer-checker=core,debug.ExprInspection -std=c++11 -verify %s
2// RUN: %clang_analyze_cc1 -analyzer-checker=core,debug.ExprInspection -std=c++17 -verify %s
3
4void clang_analyzer_eval(bool);
5
Artem Dergachev1fe52472018-06-14 01:32:46 +00006namespace variable_functional_cast_crash {
7
8struct A {
9 A(int) {}
10};
11
12void foo() {
13 A a = A(0);
14}
15
16struct B {
17 A a;
18 B(): a(A(0)) {}
19};
20
21} // namespace variable_functional_cast_crash
22
23
Artem Dergacheva84374d2018-06-14 01:40:49 +000024namespace ctor_initializer {
25
26struct S {
27 int x, y, z;
28};
29
30struct T {
31 S s;
32 int w;
33 T(int w): s(), w(w) {}
34};
35
36class C {
37 T t;
38public:
39 C() : t(T(4)) {
40 S s = {1, 2, 3};
41 t.s = s;
42 // FIXME: Should be TRUE in C++11 as well.
43 clang_analyzer_eval(t.w == 4);
44#if __cplusplus >= 201703L
45 // expected-warning@-2{{TRUE}}
46#else
47 // expected-warning@-4{{UNKNOWN}}
48#endif
49 }
50};
51
Artem Dergachev53b8ce02018-06-14 01:54:21 +000052
53struct A {
54 int x;
55 A(): x(0) {}
56 ~A() {}
57};
58
59struct B {
60 A a;
61 B() : a(A()) {}
62};
63
64void foo() {
65 B b;
66 clang_analyzer_eval(b.a.x == 0); // expected-warning{{TRUE}}
67}
68
Artem Dergacheva84374d2018-06-14 01:40:49 +000069} // namespace ctor_initializer
70
71
Artem Dergachev53b8ce02018-06-14 01:54:21 +000072namespace elision_on_ternary_op_branches {
73class C1 {
74 int x;
75public:
76 C1(int x): x(x) {}
77 int getX() const { return x; }
78 ~C1();
79};
80
81class C2 {
82 int x;
83 int y;
84public:
85 C2(int x, int y): x(x), y(y) {}
86 int getX() const { return x; }
87 int getY() const { return y; }
88 ~C2();
89};
90
91void foo(int coin) {
92 C1 c1 = coin ? C1(1) : C1(2);
93 if (coin) {
94 clang_analyzer_eval(c1.getX() == 1); // expected-warning{{TRUE}}
95 } else {
96 clang_analyzer_eval(c1.getX() == 2); // expected-warning{{TRUE}}
97 }
98 C2 c2 = coin ? C2(3, 4) : C2(5, 6);
99 if (coin) {
100 clang_analyzer_eval(c2.getX() == 3); // expected-warning{{TRUE}}
101 clang_analyzer_eval(c2.getY() == 4); // expected-warning{{TRUE}}
102 } else {
103 clang_analyzer_eval(c2.getX() == 5); // expected-warning{{TRUE}}
104 clang_analyzer_eval(c2.getY() == 6); // expected-warning{{TRUE}}
105 }
106}
107} // namespace elision_on_ternary_op_branches
108
109
Artem Dergachev1fe52472018-06-14 01:32:46 +0000110namespace address_vector_tests {
111
Artem Dergachev9d3a7d82018-03-30 19:21:18 +0000112template <typename T> struct AddressVector {
113 T *buf[10];
114 int len;
115
116 AddressVector() : len(0) {}
117
118 void push(T *t) {
119 buf[len] = t;
120 ++len;
121 }
122};
123
124class ClassWithoutDestructor {
125 AddressVector<ClassWithoutDestructor> &v;
126
127public:
128 ClassWithoutDestructor(AddressVector<ClassWithoutDestructor> &v) : v(v) {
129 v.push(this);
130 }
131
132 ClassWithoutDestructor(ClassWithoutDestructor &&c) : v(c.v) { v.push(this); }
133 ClassWithoutDestructor(const ClassWithoutDestructor &c) : v(c.v) {
134 v.push(this);
135 }
136};
137
138ClassWithoutDestructor make1(AddressVector<ClassWithoutDestructor> &v) {
139 return ClassWithoutDestructor(v);
140}
141ClassWithoutDestructor make2(AddressVector<ClassWithoutDestructor> &v) {
142 return make1(v);
143}
144ClassWithoutDestructor make3(AddressVector<ClassWithoutDestructor> &v) {
145 return make2(v);
146}
147
148void testMultipleReturns() {
149 AddressVector<ClassWithoutDestructor> v;
150 ClassWithoutDestructor c = make3(v);
151
152#if __cplusplus >= 201703L
153 // FIXME: Both should be TRUE.
154 clang_analyzer_eval(v.len == 1); // expected-warning{{TRUE}}
155 clang_analyzer_eval(v.buf[0] == &c); // expected-warning{{FALSE}}
156#else
157 clang_analyzer_eval(v.len == 5); // expected-warning{{TRUE}}
158 clang_analyzer_eval(v.buf[0] != v.buf[1]); // expected-warning{{TRUE}}
159 clang_analyzer_eval(v.buf[1] != v.buf[2]); // expected-warning{{TRUE}}
160 clang_analyzer_eval(v.buf[2] != v.buf[3]); // expected-warning{{TRUE}}
161 clang_analyzer_eval(v.buf[3] != v.buf[4]); // expected-warning{{TRUE}}
162 clang_analyzer_eval(v.buf[4] == &c); // expected-warning{{TRUE}}
163#endif
164}
Artem Dergachev1fe52472018-06-14 01:32:46 +0000165
Artem Dergachev53b8ce02018-06-14 01:54:21 +0000166class ClassWithDestructor {
167 AddressVector<ClassWithDestructor> &v;
168
169public:
170 ClassWithDestructor(AddressVector<ClassWithDestructor> &v) : v(v) {
171 v.push(this);
172 }
173
174 ClassWithDestructor(ClassWithDestructor &&c) : v(c.v) { v.push(this); }
175 ClassWithDestructor(const ClassWithDestructor &c) : v(c.v) {
176 v.push(this);
177 }
178
179 ~ClassWithDestructor() { v.push(this); }
180};
181
182void testVariable() {
183 AddressVector<ClassWithDestructor> v;
184 {
185 ClassWithDestructor c = ClassWithDestructor(v);
186 }
187#if __cplusplus >= 201703L
188 // 0. Construct the variable.
189 // 1. Destroy the variable.
190 clang_analyzer_eval(v.len == 2); // expected-warning{{TRUE}}
191 clang_analyzer_eval(v.buf[0] == v.buf[1]); // expected-warning{{TRUE}}
192#else
193 // 0. Construct the temporary.
194 // 1. Construct the variable.
195 // 2. Destroy the temporary.
196 // 3. Destroy the variable.
197 clang_analyzer_eval(v.len == 4); // expected-warning{{TRUE}}
198 clang_analyzer_eval(v.buf[0] == v.buf[2]); // expected-warning{{TRUE}}
199 clang_analyzer_eval(v.buf[1] == v.buf[3]); // expected-warning{{TRUE}}
200#endif
201}
202
203struct TestCtorInitializer {
204 ClassWithDestructor c;
205 TestCtorInitializer(AddressVector<ClassWithDestructor> &v)
206 : c(ClassWithDestructor(v)) {}
207};
208
209void testCtorInitializer() {
210 AddressVector<ClassWithDestructor> v;
211 {
212 TestCtorInitializer t(v);
213 }
214#if __cplusplus >= 201703L
215 // 0. Construct the member variable.
216 // 1. Destroy the member variable.
217 clang_analyzer_eval(v.len == 2); // expected-warning{{TRUE}}
218 clang_analyzer_eval(v.buf[0] == v.buf[1]); // expected-warning{{TRUE}}
219#else
220 // 0. Construct the temporary.
221 // 1. Construct the member variable.
222 // 2. Destroy the temporary.
223 // 3. Destroy the member variable.
224 clang_analyzer_eval(v.len == 4); // expected-warning{{TRUE}}
225 clang_analyzer_eval(v.buf[0] == v.buf[2]); // expected-warning{{TRUE}}
226 clang_analyzer_eval(v.buf[1] == v.buf[3]); // expected-warning{{TRUE}}
227#endif
228}
229
Artem Dergachev1fe52472018-06-14 01:32:46 +0000230} // namespace address_vector_tests