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