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