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
71This checker specifically does
72not report null pointer dereferences for x86 and x86-64 targets when the
73address space is 256 (x86 GS Segment), 257 (x86 FS Segment), or 258 (x86 SS
74segment). See `X86/X86-64 Language Extensions
75<https://clang.llvm.org/docs/LanguageExtensions.html#memory-references-to-specified-segments>`__
76for reference.
77
78The ``SuppressAddressSpaces`` option suppresses
79warnings for null dereferences of all pointers with address spaces. You can
80disable this behavior with the option
81``-analyzer-config core.NullDereference:SuppressAddressSpaces=false``.
82*Defaults to true*.
83
84.. code-block:: objc
85
86 // C
87 void test(int *p) {
88   if (p)
89     return;
90
91   int x = p[0]; // warn
92 }
93
94 // C
95 void test(int *p) {
96   if (!p)
97     *p = 0; // warn
98 }
99
100 // C++
101 class C {
102 public:
103   int x;
104 };
105
106 void test() {
107   C *pc = 0;
108   int k = pc->x; // warn
109 }
110
111 // Objective-C
112 @interface MyClass {
113 @public
114   int x;
115 }
116 @end
117
118 void test() {
119   MyClass *obj = 0;
120   obj->x = 1; // warn
121 }
122
123.. _core-StackAddressEscape:
124
125core.StackAddressEscape (C)
126"""""""""""""""""""""""""""
127Check that addresses to stack memory do not escape the function.
128
129.. code-block:: c
130
131 char const *p;
132
133 void test() {
134   char const str[] = "string";
135   p = str; // warn
136 }
137
138 void* test() {
139    return __builtin_alloca(12); // warn
140 }
141
142 void test() {
143   static int *x;
144   int y;
145   x = &y; // warn
146 }
147
148
149.. _core-UndefinedBinaryOperatorResult:
150
151core.UndefinedBinaryOperatorResult (C)
152""""""""""""""""""""""""""""""""""""""
153Check for undefined results of binary operators.
154
155.. code-block:: c
156
157 void test() {
158   int x;
159   int y = x + 1; // warn: left operand is garbage
160 }
161
162.. _core-VLASize:
163
164core.VLASize (C)
165""""""""""""""""
166Check for declarations of Variable Length Arrays of undefined or zero size.
167
168 Check for declarations of VLA of undefined or zero size.
169
170.. code-block:: c
171
172 void test() {
173   int x;
174   int vla1[x]; // warn: garbage as size
175 }
176
177 void test() {
178   int x = 0;
179   int vla2[x]; // warn: zero size
180 }
181
182.. _core-uninitialized-ArraySubscript:
183
184core.uninitialized.ArraySubscript (C)
185"""""""""""""""""""""""""""""""""""""
186Check for uninitialized values used as array subscripts.
187
188.. code-block:: c
189
190 void test() {
191   int i, a[10];
192   int x = a[i]; // warn: array subscript is undefined
193 }
194
195.. _core-uninitialized-Assign:
196
197core.uninitialized.Assign (C)
198"""""""""""""""""""""""""""""
199Check for assigning uninitialized values.
200
201.. code-block:: c
202
203 void test() {
204   int x;
205   x |= 1; // warn: left expression is uninitialized
206 }
207
208.. _core-uninitialized-Branch:
209
210core.uninitialized.Branch (C)
211"""""""""""""""""""""""""""""
212Check for uninitialized values used as branch conditions.
213
214.. code-block:: c
215
216 void test() {
217   int x;
218   if (x) // warn
219     return;
220 }
221
222.. _core-uninitialized-CapturedBlockVariable:
223
224core.uninitialized.CapturedBlockVariable (C)
225""""""""""""""""""""""""""""""""""""""""""""
226Check for blocks that capture uninitialized values.
227
228.. code-block:: c
229
230 void test() {
231   int x;
232   ^{ int y = x; }(); // warn
233 }
234
235.. _core-uninitialized-UndefReturn:
236
237core.uninitialized.UndefReturn (C)
238""""""""""""""""""""""""""""""""""
239Check for uninitialized values being returned to the caller.
240
241.. code-block:: c
242
243 int test() {
244   int x;
245   return x; // warn
246 }
247
248.. _core-uninitialized-NewArraySize:
249
250core.uninitialized.NewArraySize (C++)
251"""""""""""""""""""""""""""""""""""""
252
253Check if the element count in new[] is garbage or undefined.
254
255.. code-block:: cpp
256
257  void test() {
258    int n;
259    int *arr = new int[n]; // warn: Element count in new[] is a garbage value
260    delete[] arr;
261  }
262
263
264.. _cplusplus-checkers:
265
266
267cplusplus
268^^^^^^^^^
269
270C++ Checkers.
271
272.. _cplusplus-InnerPointer:
273
274cplusplus.InnerPointer (C++)
275""""""""""""""""""""""""""""
276Check for inner pointers of C++ containers used after re/deallocation.
277
278Many container methods in the C++ standard library are known to invalidate
279"references" (including actual references, iterators and raw pointers) to
280elements of the container. Using such references after they are invalidated
281causes undefined behavior, which is a common source of memory errors in C++ that
282this checker is capable of finding.
283
284The checker is currently limited to ``std::string`` objects and doesn't
285recognize some of the more sophisticated approaches to passing unowned pointers
286around, such as ``std::string_view``.
287
288.. code-block:: cpp
289
290 void deref_after_assignment() {
291   std::string s = "llvm";
292   const char *c = s.data(); // note: pointer to inner buffer of 'std::string' obtained here
293   s = "clang"; // note: inner buffer of 'std::string' reallocated by call to 'operator='
294   consume(c); // warn: inner pointer of container used after re/deallocation
295 }
296
297 const char *return_temp(int x) {
298   return std::to_string(x).c_str(); // warn: inner pointer of container used after re/deallocation
299   // note: pointer to inner buffer of 'std::string' obtained here
300   // note: inner buffer of 'std::string' deallocated by call to destructor
301 }
302
303.. _cplusplus-NewDelete:
304
305cplusplus.NewDelete (C++)
306"""""""""""""""""""""""""
307Check for double-free and use-after-free problems. Traces memory managed by new/delete.
308
309.. literalinclude:: checkers/newdelete_example.cpp
310    :language: cpp
311
312.. _cplusplus-NewDeleteLeaks:
313
314cplusplus.NewDeleteLeaks (C++)
315""""""""""""""""""""""""""""""
316Check for memory leaks. Traces memory managed by new/delete.
317
318.. code-block:: cpp
319
320 void test() {
321   int *p = new int;
322 } // warn
323
324.. _cplusplus-PlacementNewChecker:
325
326cplusplus.PlacementNewChecker (C++)
327"""""""""""""""""""""""""""""""""""
328Check if default placement new is provided with pointers to sufficient storage capacity.
329
330.. code-block:: cpp
331
332 #include <new>
333
334 void f() {
335   short s;
336   long *lp = ::new (&s) long; // warn
337 }
338
339.. _cplusplus-SelfAssignment:
340
341cplusplus.SelfAssignment (C++)
342""""""""""""""""""""""""""""""
343Checks C++ copy and move assignment operators for self assignment.
344
345.. _cplusplus-StringChecker:
346
347cplusplus.StringChecker (C++)
348"""""""""""""""""""""""""""""
349Checks std::string operations.
350
351Checks if the cstring pointer from which the ``std::string`` object is
352constructed is ``NULL`` or not.
353If the checker cannot reason about the nullness of the pointer it will assume
354that it was non-null to satisfy the precondition of the constructor.
355
356This checker is capable of checking the `SEI CERT C++ coding rule STR51-CPP.
357Do not attempt to create a std::string from a null pointer
358<https://wiki.sei.cmu.edu/confluence/x/E3s-BQ>`__.
359
360.. code-block:: cpp
361
362 #include <string>
363
364 void f(const char *p) {
365   if (!p) {
366     std::string msg(p); // warn: The parameter must not be null
367   }
368 }
369
370.. _deadcode-checkers:
371
372deadcode
373^^^^^^^^
374
375Dead Code Checkers.
376
377.. _deadcode-DeadStores:
378
379deadcode.DeadStores (C)
380"""""""""""""""""""""""
381Check for values stored to variables that are never read afterwards.
382
383.. code-block:: c
384
385 void test() {
386   int x;
387   x = 1; // warn
388 }
389
390The ``WarnForDeadNestedAssignments`` option enables the checker to emit
391warnings for nested dead assignments. You can disable with the
392``-analyzer-config deadcode.DeadStores:WarnForDeadNestedAssignments=false``.
393*Defaults to true*.
394
395Would warn for this e.g.:
396if ((y = make_int())) {
397}
398
399.. _nullability-checkers:
400
401nullability
402^^^^^^^^^^^
403
404Objective C checkers that warn for null pointer passing and dereferencing errors.
405
406.. _nullability-NullPassedToNonnull:
407
408nullability.NullPassedToNonnull (ObjC)
409""""""""""""""""""""""""""""""""""""""
410Warns when a null pointer is passed to a pointer which has a _Nonnull type.
411
412.. code-block:: objc
413
414 if (name != nil)
415   return;
416 // Warning: nil passed to a callee that requires a non-null 1st parameter
417 NSString *greeting = [@"Hello " stringByAppendingString:name];
418
419.. _nullability-NullReturnedFromNonnull:
420
421nullability.NullReturnedFromNonnull (ObjC)
422""""""""""""""""""""""""""""""""""""""""""
423Warns when a null pointer is returned from a function that has _Nonnull return type.
424
425.. code-block:: objc
426
427 - (nonnull id)firstChild {
428   id result = nil;
429   if ([_children count] > 0)
430     result = _children[0];
431
432   // Warning: nil returned from a method that is expected
433   // to return a non-null value
434   return result;
435 }
436
437.. _nullability-NullableDereferenced:
438
439nullability.NullableDereferenced (ObjC)
440"""""""""""""""""""""""""""""""""""""""
441Warns when a nullable pointer is dereferenced.
442
443.. code-block:: objc
444
445 struct LinkedList {
446   int data;
447   struct LinkedList *next;
448 };
449
450 struct LinkedList * _Nullable getNext(struct LinkedList *l);
451
452 void updateNextData(struct LinkedList *list, int newData) {
453   struct LinkedList *next = getNext(list);
454   // Warning: Nullable pointer is dereferenced
455   next->data = 7;
456 }
457
458.. _nullability-NullablePassedToNonnull:
459
460nullability.NullablePassedToNonnull (ObjC)
461""""""""""""""""""""""""""""""""""""""""""
462Warns when a nullable pointer is passed to a pointer which has a _Nonnull type.
463
464.. code-block:: objc
465
466 typedef struct Dummy { int val; } Dummy;
467 Dummy *_Nullable returnsNullable();
468 void takesNonnull(Dummy *_Nonnull);
469
470 void test() {
471   Dummy *p = returnsNullable();
472   takesNonnull(p); // warn
473 }
474
475.. _nullability-NullableReturnedFromNonnull:
476
477nullability.NullableReturnedFromNonnull (ObjC)
478""""""""""""""""""""""""""""""""""""""""""""""
479Warns when a nullable pointer is returned from a function that has _Nonnull return type.
480
481.. _optin-checkers:
482
483optin
484^^^^^
485
486Checkers for portability, performance or coding style specific rules.
487
488.. _optin-cplusplus-UninitializedObject:
489
490optin.cplusplus.UninitializedObject (C++)
491"""""""""""""""""""""""""""""""""""""""""
492
493This checker reports uninitialized fields in objects created after a constructor
494call. It doesn't only find direct uninitialized fields, but rather makes a deep
495inspection of the object, analyzing all of its fields' subfields.
496The checker regards inherited fields as direct fields, so one will receive
497warnings for uninitialized inherited data members as well.
498
499.. code-block:: cpp
500
501 // With Pedantic and CheckPointeeInitialization set to true
502
503 struct A {
504   struct B {
505     int x; // note: uninitialized field 'this->b.x'
506     // note: uninitialized field 'this->bptr->x'
507     int y; // note: uninitialized field 'this->b.y'
508     // note: uninitialized field 'this->bptr->y'
509   };
510   int *iptr; // note: uninitialized pointer 'this->iptr'
511   B b;
512   B *bptr;
513   char *cptr; // note: uninitialized pointee 'this->cptr'
514
515   A (B *bptr, char *cptr) : bptr(bptr), cptr(cptr) {}
516 };
517
518 void f() {
519   A::B b;
520   char c;
521   A a(&b, &c); // warning: 6 uninitialized fields
522  //          after the constructor call
523 }
524
525 // With Pedantic set to false and
526 // CheckPointeeInitialization set to true
527 // (every field is uninitialized)
528
529 struct A {
530   struct B {
531     int x;
532     int y;
533   };
534   int *iptr;
535   B b;
536   B *bptr;
537   char *cptr;
538
539   A (B *bptr, char *cptr) : bptr(bptr), cptr(cptr) {}
540 };
541
542 void f() {
543   A::B b;
544   char c;
545   A a(&b, &c); // no warning
546 }
547
548 // With Pedantic set to true and
549 // CheckPointeeInitialization set to false
550 // (pointees are regarded as initialized)
551
552 struct A {
553   struct B {
554     int x; // note: uninitialized field 'this->b.x'
555     int y; // note: uninitialized field 'this->b.y'
556   };
557   int *iptr; // note: uninitialized pointer 'this->iptr'
558   B b;
559   B *bptr;
560   char *cptr;
561
562   A (B *bptr, char *cptr) : bptr(bptr), cptr(cptr) {}
563 };
564
565 void f() {
566   A::B b;
567   char c;
568   A a(&b, &c); // warning: 3 uninitialized fields
569  //          after the constructor call
570 }
571
572
573**Options**
574
575This checker has several options which can be set from command line (e.g.
576``-analyzer-config optin.cplusplus.UninitializedObject:Pedantic=true``):
577
578* ``Pedantic`` (boolean). If to false, the checker won't emit warnings for
579  objects that don't have at least one initialized field. Defaults to false.
580
581* ``NotesAsWarnings``  (boolean). If set to true, the checker will emit a
582  warning for each uninitialized field, as opposed to emitting one warning per
583  constructor call, and listing the uninitialized fields that belongs to it in
584  notes. *Defaults to false*.
585
586* ``CheckPointeeInitialization`` (boolean). If set to false, the checker will
587  not analyze the pointee of pointer/reference fields, and will only check
588  whether the object itself is initialized. *Defaults to false*.
589
590* ``IgnoreRecordsWithField`` (string). If supplied, the checker will not analyze
591  structures that have a field with a name or type name that matches  the given
592  pattern. *Defaults to ""*.
593
594.. _optin-cplusplus-VirtualCall:
595
596optin.cplusplus.VirtualCall (C++)
597"""""""""""""""""""""""""""""""""
598Check virtual function calls during construction or destruction.
599
600.. code-block:: cpp
601
602 class A {
603 public:
604   A() {
605     f(); // warn
606   }
607   virtual void f();
608 };
609
610 class A {
611 public:
612   ~A() {
613     this->f(); // warn
614   }
615   virtual void f();
616 };
617
618.. _optin-mpi-MPI-Checker:
619
620optin.mpi.MPI-Checker (C)
621"""""""""""""""""""""""""
622Checks MPI code.
623
624.. code-block:: c
625
626 void test() {
627   double buf = 0;
628   MPI_Request sendReq1;
629   MPI_Ireduce(MPI_IN_PLACE, &buf, 1, MPI_DOUBLE, MPI_SUM,
630       0, MPI_COMM_WORLD, &sendReq1);
631 } // warn: request 'sendReq1' has no matching wait.
632
633 void test() {
634   double buf = 0;
635   MPI_Request sendReq;
636   MPI_Isend(&buf, 1, MPI_DOUBLE, 0, 0, MPI_COMM_WORLD, &sendReq);
637   MPI_Irecv(&buf, 1, MPI_DOUBLE, 0, 0, MPI_COMM_WORLD, &sendReq); // warn
638   MPI_Isend(&buf, 1, MPI_DOUBLE, 0, 0, MPI_COMM_WORLD, &sendReq); // warn
639   MPI_Wait(&sendReq, MPI_STATUS_IGNORE);
640 }
641
642 void missingNonBlocking() {
643   int rank = 0;
644   MPI_Comm_rank(MPI_COMM_WORLD, &rank);
645   MPI_Request sendReq1[10][10][10];
646   MPI_Wait(&sendReq1[1][7][9], MPI_STATUS_IGNORE); // warn
647 }
648
649.. _optin-osx-cocoa-localizability-EmptyLocalizationContextChecker:
650
651optin.osx.cocoa.localizability.EmptyLocalizationContextChecker (ObjC)
652"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
653Check that NSLocalizedString macros include a comment for context.
654
655.. code-block:: objc
656
657 - (void)test {
658   NSString *string = NSLocalizedString(@"LocalizedString", nil); // warn
659   NSString *string2 = NSLocalizedString(@"LocalizedString", @" "); // warn
660   NSString *string3 = NSLocalizedStringWithDefaultValue(
661     @"LocalizedString", nil, [[NSBundle alloc] init], nil,@""); // warn
662 }
663
664.. _optin-osx-cocoa-localizability-NonLocalizedStringChecker:
665
666optin.osx.cocoa.localizability.NonLocalizedStringChecker (ObjC)
667"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
668Warns about uses of non-localized NSStrings passed to UI methods expecting localized NSStrings.
669
670.. code-block:: objc
671
672 NSString *alarmText =
673   NSLocalizedString(@"Enabled", @"Indicates alarm is turned on");
674 if (!isEnabled) {
675   alarmText = @"Disabled";
676 }
677 UILabel *alarmStateLabel = [[UILabel alloc] init];
678
679 // Warning: User-facing text should use localized string macro
680 [alarmStateLabel setText:alarmText];
681
682.. _optin-performance-GCDAntipattern:
683
684optin.performance.GCDAntipattern
685""""""""""""""""""""""""""""""""
686Check for performance anti-patterns when using Grand Central Dispatch.
687
688.. _optin-performance-Padding:
689
690optin.performance.Padding
691"""""""""""""""""""""""""
692Check for excessively padded structs.
693
694.. _optin-portability-UnixAPI:
695
696optin.portability.UnixAPI
697"""""""""""""""""""""""""
698Finds implementation-defined behavior in UNIX/Posix functions.
699
700
701.. _security-checkers:
702
703security
704^^^^^^^^
705
706Security related checkers.
707
708.. _security-FloatLoopCounter:
709
710security.FloatLoopCounter (C)
711"""""""""""""""""""""""""""""
712Warn on using a floating point value as a loop counter (CERT: FLP30-C, FLP30-CPP).
713
714.. code-block:: c
715
716 void test() {
717   for (float x = 0.1f; x <= 1.0f; x += 0.1f) {} // warn
718 }
719
720.. _security-insecureAPI-UncheckedReturn:
721
722security.insecureAPI.UncheckedReturn (C)
723""""""""""""""""""""""""""""""""""""""""
724Warn on uses of functions whose return values must be always checked.
725
726.. code-block:: c
727
728 void test() {
729   setuid(1); // warn
730 }
731
732.. _security-insecureAPI-bcmp:
733
734security.insecureAPI.bcmp (C)
735"""""""""""""""""""""""""""""
736Warn on uses of the 'bcmp' function.
737
738.. code-block:: c
739
740 void test() {
741   bcmp(ptr0, ptr1, n); // warn
742 }
743
744.. _security-insecureAPI-bcopy:
745
746security.insecureAPI.bcopy (C)
747""""""""""""""""""""""""""""""
748Warn on uses of the 'bcopy' function.
749
750.. code-block:: c
751
752 void test() {
753   bcopy(src, dst, n); // warn
754 }
755
756.. _security-insecureAPI-bzero:
757
758security.insecureAPI.bzero (C)
759""""""""""""""""""""""""""""""
760Warn on uses of the 'bzero' function.
761
762.. code-block:: c
763
764 void test() {
765   bzero(ptr, n); // warn
766 }
767
768.. _security-insecureAPI-getpw:
769
770security.insecureAPI.getpw (C)
771""""""""""""""""""""""""""""""
772Warn on uses of the 'getpw' function.
773
774.. code-block:: c
775
776 void test() {
777   char buff[1024];
778   getpw(2, buff); // warn
779 }
780
781.. _security-insecureAPI-gets:
782
783security.insecureAPI.gets (C)
784"""""""""""""""""""""""""""""
785Warn on uses of the 'gets' function.
786
787.. code-block:: c
788
789 void test() {
790   char buff[1024];
791   gets(buff); // warn
792 }
793
794.. _security-insecureAPI-mkstemp:
795
796security.insecureAPI.mkstemp (C)
797""""""""""""""""""""""""""""""""
798Warn when 'mkstemp' is passed fewer than 6 X's in the format string.
799
800.. code-block:: c
801
802 void test() {
803   mkstemp("XX"); // warn
804 }
805
806.. _security-insecureAPI-mktemp:
807
808security.insecureAPI.mktemp (C)
809"""""""""""""""""""""""""""""""
810Warn on uses of the ``mktemp`` function.
811
812.. code-block:: c
813
814 void test() {
815   char *x = mktemp("/tmp/zxcv"); // warn: insecure, use mkstemp
816 }
817
818.. _security-insecureAPI-rand:
819
820security.insecureAPI.rand (C)
821"""""""""""""""""""""""""""""
822Warn on uses of inferior random number generating functions (only if arc4random function is available):
823``drand48, erand48, jrand48, lcong48, lrand48, mrand48, nrand48, random, rand_r``.
824
825.. code-block:: c
826
827 void test() {
828   random(); // warn
829 }
830
831.. _security-insecureAPI-strcpy:
832
833security.insecureAPI.strcpy (C)
834"""""""""""""""""""""""""""""""
835Warn on uses of the ``strcpy`` and ``strcat`` functions.
836
837.. code-block:: c
838
839 void test() {
840   char x[4];
841   char *y = "abcd";
842
843   strcpy(x, y); // warn
844 }
845
846
847.. _security-insecureAPI-vfork:
848
849security.insecureAPI.vfork (C)
850""""""""""""""""""""""""""""""
851 Warn on uses of the 'vfork' function.
852
853.. code-block:: c
854
855 void test() {
856   vfork(); // warn
857 }
858
859.. _security-insecureAPI-DeprecatedOrUnsafeBufferHandling:
860
861security.insecureAPI.DeprecatedOrUnsafeBufferHandling (C)
862"""""""""""""""""""""""""""""""""""""""""""""""""""""""""
863 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``
864
865.. code-block:: c
866
867 void test() {
868   char buf [5];
869   strncpy(buf, "a", 1); // warn
870 }
871
872.. _unix-checkers:
873
874unix
875^^^^
876POSIX/Unix checkers.
877
878.. _unix-API:
879
880unix.API (C)
881""""""""""""
882Check calls to various UNIX/Posix functions: ``open, pthread_once, calloc, malloc, realloc, alloca``.
883
884.. literalinclude:: checkers/unix_api_example.c
885    :language: c
886
887.. _unix-Malloc:
888
889unix.Malloc (C)
890"""""""""""""""
891Check for memory leaks, double free, and use-after-free problems. Traces memory managed by malloc()/free().
892
893.. literalinclude:: checkers/unix_malloc_example.c
894    :language: c
895
896.. _unix-MallocSizeof:
897
898unix.MallocSizeof (C)
899"""""""""""""""""""""
900Check for dubious ``malloc`` arguments involving ``sizeof``.
901
902.. code-block:: c
903
904 void test() {
905   long *p = malloc(sizeof(short));
906     // warn: result is converted to 'long *', which is
907     // incompatible with operand type 'short'
908   free(p);
909 }
910
911.. _unix-MismatchedDeallocator:
912
913unix.MismatchedDeallocator (C, C++)
914"""""""""""""""""""""""""""""""""""
915Check for mismatched deallocators.
916
917.. literalinclude:: checkers/mismatched_deallocator_example.cpp
918    :language: c
919
920.. _unix-Vfork:
921
922unix.Vfork (C)
923""""""""""""""
924Check for proper usage of ``vfork``.
925
926.. code-block:: c
927
928 int test(int x) {
929   pid_t pid = vfork(); // warn
930   if (pid != 0)
931     return 0;
932
933   switch (x) {
934   case 0:
935     pid = 1;
936     execl("", "", 0);
937     _exit(1);
938     break;
939   case 1:
940     x = 0; // warn: this assignment is prohibited
941     break;
942   case 2:
943     foo(); // warn: this function call is prohibited
944     break;
945   default:
946     return 0; // warn: return is prohibited
947   }
948
949   while(1);
950 }
951
952.. _unix-cstring-BadSizeArg:
953
954unix.cstring.BadSizeArg (C)
955"""""""""""""""""""""""""""
956Check 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.
957
958.. code-block:: c
959
960 void test() {
961   char dest[3];
962   strncat(dest, """""""""""""""""""""""""*", sizeof(dest));
963     // warn: potential buffer overflow
964 }
965
966.. _unix-cstring-NullArg:
967
968unix.cstring.NullArg (C)
969"""""""""""""""""""""""""
970Check for null pointers being passed as arguments to C string functions:
971``strlen, strnlen, strcpy, strncpy, strcat, strncat, strcmp, strncmp, strcasecmp, strncasecmp, wcslen, wcsnlen``.
972
973.. code-block:: c
974
975 int test() {
976   return strlen(0); // warn
977 }
978
979.. _osx-checkers:
980
981osx
982^^^
983macOS checkers.
984
985.. _osx-API:
986
987osx.API (C)
988"""""""""""
989Check for proper uses of various Apple APIs.
990
991.. code-block:: objc
992
993 void test() {
994   dispatch_once_t pred = 0;
995   dispatch_once(&pred, ^(){}); // warn: dispatch_once uses local
996 }
997
998.. _osx-NumberObjectConversion:
999
1000osx.NumberObjectConversion (C, C++, ObjC)
1001"""""""""""""""""""""""""""""""""""""""""
1002Check for erroneous conversions of objects representing numbers into numbers.
1003
1004.. code-block:: objc
1005
1006 NSNumber *photoCount = [albumDescriptor objectForKey:@"PhotoCount"];
1007 // Warning: Comparing a pointer value of type 'NSNumber *'
1008 // to a scalar integer value
1009 if (photoCount > 0) {
1010   [self displayPhotos];
1011 }
1012
1013.. _osx-ObjCProperty:
1014
1015osx.ObjCProperty (ObjC)
1016"""""""""""""""""""""""
1017Check for proper uses of Objective-C properties.
1018
1019.. code-block:: objc
1020
1021 NSNumber *photoCount = [albumDescriptor objectForKey:@"PhotoCount"];
1022 // Warning: Comparing a pointer value of type 'NSNumber *'
1023 // to a scalar integer value
1024 if (photoCount > 0) {
1025   [self displayPhotos];
1026 }
1027
1028
1029.. _osx-SecKeychainAPI:
1030
1031osx.SecKeychainAPI (C)
1032""""""""""""""""""""""
1033Check for proper uses of Secure Keychain APIs.
1034
1035.. literalinclude:: checkers/seckeychainapi_example.m
1036    :language: objc
1037
1038.. _osx-cocoa-AtSync:
1039
1040osx.cocoa.AtSync (ObjC)
1041"""""""""""""""""""""""
1042Check for nil pointers used as mutexes for @synchronized.
1043
1044.. code-block:: objc
1045
1046 void test(id x) {
1047   if (!x)
1048     @synchronized(x) {} // warn: nil value used as mutex
1049 }
1050
1051 void test() {
1052   id y;
1053   @synchronized(y) {} // warn: uninitialized value used as mutex
1054 }
1055
1056.. _osx-cocoa-AutoreleaseWrite:
1057
1058osx.cocoa.AutoreleaseWrite
1059""""""""""""""""""""""""""
1060Warn about potentially crashing writes to autoreleasing objects from different autoreleasing pools in Objective-C.
1061
1062.. _osx-cocoa-ClassRelease:
1063
1064osx.cocoa.ClassRelease (ObjC)
1065"""""""""""""""""""""""""""""
1066Check for sending 'retain', 'release', or 'autorelease' directly to a Class.
1067
1068.. code-block:: objc
1069
1070 @interface MyClass : NSObject
1071 @end
1072
1073 void test(void) {
1074   [MyClass release]; // warn
1075 }
1076
1077.. _osx-cocoa-Dealloc:
1078
1079osx.cocoa.Dealloc (ObjC)
1080""""""""""""""""""""""""
1081Warn about Objective-C classes that lack a correct implementation of -dealloc
1082
1083.. literalinclude:: checkers/dealloc_example.m
1084    :language: objc
1085
1086.. _osx-cocoa-IncompatibleMethodTypes:
1087
1088osx.cocoa.IncompatibleMethodTypes (ObjC)
1089""""""""""""""""""""""""""""""""""""""""
1090Warn about Objective-C method signatures with type incompatibilities.
1091
1092.. code-block:: objc
1093
1094 @interface MyClass1 : NSObject
1095 - (int)foo;
1096 @end
1097
1098 @implementation MyClass1
1099 - (int)foo { return 1; }
1100 @end
1101
1102 @interface MyClass2 : MyClass1
1103 - (float)foo;
1104 @end
1105
1106 @implementation MyClass2
1107 - (float)foo { return 1.0; } // warn
1108 @end
1109
1110.. _osx-cocoa-Loops:
1111
1112osx.cocoa.Loops
1113"""""""""""""""
1114Improved modeling of loops using Cocoa collection types.
1115
1116.. _osx-cocoa-MissingSuperCall:
1117
1118osx.cocoa.MissingSuperCall (ObjC)
1119"""""""""""""""""""""""""""""""""
1120Warn about Objective-C methods that lack a necessary call to super.
1121
1122.. code-block:: objc
1123
1124 @interface Test : UIViewController
1125 @end
1126 @implementation test
1127 - (void)viewDidLoad {} // warn
1128 @end
1129
1130
1131.. _osx-cocoa-NSAutoreleasePool:
1132
1133osx.cocoa.NSAutoreleasePool (ObjC)
1134""""""""""""""""""""""""""""""""""
1135Warn for suboptimal uses of NSAutoreleasePool in Objective-C GC mode.
1136
1137.. code-block:: objc
1138
1139 void test() {
1140   NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
1141   [pool release]; // warn
1142 }
1143
1144.. _osx-cocoa-NSError:
1145
1146osx.cocoa.NSError (ObjC)
1147""""""""""""""""""""""""
1148Check usage of NSError parameters.
1149
1150.. code-block:: objc
1151
1152 @interface A : NSObject
1153 - (void)foo:(NSError """""""""""""""""""""""")error;
1154 @end
1155
1156 @implementation A
1157 - (void)foo:(NSError """""""""""""""""""""""")error {
1158   // warn: method accepting NSError"""""""""""""""""""""""" should have a non-void
1159   // return value
1160 }
1161 @end
1162
1163 @interface A : NSObject
1164 - (BOOL)foo:(NSError """""""""""""""""""""""")error;
1165 @end
1166
1167 @implementation A
1168 - (BOOL)foo:(NSError """""""""""""""""""""""")error {
1169   *error = 0; // warn: potential null dereference
1170   return 0;
1171 }
1172 @end
1173
1174.. _osx-cocoa-NilArg:
1175
1176osx.cocoa.NilArg (ObjC)
1177"""""""""""""""""""""""
1178Check for prohibited nil arguments to ObjC method calls.
1179
1180 - caseInsensitiveCompare:
1181 - compare:
1182 - compare:options:
1183 - compare:options:range:
1184 - compare:options:range:locale:
1185 - componentsSeparatedByCharactersInSet:
1186 - initWithFormat:
1187
1188.. code-block:: objc
1189
1190 NSComparisonResult test(NSString *s) {
1191   NSString *aString = nil;
1192   return [s caseInsensitiveCompare:aString];
1193     // warn: argument to 'NSString' method
1194     // 'caseInsensitiveCompare:' cannot be nil
1195 }
1196
1197
1198.. _osx-cocoa-NonNilReturnValue:
1199
1200osx.cocoa.NonNilReturnValue
1201"""""""""""""""""""""""""""
1202Models the APIs that are guaranteed to return a non-nil value.
1203
1204.. _osx-cocoa-ObjCGenerics:
1205
1206osx.cocoa.ObjCGenerics (ObjC)
1207"""""""""""""""""""""""""""""
1208Check for type errors when using Objective-C generics.
1209
1210.. code-block:: objc
1211
1212 NSMutableArray *names = [NSMutableArray array];
1213 NSMutableArray *birthDates = names;
1214
1215 // Warning: Conversion from value of type 'NSDate *'
1216 // to incompatible type 'NSString *'
1217 [birthDates addObject: [NSDate date]];
1218
1219.. _osx-cocoa-RetainCount:
1220
1221osx.cocoa.RetainCount (ObjC)
1222""""""""""""""""""""""""""""
1223Check for leaks and improper reference count management
1224
1225.. code-block:: objc
1226
1227 void test() {
1228   NSString *s = [[NSString alloc] init]; // warn
1229 }
1230
1231 CFStringRef test(char *bytes) {
1232   return CFStringCreateWithCStringNoCopy(
1233            0, bytes, NSNEXTSTEPStringEncoding, 0); // warn
1234 }
1235
1236
1237.. _osx-cocoa-RunLoopAutoreleaseLeak:
1238
1239osx.cocoa.RunLoopAutoreleaseLeak
1240""""""""""""""""""""""""""""""""
1241Check for leaked memory in autorelease pools that will never be drained.
1242
1243.. _osx-cocoa-SelfInit:
1244
1245osx.cocoa.SelfInit (ObjC)
1246"""""""""""""""""""""""""
1247Check that 'self' is properly initialized inside an initializer method.
1248
1249.. code-block:: objc
1250
1251 @interface MyObj : NSObject {
1252   id x;
1253 }
1254 - (id)init;
1255 @end
1256
1257 @implementation MyObj
1258 - (id)init {
1259   [super init];
1260   x = 0; // warn: instance variable used while 'self' is not
1261          // initialized
1262   return 0;
1263 }
1264 @end
1265
1266 @interface MyObj : NSObject
1267 - (id)init;
1268 @end
1269
1270 @implementation MyObj
1271 - (id)init {
1272   [super init];
1273   return self; // warn: returning uninitialized 'self'
1274 }
1275 @end
1276
1277.. _osx-cocoa-SuperDealloc:
1278
1279osx.cocoa.SuperDealloc (ObjC)
1280"""""""""""""""""""""""""""""
1281Warn about improper use of '[super dealloc]' in Objective-C.
1282
1283.. code-block:: objc
1284
1285 @interface SuperDeallocThenReleaseIvarClass : NSObject {
1286   NSObject *_ivar;
1287 }
1288 @end
1289
1290 @implementation SuperDeallocThenReleaseIvarClass
1291 - (void)dealloc {
1292   [super dealloc];
1293   [_ivar release]; // warn
1294 }
1295 @end
1296
1297.. _osx-cocoa-UnusedIvars:
1298
1299osx.cocoa.UnusedIvars (ObjC)
1300""""""""""""""""""""""""""""
1301Warn about private ivars that are never used.
1302
1303.. code-block:: objc
1304
1305 @interface MyObj : NSObject {
1306 @private
1307   id x; // warn
1308 }
1309 @end
1310
1311 @implementation MyObj
1312 @end
1313
1314.. _osx-cocoa-VariadicMethodTypes:
1315
1316osx.cocoa.VariadicMethodTypes (ObjC)
1317""""""""""""""""""""""""""""""""""""
1318Check for passing non-Objective-C types to variadic collection
1319initialization methods that expect only Objective-C types.
1320
1321.. code-block:: objc
1322
1323 void test() {
1324   [NSSet setWithObjects:@"Foo", "Bar", nil];
1325     // warn: argument should be an ObjC pointer type, not 'char *'
1326 }
1327
1328.. _osx-coreFoundation-CFError:
1329
1330osx.coreFoundation.CFError (C)
1331""""""""""""""""""""""""""""""
1332Check usage of CFErrorRef* parameters
1333
1334.. code-block:: c
1335
1336 void test(CFErrorRef *error) {
1337   // warn: function accepting CFErrorRef* should have a
1338   // non-void return
1339 }
1340
1341 int foo(CFErrorRef *error) {
1342   *error = 0; // warn: potential null dereference
1343   return 0;
1344 }
1345
1346.. _osx-coreFoundation-CFNumber:
1347
1348osx.coreFoundation.CFNumber (C)
1349"""""""""""""""""""""""""""""""
1350Check for proper uses of CFNumber APIs.
1351
1352.. code-block:: c
1353
1354 CFNumberRef test(unsigned char x) {
1355   return CFNumberCreate(0, kCFNumberSInt16Type, &x);
1356    // warn: 8 bit integer is used to initialize a 16 bit integer
1357 }
1358
1359.. _osx-coreFoundation-CFRetainRelease:
1360
1361osx.coreFoundation.CFRetainRelease (C)
1362""""""""""""""""""""""""""""""""""""""
1363Check for null arguments to CFRetain/CFRelease/CFMakeCollectable.
1364
1365.. code-block:: c
1366
1367 void test(CFTypeRef p) {
1368   if (!p)
1369     CFRetain(p); // warn
1370 }
1371
1372 void test(int x, CFTypeRef p) {
1373   if (p)
1374     return;
1375
1376   CFRelease(p); // warn
1377 }
1378
1379.. _osx-coreFoundation-containers-OutOfBounds:
1380
1381osx.coreFoundation.containers.OutOfBounds (C)
1382"""""""""""""""""""""""""""""""""""""""""""""
1383Checks for index out-of-bounds when using 'CFArray' API.
1384
1385.. code-block:: c
1386
1387 void test() {
1388   CFArrayRef A = CFArrayCreate(0, 0, 0, &kCFTypeArrayCallBacks);
1389   CFArrayGetValueAtIndex(A, 0); // warn
1390 }
1391
1392.. _osx-coreFoundation-containers-PointerSizedValues:
1393
1394osx.coreFoundation.containers.PointerSizedValues (C)
1395""""""""""""""""""""""""""""""""""""""""""""""""""""
1396Warns if 'CFArray', 'CFDictionary', 'CFSet' are created with non-pointer-size values.
1397
1398.. code-block:: c
1399
1400 void test() {
1401   int x[] = { 1 };
1402   CFArrayRef A = CFArrayCreate(0, (const void """""""""""""""""""""""")x, 1,
1403                                &kCFTypeArrayCallBacks); // warn
1404 }
1405
1406Fuchsia
1407^^^^^^^
1408
1409Fuchsia is an open source capability-based operating system currently being
1410developed by Google. This section describes checkers that can find various
1411misuses of Fuchsia APIs.
1412
1413.. _fuchsia-HandleChecker:
1414
1415fuchsia.HandleChecker
1416""""""""""""""""""""""""""""
1417Handles identify resources. Similar to pointers they can be leaked,
1418double freed, or use after freed. This check attempts to find such problems.
1419
1420.. code-block:: cpp
1421
1422 void checkLeak08(int tag) {
1423   zx_handle_t sa, sb;
1424   zx_channel_create(0, &sa, &sb);
1425   if (tag)
1426     zx_handle_close(sa);
1427   use(sb); // Warn: Potential leak of handle
1428   zx_handle_close(sb);
1429 }
1430
1431WebKit
1432^^^^^^
1433
1434WebKit is an open-source web browser engine available for macOS, iOS and Linux.
1435This section describes checkers that can find issues in WebKit codebase.
1436
1437Most of the checkers focus on memory management for which WebKit uses custom implementation of reference counted smartpointers.
1438
1439Checkers are formulated in terms related to ref-counting:
1440 - *Ref-counted type* is either ``Ref<T>`` or ``RefPtr<T>``.
1441 - *Ref-countable type* is any type that implements ``ref()`` and ``deref()`` methods as ``RefPtr<>`` is a template (i. e. relies on duck typing).
1442 - *Uncounted type* is ref-countable but not ref-counted type.
1443
1444.. _webkit-RefCntblBaseVirtualDtor:
1445
1446webkit.RefCntblBaseVirtualDtor
1447""""""""""""""""""""""""""""""""""""
1448All uncounted types used as base classes must have a virtual destructor.
1449
1450Ref-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]``.
1451
1452.. code-block:: cpp
1453
1454 struct RefCntblBase {
1455   void ref() {}
1456   void deref() {}
1457 };
1458
1459 struct Derived : RefCntblBase { }; // warn
1460
1461.. _webkit-NoUncountedMemberChecker:
1462
1463webkit.NoUncountedMemberChecker
1464"""""""""""""""""""""""""""""""""""""
1465Raw pointers and references to uncounted types can't be used as class members. Only ref-counted types are allowed.
1466
1467.. code-block:: cpp
1468
1469 struct RefCntbl {
1470   void ref() {}
1471   void deref() {}
1472 };
1473
1474 struct Foo {
1475   RefCntbl * ptr; // warn
1476   RefCntbl & ptr; // warn
1477   // ...
1478 };
1479
1480.. _webkit-UncountedLambdaCapturesChecker:
1481
1482webkit.UncountedLambdaCapturesChecker
1483"""""""""""""""""""""""""""""""""""""
1484Raw pointers and references to uncounted types can't be captured in lambdas. Only ref-counted types are allowed.
1485
1486.. code-block:: cpp
1487
1488 struct RefCntbl {
1489   void ref() {}
1490   void deref() {}
1491 };
1492
1493 void foo(RefCntbl* a, RefCntbl& b) {
1494   [&, a](){ // warn about 'a'
1495     do_something(b); // warn about 'b'
1496   };
1497 };
1498
1499.. _alpha-checkers:
1500
1501Experimental Checkers
1502---------------------
1503
1504*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.*
1505
1506alpha.clone
1507^^^^^^^^^^^
1508
1509.. _alpha-clone-CloneChecker:
1510
1511alpha.clone.CloneChecker (C, C++, ObjC)
1512"""""""""""""""""""""""""""""""""""""""
1513Reports similar pieces of code.
1514
1515.. code-block:: c
1516
1517 void log();
1518
1519 int max(int a, int b) { // warn
1520   log();
1521   if (a > b)
1522     return a;
1523   return b;
1524 }
1525
1526 int maxClone(int x, int y) { // similar code here
1527   log();
1528   if (x > y)
1529     return x;
1530   return y;
1531 }
1532
1533alpha.core
1534^^^^^^^^^^
1535
1536.. _alpha-core-BoolAssignment:
1537
1538alpha.core.BoolAssignment (ObjC)
1539""""""""""""""""""""""""""""""""
1540Warn about assigning non-{0,1} values to boolean variables.
1541
1542.. code-block:: objc
1543
1544 void test() {
1545   BOOL b = -1; // warn
1546 }
1547
1548.. _alpha-core-C11Lock:
1549
1550alpha.core.C11Lock
1551""""""""""""""""""
1552Similarly to :ref:`alpha.unix.PthreadLock <alpha-unix-PthreadLock>`, checks for
1553the locking/unlocking of ``mtx_t`` mutexes.
1554
1555.. code-block:: cpp
1556
1557 mtx_t mtx1;
1558
1559 void bad1(void)
1560 {
1561   mtx_lock(&mtx1);
1562   mtx_lock(&mtx1); // warn: This lock has already been acquired
1563 }
1564
1565.. _alpha-core-CallAndMessageUnInitRefArg:
1566
1567alpha.core.CallAndMessageUnInitRefArg (C,C++, ObjC)
1568"""""""""""""""""""""""""""""""""""""""""""""""""""
1569Check for logical errors for function calls and Objective-C
1570message expressions (e.g., uninitialized arguments, null function pointers, and pointer to undefined variables).
1571
1572.. code-block:: c
1573
1574 void test(void) {
1575   int t;
1576   int &p = t;
1577   int &s = p;
1578   int &q = s;
1579   foo(q); // warn
1580 }
1581
1582 void test(void) {
1583   int x;
1584   foo(&x); // warn
1585 }
1586
1587.. _alpha-core-CastSize:
1588
1589alpha.core.CastSize (C)
1590"""""""""""""""""""""""
1591Check when casting a malloc'ed type ``T``, whether the size is a multiple of the size of ``T``.
1592
1593.. code-block:: c
1594
1595 void test() {
1596   int *x = (int *) malloc(11); // warn
1597 }
1598
1599.. _alpha-core-CastToStruct:
1600
1601alpha.core.CastToStruct (C, C++)
1602""""""""""""""""""""""""""""""""
1603Check for cast from non-struct pointer to struct pointer.
1604
1605.. code-block:: cpp
1606
1607 // C
1608 struct s {};
1609
1610 void test(int *p) {
1611   struct s *ps = (struct s *) p; // warn
1612 }
1613
1614 // C++
1615 class c {};
1616
1617 void test(int *p) {
1618   c *pc = (c *) p; // warn
1619 }
1620
1621.. _alpha-core-Conversion:
1622
1623alpha.core.Conversion (C, C++, ObjC)
1624""""""""""""""""""""""""""""""""""""
1625Loss of sign/precision in implicit conversions.
1626
1627.. code-block:: c
1628
1629 void test(unsigned U, signed S) {
1630   if (S > 10) {
1631     if (U < S) {
1632     }
1633   }
1634   if (S < -10) {
1635     if (U < S) { // warn (loss of sign)
1636     }
1637   }
1638 }
1639
1640 void test() {
1641   long long A = 1LL << 60;
1642   short X = A; // warn (loss of precision)
1643 }
1644
1645.. _alpha-core-DynamicTypeChecker:
1646
1647alpha.core.DynamicTypeChecker (ObjC)
1648""""""""""""""""""""""""""""""""""""
1649Check for cases where the dynamic and the static type of an object are unrelated.
1650
1651
1652.. code-block:: objc
1653
1654 id date = [NSDate date];
1655
1656 // Warning: Object has a dynamic type 'NSDate *' which is
1657 // incompatible with static type 'NSNumber *'"
1658 NSNumber *number = date;
1659 [number doubleValue];
1660
1661.. _alpha-core-FixedAddr:
1662
1663alpha.core.FixedAddr (C)
1664""""""""""""""""""""""""
1665Check for assignment of a fixed address to a pointer.
1666
1667.. code-block:: c
1668
1669 void test() {
1670   int *p;
1671   p = (int *) 0x10000; // warn
1672 }
1673
1674.. _alpha-core-IdenticalExpr:
1675
1676alpha.core.IdenticalExpr (C, C++)
1677"""""""""""""""""""""""""""""""""
1678Warn about unintended use of identical expressions in operators.
1679
1680.. code-block:: cpp
1681
1682 // C
1683 void test() {
1684   int a = 5;
1685   int b = a | 4 | a; // warn: identical expr on both sides
1686 }
1687
1688 // C++
1689 bool f(void);
1690
1691 void test(bool b) {
1692   int i = 10;
1693   if (f()) { // warn: true and false branches are identical
1694     do {
1695       i--;
1696     } while (f());
1697   } else {
1698     do {
1699       i--;
1700     } while (f());
1701   }
1702 }
1703
1704.. _alpha-core-PointerArithm:
1705
1706alpha.core.PointerArithm (C)
1707""""""""""""""""""""""""""""
1708Check for pointer arithmetic on locations other than array elements.
1709
1710.. code-block:: c
1711
1712 void test() {
1713   int x;
1714   int *p;
1715   p = &x + 1; // warn
1716 }
1717
1718.. _alpha-core-PointerSub:
1719
1720alpha.core.PointerSub (C)
1721"""""""""""""""""""""""""
1722Check for pointer subtractions on two pointers pointing to different memory chunks.
1723
1724.. code-block:: c
1725
1726 void test() {
1727   int x, y;
1728   int d = &y - &x; // warn
1729 }
1730
1731.. _alpha-core-SizeofPtr:
1732
1733alpha.core.SizeofPtr (C)
1734""""""""""""""""""""""""
1735Warn about unintended use of ``sizeof()`` on pointer expressions.
1736
1737.. code-block:: c
1738
1739 struct s {};
1740
1741 int test(struct s *p) {
1742   return sizeof(p);
1743     // warn: sizeof(ptr) can produce an unexpected result
1744 }
1745
1746.. _alpha-core-StackAddressAsyncEscape:
1747
1748alpha.core.StackAddressAsyncEscape (C)
1749""""""""""""""""""""""""""""""""""""""
1750Check that addresses to stack memory do not escape the function that involves dispatch_after or dispatch_async.
1751This checker is a part of ``core.StackAddressEscape``, but is temporarily disabled until some false positives are fixed.
1752
1753.. code-block:: c
1754
1755 dispatch_block_t test_block_inside_block_async_leak() {
1756   int x = 123;
1757   void (^inner)(void) = ^void(void) {
1758     int y = x;
1759     ++y;
1760   };
1761   void (^outer)(void) = ^void(void) {
1762     int z = x;
1763     ++z;
1764     inner();
1765   };
1766   return outer; // warn: address of stack-allocated block is captured by a
1767                 //       returned block
1768 }
1769
1770.. _alpha-core-TestAfterDivZero:
1771
1772alpha.core.TestAfterDivZero (C)
1773"""""""""""""""""""""""""""""""
1774Check for division by variable that is later compared against 0.
1775Either the comparison is useless or there is division by zero.
1776
1777.. code-block:: c
1778
1779 void test(int x) {
1780   var = 77 / x;
1781   if (x == 0) { } // warn
1782 }
1783
1784alpha.cplusplus
1785^^^^^^^^^^^^^^^
1786
1787.. _alpha-cplusplus-DeleteWithNonVirtualDtor:
1788
1789alpha.cplusplus.DeleteWithNonVirtualDtor (C++)
1790""""""""""""""""""""""""""""""""""""""""""""""
1791Reports destructions of polymorphic objects with a non-virtual destructor in their base class.
1792
1793.. code-block:: cpp
1794
1795 NonVirtual *create() {
1796   NonVirtual *x = new NVDerived(); // note: conversion from derived to base
1797                                    //       happened here
1798   return x;
1799 }
1800
1801 void sink(NonVirtual *x) {
1802   delete x; // warn: destruction of a polymorphic object with no virtual
1803             //       destructor
1804 }
1805
1806.. _alpha-cplusplus-EnumCastOutOfRange:
1807
1808alpha.cplusplus.EnumCastOutOfRange (C++)
1809""""""""""""""""""""""""""""""""""""""""
1810Check for integer to enumeration casts that could result in undefined values.
1811
1812.. code-block:: cpp
1813
1814 enum TestEnum {
1815   A = 0
1816 };
1817
1818 void foo() {
1819   TestEnum t = static_cast(-1);
1820       // warn: the value provided to the cast expression is not in
1821       //       the valid range of values for the enum
1822
1823.. _alpha-cplusplus-InvalidatedIterator:
1824
1825alpha.cplusplus.InvalidatedIterator (C++)
1826"""""""""""""""""""""""""""""""""""""""""
1827Check for use of invalidated iterators.
1828
1829.. code-block:: cpp
1830
1831 void bad_copy_assign_operator_list1(std::list &L1,
1832                                     const std::list &L2) {
1833   auto i0 = L1.cbegin();
1834   L1 = L2;
1835   *i0; // warn: invalidated iterator accessed
1836 }
1837
1838
1839.. _alpha-cplusplus-IteratorRange:
1840
1841alpha.cplusplus.IteratorRange (C++)
1842"""""""""""""""""""""""""""""""""""
1843Check for iterators used outside their valid ranges.
1844
1845.. code-block:: cpp
1846
1847 void simple_bad_end(const std::vector &v) {
1848   auto i = v.end();
1849   *i; // warn: iterator accessed outside of its range
1850 }
1851
1852.. _alpha-cplusplus-MismatchedIterator:
1853
1854alpha.cplusplus.MismatchedIterator (C++)
1855""""""""""""""""""""""""""""""""""""""""
1856Check for use of iterators of different containers where iterators of the same container are expected.
1857
1858.. code-block:: cpp
1859
1860 void bad_insert3(std::vector &v1, std::vector &v2) {
1861   v2.insert(v1.cbegin(), v2.cbegin(), v2.cend()); // warn: container accessed
1862                                                   //       using foreign
1863                                                   //       iterator argument
1864   v1.insert(v1.cbegin(), v1.cbegin(), v2.cend()); // warn: iterators of
1865                                                   //       different containers
1866                                                   //       used where the same
1867                                                   //       container is
1868                                                   //       expected
1869   v1.insert(v1.cbegin(), v2.cbegin(), v1.cend()); // warn: iterators of
1870                                                   //       different containers
1871                                                   //       used where the same
1872                                                   //       container is
1873                                                   //       expected
1874 }
1875
1876.. _alpha-cplusplus-MisusedMovedObject:
1877
1878alpha.cplusplus.MisusedMovedObject (C++)
1879""""""""""""""""""""""""""""""""""""""""
1880Method calls on a moved-from object and copying a moved-from object will be reported.
1881
1882
1883.. code-block:: cpp
1884
1885  struct A {
1886   void foo() {}
1887 };
1888
1889 void f() {
1890   A a;
1891   A b = std::move(a); // note: 'a' became 'moved-from' here
1892   a.foo();            // warn: method call on a 'moved-from' object 'a'
1893 }
1894
1895.. _alpha-cplusplus-SmartPtr:
1896
1897alpha.cplusplus.SmartPtr (C++)
1898""""""""""""""""""""""""""""""
1899Check for dereference of null smart pointers.
1900
1901.. code-block:: cpp
1902
1903 void deref_smart_ptr() {
1904   std::unique_ptr<int> P;
1905   *P; // warn: dereference of a default constructed smart unique_ptr
1906 }
1907
1908
1909alpha.deadcode
1910^^^^^^^^^^^^^^
1911.. _alpha-deadcode-UnreachableCode:
1912
1913alpha.deadcode.UnreachableCode (C, C++)
1914"""""""""""""""""""""""""""""""""""""""
1915Check unreachable code.
1916
1917.. code-block:: cpp
1918
1919 // C
1920 int test() {
1921   int x = 1;
1922   while(x);
1923   return x; // warn
1924 }
1925
1926 // C++
1927 void test() {
1928   int a = 2;
1929
1930   while (a > 1)
1931     a--;
1932
1933   if (a > 1)
1934     a++; // warn
1935 }
1936
1937 // Objective-C
1938 void test(id x) {
1939   return;
1940   [x retain]; // warn
1941 }
1942
1943alpha.fuchsia
1944^^^^^^^^^^^^^
1945
1946.. _alpha-fuchsia-lock:
1947
1948alpha.fuchsia.Lock
1949""""""""""""""""""
1950Similarly to :ref:`alpha.unix.PthreadLock <alpha-unix-PthreadLock>`, checks for
1951the locking/unlocking of fuchsia mutexes.
1952
1953.. code-block:: cpp
1954
1955 spin_lock_t mtx1;
1956
1957 void bad1(void)
1958 {
1959   spin_lock(&mtx1);
1960   spin_lock(&mtx1);	// warn: This lock has already been acquired
1961 }
1962
1963alpha.llvm
1964^^^^^^^^^^
1965
1966.. _alpha-llvm-Conventions:
1967
1968alpha.llvm.Conventions
1969""""""""""""""""""""""
1970
1971Check code for LLVM codebase conventions:
1972
1973* A StringRef should not be bound to a temporary std::string whose lifetime is shorter than the StringRef's.
1974* Clang AST nodes should not have fields that can allocate memory.
1975
1976
1977alpha.osx
1978^^^^^^^^^
1979
1980.. _alpha-osx-cocoa-DirectIvarAssignment:
1981
1982alpha.osx.cocoa.DirectIvarAssignment (ObjC)
1983"""""""""""""""""""""""""""""""""""""""""""
1984Check for direct assignments to instance variables.
1985
1986
1987.. code-block:: objc
1988
1989 @interface MyClass : NSObject {}
1990 @property (readonly) id A;
1991 - (void) foo;
1992 @end
1993
1994 @implementation MyClass
1995 - (void) foo {
1996   _A = 0; // warn
1997 }
1998 @end
1999
2000.. _alpha-osx-cocoa-DirectIvarAssignmentForAnnotatedFunctions:
2001
2002alpha.osx.cocoa.DirectIvarAssignmentForAnnotatedFunctions (ObjC)
2003""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
2004Check for direct assignments to instance variables in
2005the methods annotated with ``objc_no_direct_instance_variable_assignment``.
2006
2007.. code-block:: objc
2008
2009 @interface MyClass : NSObject {}
2010 @property (readonly) id A;
2011 - (void) fAnnotated __attribute__((
2012     annotate("objc_no_direct_instance_variable_assignment")));
2013 - (void) fNotAnnotated;
2014 @end
2015
2016 @implementation MyClass
2017 - (void) fAnnotated {
2018   _A = 0; // warn
2019 }
2020 - (void) fNotAnnotated {
2021   _A = 0; // no warn
2022 }
2023 @end
2024
2025
2026.. _alpha-osx-cocoa-InstanceVariableInvalidation:
2027
2028alpha.osx.cocoa.InstanceVariableInvalidation (ObjC)
2029"""""""""""""""""""""""""""""""""""""""""""""""""""
2030Check that the invalidatable instance variables are
2031invalidated in the methods annotated with objc_instance_variable_invalidator.
2032
2033.. code-block:: objc
2034
2035 @protocol Invalidation <NSObject>
2036 - (void) invalidate
2037   __attribute__((annotate("objc_instance_variable_invalidator")));
2038 @end
2039
2040 @interface InvalidationImpObj : NSObject <Invalidation>
2041 @end
2042
2043 @interface SubclassInvalidationImpObj : InvalidationImpObj {
2044   InvalidationImpObj *var;
2045 }
2046 - (void)invalidate;
2047 @end
2048
2049 @implementation SubclassInvalidationImpObj
2050 - (void) invalidate {}
2051 @end
2052 // warn: var needs to be invalidated or set to nil
2053
2054.. _alpha-osx-cocoa-MissingInvalidationMethod:
2055
2056alpha.osx.cocoa.MissingInvalidationMethod (ObjC)
2057""""""""""""""""""""""""""""""""""""""""""""""""
2058Check that the invalidation methods are present in classes that contain invalidatable instance variables.
2059
2060.. code-block:: objc
2061
2062 @protocol Invalidation <NSObject>
2063 - (void)invalidate
2064   __attribute__((annotate("objc_instance_variable_invalidator")));
2065 @end
2066
2067 @interface NeedInvalidation : NSObject <Invalidation>
2068 @end
2069
2070 @interface MissingInvalidationMethodDecl : NSObject {
2071   NeedInvalidation *Var; // warn
2072 }
2073 @end
2074
2075 @implementation MissingInvalidationMethodDecl
2076 @end
2077
2078.. _alpha-osx-cocoa-localizability-PluralMisuseChecker:
2079
2080alpha.osx.cocoa.localizability.PluralMisuseChecker (ObjC)
2081"""""""""""""""""""""""""""""""""""""""""""""""""""""""""
2082Warns against using one vs. many plural pattern in code when generating localized strings.
2083
2084.. code-block:: objc
2085
2086 NSString *reminderText =
2087   NSLocalizedString(@"None", @"Indicates no reminders");
2088 if (reminderCount == 1) {
2089   // Warning: Plural cases are not supported across all languages.
2090   // Use a .stringsdict file instead
2091   reminderText =
2092     NSLocalizedString(@"1 Reminder", @"Indicates single reminder");
2093 } else if (reminderCount >= 2) {
2094   // Warning: Plural cases are not supported across all languages.
2095   // Use a .stringsdict file instead
2096   reminderText =
2097     [NSString stringWithFormat:
2098       NSLocalizedString(@"%@ Reminders", @"Indicates multiple reminders"),
2099         reminderCount];
2100 }
2101
2102alpha.security
2103^^^^^^^^^^^^^^
2104
2105.. _alpha-security-ArrayBound:
2106
2107alpha.security.ArrayBound (C)
2108"""""""""""""""""""""""""""""
2109Warn about buffer overflows (older checker).
2110
2111.. code-block:: c
2112
2113 void test() {
2114   char *s = "";
2115   char c = s[1]; // warn
2116 }
2117
2118 struct seven_words {
2119   int c[7];
2120 };
2121
2122 void test() {
2123   struct seven_words a, *p;
2124   p = &a;
2125   p[0] = a;
2126   p[1] = a;
2127   p[2] = a; // warn
2128 }
2129
2130 // note: requires unix.Malloc or
2131 // alpha.unix.MallocWithAnnotations checks enabled.
2132 void test() {
2133   int *p = malloc(12);
2134   p[3] = 4; // warn
2135 }
2136
2137 void test() {
2138   char a[2];
2139   int *b = (int*)a;
2140   b[1] = 3; // warn
2141 }
2142
2143.. _alpha-security-ArrayBoundV2:
2144
2145alpha.security.ArrayBoundV2 (C)
2146"""""""""""""""""""""""""""""""
2147Warn about buffer overflows (newer checker).
2148
2149.. code-block:: c
2150
2151 void test() {
2152   char *s = "";
2153   char c = s[1]; // warn
2154 }
2155
2156 void test() {
2157   int buf[100];
2158   int *p = buf;
2159   p = p + 99;
2160   p[1] = 1; // warn
2161 }
2162
2163 // note: compiler has internal check for this.
2164 // Use -Wno-array-bounds to suppress compiler warning.
2165 void test() {
2166   int buf[100][100];
2167   buf[0][-1] = 1; // warn
2168 }
2169
2170 // note: requires alpha.security.taint check turned on.
2171 void test() {
2172   char s[] = "abc";
2173   int x = getchar();
2174   char c = s[x]; // warn: index is tainted
2175 }
2176
2177.. _alpha-security-MallocOverflow:
2178
2179alpha.security.MallocOverflow (C)
2180"""""""""""""""""""""""""""""""""
2181Check for overflows in the arguments to ``malloc()``.
2182It tries to catch ``malloc(n * c)`` patterns, where:
2183
2184 - ``n``: a variable or member access of an object
2185 - ``c``: a constant foldable integral
2186
2187This checker was designed for code audits, so expect false-positive reports.
2188One is supposed to silence this checker by ensuring proper bounds checking on
2189the variable in question using e.g. an ``assert()`` or a branch.
2190
2191.. code-block:: c
2192
2193 void test(int n) {
2194   void *p = malloc(n * sizeof(int)); // warn
2195 }
2196
2197 void test2(int n) {
2198   if (n > 100) // gives an upper-bound
2199     return;
2200   void *p = malloc(n * sizeof(int)); // no warning
2201 }
2202
2203 void test3(int n) {
2204   assert(n <= 100 && "Contract violated.");
2205   void *p = malloc(n * sizeof(int)); // no warning
2206 }
2207
2208Limitations:
2209
2210 - The checker won't warn for variables involved in explicit casts,
2211   since that might limit the variable's domain.
2212   E.g.: ``(unsigned char)int x`` would limit the domain to ``[0,255]``.
2213   The checker will miss the true-positive cases when the explicit cast would
2214   not tighten the domain to prevent the overflow in the subsequent
2215   multiplication operation.
2216
2217 - It is an AST-based checker, thus it does not make use of the
2218   path-sensitive taint-analysis.
2219
2220.. _alpha-security-MmapWriteExec:
2221
2222alpha.security.MmapWriteExec (C)
2223""""""""""""""""""""""""""""""""
2224Warn on mmap() calls that are both writable and executable.
2225
2226.. code-block:: c
2227
2228 void test(int n) {
2229   void *c = mmap(NULL, 32, PROT_READ | PROT_WRITE | PROT_EXEC,
2230                  MAP_PRIVATE | MAP_ANON, -1, 0);
2231   // warn: Both PROT_WRITE and PROT_EXEC flags are set. This can lead to
2232   //       exploitable memory regions, which could be overwritten with malicious
2233   //       code
2234 }
2235
2236.. _alpha-security-ReturnPtrRange:
2237
2238alpha.security.ReturnPtrRange (C)
2239"""""""""""""""""""""""""""""""""
2240Check for an out-of-bound pointer being returned to callers.
2241
2242.. code-block:: c
2243
2244 static int A[10];
2245
2246 int *test() {
2247   int *p = A + 10;
2248   return p; // warn
2249 }
2250
2251 int test(void) {
2252   int x;
2253   return x; // warn: undefined or garbage returned
2254 }
2255
2256
2257alpha.security.cert
2258^^^^^^^^^^^^^^^^^^^
2259
2260SEI CERT checkers which tries to find errors based on their `C coding rules <https://wiki.sei.cmu.edu/confluence/display/c/2+Rules>`_.
2261
2262.. _alpha-security-cert-pos-checkers:
2263
2264alpha.security.cert.pos
2265^^^^^^^^^^^^^^^^^^^^^^^
2266
2267SEI CERT checkers of `POSIX C coding rules <https://wiki.sei.cmu.edu/confluence/pages/viewpage.action?pageId=87152405>`_.
2268
2269.. _alpha-security-cert-pos-34c:
2270
2271alpha.security.cert.pos.34c
2272"""""""""""""""""""""""""""
2273Finds calls to the ``putenv`` function which pass a pointer to an automatic variable as the argument.
2274
2275.. code-block:: c
2276
2277  int func(const char *var) {
2278    char env[1024];
2279    int retval = snprintf(env, sizeof(env),"TEST=%s", var);
2280    if (retval < 0 || (size_t)retval >= sizeof(env)) {
2281        /* Handle error */
2282    }
2283
2284    return putenv(env); // putenv function should not be called with auto variables
2285  }
2286
2287Limitations:
2288
2289   - Technically, one can pass automatic variables to ``putenv``,
2290     but one needs to ensure that the given environment key stays
2291     alive until it's removed or overwritten.
2292     Since the analyzer cannot keep track of which envvars get overwritten
2293     and when, it needs to be slightly more aggressive and warn for such
2294     cases too, leading in some cases to false-positive reports like this:
2295
2296     .. code-block:: c
2297
2298        void baz() {
2299          char env[] = "NAME=value";
2300          putenv(env); // false-positive warning: putenv function should not be called...
2301          // More code...
2302          putenv((char *)"NAME=anothervalue");
2303          // This putenv call overwrites the previous entry, thus that can no longer dangle.
2304        } // 'env' array becomes dead only here.
2305
2306alpha.security.cert.env
2307^^^^^^^^^^^^^^^^^^^^^^^
2308
2309SEI CERT checkers of `Environment C coding rules <https://wiki.sei.cmu.edu/confluence/x/JdcxBQ>`_.
2310
2311.. _alpha-security-cert-env-InvalidPtr:
2312
2313alpha.security.cert.env.InvalidPtr
2314""""""""""""""""""""""""""""""""""
2315
2316Corresponds to SEI CERT Rules ENV31-C and ENV34-C.
2317
2318ENV31-C:
2319Rule is about the possible problem with `main` function's third argument, environment pointer,
2320"envp". When enviornment array is modified using some modification function
2321such as putenv, setenv or others, It may happen that memory is reallocated,
2322however "envp" is not updated to reflect the changes and points to old memory
2323region.
2324
2325ENV34-C:
2326Some functions return a pointer to a statically allocated buffer.
2327Consequently, subsequent call of these functions will invalidate previous
2328pointer. These functions include: getenv, localeconv, asctime, setlocale, strerror
2329
2330.. code-block:: c
2331
2332  int main(int argc, const char *argv[], const char *envp[]) {
2333    if (setenv("MY_NEW_VAR", "new_value", 1) != 0) {
2334      // setenv call may invalidate 'envp'
2335      /* Handle error */
2336    }
2337    if (envp != NULL) {
2338      for (size_t i = 0; envp[i] != NULL; ++i) {
2339        puts(envp[i]);
2340        // envp may no longer point to the current environment
2341        // this program has unanticipated behavior, since envp
2342        // does not reflect changes made by setenv function.
2343      }
2344    }
2345    return 0;
2346  }
2347
2348  void previous_call_invalidation() {
2349    char *p, *pp;
2350
2351    p = getenv("VAR");
2352    pp = getenv("VAR2");
2353    // subsequent call to 'getenv' invalidated previous one
2354
2355    *p;
2356    // dereferencing invalid pointer
2357  }
2358
2359alpha.security.taint
2360^^^^^^^^^^^^^^^^^^^^
2361
2362Checkers implementing `taint analysis <https://en.wikipedia.org/wiki/Taint_checking>`_.
2363
2364.. _alpha-security-taint-TaintPropagation:
2365
2366alpha.security.taint.TaintPropagation (C, C++)
2367""""""""""""""""""""""""""""""""""""""""""""""
2368
2369Taint analysis identifies untrusted sources of information (taint sources), rules as to how the untrusted data flows along the execution path (propagation rules), and points of execution where the use of tainted data is risky (taints sinks).
2370The most notable examples of taint sources are:
2371
2372  - network originating data
2373  - environment variables
2374  - database originating data
2375
2376``GenericTaintChecker`` is the main implementation checker for this rule, and it generates taint information used by other checkers.
2377
2378.. code-block:: c
2379
2380 void test() {
2381   char x = getchar(); // 'x' marked as tainted
2382   system(&x); // warn: untrusted data is passed to a system call
2383 }
2384
2385 // note: compiler internally checks if the second param to
2386 // sprintf is a string literal or not.
2387 // Use -Wno-format-security to suppress compiler warning.
2388 void test() {
2389   char s[10], buf[10];
2390   fscanf(stdin, "%s", s); // 's' marked as tainted
2391
2392   sprintf(buf, s); // warn: untrusted data as a format string
2393 }
2394
2395 void test() {
2396   size_t ts;
2397   scanf("%zd", &ts); // 'ts' marked as tainted
2398   int *p = (int *)malloc(ts * sizeof(int));
2399     // warn: untrusted data as buffer size
2400 }
2401
2402There are built-in sources, propagations and sinks defined in code inside ``GenericTaintChecker``.
2403These operations are handled even if no external taint configuration is provided.
2404
2405Default sources defined by ``GenericTaintChecker``:
2406 ``_IO_getc``, ``fdopen``, ``fopen``, ``freopen``, ``get_current_dir_name``, ``getch``, ``getchar``, ``getchar_unlocked``, ``getwd``, ``getcwd``, ``getgroups``, ``gethostname``, ``getlogin``, ``getlogin_r``, ``getnameinfo``, ``gets``, ``gets_s``, ``getseuserbyname``, ``readlink``, ``readlinkat``, ``scanf``, ``scanf_s``, ``socket``, ``wgetch``
2407
2408Default propagations defined by ``GenericTaintChecker``:
2409``atoi``, ``atol``, ``atoll``, ``basename``, ``dirname``, ``fgetc``, ``fgetln``, ``fgets``, ``fnmatch``, ``fread``, ``fscanf``, ``fscanf_s``, ``index``, ``inflate``, ``isalnum``, ``isalpha``, ``isascii``, ``isblank``, ``iscntrl``, ``isdigit``, ``isgraph``, ``islower``, ``isprint``, ``ispunct``, ``isspace``, ``isupper``, ``isxdigit``, ``memchr``, ``memrchr``, ``sscanf``, ``getc``, ``getc_unlocked``, ``getdelim``, ``getline``, ``getw``, ``memcmp``, ``memcpy``, ``memmem``, ``memmove``, ``mbtowc``, ``pread``, ``qsort``, ``qsort_r``, ``rawmemchr``, ``read``, ``recv``, ``recvfrom``, ``rindex``, ``strcasestr``, ``strchr``, ``strchrnul``, ``strcasecmp``, ``strcmp``, ``strcspn``, ``strlen``, ``strncasecmp``, ``strncmp``, ``strndup``, ``strndupa``, ``strnlen``, ``strpbrk``, ``strrchr``, ``strsep``, ``strspn``, ``strstr``, ``strtol``, ``strtoll``, ``strtoul``, ``strtoull``, ``tolower``, ``toupper``, ``ttyname``, ``ttyname_r``, ``wctomb``, ``wcwidth``
2410
2411Default sinks defined in ``GenericTaintChecker``:
2412``printf``, ``setproctitle``, ``system``, ``popen``, ``execl``, ``execle``, ``execlp``, ``execv``, ``execvp``, ``execvP``, ``execve``, ``dlopen``, ``memcpy``, ``memmove``, ``strncpy``, ``strndup``, ``malloc``, ``calloc``, ``alloca``, ``memccpy``, ``realloc``, ``bcopy``
2413
2414The user can configure taint sources, sinks, and propagation rules by providing a configuration file via checker option ``alpha.security.taint.TaintPropagation:Config``.
2415
2416External taint configuration is in `YAML <http://llvm.org/docs/YamlIO.html#introduction-to-yaml>`_ format. The taint-related options defined in the config file extend but do not override the built-in sources, rules, sinks.
2417The format of the external taint configuration file is not stable, and could change without any notice even in a non-backward compatible way.
2418
2419For a more detailed description of configuration options, please see the :doc:`user-docs/TaintAnalysisConfiguration`. For an example see :ref:`clangsa-taint-configuration-example`.
2420
2421alpha.unix
2422^^^^^^^^^^^
2423
2424.. _alpha-unix-StdCLibraryFunctionArgs:
2425
2426alpha.unix.StdCLibraryFunctionArgs (C)
2427""""""""""""""""""""""""""""""""""""""
2428Check for calls of standard library functions that violate predefined argument
2429constraints. For example, it is stated in the C standard that for the ``int
2430isalnum(int ch)`` function the behavior is undefined if the value of ``ch`` is
2431not representable as unsigned char and is not equal to ``EOF``.
2432
2433.. code-block:: c
2434
2435  void test_alnum_concrete(int v) {
2436    int ret = isalnum(256); // \
2437    // warning: Function argument constraint is not satisfied
2438    (void)ret;
2439  }
2440
2441If the argument's value is unknown then the value is assumed to hold the proper value range.
2442
2443.. code-block:: c
2444
2445  #define EOF -1
2446  int test_alnum_symbolic(int x) {
2447    int ret = isalnum(x);
2448    // after the call, ret is assumed to be in the range [-1, 255]
2449
2450    if (ret > 255)      // impossible (infeasible branch)
2451      if (x == 0)
2452        return ret / x; // division by zero is not reported
2453    return ret;
2454  }
2455
2456If the user disables the checker then the argument violation warning is
2457suppressed. However, the assumption about the argument is still modeled. This
2458is because exploring an execution path that already contains undefined behavior
2459is not valuable.
2460
2461There are different kind of constraints modeled: range constraint, not null
2462constraint, buffer size constraint. A **range constraint** requires the
2463argument's value to be in a specific range, see ``isalnum`` as an example above.
2464A **not null constraint** requires the pointer argument to be non-null.
2465
2466A **buffer size** constraint specifies the minimum size of the buffer
2467argument. The size might be a known constant. For example, ``asctime_r`` requires
2468that the buffer argument's size must be greater than or equal to ``26`` bytes. In
2469other cases, the size is denoted by another argument or as a multiplication of
2470two arguments.
2471For instance, ``size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream)``.
2472Here, ``ptr`` is the buffer, and its minimum size is ``size * nmemb``
2473
2474.. code-block:: c
2475
2476  void buffer_size_constraint_violation(FILE *file) {
2477    enum { BUFFER_SIZE = 1024 };
2478    wchar_t wbuf[BUFFER_SIZE];
2479
2480    const size_t size = sizeof(*wbuf);   // 4
2481    const size_t nitems = sizeof(wbuf);  // 4096
2482
2483    // Below we receive a warning because the 3rd parameter should be the
2484    // number of elements to read, not the size in bytes. This case is a known
2485    // vulnerability described by the ARR38-C SEI-CERT rule.
2486    fread(wbuf, size, nitems, file);
2487  }
2488
2489**Limitations**
2490
2491The checker is in alpha because the reports cannot provide notes about the
2492values of the arguments. Without this information it is hard to confirm if the
2493constraint is indeed violated. For example, consider the above case for
2494``fread``. We display in the warning message that the size of the 1st arg
2495should be equal to or less than the value of the 2nd arg times the 3rd arg.
2496However, we fail to display the concrete values (``4`` and ``4096``) for those
2497arguments.
2498
2499**Parameters**
2500
2501The checker models functions (and emits diagnostics) from the C standard by
2502default. The ``ModelPOSIX`` option enables the checker to model (and emit
2503diagnostics) for functions that are defined in the POSIX standard. This option
2504is disabled by default.
2505
2506.. _alpha-unix-BlockInCriticalSection:
2507
2508alpha.unix.BlockInCriticalSection (C)
2509"""""""""""""""""""""""""""""""""""""
2510Check for calls to blocking functions inside a critical section.
2511Applies to: ``lock, unlock, sleep, getc, fgets, read, recv, pthread_mutex_lock,``
2512`` pthread_mutex_unlock, mtx_lock, mtx_timedlock, mtx_trylock, mtx_unlock, lock_guard, unique_lock``
2513
2514.. code-block:: c
2515
2516 void test() {
2517   std::mutex m;
2518   m.lock();
2519   sleep(3); // warn: a blocking function sleep is called inside a critical
2520             //       section
2521   m.unlock();
2522 }
2523
2524.. _alpha-unix-Chroot:
2525
2526alpha.unix.Chroot (C)
2527"""""""""""""""""""""
2528Check improper use of chroot.
2529
2530.. code-block:: c
2531
2532 void f();
2533
2534 void test() {
2535   chroot("/usr/local");
2536   f(); // warn: no call of chdir("/") immediately after chroot
2537 }
2538
2539.. _alpha-unix-Errno:
2540
2541alpha.unix.Errno (C)
2542""""""""""""""""""""
2543
2544Check for improper use of ``errno``.
2545This checker implements partially CERT rule
2546`ERR30-C. Set errno to zero before calling a library function known to set errno,
2547and check errno only after the function returns a value indicating failure
2548<https://wiki.sei.cmu.edu/confluence/pages/viewpage.action?pageId=87152351>`_.
2549The checker can find the first read of ``errno`` after successful standard
2550function calls.
2551
2552The C and POSIX standards often do not define if a standard library function
2553may change value of ``errno`` if the call does not fail.
2554Therefore, ``errno`` should only be used if it is known from the return value
2555of a function that the call has failed.
2556There are exceptions to this rule (for example ``strtol``) but the affected
2557functions are not yet supported by the checker.
2558The return values for the failure cases are documented in the standard Linux man
2559pages of the functions and in the `POSIX standard <https://pubs.opengroup.org/onlinepubs/9699919799/>`_.
2560
2561.. code-block:: c
2562
2563 int unsafe_errno_read(int sock, void *data, int data_size) {
2564   if (send(sock, data, data_size, 0) != data_size) {
2565     // 'send' can be successful even if not all data was sent
2566     if (errno == 1) { // An undefined value may be read from 'errno'
2567       return 0;
2568     }
2569   }
2570   return 1;
2571 }
2572
2573The supported functions are the same that are modeled by checker
2574:ref:`alpha-unix-StdCLibraryFunctionArgs`.
2575The ``ModelPOSIX`` option of that checker affects the set of checked functions.
2576
2577**Parameters**
2578
2579The ``AllowErrnoReadOutsideConditionExpressions`` option allows read of the
2580errno value if the value is not used in a condition (in ``if`` statements,
2581loops, conditional expressions, ``switch`` statements). For example ``errno``
2582can be stored into a variable without getting a warning by the checker.
2583
2584.. code-block:: c
2585
2586 int unsafe_errno_read(int sock, void *data, int data_size) {
2587   if (send(sock, data, data_size, 0) != data_size) {
2588     int err = errno;
2589     // warning if 'AllowErrnoReadOutsideConditionExpressions' is false
2590     // no warning if 'AllowErrnoReadOutsideConditionExpressions' is true
2591   }
2592   return 1;
2593 }
2594
2595Default value of this option is ``true``. This allows save of the errno value
2596for possible later error handling.
2597
2598**Limitations**
2599
2600 - Only the very first usage of ``errno`` is checked after an affected function
2601   call. Value of ``errno`` is not followed when it is stored into a variable
2602   or returned from a function.
2603 - Documentation of function ``lseek`` is not clear about what happens if the
2604   function returns different value than the expected file position but not -1.
2605   To avoid possible false-positives ``errno`` is allowed to be used in this
2606   case.
2607
2608.. _alpha-unix-PthreadLock:
2609
2610alpha.unix.PthreadLock (C)
2611""""""""""""""""""""""""""
2612Simple lock -> unlock checker.
2613Applies to: ``pthread_mutex_lock, pthread_rwlock_rdlock, pthread_rwlock_wrlock, lck_mtx_lock, lck_rw_lock_exclusive``
2614``lck_rw_lock_shared, pthread_mutex_trylock, pthread_rwlock_tryrdlock, pthread_rwlock_tryrwlock, lck_mtx_try_lock,
2615lck_rw_try_lock_exclusive, lck_rw_try_lock_shared, pthread_mutex_unlock, pthread_rwlock_unlock, lck_mtx_unlock, lck_rw_done``.
2616
2617
2618.. code-block:: c
2619
2620 pthread_mutex_t mtx;
2621
2622 void test() {
2623   pthread_mutex_lock(&mtx);
2624   pthread_mutex_lock(&mtx);
2625     // warn: this lock has already been acquired
2626 }
2627
2628 lck_mtx_t lck1, lck2;
2629
2630 void test() {
2631   lck_mtx_lock(&lck1);
2632   lck_mtx_lock(&lck2);
2633   lck_mtx_unlock(&lck1);
2634     // warn: this was not the most recently acquired lock
2635 }
2636
2637 lck_mtx_t lck1, lck2;
2638
2639 void test() {
2640   if (lck_mtx_try_lock(&lck1) == 0)
2641     return;
2642
2643   lck_mtx_lock(&lck2);
2644   lck_mtx_unlock(&lck1);
2645     // warn: this was not the most recently acquired lock
2646 }
2647
2648.. _alpha-unix-SimpleStream:
2649
2650alpha.unix.SimpleStream (C)
2651"""""""""""""""""""""""""""
2652Check for misuses of stream APIs. Check for misuses of stream APIs: ``fopen, fclose``
2653(demo checker, the subject of the demo (`Slides <https://llvm.org/devmtg/2012-11/Zaks-Rose-Checker24Hours.pdf>`_ ,
2654`Video <https://youtu.be/kdxlsP5QVPw>`_) by Anna Zaks and Jordan Rose presented at the
2655`2012 LLVM Developers' Meeting <https://llvm.org/devmtg/2012-11/>`_).
2656
2657.. code-block:: c
2658
2659 void test() {
2660   FILE *F = fopen("myfile.txt", "w");
2661 } // warn: opened file is never closed
2662
2663 void test() {
2664   FILE *F = fopen("myfile.txt", "w");
2665
2666   if (F)
2667     fclose(F);
2668
2669   fclose(F); // warn: closing a previously closed file stream
2670 }
2671
2672.. _alpha-unix-Stream:
2673
2674alpha.unix.Stream (C)
2675"""""""""""""""""""""
2676Check stream handling functions: ``fopen, tmpfile, fclose, fread, fwrite, fseek, ftell, rewind, fgetpos,``
2677``fsetpos, clearerr, feof, ferror, fileno``.
2678
2679.. code-block:: c
2680
2681 void test() {
2682   FILE *p = fopen("foo", "r");
2683 } // warn: opened file is never closed
2684
2685 void test() {
2686   FILE *p = fopen("foo", "r");
2687   fseek(p, 1, SEEK_SET); // warn: stream pointer might be NULL
2688   fclose(p);
2689 }
2690
2691 void test() {
2692   FILE *p = fopen("foo", "r");
2693
2694   if (p)
2695     fseek(p, 1, 3);
2696      // warn: third arg should be SEEK_SET, SEEK_END, or SEEK_CUR
2697
2698   fclose(p);
2699 }
2700
2701 void test() {
2702   FILE *p = fopen("foo", "r");
2703   fclose(p);
2704   fclose(p); // warn: already closed
2705 }
2706
2707 void test() {
2708   FILE *p = tmpfile();
2709   ftell(p); // warn: stream pointer might be NULL
2710   fclose(p);
2711 }
2712
2713
2714.. _alpha-unix-cstring-BufferOverlap:
2715
2716alpha.unix.cstring.BufferOverlap (C)
2717""""""""""""""""""""""""""""""""""""
2718Checks for overlap in two buffer arguments. Applies to:  ``memcpy, mempcpy, wmemcpy, wmempcpy``.
2719
2720.. code-block:: c
2721
2722 void test() {
2723   int a[4] = {0};
2724   memcpy(a + 2, a + 1, 8); // warn
2725 }
2726
2727.. _alpha-unix-cstring-NotNullTerminated:
2728
2729alpha.unix.cstring.NotNullTerminated (C)
2730""""""""""""""""""""""""""""""""""""""""
2731Check for arguments which are not null-terminated strings; applies to: ``strlen, strnlen, strcpy, strncpy, strcat, strncat, wcslen, wcsnlen``.
2732
2733.. code-block:: c
2734
2735 void test() {
2736   int y = strlen((char *)&test); // warn
2737 }
2738
2739.. _alpha-unix-cstring-OutOfBounds:
2740
2741alpha.unix.cstring.OutOfBounds (C)
2742""""""""""""""""""""""""""""""""""
2743Check for out-of-bounds access in string functions, such as:
2744``memcpy, bcopy, strcpy, strncpy, strcat, strncat, memmove, memcmp, memset`` and more.
2745
2746This check also works with string literals, except there is a known bug in that
2747the analyzer cannot detect embedded NULL characters when determining the string length.
2748
2749.. code-block:: c
2750
2751 void test1() {
2752   const char str[] = "Hello world";
2753   char buffer[] = "Hello world";
2754   memcpy(buffer, str, sizeof(str) + 1); // warn
2755 }
2756
2757 void test2() {
2758   const char str[] = "Hello world";
2759   char buffer[] = "Helloworld";
2760   memcpy(buffer, str, sizeof(str)); // warn
2761 }
2762
2763.. _alpha-unix-cstring-UninitializedRead:
2764
2765alpha.unix.cstring.UninitializedRead (C)
2766""""""""""""""""""""""""""""""""""""""""
2767Check for uninitialized reads from common memory copy/manipulation functions such as:
2768 ``memcpy, mempcpy, memmove, memcmp, strcmp, strncmp, strcpy, strlen, strsep`` and many more.
2769
2770.. code-block:: c
2771
2772 void test() {
2773  char src[10];
2774  char dst[5];
2775  memcpy(dst,src,sizeof(dst)); // warn: Bytes string function accesses uninitialized/garbage values
2776 }
2777
2778Limitations:
2779
2780   - Due to limitations of the memory modeling in the analyzer, one can likely
2781     observe a lot of false-positive reports like this:
2782
2783      .. code-block:: c
2784
2785        void false_positive() {
2786          int src[] = {1, 2, 3, 4};
2787          int dst[5] = {0};
2788          memcpy(dst, src, 4 * sizeof(int)); // false-positive:
2789          // The 'src' buffer was correctly initialized, yet we cannot conclude
2790          // that since the analyzer could not see a direct initialization of the
2791          // very last byte of the source buffer.
2792        }
2793
2794     More details at the corresponding `GitHub issue <https://github.com/llvm/llvm-project/issues/43459>`_.
2795
2796.. _alpha-nondeterminism-PointerIteration:
2797
2798alpha.nondeterminism.PointerIteration (C++)
2799"""""""""""""""""""""""""""""""""""""""""""
2800Check for non-determinism caused by iterating unordered containers of pointers.
2801
2802.. code-block:: c
2803
2804 void test() {
2805  int a = 1, b = 2;
2806  std::unordered_set<int *> UnorderedPtrSet = {&a, &b};
2807
2808  for (auto i : UnorderedPtrSet) // warn
2809    f(i);
2810 }
2811
2812.. _alpha-nondeterminism-PointerSorting:
2813
2814alpha.nondeterminism.PointerSorting (C++)
2815"""""""""""""""""""""""""""""""""""""""""
2816Check for non-determinism caused by sorting of pointers.
2817
2818.. code-block:: c
2819
2820 void test() {
2821  int a = 1, b = 2;
2822  std::vector<int *> V = {&a, &b};
2823  std::sort(V.begin(), V.end()); // warn
2824 }
2825
2826
2827alpha.WebKit
2828^^^^^^^^^^^^
2829
2830.. _alpha-webkit-UncountedCallArgsChecker:
2831
2832alpha.webkit.UncountedCallArgsChecker
2833"""""""""""""""""""""""""""""""""""""
2834The 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.
2835
2836Here 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.
2837
2838  .. code-block:: cpp
2839
2840    RefCountable* provide_uncounted();
2841    void consume(RefCountable*);
2842
2843    // 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.
2844
2845    void foo1() {
2846      consume(provide_uncounted()); // warn
2847    }
2848
2849    void foo2() {
2850      RefCountable* uncounted = provide_uncounted();
2851      consume(uncounted); // warn
2852    }
2853
2854Although 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.
2855
2856Note: 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.
2857
2858  .. code-block:: cpp
2859
2860    struct Foo {
2861      RefPtr<RefCountable> member;
2862      void consume(RefCountable*) { /* ... */ }
2863      void bugprone() {
2864        consume(member.get()); // warn
2865      }
2866    };
2867
2868The 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.
2869
2870Allowed kinds of arguments:
2871
2872- values obtained from ref-counted objects (including temporaries as those survive the call too)
2873
2874  .. code-block:: cpp
2875
2876    RefCountable* provide_uncounted();
2877    void consume(RefCountable*);
2878
2879    void foo() {
2880      RefPtr<RefCountable> rc = makeRef(provide_uncounted());
2881      consume(rc.get()); // ok
2882      consume(makeRef(provide_uncounted()).get()); // ok
2883    }
2884
2885- forwarding uncounted arguments from caller to callee
2886
2887  .. code-block:: cpp
2888
2889    void foo(RefCountable& a) {
2890      bar(a); // ok
2891    }
2892
2893  Caller of ``foo()`` is responsible for  ``a``'s lifetime.
2894
2895- ``this`` pointer
2896
2897  .. code-block:: cpp
2898
2899    void Foo::foo() {
2900      baz(this);  // ok
2901    }
2902
2903  Caller of ``foo()`` is responsible for keeping the memory pointed to by ``this`` pointer safe.
2904
2905- constants
2906
2907  .. code-block:: cpp
2908
2909    foo(nullptr, NULL, 0); // ok
2910
2911We 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.
2912
2913- constructors of ref-counted types (including factory methods)
2914- getters of ref-counted types
2915- member overloaded operators
2916- casts
2917- unary operators like ``&`` or ``*``
2918
2919alpha.webkit.UncountedLocalVarsChecker
2920""""""""""""""""""""""""""""""""""""""
2921The 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.
2922
2923These are examples of cases that we consider safe:
2924
2925  .. code-block:: cpp
2926
2927    void foo1() {
2928      RefPtr<RefCountable> counted;
2929      // The scope of uncounted is EMBEDDED in the scope of counted.
2930      {
2931        RefCountable* uncounted = counted.get(); // ok
2932      }
2933    }
2934
2935    void foo2(RefPtr<RefCountable> counted_param) {
2936      RefCountable* uncounted = counted_param.get(); // ok
2937    }
2938
2939    void FooClass::foo_method() {
2940      RefCountable* uncounted = this; // ok
2941    }
2942
2943Here 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.
2944
2945  .. code-block:: cpp
2946
2947    void foo1() {
2948      RefCountable* uncounted = new RefCountable; // warn
2949    }
2950
2951    RefCountable* global_uncounted;
2952    void foo2() {
2953      RefCountable* uncounted = global_uncounted; // warn
2954    }
2955
2956    void foo3() {
2957      RefPtr<RefCountable> counted;
2958      // The scope of uncounted is not EMBEDDED in the scope of counted.
2959      RefCountable* uncounted = counted.get(); // warn
2960    }
2961
2962We 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:
2963- variable defined in condition part of an ```if``` statement
2964- variable defined in init statement condition of a ```for``` statement
2965
2966For the time being we also don't warn about uninitialized uncounted local variables.
2967
2968Debug Checkers
2969---------------
2970
2971.. _debug-checkers:
2972
2973
2974debug
2975^^^^^
2976
2977Checkers used for debugging the analyzer.
2978:doc:`developer-docs/DebugChecks` page contains a detailed description.
2979
2980.. _debug-AnalysisOrder:
2981
2982debug.AnalysisOrder
2983"""""""""""""""""""
2984Print callbacks that are called during analysis in order.
2985
2986.. _debug-ConfigDumper:
2987
2988debug.ConfigDumper
2989""""""""""""""""""
2990Dump config table.
2991
2992.. _debug-DumpCFG Display:
2993
2994debug.DumpCFG Display
2995"""""""""""""""""""""
2996Control-Flow Graphs.
2997
2998.. _debug-DumpCallGraph:
2999
3000debug.DumpCallGraph
3001"""""""""""""""""""
3002Display Call Graph.
3003
3004.. _debug-DumpCalls:
3005
3006debug.DumpCalls
3007"""""""""""""""
3008Print calls as they are traversed by the engine.
3009
3010.. _debug-DumpDominators:
3011
3012debug.DumpDominators
3013""""""""""""""""""""
3014Print the dominance tree for a given CFG.
3015
3016.. _debug-DumpLiveVars:
3017
3018debug.DumpLiveVars
3019""""""""""""""""""
3020Print results of live variable analysis.
3021
3022.. _debug-DumpTraversal:
3023
3024debug.DumpTraversal
3025"""""""""""""""""""
3026Print branch conditions as they are traversed by the engine.
3027
3028.. _debug-ExprInspection:
3029
3030debug.ExprInspection
3031""""""""""""""""""""
3032Check the analyzer's understanding of expressions.
3033
3034.. _debug-Stats:
3035
3036debug.Stats
3037"""""""""""
3038Emit warnings with analyzer statistics.
3039
3040.. _debug-TaintTest:
3041
3042debug.TaintTest
3043"""""""""""""""
3044Mark tainted symbols as such.
3045
3046.. _debug-ViewCFG:
3047
3048debug.ViewCFG
3049"""""""""""""
3050View Control-Flow Graphs using GraphViz.
3051
3052.. _debug-ViewCallGraph:
3053
3054debug.ViewCallGraph
3055"""""""""""""""""""
3056View Call Graph using GraphViz.
3057
3058.. _debug-ViewExplodedGraph:
3059
3060debug.ViewExplodedGraph
3061"""""""""""""""""""""""
3062View Exploded Graphs using GraphViz.
3063
3064