1 // RUN: %clang_analyze_cc1 -std=c++14 -verify %s \ 2 // RUN: -analyzer-checker=core \ 3 // RUN: -analyzer-checker=optin.cplusplus.UninitializedObject \ 4 // RUN: -analyzer-config optin.cplusplus.UninitializedObject:Pedantic=true -DPEDANTIC \ 5 // RUN: -analyzer-config \ 6 // RUN: optin.cplusplus.UninitializedObject:CheckPointeeInitialization=true 7 8 // RUN: %clang_analyze_cc1 -std=c++14 -verify %s \ 9 // RUN: -analyzer-checker=core \ 10 // RUN: -analyzer-checker=optin.cplusplus.UninitializedObject \ 11 // RUN: -analyzer-config \ 12 // RUN: optin.cplusplus.UninitializedObject:CheckPointeeInitialization=true 13 14 //===----------------------------------------------------------------------===// 15 // Default constructor test. 16 //===----------------------------------------------------------------------===// 17 18 class CompilerGeneratedConstructorTest { 19 int a, b, c, d, e, f, g, h, i, j; 20 21 public: 22 CompilerGeneratedConstructorTest() = default; 23 }; 24 25 void fCompilerGeneratedConstructorTest() { 26 CompilerGeneratedConstructorTest(); 27 } 28 29 #ifdef PEDANTIC 30 class DefaultConstructorTest { 31 int a; // expected-note{{uninitialized field 'this->a'}} 32 33 public: 34 DefaultConstructorTest(); 35 }; 36 37 DefaultConstructorTest::DefaultConstructorTest() = default; 38 39 void fDefaultConstructorTest() { 40 DefaultConstructorTest(); // expected-warning{{1 uninitialized field}} 41 } 42 #else 43 class DefaultConstructorTest { 44 int a; 45 46 public: 47 DefaultConstructorTest(); 48 }; 49 50 DefaultConstructorTest::DefaultConstructorTest() = default; 51 52 void fDefaultConstructorTest() { 53 DefaultConstructorTest(); 54 } 55 #endif // PEDANTIC 56 57 //===----------------------------------------------------------------------===// 58 // Initializer list test. 59 //===----------------------------------------------------------------------===// 60 61 class InitListTest1 { 62 int a; 63 int b; 64 65 public: 66 InitListTest1() 67 : a(1), 68 b(2) { 69 // All good! 70 } 71 }; 72 73 void fInitListTest1() { 74 InitListTest1(); 75 } 76 77 class InitListTest2 { 78 int a; 79 int b; // expected-note{{uninitialized field 'this->b'}} 80 81 public: 82 InitListTest2() 83 : a(3) {} // expected-warning{{1 uninitialized field}} 84 }; 85 86 void fInitListTest2() { 87 InitListTest2(); 88 } 89 90 class InitListTest3 { 91 int a; // expected-note{{uninitialized field 'this->a'}} 92 int b; 93 94 public: 95 InitListTest3() 96 : b(4) {} // expected-warning{{1 uninitialized field}} 97 }; 98 99 void fInitListTest3() { 100 InitListTest3(); 101 } 102 103 //===----------------------------------------------------------------------===// 104 // Constructor body test. 105 //===----------------------------------------------------------------------===// 106 107 class CtorBodyTest1 { 108 int a, b; 109 110 public: 111 CtorBodyTest1() { 112 a = 5; 113 b = 6; 114 // All good! 115 } 116 }; 117 118 void fCtorBodyTest1() { 119 CtorBodyTest1(); 120 } 121 122 class CtorBodyTest2 { 123 int a; 124 int b; // expected-note{{uninitialized field 'this->b'}} 125 126 public: 127 CtorBodyTest2() { 128 a = 7; // expected-warning{{1 uninitialized field}} 129 } 130 }; 131 132 void fCtorBodyTest2() { 133 CtorBodyTest2(); 134 } 135 136 class CtorBodyTest3 { 137 int a; // expected-note{{uninitialized field 'this->a'}} 138 int b; 139 140 public: 141 CtorBodyTest3() { 142 b = 8; // expected-warning{{1 uninitialized field}} 143 } 144 }; 145 146 void fCtorBodyTest3() { 147 CtorBodyTest3(); 148 } 149 150 #ifdef PEDANTIC 151 class CtorBodyTest4 { 152 int a; // expected-note{{uninitialized field 'this->a'}} 153 int b; // expected-note{{uninitialized field 'this->b'}} 154 155 public: 156 CtorBodyTest4() {} 157 }; 158 159 void fCtorBodyTest4() { 160 CtorBodyTest4(); // expected-warning{{2 uninitialized fields}} 161 } 162 #else 163 class CtorBodyTest4 { 164 int a; 165 int b; 166 167 public: 168 CtorBodyTest4() {} 169 }; 170 171 void fCtorBodyTest4() { 172 CtorBodyTest4(); 173 } 174 #endif 175 176 //===----------------------------------------------------------------------===// 177 // Constructor delegation test. 178 //===----------------------------------------------------------------------===// 179 180 class CtorDelegationTest1 { 181 int a; 182 int b; 183 184 public: 185 CtorDelegationTest1(int) 186 : a(9) { 187 // leaves 'b' unintialized, but we'll never check this function 188 } 189 190 CtorDelegationTest1() 191 : CtorDelegationTest1(int{}) { // Initializing 'a' 192 b = 10; 193 // All good! 194 } 195 }; 196 197 void fCtorDelegationTest1() { 198 CtorDelegationTest1(); 199 } 200 201 class CtorDelegationTest2 { 202 int a; // expected-note{{uninitialized field 'this->a'}} 203 int b; 204 205 public: 206 CtorDelegationTest2(int) 207 : b(11) { 208 // leaves 'a' unintialized, but we'll never check this function 209 } 210 211 CtorDelegationTest2() 212 : CtorDelegationTest2(int{}) { // expected-warning{{1 uninitialized field}} 213 } 214 }; 215 216 void fCtorDelegationTest2() { 217 CtorDelegationTest2(); 218 } 219 220 //===----------------------------------------------------------------------===// 221 // Tests for classes containing records. 222 //===----------------------------------------------------------------------===// 223 224 class ContainsRecordTest1 { 225 struct RecordType { 226 int x; 227 int y; 228 } rec; 229 int c, d; 230 231 public: 232 ContainsRecordTest1() 233 : rec({12, 13}), 234 c(14), 235 d(15) { 236 // All good! 237 } 238 }; 239 240 void fContainsRecordTest1() { 241 ContainsRecordTest1(); 242 } 243 244 class ContainsRecordTest2 { 245 struct RecordType { 246 int x; 247 int y; // expected-note{{uninitialized field 'this->rec.y'}} 248 } rec; 249 int c, d; 250 251 public: 252 ContainsRecordTest2() 253 : c(16), 254 d(17) { 255 rec.x = 18; // expected-warning{{1 uninitialized field}} 256 } 257 }; 258 259 void fContainsRecordTest2() { 260 ContainsRecordTest2(); 261 } 262 263 class ContainsRecordTest3 { 264 struct RecordType { 265 int x; // expected-note{{uninitialized field 'this->rec.x'}} 266 int y; // expected-note{{uninitialized field 'this->rec.y'}} 267 } rec; 268 int c, d; 269 270 public: 271 ContainsRecordTest3() 272 : c(19), 273 d(20) { // expected-warning{{2 uninitialized fields}} 274 } 275 }; 276 277 void fContainsRecordTest3() { 278 ContainsRecordTest3(); 279 } 280 281 class ContainsRecordTest4 { 282 struct RecordType { 283 int x; // expected-note{{uninitialized field 'this->rec.x'}} 284 int y; // expected-note{{uninitialized field 'this->rec.y'}} 285 } rec; 286 int c, d; // expected-note{{uninitialized field 'this->d'}} 287 288 public: 289 ContainsRecordTest4() 290 : c(19) { // expected-warning{{3 uninitialized fields}} 291 } 292 }; 293 294 void fContainsRecordTest4() { 295 ContainsRecordTest4(); 296 } 297 298 //===----------------------------------------------------------------------===// 299 // Tests for template classes. 300 //===----------------------------------------------------------------------===// 301 302 template <class T> 303 class IntTemplateClassTest1 { 304 T t; 305 int b; 306 307 public: 308 IntTemplateClassTest1(T i) { 309 b = 21; 310 t = i; 311 // All good! 312 } 313 }; 314 315 void fIntTemplateClassTest1() { 316 IntTemplateClassTest1<int>(22); 317 } 318 319 template <class T> 320 class IntTemplateClassTest2 { 321 T t; // expected-note{{uninitialized field 'this->t'}} 322 int b; 323 324 public: 325 IntTemplateClassTest2() { 326 b = 23; // expected-warning{{1 uninitialized field}} 327 } 328 }; 329 330 void fIntTemplateClassTest2() { 331 IntTemplateClassTest2<int>(); 332 } 333 334 struct Record { 335 int x; // expected-note{{uninitialized field 'this->t.x'}} 336 int y; // expected-note{{uninitialized field 'this->t.y'}} 337 }; 338 339 template <class T> 340 class RecordTemplateClassTest { 341 T t; 342 int b; 343 344 public: 345 RecordTemplateClassTest() { 346 b = 24; // expected-warning{{2 uninitialized fields}} 347 } 348 }; 349 350 void fRecordTemplateClassTest() { 351 RecordTemplateClassTest<Record>(); 352 } 353 354 //===----------------------------------------------------------------------===// 355 // Tests involving functions with unknown implementations. 356 //===----------------------------------------------------------------------===// 357 358 template <class T> 359 void mayInitialize(T &); 360 361 template <class T> 362 void wontInitialize(const T &); 363 364 class PassingToUnknownFunctionTest1 { 365 int a, b; 366 367 public: 368 PassingToUnknownFunctionTest1() { 369 mayInitialize(a); 370 mayInitialize(b); 371 // All good! 372 } 373 374 PassingToUnknownFunctionTest1(int) { 375 mayInitialize(a); 376 // All good! 377 } 378 379 PassingToUnknownFunctionTest1(int, int) { 380 mayInitialize(*this); 381 // All good! 382 } 383 }; 384 385 void fPassingToUnknownFunctionTest1() { 386 PassingToUnknownFunctionTest1(); 387 PassingToUnknownFunctionTest1(int()); 388 PassingToUnknownFunctionTest1(int(), int()); 389 } 390 391 class PassingToUnknownFunctionTest2 { 392 int a; // expected-note{{uninitialized field 'this->a'}} 393 int b; 394 395 public: 396 PassingToUnknownFunctionTest2() { 397 wontInitialize(a); 398 b = 4; // expected-warning{{1 uninitialized field}} 399 } 400 }; 401 402 void fPassingToUnknownFunctionTest2() { 403 PassingToUnknownFunctionTest2(); 404 } 405 406 //===----------------------------------------------------------------------===// 407 // Tests for classes containing unions. 408 //===----------------------------------------------------------------------===// 409 410 // FIXME: As of writing this checker, there is no good support for union types 411 // in the Static Analyzer. Here is non-exhaustive list of cases. 412 // Note that the rules for unions are different in C and C++. 413 // http://lists.llvm.org/pipermail/cfe-dev/2017-March/052910.html 414 415 class ContainsSimpleUnionTest1 { 416 union SimpleUnion { 417 float uf; 418 int ui; 419 char uc; 420 } u; 421 422 public: 423 ContainsSimpleUnionTest1() { 424 u.uf = 3.14; 425 // All good! 426 } 427 }; 428 429 void fContainsSimpleUnionTest1() { 430 ContainsSimpleUnionTest1(); 431 } 432 433 class ContainsSimpleUnionTest2 { 434 union SimpleUnion { 435 float uf; 436 int ui; 437 char uc; 438 // TODO: we'd expect the note: {{uninitialized field 'this->u'}} 439 } u; // no-note 440 441 public: 442 ContainsSimpleUnionTest2() {} 443 }; 444 445 void fContainsSimpleUnionTest2() { 446 // TODO: we'd expect the warning: {{1 uninitialized field}} 447 ContainsSimpleUnionTest2(); // no-warning 448 } 449 450 class UnionPointerTest1 { 451 public: 452 union SimpleUnion { 453 float uf; 454 int ui; 455 char uc; 456 }; 457 458 private: 459 SimpleUnion *uptr; 460 461 public: 462 UnionPointerTest1(SimpleUnion *uptr, int) : uptr(uptr) { 463 // All good! 464 } 465 }; 466 467 void fUnionPointerTest1() { 468 UnionPointerTest1::SimpleUnion u; 469 u.uf = 41; 470 UnionPointerTest1(&u, int()); 471 } 472 473 class UnionPointerTest2 { 474 public: 475 union SimpleUnion { 476 float uf; 477 int ui; 478 char uc; 479 }; 480 481 private: 482 // TODO: we'd expect the note: {{uninitialized field 'this->uptr'}} 483 SimpleUnion *uptr; // no-note 484 485 public: 486 UnionPointerTest2(SimpleUnion *uptr, char) : uptr(uptr) {} 487 }; 488 489 void fUnionPointerTest2() { 490 UnionPointerTest2::SimpleUnion u; 491 // TODO: we'd expect the warning: {{1 uninitialized field}} 492 UnionPointerTest2(&u, int()); // no-warning 493 } 494 495 class ContainsUnionWithRecordTest1 { 496 union UnionWithRecord { 497 struct RecordType { 498 int x; 499 int y; 500 } us; 501 double ud; 502 long ul; 503 504 UnionWithRecord(){}; 505 } u; 506 507 public: 508 ContainsUnionWithRecordTest1() { 509 u.ud = 3.14; 510 // All good! 511 } 512 }; 513 514 void fContainsUnionWithRecordTest1() { 515 ContainsUnionWithRecordTest1(); 516 } 517 518 class ContainsUnionWithRecordTest2 { 519 union UnionWithRecord { 520 struct RecordType { 521 int x; 522 int y; 523 } us; 524 double ud; 525 long ul; 526 527 UnionWithRecord(){}; 528 } u; 529 530 public: 531 ContainsUnionWithRecordTest2() { 532 u.us = UnionWithRecord::RecordType{42, 43}; 533 // All good! 534 } 535 }; 536 537 void fContainsUnionWithRecordTest2() { 538 ContainsUnionWithRecordTest1(); 539 } 540 541 class ContainsUnionWithRecordTest3 { 542 union UnionWithRecord { 543 struct RecordType { 544 int x; 545 int y; 546 } us; 547 double ud; 548 long ul; 549 550 UnionWithRecord(){}; 551 // TODO: we'd expect the note: {{uninitialized field 'this->u'}} 552 } u; // no-note 553 554 public: 555 ContainsUnionWithRecordTest3() { 556 UnionWithRecord::RecordType rec; 557 rec.x = 44; 558 // TODO: we'd expect the warning: {{1 uninitialized field}} 559 u.us = rec; // no-warning 560 } 561 }; 562 563 void fContainsUnionWithRecordTest3() { 564 ContainsUnionWithRecordTest3(); 565 } 566 567 class ContainsUnionWithSimpleUnionTest1 { 568 union UnionWithSimpleUnion { 569 union SimpleUnion { 570 float uf; 571 int ui; 572 char uc; 573 } usu; 574 long ul; 575 unsigned uu; 576 } u; 577 578 public: 579 ContainsUnionWithSimpleUnionTest1() { 580 u.usu.ui = 5; 581 // All good! 582 } 583 }; 584 585 void fContainsUnionWithSimpleUnionTest1() { 586 ContainsUnionWithSimpleUnionTest1(); 587 } 588 589 class ContainsUnionWithSimpleUnionTest2 { 590 union UnionWithSimpleUnion { 591 union SimpleUnion { 592 float uf; 593 int ui; 594 char uc; 595 } usu; 596 long ul; 597 unsigned uu; 598 // TODO: we'd expect the note: {{uninitialized field 'this->u'}} 599 } u; // no-note 600 601 public: 602 ContainsUnionWithSimpleUnionTest2() {} 603 }; 604 605 void fContainsUnionWithSimpleUnionTest2() { 606 // TODO: we'd expect the warning: {{1 uninitialized field}} 607 ContainsUnionWithSimpleUnionTest2(); // no-warning 608 } 609 610 //===----------------------------------------------------------------------===// 611 // Zero initialization tests. 612 //===----------------------------------------------------------------------===// 613 614 struct GlobalVariableTest { 615 int i; 616 617 GlobalVariableTest() {} 618 }; 619 620 GlobalVariableTest gvt; // no-warning 621 622 //===----------------------------------------------------------------------===// 623 // Copy and move constructor tests. 624 //===----------------------------------------------------------------------===// 625 626 template <class T> 627 void funcToSquelchCompilerWarnings(const T &t); 628 629 #ifdef PEDANTIC 630 struct CopyConstructorTest { 631 int i; // expected-note{{uninitialized field 'this->i'}} 632 633 CopyConstructorTest() : i(1337) {} 634 CopyConstructorTest(const CopyConstructorTest &other) {} 635 }; 636 637 void fCopyConstructorTest() { 638 CopyConstructorTest cct; 639 CopyConstructorTest copy = cct; // expected-warning{{1 uninitialized field}} 640 funcToSquelchCompilerWarnings(copy); 641 } 642 #else 643 struct CopyConstructorTest { 644 int i; 645 646 CopyConstructorTest() : i(1337) {} 647 CopyConstructorTest(const CopyConstructorTest &other) {} 648 }; 649 650 void fCopyConstructorTest() { 651 CopyConstructorTest cct; 652 CopyConstructorTest copy = cct; 653 funcToSquelchCompilerWarnings(copy); 654 } 655 #endif // PEDANTIC 656 657 struct MoveConstructorTest { 658 // TODO: we'd expect the note: {{uninitialized field 'this->i'}} 659 int i; // no-note 660 661 MoveConstructorTest() : i(1337) {} 662 MoveConstructorTest(const CopyConstructorTest &other) = delete; 663 MoveConstructorTest(const CopyConstructorTest &&other) {} 664 }; 665 666 void fMoveConstructorTest() { 667 MoveConstructorTest cct; 668 // TODO: we'd expect the warning: {{1 uninitialized field}} 669 MoveConstructorTest copy(static_cast<MoveConstructorTest &&>(cct)); // no-warning 670 funcToSquelchCompilerWarnings(copy); 671 } 672 673 //===----------------------------------------------------------------------===// 674 // Array tests. 675 //===----------------------------------------------------------------------===// 676 677 struct IntArrayTest { 678 int arr[256]; 679 680 IntArrayTest() { 681 // All good! 682 } 683 }; 684 685 void fIntArrayTest() { 686 IntArrayTest(); 687 } 688 689 struct RecordTypeArrayTest { 690 struct RecordType { 691 int x, y; 692 } arr[256]; 693 694 RecordTypeArrayTest() { 695 // All good! 696 } 697 }; 698 699 void fRecordTypeArrayTest() { 700 RecordTypeArrayTest(); 701 } 702 703 template <class T> 704 class CharArrayPointerTest { 705 T *t; // no-crash 706 707 public: 708 CharArrayPointerTest(T *t, int) : t(t) {} 709 }; 710 711 void fCharArrayPointerTest() { 712 char str[16] = "012345678912345"; 713 CharArrayPointerTest<char[16]>(&str, int()); 714 } 715 716 //===----------------------------------------------------------------------===// 717 // Memset tests. 718 //===----------------------------------------------------------------------===// 719 720 struct MemsetTest1 { 721 int a, b, c; 722 723 MemsetTest1() { 724 __builtin_memset(this, 0, sizeof(decltype(*this))); 725 } 726 }; 727 728 void fMemsetTest1() { 729 MemsetTest1(); 730 } 731 732 struct MemsetTest2 { 733 int a; 734 735 MemsetTest2() { 736 __builtin_memset(&a, 0, sizeof(int)); 737 } 738 }; 739 740 void fMemsetTest2() { 741 MemsetTest2(); 742 } 743 744 //===----------------------------------------------------------------------===// 745 // Lambda tests. 746 //===----------------------------------------------------------------------===// 747 748 template <class Callable> 749 struct LambdaThisTest { 750 Callable functor; 751 752 LambdaThisTest(const Callable &functor, int) : functor(functor) { 753 // All good! 754 } 755 }; 756 757 struct HasCapturableThis { 758 void fLambdaThisTest() { 759 auto isEven = [this](int a) { return a % 2 == 0; }; // no-crash 760 LambdaThisTest<decltype(isEven)>(isEven, int()); 761 } 762 }; 763 764 template <class Callable> 765 struct LambdaTest1 { 766 Callable functor; 767 768 LambdaTest1(const Callable &functor, int) : functor(functor) { 769 // All good! 770 } 771 }; 772 773 void fLambdaTest1() { 774 auto isEven = [](int a) { return a % 2 == 0; }; 775 LambdaTest1<decltype(isEven)>(isEven, int()); 776 } 777 778 #ifdef PEDANTIC 779 template <class Callable> 780 struct LambdaTest2 { 781 Callable functor; 782 783 LambdaTest2(const Callable &functor, int) : functor(functor) {} // expected-warning{{1 uninitialized field}} 784 }; 785 786 void fLambdaTest2() { 787 int b; 788 auto equals = [&b](int a) { return a == b; }; // expected-note{{uninitialized pointee 'this->functor./*captured variable*/b'}} 789 LambdaTest2<decltype(equals)>(equals, int()); 790 } 791 #else 792 template <class Callable> 793 struct LambdaTest2 { 794 Callable functor; 795 796 LambdaTest2(const Callable &functor, int) : functor(functor) {} 797 }; 798 799 void fLambdaTest2() { 800 int b; 801 auto equals = [&b](int a) { return a == b; }; 802 LambdaTest2<decltype(equals)>(equals, int()); 803 } 804 #endif //PEDANTIC 805 806 #ifdef PEDANTIC 807 namespace LT3Detail { 808 809 struct RecordType { 810 int x; // expected-note{{uninitialized field 'this->functor./*captured variable*/rec1.x'}} 811 int y; // expected-note{{uninitialized field 'this->functor./*captured variable*/rec1.y'}} 812 }; 813 814 } // namespace LT3Detail 815 template <class Callable> 816 struct LambdaTest3 { 817 Callable functor; 818 819 LambdaTest3(const Callable &functor, int) : functor(functor) {} // expected-warning{{2 uninitialized fields}} 820 }; 821 822 void fLambdaTest3() { 823 LT3Detail::RecordType rec1; 824 auto equals = [&rec1](LT3Detail::RecordType rec2) { 825 return rec1.x == rec2.x; 826 }; 827 LambdaTest3<decltype(equals)>(equals, int()); 828 } 829 #else 830 namespace LT3Detail { 831 832 struct RecordType { 833 int x; 834 int y; 835 }; 836 837 } // namespace LT3Detail 838 template <class Callable> 839 struct LambdaTest3 { 840 Callable functor; 841 842 LambdaTest3(const Callable &functor, int) : functor(functor) {} 843 }; 844 845 void fLambdaTest3() { 846 LT3Detail::RecordType rec1; 847 auto equals = [&rec1](LT3Detail::RecordType rec2) { 848 return rec1.x == rec2.x; 849 }; 850 LambdaTest3<decltype(equals)>(equals, int()); 851 } 852 #endif //PEDANTIC 853 854 template <class Callable> 855 struct MultipleLambdaCapturesTest1 { 856 Callable functor; 857 int dontGetFilteredByNonPedanticMode = 0; 858 859 MultipleLambdaCapturesTest1(const Callable &functor, int) : functor(functor) {} // expected-warning{{2 uninitialized field}} 860 }; 861 862 void fMultipleLambdaCapturesTest1() { 863 int b1, b2 = 3, b3; 864 auto equals = [&b1, &b2, &b3](int a) { return a == b1 == b2 == b3; }; // expected-note{{uninitialized pointee 'this->functor./*captured variable*/b1'}} 865 // expected-note@-1{{uninitialized pointee 'this->functor./*captured variable*/b3'}} 866 MultipleLambdaCapturesTest1<decltype(equals)>(equals, int()); 867 } 868 869 template <class Callable> 870 struct MultipleLambdaCapturesTest2 { 871 Callable functor; 872 int dontGetFilteredByNonPedanticMode = 0; 873 874 MultipleLambdaCapturesTest2(const Callable &functor, int) : functor(functor) {} // expected-warning{{1 uninitialized field}} 875 }; 876 877 void fMultipleLambdaCapturesTest2() { 878 int b1, b2 = 3, b3; 879 auto equals = [b1, &b2, &b3](int a) { return a == b1 == b2 == b3; }; // expected-note{{uninitialized pointee 'this->functor./*captured variable*/b3'}} 880 MultipleLambdaCapturesTest2<decltype(equals)>(equals, int()); 881 } 882 883 struct LambdaWrapper { 884 void *func; // no-crash 885 int dontGetFilteredByNonPedanticMode = 0; 886 887 LambdaWrapper(void *ptr) : func(ptr) {} // expected-warning{{1 uninitialized field}} 888 }; 889 890 struct ThisCapturingLambdaFactory { 891 int a; // expected-note{{uninitialized field 'static_cast<decltype(a.ret()) *>(this->func)->/*'this' capture*/->a'}} 892 893 auto ret() { 894 return [this] { (void)this; }; 895 } 896 }; 897 898 void fLambdaFieldWithInvalidThisCapture() { 899 void *ptr; 900 { 901 ThisCapturingLambdaFactory a; 902 decltype(a.ret()) lambda = a.ret(); 903 ptr = λ 904 } 905 LambdaWrapper t(ptr); 906 } 907 908 //===----------------------------------------------------------------------===// 909 // System header tests. 910 //===----------------------------------------------------------------------===// 911 912 #include "Inputs/system-header-simulator-for-cxx-uninitialized-object.h" 913 914 struct SystemHeaderTest1 { 915 RecordInSystemHeader rec; // defined in the system header simulator 916 917 SystemHeaderTest1() { 918 // All good! 919 } 920 }; 921 922 void fSystemHeaderTest1() { 923 SystemHeaderTest1(); 924 } 925 926 #ifdef PEDANTIC 927 struct SystemHeaderTest2 { 928 struct RecordType { 929 int x; // expected-note{{uninitialized field 'this->container.t.x}} 930 int y; // expected-note{{uninitialized field 'this->container.t.y}} 931 }; 932 ContainerInSystemHeader<RecordType> container; 933 934 SystemHeaderTest2(RecordType &rec, int) : container(rec) {} // expected-warning{{2 uninitialized fields}} 935 }; 936 937 void fSystemHeaderTest2() { 938 SystemHeaderTest2::RecordType rec; 939 SystemHeaderTest2(rec, int()); 940 } 941 #else 942 struct SystemHeaderTest2 { 943 struct RecordType { 944 int x; 945 int y; 946 }; 947 ContainerInSystemHeader<RecordType> container; 948 949 SystemHeaderTest2(RecordType &rec, int) : container(rec) {} 950 }; 951 952 void fSystemHeaderTest2() { 953 SystemHeaderTest2::RecordType rec; 954 SystemHeaderTest2(rec, int()); 955 } 956 #endif //PEDANTIC 957 958 //===----------------------------------------------------------------------===// 959 // Incomplete type tests. 960 //===----------------------------------------------------------------------===// 961 962 struct IncompleteTypeTest1 { 963 struct RecordType; 964 // no-crash 965 RecordType *recptr; // expected-note{{uninitialized pointer 'this->recptr}} 966 int dontGetFilteredByNonPedanticMode = 0; 967 968 IncompleteTypeTest1() {} // expected-warning{{1 uninitialized field}} 969 }; 970 971 void fIncompleteTypeTest1() { 972 IncompleteTypeTest1(); 973 } 974 975 struct IncompleteTypeTest2 { 976 struct RecordType; 977 RecordType *recptr; // no-crash 978 int dontGetFilteredByNonPedanticMode = 0; 979 980 RecordType *recordTypeFactory(); 981 982 IncompleteTypeTest2() : recptr(recordTypeFactory()) {} 983 }; 984 985 void fIncompleteTypeTest2() { 986 IncompleteTypeTest2(); 987 } 988 989 struct IncompleteTypeTest3 { 990 struct RecordType; 991 RecordType &recref; // no-crash 992 int dontGetFilteredByNonPedanticMode = 0; 993 994 RecordType &recordTypeFactory(); 995 996 IncompleteTypeTest3() : recref(recordTypeFactory()) {} 997 }; 998 999 void fIncompleteTypeTest3() { 1000 IncompleteTypeTest3(); 1001 } 1002 1003 //===----------------------------------------------------------------------===// 1004 // Builtin type or enumeration type related tests. 1005 //===----------------------------------------------------------------------===// 1006 1007 struct IntegralTypeTest { 1008 int a; // expected-note{{uninitialized field 'this->a'}} 1009 int dontGetFilteredByNonPedanticMode = 0; 1010 1011 IntegralTypeTest() {} // expected-warning{{1 uninitialized field}} 1012 }; 1013 1014 void fIntegralTypeTest() { 1015 IntegralTypeTest(); 1016 } 1017 1018 struct FloatingTypeTest { 1019 float a; // expected-note{{uninitialized field 'this->a'}} 1020 int dontGetFilteredByNonPedanticMode = 0; 1021 1022 FloatingTypeTest() {} // expected-warning{{1 uninitialized field}} 1023 }; 1024 1025 void fFloatingTypeTest() { 1026 FloatingTypeTest(); 1027 } 1028 1029 struct NullptrTypeTypeTest { 1030 decltype(nullptr) a; // expected-note{{uninitialized field 'this->a'}} 1031 int dontGetFilteredByNonPedanticMode = 0; 1032 1033 NullptrTypeTypeTest() {} // expected-warning{{1 uninitialized field}} 1034 }; 1035 1036 void fNullptrTypeTypeTest() { 1037 NullptrTypeTypeTest(); 1038 } 1039 1040 struct EnumTest { 1041 enum Enum { 1042 A, 1043 B 1044 } enum1; // expected-note{{uninitialized field 'this->enum1'}} 1045 enum class Enum2 { 1046 A, 1047 B 1048 } enum2; // expected-note{{uninitialized field 'this->enum2'}} 1049 int dontGetFilteredByNonPedanticMode = 0; 1050 1051 EnumTest() {} // expected-warning{{2 uninitialized fields}} 1052 }; 1053 1054 void fEnumTest() { 1055 EnumTest(); 1056 } 1057 1058 //===----------------------------------------------------------------------===// 1059 // Tests for constructor calls within another cunstructor, without the two 1060 // records being in any relation. 1061 //===----------------------------------------------------------------------===// 1062 1063 void halt() __attribute__((__noreturn__)); 1064 void assert(int b) { 1065 if (!b) 1066 halt(); 1067 } 1068 1069 // While a singleton would make more sense as a static variable, that would zero 1070 // initialize all of its fields, hence the not too practical implementation. 1071 struct Singleton { 1072 int i; // expected-note{{uninitialized field 'this->i'}} 1073 int dontGetFilteredByNonPedanticMode = 0; 1074 1075 Singleton() { 1076 assert(!isInstantiated); 1077 isInstantiated = true; // expected-warning{{1 uninitialized field}} 1078 } 1079 1080 ~Singleton() { 1081 isInstantiated = false; 1082 } 1083 1084 static bool isInstantiated; 1085 }; 1086 1087 bool Singleton::isInstantiated = false; 1088 1089 struct SingletonTest { 1090 int dontGetFilteredByNonPedanticMode = 0; 1091 1092 SingletonTest() { 1093 Singleton(); 1094 } 1095 }; 1096 1097 void fSingletonTest() { 1098 SingletonTest(); 1099 } 1100 1101 //===----------------------------------------------------------------------===// 1102 // C++11 member initializer tests. 1103 //===----------------------------------------------------------------------===// 1104 1105 struct CXX11MemberInitTest1 { 1106 int a = 3; 1107 int b; 1108 CXX11MemberInitTest1() : b(2) { 1109 // All good! 1110 } 1111 }; 1112 1113 void fCXX11MemberInitTest1() { 1114 CXX11MemberInitTest1(); 1115 } 1116 1117 struct CXX11MemberInitTest2 { 1118 struct RecordType { 1119 // TODO: we'd expect the note: {{uninitialized field 'this->rec.a'}} 1120 int a; // no-note 1121 // TODO: we'd expect the note: {{uninitialized field 'this->rec.b'}} 1122 int b; // no-note 1123 1124 RecordType(int) {} 1125 }; 1126 1127 RecordType rec = RecordType(int()); 1128 int dontGetFilteredByNonPedanticMode = 0; 1129 1130 CXX11MemberInitTest2() {} 1131 }; 1132 1133 void fCXX11MemberInitTest2() { 1134 // TODO: we'd expect the warning: {{2 uninitializeds field}} 1135 CXX11MemberInitTest2(); // no-warning 1136 } 1137 1138 //===----------------------------------------------------------------------===// 1139 // "Esoteric" primitive type tests. 1140 //===----------------------------------------------------------------------===// 1141 1142 struct MyAtomicInt { 1143 _Atomic(int) x; // expected-note{{uninitialized field 'this->x'}} 1144 int dontGetFilteredByNonPedanticMode = 0; 1145 1146 MyAtomicInt() {} // expected-warning{{1 uninitialized field}} 1147 }; 1148 1149 void _AtomicTest() { 1150 MyAtomicInt b; 1151 } 1152 1153 struct VectorSizeLong { 1154 VectorSizeLong() {} 1155 __attribute__((__vector_size__(16))) long x; 1156 }; 1157 1158 void __vector_size__LongTest() { 1159 // TODO: Warn for v.x. 1160 VectorSizeLong v; 1161 v.x[0] = 0; 1162 } 1163 1164 struct ComplexUninitTest { 1165 ComplexUninitTest() {} 1166 __complex__ float x; 1167 __complex__ int y; 1168 }; 1169 1170 struct ComplexInitTest { 1171 ComplexInitTest() { 1172 x = {1.0f, 1.0f}; 1173 y = {1, 1}; 1174 } 1175 __complex__ float x; 1176 __complex__ int y; 1177 }; 1178 1179 void fComplexTest() { 1180 ComplexInitTest x; 1181 1182 // TODO: we should emit a warning for x2.x and x2.y. 1183 ComplexUninitTest x2; 1184 } 1185