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