brintos

brintos / llvm-project-archived public Read only

0
0
Text · 116.0 KiB · 31edf9e Raw
4065 lines · plain
1==================2Available Checkers3==================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 Contents16   :depth: 417 18 19.. _default-checkers:20 21Default Checkers22----------------23 24.. _core-checkers:25 26core27^^^^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-BitwiseShift:33 34core.BitwiseShift (C, C++)35""""""""""""""""""""""""""36 37Finds undefined behavior caused by the bitwise left- and right-shift operator38operating on integer types.39 40By default, this checker only reports situations when the right operand is41either negative or larger than the bit width of the type of the left operand;42these are logically unsound.43 44Moreover, if the pedantic mode is activated by45``-analyzer-config core.BitwiseShift:Pedantic=true``, then this checker also46reports situations where the _left_ operand of a shift operator is negative or47overflow occurs during the right shift of a signed value. (Most compilers48handle these predictably, but the C standard and the C++ standards before C++2049say that they're undefined behavior. In the C++20 standard these constructs are50well-defined, so activating pedantic mode in C++20 has no effect.)51 52**Examples**53 54.. code-block:: cpp55 56 static_assert(sizeof(int) == 4, "assuming 32-bit int")57 58 void basic_examples(int a, int b) {59   if (b < 0) {60     b = a << b; // warn: right operand is negative in left shift61   } else if (b >= 32) {62     b = a >> b; // warn: right shift overflows the capacity of 'int'63   }64 }65 66 int pedantic_examples(int a, int b) {67   if (a < 0) {68     return a >> b; // warn: left operand is negative in right shift69   }70   a = 1000u << 31; // OK, overflow of unsigned value is well-defined, a == 071   if (b > 10) {72     a = b << 31; // this is undefined before C++20, but the checker doesn't73                  // warn because it doesn't know the exact value of b74   }75   return 1000 << 31; // warn: this overflows the capacity of 'int'76 }77 78**Solution**79 80Ensure the shift operands are in proper range before shifting.81 82.. _core-CallAndMessage:83 84core.CallAndMessage (C, C++, ObjC)85""""""""""""""""""""""""""""""""""86 Check for logical errors for function calls and Objective-C message expressions (e.g., uninitialized arguments, null function pointers).87 88.. literalinclude:: checkers/callandmessage_example.c89    :language: objc90 91.. _core-DivideZero:92 93core.DivideZero (C, C++, ObjC)94""""""""""""""""""""""""""""""95 Check for division by zero.96 97.. literalinclude:: checkers/dividezero_example.c98    :language: c99 100.. _core-FixedAddressDereference:101 102core.FixedAddressDereference (C, C++, ObjC)103"""""""""""""""""""""""""""""""""""""""""""104Check for dereferences of fixed addresses.105 106A pointer contains a fixed address if it was set to a hard-coded value or it107becomes otherwise obvious that at that point it can have only a single fixed108numerical value.109 110.. code-block:: c111 112 void test1() {113   int *p = (int *)0x020;114   int x = p[0]; // warn115 }116 117 void test2(int *p) {118   if (p == (int *)-1)119     *p = 0; // warn120 }121 122 void test3() {123   int (*p_function)(char, char);124   p_function = (int (*)(char, char))0x04080;125   int x = (*p_function)('x', 'y'); // NO warning yet at functon pointer calls126 }127 128If the analyzer option ``suppress-dereferences-from-any-address-space`` is set129to true (the default value), then this checker never reports dereference of130pointers with a specified address space. If the option is set to false, then131reports from the specific x86 address spaces 256, 257 and 258 are still132suppressed, but fixed address dereferences from other address spaces are133reported.134 135.. _core-NonNullParamChecker:136 137core.NonNullParamChecker (C, C++, ObjC)138"""""""""""""""""""""""""""""""""""""""139Check for null pointers passed as arguments to a function whose arguments are references or marked with the 'nonnull' attribute.140 141.. code-block:: cpp142 143 int f(int *p) __attribute__((nonnull));144 145 void test(int *p) {146   if (!p)147     f(p); // warn148 }149 150.. _core-NullDereference:151 152core.NullDereference (C, C++, ObjC)153"""""""""""""""""""""""""""""""""""154Check for dereferences of null pointers.155 156.. code-block:: objc157 158 // C159 void test(int *p) {160   if (p)161     return;162 163   int x = p[0]; // warn164 }165 166 // C167 void test(int *p) {168   if (!p)169     *p = 0; // warn170 }171 172 // C++173 class C {174 public:175   int x;176 };177 178 void test() {179   C *pc = 0;180   int k = pc->x; // warn181 }182 183 // Objective-C184 @interface MyClass {185 @public186   int x;187 }188 @end189 190 void test() {191   MyClass *obj = 0;192   obj->x = 1; // warn193 }194 195Null pointer dereferences of pointers with address spaces are not always defined196as error. Specifically on x86/x86-64 target if the pointer address space is197256 (x86 GS Segment), 257 (x86 FS Segment), or 258 (x86 SS Segment), a null198dereference is not defined as error. See `X86/X86-64 Language Extensions199<https://clang.llvm.org/docs/LanguageExtensions.html#memory-references-to-specified-segments>`__200for reference.201 202If the analyzer option ``suppress-dereferences-from-any-address-space`` is set203to true (the default value), then this checker never reports dereference of204pointers with a specified address space. If the option is set to false, then205reports from the specific x86 address spaces 256, 257 and 258 are still206suppressed, but null dereferences from other address spaces are reported.207 208.. _core-NullPointerArithm:209 210core.NullPointerArithm (C, C++)211"""""""""""""""""""""""""""""""212Check for undefined arithmetic operations with null pointers.213 214The checker can detect the following cases:215 216  - ``p + x`` and ``x + p`` where ``p`` is a null pointer and ``x`` is a nonzero217    integer value.218  - ``p - x`` where ``p`` is a null pointer and ``x`` is a nonzero integer219    value.220  - ``p1 - p2`` where one of ``p1`` and ``p2`` is null and the other a221    non-null pointer.222 223Result of these operations is undefined according to the standard.224In the above listed cases, the checker will warn even if the expression225described to be "nonzero" or "non-null" has unknown value, because it is likely226that it can have non-zero value during the program execution.227 228.. code-block:: c229 230 void test1(int *p, int offset) {231   if (p)232     return;233 234   int *p1 = p + offset; // warn: 'p' is null, 'offset' is unknown but likely non-zero235 }236 237 void test2(int *p, int offset) {238   if (p) { } // this indicates that it is possible for 'p' to be null239   if (offset == 0)240     return;241 242   int *p1 = p - offset; // warn: 'p' is null, 'offset' is known to be non-zero243 }244 245 void test3(char *p1, char *p2) {246   if (p1)247     return;248 249   int a = p1 - p2; // warn: 'p1' is null, 'p2' can be likely non-null250 }251 252.. _core-StackAddressEscape:253 254core.StackAddressEscape (C)255"""""""""""""""""""""""""""256Check that addresses to stack memory do not escape the function.257 258.. code-block:: c259 260 char const *p;261 262 void test() {263   char const str[] = "string";264   p = str; // warn265 }266 267 void* test() {268    return __builtin_alloca(12); // warn269 }270 271 void test() {272   static int *x;273   int y;274   x = &y; // warn275 }276 277 278.. _core-UndefinedBinaryOperatorResult:279 280core.UndefinedBinaryOperatorResult (C)281""""""""""""""""""""""""""""""""""""""282Check for undefined results of binary operators.283 284.. code-block:: c285 286 void test() {287   int x;288   int y = x + 1; // warn: left operand is garbage289 }290 291.. _core-VLASize:292 293core.VLASize (C)294""""""""""""""""295Check for declarations of Variable Length Arrays (VLA) of undefined, zero or negative296size.297 298.. code-block:: c299 300 void test() {301   int x;302   int vla1[x]; // warn: garbage as size303 }304 305 void test() {306   int x = 0;307   int vla2[x]; // warn: zero size308 }309 310 311The checker also gives warning if the `TaintPropagation` checker is switched on312and an unbound, attacker controlled (tainted) value is used to define313the size of the VLA.314 315.. code-block:: c316 317 void taintedVLA(void) {318   int x;319   scanf("%d", &x);320   int vla[x]; // Declared variable-length array (VLA) has tainted (attacker controlled) size, that can be 0 or negative321 }322 323 void taintedVerfieidVLA(void) {324   int x;325   scanf("%d", &x);326   if (x<1)327     return;328   int vla[x]; // no-warning. The analyzer can prove that x must be positive.329 }330 331 332.. _core-uninitialized-ArraySubscript:333 334core.uninitialized.ArraySubscript (C)335"""""""""""""""""""""""""""""""""""""336Check for uninitialized values used as array subscripts.337 338.. code-block:: c339 340 void test() {341   int i, a[10];342   int x = a[i]; // warn: array subscript is undefined343 }344 345.. _core-uninitialized-Assign:346 347core.uninitialized.Assign (C)348"""""""""""""""""""""""""""""349Check for assigning uninitialized values.350 351.. code-block:: c352 353 void test() {354   int x;355   x |= 1; // warn: left expression is uninitialized356 }357 358.. _core-uninitialized-Branch:359 360core.uninitialized.Branch (C)361"""""""""""""""""""""""""""""362Check for uninitialized values used as branch conditions.363 364.. code-block:: c365 366 void test() {367   int x;368   if (x) // warn369     return;370 }371 372.. _core-uninitialized-CapturedBlockVariable:373 374core.uninitialized.CapturedBlockVariable (C)375""""""""""""""""""""""""""""""""""""""""""""376Check for blocks that capture uninitialized values.377 378.. code-block:: c379 380 void test() {381   int x;382   ^{ int y = x; }(); // warn383 }384 385.. _core-uninitialized-UndefReturn:386 387core.uninitialized.UndefReturn (C)388""""""""""""""""""""""""""""""""""389Check for uninitialized values being returned to the caller.390 391.. code-block:: c392 393 int test() {394   int x;395   return x; // warn396 }397 398.. _core-uninitialized-NewArraySize:399 400core.uninitialized.NewArraySize (C++)401"""""""""""""""""""""""""""""""""""""402 403Check if the element count in new[] is garbage or undefined.404 405.. code-block:: cpp406 407  void test() {408    int n;409    int *arr = new int[n]; // warn: Element count in new[] is a garbage value410    delete[] arr;411  }412 413 414.. _cplusplus-checkers:415 416 417cplusplus418^^^^^^^^^419 420C++ Checkers.421 422.. _cplusplus-ArrayDelete:423 424cplusplus.ArrayDelete (C++)425"""""""""""""""""""""""""""426 427Reports destructions of arrays of polymorphic objects that are destructed as428their base class. If the dynamic type of the array is different from its static429type, calling `delete[]` is undefined.430 431This checker corresponds to the SEI CERT rule `EXP51-CPP: Do not delete an array through a pointer of the incorrect type <https://wiki.sei.cmu.edu/confluence/display/cplusplus/EXP51-CPP.+Do+not+delete+an+array+through+a+pointer+of+the+incorrect+type>`_.432 433.. code-block:: cpp434 435 class Base {436 public:437   virtual ~Base() {}438 };439 class Derived : public Base {};440 441 Base *create() {442   Base *x = new Derived[10]; // note: Casting from 'Derived' to 'Base' here443   return x;444 }445 446 void foo() {447   Base *x = create();448   delete[] x; // warn: Deleting an array of 'Derived' objects as their base class 'Base' is undefined449 }450 451**Limitations**452 453The checker does not emit note tags when casting to and from reference types,454even though the pointer values are tracked across references.455 456.. code-block:: cpp457 458 void foo() {459   Derived *d = new Derived[10];460   Derived &dref = *d;461 462   Base &bref = static_cast<Base&>(dref); // no note463   Base *b = &bref;464   delete[] b; // warn: Deleting an array of 'Derived' objects as their base class 'Base' is undefined465 }466 467.. _cplusplus-InnerPointer:468 469cplusplus.InnerPointer (C++)470""""""""""""""""""""""""""""471Check for inner pointers of C++ containers used after re/deallocation.472 473Many container methods in the C++ standard library are known to invalidate474"references" (including actual references, iterators and raw pointers) to475elements of the container. Using such references after they are invalidated476causes undefined behavior, which is a common source of memory errors in C++ that477this checker is capable of finding.478 479The checker is currently limited to ``std::string`` objects and doesn't480recognize some of the more sophisticated approaches to passing unowned pointers481around, such as ``std::string_view``.482 483.. code-block:: cpp484 485 void deref_after_assignment() {486   std::string s = "llvm";487   const char *c = s.data(); // note: pointer to inner buffer of 'std::string' obtained here488   s = "clang"; // note: inner buffer of 'std::string' reallocated by call to 'operator='489   consume(c); // warn: inner pointer of container used after re/deallocation490 }491 492 const char *return_temp(int x) {493   return std::to_string(x).c_str(); // warn: inner pointer of container used after re/deallocation494   // note: pointer to inner buffer of 'std::string' obtained here495   // note: inner buffer of 'std::string' deallocated by call to destructor496 }497 498.. _cplusplus-Move:499 500cplusplus.Move (C++)501""""""""""""""""""""502Find use-after-move bugs in C++. This includes method calls on moved-from503objects, assignment of a moved-from object, and repeated move of a moved-from504object.505 506.. code-block:: cpp507 508 struct A {509   void foo() {}510 };511 512 void f1() {513   A a;514   A b = std::move(a); // note: 'a' became 'moved-from' here515   a.foo();            // warn: method call on a 'moved-from' object 'a'516 }517 518 void f2() {519   A a;520   A b = std::move(a);521   A c(std::move(a)); // warn: move of an already moved-from object522 }523 524 void f3() {525   A a;526   A b = std::move(a);527   b = a; // warn: copy of moved-from object528 }529 530The checker option ``WarnOn`` controls on what objects the use-after-move is531checked:532 533* The most strict value is ``KnownsOnly``, in this mode only objects are534  checked whose type is known to be move-unsafe. These include most STL objects535  (but excluding move-safe ones) and smart pointers.536* With option value ``KnownsAndLocals`` local variables (of any type) are537  additionally checked. The idea behind this is that local variables are538  usually not tempting to be re-used so an use after move is more likely a bug539  than with member variables.540* With option value ``All`` any use-after move condition is checked on all541  kinds of variables, excluding global variables and known move-safe cases.542 543Default value is ``KnownsAndLocals``.544 545Calls of methods named ``empty()`` or ``isEmpty()`` are allowed on moved-from546objects because these methods are considered as move-safe. Functions called547``reset()``, ``destroy()``, ``clear()``, ``assign``, ``resize``,  ``shrink`` are548treated as state-reset functions and are allowed on moved-from objects, these549make the object valid again. This applies to any type of object (not only STL550ones).551 552.. _cplusplus-NewDelete:553 554cplusplus.NewDelete (C++)555"""""""""""""""""""""""""556Check for double-free and use-after-free problems. Traces memory managed by new/delete.557 558Custom allocation/deallocation functions can be defined using559:ref:`ownership attributes<analyzer-ownership-attrs>`.560 561.. literalinclude:: checkers/newdelete_example.cpp562    :language: cpp563 564.. _cplusplus-NewDeleteLeaks:565 566cplusplus.NewDeleteLeaks (C++)567""""""""""""""""""""""""""""""568Check for memory leaks. Traces memory managed by new/delete.569 570Custom allocation/deallocation functions can be defined using571:ref:`ownership attributes<analyzer-ownership-attrs>`.572 573.. code-block:: cpp574 575 void test() {576   int *p = new int;577 } // warn578 579.. _cplusplus-PlacementNew:580 581cplusplus.PlacementNew (C++)582""""""""""""""""""""""""""""583Check if default placement new is provided with pointers to sufficient storage capacity.584 585.. code-block:: cpp586 587 #include <new>588 589 void f() {590   short s;591   long *lp = ::new (&s) long; // warn592 }593 594.. _cplusplus-SelfAssignment:595 596cplusplus.SelfAssignment (C++)597""""""""""""""""""""""""""""""598Checks C++ copy and move assignment operators for self assignment.599 600.. _cplusplus-StringChecker:601 602cplusplus.StringChecker (C++)603"""""""""""""""""""""""""""""604Checks std::string operations.605 606Checks if the cstring pointer from which the ``std::string`` object is607constructed is ``NULL`` or not.608If the checker cannot reason about the nullness of the pointer it will assume609that it was non-null to satisfy the precondition of the constructor.610 611This checker is capable of checking the `SEI CERT C++ coding rule STR51-CPP.612Do not attempt to create a std::string from a null pointer613<https://wiki.sei.cmu.edu/confluence/x/E3s-BQ>`__.614 615.. code-block:: cpp616 617 #include <string>618 619 void f(const char *p) {620   if (!p) {621     std::string msg(p); // warn: The parameter must not be null622   }623 }624 625.. _cplusplus-PureVirtualCall:626 627cplusplus.PureVirtualCall (C++)628"""""""""""""""""""""""""""""""629 630When `virtual methods are called during construction and destruction631<https://en.cppreference.com/w/cpp/language/virtual#During_construction_and_destruction>`__632the polymorphism is restricted to the class that's being constructed or633destructed because the more derived contexts are either not yet initialized or634already destructed.635 636This checker reports situations where this restricted polymorphism causes a637call to a pure virtual method, which is undefined behavior. (See also the638related checker :ref:`optin-cplusplus-VirtualCall` which reports situations639where the restricted polymorphism affects a call and the called method is not640pure virtual – but may be still surprising for the programmer.)641 642.. code-block:: cpp643 644 struct A {645   virtual int getKind() = 0;646 647   A() {648     // warn: This calls the pure virtual method A::getKind().649     log << "Constructing " << getKind();650   }651   virtual ~A() {652     releaseResources();653   }654   void releaseResources() {655     // warn: This can call the pure virtual method A::getKind() when this is656     // called from the destructor.657     callSomeFunction(getKind());658   }659 };660 661.. _deadcode-checkers:662 663deadcode664^^^^^^^^665 666Dead Code Checkers.667 668.. _deadcode-DeadStores:669 670deadcode.DeadStores (C)671"""""""""""""""""""""""672Check for values stored to variables that are never read afterwards.673 674.. code-block:: c675 676 void test() {677   int x;678   x = 1; // warn679 }680 681The ``WarnForDeadNestedAssignments`` option enables the checker to emit682warnings for nested dead assignments. You can disable with the683``-analyzer-config deadcode.DeadStores:WarnForDeadNestedAssignments=false``.684*Defaults to true*.685 686Would warn for this e.g.:687if ((y = make_int())) {688}689 690.. _nullability-checkers:691 692nullability693^^^^^^^^^^^694 695Checkers (mostly Objective C) that warn for null pointer passing and dereferencing errors.696 697.. _nullability-NullPassedToNonnull:698 699nullability.NullPassedToNonnull (ObjC)700""""""""""""""""""""""""""""""""""""""701Warns when a null pointer is passed to a pointer which has a _Nonnull type.702 703.. code-block:: objc704 705 if (name != nil)706   return;707 // Warning: nil passed to a callee that requires a non-null 1st parameter708 NSString *greeting = [@"Hello " stringByAppendingString:name];709 710.. _nullability-NullReturnedFromNonnull:711 712nullability.NullReturnedFromNonnull (C, C++, ObjC)713""""""""""""""""""""""""""""""""""""""""""""""""""714Warns when a null pointer is returned from a function that has _Nonnull return type.715 716.. code-block:: objc717 718 - (nonnull id)firstChild {719   id result = nil;720   if ([_children count] > 0)721     result = _children[0];722 723   // Warning: nil returned from a method that is expected724   // to return a non-null value725   return result;726 }727 728Warns when a null pointer is returned from a function annotated with ``__attribute__((returns_nonnull))``729 730.. code-block:: cpp731 732 int global;733 __attribute__((returns_nonnull)) void* getPtr(void* p);734 735 void* getPtr(void* p) {736   if (p) { // forgot to negate the condition737     return &global;738   }739   // Warning: nullptr returned from a function that is expected740   // to return a non-null value741   return p;742 }743 744.. _nullability-NullableDereferenced:745 746nullability.NullableDereferenced (ObjC)747"""""""""""""""""""""""""""""""""""""""748Warns when a nullable pointer is dereferenced.749 750.. code-block:: objc751 752 struct LinkedList {753   int data;754   struct LinkedList *next;755 };756 757 struct LinkedList * _Nullable getNext(struct LinkedList *l);758 759 void updateNextData(struct LinkedList *list, int newData) {760   struct LinkedList *next = getNext(list);761   // Warning: Nullable pointer is dereferenced762   next->data = 7;763 }764 765.. _nullability-NullablePassedToNonnull:766 767nullability.NullablePassedToNonnull (ObjC)768""""""""""""""""""""""""""""""""""""""""""769Warns when a nullable pointer is passed to a pointer which has a _Nonnull type.770 771.. code-block:: objc772 773 typedef struct Dummy { int val; } Dummy;774 Dummy *_Nullable returnsNullable();775 void takesNonnull(Dummy *_Nonnull);776 777 void test() {778   Dummy *p = returnsNullable();779   takesNonnull(p); // warn780 }781 782.. _nullability-NullableReturnedFromNonnull:783 784nullability.NullableReturnedFromNonnull (ObjC)785""""""""""""""""""""""""""""""""""""""""""""""786Warns when a nullable pointer is returned from a function that has _Nonnull return type.787 788.. _optin-checkers:789 790optin791^^^^^792 793Checkers for portability, performance, optional security and coding style specific rules.794 795.. _optin-core-EnumCastOutOfRange:796 797optin.core.EnumCastOutOfRange (C, C++)798""""""""""""""""""""""""""""""""""""""799Check for integer to enumeration casts that would produce a value with no800corresponding enumerator. This is not necessarily undefined behavior, but can801lead to nasty surprises, so projects may decide to use a coding standard that802disallows these "unusual" conversions.803 804Note that no warnings are produced when the enum type (e.g. `std::byte`) has no805enumerators at all.806 807.. code-block:: cpp808 809 enum WidgetKind { A=1, B, C, X=99 };810 811 void foo() {812   WidgetKind c = static_cast<WidgetKind>(3);  // OK813   WidgetKind x = static_cast<WidgetKind>(99); // OK814   WidgetKind d = static_cast<WidgetKind>(4);  // warn815 }816 817**Limitations**818 819This checker does not accept the coding pattern where an enum type is used to820store combinations of flag values.821Such enums should be annotated with the `__attribute__((flag_enum))` or by the822`[[clang::flag_enum]]` attribute to signal this intent. Refer to the823`documentation <https://clang.llvm.org/docs/AttributeReference.html#flag-enum>`_824of this Clang attribute.825 826.. code-block:: cpp827 828 enum AnimalFlags829 {830     HasClaws   = 1,831     CanFly     = 2,832     EatsFish   = 4,833     Endangered = 8834 };835 836 AnimalFlags operator|(AnimalFlags a, AnimalFlags b)837 {838     return static_cast<AnimalFlags>(static_cast<int>(a) | static_cast<int>(b));839 }840 841 auto flags = HasClaws | CanFly;842 843Projects that use this pattern should not enable this optin checker.844 845.. _optin-cplusplus-UninitializedObject:846 847optin.cplusplus.UninitializedObject (C++)848"""""""""""""""""""""""""""""""""""""""""849 850This checker reports uninitialized fields in objects created after a constructor851call. It doesn't only find direct uninitialized fields, but rather makes a deep852inspection of the object, analyzing all of its fields' subfields.853The checker regards inherited fields as direct fields, so one will receive854warnings for uninitialized inherited data members as well.855 856.. code-block:: cpp857 858 // With Pedantic and CheckPointeeInitialization set to true859 860 struct A {861   struct B {862     int x; // note: uninitialized field 'this->b.x'863     // note: uninitialized field 'this->bptr->x'864     int y; // note: uninitialized field 'this->b.y'865     // note: uninitialized field 'this->bptr->y'866   };867   int *iptr; // note: uninitialized pointer 'this->iptr'868   B b;869   B *bptr;870   char *cptr; // note: uninitialized pointee 'this->cptr'871 872   A (B *bptr, char *cptr) : bptr(bptr), cptr(cptr) {}873 };874 875 void f() {876   A::B b;877   char c;878   A a(&b, &c); // warning: 6 uninitialized fields879  //          after the constructor call880 }881 882 // With Pedantic set to false and883 // CheckPointeeInitialization set to true884 // (every field is uninitialized)885 886 struct A {887   struct B {888     int x;889     int y;890   };891   int *iptr;892   B b;893   B *bptr;894   char *cptr;895 896   A (B *bptr, char *cptr) : bptr(bptr), cptr(cptr) {}897 };898 899 void f() {900   A::B b;901   char c;902   A a(&b, &c); // no warning903 }904 905 // With Pedantic set to true and906 // CheckPointeeInitialization set to false907 // (pointees are regarded as initialized)908 909 struct A {910   struct B {911     int x; // note: uninitialized field 'this->b.x'912     int y; // note: uninitialized field 'this->b.y'913   };914   int *iptr; // note: uninitialized pointer 'this->iptr'915   B b;916   B *bptr;917   char *cptr;918 919   A (B *bptr, char *cptr) : bptr(bptr), cptr(cptr) {}920 };921 922 void f() {923   A::B b;924   char c;925   A a(&b, &c); // warning: 3 uninitialized fields926  //          after the constructor call927 }928 929 930**Options**931 932This checker has several options which can be set from command line (e.g.933``-analyzer-config optin.cplusplus.UninitializedObject:Pedantic=true``):934 935* ``Pedantic`` (boolean). If to false, the checker won't emit warnings for936  objects that don't have at least one initialized field. Defaults to false.937 938* ``NotesAsWarnings``  (boolean). If set to true, the checker will emit a939  warning for each uninitialized field, as opposed to emitting one warning per940  constructor call, and listing the uninitialized fields that belongs to it in941  notes. *Defaults to false*.942 943* ``CheckPointeeInitialization`` (boolean). If set to false, the checker will944  not analyze the pointee of pointer/reference fields, and will only check945  whether the object itself is initialized. *Defaults to false*.946 947* ``IgnoreRecordsWithField`` (string). If supplied, the checker will not analyze948  structures that have a field with a name or type name that matches  the given949  pattern. *Defaults to ""*.950 951.. _optin-cplusplus-VirtualCall:952 953optin.cplusplus.VirtualCall (C++)954"""""""""""""""""""""""""""""""""955 956When `virtual methods are called during construction and destruction957<https://en.cppreference.com/w/cpp/language/virtual#During_construction_and_destruction>`__958the polymorphism is restricted to the class that's being constructed or959destructed because the more derived contexts are either not yet initialized or960already destructed.961 962Although this behavior is well-defined, it can surprise the programmer and963cause unintended behavior, so this checker reports calls that appear to be964virtual calls but can be affected by this restricted polymorphism.965 966Note that situations where this restricted polymorphism causes a call to a pure967virtual method (which is definitely invalid, triggers undefined behavior) are968**reported by another checker:** :ref:`cplusplus-PureVirtualCall` and **this969checker does not report them**.970 971.. code-block:: cpp972 973 struct A {974   virtual int getKind();975 976   A() {977     // warn: This calls A::getKind() even if we are constructing an instance978     // of a different class that is derived from A.979     log << "Constructing " << getKind();980   }981   virtual ~A() {982     releaseResources();983   }984   void releaseResources() {985     // warn: This can be called within ~A() and calls A::getKind() even if986     // we are destructing a class that is derived from A.987     callSomeFunction(getKind());988   }989 };990 991.. _optin-mpi-MPI-Checker:992 993optin.mpi.MPI-Checker (C)994"""""""""""""""""""""""""995Checks MPI code.996 997.. code-block:: c998 999 void test() {1000   double buf = 0;1001   MPI_Request sendReq1;1002   MPI_Ireduce(MPI_IN_PLACE, &buf, 1, MPI_DOUBLE, MPI_SUM,1003       0, MPI_COMM_WORLD, &sendReq1);1004 } // warn: request 'sendReq1' has no matching wait.1005 1006 void test() {1007   double buf = 0;1008   MPI_Request sendReq;1009   MPI_Isend(&buf, 1, MPI_DOUBLE, 0, 0, MPI_COMM_WORLD, &sendReq);1010   MPI_Irecv(&buf, 1, MPI_DOUBLE, 0, 0, MPI_COMM_WORLD, &sendReq); // warn1011   MPI_Isend(&buf, 1, MPI_DOUBLE, 0, 0, MPI_COMM_WORLD, &sendReq); // warn1012   MPI_Wait(&sendReq, MPI_STATUS_IGNORE);1013 }1014 1015 void missingNonBlocking() {1016   int rank = 0;1017   MPI_Comm_rank(MPI_COMM_WORLD, &rank);1018   MPI_Request sendReq1[10][10][10];1019   MPI_Wait(&sendReq1[1][7][9], MPI_STATUS_IGNORE); // warn1020 }1021 1022.. _optin-osx-cocoa-localizability-EmptyLocalizationContextChecker:1023 1024optin.osx.cocoa.localizability.EmptyLocalizationContextChecker (ObjC)1025"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""1026Check that NSLocalizedString macros include a comment for context.1027 1028.. code-block:: objc1029 1030 - (void)test {1031   NSString *string = NSLocalizedString(@"LocalizedString", nil); // warn1032   NSString *string2 = NSLocalizedString(@"LocalizedString", @" "); // warn1033   NSString *string3 = NSLocalizedStringWithDefaultValue(1034     @"LocalizedString", nil, [[NSBundle alloc] init], nil,@""); // warn1035 }1036 1037.. _optin-osx-cocoa-localizability-NonLocalizedStringChecker:1038 1039optin.osx.cocoa.localizability.NonLocalizedStringChecker (ObjC)1040"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""1041Warns about uses of non-localized NSStrings passed to UI methods expecting localized NSStrings.1042 1043.. code-block:: objc1044 1045 NSString *alarmText =1046   NSLocalizedString(@"Enabled", @"Indicates alarm is turned on");1047 if (!isEnabled) {1048   alarmText = @"Disabled";1049 }1050 UILabel *alarmStateLabel = [[UILabel alloc] init];1051 1052 // Warning: User-facing text should use localized string macro1053 [alarmStateLabel setText:alarmText];1054 1055.. _optin-performance-GCDAntipattern:1056 1057optin.performance.GCDAntipattern1058""""""""""""""""""""""""""""""""1059Check for performance anti-patterns when using Grand Central Dispatch.1060 1061.. _optin-performance-Padding:1062 1063optin.performance.Padding (C, C++, ObjC)1064""""""""""""""""""""""""""""""""""""""""1065Check for excessively padded structs.1066 1067This checker detects structs with excessive padding, which can lead to wasted1068memory thus decreased performance by reducing the effectiveness of the1069processor cache. Padding bytes are added by compilers to align data accesses1070as some processors require data to be aligned to certain boundaries. On others,1071unaligned data access are possible, but impose significantly larger latencies.1072 1073To avoid padding bytes, the fields of a struct should be ordered by decreasing1074by alignment. Usually, its easier to think of the ``sizeof`` of the fields, and1075ordering the fields by ``sizeof`` would usually also lead to the same optimal1076layout.1077 1078In rare cases, one can use the ``#pragma pack(1)`` directive to enforce a packed1079layout too, but it can significantly increase the access times, so reordering the1080fields is usually a better solution.1081 1082 1083.. code-block:: cpp1084 1085 // warn: Excessive padding in 'struct NonOptimal' (35 padding bytes, where 3 is optimal)1086 struct NonOptimal {1087   char c1;1088   // 7 bytes of padding1089   std::int64_t big1; // 8 bytes1090   char c2;1091   // 7 bytes of padding1092   std::int64_t big2; // 8 bytes1093   char c3;1094   // 7 bytes of padding1095   std::int64_t big3; // 8 bytes1096   char c4;1097   // 7 bytes of padding1098   std::int64_t big4; // 8 bytes1099   char c5;1100   // 7 bytes of padding1101 };1102 static_assert(sizeof(NonOptimal) == 4*8+5+5*7);1103 1104 // no-warning: The fields are nicely aligned to have the minimal amount of padding bytes.1105 struct Optimal {1106   std::int64_t big1; // 8 bytes1107   std::int64_t big2; // 8 bytes1108   std::int64_t big3; // 8 bytes1109   std::int64_t big4; // 8 bytes1110   char c1;1111   char c2;1112   char c3;1113   char c4;1114   char c5;1115   // 3 bytes of padding1116 };1117 static_assert(sizeof(Optimal) == 4*8+5+3);1118 1119 // no-warning: Bit packing representation is also accepted by this checker, but1120 // it can significantly increase access times, so prefer reordering the fields.1121 #pragma pack(1)1122 struct BitPacked {1123   char c1;1124   std::int64_t big1; // 8 bytes1125   char c2;1126   std::int64_t big2; // 8 bytes1127   char c3;1128   std::int64_t big3; // 8 bytes1129   char c4;1130   std::int64_t big4; // 8 bytes1131   char c5;1132 };1133 static_assert(sizeof(BitPacked) == 4*8+5);1134 1135The ``AllowedPad`` option can be used to specify a threshold for the number1136padding bytes raising the warning. If the number of padding bytes of the struct1137and the optimal number of padding bytes differ by more than the threshold value,1138a warning will be raised.1139 1140By default, the ``AllowedPad`` threshold is 24 bytes.1141 1142To override this threshold to e.g. 4 bytes, use the1143``-analyzer-config optin.performance.Padding:AllowedPad=4`` option.1144 1145 1146.. _optin-portability-UnixAPI:1147 1148optin.portability.UnixAPI1149"""""""""""""""""""""""""1150Reports situations where 0 is passed as the "size" argument of various1151allocation functions ( ``calloc``, ``malloc``, ``realloc``, ``reallocf``,1152``alloca``, ``__builtin_alloca``, ``__builtin_alloca_with_align``, ``valloc``).1153 1154Note that similar functionality is also supported by :ref:`unix-Malloc` which1155reports code that *uses* memory allocated with size zero.1156 1157(The name of this checker is motivated by the fact that it was originally1158introduced with the vague goal that it "Finds implementation-defined behavior1159in UNIX/Posix functions.")1160 1161 1162optin.taint1163^^^^^^^^^^^1164 1165Checkers implementing1166`taint analysis <https://en.wikipedia.org/wiki/Taint_checking>`_.1167 1168.. _optin-taint-GenericTaint:1169 1170optin.taint.GenericTaint (C, C++)1171"""""""""""""""""""""""""""""""""1172 1173Taint analysis identifies potential security vulnerabilities where the1174attacker can inject malicious data to the program to execute an attack1175(privilege escalation, command injection, SQL injection etc.).1176 1177The malicious data is injected at the taint source (e.g. ``getenv()`` call)1178which is then propagated through function calls and being used as arguments of1179sensitive operations, also called as taint sinks (e.g. ``system()`` call).1180 1181One can defend against this type of vulnerability by always checking and1182sanitizing the potentially malicious, untrusted user input.1183 1184The goal of the checker is to discover and show to the user these potential1185taint source-sink pairs and the propagation call chain.1186 1187The most notable examples of taint sources are:1188 1189  - data from network1190  - files or standard input1191  - environment variables1192  - data from databases1193 1194Let us examine a practical example of a Command Injection attack.1195 1196.. code-block:: c1197 1198  // Command Injection Vulnerability Example1199  int main(int argc, char** argv) {1200    char cmd[2048] = "/bin/cat ";1201    char filename[1024];1202    printf("Filename:");1203    scanf (" %1023[^\n]", filename); // The attacker can inject a shell escape here1204    strcat(cmd, filename);1205    system(cmd); // Warning: Untrusted data is passed to a system call1206  }1207 1208The program prints the content of any user specified file.1209Unfortunately the attacker can execute arbitrary commands1210with shell escapes. For example with the following input the `ls` command is also1211executed after the contents of `/etc/shadow` is printed.1212`Input: /etc/shadow ; ls /`1213 1214The analysis implemented in this checker points out this problem.1215 1216One can protect against such attack by for example checking if the provided1217input refers to a valid file and removing any invalid user input.1218 1219.. code-block:: c1220 1221  // No vulnerability anymore, but we still get the warning1222  void sanitizeFileName(char* filename){1223    if (access(filename,F_OK)){// Verifying user input1224      printf("File does not exist\n");1225      filename[0]='\0';1226      }1227  }1228  int main(int argc, char** argv) {1229    char cmd[2048] = "/bin/cat ";1230    char filename[1024];1231    printf("Filename:");1232    scanf (" %1023[^\n]", filename); // The attacker can inject a shell escape here1233    sanitizeFileName(filename);// filename is safe after this point1234    if (!filename[0])1235      return -1;1236    strcat(cmd, filename);1237    system(cmd); // Superfluous Warning: Untrusted data is passed to a system call1238  }1239 1240Unfortunately, the checker cannot discover automatically that the programmer1241have performed data sanitation, so it still emits the warning.1242 1243One can get rid of this superfluous warning by telling by specifying the1244sanitation functions in the taint configuration file (see1245:doc:`user-docs/TaintAnalysisConfiguration`).1246 1247.. code-block:: YAML1248 1249  Filters:1250  - Name: sanitizeFileName1251    Args: [0]1252 1253The clang invocation to pass the configuration file location:1254 1255.. code-block:: bash1256 1257  clang  --analyze -Xclang -analyzer-config  -Xclang optin.taint.TaintPropagation:Config=`pwd`/taint_config.yml ...1258 1259If you are validating your inputs instead of sanitizing them, or don't want to1260mention each sanitizing function in our configuration,1261you can use a more generic approach.1262 1263Introduce a generic no-op `csa_mark_sanitized(..)` function to1264tell the Clang Static Analyzer1265that the variable is safe to be used on that analysis path.1266 1267.. code-block:: c1268 1269  // Marking sanitized variables safe.1270  // No vulnerability anymore, no warning.1271 1272  // User csa_mark_sanitize function is for the analyzer only1273  #ifdef __clang_analyzer__1274    void csa_mark_sanitized(const void *);1275  #endif1276 1277  int main(int argc, char** argv) {1278    char cmd[2048] = "/bin/cat ";1279    char filename[1024];1280    printf("Filename:");1281    scanf (" %1023[^\n]", filename);1282    if (access(filename,F_OK)){// Verifying user input1283      printf("File does not exist\n");1284      return -1;1285    }1286    #ifdef __clang_analyzer__1287      csa_mark_sanitized(filename); // Indicating to CSA that filename variable is safe to be used after this point1288    #endif1289    strcat(cmd, filename);1290    system(cmd); // No warning1291  }1292 1293Similarly to the previous example, you need to1294define a `Filter` function in a `YAML` configuration file1295and add the `csa_mark_sanitized` function.1296 1297.. code-block:: YAML1298 1299  Filters:1300  - Name: csa_mark_sanitized1301    Args: [0]1302 1303Then calling `csa_mark_sanitized(X)` will tell the analyzer that `X` is safe to1304be used after this point, because its contents are verified. It is the1305responsibility of the programmer to ensure that this verification was indeed1306correct. Please note that `csa_mark_sanitized` function is only declared and1307used during Clang Static Analysis and skipped in (production) builds.1308 1309Further examples of injection vulnerabilities this checker can find.1310 1311.. code-block:: c1312 1313  void test() {1314    char x = getchar(); // 'x' marked as tainted1315    system(&x); // warn: untrusted data is passed to a system call1316  }1317 1318  // note: compiler internally checks if the second param to1319  // sprintf is a string literal or not.1320  // Use -Wno-format-security to suppress compiler warning.1321  void test() {1322    char s[10], buf[10];1323    fscanf(stdin, "%s", s); // 's' marked as tainted1324 1325    sprintf(buf, s); // warn: untrusted data used as a format string1326  }1327 1328There are built-in sources, propagations and sinks even if no external taint1329configuration is provided.1330 1331Default sources:1332 ``_IO_getc``, ``fdopen``, ``fopen``, ``freopen``, ``get_current_dir_name``,1333 ``getch``, ``getchar``, ``getchar_unlocked``, ``getwd``, ``getcwd``,1334 ``getgroups``, ``gethostname``, ``getlogin``, ``getlogin_r``, ``getnameinfo``,1335 ``gets``, ``gets_s``, ``getseuserbyname``, ``readlink``, ``readlinkat``,1336 ``scanf``, ``scanf_s``, ``socket``, ``wgetch``1337 1338Default propagations rules:1339 ``atoi``, ``atol``, ``atoll``, ``basename``, ``dirname``, ``fgetc``,1340 ``fgetln``, ``fgets``, ``fnmatch``, ``fread``, ``fscanf``, ``fscanf_s``,1341 ``index``, ``inflate``, ``isalnum``, ``isalpha``, ``isascii``, ``isblank``,1342 ``iscntrl``, ``isdigit``, ``isgraph``, ``islower``, ``isprint``, ``ispunct``,1343 ``isspace``, ``isupper``, ``isxdigit``, ``memchr``, ``memrchr``, ``sscanf``,1344 ``getc``, ``getc_unlocked``, ``getdelim``, ``getline``, ``getw``, ``memcmp``,1345 ``memcpy``, ``memmem``, ``memmove``, ``mbtowc``, ``pread``, ``qsort``,1346 ``qsort_r``, ``rawmemchr``, ``read``, ``recv``, ``recvfrom``, ``rindex``,1347 ``strcasestr``, ``strchr``, ``strchrnul``, ``strcasecmp``, ``strcmp``,1348 ``strcspn``, ``strncasecmp``, ``strncmp``, ``strndup``,1349 ``strndupa``, ``strpbrk``, ``strrchr``, ``strsep``, ``strspn``,1350 ``strstr``, ``strtol``, ``strtoll``, ``strtoul``, ``strtoull``, ``tolower``,1351 ``toupper``, ``ttyname``, ``ttyname_r``, ``wctomb``, ``wcwidth``1352 1353Default sinks:1354 ``printf``, ``setproctitle``, ``system``, ``popen``, ``execl``, ``execle``,1355 ``execlp``, ``execv``, ``execvp``, ``execvP``, ``execve``, ``dlopen``1356 1357Please note that there are no built-in filter functions.1358 1359One can configure their own taint sources, sinks, and propagation rules by1360providing a configuration file via checker option1361``optin.taint.TaintPropagation:Config``. The configuration file is in1362`YAML <http://llvm.org/docs/YamlIO.html#introduction-to-yaml>`_ format. The1363taint-related options defined in the config file extend but do not override the1364built-in sources, rules, sinks. The format of the external taint configuration1365file is not stable, and could change without any notice even in a non-backward1366compatible way.1367 1368For a more detailed description of configuration options, please see the1369:doc:`user-docs/TaintAnalysisConfiguration`. For an example see1370:ref:`clangsa-taint-configuration-example`.1371 1372**Configuration**1373 1374* `Config`  Specifies the name of the YAML configuration file. The user can1375  define their own taint sources and sinks.1376 1377**Related Guidelines**1378 1379* `CWE Data Neutralization Issues1380  <https://cwe.mitre.org/data/definitions/137.html>`_1381* `SEI Cert STR02-C. Sanitize data passed to complex subsystems1382  <https://wiki.sei.cmu.edu/confluence/display/c/STR02-C.+Sanitize+data+passed+to+complex+subsystems>`_1383* `SEI Cert ENV33-C. Do not call system()1384  <https://wiki.sei.cmu.edu/confluence/pages/viewpage.action?pageId=87152177>`_1385* `ENV03-C. Sanitize the environment when invoking external programs1386  <https://wiki.sei.cmu.edu/confluence/display/c/ENV03-C.+Sanitize+the+environment+when+invoking+external+programs>`_1387 1388**Limitations**1389 1390* The taintedness property is not propagated through function calls which are1391  unknown (or too complex) to the analyzer, unless there is a specific1392  propagation rule built-in to the checker or given in the YAML configuration1393  file. This causes potential true positive findings to be lost.1394 1395 1396.. _optin-taint-TaintedAlloc:1397 1398optin.taint.TaintedAlloc (C, C++)1399"""""""""""""""""""""""""""""""""1400 1401This checker warns for cases when the ``size`` parameter of the ``malloc`` ,1402``calloc``, ``realloc``, ``alloca`` or the size parameter of the1403array new C++ operator is tainted (potentially attacker controlled).1404If an attacker can inject a large value as the size parameter, memory exhaustion1405denial of service attack can be carried out.1406 1407The analyzer emits warning only if it cannot prove that the size parameter is1408within reasonable bounds (``<= SIZE_MAX/4``). This functionality partially1409covers the SEI Cert coding standard rule `INT04-C1410<https://wiki.sei.cmu.edu/confluence/display/c/INT04-C.+Enforce+limits+on+integer+values+originating+from+tainted+sources>`_.1411 1412You can silence this warning either by bound checking the ``size`` parameter, or1413by explicitly marking the ``size`` parameter as sanitized. See the1414:ref:`optin-taint-GenericTaint` checker for an example.1415 1416Custom allocation/deallocation functions can be defined using1417:ref:`ownership attributes<analyzer-ownership-attrs>`.1418 1419.. code-block:: c1420 1421  void vulnerable(void) {1422    size_t size = 0;1423    scanf("%zu", &size);1424    int *p = malloc(size); // warn: malloc is called with a tainted (potentially attacker controlled) value1425    free(p);1426  }1427 1428  void not_vulnerable(void) {1429    size_t size = 0;1430    scanf("%zu", &size);1431    if (1024 < size)1432      return;1433    int *p = malloc(size); // No warning expected as the the user input is bound1434    free(p);1435  }1436 1437  void vulnerable_cpp(void) {1438    size_t size = 0;1439    scanf("%zu", &size);1440    int *ptr = new int[size];// warn: Memory allocation function is called with a tainted (potentially attacker controlled) value1441    delete[] ptr;1442  }1443 1444.. _optin-taint-TaintedDiv:1445 1446optin.taint.TaintedDiv (C, C++, ObjC)1447"""""""""""""""""""""""""""""""""""""1448This checker warns when the denominator in a division1449operation is a tainted (potentially attacker controlled) value.1450If the attacker can set the denominator to 0, a runtime error can1451be triggered. The checker warns when the denominator is a tainted1452value and the analyzer cannot prove that it is not 0. This warning1453is more pessimistic than the :ref:`core-DivideZero` checker1454which warns only when it can prove that the denominator is 0.1455 1456.. code-block:: c1457 1458  int vulnerable(int n) {1459    size_t size = 0;1460    scanf("%zu", &size);1461    return n / size; // warn: Division by a tainted value, possibly zero1462  }1463 1464  int not_vulnerable(int n) {1465    size_t size = 0;1466    scanf("%zu", &size);1467    if (!size)1468      return 0;1469    return n / size; // no warning1470  }1471 1472.. _security-checkers:1473 1474security1475^^^^^^^^1476 1477Security related checkers.1478 1479.. _security-ArrayBound:1480 1481security.ArrayBound (C, C++)1482""""""""""""""""""""""""""""1483Report out of bounds access to memory that is before the start or after the end1484of the accessed region (array, heap-allocated region, string literal etc.).1485This usually means incorrect indexing, but the checker also detects access via1486the operators ``*`` and ``->``.1487 1488.. code-block:: c1489 1490 void test_underflow(int x) {1491   int buf[100][100];1492   if (x < 0)1493     buf[0][x] = 1; // warn1494 }1495 1496 void test_overflow() {1497   int buf[100];1498   int *p = buf + 100;1499   *p = 1; // warn1500 }1501 1502If checkers like :ref:`unix-Malloc` or :ref:`cplusplus-NewDelete` are enabled1503to model the behavior of ``malloc()``, ``operator new`` and similar1504allocators), then this checker can also reports out of bounds access to1505dynamically allocated memory:1506 1507.. code-block:: cpp1508 1509 int *test_dynamic() {1510   int *mem = new int[100];1511   mem[-1] = 42; // warn1512   return mem;1513 }1514 1515In uncertain situations (when the checker can neither prove nor disprove that1516overflow occurs), the checker assumes that the the index (more precisely, the1517memory offeset) is within bounds.1518 1519However, if :ref:`optin-taint-GenericTaint` is enabled and the index/offset is1520tainted (i.e. it is influenced by an untrusted source), then this checker1521reports the potential out of bounds access:1522 1523.. code-block:: c1524 1525 void test_with_tainted_index() {1526   char s[] = "abc";1527   int x = getchar();1528   char c = s[x]; // warn: potential out of bounds access with tainted index1529 }1530 1531.. note::1532 1533  This checker is an improved and renamed version of the checker that was1534  previously known as ``alpha.security.ArrayBoundV2``. The old checker1535  ``alpha.security.ArrayBound`` was removed when the (previously1536  "experimental") V2 variant became stable enough for regular use.1537 1538.. _security-cert-env-InvalidPtr:1539 1540security.cert.env.InvalidPtr1541""""""""""""""""""""""""""""1542 1543Corresponds to SEI CERT Rules `ENV31-C <https://wiki.sei.cmu.edu/confluence/display/c/ENV31-C.+Do+not+rely+on+an+environment+pointer+following+an+operation+that+may+invalidate+it>`_ and `ENV34-C <https://wiki.sei.cmu.edu/confluence/display/c/ENV34-C.+Do+not+store+pointers+returned+by+certain+functions>`_.1544 1545* **ENV31-C**:1546  Rule is about the possible problem with ``main`` function's third argument, environment pointer,1547  "envp". When environment array is modified using some modification function1548  such as ``putenv``, ``setenv`` or others, It may happen that memory is reallocated,1549  however "envp" is not updated to reflect the changes and points to old memory1550  region.1551 1552* **ENV34-C**:1553  Some functions return a pointer to a statically allocated buffer.1554  Consequently, subsequent call of these functions will invalidate previous1555  pointer. These functions include: ``getenv``, ``localeconv``, ``asctime``, ``setlocale``, ``strerror``1556 1557.. code-block:: c1558 1559  int main(int argc, const char *argv[], const char *envp[]) {1560    if (setenv("MY_NEW_VAR", "new_value", 1) != 0) {1561      // setenv call may invalidate 'envp'1562      /* Handle error */1563    }1564    if (envp != NULL) {1565      for (size_t i = 0; envp[i] != NULL; ++i) {1566        puts(envp[i]);1567        // envp may no longer point to the current environment1568        // this program has unanticipated behavior, since envp1569        // does not reflect changes made by setenv function.1570      }1571    }1572    return 0;1573  }1574 1575  void previous_call_invalidation() {1576    char *p, *pp;1577 1578    p = getenv("VAR");1579    setenv("SOMEVAR", "VALUE", /*overwrite = */1);1580    // call to 'setenv' may invalidate p1581 1582    *p;1583    // dereferencing invalid pointer1584  }1585 1586 1587The ``InvalidatingGetEnv`` option is available for treating ``getenv`` calls as1588invalidating. When enabled, the checker issues a warning if ``getenv`` is called1589multiple times and their results are used without first creating a copy.1590This level of strictness might be considered overly pedantic for the commonly1591used ``getenv`` implementations.1592 1593To enable this option, use:1594``-analyzer-config security.cert.env.InvalidPtr:InvalidatingGetEnv=true``.1595 1596By default, this option is set to *false*.1597 1598When this option is enabled, warnings will be generated for scenarios like the1599following:1600 1601.. code-block:: c1602 1603  char* p = getenv("VAR");1604  char* pp = getenv("VAR2"); // assumes this call can invalidate `env`1605  strlen(p); // warns about accessing invalid ptr1606 1607.. _security-FloatLoopCounter:1608 1609security.FloatLoopCounter (C)1610"""""""""""""""""""""""""""""1611Warn on using a floating point value as a loop counter (CERT: FLP30-C, FLP30-CPP).1612 1613.. code-block:: c1614 1615 void test() {1616   for (float x = 0.1f; x <= 1.0f; x += 0.1f) {} // warn1617 }1618 1619.. _security-insecureAPI-UncheckedReturn:1620 1621security.insecureAPI.UncheckedReturn (C)1622""""""""""""""""""""""""""""""""""""""""1623Warn on uses of functions whose return values must be always checked.1624 1625.. code-block:: c1626 1627 void test() {1628   setuid(1); // warn1629 }1630 1631.. _security-insecureAPI-bcmp:1632 1633security.insecureAPI.bcmp (C)1634"""""""""""""""""""""""""""""1635Warn on uses of the 'bcmp' function.1636 1637.. code-block:: c1638 1639 void test() {1640   bcmp(ptr0, ptr1, n); // warn1641 }1642 1643.. _security-insecureAPI-bcopy:1644 1645security.insecureAPI.bcopy (C)1646""""""""""""""""""""""""""""""1647Warn on uses of the 'bcopy' function.1648 1649.. code-block:: c1650 1651 void test() {1652   bcopy(src, dst, n); // warn1653 }1654 1655.. _security-insecureAPI-bzero:1656 1657security.insecureAPI.bzero (C)1658""""""""""""""""""""""""""""""1659Warn on uses of the 'bzero' function.1660 1661.. code-block:: c1662 1663 void test() {1664   bzero(ptr, n); // warn1665 }1666 1667.. _security-insecureAPI-decodeValueOfObjCType:1668 1669security.insecureAPI.decodeValueOfObjCType (C)1670""""""""""""""""""""""""""""""""""""""""""""""1671Warn on uses of the Objective-C method ``-decodeValueOfObjCType:at:``.1672 1673.. code-block:: objc1674 1675  void test(NSCoder *decoder) {1676    unsigned int x;1677    [decoder decodeValueOfObjCType:"I" at:&x]; // warn1678  }1679 1680This diagnostic is emitted only on Apple platforms where the safer1681``-decodeValueOfObjCType:at:size:`` alternative is available1682(iOS 11+, macOS 10.13+, tvOS 11+, watchOS 4.0+).1683 1684.. _security-insecureAPI-getpw:1685 1686security.insecureAPI.getpw (C)1687""""""""""""""""""""""""""""""1688Warn on uses of the 'getpw' function.1689 1690.. code-block:: c1691 1692 void test() {1693   char buff[1024];1694   getpw(2, buff); // warn1695 }1696 1697.. _security-insecureAPI-gets:1698 1699security.insecureAPI.gets (C)1700"""""""""""""""""""""""""""""1701Warn on uses of the 'gets' function.1702 1703.. code-block:: c1704 1705 void test() {1706   char buff[1024];1707   gets(buff); // warn1708 }1709 1710.. _security-insecureAPI-mkstemp:1711 1712security.insecureAPI.mkstemp (C)1713""""""""""""""""""""""""""""""""1714Warn when 'mkstemp' is passed fewer than 6 X's in the format string.1715 1716.. code-block:: c1717 1718 void test() {1719   mkstemp("XX"); // warn1720 }1721 1722.. _security-insecureAPI-mktemp:1723 1724security.insecureAPI.mktemp (C)1725"""""""""""""""""""""""""""""""1726Warn on uses of the ``mktemp`` function.1727 1728.. code-block:: c1729 1730 void test() {1731   char *x = mktemp("/tmp/zxcv"); // warn: insecure, use mkstemp1732 }1733 1734.. _security-insecureAPI-rand:1735 1736security.insecureAPI.rand (C)1737"""""""""""""""""""""""""""""1738Warn on uses of inferior random number generating functions (only if arc4random function is available):1739``drand48, erand48, jrand48, lcong48, lrand48, mrand48, nrand48, random, rand_r``.1740 1741.. code-block:: c1742 1743 void test() {1744   random(); // warn1745 }1746 1747.. _security-insecureAPI-strcpy:1748 1749security.insecureAPI.strcpy (C)1750"""""""""""""""""""""""""""""""1751Warn on uses of the ``strcpy`` and ``strcat`` functions.1752 1753.. code-block:: c1754 1755 void test() {1756   char x[4];1757   char *y = "abcd";1758 1759   strcpy(x, y); // warn1760 }1761 1762 1763.. _security-insecureAPI-vfork:1764 1765security.insecureAPI.vfork (C)1766""""""""""""""""""""""""""""""1767 Warn on uses of the 'vfork' function.1768 1769.. code-block:: c1770 1771 void test() {1772   vfork(); // warn1773 }1774 1775.. _security-insecureAPI-DeprecatedOrUnsafeBufferHandling:1776 1777security.insecureAPI.DeprecatedOrUnsafeBufferHandling (C)1778"""""""""""""""""""""""""""""""""""""""""""""""""""""""""1779 Warn on occurrences of unsafe or deprecated buffer handling functions, which now have a secure variant: ``sprintf, fprintf, vsprintf, scanf, wscanf, fscanf, fwscanf, vscanf, vwscanf, vfscanf, vfwscanf, sscanf, swscanf, vsscanf, vswscanf, swprintf, snprintf, vswprintf, vsnprintf, memcpy, memmove, strncpy, strncat, memset``1780 1781.. code-block:: c1782 1783 void test() {1784   char buf [5];1785   strncpy(buf, "a", 1); // warn1786 }1787 1788.. _security-MmapWriteExec:1789 1790security.MmapWriteExec (C)1791""""""""""""""""""""""""""1792Warn on ``mmap()`` calls with both writable and executable access.1793 1794.. code-block:: c1795 1796 void test(int n) {1797   void *c = mmap(NULL, 32, PROT_READ | PROT_WRITE | PROT_EXEC,1798                  MAP_PRIVATE | MAP_ANON, -1, 0);1799   // warn: Both PROT_WRITE and PROT_EXEC flags are set. This can lead to1800   //       exploitable memory regions, which could be overwritten with malicious1801   //       code1802 }1803 1804.. _security-PointerSub:1805 1806security.PointerSub (C)1807"""""""""""""""""""""""1808Check for pointer subtractions on two pointers pointing to different memory1809chunks. According to the C standard §6.5.6 only subtraction of pointers that1810point into (or one past the end) the same array object is valid (for this1811purpose non-array variables are like arrays of size 1). This checker only1812searches for different memory objects at subtraction, but does not check if the1813array index is correct. Furthermore, only cases are reported where1814stack-allocated objects are involved (no warnings on pointers to memory1815allocated by `malloc`).1816 1817.. code-block:: c1818 1819 void test() {1820   int a, b, c[10], d[10];1821   int x = &c[3] - &c[1];1822   x = &d[4] - &c[1]; // warn: 'c' and 'd' are different arrays1823   x = (&a + 1) - &a;1824   x = &b - &a; // warn: 'a' and 'b' are different variables1825 }1826 1827 struct S {1828   int x[10];1829   int y[10];1830 };1831 1832 void test1() {1833   struct S a[10];1834   struct S b;1835   int d = &a[4] - &a[6];1836   d = &a[0].x[3] - &a[0].x[1];1837   d = a[0].y - a[0].x; // warn: 'S.b' and 'S.a' are different objects1838   d = (char *)&b.y - (char *)&b.x; // warn: different members of the same object1839   d = (char *)&b.y - (char *)&b; // warn: object of type S is not the same array as a member of it1840 }1841 1842There may be existing applications that use code like above for calculating1843offsets of members in a structure, using pointer subtractions. This is still1844undefined behavior according to the standard and code like this can be replaced1845with the `offsetof` macro.1846 1847.. _security-putenv-stack-array:1848 1849security.PutenvStackArray (C)1850"""""""""""""""""""""""""""""1851Finds calls to the ``putenv`` function which pass a pointer to a stack-allocated1852(automatic) array as the argument. Function ``putenv`` does not copy the passed1853string, only a pointer to the data is stored and this data can be read even by1854other threads. Content of a stack-allocated array is likely to be overwritten1855after exiting from the function.1856 1857The problem can be solved by using a static array variable or dynamically1858allocated memory. Even better is to avoid using ``putenv`` (it has other1859problems related to memory leaks) and use ``setenv`` instead.1860 1861The check corresponds to CERT rule1862`POS34-C. Do not call putenv() with a pointer to an automatic variable as the argument1863<https://wiki.sei.cmu.edu/confluence/display/c/POS34-C.+Do+not+call+putenv%28%29+with+a+pointer+to+an+automatic+variable+as+the+argument>`_.1864 1865.. code-block:: c1866 1867  int f() {1868    char env[] = "NAME=value";1869    return putenv(env); // putenv function should not be called with stack-allocated string1870  }1871 1872There is one case where the checker can report a false positive. This is when1873the stack-allocated array is used at `putenv` in a function or code branch that1874does not return (process is terminated on all execution paths).1875 1876Another special case is if the `putenv` is called from function `main`. Here1877the stack is deallocated at the end of the program and it should be no problem1878to use the stack-allocated string (a multi-threaded program may require more1879attention). The checker does not warn for cases when stack space of `main` is1880used at the `putenv` call.1881 1882security.SetgidSetuidOrder (C)1883""""""""""""""""""""""""""""""1884When dropping user-level and group-level privileges in a program by using1885``setuid`` and ``setgid`` calls, it is important to reset the group-level1886privileges (with ``setgid``) first. Function ``setgid`` will likely fail if1887the superuser privileges are already dropped.1888 1889The checker checks for sequences of ``setuid(getuid())`` and1890``setgid(getgid())`` calls (in this order). If such a sequence is found and1891there is no other privilege-changing function call (``seteuid``, ``setreuid``,1892``setresuid`` and the GID versions of these) in between, a warning is1893generated. The checker finds only exactly ``setuid(getuid())`` calls (and the1894GID versions), not for example if the result of ``getuid()`` is stored in a1895variable.1896 1897.. code-block:: c1898 1899 void test1() {1900   // ...1901   // end of section with elevated privileges1902   // reset privileges (user and group) to normal user1903   if (setuid(getuid()) != 0) {1904     handle_error();1905     return;1906   }1907   if (setgid(getgid()) != 0) { // warning: A 'setgid(getgid())' call following a 'setuid(getuid())' call is likely to fail1908     handle_error();1909     return;1910   }1911   // user-ID and group-ID are reset to normal user now1912   // ...1913 }1914 1915In the code above the problem is that ``setuid(getuid())`` removes superuser1916privileges before ``setgid(getgid())`` is called. To fix the problem the1917``setgid(getgid())`` should be called first. Further attention is needed to1918avoid code like ``setgid(getuid())`` (this checker does not detect bugs like1919this) and always check the return value of these calls.1920 1921This check corresponds to SEI CERT Rule `POS36-C <https://wiki.sei.cmu.edu/confluence/display/c/POS36-C.+Observe+correct+revocation+order+while+relinquishing+privileges>`_.1922 1923.. _security-VAList:1924 1925security.VAList (C, C++)1926""""""""""""""""""""""""1927Reports use of uninitialized (or already released) ``va_list`` objects and1928situations where a ``va_start`` call is not followed by ``va_end``.1929 1930.. code-block:: c1931 1932 int test_use_after_release(int x, ...) {1933   va_list va;1934   va_start(va, x);1935   va_end(va);1936   return va_arg(va, int); // warn: va is uninitialized1937 }1938 1939 void test_leak(int x, ...) {1940   va_list va;1941   va_start(va, x);1942 } // warn: va is leaked1943 1944.. _unix-checkers:1945 1946unix1947^^^^1948POSIX/Unix checkers.1949 1950.. _unix-API:1951 1952unix.API (C)1953""""""""""""1954Check calls to various UNIX/Posix functions: ``open, pthread_once, calloc, malloc, realloc, alloca``.1955 1956.. literalinclude:: checkers/unix_api_example.c1957    :language: c1958 1959.. _unix-BlockInCriticalSection:1960 1961unix.BlockInCriticalSection (C, C++)1962""""""""""""""""""""""""""""""""""""1963Check for calls to blocking functions inside a critical section.1964Blocking functions detected by this checker: ``sleep, getc, fgets, read, recv``.1965Critical section handling functions modeled by this checker:1966``lock, unlock, pthread_mutex_lock, pthread_mutex_trylock, pthread_mutex_unlock, mtx_lock, mtx_timedlock, mtx_trylock, mtx_unlock, lock_guard, unique_lock``.1967 1968.. code-block:: c1969 1970 void pthread_lock_example(pthread_mutex_t *m) {1971   pthread_mutex_lock(m); // note: entering critical section here1972   sleep(10); // warn: Call to blocking function 'sleep' inside of critical section1973   pthread_mutex_unlock(m);1974 }1975 1976.. code-block:: cpp1977 1978 void overlapping_critical_sections(mtx_t *m1, std::mutex &m2) {1979   std::lock_guard lg{m2}; // note: entering critical section here1980   mtx_lock(m1); // note: entering critical section here1981   sleep(10); // warn: Call to blocking function 'sleep' inside of critical section1982   mtx_unlock(m1);1983   sleep(10); // warn: Call to blocking function 'sleep' inside of critical section1984              // still inside of the critical section of the std::lock_guard1985 }1986 1987**Limitations**1988 1989* The ``trylock`` and ``timedlock`` versions of acquiring locks are currently assumed to always succeed.1990  This can lead to false positives.1991 1992.. code-block:: c1993 1994 void trylock_example(pthread_mutex_t *m) {1995   if (pthread_mutex_trylock(m) == 0) { // assume trylock always succeeds1996     sleep(10); // warn: Call to blocking function 'sleep' inside of critical section1997     pthread_mutex_unlock(m);1998   } else {1999     sleep(10); // false positive: Incorrect warning about blocking function inside critical section.2000   }2001 }2002 2003.. _unix-Chroot:2004 2005unix.Chroot (C)2006"""""""""""""""2007Check improper use of chroot described by SEI Cert C recommendation `POS05-C.2008Limit access to files by creating a jail2009<https://wiki.sei.cmu.edu/confluence/display/c/POS05-C.+Limit+access+to+files+by+creating+a+jail>`_.2010The checker finds usage patterns where ``chdir("/")`` is not called immediately2011after a call to ``chroot(path)``.2012 2013.. code-block:: c2014 2015 void f();2016 2017 void test_bad() {2018   chroot("/usr/local");2019   f(); // warn: no call of chdir("/") immediately after chroot2020 }2021 2022  void test_bad_path() {2023    chroot("/usr/local");2024    chdir("/usr"); // warn: no call of chdir("/") immediately after chroot2025    f();2026  }2027 2028 void test_good() {2029   chroot("/usr/local");2030   chdir("/"); // no warning2031   f();2032 }2033 2034.. _unix-Errno:2035 2036unix.Errno (C)2037""""""""""""""2038 2039Check for improper use of ``errno``.2040This checker implements partially CERT rule2041`ERR30-C. Set errno to zero before calling a library function known to set errno,2042and check errno only after the function returns a value indicating failure2043<https://wiki.sei.cmu.edu/confluence/pages/viewpage.action?pageId=87152351>`_.2044The checker can find the first read of ``errno`` after successful standard2045function calls.2046 2047The C and POSIX standards often do not define if a standard library function2048may change value of ``errno`` if the call does not fail.2049Therefore, ``errno`` should only be used if it is known from the return value2050of a function that the call has failed.2051There are exceptions to this rule (for example ``strtol``) but the affected2052functions are not yet supported by the checker.2053The return values for the failure cases are documented in the standard Linux man2054pages of the functions and in the `POSIX standard <https://pubs.opengroup.org/onlinepubs/9699919799/>`_.2055 2056.. code-block:: c2057 2058 int unsafe_errno_read(int sock, void *data, int data_size) {2059   if (send(sock, data, data_size, 0) != data_size) {2060     // 'send' can be successful even if not all data was sent2061     if (errno == 1) { // An undefined value may be read from 'errno'2062       return 0;2063     }2064   }2065   return 1;2066 }2067 2068The checker :ref:`unix-StdCLibraryFunctions` must be turned on to get the2069warnings from this checker. The supported functions are the same as by2070:ref:`unix-StdCLibraryFunctions`. The ``ModelPOSIX`` option of that2071checker affects the set of checked functions.2072 2073**Parameters**2074 2075The ``AllowErrnoReadOutsideConditionExpressions`` option allows read of the2076errno value if the value is not used in a condition (in ``if`` statements,2077loops, conditional expressions, ``switch`` statements). For example ``errno``2078can be stored into a variable without getting a warning by the checker.2079 2080.. code-block:: c2081 2082 int unsafe_errno_read(int sock, void *data, int data_size) {2083   if (send(sock, data, data_size, 0) != data_size) {2084     int err = errno;2085     // warning if 'AllowErrnoReadOutsideConditionExpressions' is false2086     // no warning if 'AllowErrnoReadOutsideConditionExpressions' is true2087   }2088   return 1;2089 }2090 2091Default value of this option is ``true``. This allows save of the errno value2092for possible later error handling.2093 2094**Limitations**2095 2096 - Only the very first usage of ``errno`` is checked after an affected function2097   call. Value of ``errno`` is not followed when it is stored into a variable2098   or returned from a function.2099 - Documentation of function ``lseek`` is not clear about what happens if the2100   function returns different value than the expected file position but not -1.2101   To avoid possible false-positives ``errno`` is allowed to be used in this2102   case.2103 2104.. _unix-Malloc:2105 2106unix.Malloc (C)2107"""""""""""""""2108Check for memory leaks, double free, and use-after-free problems. Traces memory managed by malloc()/free().2109 2110Custom allocation/deallocation functions can be defined using2111:ref:`ownership attributes<analyzer-ownership-attrs>`.2112 2113.. literalinclude:: checkers/unix_malloc_example.c2114    :language: c2115 2116.. _unix-MallocSizeof:2117 2118unix.MallocSizeof (C)2119"""""""""""""""""""""2120Check for dubious ``malloc`` arguments involving ``sizeof``.2121 2122Custom allocation/deallocation functions can be defined using2123:ref:`ownership attributes<analyzer-ownership-attrs>`.2124 2125.. code-block:: c2126 2127 void test() {2128   long *p = malloc(sizeof(short));2129     // warn: result is converted to 'long *', which is2130     // incompatible with operand type 'short'2131   free(p);2132 }2133 2134.. _unix-MismatchedDeallocator:2135 2136unix.MismatchedDeallocator (C, C++)2137"""""""""""""""""""""""""""""""""""2138Check for mismatched deallocators.2139 2140Custom allocation/deallocation functions can be defined using2141:ref:`ownership attributes<analyzer-ownership-attrs>`.2142 2143.. literalinclude:: checkers/mismatched_deallocator_example.cpp2144    :language: c2145 2146.. _unix-Vfork:2147 2148unix.Vfork (C)2149""""""""""""""2150Check for proper usage of ``vfork``.2151 2152.. code-block:: c2153 2154 int test(int x) {2155   pid_t pid = vfork(); // warn2156   if (pid != 0)2157     return 0;2158 2159   switch (x) {2160   case 0:2161     pid = 1;2162     execl("", "", 0);2163     _exit(1);2164     break;2165   case 1:2166     x = 0; // warn: this assignment is prohibited2167     break;2168   case 2:2169     foo(); // warn: this function call is prohibited2170     break;2171   default:2172     return 0; // warn: return is prohibited2173   }2174 2175   while(1);2176 }2177 2178.. _unix-cstring-BadSizeArg:2179 2180unix.cstring.BadSizeArg (C)2181"""""""""""""""""""""""""""2182Check 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.2183 2184.. code-block:: c2185 2186 void test() {2187   char dest[3];2188   strncat(dest, """""""""""""""""""""""""*", sizeof(dest));2189     // warn: potential buffer overflow2190 }2191 2192.. _unix-cstring-NotNullTerminated:2193 2194unix.cstring.NotNullTerminated (C)2195""""""""""""""""""""""""""""""""""2196Check for arguments which are not null-terminated strings;2197applies to the ``strlen``, ``strcpy``, ``strcat``, ``strcmp`` family of functions.2198 2199Only very fundamental cases are detected where the passed memory block is2200absolutely different from a null-terminated string. This checker does not2201find if a memory buffer is passed where the terminating zero character2202is missing.2203 2204.. code-block:: c2205 2206 void test1() {2207   int l = strlen((char *)&test1); // warn2208 }2209 2210 void test2() {2211 label:2212   int l = strlen((char *)&&label); // warn2213 }2214 2215.. _unix-cstring-NullArg:2216 2217unix.cstring.NullArg (C)2218""""""""""""""""""""""""2219Check for null pointers being passed as arguments to C string functions:2220``strlen, strnlen, strcpy, strncpy, strcat, strncat, strcmp, strncmp, strcasecmp, strncasecmp, wcslen, wcsnlen``.2221 2222.. code-block:: c2223 2224 int test() {2225   return strlen(0); // warn2226 }2227 2228.. _unix-StdCLibraryFunctions:2229 2230unix.StdCLibraryFunctions (C)2231"""""""""""""""""""""""""""""2232Check for calls of standard library functions that violate predefined argument2233constraints. For example, according to the C standard the behavior of function2234``int isalnum(int ch)`` is undefined if the value of ``ch`` is not representable2235as ``unsigned char`` and is not equal to ``EOF``.2236 2237You can think of this checker as defining restrictions (pre- and postconditions)2238on standard library functions. Preconditions are checked, and when they are2239violated, a warning is emitted. Postconditions are added to the analysis, e.g.2240that the return value of a function is not greater than 255. Preconditions are2241added to the analysis too, in the case when the affected values are not known2242before the call.2243 2244For example, if an argument to a function must be in between 0 and 255, but the2245value of the argument is unknown, the analyzer will assume that it is in this2246interval. Similarly, if a function mustn't be called with a null pointer and the2247analyzer cannot prove that it is null, then it will assume that it is non-null.2248 2249These are the possible checks on the values passed as function arguments:2250 - The argument has an allowed range (or multiple ranges) of values. The checker2251   can detect if a passed value is outside of the allowed range and show the2252   actual and allowed values.2253 - The argument has pointer type and is not allowed to be null pointer. Many2254   (but not all) standard functions can produce undefined behavior if a null2255   pointer is passed, these cases can be detected by the checker.2256 - The argument is a pointer to a memory block and the minimal size of this2257   buffer is determined by another argument to the function, or by2258   multiplication of two arguments (like at function ``fread``), or is a fixed2259   value (for example ``asctime_r`` requires at least a buffer of size 26). The2260   checker can detect if the buffer size is too small and in optimal case show2261   the size of the buffer and the values of the corresponding arguments.2262 2263.. code-block:: c2264 2265  #define EOF -12266  void test_alnum_concrete(int v) {2267    int ret = isalnum(256); // \2268    // warning: Function argument outside of allowed range2269    (void)ret;2270  }2271 2272  void buffer_size_violation(FILE *file) {2273    enum { BUFFER_SIZE = 1024 };2274    wchar_t wbuf[BUFFER_SIZE];2275 2276    const size_t size = sizeof(*wbuf);   // 42277    const size_t nitems = sizeof(wbuf);  // 40962278 2279    // Below we receive a warning because the 3rd parameter should be the2280    // number of elements to read, not the size in bytes. This case is a known2281    // vulnerability described by the ARR38-C SEI-CERT rule.2282    fread(wbuf, size, nitems, file);2283  }2284 2285  int test_alnum_symbolic(int x) {2286    int ret = isalnum(x);2287    // after the call, ret is assumed to be in the range [-1, 255]2288 2289    if (ret > 255)      // impossible (infeasible branch)2290      if (x == 0)2291        return ret / x; // division by zero is not reported2292    return ret;2293  }2294 2295Additionally to the argument and return value conditions, this checker also adds2296state of the value ``errno`` if applicable to the analysis. Many system2297functions set the ``errno`` value only if an error occurs (together with a2298specific return value of the function), otherwise it becomes undefined. This2299checker changes the analysis state to contain such information. This data is2300used by other checkers, for example :ref:`unix-Errno`.2301 2302**Limitations**2303 2304The checker can not always provide notes about the values of the arguments.2305Without this information it is hard to confirm if the constraint is indeed2306violated. The argument values are shown if they are known constants or the value2307is determined by previous (not too complicated) assumptions.2308 2309The checker can produce false positives in cases such as if the program has2310invariants not known to the analyzer engine or the bug report path contains2311calls to unknown functions. In these cases the analyzer fails to detect the real2312range of the argument.2313 2314**Parameters**2315 2316The ``ModelPOSIX`` option controls if functions from the POSIX standard are2317recognized by the checker.2318 2319With ``ModelPOSIX=true``, many POSIX functions are modeled according to the2320`POSIX standard`_. This includes ranges of parameters and possible return2321values. Furthermore the behavior related to ``errno`` in the POSIX case is2322often that ``errno`` is set only if a function call fails, and it becomes2323undefined after a successful function call.2324 2325With ``ModelPOSIX=false``, this checker follows the C99 language standard and2326only models the functions that are described there. It is possible that the2327same functions are modeled differently in the two cases because differences in2328the standards. The C standard specifies less aspects of the functions, for2329example exact ``errno`` behavior is often unspecified (and not modeled by the2330checker).2331 2332Default value of the option is ``true``.2333 2334.. _unix-Stream:2335 2336unix.Stream (C)2337"""""""""""""""2338Check C stream handling functions:2339``fopen, fdopen, freopen, tmpfile, fclose, fread, fwrite, fgetc, fgets, fputc, fputs, fprintf, fscanf, ungetc, getdelim, getline, fseek, fseeko, ftell, ftello, fflush, rewind, fgetpos, fsetpos, clearerr, feof, ferror, fileno``.2340 2341The checker maintains information about the C stream objects (``FILE *``) and2342can detect error conditions related to use of streams. The following conditions2343are detected:2344 2345* The ``FILE *`` pointer passed to the function is NULL (the single exception is2346  ``fflush`` where NULL is allowed).2347* Use of stream after close.2348* Opened stream is not closed.2349* Read from a stream after end-of-file. (This is not a fatal error but reported2350  by the checker. Stream remains in EOF state and the read operation fails.)2351* Use of stream when the file position is indeterminate after a previous failed2352  operation. Some functions (like ``ferror``, ``clearerr``, ``fseek``) are2353  allowed in this state.2354* Invalid 3rd ("``whence``") argument to ``fseek``.2355 2356The stream operations are by this checker usually split into two cases, a success2357and a failure case.2358On the success case it also assumes that the current value of ``stdout``,2359``stderr``, or ``stdin`` can't be equal to the file pointer returned by ``fopen``.2360Operations performed on ``stdout``, ``stderr``, or ``stdin`` are not checked by2361this checker in contrast to the streams opened by ``fopen``.2362 2363In the case of write operations (like ``fwrite``,2364``fprintf`` and even ``fsetpos``) this behavior could produce a large amount of2365unwanted reports on projects that don't have error checks around the write2366operations, so by default the checker assumes that write operations always succeed.2367This behavior can be controlled by the ``Pedantic`` flag: With2368``-analyzer-config unix.Stream:Pedantic=true`` the checker will model the2369cases where a write operation fails and report situations where this leads to2370erroneous behavior. (The default is ``Pedantic=false``, where write operations2371are assumed to succeed.)2372 2373.. code-block:: c2374 2375 void test1() {2376   FILE *p = fopen("foo", "r");2377 } // warn: opened file is never closed2378 2379 void test2() {2380   FILE *p = fopen("foo", "r");2381   fseek(p, 1, SEEK_SET); // warn: stream pointer might be NULL2382   fclose(p);2383 }2384 2385 void test3() {2386   FILE *p = fopen("foo", "r");2387   if (p) {2388     fseek(p, 1, 3); // warn: third arg should be SEEK_SET, SEEK_END, or SEEK_CUR2389     fclose(p);2390   }2391 }2392 2393 void test4() {2394   FILE *p = fopen("foo", "r");2395   if (!p)2396     return;2397 2398   fclose(p);2399   fclose(p); // warn: stream already closed2400 }2401 2402 void test5() {2403   FILE *p = fopen("foo", "r");2404   if (!p)2405     return;2406 2407   fgetc(p);2408   if (!ferror(p))2409     fgetc(p); // warn: possible read after end-of-file2410 2411   fclose(p);2412 }2413 2414 void test6() {2415   FILE *p = fopen("foo", "r");2416   if (!p)2417     return;2418 2419   fgetc(p);2420   if (!feof(p))2421     fgetc(p); // warn: file position may be indeterminate after I/O error2422 2423   fclose(p);2424 }2425 2426**Limitations**2427 2428The checker does not track the correspondence between integer file descriptors2429and ``FILE *`` pointers.2430 2431.. _osx-checkers:2432 2433osx2434^^^2435macOS checkers.2436 2437.. _osx-API:2438 2439osx.API (C)2440"""""""""""2441Check for proper uses of various Apple APIs.2442 2443.. code-block:: objc2444 2445 void test() {2446   dispatch_once_t pred = 0;2447   dispatch_once(&pred, ^(){}); // warn: dispatch_once uses local2448 }2449 2450.. _osx-NumberObjectConversion:2451 2452osx.NumberObjectConversion (C, C++, ObjC)2453"""""""""""""""""""""""""""""""""""""""""2454Check for erroneous conversions of objects representing numbers into numbers.2455 2456.. code-block:: objc2457 2458 NSNumber *photoCount = [albumDescriptor objectForKey:@"PhotoCount"];2459 // Warning: Comparing a pointer value of type 'NSNumber *'2460 // to a scalar integer value2461 if (photoCount > 0) {2462   [self displayPhotos];2463 }2464 2465.. _osx-ObjCProperty:2466 2467osx.ObjCProperty (ObjC)2468"""""""""""""""""""""""2469Check for proper uses of Objective-C properties.2470 2471.. code-block:: objc2472 2473 NSNumber *photoCount = [albumDescriptor objectForKey:@"PhotoCount"];2474 // Warning: Comparing a pointer value of type 'NSNumber *'2475 // to a scalar integer value2476 if (photoCount > 0) {2477   [self displayPhotos];2478 }2479 2480 2481.. _osx-SecKeychainAPI:2482 2483osx.SecKeychainAPI (C)2484""""""""""""""""""""""2485Check for proper uses of Secure Keychain APIs.2486 2487.. literalinclude:: checkers/seckeychainapi_example.m2488    :language: objc2489 2490.. _osx-cocoa-AtSync:2491 2492osx.cocoa.AtSync (ObjC)2493"""""""""""""""""""""""2494Check for nil pointers used as mutexes for @synchronized.2495 2496.. code-block:: objc2497 2498 void test(id x) {2499   if (!x)2500     @synchronized(x) {} // warn: nil value used as mutex2501 }2502 2503 void test() {2504   id y;2505   @synchronized(y) {} // warn: uninitialized value used as mutex2506 }2507 2508.. _osx-cocoa-AutoreleaseWrite:2509 2510osx.cocoa.AutoreleaseWrite2511""""""""""""""""""""""""""2512Warn about potentially crashing writes to autoreleasing objects from different autoreleasing pools in Objective-C.2513 2514.. _osx-cocoa-ClassRelease:2515 2516osx.cocoa.ClassRelease (ObjC)2517"""""""""""""""""""""""""""""2518Check for sending 'retain', 'release', or 'autorelease' directly to a Class.2519 2520.. code-block:: objc2521 2522 @interface MyClass : NSObject2523 @end2524 2525 void test(void) {2526   [MyClass release]; // warn2527 }2528 2529.. _osx-cocoa-Dealloc:2530 2531osx.cocoa.Dealloc (ObjC)2532""""""""""""""""""""""""2533Warn about Objective-C classes that lack a correct implementation of -dealloc2534 2535.. literalinclude:: checkers/dealloc_example.m2536    :language: objc2537 2538.. _osx-cocoa-IncompatibleMethodTypes:2539 2540osx.cocoa.IncompatibleMethodTypes (ObjC)2541""""""""""""""""""""""""""""""""""""""""2542Warn about Objective-C method signatures with type incompatibilities.2543 2544.. code-block:: objc2545 2546 @interface MyClass1 : NSObject2547 - (int)foo;2548 @end2549 2550 @implementation MyClass12551 - (int)foo { return 1; }2552 @end2553 2554 @interface MyClass2 : MyClass12555 - (float)foo;2556 @end2557 2558 @implementation MyClass22559 - (float)foo { return 1.0; } // warn2560 @end2561 2562.. _osx-cocoa-Loops:2563 2564osx.cocoa.Loops2565"""""""""""""""2566Improved modeling of loops using Cocoa collection types.2567 2568.. _osx-cocoa-MissingSuperCall:2569 2570osx.cocoa.MissingSuperCall (ObjC)2571"""""""""""""""""""""""""""""""""2572Warn about Objective-C methods that lack a necessary call to super.2573 2574.. code-block:: objc2575 2576 @interface Test : UIViewController2577 @end2578 @implementation test2579 - (void)viewDidLoad {} // warn2580 @end2581 2582 2583.. _osx-cocoa-NSAutoreleasePool:2584 2585osx.cocoa.NSAutoreleasePool (ObjC)2586""""""""""""""""""""""""""""""""""2587Warn for suboptimal uses of NSAutoreleasePool in Objective-C GC mode.2588 2589.. code-block:: objc2590 2591 void test() {2592   NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];2593   [pool release]; // warn2594 }2595 2596.. _osx-cocoa-NSError:2597 2598osx.cocoa.NSError (ObjC)2599""""""""""""""""""""""""2600Check usage of NSError parameters.2601 2602.. code-block:: objc2603 2604 @interface A : NSObject2605 - (void)foo:(NSError """""""""""""""""""""""")error;2606 @end2607 2608 @implementation A2609 - (void)foo:(NSError """""""""""""""""""""""")error {2610   // warn: method accepting NSError"""""""""""""""""""""""" should have a non-void2611   // return value2612 }2613 @end2614 2615 @interface A : NSObject2616 - (BOOL)foo:(NSError """""""""""""""""""""""")error;2617 @end2618 2619 @implementation A2620 - (BOOL)foo:(NSError """""""""""""""""""""""")error {2621   *error = 0; // warn: potential null dereference2622   return 0;2623 }2624 @end2625 2626.. _osx-cocoa-NilArg:2627 2628osx.cocoa.NilArg (ObjC)2629"""""""""""""""""""""""2630Check for prohibited nil arguments to ObjC method calls.2631 2632 - caseInsensitiveCompare:2633 - compare:2634 - compare:options:2635 - compare:options:range:2636 - compare:options:range:locale:2637 - componentsSeparatedByCharactersInSet:2638 - initWithFormat:2639 2640.. code-block:: objc2641 2642 NSComparisonResult test(NSString *s) {2643   NSString *aString = nil;2644   return [s caseInsensitiveCompare:aString];2645     // warn: argument to 'NSString' method2646     // 'caseInsensitiveCompare:' cannot be nil2647 }2648 2649 2650.. _osx-cocoa-NonNilReturnValue:2651 2652osx.cocoa.NonNilReturnValue2653"""""""""""""""""""""""""""2654Models the APIs that are guaranteed to return a non-nil value.2655 2656.. _osx-cocoa-ObjCGenerics:2657 2658osx.cocoa.ObjCGenerics (ObjC)2659"""""""""""""""""""""""""""""2660Check for type errors when using Objective-C generics.2661 2662.. code-block:: objc2663 2664 NSMutableArray *names = [NSMutableArray array];2665 NSMutableArray *birthDates = names;2666 2667 // Warning: Conversion from value of type 'NSDate *'2668 // to incompatible type 'NSString *'2669 [birthDates addObject: [NSDate date]];2670 2671.. _osx-cocoa-RetainCount:2672 2673osx.cocoa.RetainCount (ObjC)2674""""""""""""""""""""""""""""2675Check for leaks and improper reference count management2676 2677.. code-block:: objc2678 2679 void test() {2680   NSString *s = [[NSString alloc] init]; // warn2681 }2682 2683 CFStringRef test(char *bytes) {2684   return CFStringCreateWithCStringNoCopy(2685            0, bytes, NSNEXTSTEPStringEncoding, 0); // warn2686 }2687 2688 2689.. _osx-cocoa-RunLoopAutoreleaseLeak:2690 2691osx.cocoa.RunLoopAutoreleaseLeak2692""""""""""""""""""""""""""""""""2693Check for leaked memory in autorelease pools that will never be drained.2694 2695.. _osx-cocoa-SelfInit:2696 2697osx.cocoa.SelfInit (ObjC)2698"""""""""""""""""""""""""2699Check that 'self' is properly initialized inside an initializer method.2700 2701.. code-block:: objc2702 2703 @interface MyObj : NSObject {2704   id x;2705 }2706 - (id)init;2707 @end2708 2709 @implementation MyObj2710 - (id)init {2711   [super init];2712   x = 0; // warn: instance variable used while 'self' is not2713          // initialized2714   return 0;2715 }2716 @end2717 2718 @interface MyObj : NSObject2719 - (id)init;2720 @end2721 2722 @implementation MyObj2723 - (id)init {2724   [super init];2725   return self; // warn: returning uninitialized 'self'2726 }2727 @end2728 2729.. _osx-cocoa-SuperDealloc:2730 2731osx.cocoa.SuperDealloc (ObjC)2732"""""""""""""""""""""""""""""2733Warn about improper use of '[super dealloc]' in Objective-C.2734 2735.. code-block:: objc2736 2737 @interface SuperDeallocThenReleaseIvarClass : NSObject {2738   NSObject *_ivar;2739 }2740 @end2741 2742 @implementation SuperDeallocThenReleaseIvarClass2743 - (void)dealloc {2744   [super dealloc];2745   [_ivar release]; // warn2746 }2747 @end2748 2749.. _osx-cocoa-UnusedIvars:2750 2751osx.cocoa.UnusedIvars (ObjC)2752""""""""""""""""""""""""""""2753Warn about private ivars that are never used.2754 2755.. code-block:: objc2756 2757 @interface MyObj : NSObject {2758 @private2759   id x; // warn2760 }2761 @end2762 2763 @implementation MyObj2764 @end2765 2766.. _osx-cocoa-VariadicMethodTypes:2767 2768osx.cocoa.VariadicMethodTypes (ObjC)2769""""""""""""""""""""""""""""""""""""2770Check for passing non-Objective-C types to variadic collection2771initialization methods that expect only Objective-C types.2772 2773.. code-block:: objc2774 2775 void test() {2776   [NSSet setWithObjects:@"Foo", "Bar", nil];2777     // warn: argument should be an ObjC pointer type, not 'char *'2778 }2779 2780.. _osx-coreFoundation-CFError:2781 2782osx.coreFoundation.CFError (C)2783""""""""""""""""""""""""""""""2784Check usage of CFErrorRef* parameters2785 2786.. code-block:: c2787 2788 void test(CFErrorRef *error) {2789   // warn: function accepting CFErrorRef* should have a2790   // non-void return2791 }2792 2793 int foo(CFErrorRef *error) {2794   *error = 0; // warn: potential null dereference2795   return 0;2796 }2797 2798.. _osx-coreFoundation-CFNumber:2799 2800osx.coreFoundation.CFNumber (C)2801"""""""""""""""""""""""""""""""2802Check for proper uses of CFNumber APIs.2803 2804.. code-block:: c2805 2806 CFNumberRef test(unsigned char x) {2807   return CFNumberCreate(0, kCFNumberSInt16Type, &x);2808    // warn: 8-bit integer is used to initialize a 16-bit integer2809 }2810 2811.. _osx-coreFoundation-CFRetainRelease:2812 2813osx.coreFoundation.CFRetainRelease (C)2814""""""""""""""""""""""""""""""""""""""2815Check for null arguments to CFRetain/CFRelease/CFMakeCollectable.2816 2817.. code-block:: c2818 2819 void test(CFTypeRef p) {2820   if (!p)2821     CFRetain(p); // warn2822 }2823 2824 void test(int x, CFTypeRef p) {2825   if (p)2826     return;2827 2828   CFRelease(p); // warn2829 }2830 2831.. _osx-coreFoundation-containers-OutOfBounds:2832 2833osx.coreFoundation.containers.OutOfBounds (C)2834"""""""""""""""""""""""""""""""""""""""""""""2835Checks for index out-of-bounds when using 'CFArray' API.2836 2837.. code-block:: c2838 2839 void test() {2840   CFArrayRef A = CFArrayCreate(0, 0, 0, &kCFTypeArrayCallBacks);2841   CFArrayGetValueAtIndex(A, 0); // warn2842 }2843 2844.. _osx-coreFoundation-containers-PointerSizedValues:2845 2846osx.coreFoundation.containers.PointerSizedValues (C)2847""""""""""""""""""""""""""""""""""""""""""""""""""""2848Warns if 'CFArray', 'CFDictionary', 'CFSet' are created with non-pointer-size values.2849 2850.. code-block:: c2851 2852 void test() {2853   int x[] = { 1 };2854   CFArrayRef A = CFArrayCreate(0, (const void """""""""""""""""""""""")x, 1,2855                                &kCFTypeArrayCallBacks); // warn2856 }2857 2858Fuchsia2859^^^^^^^2860 2861Fuchsia is an open source capability-based operating system currently being2862developed by Google. This section describes checkers that can find various2863misuses of Fuchsia APIs.2864 2865.. _fuchsia-HandleChecker:2866 2867fuchsia.HandleChecker2868""""""""""""""""""""""""""""2869Handles identify resources. Similar to pointers they can be leaked,2870double freed, or use after freed. This check attempts to find such problems.2871 2872.. code-block:: cpp2873 2874 void checkLeak08(int tag) {2875   zx_handle_t sa, sb;2876   zx_channel_create(0, &sa, &sb);2877   if (tag)2878     zx_handle_close(sa);2879   use(sb); // Warn: Potential leak of handle2880   zx_handle_close(sb);2881 }2882 2883WebKit2884^^^^^^2885 2886WebKit is an open-source web browser engine available for macOS, iOS and Linux.2887This section describes checkers that can find issues in WebKit codebase.2888 2889Most of the checkers focus on memory management for which WebKit uses custom implementation of reference counted smartpointers.2890 2891Checkers are formulated in terms related to ref-counting:2892 - *Ref-counted type* is either ``Ref<T>`` or ``RefPtr<T>``.2893 - *Ref-countable type* is any type that implements ``ref()`` and ``deref()`` methods as ``RefPtr<>`` is a template (i. e. relies on duck typing).2894 - *Uncounted type* is ref-countable but not ref-counted type.2895 2896.. _webkit-RefCntblBaseVirtualDtor:2897 2898webkit.RefCntblBaseVirtualDtor2899""""""""""""""""""""""""""""""""""""2900All uncounted types used as base classes must have a virtual destructor.2901 2902Ref-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]``.2903 2904.. code-block:: cpp2905 2906 struct RefCntblBase {2907   void ref() {}2908   void deref() {}2909 };2910 2911 struct Derived : RefCntblBase { }; // warn2912 2913.. _webkit-NoUncountedMemberChecker:2914 2915webkit.NoUncountedMemberChecker2916"""""""""""""""""""""""""""""""""""""2917Raw pointers and references to uncounted types can't be used as class members. Only ref-counted types are allowed.2918 2919.. code-block:: cpp2920 2921 struct RefCntbl {2922   void ref() {}2923   void deref() {}2924 };2925 2926 struct Foo {2927   RefCntbl * ptr; // warn2928   RefCntbl & ptr; // warn2929   // ...2930 };2931 2932.. _webkit-UncountedLambdaCapturesChecker:2933 2934webkit.UncountedLambdaCapturesChecker2935"""""""""""""""""""""""""""""""""""""2936Raw pointers and references to uncounted types can't be captured in lambdas. Only ref-counted types are allowed.2937 2938.. code-block:: cpp2939 2940 struct RefCntbl {2941   void ref() {}2942   void deref() {}2943 };2944 2945 void foo(RefCntbl* a, RefCntbl& b) {2946   [&, a](){ // warn about 'a'2947     do_something(b); // warn about 'b'2948   };2949 };2950 2951.. _alpha-checkers:2952 2953Experimental Checkers2954---------------------2955 2956*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.*2957 2958alpha.clone2959^^^^^^^^^^^2960 2961.. _alpha-clone-CloneChecker:2962 2963alpha.clone.CloneChecker (C, C++, ObjC)2964"""""""""""""""""""""""""""""""""""""""2965Reports similar pieces of code.2966 2967.. code-block:: c2968 2969 void log();2970 2971 int max(int a, int b) { // warn2972   log();2973   if (a > b)2974     return a;2975   return b;2976 }2977 2978 int maxClone(int x, int y) { // similar code here2979   log();2980   if (x > y)2981     return x;2982   return y;2983 }2984 2985alpha.core2986^^^^^^^^^^2987 2988.. _alpha-core-BoolAssignment:2989 2990alpha.core.BoolAssignment (ObjC)2991""""""""""""""""""""""""""""""""2992Warn about assigning non-{0,1} values to boolean variables.2993 2994.. code-block:: objc2995 2996 void test() {2997   BOOL b = -1; // warn2998 }2999 3000.. _alpha-core-C11Lock:3001 3002alpha.core.C11Lock3003""""""""""""""""""3004Similarly to :ref:`alpha.unix.PthreadLock <alpha-unix-PthreadLock>`, checks for3005the locking/unlocking of ``mtx_t`` mutexes.3006 3007.. code-block:: cpp3008 3009 mtx_t mtx1;3010 3011 void bad1(void)3012 {3013   mtx_lock(&mtx1);3014   mtx_lock(&mtx1); // warn: This lock has already been acquired3015 }3016 3017.. _alpha-core-CastToStruct:3018 3019alpha.core.CastToStruct (C, C++)3020""""""""""""""""""""""""""""""""3021Check for cast from non-struct pointer to struct pointer.3022 3023.. code-block:: cpp3024 3025 // C3026 struct s {};3027 3028 void test(int *p) {3029   struct s *ps = (struct s *) p; // warn3030 }3031 3032 // C++3033 class c {};3034 3035 void test(int *p) {3036   c *pc = (c *) p; // warn3037 }3038 3039.. _alpha-core-Conversion:3040 3041alpha.core.Conversion (C, C++, ObjC)3042""""""""""""""""""""""""""""""""""""3043Loss of sign/precision in implicit conversions.3044 3045.. code-block:: c3046 3047 void test(unsigned U, signed S) {3048   if (S > 10) {3049     if (U < S) {3050     }3051   }3052   if (S < -10) {3053     if (U < S) { // warn (loss of sign)3054     }3055   }3056 }3057 3058 void test() {3059   long long A = 1LL << 60;3060   short X = A; // warn (loss of precision)3061 }3062 3063.. _alpha-core-DynamicTypeChecker:3064 3065alpha.core.DynamicTypeChecker (ObjC)3066""""""""""""""""""""""""""""""""""""3067Check for cases where the dynamic and the static type of an object are unrelated.3068 3069 3070.. code-block:: objc3071 3072 id date = [NSDate date];3073 3074 // Warning: Object has a dynamic type 'NSDate *' which is3075 // incompatible with static type 'NSNumber *'"3076 NSNumber *number = date;3077 [number doubleValue];3078 3079.. _alpha-core-FixedAddr:3080 3081alpha.core.FixedAddr (C)3082""""""""""""""""""""""""3083Check for assignment of a fixed address to a pointer.3084 3085.. code-block:: c3086 3087 void test() {3088   int *p;3089   p = (int *) 0x10000; // warn3090 }3091 3092.. _alpha-core-PointerArithm:3093 3094alpha.core.PointerArithm (C)3095""""""""""""""""""""""""""""3096Check for pointer arithmetic on locations other than array elements.3097 3098.. code-block:: c3099 3100 void test() {3101   int x;3102   int *p;3103   p = &x + 1; // warn3104 }3105 3106.. _alpha-core-StackAddressAsyncEscape:3107 3108alpha.core.StackAddressAsyncEscape (ObjC)3109"""""""""""""""""""""""""""""""""""""""""3110Check that addresses to stack memory do not escape the function that involves dispatch_after or dispatch_async.3111This checker is a part of ``core.StackAddressEscape``, but is temporarily disabled until some false positives are fixed.3112 3113.. code-block:: c3114 3115 dispatch_block_t test_block_inside_block_async_leak() {3116   int x = 123;3117   void (^inner)(void) = ^void(void) {3118     int y = x;3119     ++y;3120   };3121   void (^outer)(void) = ^void(void) {3122     int z = x;3123     ++z;3124     inner();3125   };3126   return outer; // warn: address of stack-allocated block is captured by a3127                 //       returned block3128 }3129 3130.. _alpha-core-StdVariant:3131 3132alpha.core.StdVariant (C++)3133"""""""""""""""""""""""""""3134Check if a value of active type is retrieved from an ``std::variant`` instance with ``std::get``.3135In case of bad variant type access (the accessed type differs from the active type)3136a warning is emitted. Currently, this checker does not take exception handling into account.3137 3138.. code-block:: cpp3139 3140 void test() {3141   std::variant<int, char> v = 25;3142   char c = stg::get<char>(v); // warn: "int" is the active alternative3143 }3144 3145.. _alpha-core-TestAfterDivZero:3146 3147alpha.core.TestAfterDivZero (C)3148"""""""""""""""""""""""""""""""3149Check for division by variable that is later compared against 0.3150Either the comparison is useless or there is division by zero.3151 3152.. code-block:: c3153 3154 void test(int x) {3155   var = 77 / x;3156   if (x == 0) { } // warn3157 }3158 3159.. _alpha-core-StoreToImmutable:3160 3161alpha.core.StoreToImmutable (C, C++)3162""""""""""""""""""""""""""""""""""""3163Check for writes to immutable memory regions. This implements part of SEI CERT Rule ENV30-C.3164 3165This checker detects attempts to write to memory regions that are marked as immutable,3166including const variables, string literals, and other const-qualified memory.3167 3168.. literalinclude:: checkers/storetoimmutable_example.cpp3169    :language: cpp3170 3171**Solution**3172 3173Avoid writing to const-qualified memory regions. If you need to modify the data,3174remove the const qualifier from the original declaration or use a mutable copy.3175 3176alpha.cplusplus3177^^^^^^^^^^^^^^^3178 3179.. _alpha-cplusplus-DeleteWithNonVirtualDtor:3180 3181alpha.cplusplus.DeleteWithNonVirtualDtor (C++)3182""""""""""""""""""""""""""""""""""""""""""""""3183Reports destructions of polymorphic objects with a non-virtual destructor in their base class.3184 3185.. code-block:: cpp3186 3187 class NonVirtual {};3188 class NVDerived : public NonVirtual {};3189 3190 NonVirtual *create() {3191   NonVirtual *x = new NVDerived(); // note: Casting from 'NVDerived' to3192                                    //       'NonVirtual' here3193   return x;3194 }3195 3196 void foo() {3197   NonVirtual *x = create();3198   delete x; // warn: destruction of a polymorphic object with no virtual3199             //       destructor3200 }3201 3202.. _alpha-cplusplus-InvalidatedIterator:3203 3204alpha.cplusplus.InvalidatedIterator (C++)3205"""""""""""""""""""""""""""""""""""""""""3206Check for use of invalidated iterators.3207 3208.. code-block:: cpp3209 3210 void bad_copy_assign_operator_list1(std::list &L1,3211                                     const std::list &L2) {3212   auto i0 = L1.cbegin();3213   L1 = L2;3214   *i0; // warn: invalidated iterator accessed3215 }3216 3217 3218.. _alpha-cplusplus-IteratorRange:3219 3220alpha.cplusplus.IteratorRange (C++)3221"""""""""""""""""""""""""""""""""""3222Check for iterators used outside their valid ranges.3223 3224.. code-block:: cpp3225 3226 void simple_bad_end(const std::vector &v) {3227   auto i = v.end();3228   *i; // warn: iterator accessed outside of its range3229 }3230 3231.. _alpha-cplusplus-MismatchedIterator:3232 3233alpha.cplusplus.MismatchedIterator (C++)3234""""""""""""""""""""""""""""""""""""""""3235Check for use of iterators of different containers where iterators of the same container are expected.3236 3237.. code-block:: cpp3238 3239 void bad_insert3(std::vector &v1, std::vector &v2) {3240   v2.insert(v1.cbegin(), v2.cbegin(), v2.cend()); // warn: container accessed3241                                                   //       using foreign3242                                                   //       iterator argument3243   v1.insert(v1.cbegin(), v1.cbegin(), v2.cend()); // warn: iterators of3244                                                   //       different containers3245                                                   //       used where the same3246                                                   //       container is3247                                                   //       expected3248   v1.insert(v1.cbegin(), v2.cbegin(), v1.cend()); // warn: iterators of3249                                                   //       different containers3250                                                   //       used where the same3251                                                   //       container is3252                                                   //       expected3253 }3254 3255.. _alpha-cplusplus-SmartPtr:3256 3257alpha.cplusplus.SmartPtr (C++)3258""""""""""""""""""""""""""""""3259Check for dereference of null smart pointers.3260 3261.. code-block:: cpp3262 3263 void deref_smart_ptr() {3264   std::unique_ptr<int> P;3265   *P; // warn: dereference of a default constructed smart unique_ptr3266 }3267 3268 3269alpha.deadcode3270^^^^^^^^^^^^^^3271.. _alpha-deadcode-UnreachableCode:3272 3273alpha.deadcode.UnreachableCode (C, C++)3274"""""""""""""""""""""""""""""""""""""""3275Check unreachable code.3276 3277.. code-block:: cpp3278 3279 // C3280 int test() {3281   int x = 1;3282   while(x);3283   return x; // warn3284 }3285 3286 // C++3287 void test() {3288   int a = 2;3289 3290   while (a > 1)3291     a--;3292 3293   if (a > 1)3294     a++; // warn3295 }3296 3297 // Objective-C3298 void test(id x) {3299   return;3300   [x retain]; // warn3301 }3302 3303alpha.fuchsia3304^^^^^^^^^^^^^3305 3306.. _alpha-fuchsia-lock:3307 3308alpha.fuchsia.Lock3309""""""""""""""""""3310Similarly to :ref:`alpha.unix.PthreadLock <alpha-unix-PthreadLock>`, checks for3311the locking/unlocking of fuchsia mutexes.3312 3313.. code-block:: cpp3314 3315 spin_lock_t mtx1;3316 3317 void bad1(void)3318 {3319   spin_lock(&mtx1);3320   spin_lock(&mtx1);	// warn: This lock has already been acquired3321 }3322 3323alpha.llvm3324^^^^^^^^^^3325 3326.. _alpha-llvm-Conventions:3327 3328alpha.llvm.Conventions3329""""""""""""""""""""""3330 3331Check code for LLVM codebase conventions:3332 3333* A StringRef should not be bound to a temporary std::string whose lifetime is shorter than the StringRef's.3334* Clang AST nodes should not have fields that can allocate memory.3335 3336 3337alpha.osx3338^^^^^^^^^3339 3340.. _alpha-osx-cocoa-DirectIvarAssignment:3341 3342alpha.osx.cocoa.DirectIvarAssignment (ObjC)3343"""""""""""""""""""""""""""""""""""""""""""3344Check for direct assignments to instance variables.3345 3346 3347.. code-block:: objc3348 3349 @interface MyClass : NSObject {}3350 @property (readonly) id A;3351 - (void) foo;3352 @end3353 3354 @implementation MyClass3355 - (void) foo {3356   _A = 0; // warn3357 }3358 @end3359 3360.. _alpha-osx-cocoa-DirectIvarAssignmentForAnnotatedFunctions:3361 3362alpha.osx.cocoa.DirectIvarAssignmentForAnnotatedFunctions (ObjC)3363""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""3364Check for direct assignments to instance variables in3365the methods annotated with ``objc_no_direct_instance_variable_assignment``.3366 3367.. code-block:: objc3368 3369 @interface MyClass : NSObject {}3370 @property (readonly) id A;3371 - (void) fAnnotated __attribute__((3372     annotate("objc_no_direct_instance_variable_assignment")));3373 - (void) fNotAnnotated;3374 @end3375 3376 @implementation MyClass3377 - (void) fAnnotated {3378   _A = 0; // warn3379 }3380 - (void) fNotAnnotated {3381   _A = 0; // no warn3382 }3383 @end3384 3385 3386.. _alpha-osx-cocoa-InstanceVariableInvalidation:3387 3388alpha.osx.cocoa.InstanceVariableInvalidation (ObjC)3389"""""""""""""""""""""""""""""""""""""""""""""""""""3390Check that the invalidatable instance variables are3391invalidated in the methods annotated with objc_instance_variable_invalidator.3392 3393.. code-block:: objc3394 3395 @protocol Invalidation <NSObject>3396 - (void) invalidate3397   __attribute__((annotate("objc_instance_variable_invalidator")));3398 @end3399 3400 @interface InvalidationImpObj : NSObject <Invalidation>3401 @end3402 3403 @interface SubclassInvalidationImpObj : InvalidationImpObj {3404   InvalidationImpObj *var;3405 }3406 - (void)invalidate;3407 @end3408 3409 @implementation SubclassInvalidationImpObj3410 - (void) invalidate {}3411 @end3412 // warn: var needs to be invalidated or set to nil3413 3414.. _alpha-osx-cocoa-MissingInvalidationMethod:3415 3416alpha.osx.cocoa.MissingInvalidationMethod (ObjC)3417""""""""""""""""""""""""""""""""""""""""""""""""3418Check that the invalidation methods are present in classes that contain invalidatable instance variables.3419 3420.. code-block:: objc3421 3422 @protocol Invalidation <NSObject>3423 - (void)invalidate3424   __attribute__((annotate("objc_instance_variable_invalidator")));3425 @end3426 3427 @interface NeedInvalidation : NSObject <Invalidation>3428 @end3429 3430 @interface MissingInvalidationMethodDecl : NSObject {3431   NeedInvalidation *Var; // warn3432 }3433 @end3434 3435 @implementation MissingInvalidationMethodDecl3436 @end3437 3438.. _alpha-osx-cocoa-localizability-PluralMisuseChecker:3439 3440alpha.osx.cocoa.localizability.PluralMisuseChecker (ObjC)3441"""""""""""""""""""""""""""""""""""""""""""""""""""""""""3442Warns against using one vs. many plural pattern in code when generating localized strings.3443 3444.. code-block:: objc3445 3446 NSString *reminderText =3447   NSLocalizedString(@"None", @"Indicates no reminders");3448 if (reminderCount == 1) {3449   // Warning: Plural cases are not supported across all languages.3450   // Use a .stringsdict file instead3451   reminderText =3452     NSLocalizedString(@"1 Reminder", @"Indicates single reminder");3453 } else if (reminderCount >= 2) {3454   // Warning: Plural cases are not supported across all languages.3455   // Use a .stringsdict file instead3456   reminderText =3457     [NSString stringWithFormat:3458       NSLocalizedString(@"%@ Reminders", @"Indicates multiple reminders"),3459         reminderCount];3460 }3461 3462alpha.security3463^^^^^^^^^^^^^^3464 3465.. _alpha-security-ReturnPtrRange:3466 3467alpha.security.ReturnPtrRange (C)3468"""""""""""""""""""""""""""""""""3469Check for an out-of-bound pointer being returned to callers.3470 3471.. code-block:: c3472 3473 static int A[10];3474 3475 int *test() {3476   int *p = A + 10;3477   return p; // warn3478 }3479 3480 int test(void) {3481   int x;3482   return x; // warn: undefined or garbage returned3483 }3484 3485alpha.unix3486^^^^^^^^^^3487 3488.. _alpha-unix-PthreadLock:3489 3490alpha.unix.PthreadLock (C)3491""""""""""""""""""""""""""3492Simple lock -> unlock checker.3493Applies to: ``pthread_mutex_lock, pthread_rwlock_rdlock, pthread_rwlock_wrlock, lck_mtx_lock, lck_rw_lock_exclusive``3494``lck_rw_lock_shared, pthread_mutex_trylock, pthread_rwlock_tryrdlock, pthread_rwlock_tryrwlock, lck_mtx_try_lock,3495lck_rw_try_lock_exclusive, lck_rw_try_lock_shared, pthread_mutex_unlock, pthread_rwlock_unlock, lck_mtx_unlock, lck_rw_done``.3496 3497 3498.. code-block:: c3499 3500 pthread_mutex_t mtx;3501 3502 void test() {3503   pthread_mutex_lock(&mtx);3504   pthread_mutex_lock(&mtx);3505     // warn: this lock has already been acquired3506 }3507 3508 lck_mtx_t lck1, lck2;3509 3510 void test() {3511   lck_mtx_lock(&lck1);3512   lck_mtx_lock(&lck2);3513   lck_mtx_unlock(&lck1);3514     // warn: this was not the most recently acquired lock3515 }3516 3517 lck_mtx_t lck1, lck2;3518 3519 void test() {3520   if (lck_mtx_try_lock(&lck1) == 0)3521     return;3522 3523   lck_mtx_lock(&lck2);3524   lck_mtx_unlock(&lck1);3525     // warn: this was not the most recently acquired lock3526 }3527 3528.. _alpha-unix-SimpleStream:3529 3530alpha.unix.SimpleStream (C)3531"""""""""""""""""""""""""""3532Check for misuses of stream APIs. Check for misuses of stream APIs: ``fopen, fclose``3533(demo checker, the subject of the demo (`Slides <https://llvm.org/devmtg/2012-11/Zaks-Rose-Checker24Hours.pdf>`_ ,3534`Video <https://youtu.be/kdxlsP5QVPw>`_) by Anna Zaks and Jordan Rose presented at the3535`2012 LLVM Developers' Meeting <https://llvm.org/devmtg/2012-11/>`_).3536 3537.. code-block:: c3538 3539 void test() {3540   FILE *F = fopen("myfile.txt", "w");3541 } // warn: opened file is never closed3542 3543 void test() {3544   FILE *F = fopen("myfile.txt", "w");3545 3546   if (F)3547     fclose(F);3548 3549   fclose(F); // warn: closing a previously closed file stream3550 }3551 3552.. _alpha-unix-cstring-BufferOverlap:3553 3554alpha.unix.cstring.BufferOverlap (C)3555""""""""""""""""""""""""""""""""""""3556Checks for overlap in two buffer arguments. Applies to:  ``memcpy, mempcpy, wmemcpy, wmempcpy``.3557 3558.. code-block:: c3559 3560 void test() {3561   int a[4] = {0};3562   memcpy(a + 2, a + 1, 8); // warn3563 }3564 3565.. _alpha-unix-cstring-OutOfBounds:3566 3567alpha.unix.cstring.OutOfBounds (C)3568""""""""""""""""""""""""""""""""""3569Check for out-of-bounds access in string functions, such as:3570``memcpy, bcopy, strcpy, strncpy, strcat, strncat, memmove, memcmp, memset`` and more.3571 3572This check also works with string literals, except there is a known bug in that3573the analyzer cannot detect embedded NULL characters when determining the string length.3574 3575.. code-block:: c3576 3577 void test1() {3578   const char str[] = "Hello world";3579   char buffer[] = "Hello world";3580   memcpy(buffer, str, sizeof(str) + 1); // warn3581 }3582 3583 void test2() {3584   const char str[] = "Hello world";3585   char buffer[] = "Helloworld";3586   memcpy(buffer, str, sizeof(str)); // warn3587 }3588 3589.. _alpha-unix-cstring-UninitializedRead:3590 3591alpha.unix.cstring.UninitializedRead (C)3592""""""""""""""""""""""""""""""""""""""""3593Check for uninitialized reads from common memory copy/manipulation functions such as:3594 ``memcpy, mempcpy, memmove, memcmp, strcmp, strncmp, strcpy, strlen, strsep`` and many more.3595 3596.. code-block:: c3597 3598 void test() {3599  char src[10];3600  char dst[5];3601  memcpy(dst,src,sizeof(dst)); // warn: Bytes string function accesses uninitialized/garbage values3602 }3603 3604Limitations:3605 3606   - Due to limitations of the memory modeling in the analyzer, one can likely3607     observe a lot of false-positive reports like this:3608 3609      .. code-block:: c3610 3611        void false_positive() {3612          int src[] = {1, 2, 3, 4};3613          int dst[5] = {0};3614          memcpy(dst, src, 4 * sizeof(int)); // false-positive:3615          // The 'src' buffer was correctly initialized, yet we cannot conclude3616          // that since the analyzer could not see a direct initialization of the3617          // very last byte of the source buffer.3618        }3619 3620     More details at the corresponding `GitHub issue <https://github.com/llvm/llvm-project/issues/43459>`_.3621 3622alpha.WebKit3623^^^^^^^^^^^^3624 3625alpha.webkit.ForwardDeclChecker3626"""""""""""""""""""""""""""""""3627Check for local variables, member variables, and function arguments that are forward declared.3628 3629.. code-block:: cpp3630 3631 struct Obj;3632 Obj* provide();3633 3634 struct Foo {3635   Obj* ptr; // warn3636 };3637 3638  void foo() {3639    Obj* obj = provide(); // warn3640    consume(obj); // warn3641  }3642 3643.. _alpha-webkit-NoUncheckedPtrMemberChecker:3644 3645alpha.webkit.MemoryUnsafeCastChecker3646""""""""""""""""""""""""""""""""""""""3647Check for all casts from a base type to its derived type as these might be memory-unsafe.3648 3649Example:3650 3651.. code-block:: cpp3652 3653    class Base { };3654    class Derived : public Base { };3655 3656    void f(Base* base) {3657        Derived* derived = static_cast<Derived*>(base); // ERROR3658    }3659 3660For all cast operations (C-style casts, static_cast, reinterpret_cast, dynamic_cast), if the source type a `Base*` and the destination type is `Derived*`, where `Derived` inherits from `Base`, the static analyzer should signal an error.3661 3662This applies to:3663 3664- C structs, C++ structs and classes, and Objective-C classes and protocols.3665- Pointers and references.3666- Inside template instantiations and macro expansions that are visible to the compiler.3667 3668For types like this, instead of using built in casts, the programmer will use helper functions that internally perform the appropriate type check and disable static analysis.3669 3670alpha.webkit.NoUncheckedPtrMemberChecker3671""""""""""""""""""""""""""""""""""""""""3672Raw pointers and references to an object which supports CheckedPtr or CheckedRef can't be used as class members. Only CheckedPtr, CheckedRef, RefPtr, or Ref are allowed.3673 3674.. code-block:: cpp3675 3676 struct CheckableObj {3677   void incrementCheckedPtrCount() {}3678   void decrementCheckedPtrCount() {}3679 };3680 3681 struct Foo {3682   CheckableObj* ptr; // warn3683   CheckableObj& ptr; // warn3684   // ...3685 };3686 3687See `WebKit Guidelines for Safer C++ Programming <https://github.com/WebKit/WebKit/wiki/Safer-CPP-Guidelines>`_ for details.3688 3689alpha.webkit.NoUnretainedMemberChecker3690""""""""""""""""""""""""""""""""""""""""3691Raw pointers and references to a NS or CF object can't be used as class members or ivars. Only RetainPtr is allowed for CF types regardless of whether ARC is enabled or disabled. Only RetainPtr or OSObjectPtr is allowed for NS types when ARC is disabled.3692 3693.. code-block:: cpp3694 3695 struct Foo {3696   NSObject *ptr; // warn3697   dispatch_queue_t queue; // warn3698   // ...3699 };3700 3701See `WebKit Guidelines for Safer C++ Programming <https://github.com/WebKit/WebKit/wiki/Safer-CPP-Guidelines>`_ for details.3702 3703alpha.webkit.UnretainedLambdaCapturesChecker3704""""""""""""""""""""""""""""""""""""""""""""3705Raw pointers and references to NS or CF types can't be captured in lambdas. Only RetainPtr is allowed for CF types regardless of whether ARC is enabled or disabled, and only RetainPtr or OSObjectPtr is allowed for NS types when ARC is disabled.3706 3707.. code-block:: cpp3708 3709 void foo(NSObject *a, NSObject *b, dispatch_queue_t c) {3710   [&, a](){ // warn about 'a'3711     do_something(b); // warn about 'b'3712     dispatch_queue_get_specific(c, "some"); // warn about 'c'3713   };3714 };3715 3716.. _alpha-webkit-UncountedCallArgsChecker:3717 3718alpha.webkit.UncountedCallArgsChecker3719"""""""""""""""""""""""""""""""""""""3720The 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.3721 3722Here 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.3723 3724  .. code-block:: cpp3725 3726    RefCountable* provide_uncounted();3727    void consume(RefCountable*);3728 3729    // 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.3730 3731    void foo1() {3732      consume(provide_uncounted()); // warn3733    }3734 3735    void foo2() {3736      RefCountable* uncounted = provide_uncounted();3737      consume(uncounted); // warn3738    }3739 3740Although 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.3741 3742Note: 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.3743 3744  .. code-block:: cpp3745 3746    struct Foo {3747      RefPtr<RefCountable> member;3748      void consume(RefCountable*) { /* ... */ }3749      void bugprone() {3750        consume(member.get()); // warn3751      }3752    };3753 3754The 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.3755 3756Allowed kinds of arguments:3757 3758- values obtained from ref-counted objects (including temporaries as those survive the call too)3759 3760  .. code-block:: cpp3761 3762    RefCountable* provide_uncounted();3763    void consume(RefCountable*);3764 3765    void foo() {3766      RefPtr<RefCountable> rc = makeRef(provide_uncounted());3767      consume(rc.get()); // ok3768      consume(makeRef(provide_uncounted()).get()); // ok3769    }3770 3771- forwarding uncounted arguments from caller to callee3772 3773  .. code-block:: cpp3774 3775    void foo(RefCountable& a) {3776      bar(a); // ok3777    }3778 3779  Caller of ``foo()`` is responsible for  ``a``'s lifetime.3780 3781- ``this`` pointer3782 3783  .. code-block:: cpp3784 3785    void Foo::foo() {3786      baz(this);  // ok3787    }3788 3789  Caller of ``foo()`` is responsible for keeping the memory pointed to by ``this`` pointer safe.3790 3791- constants3792 3793  .. code-block:: cpp3794 3795    foo(nullptr, NULL, 0); // ok3796 3797We 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.3798 3799- constructors of ref-counted types (including factory methods)3800- getters of ref-counted types3801- member overloaded operators3802- casts3803- unary operators like ``&`` or ``*``3804 3805alpha.webkit.UncheckedCallArgsChecker3806"""""""""""""""""""""""""""""""""""""3807The goal of this rule is to make sure that lifetime of any dynamically allocated CheckedPtr capable object passed as a call argument keeps its memory region past the end of the call. This applies to call to any function, method, lambda, function pointer or functor. CheckedPtr capable objects aren't supposed to be allocated on stack so we check arguments for parameters of raw pointers and references to unchecked types.3808 3809The rules of when to use and not to use CheckedPtr / CheckedRef are same as alpha.webkit.UncountedCallArgsChecker for ref-counted objects.3810 3811alpha.webkit.UnretainedCallArgsChecker3812""""""""""""""""""""""""""""""""""""""3813The goal of this rule is to make sure that lifetime of any dynamically allocated NS or CF objects passed as a call argument keeps its memory region past the end of the call. This applies to call to any function, method, lambda, function pointer or functor. NS or CF objects aren't supposed to be allocated on stack so we check arguments for parameters of raw pointers and references to unretained types.3814 3815The rules of when to use and not to use RetainPtr or OSObjectPtr are same as alpha.webkit.UncountedCallArgsChecker for ref-counted objects.3816 3817alpha.webkit.UncountedLocalVarsChecker3818""""""""""""""""""""""""""""""""""""""3819The goal of this rule is to make sure that any uncounted local variable is backed by a ref-counted object with lifetime that is strictly larger than the scope of the uncounted local variable. To be on the safe side we require the scope of an uncounted variable to be embedded in the scope of ref-counted object that backs it.3820 3821These are examples of cases that we consider safe:3822 3823  .. code-block:: cpp3824 3825    void foo1() {3826      RefPtr<RefCountable> counted;3827      // The scope of uncounted is EMBEDDED in the scope of counted.3828      {3829        RefCountable* uncounted = counted.get(); // ok3830      }3831    }3832 3833    void foo2(RefPtr<RefCountable> counted_param) {3834      RefCountable* uncounted = counted_param.get(); // ok3835    }3836 3837    void FooClass::foo_method() {3838      RefCountable* uncounted = this; // ok3839    }3840 3841Here 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 a local variable is safe or it's considered unsafe.3842 3843  .. code-block:: cpp3844 3845    void foo1() {3846      RefCountable* uncounted = new RefCountable; // warn3847    }3848 3849    RefCountable* global_uncounted;3850    void foo2() {3851      RefCountable* uncounted = global_uncounted; // warn3852    }3853 3854    void foo3() {3855      RefPtr<RefCountable> counted;3856      // The scope of uncounted is not EMBEDDED in the scope of counted.3857      RefCountable* uncounted = counted.get(); // warn3858    }3859 3860alpha.webkit.UncheckedLocalVarsChecker3861""""""""""""""""""""""""""""""""""""""3862The goal of this rule is to make sure that any unchecked local variable is backed by a CheckedPtr or CheckedRef with lifetime that is strictly larger than the scope of the unchecked local variable. To be on the safe side we require the scope of an unchecked variable to be embedded in the scope of CheckedPtr/CheckRef object that backs it.3863 3864These are examples of cases that we consider safe:3865 3866  .. code-block:: cpp3867 3868    void foo1() {3869      CheckedPtr<RefCountable> counted;3870      // The scope of uncounted is EMBEDDED in the scope of counted.3871      {3872        RefCountable* uncounted = counted.get(); // ok3873      }3874    }3875 3876    void foo2(CheckedPtr<RefCountable> counted_param) {3877      RefCountable* uncounted = counted_param.get(); // ok3878    }3879 3880    void FooClass::foo_method() {3881      RefCountable* uncounted = this; // ok3882    }3883 3884Here 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 a local variable is safe or it's considered unsafe.3885 3886  .. code-block:: cpp3887 3888    void foo1() {3889      RefCountable* uncounted = new RefCountable; // warn3890    }3891 3892    RefCountable* global_uncounted;3893    void foo2() {3894      RefCountable* uncounted = global_uncounted; // warn3895    }3896 3897    void foo3() {3898      RefPtr<RefCountable> counted;3899      // The scope of uncounted is not EMBEDDED in the scope of counted.3900      RefCountable* uncounted = counted.get(); // warn3901    }3902 3903alpha.webkit.UnretainedLocalVarsChecker3904"""""""""""""""""""""""""""""""""""""""3905The goal of this rule is to make sure that any NS or CF local variable is backed by a RetainPtr or OSObjectPtr with lifetime that is strictly larger than the scope of the unretained local variable. To be on the safe side we require the scope of an unretained variable to be embedded in the scope of RetainPtr or OSObjectPtr object that backs it.3906 3907The rules of when to use and not to use RetainPtr or OSObjectPtr are same as alpha.webkit.UncountedCallArgsChecker for ref-counted objects.3908 3909These are examples of cases that we consider safe:3910 3911  .. code-block:: cpp3912 3913    void foo1() {3914      RetainPtr<NSObject> retained;3915      // The scope of unretained is EMBEDDED in the scope of retained.3916      {3917        NSObject* unretained = retained.get(); // ok3918      }3919    }3920 3921    void foo2(RetainPtr<NSObject> retained_param) {3922      NSObject* unretained = retained_param.get(); // ok3923    }3924 3925    void FooClass::foo_method() {3926      NSObject* unretained = this; // ok3927    }3928 3929Here 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 a local variable is safe or it's considered unsafe.3930 3931  .. code-block:: cpp3932 3933    void foo1() {3934      NSObject* unretained = [[NSObject alloc] init]; // warn3935    }3936 3937    NSObject* global_unretained;3938    void foo2() {3939      NSObject* unretained = global_unretained; // warn3940    }3941 3942    void foo3() {3943      RetainPtr<NSObject> retained;3944      // The scope of unretained is not EMBEDDED in the scope of retained.3945      NSObject* unretained = retained.get(); // warn3946    }3947 3948webkit.RetainPtrCtorAdoptChecker3949""""""""""""""""""""""""""""""""3950The goal of this rule is to make sure the constructors of RetainPtr and OSObjectPtr as well as adoptNS, adoptCF, and adoptOSObject are used correctly.3951When creating a RetainPtr or OSObjectPtr with +1 semantics, adoptNS, adoptCF, or adoptOSObject should be used, and in +0 semantics, RetainPtr or OSObjectPtr constructor should be used.3952Warn otherwise.3953 3954These are examples of cases that we consider correct:3955 3956  .. code-block:: cpp3957 3958    RetainPtr ptr = adoptNS([[NSObject alloc] init]); // ok3959    RetainPtr ptr = CGImageGetColorSpace(image); // ok3960    OSObjectPtr ptr = adoptOSObject(dispatch_queue_create("some queue", nullptr)); // ok3961 3962Here are some examples of cases that we consider incorrect use of RetainPtr constructor and adoptCF3963 3964  .. code-block:: cpp3965 3966    RetainPtr ptr = [[NSObject alloc] init]; // warn3967    auto ptr = adoptCF(CGImageGetColorSpace(image)); // warn3968    OSObjectPtr ptr = dispatch_queue_create("some queue", nullptr); // warn3969 3970Debug Checkers3971---------------3972 3973.. _debug-checkers:3974 3975 3976debug3977^^^^^3978 3979Checkers used for debugging the analyzer.3980:doc:`developer-docs/DebugChecks` page contains a detailed description.3981 3982.. _debug-AnalysisOrder:3983 3984debug.AnalysisOrder3985"""""""""""""""""""3986Print callbacks that are called during analysis in order.3987 3988.. _debug-ConfigDumper:3989 3990debug.ConfigDumper3991""""""""""""""""""3992Dump config table.3993 3994.. _debug-DumpCFG Display:3995 3996debug.DumpCFG Display3997"""""""""""""""""""""3998Control-Flow Graphs.3999 4000.. _debug-DumpCallGraph:4001 4002debug.DumpCallGraph4003"""""""""""""""""""4004Display Call Graph.4005 4006.. _debug-DumpCalls:4007 4008debug.DumpCalls4009"""""""""""""""4010Print calls as they are traversed by the engine.4011 4012.. _debug-DumpDominators:4013 4014debug.DumpDominators4015""""""""""""""""""""4016Print the dominance tree for a given CFG.4017 4018.. _debug-DumpLiveVars:4019 4020debug.DumpLiveVars4021""""""""""""""""""4022Print results of live variable analysis.4023 4024.. _debug-DumpTraversal:4025 4026debug.DumpTraversal4027"""""""""""""""""""4028Print branch conditions as they are traversed by the engine.4029 4030.. _debug-ExprInspection:4031 4032debug.ExprInspection4033""""""""""""""""""""4034Check the analyzer's understanding of expressions.4035 4036.. _debug-Stats:4037 4038debug.Stats4039"""""""""""4040Emit warnings with analyzer statistics.4041 4042.. _debug-TaintTest:4043 4044debug.TaintTest4045"""""""""""""""4046Mark tainted symbols as such.4047 4048.. _debug-ViewCFG:4049 4050debug.ViewCFG4051"""""""""""""4052View Control-Flow Graphs using GraphViz.4053 4054.. _debug-ViewCallGraph:4055 4056debug.ViewCallGraph4057"""""""""""""""""""4058View Call Graph using GraphViz.4059 4060.. _debug-ViewExplodedGraph:4061 4062debug.ViewExplodedGraph4063"""""""""""""""""""""""4064View Exploded Graphs using GraphViz.4065