18ef62808Sisuckatcs // RUN: %clang_analyze_cc1 -analyzer-checker=core,debug.ExprInspection -std=c++17 -verify %s 28ef62808Sisuckatcs 38ef62808Sisuckatcs void clang_analyzer_eval(bool); 48ef62808Sisuckatcs 58ef62808Sisuckatcs void array_init() { 68ef62808Sisuckatcs int arr[] = {1, 2, 3, 4, 5}; 78ef62808Sisuckatcs 88ef62808Sisuckatcs auto [a, b, c, d, e] = arr; 98ef62808Sisuckatcs 108ef62808Sisuckatcs clang_analyzer_eval(a == 1); // expected-warning{{TRUE}} 118ef62808Sisuckatcs clang_analyzer_eval(b == 2); // expected-warning{{TRUE}} 128ef62808Sisuckatcs clang_analyzer_eval(c == 3); // expected-warning{{TRUE}} 138ef62808Sisuckatcs clang_analyzer_eval(d == 4); // expected-warning{{TRUE}} 148ef62808Sisuckatcs clang_analyzer_eval(e == 5); // expected-warning{{TRUE}} 158ef62808Sisuckatcs } 168ef62808Sisuckatcs 178ef62808Sisuckatcs void array_uninit() { 188ef62808Sisuckatcs int arr[5]; 198ef62808Sisuckatcs 208ef62808Sisuckatcs auto [a, b, c, d, e] = arr; 218ef62808Sisuckatcs 228ef62808Sisuckatcs int x = e; // expected-warning{{Assigned value is garbage or undefined}} 238ef62808Sisuckatcs } 248ef62808Sisuckatcs 258ef62808Sisuckatcs void lambda_init() { 268ef62808Sisuckatcs int arr[] = {1, 2, 3, 4, 5}; 278ef62808Sisuckatcs 288ef62808Sisuckatcs auto l = [arr] { return arr[0]; }(); 298ef62808Sisuckatcs clang_analyzer_eval(l == 1); // expected-warning{{TRUE}} 308ef62808Sisuckatcs 318ef62808Sisuckatcs l = [arr] { return arr[1]; }(); 328ef62808Sisuckatcs clang_analyzer_eval(l == 2); // expected-warning{{TRUE}} 338ef62808Sisuckatcs 348ef62808Sisuckatcs l = [arr] { return arr[2]; }(); 358ef62808Sisuckatcs clang_analyzer_eval(l == 3); // expected-warning{{TRUE}} 368ef62808Sisuckatcs 378ef62808Sisuckatcs l = [arr] { return arr[3]; }(); 388ef62808Sisuckatcs clang_analyzer_eval(l == 4); // expected-warning{{TRUE}} 398ef62808Sisuckatcs 408ef62808Sisuckatcs l = [arr] { return arr[4]; }(); 418ef62808Sisuckatcs clang_analyzer_eval(l == 5); // expected-warning{{TRUE}} 428ef62808Sisuckatcs } 438ef62808Sisuckatcs 448ef62808Sisuckatcs void lambda_uninit() { 458ef62808Sisuckatcs int arr[5]; 468ef62808Sisuckatcs 478ef62808Sisuckatcs // FIXME: These should be Undefined, but we fail to read Undefined from a lazyCompoundVal 488ef62808Sisuckatcs int l = [arr] { return arr[0]; }(); 498ef62808Sisuckatcs clang_analyzer_eval(l); // expected-warning{{UNKNOWN}} 508ef62808Sisuckatcs 518ef62808Sisuckatcs l = [arr] { return arr[1]; }(); 528ef62808Sisuckatcs clang_analyzer_eval(l); // expected-warning{{UNKNOWN}} 538ef62808Sisuckatcs 548ef62808Sisuckatcs l = [arr] { return arr[2]; }(); 558ef62808Sisuckatcs clang_analyzer_eval(l); // expected-warning{{UNKNOWN}} 568ef62808Sisuckatcs 578ef62808Sisuckatcs l = [arr] { return arr[3]; }(); 588ef62808Sisuckatcs clang_analyzer_eval(l); // expected-warning{{UNKNOWN}} 598ef62808Sisuckatcs 608ef62808Sisuckatcs l = [arr] { return arr[4]; }(); 618ef62808Sisuckatcs clang_analyzer_eval(l); // expected-warning{{UNKNOWN}} 628ef62808Sisuckatcs } 638ef62808Sisuckatcs 648ef62808Sisuckatcs struct S { 658ef62808Sisuckatcs int arr[5]; 668ef62808Sisuckatcs }; 678ef62808Sisuckatcs 688ef62808Sisuckatcs void copy_ctor_init() { 698ef62808Sisuckatcs S orig; 708ef62808Sisuckatcs orig.arr[0] = 1; 718ef62808Sisuckatcs orig.arr[1] = 2; 728ef62808Sisuckatcs orig.arr[2] = 3; 738ef62808Sisuckatcs orig.arr[3] = 4; 748ef62808Sisuckatcs orig.arr[4] = 5; 758ef62808Sisuckatcs 768ef62808Sisuckatcs S copy = orig; 778ef62808Sisuckatcs clang_analyzer_eval(copy.arr[0] == 1); // expected-warning{{TRUE}} 788ef62808Sisuckatcs clang_analyzer_eval(copy.arr[1] == 2); // expected-warning{{TRUE}} 798ef62808Sisuckatcs clang_analyzer_eval(copy.arr[2] == 3); // expected-warning{{TRUE}} 808ef62808Sisuckatcs clang_analyzer_eval(copy.arr[3] == 4); // expected-warning{{TRUE}} 818ef62808Sisuckatcs clang_analyzer_eval(copy.arr[4] == 5); // expected-warning{{TRUE}} 828ef62808Sisuckatcs } 838ef62808Sisuckatcs 848ef62808Sisuckatcs void copy_ctor_uninit() { 858ef62808Sisuckatcs S orig; 868ef62808Sisuckatcs 878ef62808Sisuckatcs S copy = orig; 888ef62808Sisuckatcs 898ef62808Sisuckatcs // FIXME: These should be Undefined, but we fail to read Undefined from a lazyCompoundVal. 908ef62808Sisuckatcs // If the struct is not considered a small struct, instead of a copy, we store a lazy compound value. 918ef62808Sisuckatcs // As the struct has an array data member, it is not considered small. 928ef62808Sisuckatcs clang_analyzer_eval(copy.arr[0]); // expected-warning{{UNKNOWN}} 938ef62808Sisuckatcs clang_analyzer_eval(copy.arr[1]); // expected-warning{{UNKNOWN}} 948ef62808Sisuckatcs clang_analyzer_eval(copy.arr[2]); // expected-warning{{UNKNOWN}} 958ef62808Sisuckatcs clang_analyzer_eval(copy.arr[3]); // expected-warning{{UNKNOWN}} 968ef62808Sisuckatcs clang_analyzer_eval(copy.arr[4]); // expected-warning{{UNKNOWN}} 978ef62808Sisuckatcs } 988ef62808Sisuckatcs 998ef62808Sisuckatcs void move_ctor_init() { 1008ef62808Sisuckatcs S orig; 1018ef62808Sisuckatcs orig.arr[0] = 1; 1028ef62808Sisuckatcs orig.arr[1] = 2; 1038ef62808Sisuckatcs orig.arr[2] = 3; 1048ef62808Sisuckatcs orig.arr[3] = 4; 1058ef62808Sisuckatcs orig.arr[4] = 5; 1068ef62808Sisuckatcs 1078ef62808Sisuckatcs S moved = (S &&) orig; 1088ef62808Sisuckatcs 1098ef62808Sisuckatcs clang_analyzer_eval(moved.arr[0] == 1); // expected-warning{{TRUE}} 1108ef62808Sisuckatcs clang_analyzer_eval(moved.arr[1] == 2); // expected-warning{{TRUE}} 1118ef62808Sisuckatcs clang_analyzer_eval(moved.arr[2] == 3); // expected-warning{{TRUE}} 1128ef62808Sisuckatcs clang_analyzer_eval(moved.arr[3] == 4); // expected-warning{{TRUE}} 1138ef62808Sisuckatcs clang_analyzer_eval(moved.arr[4] == 5); // expected-warning{{TRUE}} 1148ef62808Sisuckatcs } 1158ef62808Sisuckatcs 1168ef62808Sisuckatcs void move_ctor_uninit() { 1178ef62808Sisuckatcs S orig; 1188ef62808Sisuckatcs 1198ef62808Sisuckatcs S moved = (S &&) orig; 1208ef62808Sisuckatcs 1218ef62808Sisuckatcs // FIXME: These should be Undefined, but we fail to read Undefined from a lazyCompoundVal. 1228ef62808Sisuckatcs clang_analyzer_eval(moved.arr[0]); // expected-warning{{UNKNOWN}} 1238ef62808Sisuckatcs clang_analyzer_eval(moved.arr[1]); // expected-warning{{UNKNOWN}} 1248ef62808Sisuckatcs clang_analyzer_eval(moved.arr[2]); // expected-warning{{UNKNOWN}} 1258ef62808Sisuckatcs clang_analyzer_eval(moved.arr[3]); // expected-warning{{UNKNOWN}} 1268ef62808Sisuckatcs clang_analyzer_eval(moved.arr[4]); // expected-warning{{UNKNOWN}} 1278ef62808Sisuckatcs } 128*8a13326dSisuckatcs 129*8a13326dSisuckatcs // The struct has a user defined copy and move ctor, which allow us to 130*8a13326dSisuckatcs // track the values more precisely when an array of this struct is being 131*8a13326dSisuckatcs // copy/move initialized by ArrayInitLoopExpr. 132*8a13326dSisuckatcs struct S2 { 133*8a13326dSisuckatcs inline static int c = 0; 134*8a13326dSisuckatcs int i; 135*8a13326dSisuckatcs 136*8a13326dSisuckatcs S2() : i(++c) {} 137*8a13326dSisuckatcs 138*8a13326dSisuckatcs S2(const S2 ©) { 139*8a13326dSisuckatcs i = copy.i + 1; 140*8a13326dSisuckatcs } 141*8a13326dSisuckatcs 142*8a13326dSisuckatcs S2(S2 &&move) { 143*8a13326dSisuckatcs i = move.i + 2; 144*8a13326dSisuckatcs } 145*8a13326dSisuckatcs }; 146*8a13326dSisuckatcs 147*8a13326dSisuckatcs void array_init_non_pod() { 148*8a13326dSisuckatcs S2::c = 0; 149*8a13326dSisuckatcs S2 arr[4]; 150*8a13326dSisuckatcs 151*8a13326dSisuckatcs auto [a, b, c, d] = arr; 152*8a13326dSisuckatcs 153*8a13326dSisuckatcs clang_analyzer_eval(a.i == 2); // expected-warning{{TRUE}} 154*8a13326dSisuckatcs clang_analyzer_eval(b.i == 3); // expected-warning{{TRUE}} 155*8a13326dSisuckatcs clang_analyzer_eval(c.i == 4); // expected-warning{{TRUE}} 156*8a13326dSisuckatcs clang_analyzer_eval(d.i == 5); // expected-warning{{TRUE}} 157*8a13326dSisuckatcs } 158*8a13326dSisuckatcs 159*8a13326dSisuckatcs struct S3 { 160*8a13326dSisuckatcs int i; 161*8a13326dSisuckatcs }; 162*8a13326dSisuckatcs 163*8a13326dSisuckatcs void array_uninit_non_pod() { 164*8a13326dSisuckatcs S3 arr[1]; 165*8a13326dSisuckatcs 166*8a13326dSisuckatcs auto [a] = arr; // expected-warning@159{{ in implicit constructor is garbage or undefined }} 167*8a13326dSisuckatcs } 168*8a13326dSisuckatcs 169*8a13326dSisuckatcs void lambda_init_non_pod() { 170*8a13326dSisuckatcs S2::c = 0; 171*8a13326dSisuckatcs S2 arr[4]; 172*8a13326dSisuckatcs 173*8a13326dSisuckatcs // FIXME: These should be TRUE, but we fail to capture the array properly. 174*8a13326dSisuckatcs auto l = [arr] { return arr[0].i; }(); 175*8a13326dSisuckatcs clang_analyzer_eval(l == 2); // expected-warning{{TRUE}} // expected-warning{{FALSE}} 176*8a13326dSisuckatcs 177*8a13326dSisuckatcs l = [arr] { return arr[1].i; }(); 178*8a13326dSisuckatcs clang_analyzer_eval(l == 3); // expected-warning{{TRUE}} // expected-warning{{FALSE}} 179*8a13326dSisuckatcs 180*8a13326dSisuckatcs l = [arr] { return arr[2].i; }(); 181*8a13326dSisuckatcs clang_analyzer_eval(l == 4); // expected-warning{{TRUE}} // expected-warning{{FALSE}} 182*8a13326dSisuckatcs 183*8a13326dSisuckatcs l = [arr] { return arr[3].i; }(); 184*8a13326dSisuckatcs clang_analyzer_eval(l == 5); // expected-warning{{TRUE}} // expected-warning{{FALSE}} 185*8a13326dSisuckatcs } 186*8a13326dSisuckatcs 187*8a13326dSisuckatcs void lambda_uninit_non_pod() { 188*8a13326dSisuckatcs S3 arr[4]; 189*8a13326dSisuckatcs 190*8a13326dSisuckatcs int l = [arr] { return arr[3].i; }(); 191*8a13326dSisuckatcs } 192*8a13326dSisuckatcs 193*8a13326dSisuckatcs // If this struct is being copy/move constructed by the implicit ctors, ArrayInitLoopExpr 194*8a13326dSisuckatcs // is responsible for the initialization of 'arr' by copy/move constructing each of the 195*8a13326dSisuckatcs // elements. 196*8a13326dSisuckatcs struct S5 { 197*8a13326dSisuckatcs S2 arr[4]; 198*8a13326dSisuckatcs }; 199*8a13326dSisuckatcs 200*8a13326dSisuckatcs void copy_ctor_init_non_pod() { 201*8a13326dSisuckatcs S2::c = 0; 202*8a13326dSisuckatcs S5 orig; 203*8a13326dSisuckatcs 204*8a13326dSisuckatcs S5 copy = orig; 205*8a13326dSisuckatcs clang_analyzer_eval(copy.arr[0].i == 2); // expected-warning{{TRUE}} 206*8a13326dSisuckatcs clang_analyzer_eval(copy.arr[1].i == 3); // expected-warning{{TRUE}} 207*8a13326dSisuckatcs clang_analyzer_eval(copy.arr[2].i == 4); // expected-warning{{TRUE}} 208*8a13326dSisuckatcs clang_analyzer_eval(copy.arr[3].i == 5); // expected-warning{{TRUE}} 209*8a13326dSisuckatcs } 210*8a13326dSisuckatcs 211*8a13326dSisuckatcs void move_ctor_init_non_pod() { 212*8a13326dSisuckatcs S2::c = 0; 213*8a13326dSisuckatcs S5 orig; 214*8a13326dSisuckatcs 215*8a13326dSisuckatcs S5 moved = (S5 &&) orig; 216*8a13326dSisuckatcs 217*8a13326dSisuckatcs clang_analyzer_eval(moved.arr[0].i == 3); // expected-warning{{TRUE}} 218*8a13326dSisuckatcs clang_analyzer_eval(moved.arr[1].i == 4); // expected-warning{{TRUE}} 219*8a13326dSisuckatcs clang_analyzer_eval(moved.arr[2].i == 5); // expected-warning{{TRUE}} 220*8a13326dSisuckatcs clang_analyzer_eval(moved.arr[3].i == 6); // expected-warning{{TRUE}} 221*8a13326dSisuckatcs } 222