1 // RUN: %clang_analyze_cc1 -analyzer-checker=core,optin.cplusplus.UninitializedObject \ 2 // RUN: -analyzer-config optin.cplusplus.UninitializedObject:Pedantic=true -DPEDANTIC \ 3 // RUN: -analyzer-config optin.cplusplus.UninitializedObject:CheckPointeeInitialization=true \ 4 // RUN: -std=c++11 -verify %s 5 6 // RUN: %clang_analyze_cc1 -analyzer-checker=core,optin.cplusplus.UninitializedObject \ 7 // RUN: -analyzer-config optin.cplusplus.UninitializedObject:CheckPointeeInitialization=true \ 8 // RUN: -std=c++11 -verify %s 9 10 //===----------------------------------------------------------------------===// 11 // Concrete location tests. 12 //===----------------------------------------------------------------------===// 13 14 struct ConcreteIntLocTest { 15 int *ptr; 16 17 ConcreteIntLocTest() : ptr(reinterpret_cast<int *>(0xDEADBEEF)) {} 18 }; 19 20 void fConcreteIntLocTest() { 21 ConcreteIntLocTest(); 22 } 23 24 //===----------------------------------------------------------------------===// 25 // nonloc::LocAsInteger tests. 26 //===----------------------------------------------------------------------===// 27 28 using intptr_t = unsigned long long; 29 30 struct LocAsIntegerTest { 31 intptr_t ptr; // expected-note{{uninitialized pointee 'reinterpret_cast<char *>(this->ptr)'}} 32 int dontGetFilteredByNonPedanticMode = 0; 33 34 LocAsIntegerTest(void *ptr) : ptr(reinterpret_cast<intptr_t>(ptr)) {} // expected-warning{{1 uninitialized field}} 35 }; 36 37 void fLocAsIntegerTest() { 38 char c; 39 LocAsIntegerTest t(&c); 40 } 41 42 //===----------------------------------------------------------------------===// 43 // Null pointer tests. 44 //===----------------------------------------------------------------------===// 45 46 class NullPtrTest { 47 struct RecordType { 48 int x; 49 int y; 50 }; 51 52 float *fptr = nullptr; 53 int *ptr; 54 RecordType *recPtr; 55 56 public: 57 NullPtrTest() : ptr(nullptr), recPtr(nullptr) { 58 // All good! 59 } 60 }; 61 62 void fNullPtrTest() { 63 NullPtrTest(); 64 } 65 66 //===----------------------------------------------------------------------===// 67 // Alloca tests. 68 //===----------------------------------------------------------------------===// 69 70 struct UntypedAllocaTest { 71 void *allocaPtr; 72 int dontGetFilteredByNonPedanticMode = 0; 73 74 UntypedAllocaTest() : allocaPtr(__builtin_alloca(sizeof(int))) { 75 // All good! 76 } 77 }; 78 79 void fUntypedAllocaTest() { 80 UntypedAllocaTest(); 81 } 82 83 struct TypedAllocaTest1 { 84 int *allocaPtr; // expected-note{{uninitialized pointee 'this->allocaPtr'}} 85 int dontGetFilteredByNonPedanticMode = 0; 86 87 TypedAllocaTest1() // expected-warning{{1 uninitialized field}} 88 : allocaPtr(static_cast<int *>(__builtin_alloca(sizeof(int)))) {} 89 }; 90 91 void fTypedAllocaTest1() { 92 TypedAllocaTest1(); 93 } 94 95 struct TypedAllocaTest2 { 96 int *allocaPtr; 97 int dontGetFilteredByNonPedanticMode = 0; 98 99 TypedAllocaTest2() 100 : allocaPtr(static_cast<int *>(__builtin_alloca(sizeof(int)))) { 101 *allocaPtr = 55555; 102 // All good! 103 } 104 }; 105 106 void fTypedAllocaTest2() { 107 TypedAllocaTest2(); 108 } 109 110 //===----------------------------------------------------------------------===// 111 // Heap pointer tests. 112 //===----------------------------------------------------------------------===// 113 114 class HeapPointerTest1 { 115 struct RecordType { 116 // TODO: we'd expect the note: {{uninitialized field 'this->recPtr->y'}} 117 int x; // no-note 118 // TODO: we'd expect the note: {{uninitialized field 'this->recPtr->y'}} 119 int y; // no-note 120 }; 121 // TODO: we'd expect the note: {{uninitialized pointee 'this->fptr'}} 122 float *fptr = new float; // no-note 123 // TODO: we'd expect the note: {{uninitialized pointee 'this->ptr'}} 124 int *ptr; // no-note 125 RecordType *recPtr; 126 127 public: 128 // TODO: we'd expect the warning: {{4 uninitialized fields}} 129 HeapPointerTest1() : ptr(new int), recPtr(new RecordType) { // no-note 130 } 131 }; 132 133 void fHeapPointerTest1() { 134 HeapPointerTest1(); 135 } 136 137 class HeapPointerTest2 { 138 struct RecordType { 139 int x; 140 int y; 141 }; 142 143 float *fptr = new float(); // initializes to 0 144 int *ptr; 145 RecordType *recPtr; 146 147 public: 148 HeapPointerTest2() : ptr(new int{25}), recPtr(new RecordType{26, 27}) { 149 // All good! 150 } 151 }; 152 153 void fHeapPointerTest2() { 154 HeapPointerTest2(); 155 } 156 157 //===----------------------------------------------------------------------===// 158 // Stack pointer tests. 159 //===----------------------------------------------------------------------===// 160 161 class StackPointerTest1 { 162 public: 163 struct RecordType { 164 int x; 165 int y; 166 }; 167 168 private: 169 int *ptr; 170 RecordType *recPtr; 171 172 public: 173 StackPointerTest1(int *_ptr, StackPointerTest1::RecordType *_recPtr) : ptr(_ptr), recPtr(_recPtr) { 174 // All good! 175 } 176 }; 177 178 void fStackPointerTest1() { 179 int ok_a = 28; 180 StackPointerTest1::RecordType ok_rec{29, 30}; 181 StackPointerTest1(&ok_a, &ok_rec); // 'a', 'rec.x', 'rec.y' uninitialized 182 } 183 184 #ifdef PEDANTIC 185 class StackPointerTest2 { 186 public: 187 struct RecordType { 188 int x; // expected-note{{uninitialized field 'this->recPtr->x'}} 189 int y; // expected-note{{uninitialized field 'this->recPtr->y'}} 190 }; 191 192 private: 193 int *ptr; // expected-note{{uninitialized pointee 'this->ptr'}} 194 RecordType *recPtr; 195 196 public: 197 StackPointerTest2(int *_ptr, RecordType *_recPtr) : ptr(_ptr), recPtr(_recPtr) { // expected-warning{{3 uninitialized fields}} 198 } 199 }; 200 201 void fStackPointerTest2() { 202 int a; 203 StackPointerTest2::RecordType rec; 204 StackPointerTest2(&a, &rec); // 'a', 'rec.x', 'rec.y' uninitialized 205 } 206 #else 207 class StackPointerTest2 { 208 public: 209 struct RecordType { 210 int x; 211 int y; 212 }; 213 214 private: 215 int *ptr; 216 RecordType *recPtr; 217 218 public: 219 StackPointerTest2(int *_ptr, RecordType *_recPtr) : ptr(_ptr), recPtr(_recPtr) { 220 } 221 }; 222 223 void fStackPointerTest2() { 224 int a; 225 StackPointerTest2::RecordType rec; 226 StackPointerTest2(&a, &rec); // 'a', 'rec.x', 'rec.y' uninitialized 227 } 228 #endif // PEDANTIC 229 230 class UninitPointerTest { 231 struct RecordType { 232 int x; 233 int y; 234 }; 235 236 int *ptr; // expected-note{{uninitialized pointer 'this->ptr'}} 237 RecordType *recPtr; 238 239 public: 240 UninitPointerTest() : recPtr(new RecordType{13, 13}) { // expected-warning{{1 uninitialized field}} 241 } 242 }; 243 244 void fUninitPointerTest() { 245 UninitPointerTest(); 246 } 247 248 struct CharPointerTest { 249 const char *str; 250 int dontGetFilteredByNonPedanticMode = 0; 251 252 CharPointerTest() : str("") {} 253 }; 254 255 void fCharPointerTest() { 256 CharPointerTest(); 257 } 258 259 struct VectorSizePointer { 260 VectorSizePointer() {} // expected-warning{{1 uninitialized field}} 261 __attribute__((__vector_size__(8))) int *x; // expected-note{{uninitialized pointer 'this->x'}} 262 int dontGetFilteredByNonPedanticMode = 0; 263 }; 264 265 void __vector_size__PointerTest() { 266 VectorSizePointer v; 267 } 268 269 struct VectorSizePointee { 270 using MyVectorType = __attribute__((__vector_size__(8))) int; 271 MyVectorType *x; 272 273 VectorSizePointee(decltype(x) x) : x(x) {} 274 }; 275 276 void __vector_size__PointeeTest() { 277 VectorSizePointee::MyVectorType i; 278 // TODO: Report v.x's pointee. 279 VectorSizePointee v(&i); 280 } 281 282 struct CyclicPointerTest1 { 283 int *ptr; // expected-note{{object references itself 'this->ptr'}} 284 int dontGetFilteredByNonPedanticMode = 0; 285 286 CyclicPointerTest1() : ptr(reinterpret_cast<int *>(&ptr)) {} // expected-warning{{1 uninitialized field}} 287 }; 288 289 void fCyclicPointerTest1() { 290 CyclicPointerTest1(); 291 } 292 293 struct CyclicPointerTest2 { 294 int **pptr; // expected-note{{object references itself 'this->pptr'}} 295 int dontGetFilteredByNonPedanticMode = 0; 296 297 CyclicPointerTest2() : pptr(reinterpret_cast<int **>(&pptr)) {} // expected-warning{{1 uninitialized field}} 298 }; 299 300 void fCyclicPointerTest2() { 301 CyclicPointerTest2(); 302 } 303 304 //===----------------------------------------------------------------------===// 305 // Void pointer tests. 306 //===----------------------------------------------------------------------===// 307 308 // Void pointer tests are mainly no-crash tests. 309 310 void *malloc(int size); 311 312 class VoidPointerTest1 { 313 void *vptr; 314 315 public: 316 VoidPointerTest1(void *vptr, char) : vptr(vptr) { 317 // All good! 318 } 319 }; 320 321 void fVoidPointerTest1() { 322 void *vptr = malloc(sizeof(int)); 323 VoidPointerTest1(vptr, char()); 324 } 325 326 class VoidPointerTest2 { 327 void **vpptr; 328 329 public: 330 VoidPointerTest2(void **vpptr, char) : vpptr(vpptr) { 331 // All good! 332 } 333 }; 334 335 void fVoidPointerTest2() { 336 void *vptr = malloc(sizeof(int)); 337 VoidPointerTest2(&vptr, char()); 338 } 339 340 class VoidPointerRRefTest1 { 341 void *&&vptrrref; // expected-note {{here}} 342 343 public: 344 VoidPointerRRefTest1(void *vptr, char) : vptrrref(static_cast<void *&&>(vptr)) { // expected-warning {{binding reference member 'vptrrref' to stack allocated parameter 'vptr'}} 345 // All good! 346 } 347 }; 348 349 void fVoidPointerRRefTest1() { 350 void *vptr = malloc(sizeof(int)); 351 VoidPointerRRefTest1(vptr, char()); 352 } 353 354 class VoidPointerRRefTest2 { 355 void **&&vpptrrref; // expected-note {{here}} 356 357 public: 358 VoidPointerRRefTest2(void **vptr, char) : vpptrrref(static_cast<void **&&>(vptr)) { // expected-warning {{binding reference member 'vpptrrref' to stack allocated parameter 'vptr'}} 359 // All good! 360 } 361 }; 362 363 void fVoidPointerRRefTest2() { 364 void *vptr = malloc(sizeof(int)); 365 VoidPointerRRefTest2(&vptr, char()); 366 } 367 368 class VoidPointerLRefTest { 369 void *&vptrrref; // expected-note {{here}} 370 371 public: 372 VoidPointerLRefTest(void *vptr, char) : vptrrref(static_cast<void *&>(vptr)) { // expected-warning {{binding reference member 'vptrrref' to stack allocated parameter 'vptr'}} 373 // All good! 374 } 375 }; 376 377 void fVoidPointerLRefTest() { 378 void *vptr = malloc(sizeof(int)); 379 VoidPointerLRefTest(vptr, char()); 380 } 381 382 struct CyclicVoidPointerTest { 383 void *vptr; // expected-note{{object references itself 'this->vptr'}} 384 int dontGetFilteredByNonPedanticMode = 0; 385 386 CyclicVoidPointerTest() : vptr(&vptr) {} // expected-warning{{1 uninitialized field}} 387 }; 388 389 void fCyclicVoidPointerTest() { 390 CyclicVoidPointerTest(); 391 } 392 393 struct IntDynTypedVoidPointerTest1 { 394 void *vptr; // expected-note{{uninitialized pointee 'static_cast<int *>(this->vptr)'}} 395 int dontGetFilteredByNonPedanticMode = 0; 396 397 IntDynTypedVoidPointerTest1(void *vptr) : vptr(vptr) {} // expected-warning{{1 uninitialized field}} 398 }; 399 400 void fIntDynTypedVoidPointerTest1() { 401 int a; 402 IntDynTypedVoidPointerTest1 tmp(&a); 403 } 404 405 struct RecordDynTypedVoidPointerTest { 406 struct RecordType { 407 int x; // expected-note{{uninitialized field 'static_cast<struct RecordDynTypedVoidPointerTest::RecordType *>(this->vptr)->x'}} 408 int y; // expected-note{{uninitialized field 'static_cast<struct RecordDynTypedVoidPointerTest::RecordType *>(this->vptr)->y'}} 409 }; 410 411 void *vptr; 412 int dontGetFilteredByNonPedanticMode = 0; 413 414 RecordDynTypedVoidPointerTest(void *vptr) : vptr(vptr) {} // expected-warning{{2 uninitialized fields}} 415 }; 416 417 void fRecordDynTypedVoidPointerTest() { 418 RecordDynTypedVoidPointerTest::RecordType a; 419 RecordDynTypedVoidPointerTest tmp(&a); 420 } 421 422 struct NestedNonVoidDynTypedVoidPointerTest { 423 struct RecordType { 424 int x; // expected-note{{uninitialized field 'static_cast<struct NestedNonVoidDynTypedVoidPointerTest::RecordType *>(this->vptr)->x'}} 425 int y; // expected-note{{uninitialized field 'static_cast<struct NestedNonVoidDynTypedVoidPointerTest::RecordType *>(this->vptr)->y'}} 426 void *vptr; // expected-note{{uninitialized pointee 'static_cast<char *>(static_cast<struct NestedNonVoidDynTypedVoidPointerTest::RecordType *>(this->vptr)->vptr)'}} 427 }; 428 429 void *vptr; 430 int dontGetFilteredByNonPedanticMode = 0; 431 432 NestedNonVoidDynTypedVoidPointerTest(void *vptr, void *c) : vptr(vptr) { 433 static_cast<RecordType *>(vptr)->vptr = c; // expected-warning{{3 uninitialized fields}} 434 } 435 }; 436 437 void fNestedNonVoidDynTypedVoidPointerTest() { 438 NestedNonVoidDynTypedVoidPointerTest::RecordType a; 439 char c; 440 NestedNonVoidDynTypedVoidPointerTest tmp(&a, &c); 441 } 442 443 //===----------------------------------------------------------------------===// 444 // Multipointer tests. 445 //===----------------------------------------------------------------------===// 446 447 #ifdef PEDANTIC 448 class MultiPointerTest1 { 449 public: 450 struct RecordType { 451 int x; 452 int y; 453 }; 454 455 private: 456 RecordType **mptr; // expected-note{{uninitialized pointee 'this->mptr'}} 457 458 public: 459 MultiPointerTest1(RecordType **p, int) : mptr(p) { // expected-warning{{1 uninitialized field}} 460 } 461 }; 462 463 void fMultiPointerTest1() { 464 MultiPointerTest1::RecordType *p1; 465 MultiPointerTest1::RecordType **mptr = &p1; 466 MultiPointerTest1(mptr, int()); // '*mptr' uninitialized 467 } 468 #else 469 class MultiPointerTest1 { 470 public: 471 struct RecordType { 472 int x; 473 int y; 474 }; 475 476 private: 477 RecordType **mptr; 478 479 public: 480 MultiPointerTest1(RecordType **p, int) : mptr(p) {} 481 }; 482 483 void fMultiPointerTest1() { 484 MultiPointerTest1::RecordType *p1; 485 MultiPointerTest1::RecordType **mptr = &p1; 486 MultiPointerTest1(mptr, int()); // '*mptr' uninitialized 487 } 488 #endif // PEDANTIC 489 490 #ifdef PEDANTIC 491 class MultiPointerTest2 { 492 public: 493 struct RecordType { 494 int x; // expected-note{{uninitialized field 'this->mptr->x'}} 495 int y; // expected-note{{uninitialized field 'this->mptr->y'}} 496 }; 497 498 private: 499 RecordType **mptr; 500 501 public: 502 MultiPointerTest2(RecordType **p, int) : mptr(p) { // expected-warning{{2 uninitialized fields}} 503 } 504 }; 505 506 void fMultiPointerTest2() { 507 MultiPointerTest2::RecordType i; 508 MultiPointerTest2::RecordType *p1 = &i; 509 MultiPointerTest2::RecordType **mptr = &p1; 510 MultiPointerTest2(mptr, int()); // '**mptr' uninitialized 511 } 512 #else 513 class MultiPointerTest2 { 514 public: 515 struct RecordType { 516 int x; 517 int y; 518 }; 519 520 private: 521 RecordType **mptr; 522 523 public: 524 MultiPointerTest2(RecordType **p, int) : mptr(p) { 525 } 526 }; 527 528 void fMultiPointerTest2() { 529 MultiPointerTest2::RecordType i; 530 MultiPointerTest2::RecordType *p1 = &i; 531 MultiPointerTest2::RecordType **mptr = &p1; 532 MultiPointerTest2(mptr, int()); // '**mptr' uninitialized 533 } 534 #endif // PEDANTIC 535 536 class MultiPointerTest3 { 537 public: 538 struct RecordType { 539 int x; 540 int y; 541 }; 542 543 private: 544 RecordType **mptr; 545 546 public: 547 MultiPointerTest3(RecordType **p, int) : mptr(p) { 548 // All good! 549 } 550 }; 551 552 void fMultiPointerTest3() { 553 MultiPointerTest3::RecordType i{31, 32}; 554 MultiPointerTest3::RecordType *p1 = &i; 555 MultiPointerTest3::RecordType **mptr = &p1; 556 MultiPointerTest3(mptr, int()); // '**mptr' uninitialized 557 } 558 559 //===----------------------------------------------------------------------===// 560 // Incomplete pointee tests. 561 //===----------------------------------------------------------------------===// 562 563 class IncompleteType; 564 565 struct IncompletePointeeTypeTest { 566 IncompleteType *pImpl; //no-crash 567 int dontGetFilteredByNonPedanticMode = 0; 568 569 IncompletePointeeTypeTest(IncompleteType *A) : pImpl(A) {} 570 }; 571 572 void fIncompletePointeeTypeTest(void *ptr) { 573 IncompletePointeeTypeTest(reinterpret_cast<IncompleteType *>(ptr)); 574 } 575 576 //===----------------------------------------------------------------------===// 577 // Function pointer tests. 578 //===----------------------------------------------------------------------===// 579 580 struct FunctionPointerWithDifferentDynTypeTest { 581 using Func1 = void *(*)(); 582 using Func2 = int *(*)(); 583 584 Func1 f; // no-crash 585 FunctionPointerWithDifferentDynTypeTest(Func2 f) : f((Func1)f) {} 586 }; 587 588 // Note that there isn't a function calling the constructor of 589 // FunctionPointerWithDifferentDynTypeTest, because a crash could only be 590 // reproduced without it. 591 592 //===----------------------------------------------------------------------===// 593 // Member pointer tests. 594 //===----------------------------------------------------------------------===// 595 596 struct UsefulFunctions { 597 int a, b; 598 599 void print() {} 600 void dump() {} 601 }; 602 603 #ifdef PEDANTIC 604 struct PointerToMemberFunctionTest1 { 605 void (UsefulFunctions::*f)(void); // expected-note{{uninitialized field 'this->f'}} 606 PointerToMemberFunctionTest1() {} 607 }; 608 609 void fPointerToMemberFunctionTest1() { 610 PointerToMemberFunctionTest1(); // expected-warning{{1 uninitialized field}} 611 } 612 613 struct PointerToMemberFunctionTest2 { 614 void (UsefulFunctions::*f)(void); 615 PointerToMemberFunctionTest2(void (UsefulFunctions::*f)(void)) : f(f) { 616 // All good! 617 } 618 }; 619 620 void fPointerToMemberFunctionTest2() { 621 void (UsefulFunctions::*f)(void) = &UsefulFunctions::print; 622 PointerToMemberFunctionTest2 a(f); 623 } 624 625 struct MultiPointerToMemberFunctionTest1 { 626 void (UsefulFunctions::**f)(void); // expected-note{{uninitialized pointer 'this->f'}} 627 MultiPointerToMemberFunctionTest1() {} 628 }; 629 630 void fMultiPointerToMemberFunctionTest1() { 631 MultiPointerToMemberFunctionTest1(); // expected-warning{{1 uninitialized field}} 632 } 633 634 struct MultiPointerToMemberFunctionTest2 { 635 void (UsefulFunctions::**f)(void); 636 MultiPointerToMemberFunctionTest2(void (UsefulFunctions::**f)(void)) : f(f) { 637 // All good! 638 } 639 }; 640 641 void fMultiPointerToMemberFunctionTest2() { 642 void (UsefulFunctions::*f)(void) = &UsefulFunctions::print; 643 MultiPointerToMemberFunctionTest2 a(&f); 644 } 645 646 struct PointerToMemberDataTest1 { 647 int UsefulFunctions::*d; // expected-note{{uninitialized field 'this->d'}} 648 PointerToMemberDataTest1() {} 649 }; 650 651 void fPointerToMemberDataTest1() { 652 PointerToMemberDataTest1(); // expected-warning{{1 uninitialized field}} 653 } 654 655 struct PointerToMemberDataTest2 { 656 int UsefulFunctions::*d; 657 PointerToMemberDataTest2(int UsefulFunctions::*d) : d(d) { 658 // All good! 659 } 660 }; 661 662 void fPointerToMemberDataTest2() { 663 int UsefulFunctions::*d = &UsefulFunctions::a; 664 PointerToMemberDataTest2 a(d); 665 } 666 667 struct MultiPointerToMemberDataTest1 { 668 int UsefulFunctions::**d; // expected-note{{uninitialized pointer 'this->d'}} 669 MultiPointerToMemberDataTest1() {} 670 }; 671 672 void fMultiPointerToMemberDataTest1() { 673 MultiPointerToMemberDataTest1(); // expected-warning{{1 uninitialized field}} 674 } 675 676 struct MultiPointerToMemberDataTest2 { 677 int UsefulFunctions::**d; 678 MultiPointerToMemberDataTest2(int UsefulFunctions::**d) : d(d) { 679 // All good! 680 } 681 }; 682 683 void fMultiPointerToMemberDataTest2() { 684 int UsefulFunctions::*d = &UsefulFunctions::a; 685 MultiPointerToMemberDataTest2 a(&d); 686 } 687 #endif // PEDANTIC 688 689 //===----------------------------------------------------------------------===// 690 // Tests for list-like records. 691 //===----------------------------------------------------------------------===// 692 693 class ListTest1 { 694 public: 695 struct Node { 696 Node *next = nullptr; // no crash 697 int i; 698 }; 699 700 private: 701 Node *head = nullptr; 702 703 public: 704 ListTest1() { 705 // All good! 706 } 707 }; 708 709 void fListTest1() { 710 ListTest1(); 711 } 712 713 class ListTest2 { 714 public: 715 struct Node { 716 Node *next = nullptr; 717 int i; // expected-note{{uninitialized field 'this->head->i'}} 718 }; 719 720 private: 721 Node *head = nullptr; 722 723 public: 724 ListTest2(Node *node, int) : head(node) { // expected-warning{{1 uninitialized field}} 725 } 726 }; 727 728 void fListTest2() { 729 ListTest2::Node n; 730 ListTest2(&n, int()); 731 } 732 733 class CyclicList { 734 public: 735 struct Node { 736 Node *next = nullptr; 737 int i; // expected-note{{uninitialized field 'this->head->i'}} 738 }; 739 740 private: 741 Node *head = nullptr; 742 743 public: 744 CyclicList(Node *node, int) : head(node) { // expected-warning{{1 uninitialized field}} 745 } 746 }; 747 748 void fCyclicList() { 749 /* 750 n3 751 / \ 752 this -- n1 -- n2 753 */ 754 755 CyclicList::Node n1; 756 CyclicList::Node n2; 757 n2.next = &n1; 758 n2.i = 50; 759 CyclicList::Node n3; 760 n3.next = &n2; 761 n3.i = 50; 762 n1.next = &n3; 763 // note that n1.i is uninitialized 764 CyclicList(&n1, int()); 765 } 766 767 struct RingListTest { 768 RingListTest *next; // no-crash 769 RingListTest() : next(this) {} 770 }; 771 772 void fRingListTest() { 773 RingListTest(); 774 } 775 776 //===----------------------------------------------------------------------===// 777 // Tests for classes containing references. 778 //===----------------------------------------------------------------------===// 779 780 class ReferenceTest1 { 781 public: 782 struct RecordType { 783 int x; 784 int y; 785 }; 786 787 private: 788 RecordType &lref; 789 RecordType &&rref; 790 791 public: 792 ReferenceTest1(RecordType &lref, RecordType &rref) : lref(lref), rref(static_cast<RecordType &&>(rref)) { 793 // All good! 794 } 795 }; 796 797 void fReferenceTest1() { 798 ReferenceTest1::RecordType d{33, 34}; 799 ReferenceTest1(d, d); 800 } 801 802 #ifdef PEDANTIC 803 class ReferenceTest2 { 804 public: 805 struct RecordType { 806 int x; // expected-note{{uninitialized field 'this->lref.x'}} 807 int y; // expected-note{{uninitialized field 'this->lref.y'}} 808 }; 809 810 private: 811 RecordType &lref; 812 RecordType &&rref; 813 814 public: 815 ReferenceTest2(RecordType &lref, RecordType &rref) 816 : lref(lref), rref(static_cast<RecordType &&>(rref)) { // expected-warning{{2 uninitialized fields}} 817 } 818 }; 819 820 void fReferenceTest2() { 821 ReferenceTest2::RecordType c; 822 ReferenceTest2(c, c); 823 } 824 #else 825 class ReferenceTest2 { 826 public: 827 struct RecordType { 828 int x; 829 int y; 830 }; 831 832 private: 833 RecordType &lref; 834 RecordType &&rref; 835 836 public: 837 ReferenceTest2(RecordType &lref, RecordType &rref) 838 : lref(lref), rref(static_cast<RecordType &&>(rref)) { 839 } 840 }; 841 842 void fReferenceTest2() { 843 ReferenceTest2::RecordType c; 844 ReferenceTest2(c, c); 845 } 846 #endif // PEDANTIC 847 848 class ReferenceTest3 { 849 public: 850 struct RecordType { 851 int x; // expected-note{{uninitialized field 'this->lref.x'}} 852 int y; // expected-note{{uninitialized field 'this->lref.y'}} 853 }; 854 855 private: 856 RecordType &lref; 857 RecordType &&rref; 858 859 public: 860 ReferenceTest3(RecordType &lref, RecordType &rref) 861 : lref(lref), rref(static_cast<RecordType &&>(rref)) { // expected-warning{{2 uninitialized fields}} 862 } 863 }; 864 865 void fReferenceTest3() { 866 ReferenceTest3::RecordType c, d{35, 36}; 867 ReferenceTest3(c, d); 868 } 869 870 class ReferenceTest4 { 871 public: 872 struct RecordType { 873 int x; // expected-note{{uninitialized field 'this->rref.x'}} 874 int y; // expected-note{{uninitialized field 'this->rref.y'}} 875 }; 876 877 private: 878 RecordType &lref; 879 RecordType &&rref; 880 881 public: 882 ReferenceTest4(RecordType &lref, RecordType &rref) 883 : lref(lref), rref(static_cast<RecordType &&>(rref)) { // expected-warning{{2 uninitialized fields}} 884 } 885 }; 886 887 void fReferenceTest5() { 888 ReferenceTest4::RecordType c, d{37, 38}; 889 ReferenceTest4(d, c); 890 } 891 892 //===----------------------------------------------------------------------===// 893 // Tests for objects containing multiple references to the same object. 894 //===----------------------------------------------------------------------===// 895 896 struct IntMultipleReferenceToSameObjectTest { 897 int *iptr; // expected-note{{uninitialized pointee 'this->iptr'}} 898 int &iref; // no-note, pointee of this->iref was already reported 899 900 int dontGetFilteredByNonPedanticMode = 0; 901 902 IntMultipleReferenceToSameObjectTest(int *i) : iptr(i), iref(*i) {} // expected-warning{{1 uninitialized field}} 903 }; 904 905 void fIntMultipleReferenceToSameObjectTest() { 906 int a; 907 IntMultipleReferenceToSameObjectTest Test(&a); 908 } 909 910 struct IntReferenceWrapper1 { 911 int &a; // expected-note{{uninitialized pointee 'this->a'}} 912 913 int dontGetFilteredByNonPedanticMode = 0; 914 915 IntReferenceWrapper1(int &a) : a(a) {} // expected-warning{{1 uninitialized field}} 916 }; 917 918 struct IntReferenceWrapper2 { 919 int &a; // no-note, pointee of this->a was already reported 920 921 int dontGetFilteredByNonPedanticMode = 0; 922 923 IntReferenceWrapper2(int &a) : a(a) {} // no-warning 924 }; 925 926 void fMultipleObjectsReferencingTheSameObjectTest() { 927 int a; 928 929 IntReferenceWrapper1 T1(a); 930 IntReferenceWrapper2 T2(a); 931 } 932