1 // RUN: %clang_analyze_cc1 -analyzer-checker=core,debug.ExprInspection -std=c++17 -verify %s
3 void clang_analyzer_eval(bool);
6 int arr
[] = {1, 2, 3, 4, 5};
8 auto [a
, b
, c
, d
, e
] = arr
;
10 clang_analyzer_eval(a
== 1); // expected-warning{{TRUE}}
11 clang_analyzer_eval(b
== 2); // expected-warning{{TRUE}}
12 clang_analyzer_eval(c
== 3); // expected-warning{{TRUE}}
13 clang_analyzer_eval(d
== 4); // expected-warning{{TRUE}}
14 clang_analyzer_eval(e
== 5); // expected-warning{{TRUE}}
20 auto [a
, b
, c
, d
, e
] = arr
;
22 int x
= e
; // expected-warning{{Assigned value is garbage or undefined}}
26 int arr
[] = {1, 2, 3, 4, 5};
28 auto l
= [arr
] { return arr
[0]; }();
29 clang_analyzer_eval(l
== 1); // expected-warning{{TRUE}}
31 l
= [arr
] { return arr
[1]; }();
32 clang_analyzer_eval(l
== 2); // expected-warning{{TRUE}}
34 l
= [arr
] { return arr
[2]; }();
35 clang_analyzer_eval(l
== 3); // expected-warning{{TRUE}}
37 l
= [arr
] { return arr
[3]; }();
38 clang_analyzer_eval(l
== 4); // expected-warning{{TRUE}}
40 l
= [arr
] { return arr
[4]; }();
41 clang_analyzer_eval(l
== 5); // expected-warning{{TRUE}}
44 void lambda_uninit() {
47 // FIXME: These should be Undefined, but we fail to read Undefined from a lazyCompoundVal
48 int l
= [arr
] { return arr
[0]; }();
49 clang_analyzer_eval(l
); // expected-warning{{UNKNOWN}}
51 l
= [arr
] { return arr
[1]; }();
52 clang_analyzer_eval(l
); // expected-warning{{UNKNOWN}}
54 l
= [arr
] { return arr
[2]; }();
55 clang_analyzer_eval(l
); // expected-warning{{UNKNOWN}}
57 l
= [arr
] { return arr
[3]; }();
58 clang_analyzer_eval(l
); // expected-warning{{UNKNOWN}}
60 l
= [arr
] { return arr
[4]; }();
61 clang_analyzer_eval(l
); // expected-warning{{UNKNOWN}}
68 void copy_ctor_init() {
77 clang_analyzer_eval(copy
.arr
[0] == 1); // expected-warning{{TRUE}}
78 clang_analyzer_eval(copy
.arr
[1] == 2); // expected-warning{{TRUE}}
79 clang_analyzer_eval(copy
.arr
[2] == 3); // expected-warning{{TRUE}}
80 clang_analyzer_eval(copy
.arr
[3] == 4); // expected-warning{{TRUE}}
81 clang_analyzer_eval(copy
.arr
[4] == 5); // expected-warning{{TRUE}}
84 void copy_ctor_uninit() {
89 // FIXME: These should be Undefined, but we fail to read Undefined from a lazyCompoundVal.
90 // If the struct is not considered a small struct, instead of a copy, we store a lazy compound value.
91 // As the struct has an array data member, it is not considered small.
92 clang_analyzer_eval(copy
.arr
[0]); // expected-warning{{UNKNOWN}}
93 clang_analyzer_eval(copy
.arr
[1]); // expected-warning{{UNKNOWN}}
94 clang_analyzer_eval(copy
.arr
[2]); // expected-warning{{UNKNOWN}}
95 clang_analyzer_eval(copy
.arr
[3]); // expected-warning{{UNKNOWN}}
96 clang_analyzer_eval(copy
.arr
[4]); // expected-warning{{UNKNOWN}}
99 void move_ctor_init() {
107 S moved
= (S
&&) orig
;
109 clang_analyzer_eval(moved
.arr
[0] == 1); // expected-warning{{TRUE}}
110 clang_analyzer_eval(moved
.arr
[1] == 2); // expected-warning{{TRUE}}
111 clang_analyzer_eval(moved
.arr
[2] == 3); // expected-warning{{TRUE}}
112 clang_analyzer_eval(moved
.arr
[3] == 4); // expected-warning{{TRUE}}
113 clang_analyzer_eval(moved
.arr
[4] == 5); // expected-warning{{TRUE}}
116 void move_ctor_uninit() {
119 S moved
= (S
&&) orig
;
121 // FIXME: These should be Undefined, but we fail to read Undefined from a lazyCompoundVal.
122 clang_analyzer_eval(moved
.arr
[0]); // expected-warning{{UNKNOWN}}
123 clang_analyzer_eval(moved
.arr
[1]); // expected-warning{{UNKNOWN}}
124 clang_analyzer_eval(moved
.arr
[2]); // expected-warning{{UNKNOWN}}
125 clang_analyzer_eval(moved
.arr
[3]); // expected-warning{{UNKNOWN}}
126 clang_analyzer_eval(moved
.arr
[4]); // expected-warning{{UNKNOWN}}
129 // The struct has a user defined copy and move ctor, which allow us to
130 // track the values more precisely when an array of this struct is being
131 // copy/move initialized by ArrayInitLoopExpr.
133 inline static int c
= 0;
147 void array_init_non_pod() {
151 auto [a
, b
, c
, d
] = arr
;
153 clang_analyzer_eval(a
.i
== 2); // expected-warning{{TRUE}}
154 clang_analyzer_eval(b
.i
== 3); // expected-warning{{TRUE}}
155 clang_analyzer_eval(c
.i
== 4); // expected-warning{{TRUE}}
156 clang_analyzer_eval(d
.i
== 5); // expected-warning{{TRUE}}
163 // The duplicate is required to emit a warning at 2 different places.
164 struct S3_duplicate
{
168 void array_uninit_non_pod() {
171 auto [a
] = arr
; // expected-warning@159{{ in implicit constructor is garbage or undefined }}
174 void lambda_init_non_pod() {
178 auto l
= [arr
] { return arr
[0].i
; }();
179 clang_analyzer_eval(l
== 2); // expected-warning{{TRUE}}
181 l
= [arr
] { return arr
[1].i
; }();
182 clang_analyzer_eval(l
== 3); // expected-warning{{TRUE}}
184 l
= [arr
] { return arr
[2].i
; }();
185 clang_analyzer_eval(l
== 4); // expected-warning{{TRUE}}
187 l
= [arr
] { return arr
[3].i
; }();
188 clang_analyzer_eval(l
== 5); // expected-warning{{TRUE}}
191 void lambda_uninit_non_pod() {
194 int l
= [arr
] { return arr
[3].i
; }(); // expected-warning@164{{ in implicit constructor is garbage or undefined }}
197 // If this struct is being copy/move constructed by the implicit ctors, ArrayInitLoopExpr
198 // is responsible for the initialization of 'arr' by copy/move constructing each of the
204 void copy_ctor_init_non_pod() {
209 clang_analyzer_eval(copy
.arr
[0].i
== 2); // expected-warning{{TRUE}}
210 clang_analyzer_eval(copy
.arr
[1].i
== 3); // expected-warning{{TRUE}}
211 clang_analyzer_eval(copy
.arr
[2].i
== 4); // expected-warning{{TRUE}}
212 clang_analyzer_eval(copy
.arr
[3].i
== 5); // expected-warning{{TRUE}}
215 void move_ctor_init_non_pod() {
219 S5 moved
= (S5
&&) orig
;
221 clang_analyzer_eval(moved
.arr
[0].i
== 3); // expected-warning{{TRUE}}
222 clang_analyzer_eval(moved
.arr
[1].i
== 4); // expected-warning{{TRUE}}
223 clang_analyzer_eval(moved
.arr
[2].i
== 5); // expected-warning{{TRUE}}
224 clang_analyzer_eval(moved
.arr
[3].i
== 6); // expected-warning{{TRUE}}
227 //Note: This is the only solution I could find to check the values without
228 // crashing clang. For more details on the crash see Issue #57135.
229 void lambda_capture_multi_array() {
230 S3 arr
[2][2] = {1,2,3,4};
233 int x
= [arr
] { return arr
[0][0].i
; }();
234 clang_analyzer_eval(x
== 1); // expected-warning{{TRUE}}
238 int x
= [arr
] { return arr
[0][1].i
; }();
239 clang_analyzer_eval(x
== 2); // expected-warning{{TRUE}}
243 int x
= [arr
] { return arr
[1][0].i
; }();
244 clang_analyzer_eval(x
== 3); // expected-warning{{TRUE}}
248 int x
= [arr
] { return arr
[1][1].i
; }();
249 clang_analyzer_eval(x
== 4); // expected-warning{{TRUE}}
253 // This struct will force constructor inlining in MultiWrapper.
254 struct UserDefinedCtor
{
257 UserDefinedCtor(const UserDefinedCtor
©
) {
263 struct MultiWrapper
{
264 UserDefinedCtor arr
[2][2];
267 void copy_ctor_multi() {
275 MultiWrapper MWCopy
= MW
;
277 clang_analyzer_eval(MWCopy
.arr
[0][0].i
== 0); // expected-warning{{TRUE}}
278 clang_analyzer_eval(MWCopy
.arr
[0][1].i
== 1); // expected-warning{{TRUE}}
279 clang_analyzer_eval(MWCopy
.arr
[1][0].i
== 2); // expected-warning{{TRUE}}
280 clang_analyzer_eval(MWCopy
.arr
[1][1].i
== 3); // expected-warning{{TRUE}}
283 void move_ctor_multi() {
291 MultiWrapper MWMove
= (MultiWrapper
&&) MW
;
293 clang_analyzer_eval(MWMove
.arr
[0][0].i
== 0); // expected-warning{{TRUE}}
294 clang_analyzer_eval(MWMove
.arr
[0][1].i
== 1); // expected-warning{{TRUE}}
295 clang_analyzer_eval(MWMove
.arr
[1][0].i
== 2); // expected-warning{{TRUE}}
296 clang_analyzer_eval(MWMove
.arr
[1][1].i
== 3); // expected-warning{{TRUE}}
299 void structured_binding_multi() {
300 S3 arr
[2][2] = {1,2,3,4};
304 clang_analyzer_eval(a
[0].i
== 1); // expected-warning{{TRUE}}
305 clang_analyzer_eval(a
[1].i
== 2); // expected-warning{{TRUE}}
306 clang_analyzer_eval(b
[0].i
== 3); // expected-warning{{TRUE}}
307 clang_analyzer_eval(b
[1].i
== 4); // expected-warning{{TRUE}}
310 // This snippet used to crash
323 auto l
= [arr
, n
] { return n
; };
326 clang_analyzer_eval(x
== 1); // expected-warning{{TRUE}}
328 // FIXME: This should be 'Undefined'.
329 clang_analyzer_eval(arr
[0].x
); // expected-warning{{UNKNOWN}}