1================== 2Available Checkers 3================== 4 5The analyzer performs checks that are categorized into families or "checkers". 6 7The default set of checkers covers a variety of checks targeted at finding security and API usage bugs, 8dead code, and other logic errors. See the :ref:`default-checkers` checkers list below. 9 10In addition to these, the analyzer contains a number of :ref:`alpha-checkers` (aka *alpha* checkers). 11These checkers are under development and are switched off by default. They may crash or emit a higher number of false positives. 12 13The :ref:`debug-checkers` package contains checkers for analyzer developers for debugging purposes. 14 15.. contents:: Table of Contents 16 :depth: 4 17 18 19.. _default-checkers: 20 21Default Checkers 22---------------- 23 24.. _core-checkers: 25 26core 27^^^^ 28Models core language features and contains general-purpose checkers such as division by zero, 29null pointer dereference, usage of uninitialized values, etc. 30*These checkers must be always switched on as other checker rely on them.* 31 32.. _core-CallAndMessage: 33 34core.CallAndMessage (C, C++, ObjC) 35"""""""""""""""""""""""""""""""""" 36 Check for logical errors for function calls and Objective-C message expressions (e.g., uninitialized arguments, null function pointers). 37 38.. literalinclude:: checkers/callandmessage_example.c 39 :language: objc 40 41.. _core-DivideZero: 42 43core.DivideZero (C, C++, ObjC) 44"""""""""""""""""""""""""""""" 45 Check for division by zero. 46 47.. literalinclude:: checkers/dividezero_example.c 48 :language: c 49 50.. _core-NonNullParamChecker: 51 52core.NonNullParamChecker (C, C++, ObjC) 53""""""""""""""""""""""""""""""""""""""" 54Check for null pointers passed as arguments to a function whose arguments are references or marked with the 'nonnull' attribute. 55 56.. code-block:: cpp 57 58 int f(int *p) __attribute__((nonnull)); 59 60 void test(int *p) { 61 if (!p) 62 f(p); // warn 63 } 64 65.. _core-NullDereference: 66 67core.NullDereference (C, C++, ObjC) 68""""""""""""""""""""""""""""""""""" 69Check for dereferences of null pointers. 70 71.. code-block:: objc 72 73 // C 74 void test(int *p) { 75 if (p) 76 return; 77 78 int x = p[0]; // warn 79 } 80 81 // C 82 void test(int *p) { 83 if (!p) 84 *p = 0; // warn 85 } 86 87 // C++ 88 class C { 89 public: 90 int x; 91 }; 92 93 void test() { 94 C *pc = 0; 95 int k = pc->x; // warn 96 } 97 98 // Objective-C 99 @interface MyClass { 100 @public 101 int x; 102 } 103 @end 104 105 void test() { 106 MyClass *obj = 0; 107 obj->x = 1; // warn 108 } 109 110.. _core-StackAddressEscape: 111 112core.StackAddressEscape (C) 113""""""""""""""""""""""""""" 114Check that addresses to stack memory do not escape the function. 115 116.. code-block:: c 117 118 char const *p; 119 120 void test() { 121 char const str[] = "string"; 122 p = str; // warn 123 } 124 125 void* test() { 126 return __builtin_alloca(12); // warn 127 } 128 129 void test() { 130 static int *x; 131 int y; 132 x = &y; // warn 133 } 134 135 136.. _core-UndefinedBinaryOperatorResult: 137 138core.UndefinedBinaryOperatorResult (C) 139"""""""""""""""""""""""""""""""""""""" 140Check for undefined results of binary operators. 141 142.. code-block:: c 143 144 void test() { 145 int x; 146 int y = x + 1; // warn: left operand is garbage 147 } 148 149.. _core-VLASize: 150 151core.VLASize (C) 152"""""""""""""""" 153Check for declarations of Variable Length Arrays of undefined or zero size. 154 155 Check for declarations of VLA of undefined or zero size. 156 157.. code-block:: c 158 159 void test() { 160 int x; 161 int vla1[x]; // warn: garbage as size 162 } 163 164 void test() { 165 int x = 0; 166 int vla2[x]; // warn: zero size 167 } 168 169.. _core-uninitialized-ArraySubscript: 170 171core.uninitialized.ArraySubscript (C) 172""""""""""""""""""""""""""""""""""""" 173Check for uninitialized values used as array subscripts. 174 175.. code-block:: c 176 177 void test() { 178 int i, a[10]; 179 int x = a[i]; // warn: array subscript is undefined 180 } 181 182.. _core-uninitialized-Assign: 183 184core.uninitialized.Assign (C) 185""""""""""""""""""""""""""""" 186Check for assigning uninitialized values. 187 188.. code-block:: c 189 190 void test() { 191 int x; 192 x |= 1; // warn: left expression is uninitialized 193 } 194 195.. _core-uninitialized-Branch: 196 197core.uninitialized.Branch (C) 198""""""""""""""""""""""""""""" 199Check for uninitialized values used as branch conditions. 200 201.. code-block:: c 202 203 void test() { 204 int x; 205 if (x) // warn 206 return; 207 } 208 209.. _core-uninitialized-CapturedBlockVariable: 210 211core.uninitialized.CapturedBlockVariable (C) 212"""""""""""""""""""""""""""""""""""""""""""" 213Check for blocks that capture uninitialized values. 214 215.. code-block:: c 216 217 void test() { 218 int x; 219 ^{ int y = x; }(); // warn 220 } 221 222.. _core-uninitialized-UndefReturn: 223 224core.uninitialized.UndefReturn (C) 225"""""""""""""""""""""""""""""""""" 226Check for uninitialized values being returned to the caller. 227 228.. code-block:: c 229 230 int test() { 231 int x; 232 return x; // warn 233 } 234 235.. _cplusplus-checkers: 236 237 238cplusplus 239^^^^^^^^^ 240 241C++ Checkers. 242 243.. _cplusplus-InnerPointer: 244 245cplusplus.InnerPointer (C++) 246"""""""""""""""""""""""""""" 247Check for inner pointers of C++ containers used after re/deallocation. 248 249Many container methods in the C++ standard library are known to invalidate 250"references" (including actual references, iterators and raw pointers) to 251elements of the container. Using such references after they are invalidated 252causes undefined behavior, which is a common source of memory errors in C++ that 253this checker is capable of finding. 254 255The checker is currently limited to ``std::string`` objects and doesn't 256recognize some of the more sophisticated approaches to passing unowned pointers 257around, such as ``std::string_view``. 258 259.. code-block:: cpp 260 261 void deref_after_assignment() { 262 std::string s = "llvm"; 263 const char *c = s.data(); // note: pointer to inner buffer of 'std::string' obtained here 264 s = "clang"; // note: inner buffer of 'std::string' reallocated by call to 'operator=' 265 consume(c); // warn: inner pointer of container used after re/deallocation 266 } 267 268 const char *return_temp(int x) { 269 return std::to_string(x).c_str(); // warn: inner pointer of container used after re/deallocation 270 // note: pointer to inner buffer of 'std::string' obtained here 271 // note: inner buffer of 'std::string' deallocated by call to destructor 272 } 273 274.. _cplusplus-NewDelete: 275 276cplusplus.NewDelete (C++) 277""""""""""""""""""""""""" 278Check for double-free and use-after-free problems. Traces memory managed by new/delete. 279 280.. literalinclude:: checkers/newdelete_example.cpp 281 :language: cpp 282 283.. _cplusplus-NewDeleteLeaks: 284 285cplusplus.NewDeleteLeaks (C++) 286"""""""""""""""""""""""""""""" 287Check for memory leaks. Traces memory managed by new/delete. 288 289.. code-block:: cpp 290 291 void test() { 292 int *p = new int; 293 } // warn 294 295.. _cplusplus-PlacementNewChecker: 296 297cplusplus.PlacementNewChecker (C++) 298""""""""""""""""""""""""""""""""""" 299Check if default placement new is provided with pointers to sufficient storage capacity. 300 301.. code-block:: cpp 302 303 #include <new> 304 305 void f() { 306 short s; 307 long *lp = ::new (&s) long; // warn 308 } 309 310.. _cplusplus-SelfAssignment: 311 312cplusplus.SelfAssignment (C++) 313"""""""""""""""""""""""""""""" 314Checks C++ copy and move assignment operators for self assignment. 315 316.. _deadcode-checkers: 317 318deadcode 319^^^^^^^^ 320 321Dead Code Checkers. 322 323.. _deadcode-DeadStores: 324 325deadcode.DeadStores (C) 326""""""""""""""""""""""" 327Check for values stored to variables that are never read afterwards. 328 329.. code-block:: c 330 331 void test() { 332 int x; 333 x = 1; // warn 334 } 335 336The ``WarnForDeadNestedAssignments`` option enables the checker to emit 337warnings for nested dead assignments. You can disable with the 338``-analyzer-config deadcode.DeadStores:WarnForDeadNestedAssignments=false``. 339*Defaults to true*. 340 341Would warn for this e.g.: 342if ((y = make_int())) { 343} 344 345.. _nullability-checkers: 346 347nullability 348^^^^^^^^^^^ 349 350Objective C checkers that warn for null pointer passing and dereferencing errors. 351 352.. _nullability-NullPassedToNonnull: 353 354nullability.NullPassedToNonnull (ObjC) 355"""""""""""""""""""""""""""""""""""""" 356Warns when a null pointer is passed to a pointer which has a _Nonnull type. 357 358.. code-block:: objc 359 360 if (name != nil) 361 return; 362 // Warning: nil passed to a callee that requires a non-null 1st parameter 363 NSString *greeting = [@"Hello " stringByAppendingString:name]; 364 365.. _nullability-NullReturnedFromNonnull: 366 367nullability.NullReturnedFromNonnull (ObjC) 368"""""""""""""""""""""""""""""""""""""""""" 369Warns when a null pointer is returned from a function that has _Nonnull return type. 370 371.. code-block:: objc 372 373 - (nonnull id)firstChild { 374 id result = nil; 375 if ([_children count] > 0) 376 result = _children[0]; 377 378 // Warning: nil returned from a method that is expected 379 // to return a non-null value 380 return result; 381 } 382 383.. _nullability-NullableDereferenced: 384 385nullability.NullableDereferenced (ObjC) 386""""""""""""""""""""""""""""""""""""""" 387Warns when a nullable pointer is dereferenced. 388 389.. code-block:: objc 390 391 struct LinkedList { 392 int data; 393 struct LinkedList *next; 394 }; 395 396 struct LinkedList * _Nullable getNext(struct LinkedList *l); 397 398 void updateNextData(struct LinkedList *list, int newData) { 399 struct LinkedList *next = getNext(list); 400 // Warning: Nullable pointer is dereferenced 401 next->data = 7; 402 } 403 404.. _nullability-NullablePassedToNonnull: 405 406nullability.NullablePassedToNonnull (ObjC) 407"""""""""""""""""""""""""""""""""""""""""" 408Warns when a nullable pointer is passed to a pointer which has a _Nonnull type. 409 410.. code-block:: objc 411 412 typedef struct Dummy { int val; } Dummy; 413 Dummy *_Nullable returnsNullable(); 414 void takesNonnull(Dummy *_Nonnull); 415 416 void test() { 417 Dummy *p = returnsNullable(); 418 takesNonnull(p); // warn 419 } 420 421.. _nullability-NullableReturnedFromNonnull: 422 423nullability.NullableReturnedFromNonnull (ObjC) 424"""""""""""""""""""""""""""""""""""""""""""""" 425Warns when a nullable pointer is returned from a function that has _Nonnull return type. 426 427.. _optin-checkers: 428 429optin 430^^^^^ 431 432Checkers for portability, performance or coding style specific rules. 433 434.. _optin-cplusplus-UninitializedObject: 435 436optin.cplusplus.UninitializedObject (C++) 437""""""""""""""""""""""""""""""""""""""""" 438 439This checker reports uninitialized fields in objects created after a constructor 440call. It doesn't only find direct uninitialized fields, but rather makes a deep 441inspection of the object, analyzing all of it's fields subfields. 442The checker regards inherited fields as direct fields, so one will receive 443warnings for uninitialized inherited data members as well. 444 445.. code-block:: cpp 446 447 // With Pedantic and CheckPointeeInitialization set to true 448 449 struct A { 450 struct B { 451 int x; // note: uninitialized field 'this->b.x' 452 // note: uninitialized field 'this->bptr->x' 453 int y; // note: uninitialized field 'this->b.y' 454 // note: uninitialized field 'this->bptr->y' 455 }; 456 int *iptr; // note: uninitialized pointer 'this->iptr' 457 B b; 458 B *bptr; 459 char *cptr; // note: uninitialized pointee 'this->cptr' 460 461 A (B *bptr, char *cptr) : bptr(bptr), cptr(cptr) {} 462 }; 463 464 void f() { 465 A::B b; 466 char c; 467 A a(&b, &c); // warning: 6 uninitialized fields 468 // after the constructor call 469 } 470 471 // With Pedantic set to false and 472 // CheckPointeeInitialization set to true 473 // (every field is uninitialized) 474 475 struct A { 476 struct B { 477 int x; 478 int y; 479 }; 480 int *iptr; 481 B b; 482 B *bptr; 483 char *cptr; 484 485 A (B *bptr, char *cptr) : bptr(bptr), cptr(cptr) {} 486 }; 487 488 void f() { 489 A::B b; 490 char c; 491 A a(&b, &c); // no warning 492 } 493 494 // With Pedantic set to true and 495 // CheckPointeeInitialization set to false 496 // (pointees are regarded as initialized) 497 498 struct A { 499 struct B { 500 int x; // note: uninitialized field 'this->b.x' 501 int y; // note: uninitialized field 'this->b.y' 502 }; 503 int *iptr; // note: uninitialized pointer 'this->iptr' 504 B b; 505 B *bptr; 506 char *cptr; 507 508 A (B *bptr, char *cptr) : bptr(bptr), cptr(cptr) {} 509 }; 510 511 void f() { 512 A::B b; 513 char c; 514 A a(&b, &c); // warning: 3 uninitialized fields 515 // after the constructor call 516 } 517 518 519**Options** 520 521This checker has several options which can be set from command line (e.g. 522``-analyzer-config optin.cplusplus.UninitializedObject:Pedantic=true``): 523 524* ``Pedantic`` (boolean). If to false, the checker won't emit warnings for 525 objects that don't have at least one initialized field. Defaults to false. 526 527* ``NotesAsWarnings`` (boolean). If set to true, the checker will emit a 528 warning for each uninitialized field, as opposed to emitting one warning per 529 constructor call, and listing the uninitialized fields that belongs to it in 530 notes. *Defaults to false*. 531 532* ``CheckPointeeInitialization`` (boolean). If set to false, the checker will 533 not analyze the pointee of pointer/reference fields, and will only check 534 whether the object itself is initialized. *Defaults to false*. 535 536* ``IgnoreRecordsWithField`` (string). If supplied, the checker will not analyze 537 structures that have a field with a name or type name that matches the given 538 pattern. *Defaults to ""*. 539 540.. _optin-cplusplus-VirtualCall: 541 542optin.cplusplus.VirtualCall (C++) 543""""""""""""""""""""""""""""""""" 544Check virtual function calls during construction or destruction. 545 546.. code-block:: cpp 547 548 class A { 549 public: 550 A() { 551 f(); // warn 552 } 553 virtual void f(); 554 }; 555 556 class A { 557 public: 558 ~A() { 559 this->f(); // warn 560 } 561 virtual void f(); 562 }; 563 564.. _optin-mpi-MPI-Checker: 565 566optin.mpi.MPI-Checker (C) 567""""""""""""""""""""""""" 568Checks MPI code. 569 570.. code-block:: c 571 572 void test() { 573 double buf = 0; 574 MPI_Request sendReq1; 575 MPI_Ireduce(MPI_IN_PLACE, &buf, 1, MPI_DOUBLE, MPI_SUM, 576 0, MPI_COMM_WORLD, &sendReq1); 577 } // warn: request 'sendReq1' has no matching wait. 578 579 void test() { 580 double buf = 0; 581 MPI_Request sendReq; 582 MPI_Isend(&buf, 1, MPI_DOUBLE, 0, 0, MPI_COMM_WORLD, &sendReq); 583 MPI_Irecv(&buf, 1, MPI_DOUBLE, 0, 0, MPI_COMM_WORLD, &sendReq); // warn 584 MPI_Isend(&buf, 1, MPI_DOUBLE, 0, 0, MPI_COMM_WORLD, &sendReq); // warn 585 MPI_Wait(&sendReq, MPI_STATUS_IGNORE); 586 } 587 588 void missingNonBlocking() { 589 int rank = 0; 590 MPI_Comm_rank(MPI_COMM_WORLD, &rank); 591 MPI_Request sendReq1[10][10][10]; 592 MPI_Wait(&sendReq1[1][7][9], MPI_STATUS_IGNORE); // warn 593 } 594 595.. _optin-osx-cocoa-localizability-EmptyLocalizationContextChecker: 596 597optin.osx.cocoa.localizability.EmptyLocalizationContextChecker (ObjC) 598""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" 599Check that NSLocalizedString macros include a comment for context. 600 601.. code-block:: objc 602 603 - (void)test { 604 NSString *string = NSLocalizedString(@"LocalizedString", nil); // warn 605 NSString *string2 = NSLocalizedString(@"LocalizedString", @" "); // warn 606 NSString *string3 = NSLocalizedStringWithDefaultValue( 607 @"LocalizedString", nil, [[NSBundle alloc] init], nil,@""); // warn 608 } 609 610.. _optin-osx-cocoa-localizability-NonLocalizedStringChecker: 611 612optin.osx.cocoa.localizability.NonLocalizedStringChecker (ObjC) 613""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" 614Warns about uses of non-localized NSStrings passed to UI methods expecting localized NSStrings. 615 616.. code-block:: objc 617 618 NSString *alarmText = 619 NSLocalizedString(@"Enabled", @"Indicates alarm is turned on"); 620 if (!isEnabled) { 621 alarmText = @"Disabled"; 622 } 623 UILabel *alarmStateLabel = [[UILabel alloc] init]; 624 625 // Warning: User-facing text should use localized string macro 626 [alarmStateLabel setText:alarmText]; 627 628.. _optin-performance-GCDAntipattern: 629 630optin.performance.GCDAntipattern 631"""""""""""""""""""""""""""""""" 632Check for performance anti-patterns when using Grand Central Dispatch. 633 634.. _optin-performance-Padding: 635 636optin.performance.Padding 637""""""""""""""""""""""""" 638Check for excessively padded structs. 639 640.. _optin-portability-UnixAPI: 641 642optin.portability.UnixAPI 643""""""""""""""""""""""""" 644Finds implementation-defined behavior in UNIX/Posix functions. 645 646 647.. _security-checkers: 648 649security 650^^^^^^^^ 651 652Security related checkers. 653 654.. _security-FloatLoopCounter: 655 656security.FloatLoopCounter (C) 657""""""""""""""""""""""""""""" 658Warn on using a floating point value as a loop counter (CERT: FLP30-C, FLP30-CPP). 659 660.. code-block:: c 661 662 void test() { 663 for (float x = 0.1f; x <= 1.0f; x += 0.1f) {} // warn 664 } 665 666.. _security-insecureAPI-UncheckedReturn: 667 668security.insecureAPI.UncheckedReturn (C) 669"""""""""""""""""""""""""""""""""""""""" 670Warn on uses of functions whose return values must be always checked. 671 672.. code-block:: c 673 674 void test() { 675 setuid(1); // warn 676 } 677 678.. _security-insecureAPI-bcmp: 679 680security.insecureAPI.bcmp (C) 681""""""""""""""""""""""""""""" 682Warn on uses of the 'bcmp' function. 683 684.. code-block:: c 685 686 void test() { 687 bcmp(ptr0, ptr1, n); // warn 688 } 689 690.. _security-insecureAPI-bcopy: 691 692security.insecureAPI.bcopy (C) 693"""""""""""""""""""""""""""""" 694Warn on uses of the 'bcopy' function. 695 696.. code-block:: c 697 698 void test() { 699 bcopy(src, dst, n); // warn 700 } 701 702.. _security-insecureAPI-bzero: 703 704security.insecureAPI.bzero (C) 705"""""""""""""""""""""""""""""" 706Warn on uses of the 'bzero' function. 707 708.. code-block:: c 709 710 void test() { 711 bzero(ptr, n); // warn 712 } 713 714.. _security-insecureAPI-getpw: 715 716security.insecureAPI.getpw (C) 717"""""""""""""""""""""""""""""" 718Warn on uses of the 'getpw' function. 719 720.. code-block:: c 721 722 void test() { 723 char buff[1024]; 724 getpw(2, buff); // warn 725 } 726 727.. _security-insecureAPI-gets: 728 729security.insecureAPI.gets (C) 730""""""""""""""""""""""""""""" 731Warn on uses of the 'gets' function. 732 733.. code-block:: c 734 735 void test() { 736 char buff[1024]; 737 gets(buff); // warn 738 } 739 740.. _security-insecureAPI-mkstemp: 741 742security.insecureAPI.mkstemp (C) 743"""""""""""""""""""""""""""""""" 744Warn when 'mkstemp' is passed fewer than 6 X's in the format string. 745 746.. code-block:: c 747 748 void test() { 749 mkstemp("XX"); // warn 750 } 751 752.. _security-insecureAPI-mktemp: 753 754security.insecureAPI.mktemp (C) 755""""""""""""""""""""""""""""""" 756Warn on uses of the ``mktemp`` function. 757 758.. code-block:: c 759 760 void test() { 761 char *x = mktemp("/tmp/zxcv"); // warn: insecure, use mkstemp 762 } 763 764.. _security-insecureAPI-rand: 765 766security.insecureAPI.rand (C) 767""""""""""""""""""""""""""""" 768Warn on uses of inferior random number generating functions (only if arc4random function is available): 769``drand48, erand48, jrand48, lcong48, lrand48, mrand48, nrand48, random, rand_r``. 770 771.. code-block:: c 772 773 void test() { 774 random(); // warn 775 } 776 777.. _security-insecureAPI-strcpy: 778 779security.insecureAPI.strcpy (C) 780""""""""""""""""""""""""""""""" 781Warn on uses of the ``strcpy`` and ``strcat`` functions. 782 783.. code-block:: c 784 785 void test() { 786 char x[4]; 787 char *y = "abcd"; 788 789 strcpy(x, y); // warn 790 } 791 792 793.. _security-insecureAPI-vfork: 794 795security.insecureAPI.vfork (C) 796"""""""""""""""""""""""""""""" 797 Warn on uses of the 'vfork' function. 798 799.. code-block:: c 800 801 void test() { 802 vfork(); // warn 803 } 804 805.. _security-insecureAPI-DeprecatedOrUnsafeBufferHandling: 806 807security.insecureAPI.DeprecatedOrUnsafeBufferHandling (C) 808""""""""""""""""""""""""""""""""""""""""""""""""""""""""" 809 Warn on occurrences of unsafe or deprecated buffer handling functions, which now have a secure variant: ``sprintf, vsprintf, scanf, wscanf, fscanf, fwscanf, vscanf, vwscanf, vfscanf, vfwscanf, sscanf, swscanf, vsscanf, vswscanf, swprintf, snprintf, vswprintf, vsnprintf, memcpy, memmove, strncpy, strncat, memset`` 810 811.. code-block:: c 812 813 void test() { 814 char buf [5]; 815 strncpy(buf, "a", 1); // warn 816 } 817 818.. _unix-checkers: 819 820unix 821^^^^ 822POSIX/Unix checkers. 823 824.. _unix-API: 825 826unix.API (C) 827"""""""""""" 828Check calls to various UNIX/Posix functions: ``open, pthread_once, calloc, malloc, realloc, alloca``. 829 830.. literalinclude:: checkers/unix_api_example.c 831 :language: c 832 833.. _unix-Malloc: 834 835unix.Malloc (C) 836""""""""""""""" 837Check for memory leaks, double free, and use-after-free problems. Traces memory managed by malloc()/free(). 838 839.. literalinclude:: checkers/unix_malloc_example.c 840 :language: c 841 842.. _unix-MallocSizeof: 843 844unix.MallocSizeof (C) 845""""""""""""""""""""" 846Check for dubious ``malloc`` arguments involving ``sizeof``. 847 848.. code-block:: c 849 850 void test() { 851 long *p = malloc(sizeof(short)); 852 // warn: result is converted to 'long *', which is 853 // incompatible with operand type 'short' 854 free(p); 855 } 856 857.. _unix-MismatchedDeallocator: 858 859unix.MismatchedDeallocator (C, C++) 860""""""""""""""""""""""""""""""""""" 861Check for mismatched deallocators. 862 863.. literalinclude:: checkers/mismatched_deallocator_example.cpp 864 :language: c 865 866.. _unix-Vfork: 867 868unix.Vfork (C) 869"""""""""""""" 870Check for proper usage of ``vfork``. 871 872.. code-block:: c 873 874 int test(int x) { 875 pid_t pid = vfork(); // warn 876 if (pid != 0) 877 return 0; 878 879 switch (x) { 880 case 0: 881 pid = 1; 882 execl("", "", 0); 883 _exit(1); 884 break; 885 case 1: 886 x = 0; // warn: this assignment is prohibited 887 break; 888 case 2: 889 foo(); // warn: this function call is prohibited 890 break; 891 default: 892 return 0; // warn: return is prohibited 893 } 894 895 while(1); 896 } 897 898.. _unix-cstring-BadSizeArg: 899 900unix.cstring.BadSizeArg (C) 901""""""""""""""""""""""""""" 902Check the size argument passed into C string functions for common erroneous patterns. Use ``-Wno-strncat-size`` compiler option to mute other ``strncat``-related compiler warnings. 903 904.. code-block:: c 905 906 void test() { 907 char dest[3]; 908 strncat(dest, """""""""""""""""""""""""*", sizeof(dest)); 909 // warn: potential buffer overflow 910 } 911 912.. _unix-cstrisng-NullArg: 913 914unix.cstrisng.NullArg (C) 915""""""""""""""""""""""""" 916Check for null pointers being passed as arguments to C string functions: 917``strlen, strnlen, strcpy, strncpy, strcat, strncat, strcmp, strncmp, strcasecmp, strncasecmp``. 918 919.. code-block:: c 920 921 int test() { 922 return strlen(0); // warn 923 } 924 925.. _osx-checkers: 926 927osx 928^^^ 929macOS checkers. 930 931.. _osx-API: 932 933osx.API (C) 934""""""""""" 935Check for proper uses of various Apple APIs. 936 937.. code-block:: objc 938 939 void test() { 940 dispatch_once_t pred = 0; 941 dispatch_once(&pred, ^(){}); // warn: dispatch_once uses local 942 } 943 944.. _osx-NumberObjectConversion: 945 946osx.NumberObjectConversion (C, C++, ObjC) 947""""""""""""""""""""""""""""""""""""""""" 948Check for erroneous conversions of objects representing numbers into numbers. 949 950.. code-block:: objc 951 952 NSNumber *photoCount = [albumDescriptor objectForKey:@"PhotoCount"]; 953 // Warning: Comparing a pointer value of type 'NSNumber *' 954 // to a scalar integer value 955 if (photoCount > 0) { 956 [self displayPhotos]; 957 } 958 959.. _osx-ObjCProperty: 960 961osx.ObjCProperty (ObjC) 962""""""""""""""""""""""" 963Check for proper uses of Objective-C properties. 964 965.. code-block:: objc 966 967 NSNumber *photoCount = [albumDescriptor objectForKey:@"PhotoCount"]; 968 // Warning: Comparing a pointer value of type 'NSNumber *' 969 // to a scalar integer value 970 if (photoCount > 0) { 971 [self displayPhotos]; 972 } 973 974 975.. _osx-SecKeychainAPI: 976 977osx.SecKeychainAPI (C) 978"""""""""""""""""""""" 979Check for proper uses of Secure Keychain APIs. 980 981.. literalinclude:: checkers/seckeychainapi_example.m 982 :language: objc 983 984.. _osx-cocoa-AtSync: 985 986osx.cocoa.AtSync (ObjC) 987""""""""""""""""""""""" 988Check for nil pointers used as mutexes for @synchronized. 989 990.. code-block:: objc 991 992 void test(id x) { 993 if (!x) 994 @synchronized(x) {} // warn: nil value used as mutex 995 } 996 997 void test() { 998 id y; 999 @synchronized(y) {} // warn: uninitialized value used as mutex 1000 } 1001 1002.. _osx-cocoa-AutoreleaseWrite: 1003 1004osx.cocoa.AutoreleaseWrite 1005"""""""""""""""""""""""""" 1006Warn about potentially crashing writes to autoreleasing objects from different autoreleasing pools in Objective-C. 1007 1008.. _osx-cocoa-ClassRelease: 1009 1010osx.cocoa.ClassRelease (ObjC) 1011""""""""""""""""""""""""""""" 1012Check for sending 'retain', 'release', or 'autorelease' directly to a Class. 1013 1014.. code-block:: objc 1015 1016 @interface MyClass : NSObject 1017 @end 1018 1019 void test(void) { 1020 [MyClass release]; // warn 1021 } 1022 1023.. _osx-cocoa-Dealloc: 1024 1025osx.cocoa.Dealloc (ObjC) 1026"""""""""""""""""""""""" 1027Warn about Objective-C classes that lack a correct implementation of -dealloc 1028 1029.. literalinclude:: checkers/dealloc_example.m 1030 :language: objc 1031 1032.. _osx-cocoa-IncompatibleMethodTypes: 1033 1034osx.cocoa.IncompatibleMethodTypes (ObjC) 1035"""""""""""""""""""""""""""""""""""""""" 1036Warn about Objective-C method signatures with type incompatibilities. 1037 1038.. code-block:: objc 1039 1040 @interface MyClass1 : NSObject 1041 - (int)foo; 1042 @end 1043 1044 @implementation MyClass1 1045 - (int)foo { return 1; } 1046 @end 1047 1048 @interface MyClass2 : MyClass1 1049 - (float)foo; 1050 @end 1051 1052 @implementation MyClass2 1053 - (float)foo { return 1.0; } // warn 1054 @end 1055 1056.. _osx-cocoa-Loops: 1057 1058osx.cocoa.Loops 1059""""""""""""""" 1060Improved modeling of loops using Cocoa collection types. 1061 1062.. _osx-cocoa-MissingSuperCall: 1063 1064osx.cocoa.MissingSuperCall (ObjC) 1065""""""""""""""""""""""""""""""""" 1066Warn about Objective-C methods that lack a necessary call to super. 1067 1068.. code-block:: objc 1069 1070 @interface Test : UIViewController 1071 @end 1072 @implementation test 1073 - (void)viewDidLoad {} // warn 1074 @end 1075 1076 1077.. _osx-cocoa-NSAutoreleasePool: 1078 1079osx.cocoa.NSAutoreleasePool (ObjC) 1080"""""""""""""""""""""""""""""""""" 1081Warn for suboptimal uses of NSAutoreleasePool in Objective-C GC mode. 1082 1083.. code-block:: objc 1084 1085 void test() { 1086 NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; 1087 [pool release]; // warn 1088 } 1089 1090.. _osx-cocoa-NSError: 1091 1092osx.cocoa.NSError (ObjC) 1093"""""""""""""""""""""""" 1094Check usage of NSError parameters. 1095 1096.. code-block:: objc 1097 1098 @interface A : NSObject 1099 - (void)foo:(NSError """""""""""""""""""""""")error; 1100 @end 1101 1102 @implementation A 1103 - (void)foo:(NSError """""""""""""""""""""""")error { 1104 // warn: method accepting NSError"""""""""""""""""""""""" should have a non-void 1105 // return value 1106 } 1107 @end 1108 1109 @interface A : NSObject 1110 - (BOOL)foo:(NSError """""""""""""""""""""""")error; 1111 @end 1112 1113 @implementation A 1114 - (BOOL)foo:(NSError """""""""""""""""""""""")error { 1115 *error = 0; // warn: potential null dereference 1116 return 0; 1117 } 1118 @end 1119 1120.. _osx-cocoa-NilArg: 1121 1122osx.cocoa.NilArg (ObjC) 1123""""""""""""""""""""""" 1124Check for prohibited nil arguments to ObjC method calls. 1125 1126 - caseInsensitiveCompare: 1127 - compare: 1128 - compare:options: 1129 - compare:options:range: 1130 - compare:options:range:locale: 1131 - componentsSeparatedByCharactersInSet: 1132 - initWithFormat: 1133 1134.. code-block:: objc 1135 1136 NSComparisonResult test(NSString *s) { 1137 NSString *aString = nil; 1138 return [s caseInsensitiveCompare:aString]; 1139 // warn: argument to 'NSString' method 1140 // 'caseInsensitiveCompare:' cannot be nil 1141 } 1142 1143 1144.. _osx-cocoa-NonNilReturnValue: 1145 1146osx.cocoa.NonNilReturnValue 1147""""""""""""""""""""""""""" 1148Models the APIs that are guaranteed to return a non-nil value. 1149 1150.. _osx-cocoa-ObjCGenerics: 1151 1152osx.cocoa.ObjCGenerics (ObjC) 1153""""""""""""""""""""""""""""" 1154Check for type errors when using Objective-C generics. 1155 1156.. code-block:: objc 1157 1158 NSMutableArray *names = [NSMutableArray array]; 1159 NSMutableArray *birthDates = names; 1160 1161 // Warning: Conversion from value of type 'NSDate *' 1162 // to incompatible type 'NSString *' 1163 [birthDates addObject: [NSDate date]]; 1164 1165.. _osx-cocoa-RetainCount: 1166 1167osx.cocoa.RetainCount (ObjC) 1168"""""""""""""""""""""""""""" 1169Check for leaks and improper reference count management 1170 1171.. code-block:: objc 1172 1173 void test() { 1174 NSString *s = [[NSString alloc] init]; // warn 1175 } 1176 1177 CFStringRef test(char *bytes) { 1178 return CFStringCreateWithCStringNoCopy( 1179 0, bytes, NSNEXTSTEPStringEncoding, 0); // warn 1180 } 1181 1182 1183.. _osx-cocoa-RunLoopAutoreleaseLeak: 1184 1185osx.cocoa.RunLoopAutoreleaseLeak 1186"""""""""""""""""""""""""""""""" 1187Check for leaked memory in autorelease pools that will never be drained. 1188 1189.. _osx-cocoa-SelfInit: 1190 1191osx.cocoa.SelfInit (ObjC) 1192""""""""""""""""""""""""" 1193Check that 'self' is properly initialized inside an initializer method. 1194 1195.. code-block:: objc 1196 1197 @interface MyObj : NSObject { 1198 id x; 1199 } 1200 - (id)init; 1201 @end 1202 1203 @implementation MyObj 1204 - (id)init { 1205 [super init]; 1206 x = 0; // warn: instance variable used while 'self' is not 1207 // initialized 1208 return 0; 1209 } 1210 @end 1211 1212 @interface MyObj : NSObject 1213 - (id)init; 1214 @end 1215 1216 @implementation MyObj 1217 - (id)init { 1218 [super init]; 1219 return self; // warn: returning uninitialized 'self' 1220 } 1221 @end 1222 1223.. _osx-cocoa-SuperDealloc: 1224 1225osx.cocoa.SuperDealloc (ObjC) 1226""""""""""""""""""""""""""""" 1227Warn about improper use of '[super dealloc]' in Objective-C. 1228 1229.. code-block:: objc 1230 1231 @interface SuperDeallocThenReleaseIvarClass : NSObject { 1232 NSObject *_ivar; 1233 } 1234 @end 1235 1236 @implementation SuperDeallocThenReleaseIvarClass 1237 - (void)dealloc { 1238 [super dealloc]; 1239 [_ivar release]; // warn 1240 } 1241 @end 1242 1243.. _osx-cocoa-UnusedIvars: 1244 1245osx.cocoa.UnusedIvars (ObjC) 1246"""""""""""""""""""""""""""" 1247Warn about private ivars that are never used. 1248 1249.. code-block:: objc 1250 1251 @interface MyObj : NSObject { 1252 @private 1253 id x; // warn 1254 } 1255 @end 1256 1257 @implementation MyObj 1258 @end 1259 1260.. _osx-cocoa-VariadicMethodTypes: 1261 1262osx.cocoa.VariadicMethodTypes (ObjC) 1263"""""""""""""""""""""""""""""""""""" 1264Check for passing non-Objective-C types to variadic collection 1265initialization methods that expect only Objective-C types. 1266 1267.. code-block:: objc 1268 1269 void test() { 1270 [NSSet setWithObjects:@"Foo", "Bar", nil]; 1271 // warn: argument should be an ObjC pointer type, not 'char *' 1272 } 1273 1274.. _osx-coreFoundation-CFError: 1275 1276osx.coreFoundation.CFError (C) 1277"""""""""""""""""""""""""""""" 1278Check usage of CFErrorRef* parameters 1279 1280.. code-block:: c 1281 1282 void test(CFErrorRef *error) { 1283 // warn: function accepting CFErrorRef* should have a 1284 // non-void return 1285 } 1286 1287 int foo(CFErrorRef *error) { 1288 *error = 0; // warn: potential null dereference 1289 return 0; 1290 } 1291 1292.. _osx-coreFoundation-CFNumber: 1293 1294osx.coreFoundation.CFNumber (C) 1295""""""""""""""""""""""""""""""" 1296Check for proper uses of CFNumber APIs. 1297 1298.. code-block:: c 1299 1300 CFNumberRef test(unsigned char x) { 1301 return CFNumberCreate(0, kCFNumberSInt16Type, &x); 1302 // warn: 8 bit integer is used to initialize a 16 bit integer 1303 } 1304 1305.. _osx-coreFoundation-CFRetainRelease: 1306 1307osx.coreFoundation.CFRetainRelease (C) 1308"""""""""""""""""""""""""""""""""""""" 1309Check for null arguments to CFRetain/CFRelease/CFMakeCollectable. 1310 1311.. code-block:: c 1312 1313 void test(CFTypeRef p) { 1314 if (!p) 1315 CFRetain(p); // warn 1316 } 1317 1318 void test(int x, CFTypeRef p) { 1319 if (p) 1320 return; 1321 1322 CFRelease(p); // warn 1323 } 1324 1325.. _osx-coreFoundation-containers-OutOfBounds: 1326 1327osx.coreFoundation.containers.OutOfBounds (C) 1328""""""""""""""""""""""""""""""""""""""""""""" 1329Checks for index out-of-bounds when using 'CFArray' API. 1330 1331.. code-block:: c 1332 1333 void test() { 1334 CFArrayRef A = CFArrayCreate(0, 0, 0, &kCFTypeArrayCallBacks); 1335 CFArrayGetValueAtIndex(A, 0); // warn 1336 } 1337 1338.. _osx-coreFoundation-containers-PointerSizedValues: 1339 1340osx.coreFoundation.containers.PointerSizedValues (C) 1341"""""""""""""""""""""""""""""""""""""""""""""""""""" 1342Warns if 'CFArray', 'CFDictionary', 'CFSet' are created with non-pointer-size values. 1343 1344.. code-block:: c 1345 1346 void test() { 1347 int x[] = { 1 }; 1348 CFArrayRef A = CFArrayCreate(0, (const void """""""""""""""""""""""")x, 1, 1349 &kCFTypeArrayCallBacks); // warn 1350 } 1351 1352Fuchsia 1353^^^^^^^ 1354 1355Fuchsia is an open source capability-based operating system currently being 1356developed by Google. This section describes checkers that can find various 1357misuses of Fuchsia APIs. 1358 1359.. _fuchsia-HandleChecker: 1360 1361fuchsia.HandleChecker 1362"""""""""""""""""""""""""""" 1363Handles identify resources. Similar to pointers they can be leaked, 1364double freed, or use after freed. This check attempts to find such problems. 1365 1366.. code-block:: cpp 1367 1368 void checkLeak08(int tag) { 1369 zx_handle_t sa, sb; 1370 zx_channel_create(0, &sa, &sb); 1371 if (tag) 1372 zx_handle_close(sa); 1373 use(sb); // Warn: Potential leak of handle 1374 zx_handle_close(sb); 1375 } 1376 1377WebKit 1378^^^^^^ 1379 1380WebKit is an open-source web browser engine available for macOS, iOS and Linux. 1381This section describes checkers that can find issues in WebKit codebase. 1382 1383Most of the checkers focus on memory management for which WebKit uses custom implementation of reference counted smartpointers. 1384 1385Checkers are formulated in terms related to ref-counting: 1386 - *Ref-counted type* is either ``Ref<T>`` or ``RefPtr<T>``. 1387 - *Ref-countable type* is any type that implements ``ref()`` and ``deref()`` methods as ``RefPtr<>`` is a template (i. e. relies on duck typing). 1388 - *Uncounted type* is ref-countable but not ref-counted type. 1389 1390.. _webkit-RefCntblBaseVirtualDtor: 1391 1392webkit.RefCntblBaseVirtualDtor 1393"""""""""""""""""""""""""""""""""""" 1394All uncounted types used as base classes must have a virtual destructor. 1395 1396Ref-counted types hold their ref-countable data by a raw pointer and allow implicit upcasting from ref-counted pointer to derived type to ref-counted pointer to base type. This might lead to an object of (dynamic) derived type being deleted via pointer to the base class type which C++ standard defines as UB in case the base class doesn't have virtual destructor ``[expr.delete]``. 1397 1398.. code-block:: cpp 1399 1400 struct RefCntblBase { 1401 void ref() {} 1402 void deref() {} 1403 }; 1404 1405 struct Derived : RefCntblBase { }; // warn 1406 1407.. _webkit-NoUncountedMemberChecker: 1408 1409webkit.NoUncountedMemberChecker 1410""""""""""""""""""""""""""""""""""""" 1411Raw pointers and references to uncounted types can't be used as class members. Only ref-counted types are allowed. 1412 1413.. code-block:: cpp 1414 1415 struct RefCntbl { 1416 void ref() {} 1417 void deref() {} 1418 }; 1419 1420 struct Foo { 1421 RefCntbl * ptr; // warn 1422 RefCntbl & ptr; // warn 1423 // ... 1424 }; 1425 1426.. _alpha-checkers: 1427 1428Experimental Checkers 1429--------------------- 1430 1431*These are checkers with known issues or limitations that keep them from being on by default. They are likely to have false positives. Bug reports and especially patches are welcome.* 1432 1433alpha.clone 1434^^^^^^^^^^^ 1435 1436.. _alpha-clone-CloneChecker: 1437 1438alpha.clone.CloneChecker (C, C++, ObjC) 1439""""""""""""""""""""""""""""""""""""""" 1440Reports similar pieces of code. 1441 1442.. code-block:: c 1443 1444 void log(); 1445 1446 int max(int a, int b) { // warn 1447 log(); 1448 if (a > b) 1449 return a; 1450 return b; 1451 } 1452 1453 int maxClone(int x, int y) { // similar code here 1454 log(); 1455 if (x > y) 1456 return x; 1457 return y; 1458 } 1459 1460.. _alpha-core-BoolAssignment: 1461 1462alpha.core.BoolAssignment (ObjC) 1463"""""""""""""""""""""""""""""""" 1464Warn about assigning non-{0,1} values to boolean variables. 1465 1466.. code-block:: objc 1467 1468 void test() { 1469 BOOL b = -1; // warn 1470 } 1471 1472alpha.core 1473^^^^^^^^^^ 1474 1475.. _alpha-core-C11Lock: 1476 1477alpha.core.C11Lock 1478"""""""""""""""""" 1479Similarly to :ref:`alpha.unix.PthreadLock <alpha-unix-PthreadLock>`, checks for 1480the locking/unlocking of ``mtx_t`` mutexes. 1481 1482.. code-block:: cpp 1483 1484 mtx_t mtx1; 1485 1486 void bad1(void) 1487 { 1488 mtx_lock(&mtx1); 1489 mtx_lock(&mtx1); // warn: This lock has already been acquired 1490 } 1491 1492.. _alpha-core-CallAndMessageUnInitRefArg: 1493 1494alpha.core.CallAndMessageUnInitRefArg (C,C++, ObjC) 1495""""""""""""""""""""""""""""""""""""""""""""""""""" 1496Check for logical errors for function calls and Objective-C 1497message expressions (e.g., uninitialized arguments, null function pointers, and pointer to undefined variables). 1498 1499.. code-block:: c 1500 1501 void test(void) { 1502 int t; 1503 int &p = t; 1504 int &s = p; 1505 int &q = s; 1506 foo(q); // warn 1507 } 1508 1509 void test(void) { 1510 int x; 1511 foo(&x); // warn 1512 } 1513 1514.. _alpha-core-CastSize: 1515 1516alpha.core.CastSize (C) 1517""""""""""""""""""""""" 1518Check when casting a malloc'ed type ``T``, whether the size is a multiple of the size of ``T``. 1519 1520.. code-block:: c 1521 1522 void test() { 1523 int *x = (int *) malloc(11); // warn 1524 } 1525 1526.. _alpha-core-CastToStruct: 1527 1528alpha.core.CastToStruct (C, C++) 1529"""""""""""""""""""""""""""""""" 1530Check for cast from non-struct pointer to struct pointer. 1531 1532.. code-block:: cpp 1533 1534 // C 1535 struct s {}; 1536 1537 void test(int *p) { 1538 struct s *ps = (struct s *) p; // warn 1539 } 1540 1541 // C++ 1542 class c {}; 1543 1544 void test(int *p) { 1545 c *pc = (c *) p; // warn 1546 } 1547 1548.. _alpha-core-Conversion: 1549 1550alpha.core.Conversion (C, C++, ObjC) 1551"""""""""""""""""""""""""""""""""""" 1552Loss of sign/precision in implicit conversions. 1553 1554.. code-block:: c 1555 1556 void test(unsigned U, signed S) { 1557 if (S > 10) { 1558 if (U < S) { 1559 } 1560 } 1561 if (S < -10) { 1562 if (U < S) { // warn (loss of sign) 1563 } 1564 } 1565 } 1566 1567 void test() { 1568 long long A = 1LL << 60; 1569 short X = A; // warn (loss of precision) 1570 } 1571 1572.. _alpha-core-DynamicTypeChecker: 1573 1574alpha.core.DynamicTypeChecker (ObjC) 1575"""""""""""""""""""""""""""""""""""" 1576Check for cases where the dynamic and the static type of an object are unrelated. 1577 1578 1579.. code-block:: objc 1580 1581 id date = [NSDate date]; 1582 1583 // Warning: Object has a dynamic type 'NSDate *' which is 1584 // incompatible with static type 'NSNumber *'" 1585 NSNumber *number = date; 1586 [number doubleValue]; 1587 1588.. _alpha-core-FixedAddr: 1589 1590alpha.core.FixedAddr (C) 1591"""""""""""""""""""""""" 1592Check for assignment of a fixed address to a pointer. 1593 1594.. code-block:: c 1595 1596 void test() { 1597 int *p; 1598 p = (int *) 0x10000; // warn 1599 } 1600 1601.. _alpha-core-IdenticalExpr: 1602 1603alpha.core.IdenticalExpr (C, C++) 1604""""""""""""""""""""""""""""""""" 1605Warn about unintended use of identical expressions in operators. 1606 1607.. code-block:: cpp 1608 1609 // C 1610 void test() { 1611 int a = 5; 1612 int b = a | 4 | a; // warn: identical expr on both sides 1613 } 1614 1615 // C++ 1616 bool f(void); 1617 1618 void test(bool b) { 1619 int i = 10; 1620 if (f()) { // warn: true and false branches are identical 1621 do { 1622 i--; 1623 } while (f()); 1624 } else { 1625 do { 1626 i--; 1627 } while (f()); 1628 } 1629 } 1630 1631.. _alpha-core-PointerArithm: 1632 1633alpha.core.PointerArithm (C) 1634"""""""""""""""""""""""""""" 1635Check for pointer arithmetic on locations other than array elements. 1636 1637.. code-block:: c 1638 1639 void test() { 1640 int x; 1641 int *p; 1642 p = &x + 1; // warn 1643 } 1644 1645.. _alpha-core-PointerSub: 1646 1647alpha.core.PointerSub (C) 1648""""""""""""""""""""""""" 1649Check for pointer subtractions on two pointers pointing to different memory chunks. 1650 1651.. code-block:: c 1652 1653 void test() { 1654 int x, y; 1655 int d = &y - &x; // warn 1656 } 1657 1658.. _alpha-core-SizeofPtr: 1659 1660alpha.core.SizeofPtr (C) 1661"""""""""""""""""""""""" 1662Warn about unintended use of ``sizeof()`` on pointer expressions. 1663 1664.. code-block:: c 1665 1666 struct s {}; 1667 1668 int test(struct s *p) { 1669 return sizeof(p); 1670 // warn: sizeof(ptr) can produce an unexpected result 1671 } 1672 1673.. _alpha-core-StackAddressAsyncEscape: 1674 1675alpha.core.StackAddressAsyncEscape (C) 1676"""""""""""""""""""""""""""""""""""""" 1677Check that addresses to stack memory do not escape the function that involves dispatch_after or dispatch_async. 1678This checker is a part of ``core.StackAddressEscape``, but is temporarily disabled until some false positives are fixed. 1679 1680.. code-block:: c 1681 1682 dispatch_block_t test_block_inside_block_async_leak() { 1683 int x = 123; 1684 void (^inner)(void) = ^void(void) { 1685 int y = x; 1686 ++y; 1687 }; 1688 void (^outer)(void) = ^void(void) { 1689 int z = x; 1690 ++z; 1691 inner(); 1692 }; 1693 return outer; // warn: address of stack-allocated block is captured by a 1694 // returned block 1695 } 1696 1697.. _alpha-core-TestAfterDivZero: 1698 1699alpha.core.TestAfterDivZero (C) 1700""""""""""""""""""""""""""""""" 1701Check for division by variable that is later compared against 0. 1702Either the comparison is useless or there is division by zero. 1703 1704.. code-block:: c 1705 1706 void test(int x) { 1707 var = 77 / x; 1708 if (x == 0) { } // warn 1709 } 1710 1711alpha.cplusplus 1712^^^^^^^^^^^^^^^ 1713 1714.. _alpha-cplusplus-DeleteWithNonVirtualDtor: 1715 1716alpha.cplusplus.DeleteWithNonVirtualDtor (C++) 1717"""""""""""""""""""""""""""""""""""""""""""""" 1718Reports destructions of polymorphic objects with a non-virtual destructor in their base class. 1719 1720.. code-block:: cpp 1721 1722 NonVirtual *create() { 1723 NonVirtual *x = new NVDerived(); // note: conversion from derived to base 1724 // happened here 1725 return x; 1726 } 1727 1728 void sink(NonVirtual *x) { 1729 delete x; // warn: destruction of a polymorphic object with no virtual 1730 // destructor 1731 } 1732 1733.. _alpha-cplusplus-EnumCastOutOfRange: 1734 1735alpha.cplusplus.EnumCastOutOfRange (C++) 1736"""""""""""""""""""""""""""""""""""""""" 1737Check for integer to enumeration casts that could result in undefined values. 1738 1739.. code-block:: cpp 1740 1741 enum TestEnum { 1742 A = 0 1743 }; 1744 1745 void foo() { 1746 TestEnum t = static_cast(-1); 1747 // warn: the value provided to the cast expression is not in 1748 the valid range of values for the enum 1749 1750.. _alpha-cplusplus-InvalidatedIterator: 1751 1752alpha.cplusplus.InvalidatedIterator (C++) 1753""""""""""""""""""""""""""""""""""""""""" 1754Check for use of invalidated iterators. 1755 1756.. code-block:: cpp 1757 1758 void bad_copy_assign_operator_list1(std::list &L1, 1759 const std::list &L2) { 1760 auto i0 = L1.cbegin(); 1761 L1 = L2; 1762 *i0; // warn: invalidated iterator accessed 1763 } 1764 1765 1766.. _alpha-cplusplus-IteratorRange: 1767 1768alpha.cplusplus.IteratorRange (C++) 1769""""""""""""""""""""""""""""""""""" 1770Check for iterators used outside their valid ranges. 1771 1772.. code-block:: cpp 1773 1774 void simple_bad_end(const std::vector &v) { 1775 auto i = v.end(); 1776 *i; // warn: iterator accessed outside of its range 1777 } 1778 1779.. _alpha-cplusplus-MismatchedIterator: 1780 1781alpha.cplusplus.MismatchedIterator (C++) 1782"""""""""""""""""""""""""""""""""""""""" 1783Check for use of iterators of different containers where iterators of the same container are expected. 1784 1785.. code-block:: cpp 1786 1787 void bad_insert3(std::vector &v1, std::vector &v2) { 1788 v2.insert(v1.cbegin(), v2.cbegin(), v2.cend()); // warn: container accessed 1789 // using foreign 1790 // iterator argument 1791 v1.insert(v1.cbegin(), v1.cbegin(), v2.cend()); // warn: iterators of 1792 // different containers 1793 // used where the same 1794 // container is 1795 // expected 1796 v1.insert(v1.cbegin(), v2.cbegin(), v1.cend()); // warn: iterators of 1797 // different containers 1798 // used where the same 1799 // container is 1800 // expected 1801 } 1802 1803.. _alpha-cplusplus-MisusedMovedObject: 1804 1805alpha.cplusplus.MisusedMovedObject (C++) 1806"""""""""""""""""""""""""""""""""""""""" 1807Method calls on a moved-from object and copying a moved-from object will be reported. 1808 1809 1810.. code-block:: cpp 1811 1812 struct A { 1813 void foo() {} 1814 }; 1815 1816 void f() { 1817 A a; 1818 A b = std::move(a); // note: 'a' became 'moved-from' here 1819 a.foo(); // warn: method call on a 'moved-from' object 'a' 1820 } 1821 1822alpha.deadcode 1823^^^^^^^^^^^^^^ 1824.. _alpha-deadcode-UnreachableCode: 1825 1826alpha.deadcode.UnreachableCode (C, C++) 1827""""""""""""""""""""""""""""""""""""""" 1828Check unreachable code. 1829 1830.. code-block:: cpp 1831 1832 // C 1833 int test() { 1834 int x = 1; 1835 while(x); 1836 return x; // warn 1837 } 1838 1839 // C++ 1840 void test() { 1841 int a = 2; 1842 1843 while (a > 1) 1844 a--; 1845 1846 if (a > 1) 1847 a++; // warn 1848 } 1849 1850 // Objective-C 1851 void test(id x) { 1852 return; 1853 [x retain]; // warn 1854 } 1855 1856.. _alpha-cplusplus-SmartPtr: 1857 1858alpha.cplusplus.SmartPtr (C++) 1859"""""""""""""""""""""""""""""" 1860Check for dereference of null smart pointers. 1861 1862.. code-block:: cpp 1863 1864 void deref_smart_ptr() { 1865 std::unique_ptr<int> P; 1866 *P; // warn: dereference of a default constructed smart unique_ptr 1867 } 1868 1869alpha.fuchsia 1870^^^^^^^^^^^^^ 1871 1872.. _alpha-fuchsia-lock: 1873 1874alpha.fuchsia.Lock 1875"""""""""""""""""" 1876Similarly to :ref:`alpha.unix.PthreadLock <alpha-unix-PthreadLock>`, checks for 1877the locking/unlocking of fuchsia mutexes. 1878 1879.. code-block:: cpp 1880 1881 spin_lock_t mtx1; 1882 1883 void bad1(void) 1884 { 1885 spin_lock(&mtx1); 1886 spin_lock(&mtx1); // warn: This lock has already been acquired 1887 } 1888 1889alpha.llvm 1890^^^^^^^^^^ 1891 1892.. _alpha-llvm-Conventions: 1893 1894alpha.llvm.Conventions 1895"""""""""""""""""""""" 1896 1897Check code for LLVM codebase conventions: 1898 1899* A StringRef should not be bound to a temporary std::string whose lifetime is shorter than the StringRef's. 1900* Clang AST nodes should not have fields that can allocate memory. 1901 1902 1903alpha.osx 1904^^^^^^^^^ 1905 1906.. _alpha-osx-cocoa-DirectIvarAssignment: 1907 1908alpha.osx.cocoa.DirectIvarAssignment (ObjC) 1909""""""""""""""""""""""""""""""""""""""""""" 1910Check for direct assignments to instance variables. 1911 1912 1913.. code-block:: objc 1914 1915 @interface MyClass : NSObject {} 1916 @property (readonly) id A; 1917 - (void) foo; 1918 @end 1919 1920 @implementation MyClass 1921 - (void) foo { 1922 _A = 0; // warn 1923 } 1924 @end 1925 1926.. _alpha-osx-cocoa-DirectIvarAssignmentForAnnotatedFunctions: 1927 1928alpha.osx.cocoa.DirectIvarAssignmentForAnnotatedFunctions (ObjC) 1929"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" 1930Check for direct assignments to instance variables in 1931the methods annotated with ``objc_no_direct_instance_variable_assignment``. 1932 1933.. code-block:: objc 1934 1935 @interface MyClass : NSObject {} 1936 @property (readonly) id A; 1937 - (void) fAnnotated __attribute__(( 1938 annotate("objc_no_direct_instance_variable_assignment"))); 1939 - (void) fNotAnnotated; 1940 @end 1941 1942 @implementation MyClass 1943 - (void) fAnnotated { 1944 _A = 0; // warn 1945 } 1946 - (void) fNotAnnotated { 1947 _A = 0; // no warn 1948 } 1949 @end 1950 1951 1952.. _alpha-osx-cocoa-InstanceVariableInvalidation: 1953 1954alpha.osx.cocoa.InstanceVariableInvalidation (ObjC) 1955""""""""""""""""""""""""""""""""""""""""""""""""""" 1956Check that the invalidatable instance variables are 1957invalidated in the methods annotated with objc_instance_variable_invalidator. 1958 1959.. code-block:: objc 1960 1961 @protocol Invalidation <NSObject> 1962 - (void) invalidate 1963 __attribute__((annotate("objc_instance_variable_invalidator"))); 1964 @end 1965 1966 @interface InvalidationImpObj : NSObject <Invalidation> 1967 @end 1968 1969 @interface SubclassInvalidationImpObj : InvalidationImpObj { 1970 InvalidationImpObj *var; 1971 } 1972 - (void)invalidate; 1973 @end 1974 1975 @implementation SubclassInvalidationImpObj 1976 - (void) invalidate {} 1977 @end 1978 // warn: var needs to be invalidated or set to nil 1979 1980.. _alpha-osx-cocoa-MissingInvalidationMethod: 1981 1982alpha.osx.cocoa.MissingInvalidationMethod (ObjC) 1983"""""""""""""""""""""""""""""""""""""""""""""""" 1984Check that the invalidation methods are present in classes that contain invalidatable instance variables. 1985 1986.. code-block:: objc 1987 1988 @protocol Invalidation <NSObject> 1989 - (void)invalidate 1990 __attribute__((annotate("objc_instance_variable_invalidator"))); 1991 @end 1992 1993 @interface NeedInvalidation : NSObject <Invalidation> 1994 @end 1995 1996 @interface MissingInvalidationMethodDecl : NSObject { 1997 NeedInvalidation *Var; // warn 1998 } 1999 @end 2000 2001 @implementation MissingInvalidationMethodDecl 2002 @end 2003 2004.. _alpha-osx-cocoa-localizability-PluralMisuseChecker: 2005 2006alpha.osx.cocoa.localizability.PluralMisuseChecker (ObjC) 2007""""""""""""""""""""""""""""""""""""""""""""""""""""""""" 2008Warns against using one vs. many plural pattern in code when generating localized strings. 2009 2010.. code-block:: objc 2011 2012 NSString *reminderText = 2013 NSLocalizedString(@"None", @"Indicates no reminders"); 2014 if (reminderCount == 1) { 2015 // Warning: Plural cases are not supported across all languages. 2016 // Use a .stringsdict file instead 2017 reminderText = 2018 NSLocalizedString(@"1 Reminder", @"Indicates single reminder"); 2019 } else if (reminderCount >= 2) { 2020 // Warning: Plural cases are not supported across all languages. 2021 // Use a .stringsdict file instead 2022 reminderText = 2023 [NSString stringWithFormat: 2024 NSLocalizedString(@"%@ Reminders", @"Indicates multiple reminders"), 2025 reminderCount]; 2026 } 2027 2028alpha.security 2029^^^^^^^^^^^^^^ 2030 2031 2032alpha.security.cert 2033^^^^^^^^^^^^^^^^^^^ 2034 2035SEI CERT checkers which tries to find errors based on their `C coding rules <https://wiki.sei.cmu.edu/confluence/display/c/2+Rules>`_. 2036 2037.. _alpha-security-cert-pos-checkers: 2038 2039alpha.security.cert.pos 2040^^^^^^^^^^^^^^^^^^^^^^^ 2041 2042SEI CERT checkers of `POSIX C coding rules <https://wiki.sei.cmu.edu/confluence/pages/viewpage.action?pageId=87152405>`_. 2043 2044.. _alpha-security-cert-pos-34c: 2045 2046alpha.security.cert.pos.34c 2047""""""""""""""""""""""""""" 2048Finds calls to the ``putenv`` function which pass a pointer to an automatic variable as the argument. 2049 2050.. code-block:: c 2051 2052 int func(const char *var) { 2053 char env[1024]; 2054 int retval = snprintf(env, sizeof(env),"TEST=%s", var); 2055 if (retval < 0 || (size_t)retval >= sizeof(env)) { 2056 /* Handle error */ 2057 } 2058 2059 return putenv(env); // putenv function should not be called with auto variables 2060 } 2061 2062.. _alpha-security-ArrayBound: 2063 2064alpha.security.ArrayBound (C) 2065""""""""""""""""""""""""""""" 2066Warn about buffer overflows (older checker). 2067 2068.. code-block:: c 2069 2070 void test() { 2071 char *s = ""; 2072 char c = s[1]; // warn 2073 } 2074 2075 struct seven_words { 2076 int c[7]; 2077 }; 2078 2079 void test() { 2080 struct seven_words a, *p; 2081 p = &a; 2082 p[0] = a; 2083 p[1] = a; 2084 p[2] = a; // warn 2085 } 2086 2087 // note: requires unix.Malloc or 2088 // alpha.unix.MallocWithAnnotations checks enabled. 2089 void test() { 2090 int *p = malloc(12); 2091 p[3] = 4; // warn 2092 } 2093 2094 void test() { 2095 char a[2]; 2096 int *b = (int*)a; 2097 b[1] = 3; // warn 2098 } 2099 2100.. _alpha-security-ArrayBoundV2: 2101 2102alpha.security.ArrayBoundV2 (C) 2103""""""""""""""""""""""""""""""" 2104Warn about buffer overflows (newer checker). 2105 2106.. code-block:: c 2107 2108 void test() { 2109 char *s = ""; 2110 char c = s[1]; // warn 2111 } 2112 2113 void test() { 2114 int buf[100]; 2115 int *p = buf; 2116 p = p + 99; 2117 p[1] = 1; // warn 2118 } 2119 2120 // note: compiler has internal check for this. 2121 // Use -Wno-array-bounds to suppress compiler warning. 2122 void test() { 2123 int buf[100][100]; 2124 buf[0][-1] = 1; // warn 2125 } 2126 2127 // note: requires alpha.security.taint check turned on. 2128 void test() { 2129 char s[] = "abc"; 2130 int x = getchar(); 2131 char c = s[x]; // warn: index is tainted 2132 } 2133 2134.. _alpha-security-MallocOverflow: 2135 2136alpha.security.MallocOverflow (C) 2137""""""""""""""""""""""""""""""""" 2138Check for overflows in the arguments to malloc(). 2139 2140.. code-block:: c 2141 2142 void test(int n) { 2143 void *p = malloc(n * sizeof(int)); // warn 2144 } 2145 2146 void test2(int n) { 2147 if (n > 100) // gives an upper-bound 2148 return; 2149 void *p = malloc(n * sizeof(int)); // no warning 2150 } 2151 2152.. _alpha-security-MmapWriteExec: 2153 2154alpha.security.MmapWriteExec (C) 2155"""""""""""""""""""""""""""""""" 2156Warn on mmap() calls that are both writable and executable. 2157 2158.. code-block:: c 2159 2160 void test(int n) { 2161 void *c = mmap(NULL, 32, PROT_READ | PROT_WRITE | PROT_EXEC, 2162 MAP_PRIVATE | MAP_ANON, -1, 0); 2163 // warn: Both PROT_WRITE and PROT_EXEC flags are set. This can lead to 2164 // exploitable memory regions, which could be overwritten with malicious 2165 // code 2166 } 2167 2168.. _alpha-security-ReturnPtrRange: 2169 2170alpha.security.ReturnPtrRange (C) 2171""""""""""""""""""""""""""""""""" 2172Check for an out-of-bound pointer being returned to callers. 2173 2174.. code-block:: c 2175 2176 static int A[10]; 2177 2178 int *test() { 2179 int *p = A + 10; 2180 return p; // warn 2181 } 2182 2183 int test(void) { 2184 int x; 2185 return x; // warn: undefined or garbage returned 2186 } 2187 2188.. _alpha-security-taint-TaintPropagation: 2189 2190alpha.security.taint.TaintPropagation (C, C++) 2191"""""""""""""""""""""""""""""""""""""""""""""" 2192Generate taint information used by other checkers. 2193A data is tainted when it comes from an unreliable source. 2194 2195.. code-block:: c 2196 2197 void test() { 2198 char x = getchar(); // 'x' marked as tainted 2199 system(&x); // warn: untrusted data is passed to a system call 2200 } 2201 2202 // note: compiler internally checks if the second param to 2203 // sprintf is a string literal or not. 2204 // Use -Wno-format-security to suppress compiler warning. 2205 void test() { 2206 char s[10], buf[10]; 2207 fscanf(stdin, "%s", s); // 's' marked as tainted 2208 2209 sprintf(buf, s); // warn: untrusted data as a format string 2210 } 2211 2212 void test() { 2213 size_t ts; 2214 scanf("%zd", &ts); // 'ts' marked as tainted 2215 int *p = (int *)malloc(ts * sizeof(int)); 2216 // warn: untrusted data as buffer size 2217 } 2218 2219alpha.unix 2220^^^^^^^^^^^ 2221 2222.. _alpha-unix-BlockInCriticalSection: 2223 2224alpha.unix.BlockInCriticalSection (C) 2225""""""""""""""""""""""""""""""""""""" 2226Check for calls to blocking functions inside a critical section. 2227Applies to: ``lock, unlock, sleep, getc, fgets, read, recv, pthread_mutex_lock,`` 2228`` pthread_mutex_unlock, mtx_lock, mtx_timedlock, mtx_trylock, mtx_unlock, lock_guard, unique_lock`` 2229 2230.. code-block:: c 2231 2232 void test() { 2233 std::mutex m; 2234 m.lock(); 2235 sleep(3); // warn: a blocking function sleep is called inside a critical 2236 // section 2237 m.unlock(); 2238 } 2239 2240.. _alpha-unix-Chroot: 2241 2242alpha.unix.Chroot (C) 2243""""""""""""""""""""" 2244Check improper use of chroot. 2245 2246.. code-block:: c 2247 2248 void f(); 2249 2250 void test() { 2251 chroot("/usr/local"); 2252 f(); // warn: no call of chdir("/") immediately after chroot 2253 } 2254 2255.. _alpha-unix-PthreadLock: 2256 2257alpha.unix.PthreadLock (C) 2258"""""""""""""""""""""""""" 2259Simple lock -> unlock checker. 2260Applies to: ``pthread_mutex_lock, pthread_rwlock_rdlock, pthread_rwlock_wrlock, lck_mtx_lock, lck_rw_lock_exclusive`` 2261``lck_rw_lock_shared, pthread_mutex_trylock, pthread_rwlock_tryrdlock, pthread_rwlock_tryrwlock, lck_mtx_try_lock, 2262lck_rw_try_lock_exclusive, lck_rw_try_lock_shared, pthread_mutex_unlock, pthread_rwlock_unlock, lck_mtx_unlock, lck_rw_done``. 2263 2264 2265.. code-block:: c 2266 2267 pthread_mutex_t mtx; 2268 2269 void test() { 2270 pthread_mutex_lock(&mtx); 2271 pthread_mutex_lock(&mtx); 2272 // warn: this lock has already been acquired 2273 } 2274 2275 lck_mtx_t lck1, lck2; 2276 2277 void test() { 2278 lck_mtx_lock(&lck1); 2279 lck_mtx_lock(&lck2); 2280 lck_mtx_unlock(&lck1); 2281 // warn: this was not the most recently acquired lock 2282 } 2283 2284 lck_mtx_t lck1, lck2; 2285 2286 void test() { 2287 if (lck_mtx_try_lock(&lck1) == 0) 2288 return; 2289 2290 lck_mtx_lock(&lck2); 2291 lck_mtx_unlock(&lck1); 2292 // warn: this was not the most recently acquired lock 2293 } 2294 2295.. _alpha-unix-SimpleStream: 2296 2297alpha.unix.SimpleStream (C) 2298""""""""""""""""""""""""""" 2299Check for misuses of stream APIs. Check for misuses of stream APIs: ``fopen, fclose`` 2300(demo checker, the subject of the demo (`Slides <https://llvm.org/devmtg/2012-11/Zaks-Rose-Checker24Hours.pdf>`_ , 2301`Video <https://youtu.be/kdxlsP5QVPw>`_) by Anna Zaks and Jordan Rose presented at the 2302`2012 LLVM Developers' Meeting <https://llvm.org/devmtg/2012-11/>`_). 2303 2304.. code-block:: c 2305 2306 void test() { 2307 FILE *F = fopen("myfile.txt", "w"); 2308 } // warn: opened file is never closed 2309 2310 void test() { 2311 FILE *F = fopen("myfile.txt", "w"); 2312 2313 if (F) 2314 fclose(F); 2315 2316 fclose(F); // warn: closing a previously closed file stream 2317 } 2318 2319.. _alpha-unix-Stream: 2320 2321alpha.unix.Stream (C) 2322""""""""""""""""""""" 2323Check stream handling functions: ``fopen, tmpfile, fclose, fread, fwrite, fseek, ftell, rewind, fgetpos,`` 2324``fsetpos, clearerr, feof, ferror, fileno``. 2325 2326.. code-block:: c 2327 2328 void test() { 2329 FILE *p = fopen("foo", "r"); 2330 } // warn: opened file is never closed 2331 2332 void test() { 2333 FILE *p = fopen("foo", "r"); 2334 fseek(p, 1, SEEK_SET); // warn: stream pointer might be NULL 2335 fclose(p); 2336 } 2337 2338 void test() { 2339 FILE *p = fopen("foo", "r"); 2340 2341 if (p) 2342 fseek(p, 1, 3); 2343 // warn: third arg should be SEEK_SET, SEEK_END, or SEEK_CUR 2344 2345 fclose(p); 2346 } 2347 2348 void test() { 2349 FILE *p = fopen("foo", "r"); 2350 fclose(p); 2351 fclose(p); // warn: already closed 2352 } 2353 2354 void test() { 2355 FILE *p = tmpfile(); 2356 ftell(p); // warn: stream pointer might be NULL 2357 fclose(p); 2358 } 2359 2360 2361.. _alpha-unix-cstring-BufferOverlap: 2362 2363alpha.unix.cstring.BufferOverlap (C) 2364"""""""""""""""""""""""""""""""""""" 2365Checks for overlap in two buffer arguments. Applies to: ``memcpy, mempcpy``. 2366 2367.. code-block:: c 2368 2369 void test() { 2370 int a[4] = {0}; 2371 memcpy(a + 2, a + 1, 8); // warn 2372 } 2373 2374.. _alpha-unix-cstring-NotNullTerminated: 2375 2376alpha.unix.cstring.NotNullTerminated (C) 2377"""""""""""""""""""""""""""""""""""""""" 2378Check for arguments which are not null-terminated strings; applies to: ``strlen, strnlen, strcpy, strncpy, strcat, strncat``. 2379 2380.. code-block:: c 2381 2382 void test() { 2383 int y = strlen((char *)&test); // warn 2384 } 2385 2386.. _alpha-unix-cstring-OutOfBounds: 2387 2388alpha.unix.cstring.OutOfBounds (C) 2389"""""""""""""""""""""""""""""""""" 2390Check for out-of-bounds access in string functions; applies to:`` strncopy, strncat``. 2391 2392 2393.. code-block:: c 2394 2395 void test() { 2396 int y = strlen((char *)&test); // warn 2397 } 2398 2399.. _alpha-nondeterminism-PointerIteration: 2400 2401alpha.nondeterminism.PointerIteration (C++) 2402""""""""""""""""""""""""""""""""""""""""""" 2403Check for non-determinism caused by iterating unordered containers of pointers. 2404 2405.. code-block:: c 2406 2407 void test() { 2408 int a = 1, b = 2; 2409 std::unordered_set<int *> UnorderedPtrSet = {&a, &b}; 2410 2411 for (auto i : UnorderedPtrSet) // warn 2412 f(i); 2413 } 2414 2415.. _alpha-nondeterminism-PointerSorting: 2416 2417alpha.nondeterminism.PointerSorting (C++) 2418""""""""""""""""""""""""""""""""""""""""" 2419Check for non-determinism caused by sorting of pointers. 2420 2421.. code-block:: c 2422 2423 void test() { 2424 int a = 1, b = 2; 2425 std::vector<int *> V = {&a, &b}; 2426 std::sort(V.begin(), V.end()); // warn 2427 } 2428 2429 2430alpha.WebKit 2431^^^^^^^^^^^^ 2432 2433.. _alpha-webkit-UncountedCallArgsChecker: 2434 2435alpha.webkit.UncountedCallArgsChecker 2436""""""""""""""""""""""""""""""""""""" 2437The goal of this rule is to make sure that lifetime of any dynamically allocated ref-countable object passed as a call argument spans past the end of the call. This applies to call to any function, method, lambda, function pointer or functor. Ref-countable types aren't supposed to be allocated on stack so we check arguments for parameters of raw pointers and references to uncounted types. 2438 2439Here are some examples of situations that we warn about as they *might* be potentially unsafe. The logic is that either we're able to guarantee that an argument is safe or it's considered if not a bug then bug-prone. 2440 2441 .. code-block:: cpp 2442 2443 RefCountable* provide_uncounted(); 2444 void consume(RefCountable*); 2445 2446 // In these cases we can't make sure callee won't directly or indirectly call `deref()` on the argument which could make it unsafe from such point until the end of the call. 2447 2448 void foo1() { 2449 consume(provide_uncounted()); // warn 2450 } 2451 2452 void foo2() { 2453 RefCountable* uncounted = provide_uncounted(); 2454 consume(uncounted); // warn 2455 } 2456 2457Although we are enforcing member variables to be ref-counted by `webkit.NoUncountedMemberChecker` any method of the same class still has unrestricted access to these. Since from a caller's perspective we can't guarantee a particular member won't get modified by callee (directly or indirectly) we don't consider values obtained from members safe. 2458 2459Note: It's likely this heuristic could be made more precise with fewer false positives - for example calls to free functions that don't have any parameter other than the pointer should be safe as the callee won't be able to tamper with the member unless it's a global variable. 2460 2461 .. code-block:: cpp 2462 2463 struct Foo { 2464 RefPtr<RefCountable> member; 2465 void consume(RefCountable*) { /* ... */ } 2466 void bugprone() { 2467 consume(member.get()); // warn 2468 } 2469 }; 2470 2471The implementation of this rule is a heuristic - we define a whitelist of kinds of values that are considered safe to be passed as arguments. If we can't prove an argument is safe it's considered an error. 2472 2473Allowed kinds of arguments: 2474 2475- values obtained from ref-counted objects (including temporaries as those survive the call too) 2476 2477 .. code-block:: cpp 2478 2479 RefCountable* provide_uncounted(); 2480 void consume(RefCountable*); 2481 2482 void foo() { 2483 RefPtr<RefCountable> rc = makeRef(provide_uncounted()); 2484 consume(rc.get()); // ok 2485 consume(makeRef(provide_uncounted()).get()); // ok 2486 } 2487 2488- forwarding uncounted arguments from caller to callee 2489 2490 .. code-block:: cpp 2491 2492 void foo(RefCountable& a) { 2493 bar(a); // ok 2494 } 2495 2496 Caller of ``foo()`` is responsible for ``a``'s lifetime. 2497 2498- ``this`` pointer 2499 2500 .. code-block:: cpp 2501 2502 void Foo::foo() { 2503 baz(this); // ok 2504 } 2505 2506 Caller of ``foo()`` is responsible for keeping the memory pointed to by ``this`` pointer safe. 2507 2508- constants 2509 2510 .. code-block:: cpp 2511 2512 foo(nullptr, NULL, 0); // ok 2513 2514We also define a set of safe transformations which if passed a safe value as an input provide (usually it's the return value) a safe value (or an object that provides safe values). This is also a heuristic. 2515 2516- constructors of ref-counted types (including factory methods) 2517- getters of ref-counted types 2518- member overloaded operators 2519- casts 2520- unary operators like ``&`` or ``*`` 2521 2522 2523Debug Checkers 2524--------------- 2525 2526.. _debug-checkers: 2527 2528 2529debug 2530^^^^^ 2531 2532Checkers used for debugging the analyzer. 2533:doc:`developer-docs/DebugChecks` page contains a detailed description. 2534 2535.. _debug-AnalysisOrder: 2536 2537debug.AnalysisOrder 2538""""""""""""""""""" 2539Print callbacks that are called during analysis in order. 2540 2541.. _debug-ConfigDumper: 2542 2543debug.ConfigDumper 2544"""""""""""""""""" 2545Dump config table. 2546 2547.. _debug-DumpCFG Display: 2548 2549debug.DumpCFG Display 2550""""""""""""""""""""" 2551Control-Flow Graphs. 2552 2553.. _debug-DumpCallGraph: 2554 2555debug.DumpCallGraph 2556""""""""""""""""""" 2557Display Call Graph. 2558 2559.. _debug-DumpCalls: 2560 2561debug.DumpCalls 2562""""""""""""""" 2563Print calls as they are traversed by the engine. 2564 2565.. _debug-DumpDominators: 2566 2567debug.DumpDominators 2568"""""""""""""""""""" 2569Print the dominance tree for a given CFG. 2570 2571.. _debug-DumpLiveVars: 2572 2573debug.DumpLiveVars 2574"""""""""""""""""" 2575Print results of live variable analysis. 2576 2577.. _debug-DumpTraversal: 2578 2579debug.DumpTraversal 2580""""""""""""""""""" 2581Print branch conditions as they are traversed by the engine. 2582 2583.. _debug-ExprInspection: 2584 2585debug.ExprInspection 2586"""""""""""""""""""" 2587Check the analyzer's understanding of expressions. 2588 2589.. _debug-Stats: 2590 2591debug.Stats 2592""""""""""" 2593Emit warnings with analyzer statistics. 2594 2595.. _debug-TaintTest: 2596 2597debug.TaintTest 2598""""""""""""""" 2599Mark tainted symbols as such. 2600 2601.. _debug-ViewCFG: 2602 2603debug.ViewCFG 2604""""""""""""" 2605View Control-Flow Graphs using GraphViz. 2606 2607.. _debug-ViewCallGraph: 2608 2609debug.ViewCallGraph 2610""""""""""""""""""" 2611View Call Graph using GraphViz. 2612 2613.. _debug-ViewExplodedGraph: 2614 2615debug.ViewExplodedGraph 2616""""""""""""""""""""""" 2617View Exploded Graphs using GraphViz. 2618 2619