1 // RUN: %clang_analyze_cc1 -analyzer-checker=core,debug.ExprInspection -analyzer-disable-checker=cplusplus -analyzer-config c++-inlining=constructors -verify %s 2 3 #include "Inputs/system-header-simulator-cxx.h" 4 5 void clang_analyzer_eval(bool); 6 7 struct s { 8 int x; 9 int y; 10 }; 11 12 void a1(void) { 13 s arr[3]; 14 int x = arr[0].x; 15 // expected-warning@-1{{Assigned value is garbage or undefined}} 16 } 17 18 void a2(void) { 19 s arr[3]; 20 int x = arr[1].x; 21 // expected-warning@-1{{Assigned value is garbage or undefined}} 22 } 23 24 void a3(void) { 25 s arr[3]; 26 int x = arr[2].x; 27 // expected-warning@-1{{Assigned value is garbage or undefined}} 28 } 29 30 struct s2 { 31 int x; 32 int y = 2; 33 }; 34 35 void b1(void) { 36 s2 arr[3]; 37 38 clang_analyzer_eval(arr[0].y == 2); // expected-warning{{TRUE}} 39 int x = arr[0].x; 40 // expected-warning@-1{{Assigned value is garbage or undefined}} 41 } 42 43 void b2(void) { 44 s2 arr[3]; 45 46 clang_analyzer_eval(arr[1].y == 2); // expected-warning{{TRUE}} 47 int x = arr[1].x; 48 // expected-warning@-1{{Assigned value is garbage or undefined}} 49 } 50 51 void b3(void) { 52 s2 arr[3]; 53 54 clang_analyzer_eval(arr[2].y == 2); // expected-warning{{TRUE}} 55 int x = arr[2].x; 56 // expected-warning@-1{{Assigned value is garbage or undefined}} 57 } 58 59 void c1(void) { 60 { 61 s2 arr[2]; 62 arr[1].x = 3; 63 64 clang_analyzer_eval(arr[1].y == 2); // expected-warning{{TRUE}} 65 clang_analyzer_eval(arr[1].x == 3); // expected-warning{{TRUE}} 66 } 67 68 { 69 s2 arr[2]; 70 71 clang_analyzer_eval(arr[1].y == 2); // expected-warning{{TRUE}} 72 int x = arr[1].x; 73 // expected-warning@-1{{Assigned value is garbage or undefined}} 74 } 75 } 76 77 struct s3 { 78 int x = 1; 79 int y = 2; 80 }; 81 82 struct s4 { 83 s3 arr[2]; 84 s sarr[2]; 85 }; 86 87 void e1(void) { 88 s4 arr[2]; 89 90 clang_analyzer_eval(arr[0].arr[0].x == 1); // expected-warning{{TRUE}} 91 clang_analyzer_eval(arr[0].arr[0].y == 2); // expected-warning{{TRUE}} 92 93 clang_analyzer_eval(arr[0].arr[1].x == 1); // expected-warning{{TRUE}} 94 clang_analyzer_eval(arr[0].arr[1].y == 2); // expected-warning{{TRUE}} 95 96 clang_analyzer_eval(arr[1].arr[0].x == 1); // expected-warning{{TRUE}} 97 clang_analyzer_eval(arr[1].arr[0].y == 2); // expected-warning{{TRUE}} 98 99 clang_analyzer_eval(arr[1].arr[1].x == 1); // expected-warning{{TRUE}} 100 clang_analyzer_eval(arr[1].arr[1].y == 2); // expected-warning{{TRUE}} 101 102 int x = arr[1].sarr[1].x; 103 // expected-warning@-1{{Assigned value is garbage or undefined}} 104 } 105 106 void f1(void) { 107 s2 arr[2][2]; 108 109 clang_analyzer_eval(arr[1][1].y == 2); // expected-warning{{TRUE}} 110 int x = arr[1][1].x; 111 // expected-warning@-1{{Assigned value is garbage or undefined}} 112 } 113 114 struct s5 { 115 static int c; 116 int x; 117 118 s5() : x(c++) {} 119 }; 120 121 void g1(void) { 122 // FIXME: This test requires -analyzer-disable-checker=cplusplus, 123 // because of the checker's weird behaviour in case of arrays. 124 // E.g.: 125 // s3 *arr = new s3[4]; 126 // s3 *arr2 = new (arr + 1) s3[1]; 127 // ^~~~~~~~~~~~~~~~~~~ 128 // warning: 12 bytes is possibly not enough 129 // for array allocation which requires 130 // 4 bytes. 131 132 s5::c = 0; 133 s5 *arr = new s5[4]; 134 new (arr + 1) s5[3]; 135 136 clang_analyzer_eval(arr[0].x == 0); // expected-warning{{TRUE}} 137 clang_analyzer_eval(arr[1].x == 4); // expected-warning{{TRUE}} 138 clang_analyzer_eval(arr[2].x == 5); // expected-warning{{TRUE}} 139 clang_analyzer_eval(arr[3].x == 6); // expected-warning{{TRUE}} 140 } 141 142 void g2(void) { 143 s5::c = 0; 144 s5 arr[4]; 145 146 clang_analyzer_eval(arr[0].x == 0); // expected-warning{{TRUE}} 147 clang_analyzer_eval(arr[1].x == 1); // expected-warning{{TRUE}} 148 clang_analyzer_eval(arr[2].x == 2); // expected-warning{{TRUE}} 149 clang_analyzer_eval(arr[3].x == 3); // expected-warning{{TRUE}} 150 } 151 152 void g3(void) { 153 s5::c = 0; 154 s5 arr[2][2]; 155 156 clang_analyzer_eval(arr[0][0].x == 0); // expected-warning{{TRUE}} 157 clang_analyzer_eval(arr[0][1].x == 1); // expected-warning{{TRUE}} 158 clang_analyzer_eval(arr[1][0].x == 2); // expected-warning{{TRUE}} 159 clang_analyzer_eval(arr[1][1].x == 3); // expected-warning{{TRUE}} 160 } 161 162 void h1(void) { 163 s5::c = 0; 164 s5 a[2][2], b[2][2]; 165 166 clang_analyzer_eval(a[0][0].x == 0); // expected-warning{{TRUE}} 167 clang_analyzer_eval(a[0][1].x == 1); // expected-warning{{TRUE}} 168 clang_analyzer_eval(a[1][0].x == 2); // expected-warning{{TRUE}} 169 clang_analyzer_eval(a[1][1].x == 3); // expected-warning{{TRUE}} 170 171 clang_analyzer_eval(b[0][0].x == 4); // expected-warning{{TRUE}} 172 clang_analyzer_eval(b[0][1].x == 5); // expected-warning{{TRUE}} 173 clang_analyzer_eval(b[1][0].x == 6); // expected-warning{{TRUE}} 174 clang_analyzer_eval(b[1][1].x == 7); // expected-warning{{TRUE}} 175 } 176 177 void h2(void) { 178 s a[2][2], b[2][2]; 179 180 int x = a[1][1].x; 181 // expected-warning@-1{{Assigned value is garbage or undefined}} 182 } 183 184 void h3(void) { 185 s a[2][2], b[2][2]; 186 187 int x = b[1][1].y; 188 // expected-warning@-1{{Assigned value is garbage or undefined}} 189 } 190 191 struct Base { 192 int x; 193 int y; 194 195 Base(int x, int y) : x(x), y(y) {} 196 }; 197 198 struct Derived : public Base { 199 int i; 200 int j; 201 202 Derived(int x, int y, int i, int j) : Base(x, y), i(i), j(j) {} 203 }; 204 205 void delegate(void) { 206 Derived arr[2] = {{1, 2, 3, 4}, {5, 6, 7, 8}}; 207 208 clang_analyzer_eval(arr[0].x == 1); // expected-warning{{TRUE}} 209 clang_analyzer_eval(arr[0].y == 2); // expected-warning{{TRUE}} 210 clang_analyzer_eval(arr[0].i == 3); // expected-warning{{TRUE}} 211 clang_analyzer_eval(arr[0].j == 4); // expected-warning{{TRUE}} 212 213 clang_analyzer_eval(arr[1].x == 5); // expected-warning{{TRUE}} 214 clang_analyzer_eval(arr[1].y == 6); // expected-warning{{TRUE}} 215 clang_analyzer_eval(arr[1].i == 7); // expected-warning{{TRUE}} 216 clang_analyzer_eval(arr[1].j == 8); // expected-warning{{TRUE}} 217 } 218 219 void delegate_heap(void) { 220 Derived *arr = new Derived[2]{{1, 2, 3, 4}, {5, 6, 7, 8}}; 221 222 clang_analyzer_eval(arr[0].x == 1); // expected-warning{{TRUE}} 223 clang_analyzer_eval(arr[0].y == 2); // expected-warning{{TRUE}} 224 clang_analyzer_eval(arr[0].i == 3); // expected-warning{{TRUE}} 225 clang_analyzer_eval(arr[0].j == 4); // expected-warning{{TRUE}} 226 227 clang_analyzer_eval(arr[1].x == 5); // expected-warning{{TRUE}} 228 clang_analyzer_eval(arr[1].y == 6); // expected-warning{{TRUE}} 229 clang_analyzer_eval(arr[1].i == 7); // expected-warning{{TRUE}} 230 clang_analyzer_eval(arr[1].j == 8); // expected-warning{{TRUE}} 231 } 232 233 struct Member { 234 int x; 235 int y; 236 }; 237 238 struct Parent { 239 Member arr[2]; 240 241 Parent() : arr{{1, 2}, {3, 4}} {} 242 }; 243 244 void member() { 245 Parent arr[2]; 246 247 // FIXME: Ideally these are TRUE, but at the moment InitListExpr has no 248 // knowledge about where the initializer list is used, so we can't bind 249 // the initializer list to the required region. 250 clang_analyzer_eval(arr[0].arr[0].x == 1); // expected-warning{{UNKNOWN}} 251 clang_analyzer_eval(arr[0].arr[0].y == 2); // expected-warning{{UNKNOWN}} 252 clang_analyzer_eval(arr[0].arr[1].x == 3); // expected-warning{{UNKNOWN}} 253 clang_analyzer_eval(arr[0].arr[1].y == 4); // expected-warning{{UNKNOWN}} 254 255 clang_analyzer_eval(arr[1].arr[0].x == 1); // expected-warning{{UNKNOWN}} 256 clang_analyzer_eval(arr[1].arr[0].y == 2); // expected-warning{{UNKNOWN}} 257 clang_analyzer_eval(arr[1].arr[1].x == 3); // expected-warning{{UNKNOWN}} 258 clang_analyzer_eval(arr[1].arr[1].y == 4); // expected-warning{{UNKNOWN}} 259 } 260