1 // RUN: %clang_cc1 -analyze -analyzer-checker=debug.DumpCFG -triple x86_64-apple-darwin12 -analyzer-config cfg-temporary-dtors=true -std=c++11 %s > %t 2>&1 2 // RUN: FileCheck --input-file=%t %s 3 4 // CHECK-LABEL: void checkWrap(int i) 5 // CHECK: ENTRY 6 // CHECK-NEXT: Succs (1): B1 7 // CHECK: [B1] 8 // CHECK: Succs (21): B2 B3 B4 B5 B6 B7 B8 B9 9 // CHECK: B10 B11 B12 B13 B14 B15 B16 B17 B18 B19 10 // CHECK: B20 B21 B0 11 // CHECK: [B0 (EXIT)] 12 // CHECK-NEXT: Preds (21): B2 B3 B4 B5 B6 B7 B8 B9 13 // CHECK-NEXT: B10 B11 B12 B13 B14 B15 B16 B17 B18 B19 14 // CHECK-NEXT: B20 B21 B1 15 void checkWrap(int i) { 16 switch(i) { 17 case 0: break; 18 case 1: break; 19 case 2: break; 20 case 3: break; 21 case 4: break; 22 case 5: break; 23 case 6: break; 24 case 7: break; 25 case 8: break; 26 case 9: break; 27 case 10: break; 28 case 11: break; 29 case 12: break; 30 case 13: break; 31 case 14: break; 32 case 15: break; 33 case 16: break; 34 case 17: break; 35 case 18: break; 36 case 19: break; 37 } 38 } 39 40 // CHECK-LABEL: void checkDeclStmts() 41 // CHECK: ENTRY 42 // CHECK-NEXT: Succs (1): B1 43 // CHECK: [B1] 44 // CHECK-NEXT: 1: int i; 45 // CHECK-NEXT: 2: int j; 46 // CHECK-NEXT: 3: 1 47 // CHECK-NEXT: 4: int k = 1; 48 // CHECK-NEXT: 5: int l; 49 // CHECK-NEXT: 6: 2 50 // CHECK-NEXT: 7: int m = 2; 51 // CHECK-NEXT: CXXConstructExpr 52 // CHECK-NEXT: 9: struct standalone myStandalone; 53 // CHECK-NEXT: CXXConstructExpr 54 // CHECK-NEXT: 11: struct (anonymous struct at {{.*}}) myAnon; 55 // CHECK-NEXT: CXXConstructExpr 56 // CHECK-NEXT: 13: struct named myNamed; 57 // CHECK-NEXT: Preds (1): B2 58 // CHECK-NEXT: Succs (1): B0 59 void checkDeclStmts() { 60 int i, j; 61 int k = 1, l, m = 2; 62 63 struct standalone { int x, y; }; 64 struct standalone myStandalone; 65 66 struct { int x, y; } myAnon; 67 68 struct named { int x, y; } myNamed; 69 70 static_assert(1, "abc"); 71 } 72 73 // CHECK-LABEL: void F(EmptyE e) 74 // CHECK: ENTRY 75 // CHECK-NEXT: Succs (1): B1 76 // CHECK: [B1] 77 // CHECK-NEXT: 1: e 78 // CHECK-NEXT: 2: [B1.1] (ImplicitCastExpr, LValueToRValue, enum EmptyE) 79 // CHECK-NEXT: 3: [B1.2] (ImplicitCastExpr, IntegralCast, int) 80 // CHECK-NEXT: T: switch [B1.3] 81 // CHECK-NEXT: Preds (1): B2 82 // CHECK-NEXT: Succs (1): B0 83 // CHECK: [B0 (EXIT)] 84 // CHECK-NEXT: Preds (1): B1 85 enum EmptyE {}; 86 void F(EmptyE e) { 87 switch (e) {} 88 } 89 90 // CHECK-LABEL: void testBuiltinSize() 91 // CHECK: ENTRY 92 // CHECK-NEXT: Succs (1): B1 93 // CHECK: [B1] 94 // CHECK-NEXT: 1: __builtin_object_size 95 // CHECK-NEXT: 2: [B1.1] (ImplicitCastExpr, BuiltinFnToFnPtr, unsigned long (*)(const void *, int)) 96 // CHECK-NEXT: 3: [B1.2](dummy(), 0) 97 // CHECK-NEXT: 4: (void)[B1.3] (CStyleCastExpr, ToVoid, void) 98 // CHECK-NEXT: Preds (1): B2 99 // CHECK-NEXT: Succs (1): B0 100 // CHECK: [B0 (EXIT)] 101 // CHECK-NEXT: Preds (1): B1 102 void testBuiltinSize() { 103 extern int *dummy(); 104 (void)__builtin_object_size(dummy(), 0); 105 } 106 107 108 class A { 109 public: 110 A() {} 111 ~A() {} 112 }; 113 114 // CHECK-LABEL: void test_deletedtor() 115 // CHECK: [B2 (ENTRY)] 116 // CHECK-NEXT: Succs (1): B1 117 // CHECK: [B1] 118 // CHECK-NEXT: 1: CFGNewAllocator(A *) 119 // CHECK-NEXT: 2: (CXXConstructExpr, class A) 120 // CHECK-NEXT: 3: new A([B1.2]) 121 // CHECK-NEXT: 4: A *a = new A(); 122 // CHECK-NEXT: 5: a 123 // CHECK-NEXT: 6: [B1.5] (ImplicitCastExpr, LValueToRValue, class A *) 124 // CHECK-NEXT: 7: [B1.6]->~A() (Implicit destructor) 125 // CHECK-NEXT: 8: delete [B1.6] 126 // CHECK-NEXT: Preds (1): B2 127 // CHECK-NEXT: Succs (1): B0 128 // CHECK: [B0 (EXIT)] 129 // CHECK-NEXT: Preds (1): B1 130 void test_deletedtor() { 131 A *a = new A(); 132 delete a; 133 } 134 135 // CHECK-LABEL: void test_deleteArraydtor() 136 // CHECK: [B2 (ENTRY)] 137 // CHECK-NEXT: Succs (1): B1 138 // CHECK: [B1] 139 // CHECK-NEXT: 1: 5 140 // CHECK-NEXT: 2: CFGNewAllocator(A *) 141 // CHECK-NEXT: 3: (CXXConstructExpr, class A) 142 // CHECK-NEXT: 4: new A {{\[\[}}B1.1]] 143 // CHECK-NEXT: 5: A *a = new A [5]; 144 // CHECK-NEXT: 6: a 145 // CHECK-NEXT: 7: [B1.6] (ImplicitCastExpr, LValueToRValue, class A *) 146 // CHECK-NEXT: 8: [B1.7]->~A() (Implicit destructor) 147 // CHECK-NEXT: 9: delete [] [B1.7] 148 // CHECK-NEXT: Preds (1): B2 149 // CHECK-NEXT: Succs (1): B0 150 // CHECK: [B0 (EXIT)] 151 // CHECK-NEXT: Preds (1): B1 152 void test_deleteArraydtor() { 153 A *a = new A[5]; 154 delete[] a; 155 } 156 157 158 namespace NoReturnSingleSuccessor { 159 struct A { 160 A(); 161 ~A(); 162 }; 163 164 struct B : public A { 165 B(); 166 ~B() __attribute__((noreturn)); 167 }; 168 169 // CHECK-LABEL: int test1(int *x) 170 // CHECK: 1: 1 171 // CHECK-NEXT: 2: return 172 // CHECK-NEXT: ~B() (Implicit destructor) 173 // CHECK-NEXT: Preds (1) 174 // CHECK-NEXT: Succs (1): B0 175 int test1(int *x) { 176 B b; 177 if (x) 178 return 1; 179 } 180 181 // CHECK-LABEL: int test2(int *x) 182 // CHECK: 1: 1 183 // CHECK-NEXT: 2: return 184 // CHECK-NEXT: destructor 185 // CHECK-NEXT: Preds (1) 186 // CHECK-NEXT: Succs (1): B0 187 int test2(int *x) { 188 const A& a = B(); 189 if (x) 190 return 1; 191 } 192 } 193 194 // Test CFG support for "extending" an enum. 195 // CHECK-LABEL: int test_enum_with_extension(enum MyEnum value) 196 // CHECK: [B7 (ENTRY)] 197 // CHECK-NEXT: Succs (1): B2 198 // CHECK: [B1] 199 // CHECK-NEXT: 1: x 200 // CHECK-NEXT: 2: [B1.1] (ImplicitCastExpr, LValueToRValue, int) 201 // CHECK-NEXT: 3: return [B1.2]; 202 // CHECK-NEXT: Preds (5): B3 B4 B5 B6 B2(Unreachable) 203 // CHECK-NEXT: Succs (1): B0 204 // CHECK: [B2] 205 // CHECK-NEXT: 1: 0 206 // CHECK-NEXT: 2: int x = 0; 207 // CHECK-NEXT: 3: value 208 // CHECK-NEXT: 4: [B2.3] (ImplicitCastExpr, LValueToRValue, enum MyEnum) 209 // CHECK-NEXT: 5: [B2.4] (ImplicitCastExpr, IntegralCast, int) 210 // CHECK-NEXT: T: switch [B2.5] 211 // CHECK-NEXT: Preds (1): B7 212 // CHECK-NEXT: Succs (5): B3 B4 B5 B6 B1(Unreachable) 213 // CHECK: [B3] 214 // CHECK-NEXT: case D: 215 // CHECK-NEXT: 1: 4 216 // CHECK-NEXT: 2: x 217 // CHECK-NEXT: 3: [B3.2] = [B3.1] 218 // CHECK-NEXT: T: break; 219 // CHECK-NEXT: Preds (1): B2 220 // CHECK-NEXT: Succs (1): B1 221 // CHECK: [B4] 222 // CHECK-NEXT: case C: 223 // CHECK-NEXT: 1: 3 224 // CHECK-NEXT: 2: x 225 // CHECK-NEXT: 3: [B4.2] = [B4.1] 226 // CHECK-NEXT: T: break; 227 // CHECK-NEXT: Preds (1): B2 228 // CHECK-NEXT: Succs (1): B1 229 // CHECK: [B5] 230 // CHECK-NEXT: case B: 231 // CHECK-NEXT: 1: 2 232 // CHECK-NEXT: 2: x 233 // CHECK-NEXT: 3: [B5.2] = [B5.1] 234 // CHECK-NEXT: T: break; 235 // CHECK-NEXT: Preds (1): B2 236 // CHECK-NEXT: Succs (1): B1 237 // CHECK: [B6] 238 // CHECK-NEXT: case A: 239 // CHECK-NEXT: 1: 1 240 // CHECK-NEXT: 2: x 241 // CHECK-NEXT: 3: [B6.2] = [B6.1] 242 // CHECK-NEXT: T: break; 243 // CHECK-NEXT: Preds (1): B2 244 // CHECK-NEXT: Succs (1): B1 245 // CHECK: [B0 (EXIT)] 246 // CHECK-NEXT: Preds (1): B1 247 enum MyEnum { A, B, C }; 248 static const enum MyEnum D = (enum MyEnum) 32; 249 250 int test_enum_with_extension(enum MyEnum value) { 251 int x = 0; 252 switch (value) { 253 case A: x = 1; break; 254 case B: x = 2; break; 255 case C: x = 3; break; 256 case D: x = 4; break; 257 } 258 return x; 259 } 260 261 // CHECK-LABEL: int test_enum_with_extension_default(enum MyEnum value) 262 // CHECK: [B7 (ENTRY)] 263 // CHECK-NEXT: Succs (1): B2 264 // CHECK: [B1] 265 // CHECK-NEXT: 1: x 266 // CHECK-NEXT: 2: [B1.1] (ImplicitCastExpr, LValueToRValue, int) 267 // CHECK-NEXT: 3: return [B1.2]; 268 // CHECK-NEXT: Preds (4): B3 B4 B5 B6 269 // CHECK-NEXT: Succs (1): B0 270 // CHECK: [B2] 271 // CHECK-NEXT: 1: 0 272 // CHECK-NEXT: 2: int x = 0; 273 // CHECK-NEXT: 3: value 274 // CHECK-NEXT: 4: [B2.3] (ImplicitCastExpr, LValueToRValue, enum MyEnum) 275 // CHECK-NEXT: 5: [B2.4] (ImplicitCastExpr, IntegralCast, int) 276 // CHECK-NEXT: T: switch [B2.5] 277 // CHECK-NEXT: Preds (1): B7 278 // CHECK-NEXT: Succs (4): B4 B5 B6 B3(Unreachable) 279 // CHECK: [B3] 280 // CHECK-NEXT: default: 281 // CHECK-NEXT: 1: 4 282 // CHECK-NEXT: 2: x 283 // CHECK-NEXT: 3: [B3.2] = [B3.1] 284 // CHECK-NEXT: T: break; 285 // CHECK-NEXT: Preds (1): B2(Unreachable) 286 // CHECK-NEXT: Succs (1): B1 287 // CHECK: [B4] 288 // CHECK-NEXT: case C: 289 // CHECK-NEXT: 1: 3 290 // CHECK-NEXT: 2: x 291 // CHECK-NEXT: 3: [B4.2] = [B4.1] 292 // CHECK-NEXT: T: break; 293 // CHECK-NEXT: Preds (1): B2 294 // CHECK-NEXT: Succs (1): B1 295 // CHECK: [B5] 296 // CHECK-NEXT: case B: 297 // CHECK-NEXT: 1: 2 298 // CHECK-NEXT: 2: x 299 // CHECK-NEXT: 3: [B5.2] = [B5.1] 300 // CHECK-NEXT: T: break; 301 // CHECK-NEXT: Preds (1): B2 302 // CHECK-NEXT: Succs (1): B1 303 // CHECK: [B6] 304 // CHECK-NEXT: case A: 305 // CHECK-NEXT: 1: 1 306 // CHECK-NEXT: 2: x 307 // CHECK-NEXT: 3: [B6.2] = [B6.1] 308 // CHECK-NEXT: T: break; 309 // CHECK-NEXT: Preds (1): B2 310 // CHECK-NEXT: Succs (1): B1 311 // CHECK: [B0 (EXIT)] 312 // CHECK-NEXT: Preds (1): B1 313 int test_enum_with_extension_default(enum MyEnum value) { 314 int x = 0; 315 switch (value) { 316 case A: x = 1; break; 317 case B: x = 2; break; 318 case C: x = 3; break; 319 default: x = 4; break; 320 } 321 return x; 322 } 323 324 325 // CHECK-LABEL: void test_placement_new() 326 // CHECK: [B2 (ENTRY)] 327 // CHECK-NEXT: Succs (1): B1 328 // CHECK: [B1] 329 // CHECK-NEXT: 1: int buffer[16]; 330 // CHECK-NEXT: 2: buffer 331 // CHECK-NEXT: 3: [B1.2] (ImplicitCastExpr, ArrayToPointerDecay, int *) 332 // CHECK-NEXT: 4: [B1.3] (ImplicitCastExpr, BitCast, void *) 333 // CHECK-NEXT: 5: CFGNewAllocator(MyClass *) 334 // CHECK-NEXT: 6: (CXXConstructExpr, class MyClass) 335 // CHECK-NEXT: 7: new ([B1.4]) MyClass([B1.6]) 336 // CHECK-NEXT: 8: MyClass *obj = new (buffer) MyClass(); 337 // CHECK-NEXT: Preds (1): B2 338 // CHECK-NEXT: Succs (1): B0 339 // CHECK: [B0 (EXIT)] 340 // CHECK-NEXT: Preds (1): B1 341 342 extern void* operator new (unsigned long sz, void* v); 343 extern void* operator new[] (unsigned long sz, void* ptr); 344 345 class MyClass { 346 public: 347 MyClass() {} 348 ~MyClass() {} 349 }; 350 351 void test_placement_new() { 352 int buffer[16]; 353 MyClass* obj = new (buffer) MyClass(); 354 } 355 356 // CHECK-LABEL: void test_placement_new_array() 357 // CHECK: [B2 (ENTRY)] 358 // CHECK-NEXT: Succs (1): B1 359 // CHECK: [B1] 360 // CHECK-NEXT: 1: int buffer[16]; 361 // CHECK-NEXT: 2: buffer 362 // CHECK-NEXT: 3: [B1.2] (ImplicitCastExpr, ArrayToPointerDecay, int *) 363 // CHECK-NEXT: 4: [B1.3] (ImplicitCastExpr, BitCast, void *) 364 // CHECK-NEXT: 5: 5 365 // CHECK-NEXT: 6: CFGNewAllocator(MyClass *) 366 // CHECK-NEXT: 7: (CXXConstructExpr, class MyClass) 367 // CHECK-NEXT: 8: new ([B1.4]) MyClass {{\[\[}}B1.5]] 368 // CHECK-NEXT: 9: MyClass *obj = new (buffer) MyClass [5]; 369 // CHECK-NEXT: Preds (1): B2 370 // CHECK-NEXT: Succs (1): B0 371 // CHECK: [B0 (EXIT)] 372 // CHECK-NEXT: Preds (1): B1 373 374 void test_placement_new_array() { 375 int buffer[16]; 376 MyClass* obj = new (buffer) MyClass[5]; 377 } 378 379 380 // CHECK-LABEL: void test_lifetime_extended_temporaries() 381 // CHECK: [B1] 382 struct LifetimeExtend { LifetimeExtend(int); ~LifetimeExtend(); }; 383 struct Aggregate { const LifetimeExtend a; const LifetimeExtend b; }; 384 struct AggregateRef { const LifetimeExtend &a; const LifetimeExtend &b; }; 385 void test_lifetime_extended_temporaries() { 386 // CHECK: LifetimeExtend(1); 387 // CHECK-NEXT: : 1 388 // CHECK-NEXT: ~LifetimeExtend() 389 // CHECK-NOT: ~LifetimeExtend() 390 { 391 const LifetimeExtend &l = LifetimeExtend(1); 392 1; 393 } 394 // CHECK: LifetimeExtend(2) 395 // CHECK-NEXT: ~LifetimeExtend() 396 // CHECK-NEXT: : 2 397 // CHECK-NOT: ~LifetimeExtend() 398 { 399 // No life-time extension. 400 const int &l = (LifetimeExtend(2), 2); 401 2; 402 } 403 // CHECK: LifetimeExtend(3) 404 // CHECK-NEXT: : 3 405 // CHECK-NEXT: ~LifetimeExtend() 406 // CHECK-NOT: ~LifetimeExtend() 407 { 408 // The last one is lifetime extended. 409 const LifetimeExtend &l = (3, LifetimeExtend(3)); 410 3; 411 } 412 // CHECK: LifetimeExtend(4) 413 // CHECK-NEXT: ~LifetimeExtend() 414 // CHECK-NEXT: ~LifetimeExtend() 415 // CHECK-NEXT: : 4 416 // CHECK-NOT: ~LifetimeExtend() 417 { 418 Aggregate a{LifetimeExtend(4), LifetimeExtend(4)}; 419 4; 420 } 421 // CHECK: LifetimeExtend(5) 422 // CHECK-NEXT: : 5 423 // FIXME: We want to emit the destructors of the lifetime 424 // extended variables here. 425 // CHECK-NOT: ~LifetimeExtend() 426 { 427 AggregateRef a{LifetimeExtend(5), LifetimeExtend(5)}; 428 5; 429 } 430 // FIXME: Add tests for lifetime extension via subobject 431 // references (LifetimeExtend().some_member). 432 } 433 434 435 // CHECK-LABEL: int *PR18472() 436 // CHECK: [B2 (ENTRY)] 437 // CHECK-NEXT: Succs (1): B1 438 // CHECK: [B1] 439 // CHECK-NEXT: 1: 0 440 // CHECK-NEXT: 2: [B1.1] (ImplicitCastExpr, NullToPointer, PR18472_t) 441 // CHECK-NEXT: 3: (PR18472_t)[B1.2] (CStyleCastExpr, NoOp, PR18472_t) 442 // CHECK-NEXT: 4: CFGNewAllocator(int *) 443 // CHECK-NEXT: 5: new (([B1.3])) int 444 // CHECK-NEXT: 6: return [B1.5]; 445 // CHECK-NEXT: Preds (1): B2 446 // CHECK-NEXT: Succs (1): B0 447 // CHECK: [B0 (EXIT)] 448 // CHECK-NEXT: Preds (1): B1 449 450 extern "C" typedef int *PR18472_t; 451 void *operator new (unsigned long, PR18472_t); 452 template <class T> T *PR18472() { 453 return new (((PR18472_t) 0)) T; 454 } 455 void PR18472_helper() { 456 PR18472<int>(); 457 } 458 459