xref: /netbsd-src/external/apache2/llvm/dist/clang/docs/analyzer/checkers.rst (revision e038c9c4676b0f19b1b7dd08a940c6ed64a6d5ae)
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 its 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.. _webkit-UncountedLambdaCapturesChecker:
1427
1428webkit.UncountedLambdaCapturesChecker
1429"""""""""""""""""""""""""""""""""""""
1430Raw pointers and references to uncounted types can't be captured in lambdas. Only ref-counted types are allowed.
1431
1432.. code-block:: cpp
1433
1434 struct RefCntbl {
1435   void ref() {}
1436   void deref() {}
1437 };
1438
1439 void foo(RefCntbl* a, RefCntbl& b) {
1440   [&, a](){ // warn about 'a'
1441     do_something(b); // warn about 'b'
1442   };
1443 };
1444
1445.. _alpha-checkers:
1446
1447Experimental Checkers
1448---------------------
1449
1450*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.*
1451
1452alpha.clone
1453^^^^^^^^^^^
1454
1455.. _alpha-clone-CloneChecker:
1456
1457alpha.clone.CloneChecker (C, C++, ObjC)
1458"""""""""""""""""""""""""""""""""""""""
1459Reports similar pieces of code.
1460
1461.. code-block:: c
1462
1463 void log();
1464
1465 int max(int a, int b) { // warn
1466   log();
1467   if (a > b)
1468     return a;
1469   return b;
1470 }
1471
1472 int maxClone(int x, int y) { // similar code here
1473   log();
1474   if (x > y)
1475     return x;
1476   return y;
1477 }
1478
1479alpha.core
1480^^^^^^^^^^
1481
1482.. _alpha-core-BoolAssignment:
1483
1484alpha.core.BoolAssignment (ObjC)
1485""""""""""""""""""""""""""""""""
1486Warn about assigning non-{0,1} values to boolean variables.
1487
1488.. code-block:: objc
1489
1490 void test() {
1491   BOOL b = -1; // warn
1492 }
1493
1494.. _alpha-core-C11Lock:
1495
1496alpha.core.C11Lock
1497""""""""""""""""""
1498Similarly to :ref:`alpha.unix.PthreadLock <alpha-unix-PthreadLock>`, checks for
1499the locking/unlocking of ``mtx_t`` mutexes.
1500
1501.. code-block:: cpp
1502
1503 mtx_t mtx1;
1504
1505 void bad1(void)
1506 {
1507   mtx_lock(&mtx1);
1508   mtx_lock(&mtx1); // warn: This lock has already been acquired
1509 }
1510
1511.. _alpha-core-CallAndMessageUnInitRefArg:
1512
1513alpha.core.CallAndMessageUnInitRefArg (C,C++, ObjC)
1514"""""""""""""""""""""""""""""""""""""""""""""""""""
1515Check for logical errors for function calls and Objective-C
1516message expressions (e.g., uninitialized arguments, null function pointers, and pointer to undefined variables).
1517
1518.. code-block:: c
1519
1520 void test(void) {
1521   int t;
1522   int &p = t;
1523   int &s = p;
1524   int &q = s;
1525   foo(q); // warn
1526 }
1527
1528 void test(void) {
1529   int x;
1530   foo(&x); // warn
1531 }
1532
1533.. _alpha-core-CastSize:
1534
1535alpha.core.CastSize (C)
1536"""""""""""""""""""""""
1537Check when casting a malloc'ed type ``T``, whether the size is a multiple of the size of ``T``.
1538
1539.. code-block:: c
1540
1541 void test() {
1542   int *x = (int *) malloc(11); // warn
1543 }
1544
1545.. _alpha-core-CastToStruct:
1546
1547alpha.core.CastToStruct (C, C++)
1548""""""""""""""""""""""""""""""""
1549Check for cast from non-struct pointer to struct pointer.
1550
1551.. code-block:: cpp
1552
1553 // C
1554 struct s {};
1555
1556 void test(int *p) {
1557   struct s *ps = (struct s *) p; // warn
1558 }
1559
1560 // C++
1561 class c {};
1562
1563 void test(int *p) {
1564   c *pc = (c *) p; // warn
1565 }
1566
1567.. _alpha-core-Conversion:
1568
1569alpha.core.Conversion (C, C++, ObjC)
1570""""""""""""""""""""""""""""""""""""
1571Loss of sign/precision in implicit conversions.
1572
1573.. code-block:: c
1574
1575 void test(unsigned U, signed S) {
1576   if (S > 10) {
1577     if (U < S) {
1578     }
1579   }
1580   if (S < -10) {
1581     if (U < S) { // warn (loss of sign)
1582     }
1583   }
1584 }
1585
1586 void test() {
1587   long long A = 1LL << 60;
1588   short X = A; // warn (loss of precision)
1589 }
1590
1591.. _alpha-core-DynamicTypeChecker:
1592
1593alpha.core.DynamicTypeChecker (ObjC)
1594""""""""""""""""""""""""""""""""""""
1595Check for cases where the dynamic and the static type of an object are unrelated.
1596
1597
1598.. code-block:: objc
1599
1600 id date = [NSDate date];
1601
1602 // Warning: Object has a dynamic type 'NSDate *' which is
1603 // incompatible with static type 'NSNumber *'"
1604 NSNumber *number = date;
1605 [number doubleValue];
1606
1607.. _alpha-core-FixedAddr:
1608
1609alpha.core.FixedAddr (C)
1610""""""""""""""""""""""""
1611Check for assignment of a fixed address to a pointer.
1612
1613.. code-block:: c
1614
1615 void test() {
1616   int *p;
1617   p = (int *) 0x10000; // warn
1618 }
1619
1620.. _alpha-core-IdenticalExpr:
1621
1622alpha.core.IdenticalExpr (C, C++)
1623"""""""""""""""""""""""""""""""""
1624Warn about unintended use of identical expressions in operators.
1625
1626.. code-block:: cpp
1627
1628 // C
1629 void test() {
1630   int a = 5;
1631   int b = a | 4 | a; // warn: identical expr on both sides
1632 }
1633
1634 // C++
1635 bool f(void);
1636
1637 void test(bool b) {
1638   int i = 10;
1639   if (f()) { // warn: true and false branches are identical
1640     do {
1641       i--;
1642     } while (f());
1643   } else {
1644     do {
1645       i--;
1646     } while (f());
1647   }
1648 }
1649
1650.. _alpha-core-PointerArithm:
1651
1652alpha.core.PointerArithm (C)
1653""""""""""""""""""""""""""""
1654Check for pointer arithmetic on locations other than array elements.
1655
1656.. code-block:: c
1657
1658 void test() {
1659   int x;
1660   int *p;
1661   p = &x + 1; // warn
1662 }
1663
1664.. _alpha-core-PointerSub:
1665
1666alpha.core.PointerSub (C)
1667"""""""""""""""""""""""""
1668Check for pointer subtractions on two pointers pointing to different memory chunks.
1669
1670.. code-block:: c
1671
1672 void test() {
1673   int x, y;
1674   int d = &y - &x; // warn
1675 }
1676
1677.. _alpha-core-SizeofPtr:
1678
1679alpha.core.SizeofPtr (C)
1680""""""""""""""""""""""""
1681Warn about unintended use of ``sizeof()`` on pointer expressions.
1682
1683.. code-block:: c
1684
1685 struct s {};
1686
1687 int test(struct s *p) {
1688   return sizeof(p);
1689     // warn: sizeof(ptr) can produce an unexpected result
1690 }
1691
1692.. _alpha-core-StackAddressAsyncEscape:
1693
1694alpha.core.StackAddressAsyncEscape (C)
1695""""""""""""""""""""""""""""""""""""""
1696Check that addresses to stack memory do not escape the function that involves dispatch_after or dispatch_async.
1697This checker is a part of ``core.StackAddressEscape``, but is temporarily disabled until some false positives are fixed.
1698
1699.. code-block:: c
1700
1701 dispatch_block_t test_block_inside_block_async_leak() {
1702   int x = 123;
1703   void (^inner)(void) = ^void(void) {
1704     int y = x;
1705     ++y;
1706   };
1707   void (^outer)(void) = ^void(void) {
1708     int z = x;
1709     ++z;
1710     inner();
1711   };
1712   return outer; // warn: address of stack-allocated block is captured by a
1713                 //       returned block
1714 }
1715
1716.. _alpha-core-TestAfterDivZero:
1717
1718alpha.core.TestAfterDivZero (C)
1719"""""""""""""""""""""""""""""""
1720Check for division by variable that is later compared against 0.
1721Either the comparison is useless or there is division by zero.
1722
1723.. code-block:: c
1724
1725 void test(int x) {
1726   var = 77 / x;
1727   if (x == 0) { } // warn
1728 }
1729
1730alpha.cplusplus
1731^^^^^^^^^^^^^^^
1732
1733.. _alpha-cplusplus-DeleteWithNonVirtualDtor:
1734
1735alpha.cplusplus.DeleteWithNonVirtualDtor (C++)
1736""""""""""""""""""""""""""""""""""""""""""""""
1737Reports destructions of polymorphic objects with a non-virtual destructor in their base class.
1738
1739.. code-block:: cpp
1740
1741 NonVirtual *create() {
1742   NonVirtual *x = new NVDerived(); // note: conversion from derived to base
1743                                    //       happened here
1744   return x;
1745 }
1746
1747 void sink(NonVirtual *x) {
1748   delete x; // warn: destruction of a polymorphic object with no virtual
1749             //       destructor
1750 }
1751
1752.. _alpha-cplusplus-EnumCastOutOfRange:
1753
1754alpha.cplusplus.EnumCastOutOfRange (C++)
1755""""""""""""""""""""""""""""""""""""""""
1756Check for integer to enumeration casts that could result in undefined values.
1757
1758.. code-block:: cpp
1759
1760 enum TestEnum {
1761   A = 0
1762 };
1763
1764 void foo() {
1765   TestEnum t = static_cast(-1);
1766       // warn: the value provided to the cast expression is not in
1767       //       the valid range of values for the enum
1768
1769.. _alpha-cplusplus-InvalidatedIterator:
1770
1771alpha.cplusplus.InvalidatedIterator (C++)
1772"""""""""""""""""""""""""""""""""""""""""
1773Check for use of invalidated iterators.
1774
1775.. code-block:: cpp
1776
1777 void bad_copy_assign_operator_list1(std::list &L1,
1778                                     const std::list &L2) {
1779   auto i0 = L1.cbegin();
1780   L1 = L2;
1781   *i0; // warn: invalidated iterator accessed
1782 }
1783
1784
1785.. _alpha-cplusplus-IteratorRange:
1786
1787alpha.cplusplus.IteratorRange (C++)
1788"""""""""""""""""""""""""""""""""""
1789Check for iterators used outside their valid ranges.
1790
1791.. code-block:: cpp
1792
1793 void simple_bad_end(const std::vector &v) {
1794   auto i = v.end();
1795   *i; // warn: iterator accessed outside of its range
1796 }
1797
1798.. _alpha-cplusplus-MismatchedIterator:
1799
1800alpha.cplusplus.MismatchedIterator (C++)
1801""""""""""""""""""""""""""""""""""""""""
1802Check for use of iterators of different containers where iterators of the same container are expected.
1803
1804.. code-block:: cpp
1805
1806 void bad_insert3(std::vector &v1, std::vector &v2) {
1807   v2.insert(v1.cbegin(), v2.cbegin(), v2.cend()); // warn: container accessed
1808                                                   //       using foreign
1809                                                   //       iterator argument
1810   v1.insert(v1.cbegin(), v1.cbegin(), v2.cend()); // warn: iterators of
1811                                                   //       different containers
1812                                                   //       used where the same
1813                                                   //       container is
1814                                                   //       expected
1815   v1.insert(v1.cbegin(), v2.cbegin(), v1.cend()); // warn: iterators of
1816                                                   //       different containers
1817                                                   //       used where the same
1818                                                   //       container is
1819                                                   //       expected
1820 }
1821
1822.. _alpha-cplusplus-MisusedMovedObject:
1823
1824alpha.cplusplus.MisusedMovedObject (C++)
1825""""""""""""""""""""""""""""""""""""""""
1826Method calls on a moved-from object and copying a moved-from object will be reported.
1827
1828
1829.. code-block:: cpp
1830
1831  struct A {
1832   void foo() {}
1833 };
1834
1835 void f() {
1836   A a;
1837   A b = std::move(a); // note: 'a' became 'moved-from' here
1838   a.foo();            // warn: method call on a 'moved-from' object 'a'
1839 }
1840
1841alpha.deadcode
1842^^^^^^^^^^^^^^
1843.. _alpha-deadcode-UnreachableCode:
1844
1845alpha.deadcode.UnreachableCode (C, C++)
1846"""""""""""""""""""""""""""""""""""""""
1847Check unreachable code.
1848
1849.. code-block:: cpp
1850
1851 // C
1852 int test() {
1853   int x = 1;
1854   while(x);
1855   return x; // warn
1856 }
1857
1858 // C++
1859 void test() {
1860   int a = 2;
1861
1862   while (a > 1)
1863     a--;
1864
1865   if (a > 1)
1866     a++; // warn
1867 }
1868
1869 // Objective-C
1870 void test(id x) {
1871   return;
1872   [x retain]; // warn
1873 }
1874
1875.. _alpha-cplusplus-SmartPtr:
1876
1877alpha.cplusplus.SmartPtr (C++)
1878""""""""""""""""""""""""""""""
1879Check for dereference of null smart pointers.
1880
1881.. code-block:: cpp
1882
1883 void deref_smart_ptr() {
1884   std::unique_ptr<int> P;
1885   *P; // warn: dereference of a default constructed smart unique_ptr
1886 }
1887
1888alpha.fuchsia
1889^^^^^^^^^^^^^
1890
1891.. _alpha-fuchsia-lock:
1892
1893alpha.fuchsia.Lock
1894""""""""""""""""""
1895Similarly to :ref:`alpha.unix.PthreadLock <alpha-unix-PthreadLock>`, checks for
1896the locking/unlocking of fuchsia mutexes.
1897
1898.. code-block:: cpp
1899
1900 spin_lock_t mtx1;
1901
1902 void bad1(void)
1903 {
1904   spin_lock(&mtx1);
1905   spin_lock(&mtx1);	// warn: This lock has already been acquired
1906 }
1907
1908alpha.llvm
1909^^^^^^^^^^
1910
1911.. _alpha-llvm-Conventions:
1912
1913alpha.llvm.Conventions
1914""""""""""""""""""""""
1915
1916Check code for LLVM codebase conventions:
1917
1918* A StringRef should not be bound to a temporary std::string whose lifetime is shorter than the StringRef's.
1919* Clang AST nodes should not have fields that can allocate memory.
1920
1921
1922alpha.osx
1923^^^^^^^^^
1924
1925.. _alpha-osx-cocoa-DirectIvarAssignment:
1926
1927alpha.osx.cocoa.DirectIvarAssignment (ObjC)
1928"""""""""""""""""""""""""""""""""""""""""""
1929Check for direct assignments to instance variables.
1930
1931
1932.. code-block:: objc
1933
1934 @interface MyClass : NSObject {}
1935 @property (readonly) id A;
1936 - (void) foo;
1937 @end
1938
1939 @implementation MyClass
1940 - (void) foo {
1941   _A = 0; // warn
1942 }
1943 @end
1944
1945.. _alpha-osx-cocoa-DirectIvarAssignmentForAnnotatedFunctions:
1946
1947alpha.osx.cocoa.DirectIvarAssignmentForAnnotatedFunctions (ObjC)
1948""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
1949Check for direct assignments to instance variables in
1950the methods annotated with ``objc_no_direct_instance_variable_assignment``.
1951
1952.. code-block:: objc
1953
1954 @interface MyClass : NSObject {}
1955 @property (readonly) id A;
1956 - (void) fAnnotated __attribute__((
1957     annotate("objc_no_direct_instance_variable_assignment")));
1958 - (void) fNotAnnotated;
1959 @end
1960
1961 @implementation MyClass
1962 - (void) fAnnotated {
1963   _A = 0; // warn
1964 }
1965 - (void) fNotAnnotated {
1966   _A = 0; // no warn
1967 }
1968 @end
1969
1970
1971.. _alpha-osx-cocoa-InstanceVariableInvalidation:
1972
1973alpha.osx.cocoa.InstanceVariableInvalidation (ObjC)
1974"""""""""""""""""""""""""""""""""""""""""""""""""""
1975Check that the invalidatable instance variables are
1976invalidated in the methods annotated with objc_instance_variable_invalidator.
1977
1978.. code-block:: objc
1979
1980 @protocol Invalidation <NSObject>
1981 - (void) invalidate
1982   __attribute__((annotate("objc_instance_variable_invalidator")));
1983 @end
1984
1985 @interface InvalidationImpObj : NSObject <Invalidation>
1986 @end
1987
1988 @interface SubclassInvalidationImpObj : InvalidationImpObj {
1989   InvalidationImpObj *var;
1990 }
1991 - (void)invalidate;
1992 @end
1993
1994 @implementation SubclassInvalidationImpObj
1995 - (void) invalidate {}
1996 @end
1997 // warn: var needs to be invalidated or set to nil
1998
1999.. _alpha-osx-cocoa-MissingInvalidationMethod:
2000
2001alpha.osx.cocoa.MissingInvalidationMethod (ObjC)
2002""""""""""""""""""""""""""""""""""""""""""""""""
2003Check that the invalidation methods are present in classes that contain invalidatable instance variables.
2004
2005.. code-block:: objc
2006
2007 @protocol Invalidation <NSObject>
2008 - (void)invalidate
2009   __attribute__((annotate("objc_instance_variable_invalidator")));
2010 @end
2011
2012 @interface NeedInvalidation : NSObject <Invalidation>
2013 @end
2014
2015 @interface MissingInvalidationMethodDecl : NSObject {
2016   NeedInvalidation *Var; // warn
2017 }
2018 @end
2019
2020 @implementation MissingInvalidationMethodDecl
2021 @end
2022
2023.. _alpha-osx-cocoa-localizability-PluralMisuseChecker:
2024
2025alpha.osx.cocoa.localizability.PluralMisuseChecker (ObjC)
2026"""""""""""""""""""""""""""""""""""""""""""""""""""""""""
2027Warns against using one vs. many plural pattern in code when generating localized strings.
2028
2029.. code-block:: objc
2030
2031 NSString *reminderText =
2032   NSLocalizedString(@"None", @"Indicates no reminders");
2033 if (reminderCount == 1) {
2034   // Warning: Plural cases are not supported across all languages.
2035   // Use a .stringsdict file instead
2036   reminderText =
2037     NSLocalizedString(@"1 Reminder", @"Indicates single reminder");
2038 } else if (reminderCount >= 2) {
2039   // Warning: Plural cases are not supported across all languages.
2040   // Use a .stringsdict file instead
2041   reminderText =
2042     [NSString stringWithFormat:
2043       NSLocalizedString(@"%@ Reminders", @"Indicates multiple reminders"),
2044         reminderCount];
2045 }
2046
2047alpha.security
2048^^^^^^^^^^^^^^
2049
2050
2051alpha.security.cert
2052^^^^^^^^^^^^^^^^^^^
2053
2054SEI CERT checkers which tries to find errors based on their `C coding rules <https://wiki.sei.cmu.edu/confluence/display/c/2+Rules>`_.
2055
2056.. _alpha-security-cert-pos-checkers:
2057
2058alpha.security.cert.pos
2059^^^^^^^^^^^^^^^^^^^^^^^
2060
2061SEI CERT checkers of `POSIX C coding rules <https://wiki.sei.cmu.edu/confluence/pages/viewpage.action?pageId=87152405>`_.
2062
2063.. _alpha-security-cert-pos-34c:
2064
2065alpha.security.cert.pos.34c
2066"""""""""""""""""""""""""""
2067Finds calls to the ``putenv`` function which pass a pointer to an automatic variable as the argument.
2068
2069.. code-block:: c
2070
2071  int func(const char *var) {
2072    char env[1024];
2073    int retval = snprintf(env, sizeof(env),"TEST=%s", var);
2074    if (retval < 0 || (size_t)retval >= sizeof(env)) {
2075        /* Handle error */
2076    }
2077
2078    return putenv(env); // putenv function should not be called with auto variables
2079  }
2080
2081.. _alpha-security-ArrayBound:
2082
2083alpha.security.ArrayBound (C)
2084"""""""""""""""""""""""""""""
2085Warn about buffer overflows (older checker).
2086
2087.. code-block:: c
2088
2089 void test() {
2090   char *s = "";
2091   char c = s[1]; // warn
2092 }
2093
2094 struct seven_words {
2095   int c[7];
2096 };
2097
2098 void test() {
2099   struct seven_words a, *p;
2100   p = &a;
2101   p[0] = a;
2102   p[1] = a;
2103   p[2] = a; // warn
2104 }
2105
2106 // note: requires unix.Malloc or
2107 // alpha.unix.MallocWithAnnotations checks enabled.
2108 void test() {
2109   int *p = malloc(12);
2110   p[3] = 4; // warn
2111 }
2112
2113 void test() {
2114   char a[2];
2115   int *b = (int*)a;
2116   b[1] = 3; // warn
2117 }
2118
2119.. _alpha-security-ArrayBoundV2:
2120
2121alpha.security.ArrayBoundV2 (C)
2122"""""""""""""""""""""""""""""""
2123Warn about buffer overflows (newer checker).
2124
2125.. code-block:: c
2126
2127 void test() {
2128   char *s = "";
2129   char c = s[1]; // warn
2130 }
2131
2132 void test() {
2133   int buf[100];
2134   int *p = buf;
2135   p = p + 99;
2136   p[1] = 1; // warn
2137 }
2138
2139 // note: compiler has internal check for this.
2140 // Use -Wno-array-bounds to suppress compiler warning.
2141 void test() {
2142   int buf[100][100];
2143   buf[0][-1] = 1; // warn
2144 }
2145
2146 // note: requires alpha.security.taint check turned on.
2147 void test() {
2148   char s[] = "abc";
2149   int x = getchar();
2150   char c = s[x]; // warn: index is tainted
2151 }
2152
2153.. _alpha-security-MallocOverflow:
2154
2155alpha.security.MallocOverflow (C)
2156"""""""""""""""""""""""""""""""""
2157Check for overflows in the arguments to malloc().
2158
2159.. code-block:: c
2160
2161 void test(int n) {
2162   void *p = malloc(n * sizeof(int)); // warn
2163 }
2164
2165 void test2(int n) {
2166   if (n > 100) // gives an upper-bound
2167     return;
2168   void *p = malloc(n * sizeof(int)); // no warning
2169 }
2170
2171.. _alpha-security-MmapWriteExec:
2172
2173alpha.security.MmapWriteExec (C)
2174""""""""""""""""""""""""""""""""
2175Warn on mmap() calls that are both writable and executable.
2176
2177.. code-block:: c
2178
2179 void test(int n) {
2180   void *c = mmap(NULL, 32, PROT_READ | PROT_WRITE | PROT_EXEC,
2181                  MAP_PRIVATE | MAP_ANON, -1, 0);
2182   // warn: Both PROT_WRITE and PROT_EXEC flags are set. This can lead to
2183   //       exploitable memory regions, which could be overwritten with malicious
2184   //       code
2185 }
2186
2187.. _alpha-security-ReturnPtrRange:
2188
2189alpha.security.ReturnPtrRange (C)
2190"""""""""""""""""""""""""""""""""
2191Check for an out-of-bound pointer being returned to callers.
2192
2193.. code-block:: c
2194
2195 static int A[10];
2196
2197 int *test() {
2198   int *p = A + 10;
2199   return p; // warn
2200 }
2201
2202 int test(void) {
2203   int x;
2204   return x; // warn: undefined or garbage returned
2205 }
2206
2207.. _alpha-security-taint-TaintPropagation:
2208
2209alpha.security.taint.TaintPropagation (C, C++)
2210""""""""""""""""""""""""""""""""""""""""""""""
2211Generate taint information used by other checkers.
2212A data is tainted when it comes from an unreliable source.
2213
2214.. code-block:: c
2215
2216 void test() {
2217   char x = getchar(); // 'x' marked as tainted
2218   system(&x); // warn: untrusted data is passed to a system call
2219 }
2220
2221 // note: compiler internally checks if the second param to
2222 // sprintf is a string literal or not.
2223 // Use -Wno-format-security to suppress compiler warning.
2224 void test() {
2225   char s[10], buf[10];
2226   fscanf(stdin, "%s", s); // 's' marked as tainted
2227
2228   sprintf(buf, s); // warn: untrusted data as a format string
2229 }
2230
2231 void test() {
2232   size_t ts;
2233   scanf("%zd", &ts); // 'ts' marked as tainted
2234   int *p = (int *)malloc(ts * sizeof(int));
2235     // warn: untrusted data as buffer size
2236 }
2237
2238alpha.unix
2239^^^^^^^^^^^
2240
2241.. _alpha-unix-BlockInCriticalSection:
2242
2243alpha.unix.BlockInCriticalSection (C)
2244"""""""""""""""""""""""""""""""""""""
2245Check for calls to blocking functions inside a critical section.
2246Applies to: ``lock, unlock, sleep, getc, fgets, read, recv, pthread_mutex_lock,``
2247`` pthread_mutex_unlock, mtx_lock, mtx_timedlock, mtx_trylock, mtx_unlock, lock_guard, unique_lock``
2248
2249.. code-block:: c
2250
2251 void test() {
2252   std::mutex m;
2253   m.lock();
2254   sleep(3); // warn: a blocking function sleep is called inside a critical
2255             //       section
2256   m.unlock();
2257 }
2258
2259.. _alpha-unix-Chroot:
2260
2261alpha.unix.Chroot (C)
2262"""""""""""""""""""""
2263Check improper use of chroot.
2264
2265.. code-block:: c
2266
2267 void f();
2268
2269 void test() {
2270   chroot("/usr/local");
2271   f(); // warn: no call of chdir("/") immediately after chroot
2272 }
2273
2274.. _alpha-unix-PthreadLock:
2275
2276alpha.unix.PthreadLock (C)
2277""""""""""""""""""""""""""
2278Simple lock -> unlock checker.
2279Applies to: ``pthread_mutex_lock, pthread_rwlock_rdlock, pthread_rwlock_wrlock, lck_mtx_lock, lck_rw_lock_exclusive``
2280``lck_rw_lock_shared, pthread_mutex_trylock, pthread_rwlock_tryrdlock, pthread_rwlock_tryrwlock, lck_mtx_try_lock,
2281lck_rw_try_lock_exclusive, lck_rw_try_lock_shared, pthread_mutex_unlock, pthread_rwlock_unlock, lck_mtx_unlock, lck_rw_done``.
2282
2283
2284.. code-block:: c
2285
2286 pthread_mutex_t mtx;
2287
2288 void test() {
2289   pthread_mutex_lock(&mtx);
2290   pthread_mutex_lock(&mtx);
2291     // warn: this lock has already been acquired
2292 }
2293
2294 lck_mtx_t lck1, lck2;
2295
2296 void test() {
2297   lck_mtx_lock(&lck1);
2298   lck_mtx_lock(&lck2);
2299   lck_mtx_unlock(&lck1);
2300     // warn: this was not the most recently acquired lock
2301 }
2302
2303 lck_mtx_t lck1, lck2;
2304
2305 void test() {
2306   if (lck_mtx_try_lock(&lck1) == 0)
2307     return;
2308
2309   lck_mtx_lock(&lck2);
2310   lck_mtx_unlock(&lck1);
2311     // warn: this was not the most recently acquired lock
2312 }
2313
2314.. _alpha-unix-SimpleStream:
2315
2316alpha.unix.SimpleStream (C)
2317"""""""""""""""""""""""""""
2318Check for misuses of stream APIs. Check for misuses of stream APIs: ``fopen, fclose``
2319(demo checker, the subject of the demo (`Slides <https://llvm.org/devmtg/2012-11/Zaks-Rose-Checker24Hours.pdf>`_ ,
2320`Video <https://youtu.be/kdxlsP5QVPw>`_) by Anna Zaks and Jordan Rose presented at the
2321`2012 LLVM Developers' Meeting <https://llvm.org/devmtg/2012-11/>`_).
2322
2323.. code-block:: c
2324
2325 void test() {
2326   FILE *F = fopen("myfile.txt", "w");
2327 } // warn: opened file is never closed
2328
2329 void test() {
2330   FILE *F = fopen("myfile.txt", "w");
2331
2332   if (F)
2333     fclose(F);
2334
2335   fclose(F); // warn: closing a previously closed file stream
2336 }
2337
2338.. _alpha-unix-Stream:
2339
2340alpha.unix.Stream (C)
2341"""""""""""""""""""""
2342Check stream handling functions: ``fopen, tmpfile, fclose, fread, fwrite, fseek, ftell, rewind, fgetpos,``
2343``fsetpos, clearerr, feof, ferror, fileno``.
2344
2345.. code-block:: c
2346
2347 void test() {
2348   FILE *p = fopen("foo", "r");
2349 } // warn: opened file is never closed
2350
2351 void test() {
2352   FILE *p = fopen("foo", "r");
2353   fseek(p, 1, SEEK_SET); // warn: stream pointer might be NULL
2354   fclose(p);
2355 }
2356
2357 void test() {
2358   FILE *p = fopen("foo", "r");
2359
2360   if (p)
2361     fseek(p, 1, 3);
2362      // warn: third arg should be SEEK_SET, SEEK_END, or SEEK_CUR
2363
2364   fclose(p);
2365 }
2366
2367 void test() {
2368   FILE *p = fopen("foo", "r");
2369   fclose(p);
2370   fclose(p); // warn: already closed
2371 }
2372
2373 void test() {
2374   FILE *p = tmpfile();
2375   ftell(p); // warn: stream pointer might be NULL
2376   fclose(p);
2377 }
2378
2379
2380.. _alpha-unix-cstring-BufferOverlap:
2381
2382alpha.unix.cstring.BufferOverlap (C)
2383""""""""""""""""""""""""""""""""""""
2384Checks for overlap in two buffer arguments. Applies to:  ``memcpy, mempcpy``.
2385
2386.. code-block:: c
2387
2388 void test() {
2389   int a[4] = {0};
2390   memcpy(a + 2, a + 1, 8); // warn
2391 }
2392
2393.. _alpha-unix-cstring-NotNullTerminated:
2394
2395alpha.unix.cstring.NotNullTerminated (C)
2396""""""""""""""""""""""""""""""""""""""""
2397Check for arguments which are not null-terminated strings; applies to: ``strlen, strnlen, strcpy, strncpy, strcat, strncat``.
2398
2399.. code-block:: c
2400
2401 void test() {
2402   int y = strlen((char *)&test); // warn
2403 }
2404
2405.. _alpha-unix-cstring-OutOfBounds:
2406
2407alpha.unix.cstring.OutOfBounds (C)
2408""""""""""""""""""""""""""""""""""
2409Check for out-of-bounds access in string functions; applies to:`` strncopy, strncat``.
2410
2411
2412.. code-block:: c
2413
2414 void test() {
2415   int y = strlen((char *)&test); // warn
2416 }
2417
2418.. _alpha-nondeterminism-PointerIteration:
2419
2420alpha.nondeterminism.PointerIteration (C++)
2421"""""""""""""""""""""""""""""""""""""""""""
2422Check for non-determinism caused by iterating unordered containers of pointers.
2423
2424.. code-block:: c
2425
2426 void test() {
2427  int a = 1, b = 2;
2428  std::unordered_set<int *> UnorderedPtrSet = {&a, &b};
2429
2430  for (auto i : UnorderedPtrSet) // warn
2431    f(i);
2432 }
2433
2434.. _alpha-nondeterminism-PointerSorting:
2435
2436alpha.nondeterminism.PointerSorting (C++)
2437"""""""""""""""""""""""""""""""""""""""""
2438Check for non-determinism caused by sorting of pointers.
2439
2440.. code-block:: c
2441
2442 void test() {
2443  int a = 1, b = 2;
2444  std::vector<int *> V = {&a, &b};
2445  std::sort(V.begin(), V.end()); // warn
2446 }
2447
2448
2449alpha.WebKit
2450^^^^^^^^^^^^
2451
2452.. _alpha-webkit-UncountedCallArgsChecker:
2453
2454alpha.webkit.UncountedCallArgsChecker
2455"""""""""""""""""""""""""""""""""""""
2456The 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.
2457
2458Here 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.
2459
2460  .. code-block:: cpp
2461
2462    RefCountable* provide_uncounted();
2463    void consume(RefCountable*);
2464
2465    // 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.
2466
2467    void foo1() {
2468      consume(provide_uncounted()); // warn
2469    }
2470
2471    void foo2() {
2472      RefCountable* uncounted = provide_uncounted();
2473      consume(uncounted); // warn
2474    }
2475
2476Although 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.
2477
2478Note: 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.
2479
2480  .. code-block:: cpp
2481
2482    struct Foo {
2483      RefPtr<RefCountable> member;
2484      void consume(RefCountable*) { /* ... */ }
2485      void bugprone() {
2486        consume(member.get()); // warn
2487      }
2488    };
2489
2490The 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.
2491
2492Allowed kinds of arguments:
2493
2494- values obtained from ref-counted objects (including temporaries as those survive the call too)
2495
2496  .. code-block:: cpp
2497
2498    RefCountable* provide_uncounted();
2499    void consume(RefCountable*);
2500
2501    void foo() {
2502      RefPtr<RefCountable> rc = makeRef(provide_uncounted());
2503      consume(rc.get()); // ok
2504      consume(makeRef(provide_uncounted()).get()); // ok
2505    }
2506
2507- forwarding uncounted arguments from caller to callee
2508
2509  .. code-block:: cpp
2510
2511    void foo(RefCountable& a) {
2512      bar(a); // ok
2513    }
2514
2515  Caller of ``foo()`` is responsible for  ``a``'s lifetime.
2516
2517- ``this`` pointer
2518
2519  .. code-block:: cpp
2520
2521    void Foo::foo() {
2522      baz(this);  // ok
2523    }
2524
2525  Caller of ``foo()`` is responsible for keeping the memory pointed to by ``this`` pointer safe.
2526
2527- constants
2528
2529  .. code-block:: cpp
2530
2531    foo(nullptr, NULL, 0); // ok
2532
2533We 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.
2534
2535- constructors of ref-counted types (including factory methods)
2536- getters of ref-counted types
2537- member overloaded operators
2538- casts
2539- unary operators like ``&`` or ``*``
2540
2541alpha.webkit.UncountedLocalVarsChecker
2542""""""""""""""""""""""""""""""""""""""
2543The 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.
2544
2545These are examples of cases that we consider safe:
2546
2547  .. code-block:: cpp
2548
2549    void foo1() {
2550      RefPtr<RefCountable> counted;
2551      // The scope of uncounted is EMBEDDED in the scope of counted.
2552      {
2553        RefCountable* uncounted = counted.get(); // ok
2554      }
2555    }
2556
2557    void foo2(RefPtr<RefCountable> counted_param) {
2558      RefCountable* uncounted = counted_param.get(); // ok
2559    }
2560
2561    void FooClass::foo_method() {
2562      RefCountable* uncounted = this; // ok
2563    }
2564
2565Here 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.
2566
2567  .. code-block:: cpp
2568
2569    void foo1() {
2570      RefCountable* uncounted = new RefCountable; // warn
2571    }
2572
2573    RefCountable* global_uncounted;
2574    void foo2() {
2575      RefCountable* uncounted = global_uncounted; // warn
2576    }
2577
2578    void foo3() {
2579      RefPtr<RefCountable> counted;
2580      // The scope of uncounted is not EMBEDDED in the scope of counted.
2581      RefCountable* uncounted = counted.get(); // warn
2582    }
2583
2584We don't warn about these cases - we don't consider them necessarily safe but since they are very common and usually safe we'd introduce a lot of false positives otherwise:
2585- variable defined in condition part of an ```if``` statement
2586- variable defined in init statement condition of a ```for``` statement
2587
2588For the time being we also don't warn about uninitialized uncounted local variables.
2589
2590Debug Checkers
2591---------------
2592
2593.. _debug-checkers:
2594
2595
2596debug
2597^^^^^
2598
2599Checkers used for debugging the analyzer.
2600:doc:`developer-docs/DebugChecks` page contains a detailed description.
2601
2602.. _debug-AnalysisOrder:
2603
2604debug.AnalysisOrder
2605"""""""""""""""""""
2606Print callbacks that are called during analysis in order.
2607
2608.. _debug-ConfigDumper:
2609
2610debug.ConfigDumper
2611""""""""""""""""""
2612Dump config table.
2613
2614.. _debug-DumpCFG Display:
2615
2616debug.DumpCFG Display
2617"""""""""""""""""""""
2618Control-Flow Graphs.
2619
2620.. _debug-DumpCallGraph:
2621
2622debug.DumpCallGraph
2623"""""""""""""""""""
2624Display Call Graph.
2625
2626.. _debug-DumpCalls:
2627
2628debug.DumpCalls
2629"""""""""""""""
2630Print calls as they are traversed by the engine.
2631
2632.. _debug-DumpDominators:
2633
2634debug.DumpDominators
2635""""""""""""""""""""
2636Print the dominance tree for a given CFG.
2637
2638.. _debug-DumpLiveVars:
2639
2640debug.DumpLiveVars
2641""""""""""""""""""
2642Print results of live variable analysis.
2643
2644.. _debug-DumpTraversal:
2645
2646debug.DumpTraversal
2647"""""""""""""""""""
2648Print branch conditions as they are traversed by the engine.
2649
2650.. _debug-ExprInspection:
2651
2652debug.ExprInspection
2653""""""""""""""""""""
2654Check the analyzer's understanding of expressions.
2655
2656.. _debug-Stats:
2657
2658debug.Stats
2659"""""""""""
2660Emit warnings with analyzer statistics.
2661
2662.. _debug-TaintTest:
2663
2664debug.TaintTest
2665"""""""""""""""
2666Mark tainted symbols as such.
2667
2668.. _debug-ViewCFG:
2669
2670debug.ViewCFG
2671"""""""""""""
2672View Control-Flow Graphs using GraphViz.
2673
2674.. _debug-ViewCallGraph:
2675
2676debug.ViewCallGraph
2677"""""""""""""""""""
2678View Call Graph using GraphViz.
2679
2680.. _debug-ViewExplodedGraph:
2681
2682debug.ViewExplodedGraph
2683"""""""""""""""""""""""
2684View Exploded Graphs using GraphViz.
2685
2686