1 // RUN: %clang_analyze_cc1 -analyzer-checker=core,alpha.cplusplus.UninitializedObject \ 2 // RUN: -analyzer-config alpha.cplusplus.UninitializedObject:Pedantic=true -DPEDANTIC \ 3 // RUN: -analyzer-config alpha.cplusplus.UninitializedObject:CheckPointeeInitialization=true \ 4 // RUN: -std=c++11 -verify %s 5 6 // RUN: %clang_analyze_cc1 -analyzer-checker=core,alpha.cplusplus.UninitializedObject \ 7 // RUN: -analyzer-config alpha.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 CyclicPointerTest1 { 260 int *ptr; // expected-note{{object references itself 'this->ptr'}} 261 int dontGetFilteredByNonPedanticMode = 0; 262 263 CyclicPointerTest1() : ptr(reinterpret_cast<int *>(&ptr)) {} // expected-warning{{1 uninitialized field}} 264 }; 265 266 void fCyclicPointerTest1() { 267 CyclicPointerTest1(); 268 } 269 270 struct CyclicPointerTest2 { 271 int **pptr; // expected-note{{object references itself 'this->pptr'}} 272 int dontGetFilteredByNonPedanticMode = 0; 273 274 CyclicPointerTest2() : pptr(reinterpret_cast<int **>(&pptr)) {} // expected-warning{{1 uninitialized field}} 275 }; 276 277 void fCyclicPointerTest2() { 278 CyclicPointerTest2(); 279 } 280 281 //===----------------------------------------------------------------------===// 282 // Void pointer tests. 283 //===----------------------------------------------------------------------===// 284 285 // Void pointer tests are mainly no-crash tests. 286 287 void *malloc(int size); 288 289 class VoidPointerTest1 { 290 void *vptr; 291 292 public: 293 VoidPointerTest1(void *vptr, char) : vptr(vptr) { 294 // All good! 295 } 296 }; 297 298 void fVoidPointerTest1() { 299 void *vptr = malloc(sizeof(int)); 300 VoidPointerTest1(vptr, char()); 301 } 302 303 class VoidPointerTest2 { 304 void **vpptr; 305 306 public: 307 VoidPointerTest2(void **vpptr, char) : vpptr(vpptr) { 308 // All good! 309 } 310 }; 311 312 void fVoidPointerTest2() { 313 void *vptr = malloc(sizeof(int)); 314 VoidPointerTest2(&vptr, char()); 315 } 316 317 class VoidPointerRRefTest1 { 318 void *&&vptrrref; // expected-note {{here}} 319 320 public: 321 VoidPointerRRefTest1(void *vptr, char) : vptrrref(static_cast<void *&&>(vptr)) { // expected-warning {{binding reference member 'vptrrref' to stack allocated parameter 'vptr'}} 322 // All good! 323 } 324 }; 325 326 void fVoidPointerRRefTest1() { 327 void *vptr = malloc(sizeof(int)); 328 VoidPointerRRefTest1(vptr, char()); 329 } 330 331 class VoidPointerRRefTest2 { 332 void **&&vpptrrref; // expected-note {{here}} 333 334 public: 335 VoidPointerRRefTest2(void **vptr, char) : vpptrrref(static_cast<void **&&>(vptr)) { // expected-warning {{binding reference member 'vpptrrref' to stack allocated parameter 'vptr'}} 336 // All good! 337 } 338 }; 339 340 void fVoidPointerRRefTest2() { 341 void *vptr = malloc(sizeof(int)); 342 VoidPointerRRefTest2(&vptr, char()); 343 } 344 345 class VoidPointerLRefTest { 346 void *&vptrrref; // expected-note {{here}} 347 348 public: 349 VoidPointerLRefTest(void *vptr, char) : vptrrref(static_cast<void *&>(vptr)) { // expected-warning {{binding reference member 'vptrrref' to stack allocated parameter 'vptr'}} 350 // All good! 351 } 352 }; 353 354 void fVoidPointerLRefTest() { 355 void *vptr = malloc(sizeof(int)); 356 VoidPointerLRefTest(vptr, char()); 357 } 358 359 struct CyclicVoidPointerTest { 360 void *vptr; // expected-note{{object references itself 'this->vptr'}} 361 int dontGetFilteredByNonPedanticMode = 0; 362 363 CyclicVoidPointerTest() : vptr(&vptr) {} // expected-warning{{1 uninitialized field}} 364 }; 365 366 void fCyclicVoidPointerTest() { 367 CyclicVoidPointerTest(); 368 } 369 370 struct IntDynTypedVoidPointerTest1 { 371 void *vptr; // expected-note{{uninitialized pointee 'static_cast<int *>(this->vptr)'}} 372 int dontGetFilteredByNonPedanticMode = 0; 373 374 IntDynTypedVoidPointerTest1(void *vptr) : vptr(vptr) {} // expected-warning{{1 uninitialized field}} 375 }; 376 377 void fIntDynTypedVoidPointerTest1() { 378 int a; 379 IntDynTypedVoidPointerTest1 tmp(&a); 380 } 381 382 struct RecordDynTypedVoidPointerTest { 383 struct RecordType { 384 int x; // expected-note{{uninitialized field 'static_cast<struct RecordDynTypedVoidPointerTest::RecordType *>(this->vptr)->x'}} 385 int y; // expected-note{{uninitialized field 'static_cast<struct RecordDynTypedVoidPointerTest::RecordType *>(this->vptr)->y'}} 386 }; 387 388 void *vptr; 389 int dontGetFilteredByNonPedanticMode = 0; 390 391 RecordDynTypedVoidPointerTest(void *vptr) : vptr(vptr) {} // expected-warning{{2 uninitialized fields}} 392 }; 393 394 void fRecordDynTypedVoidPointerTest() { 395 RecordDynTypedVoidPointerTest::RecordType a; 396 RecordDynTypedVoidPointerTest tmp(&a); 397 } 398 399 struct NestedNonVoidDynTypedVoidPointerTest { 400 struct RecordType { 401 int x; // expected-note{{uninitialized field 'static_cast<struct NestedNonVoidDynTypedVoidPointerTest::RecordType *>(this->vptr)->x'}} 402 int y; // expected-note{{uninitialized field 'static_cast<struct NestedNonVoidDynTypedVoidPointerTest::RecordType *>(this->vptr)->y'}} 403 void *vptr; // expected-note{{uninitialized pointee 'static_cast<char *>(static_cast<struct NestedNonVoidDynTypedVoidPointerTest::RecordType *>(this->vptr)->vptr)'}} 404 }; 405 406 void *vptr; 407 int dontGetFilteredByNonPedanticMode = 0; 408 409 NestedNonVoidDynTypedVoidPointerTest(void *vptr, void *c) : vptr(vptr) { 410 static_cast<RecordType *>(vptr)->vptr = c; // expected-warning{{3 uninitialized fields}} 411 } 412 }; 413 414 void fNestedNonVoidDynTypedVoidPointerTest() { 415 NestedNonVoidDynTypedVoidPointerTest::RecordType a; 416 char c; 417 NestedNonVoidDynTypedVoidPointerTest tmp(&a, &c); 418 } 419 420 //===----------------------------------------------------------------------===// 421 // Multipointer tests. 422 //===----------------------------------------------------------------------===// 423 424 #ifdef PEDANTIC 425 class MultiPointerTest1 { 426 public: 427 struct RecordType { 428 int x; 429 int y; 430 }; 431 432 private: 433 RecordType **mptr; // expected-note{{uninitialized pointee 'this->mptr'}} 434 435 public: 436 MultiPointerTest1(RecordType **p, int) : mptr(p) { // expected-warning{{1 uninitialized field}} 437 } 438 }; 439 440 void fMultiPointerTest1() { 441 MultiPointerTest1::RecordType *p1; 442 MultiPointerTest1::RecordType **mptr = &p1; 443 MultiPointerTest1(mptr, int()); // '*mptr' uninitialized 444 } 445 #else 446 class MultiPointerTest1 { 447 public: 448 struct RecordType { 449 int x; 450 int y; 451 }; 452 453 private: 454 RecordType **mptr; 455 456 public: 457 MultiPointerTest1(RecordType **p, int) : mptr(p) {} 458 }; 459 460 void fMultiPointerTest1() { 461 MultiPointerTest1::RecordType *p1; 462 MultiPointerTest1::RecordType **mptr = &p1; 463 MultiPointerTest1(mptr, int()); // '*mptr' uninitialized 464 } 465 #endif // PEDANTIC 466 467 #ifdef PEDANTIC 468 class MultiPointerTest2 { 469 public: 470 struct RecordType { 471 int x; // expected-note{{uninitialized field 'this->mptr->x'}} 472 int y; // expected-note{{uninitialized field 'this->mptr->y'}} 473 }; 474 475 private: 476 RecordType **mptr; 477 478 public: 479 MultiPointerTest2(RecordType **p, int) : mptr(p) { // expected-warning{{2 uninitialized fields}} 480 } 481 }; 482 483 void fMultiPointerTest2() { 484 MultiPointerTest2::RecordType i; 485 MultiPointerTest2::RecordType *p1 = &i; 486 MultiPointerTest2::RecordType **mptr = &p1; 487 MultiPointerTest2(mptr, int()); // '**mptr' uninitialized 488 } 489 #else 490 class MultiPointerTest2 { 491 public: 492 struct RecordType { 493 int x; 494 int y; 495 }; 496 497 private: 498 RecordType **mptr; 499 500 public: 501 MultiPointerTest2(RecordType **p, int) : mptr(p) { 502 } 503 }; 504 505 void fMultiPointerTest2() { 506 MultiPointerTest2::RecordType i; 507 MultiPointerTest2::RecordType *p1 = &i; 508 MultiPointerTest2::RecordType **mptr = &p1; 509 MultiPointerTest2(mptr, int()); // '**mptr' uninitialized 510 } 511 #endif // PEDANTIC 512 513 class MultiPointerTest3 { 514 public: 515 struct RecordType { 516 int x; 517 int y; 518 }; 519 520 private: 521 RecordType **mptr; 522 523 public: 524 MultiPointerTest3(RecordType **p, int) : mptr(p) { 525 // All good! 526 } 527 }; 528 529 void fMultiPointerTest3() { 530 MultiPointerTest3::RecordType i{31, 32}; 531 MultiPointerTest3::RecordType *p1 = &i; 532 MultiPointerTest3::RecordType **mptr = &p1; 533 MultiPointerTest3(mptr, int()); // '**mptr' uninitialized 534 } 535 536 //===----------------------------------------------------------------------===// 537 // Incomplete pointee tests. 538 //===----------------------------------------------------------------------===// 539 540 class IncompleteType; 541 542 struct IncompletePointeeTypeTest { 543 IncompleteType *pImpl; //no-crash 544 int dontGetFilteredByNonPedanticMode = 0; 545 546 IncompletePointeeTypeTest(IncompleteType *A) : pImpl(A) {} 547 }; 548 549 void fIncompletePointeeTypeTest(void *ptr) { 550 IncompletePointeeTypeTest(reinterpret_cast<IncompleteType *>(ptr)); 551 } 552 553 //===----------------------------------------------------------------------===// 554 // Function pointer tests. 555 //===----------------------------------------------------------------------===// 556 557 struct FunctionPointerWithDifferentDynTypeTest { 558 using Func1 = void *(*)(); 559 using Func2 = int *(*)(); 560 561 Func1 f; // no-crash 562 FunctionPointerWithDifferentDynTypeTest(Func2 f) : f((Func1)f) {} 563 }; 564 565 // Note that there isn't a function calling the constructor of 566 // FunctionPointerWithDifferentDynTypeTest, because a crash could only be 567 // reproduced without it. 568 569 //===----------------------------------------------------------------------===// 570 // Member pointer tests. 571 //===----------------------------------------------------------------------===// 572 573 struct UsefulFunctions { 574 int a, b; 575 576 void print() {} 577 void dump() {} 578 }; 579 580 #ifdef PEDANTIC 581 struct PointerToMemberFunctionTest1 { 582 void (UsefulFunctions::*f)(void); // expected-note{{uninitialized field 'this->f'}} 583 PointerToMemberFunctionTest1() {} 584 }; 585 586 void fPointerToMemberFunctionTest1() { 587 PointerToMemberFunctionTest1(); // expected-warning{{1 uninitialized field}} 588 } 589 590 struct PointerToMemberFunctionTest2 { 591 void (UsefulFunctions::*f)(void); 592 PointerToMemberFunctionTest2(void (UsefulFunctions::*f)(void)) : f(f) { 593 // All good! 594 } 595 }; 596 597 void fPointerToMemberFunctionTest2() { 598 void (UsefulFunctions::*f)(void) = &UsefulFunctions::print; 599 PointerToMemberFunctionTest2 a(f); 600 } 601 602 struct MultiPointerToMemberFunctionTest1 { 603 void (UsefulFunctions::**f)(void); // expected-note{{uninitialized pointer 'this->f'}} 604 MultiPointerToMemberFunctionTest1() {} 605 }; 606 607 void fMultiPointerToMemberFunctionTest1() { 608 MultiPointerToMemberFunctionTest1(); // expected-warning{{1 uninitialized field}} 609 } 610 611 struct MultiPointerToMemberFunctionTest2 { 612 void (UsefulFunctions::**f)(void); 613 MultiPointerToMemberFunctionTest2(void (UsefulFunctions::**f)(void)) : f(f) { 614 // All good! 615 } 616 }; 617 618 void fMultiPointerToMemberFunctionTest2() { 619 void (UsefulFunctions::*f)(void) = &UsefulFunctions::print; 620 MultiPointerToMemberFunctionTest2 a(&f); 621 } 622 623 struct PointerToMemberDataTest1 { 624 int UsefulFunctions::*d; // expected-note{{uninitialized field 'this->d'}} 625 PointerToMemberDataTest1() {} 626 }; 627 628 void fPointerToMemberDataTest1() { 629 PointerToMemberDataTest1(); // expected-warning{{1 uninitialized field}} 630 } 631 632 struct PointerToMemberDataTest2 { 633 int UsefulFunctions::*d; 634 PointerToMemberDataTest2(int UsefulFunctions::*d) : d(d) { 635 // All good! 636 } 637 }; 638 639 void fPointerToMemberDataTest2() { 640 int UsefulFunctions::*d = &UsefulFunctions::a; 641 PointerToMemberDataTest2 a(d); 642 } 643 644 struct MultiPointerToMemberDataTest1 { 645 int UsefulFunctions::**d; // expected-note{{uninitialized pointer 'this->d'}} 646 MultiPointerToMemberDataTest1() {} 647 }; 648 649 void fMultiPointerToMemberDataTest1() { 650 MultiPointerToMemberDataTest1(); // expected-warning{{1 uninitialized field}} 651 } 652 653 struct MultiPointerToMemberDataTest2 { 654 int UsefulFunctions::**d; 655 MultiPointerToMemberDataTest2(int UsefulFunctions::**d) : d(d) { 656 // All good! 657 } 658 }; 659 660 void fMultiPointerToMemberDataTest2() { 661 int UsefulFunctions::*d = &UsefulFunctions::a; 662 MultiPointerToMemberDataTest2 a(&d); 663 } 664 #endif // PEDANTIC 665 666 //===----------------------------------------------------------------------===// 667 // Tests for list-like records. 668 //===----------------------------------------------------------------------===// 669 670 class ListTest1 { 671 public: 672 struct Node { 673 Node *next = nullptr; // no crash 674 int i; 675 }; 676 677 private: 678 Node *head = nullptr; 679 680 public: 681 ListTest1() { 682 // All good! 683 } 684 }; 685 686 void fListTest1() { 687 ListTest1(); 688 } 689 690 class ListTest2 { 691 public: 692 struct Node { 693 Node *next = nullptr; 694 int i; // expected-note{{uninitialized field 'this->head->i'}} 695 }; 696 697 private: 698 Node *head = nullptr; 699 700 public: 701 ListTest2(Node *node, int) : head(node) { // expected-warning{{1 uninitialized field}} 702 } 703 }; 704 705 void fListTest2() { 706 ListTest2::Node n; 707 ListTest2(&n, int()); 708 } 709 710 class CyclicList { 711 public: 712 struct Node { 713 Node *next = nullptr; 714 int i; // expected-note{{uninitialized field 'this->head->i'}} 715 }; 716 717 private: 718 Node *head = nullptr; 719 720 public: 721 CyclicList(Node *node, int) : head(node) { // expected-warning{{1 uninitialized field}} 722 } 723 }; 724 725 void fCyclicList() { 726 /* 727 n3 728 / \ 729 this -- n1 -- n2 730 */ 731 732 CyclicList::Node n1; 733 CyclicList::Node n2; 734 n2.next = &n1; 735 n2.i = 50; 736 CyclicList::Node n3; 737 n3.next = &n2; 738 n3.i = 50; 739 n1.next = &n3; 740 // note that n1.i is uninitialized 741 CyclicList(&n1, int()); 742 } 743 744 struct RingListTest { 745 RingListTest *next; // no-crash 746 RingListTest() : next(this) {} 747 }; 748 749 void fRingListTest() { 750 RingListTest(); 751 } 752 753 //===----------------------------------------------------------------------===// 754 // Tests for classes containing references. 755 //===----------------------------------------------------------------------===// 756 757 class ReferenceTest1 { 758 public: 759 struct RecordType { 760 int x; 761 int y; 762 }; 763 764 private: 765 RecordType &lref; 766 RecordType &&rref; 767 768 public: 769 ReferenceTest1(RecordType &lref, RecordType &rref) : lref(lref), rref(static_cast<RecordType &&>(rref)) { 770 // All good! 771 } 772 }; 773 774 void fReferenceTest1() { 775 ReferenceTest1::RecordType d{33, 34}; 776 ReferenceTest1(d, d); 777 } 778 779 #ifdef PEDANTIC 780 class ReferenceTest2 { 781 public: 782 struct RecordType { 783 int x; // expected-note{{uninitialized field 'this->lref.x'}} 784 int y; // expected-note{{uninitialized field 'this->lref.y'}} 785 }; 786 787 private: 788 RecordType &lref; 789 RecordType &&rref; 790 791 public: 792 ReferenceTest2(RecordType &lref, RecordType &rref) 793 : lref(lref), rref(static_cast<RecordType &&>(rref)) { // expected-warning{{2 uninitialized fields}} 794 } 795 }; 796 797 void fReferenceTest2() { 798 ReferenceTest2::RecordType c; 799 ReferenceTest2(c, c); 800 } 801 #else 802 class ReferenceTest2 { 803 public: 804 struct RecordType { 805 int x; 806 int y; 807 }; 808 809 private: 810 RecordType &lref; 811 RecordType &&rref; 812 813 public: 814 ReferenceTest2(RecordType &lref, RecordType &rref) 815 : lref(lref), rref(static_cast<RecordType &&>(rref)) { 816 } 817 }; 818 819 void fReferenceTest2() { 820 ReferenceTest2::RecordType c; 821 ReferenceTest2(c, c); 822 } 823 #endif // PEDANTIC 824 825 class ReferenceTest3 { 826 public: 827 struct RecordType { 828 int x; // expected-note{{uninitialized field 'this->lref.x'}} 829 int y; // expected-note{{uninitialized field 'this->lref.y'}} 830 }; 831 832 private: 833 RecordType &lref; 834 RecordType &&rref; 835 836 public: 837 ReferenceTest3(RecordType &lref, RecordType &rref) 838 : lref(lref), rref(static_cast<RecordType &&>(rref)) { // expected-warning{{2 uninitialized fields}} 839 } 840 }; 841 842 void fReferenceTest3() { 843 ReferenceTest3::RecordType c, d{35, 36}; 844 ReferenceTest3(c, d); 845 } 846 847 class ReferenceTest4 { 848 public: 849 struct RecordType { 850 int x; // expected-note{{uninitialized field 'this->rref.x'}} 851 int y; // expected-note{{uninitialized field 'this->rref.y'}} 852 }; 853 854 private: 855 RecordType &lref; 856 RecordType &&rref; 857 858 public: 859 ReferenceTest4(RecordType &lref, RecordType &rref) 860 : lref(lref), rref(static_cast<RecordType &&>(rref)) { // expected-warning{{2 uninitialized fields}} 861 } 862 }; 863 864 void fReferenceTest5() { 865 ReferenceTest4::RecordType c, d{37, 38}; 866 ReferenceTest4(d, c); 867 } 868 869 //===----------------------------------------------------------------------===// 870 // Tests for objects containing multiple references to the same object. 871 //===----------------------------------------------------------------------===// 872 873 struct IntMultipleReferenceToSameObjectTest { 874 int *iptr; // expected-note{{uninitialized pointee 'this->iptr'}} 875 int &iref; // no-note, pointee of this->iref was already reported 876 877 int dontGetFilteredByNonPedanticMode = 0; 878 879 IntMultipleReferenceToSameObjectTest(int *i) : iptr(i), iref(*i) {} // expected-warning{{1 uninitialized field}} 880 }; 881 882 void fIntMultipleReferenceToSameObjectTest() { 883 int a; 884 IntMultipleReferenceToSameObjectTest Test(&a); 885 } 886 887 struct IntReferenceWrapper1 { 888 int &a; // expected-note{{uninitialized pointee 'this->a'}} 889 890 int dontGetFilteredByNonPedanticMode = 0; 891 892 IntReferenceWrapper1(int &a) : a(a) {} // expected-warning{{1 uninitialized field}} 893 }; 894 895 struct IntReferenceWrapper2 { 896 int &a; // no-note, pointee of this->a was already reported 897 898 int dontGetFilteredByNonPedanticMode = 0; 899 900 IntReferenceWrapper2(int &a) : a(a) {} // no-warning 901 }; 902 903 void fMultipleObjectsReferencingTheSameObjectTest() { 904 int a; 905 906 IntReferenceWrapper1 T1(a); 907 IntReferenceWrapper2 T2(a); 908 } 909