blob: 2b4b0143fb9f53d70d26d6cb47bf0ead642b0693 [file] [log] [blame]
Kristof Umann1a170322019-02-05 00:39:33 +00001==================
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
32core.CallAndMessage (C, C++, ObjC)
33""""""""""""""""""""""""""""""""""
34 Check for logical errors for function calls and Objective-C message expressions (e.g., uninitialized arguments, null function pointers).
35
36.. literalinclude:: checkers/callandmessage_example.c
37 :language: objc
38
39core.DivideZero (C, C++, ObjC)
40""""""""""""""""""""""""""""""
41 Check for division by zero.
42
43.. literalinclude:: checkers/dividezero_example.c
44 :language: c
45
46core.NonNullParamChecker (C, C++, ObjC)
47"""""""""""""""""""""""""""""""""""""""
48Check for null pointers passed as arguments to a function whose arguments are references or marked with the 'nonnull' attribute.
49
50.. code-block:: cpp
51
52 int f(int *p) __attribute__((nonnull));
53
54 void test(int *p) {
55 if (!p)
56 f(p); // warn
57 }
58
59core.NullDereference (C, C++, ObjC)
60"""""""""""""""""""""""""""""""""""
61Check for dereferences of null pointers.
62
63.. code-block:: objc
64
65 // C
66 void test(int *p) {
67 if (p)
68 return;
69
70 int x = p[0]; // warn
71 }
72
73 // C
74 void test(int *p) {
75 if (!p)
76 *p = 0; // warn
77 }
78
79 // C++
80 class C {
81 public:
82 int x;
83 };
84
85 void test() {
86 C *pc = 0;
87 int k = pc->x; // warn
88 }
89
90 // Objective-C
91 @interface MyClass {
92 @public
93 int x;
94 }
95 @end
96
97 void test() {
98 MyClass *obj = 0;
99 obj->x = 1; // warn
100 }
101
102core.StackAddressEscape (C)
103"""""""""""""""""""""""""""
104Check that addresses to stack memory do not escape the function.
105
106.. code-block:: c
107
108 char const *p;
109
110 void test() {
111 char const str[] = "string";
112 p = str; // warn
113 }
114
115 void* test() {
116 return __builtin_alloca(12); // warn
117 }
118
119 void test() {
120 static int *x;
121 int y;
122 x = &y; // warn
123 }
124
125
126core.UndefinedBinaryOperatorResult (C)
127""""""""""""""""""""""""""""""""""""""
128Check for undefined results of binary operators.
129
130.. code-block:: c
131
132 void test() {
133 int x;
134 int y = x + 1; // warn: left operand is garbage
135 }
136
137core.VLASize (C)
138""""""""""""""""
139Check for declarations of Variable Length Arrays of undefined or zero size.
140
141 Check for declarations of VLA of undefined or zero size.
142
143.. code-block:: c
144
145 void test() {
146 int x;
147 int vla1[x]; // warn: garbage as size
148 }
149
150 void test() {
151 int x = 0;
152 int vla2[x]; // warn: zero size
153 }
154
155core.uninitialized.ArraySubscript (C)
156"""""""""""""""""""""""""""""""""""""
157Check for uninitialized values used as array subscripts.
158
159.. code-block:: c
160
161 void test() {
162 int i, a[10];
163 int x = a[i]; // warn: array subscript is undefined
164 }
165
166core.uninitialized.Assign (C)
167"""""""""""""""""""""""""""""
168Check for assigning uninitialized values.
169
170.. code-block:: c
171
172 void test() {
173 int x;
174 x |= 1; // warn: left expression is uninitialized
175 }
176
177core.uninitialized.Branch (C)
178"""""""""""""""""""""""""""""
179Check for uninitialized values used as branch conditions.
180
181.. code-block:: c
182
183 void test() {
184 int x;
185 if (x) // warn
186 return;
187 }
188
189core.uninitialized.CapturedBlockVariable (C)
190""""""""""""""""""""""""""""""""""""""""""""
191Check for blocks that capture uninitialized values.
192
193.. code-block:: c
194
195 void test() {
196 int x;
197 ^{ int y = x; }(); // warn
198 }
199
200core.uninitialized.UndefReturn (C)
201""""""""""""""""""""""""""""""""""
202Check for uninitialized values being returned to the caller.
203
204.. code-block:: c
205
206 int test() {
207 int x;
208 return x; // warn
209 }
210
211.. _cplusplus-checkers:
212
213
214cpluslus
215^^^^^^^^
216
217C++ Checkers.
218
219cplusplus.InnerPointer
220""""""""""""""""""""""
221Check for inner pointers of C++ containers used after re/deallocation.
222
223cplusplus.NewDelete (C++)
224"""""""""""""""""""""""""
225Check for double-free and use-after-free problems. Traces memory managed by new/delete.
226
227.. literalinclude:: checkers/newdelete_example.cpp
228 :language: cpp
229
230cplusplus.NewDeleteLeaks (C++)
231""""""""""""""""""""""""""""""
232Check for memory leaks. Traces memory managed by new/delete.
233
234.. code-block:: cpp
235
236 void test() {
237 int *p = new int;
238 } // warn
239
240
241cplusplus.SelfAssignment (C++)
242""""""""""""""""""""""""""""""
243Checks C++ copy and move assignment operators for self assignment.
244
245.. _deadcode-checkers:
246
247deadcode
248^^^^^^^^
249
250Dead Code Checkers.
251
252deadcode.DeadStores (C)
253"""""""""""""""""""""""
254Check for values stored to variables that are never read afterwards.
255
256.. code-block:: c
257
258 void test() {
259 int x;
260 x = 1; // warn
261 }
262
263.. _nullability-checkers:
264
265nullability
266^^^^^^^^^^^
267
268Objective C checkers that warn for null pointer passing and dereferencing errors.
269
270nullability.NullPassedToNonnull (ObjC)
271""""""""""""""""""""""""""""""""""""""
272Warns when a null pointer is passed to a pointer which has a _Nonnull type.
273
274.. code-block:: objc
275
276 if (name != nil)
277 return;
278 // Warning: nil passed to a callee that requires a non-null 1st parameter
279 NSString *greeting = [@"Hello " stringByAppendingString:name];
280
281nullability.NullReturnedFromNonnull (ObjC)
282""""""""""""""""""""""""""""""""""""""""""
283Warns when a null pointer is returned from a function that has _Nonnull return type.
284
285.. code-block:: objc
286
287 - (nonnull id)firstChild {
288 id result = nil;
289 if ([_children count] > 0)
290 result = _children[0];
291
292 // Warning: nil returned from a method that is expected
293 // to return a non-null value
294 return result;
295 }
296
297nullability.NullableDereferenced (ObjC)
298"""""""""""""""""""""""""""""""""""""""
299Warns when a nullable pointer is dereferenced.
300
301.. code-block:: objc
302
303 struct LinkedList {
304 int data;
305 struct LinkedList *next;
306 };
307
308 struct LinkedList * _Nullable getNext(struct LinkedList *l);
309
310 void updateNextData(struct LinkedList *list, int newData) {
311 struct LinkedList *next = getNext(list);
312 // Warning: Nullable pointer is dereferenced
313 next->data = 7;
314 }
315
316nullability.NullablePassedToNonnull (ObjC)
317""""""""""""""""""""""""""""""""""""""""""
318Warns when a nullable pointer is passed to a pointer which has a _Nonnull type.
319
320.. code-block:: objc
321
322 typedef struct Dummy { int val; } Dummy;
323 Dummy *_Nullable returnsNullable();
324 void takesNonnull(Dummy *_Nonnull);
325
326 void test() {
327 Dummy *p = returnsNullable();
328 takesNonnull(p); // warn
329 }
330
331nullability.NullableReturnedFromNonnull (ObjC)
332""""""""""""""""""""""""""""""""""""""""""""""
333Warns when a nullable pointer is returned from a function that has _Nonnull return type.
334
335.. _optin-checkers:
336
337optin
338^^^^^
339
340Checkers for portability, performance or coding style specific rules.
341
342optin.cplusplus.VirtualCall (C++)
343"""""""""""""""""""""""""""""""""
344Check virtual function calls during construction or destruction.
345
346.. code-block:: cpp
347
348 class A {
349 public:
350 A() {
351 f(); // warn
352 }
353 virtual void f();
354 };
355
356 class A {
357 public:
358 ~A() {
359 this->f(); // warn
360 }
361 virtual void f();
362 };
363
364optin.mpi.MPI-Checker (C)
365"""""""""""""""""""""""""
366Checks MPI code.
367
368.. code-block:: c
369
370 void test() {
371 double buf = 0;
372 MPI_Request sendReq1;
373 MPI_Ireduce(MPI_IN_PLACE, &buf, 1, MPI_DOUBLE, MPI_SUM,
374 0, MPI_COMM_WORLD, &sendReq1);
375 } // warn: request 'sendReq1' has no matching wait.
376
377 void test() {
378 double buf = 0;
379 MPI_Request sendReq;
380 MPI_Isend(&buf, 1, MPI_DOUBLE, 0, 0, MPI_COMM_WORLD, &sendReq);
381 MPI_Irecv(&buf, 1, MPI_DOUBLE, 0, 0, MPI_COMM_WORLD, &sendReq); // warn
382 MPI_Isend(&buf, 1, MPI_DOUBLE, 0, 0, MPI_COMM_WORLD, &sendReq); // warn
383 MPI_Wait(&sendReq, MPI_STATUS_IGNORE);
384 }
385
386 void missingNonBlocking() {
387 int rank = 0;
388 MPI_Comm_rank(MPI_COMM_WORLD, &rank);
389 MPI_Request sendReq1[10][10][10];
390 MPI_Wait(&sendReq1[1][7][9], MPI_STATUS_IGNORE); // warn
391 }
392
393optin.osx.cocoa.localizability.EmptyLocalizationContextChecker (ObjC)
394"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
395Check that NSLocalizedString macros include a comment for context.
396
397.. code-block:: objc
398
399 - (void)test {
400 NSString *string = NSLocalizedString(@"LocalizedString", nil); // warn
401 NSString *string2 = NSLocalizedString(@"LocalizedString", @" "); // warn
402 NSString *string3 = NSLocalizedStringWithDefaultValue(
403 @"LocalizedString", nil, [[NSBundle alloc] init], nil,@""); // warn
404 }
405
406optin.osx.cocoa.localizability.NonLocalizedStringChecker (ObjC)
407"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
408Warns about uses of non-localized NSStrings passed to UI methods expecting localized NSStrings.
409
410.. code-block:: objc
411
412 NSString *alarmText =
413 NSLocalizedString(@"Enabled", @"Indicates alarm is turned on");
414 if (!isEnabled) {
415 alarmText = @"Disabled";
416 }
417 UILabel *alarmStateLabel = [[UILabel alloc] init];
418
419 // Warning: User-facing text should use localized string macro
420 [alarmStateLabel setText:alarmText];
421
422optin.performance.GCDAntipattern
423""""""""""""""""""""""""""""""""
424Check for performance anti-patterns when using Grand Central Dispatch.
425
426optin.performance.Padding
427"""""""""""""""""""""""""
428Check for excessively padded structs.
429
430optin.portability.UnixAPI
431"""""""""""""""""""""""""
432Finds implementation-defined behavior in UNIX/Posix functions.
433
434
435.. _security-checkers:
436
437security
438^^^^^^^^
439
440Security related checkers.
441
442security.FloatLoopCounter (C)
443"""""""""""""""""""""""""""""
444Warn on using a floating point value as a loop counter (CERT: FLP30-C, FLP30-CPP).
445
446.. code-block:: c
447
448 void test() {
449 for (float x = 0.1f; x <= 1.0f; x += 0.1f) {} // warn
450 }
451
452security.insecureAPI.UncheckedReturn (C)
453""""""""""""""""""""""""""""""""""""""""
454Warn on uses of functions whose return values must be always checked.
455
456.. code-block:: c
457
458 void test() {
459 setuid(1); // warn
460 }
461
462security.insecureAPI.bcmp (C)
463"""""""""""""""""""""""""""""
464Warn on uses of the 'bcmp' function.
465
466.. code-block:: c
467
468 void test() {
469 bcmp(ptr0, ptr1, n); // warn
470 }
471
472security.insecureAPI.bcopy (C)
473""""""""""""""""""""""""""""""
474Warn on uses of the 'bcopy' function.
475
476.. code-block:: c
477
478 void test() {
479 bcopy(src, dst, n); // warn
480 }
481
482security.insecureAPI.bzero (C)
483""""""""""""""""""""""""""""""
484Warn on uses of the 'bzero' function.
485
486.. code-block:: c
487
488 void test() {
489 bzero(ptr, n); // warn
490 }
491
492security.insecureAPI.getpw (C)
493""""""""""""""""""""""""""""""
494Warn on uses of the 'getpw' function.
495
496.. code-block:: c
497
498 void test() {
499 char buff[1024];
500 getpw(2, buff); // warn
501 }
502
503security.insecureAPI.gets (C)
504"""""""""""""""""""""""""""""
505Warn on uses of the 'gets' function.
506
507.. code-block:: c
508
509 void test() {
510 char buff[1024];
511 gets(buff); // warn
512 }
513
514security.insecureAPI.mkstemp (C)
515""""""""""""""""""""""""""""""""
516Warn when 'mkstemp' is passed fewer than 6 X's in the format string.
517
518.. code-block:: c
519
520 void test() {
521 mkstemp("XX"); // warn
522 }
523
524security.insecureAPI.mktemp (C)
525"""""""""""""""""""""""""""""""
526Warn on uses of the ``mktemp`` function.
527
528.. code-block:: c
529
530 void test() {
531 char *x = mktemp("/tmp/zxcv"); // warn: insecure, use mkstemp
532 }
533
534security.insecureAPI.rand (C)
535"""""""""""""""""""""""""""""
536Warn on uses of inferior random number generating functions (only if arc4random function is available):
537``drand48, erand48, jrand48, lcong48, lrand48, mrand48, nrand48, random, rand_r``.
538
539.. code-block:: c
540
541 void test() {
542 random(); // warn
543 }
544
545security.insecureAPI.strcpy (C)
546"""""""""""""""""""""""""""""""
547Warn on uses of the ``strcpy`` and ``strcat`` functions.
548
549.. code-block:: c
550
551 void test() {
552 char x[4];
553 char *y = "abcd";
554
555 strcpy(x, y); // warn
556 }
557
558
559security.insecureAPI.vfork (C)
560""""""""""""""""""""""""""""""
561 Warn on uses of the 'vfork' function.
562
563.. code-block:: c
564
565 void test() {
566 vfork(); // warn
567 }
568
569.. _unix-checkers:
570
571unix
572^^^^
573POSIX/Unix checkers.
574
575unix.API (C)
576""""""""""""
577Check calls to various UNIX/Posix functions: ``open, pthread_once, calloc, malloc, realloc, alloca``.
578
579.. literalinclude:: checkers/unix_api_example.c
580 :language: c
581
582unix.Malloc (C)
583"""""""""""""""
584Check for memory leaks, double free, and use-after-free problems. Traces memory managed by malloc()/free().
585
586.. literalinclude:: checkers/unix_malloc_example.c
587 :language: c
588
589unix.MallocSizeof (C)
590"""""""""""""""""""""
591Check for dubious ``malloc`` arguments involving ``sizeof``.
592
593.. code-block:: c
594
595 void test() {
596 long *p = malloc(sizeof(short));
597 // warn: result is converted to 'long *', which is
598 // incompatible with operand type 'short'
599 free(p);
600 }
601
602unix.MismatchedDeallocator (C, C++)
603"""""""""""""""""""""""""""""""""""
604Check for mismatched deallocators.
605
606.. literalinclude:: checkers/mismatched_deallocator_example.cpp
607 :language: c
608
609unix.Vfork (C)
610""""""""""""""
611Check for proper usage of ``vfork``.
612
613.. code-block:: c
614
615 int test(int x) {
616 pid_t pid = vfork(); // warn
617 if (pid != 0)
618 return 0;
619
620 switch (x) {
621 case 0:
622 pid = 1;
623 execl("", "", 0);
624 _exit(1);
625 break;
626 case 1:
627 x = 0; // warn: this assignment is prohibited
628 break;
629 case 2:
630 foo(); // warn: this function call is prohibited
631 break;
632 default:
633 return 0; // warn: return is prohibited
634 }
635
636 while(1);
637 }
638
639unix.cstring.BadSizeArg (C)
640"""""""""""""""""""""""""""
641Check 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.
642
643.. code-block:: c
644
645 void test() {
646 char dest[3];
647 strncat(dest, """""""""""""""""""""""""*", sizeof(dest));
648 // warn: potential buffer overflow
649 }
650
651unix.cstrisng.NullArg (C)
652"""""""""""""""""""""""""
653Check for null pointers being passed as arguments to C string functions:
654``strlen, strnlen, strcpy, strncpy, strcat, strncat, strcmp, strncmp, strcasecmp, strncasecmp``.
655
656.. code-block:: c
657
658 int test() {
659 return strlen(0); // warn
660 }
661
662.. _osx-checkers:
663
664osx
665^^^
666OS X checkers.
667
668osx.API (C)
669"""""""""""
670Check for proper uses of various Apple APIs.
671
672.. code-block:: objc
673
674 void test() {
675 dispatch_once_t pred = 0;
676 dispatch_once(&pred, ^(){}); // warn: dispatch_once uses local
677 }
678
679osx.NumberObjectConversion (C, C++, ObjC)
680"""""""""""""""""""""""""""""""""""""""""
681Check for erroneous conversions of objects representing numbers into numbers.
682
683.. code-block:: objc
684
685 NSNumber *photoCount = [albumDescriptor objectForKey:@"PhotoCount"];
686 // Warning: Comparing a pointer value of type 'NSNumber *'
687 // to a scalar integer value
688 if (photoCount > 0) {
689 [self displayPhotos];
690 }
691
692osx.ObjCProperty (ObjC)
693"""""""""""""""""""""""
694Check for proper uses of Objective-C properties.
695
696.. code-block:: objc
697
698 NSNumber *photoCount = [albumDescriptor objectForKey:@"PhotoCount"];
699 // Warning: Comparing a pointer value of type 'NSNumber *'
700 // to a scalar integer value
701 if (photoCount > 0) {
702 [self displayPhotos];
703 }
704
705
706osx.SecKeychainAPI (C)
707""""""""""""""""""""""
708Check for proper uses of Secure Keychain APIs.
709
710.. literalinclude:: checkers/seckeychainapi_example.m
711 :language: objc
712
713osx.cocoa.AtSync (ObjC)
714"""""""""""""""""""""""
715Check for nil pointers used as mutexes for @synchronized.
716
717.. code-block:: objc
718
719 void test(id x) {
720 if (!x)
721 @synchronized(x) {} // warn: nil value used as mutex
722 }
723
724 void test() {
725 id y;
726 @synchronized(y) {} // warn: uninitialized value used as mutex
727 }
728
729osx.cocoa.AutoreleaseWrite
730""""""""""""""""""""""""""
731Warn about potentially crashing writes to autoreleasing objects from different autoreleasing pools in Objective-C.
732
733osx.cocoa.ClassRelease (ObjC)
734"""""""""""""""""""""""""""""
735Check for sending 'retain', 'release', or 'autorelease' directly to a Class.
736
737.. code-block:: objc
738
739 @interface MyClass : NSObject
740 @end
741
742 void test(void) {
743 [MyClass release]; // warn
744 }
745
746osx.cocoa.Dealloc (ObjC)
747""""""""""""""""""""""""
748Warn about Objective-C classes that lack a correct implementation of -dealloc
749
750.. literalinclude:: checkers/dealloc_example.m
751 :language: objc
752
753osx.cocoa.IncompatibleMethodTypes (ObjC)
754""""""""""""""""""""""""""""""""""""""""
755Warn about Objective-C method signatures with type incompatibilities.
756
757.. code-block:: objc
758
759 @interface MyClass1 : NSObject
760 - (int)foo;
761 @end
762
763 @implementation MyClass1
764 - (int)foo { return 1; }
765 @end
766
767 @interface MyClass2 : MyClass1
768 - (float)foo;
769 @end
770
771 @implementation MyClass2
772 - (float)foo { return 1.0; } // warn
773 @end
774
775osx.cocoa.Loops
776"""""""""""""""
777Improved modeling of loops using Cocoa collection types.
778
779osx.cocoa.MissingSuperCall (ObjC)
780"""""""""""""""""""""""""""""""""
781Warn about Objective-C methods that lack a necessary call to super.
782
783.. code-block:: objc
784
785 @interface Test : UIViewController
786 @end
787 @implementation test
788 - (void)viewDidLoad {} // warn
789 @end
790
791
792osx.cocoa.NSAutoreleasePool (ObjC)
793""""""""""""""""""""""""""""""""""
794Warn for suboptimal uses of NSAutoreleasePool in Objective-C GC mode.
795
796.. code-block:: objc
797
798 void test() {
799 NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
800 [pool release]; // warn
801 }
802
803osx.cocoa.NSError (ObjC)
804""""""""""""""""""""""""
805Check usage of NSError parameters.
806
807.. code-block:: objc
808
809 @interface A : NSObject
810 - (void)foo:(NSError """""""""""""""""""""""")error;
811 @end
812
813 @implementation A
814 - (void)foo:(NSError """""""""""""""""""""""")error {
815 // warn: method accepting NSError"""""""""""""""""""""""" should have a non-void
816 // return value
817 }
818 @end
819
820 @interface A : NSObject
821 - (BOOL)foo:(NSError """""""""""""""""""""""")error;
822 @end
823
824 @implementation A
825 - (BOOL)foo:(NSError """""""""""""""""""""""")error {
826 *error = 0; // warn: potential null dereference
827 return 0;
828 }
829 @end
830
831osx.cocoa.NilArg (ObjC)
832"""""""""""""""""""""""
833Check for prohibited nil arguments to ObjC method calls.
834
835 - caseInsensitiveCompare:
836 - compare:
837 - compare:options:
838 - compare:options:range:
839 - compare:options:range:locale:
840 - componentsSeparatedByCharactersInSet:
841 - initWithFormat:
842
843.. code-block:: objc
844
845 NSComparisonResult test(NSString *s) {
846 NSString *aString = nil;
847 return [s caseInsensitiveCompare:aString];
848 // warn: argument to 'NSString' method
849 // 'caseInsensitiveCompare:' cannot be nil
850 }
851
852
853osx.cocoa.NonNilReturnValue
854"""""""""""""""""""""""""""
855Models the APIs that are guaranteed to return a non-nil value.
856
857osx.cocoa.ObjCGenerics (ObjC)
858"""""""""""""""""""""""""""""
859Check for type errors when using Objective-C generics.
860
861.. code-block:: objc
862
863 NSMutableArray *names = [NSMutableArray array];
864 NSMutableArray *birthDates = names;
865
866 // Warning: Conversion from value of type 'NSDate *'
867 // to incompatible type 'NSString *'
868 [birthDates addObject: [NSDate date]];
869
870osx.cocoa.RetainCount (ObjC)
871""""""""""""""""""""""""""""
872Check for leaks and improper reference count management
873
874.. code-block:: objc
875
876 void test() {
877 NSString *s = [[NSString alloc] init]; // warn
878 }
879
880 CFStringRef test(char *bytes) {
881 return CFStringCreateWithCStringNoCopy(
882 0, bytes, NSNEXTSTEPStringEncoding, 0); // warn
883 }
884
885
886osx.cocoa.RunLoopAutoreleaseLeak
887""""""""""""""""""""""""""""""""
888Check for leaked memory in autorelease pools that will never be drained.
889
890osx.cocoa.SelfInit (ObjC)
891"""""""""""""""""""""""""
892Check that 'self' is properly initialized inside an initializer method.
893
894.. code-block:: objc
895
896 @interface MyObj : NSObject {
897 id x;
898 }
899 - (id)init;
900 @end
901
902 @implementation MyObj
903 - (id)init {
904 [super init];
905 x = 0; // warn: instance variable used while 'self' is not
906 // initialized
907 return 0;
908 }
909 @end
910
911 @interface MyObj : NSObject
912 - (id)init;
913 @end
914
915 @implementation MyObj
916 - (id)init {
917 [super init];
918 return self; // warn: returning uninitialized 'self'
919 }
920 @end
921
922osx.cocoa.SuperDealloc (ObjC)
923"""""""""""""""""""""""""""""
924Warn about improper use of '[super dealloc]' in Objective-C.
925
926.. code-block:: objc
927
928 @interface SuperDeallocThenReleaseIvarClass : NSObject {
929 NSObject *_ivar;
930 }
931 @end
932
933 @implementation SuperDeallocThenReleaseIvarClass
934 - (void)dealloc {
935 [super dealloc];
936 [_ivar release]; // warn
937 }
938 @end
939
940osx.cocoa.UnusedIvars (ObjC)
941""""""""""""""""""""""""""""
942Warn about private ivars that are never used.
943
944.. code-block:: objc
945
946 @interface MyObj : NSObject {
947 @private
948 id x; // warn
949 }
950 @end
951
952 @implementation MyObj
953 @end
954
955osx.cocoa.VariadicMethodTypes (ObjC)
956""""""""""""""""""""""""""""""""""""
957Check for passing non-Objective-C types to variadic collection
958initialization methods that expect only Objective-C types.
959
960.. code-block:: objc
961
962 void test() {
963 [NSSet setWithObjects:@"Foo", "Bar", nil];
964 // warn: argument should be an ObjC pointer type, not 'char *'
965 }
966
967osx.coreFoundation.CFError (C)
968""""""""""""""""""""""""""""""
969Check usage of CFErrorRef* parameters
970
971.. code-block:: c
972
973 void test(CFErrorRef *error) {
974 // warn: function accepting CFErrorRef* should have a
975 // non-void return
976 }
977
978 int foo(CFErrorRef *error) {
979 *error = 0; // warn: potential null dereference
980 return 0;
981 }
982
983osx.coreFoundation.CFNumber (C)
984"""""""""""""""""""""""""""""""
985Check for proper uses of CFNumber APIs.
986
987.. code-block:: c
988
989 CFNumberRef test(unsigned char x) {
990 return CFNumberCreate(0, kCFNumberSInt16Type, &x);
991 // warn: 8 bit integer is used to initialize a 16 bit integer
992 }
993
994osx.coreFoundation.CFRetainRelease (C)
995""""""""""""""""""""""""""""""""""""""
996Check for null arguments to CFRetain/CFRelease/CFMakeCollectable.
997
998.. code-block:: c
999
1000 void test(CFTypeRef p) {
1001 if (!p)
1002 CFRetain(p); // warn
1003 }
1004
1005 void test(int x, CFTypeRef p) {
1006 if (p)
1007 return;
1008
1009 CFRelease(p); // warn
1010 }
1011
1012osx.coreFoundation.containers.OutOfBounds (C)
1013"""""""""""""""""""""""""""""""""""""""""""""
1014Checks for index out-of-bounds when using 'CFArray' API.
1015
1016.. code-block:: c
1017
1018 void test() {
1019 CFArrayRef A = CFArrayCreate(0, 0, 0, &kCFTypeArrayCallBacks);
1020 CFArrayGetValueAtIndex(A, 0); // warn
1021 }
1022
1023osx.coreFoundation.containers.PointerSizedValues (C)
1024""""""""""""""""""""""""""""""""""""""""""""""""""""
1025Warns if 'CFArray', 'CFDictionary', 'CFSet' are created with non-pointer-size values.
1026
1027.. code-block:: c
1028
1029 void test() {
1030 int x[] = { 1 };
1031 CFArrayRef A = CFArrayCreate(0, (const void """""""""""""""""""""""")x, 1,
1032 &kCFTypeArrayCallBacks); // warn
1033 }
1034
1035
1036.. _alpha-checkers:
1037
1038Experimental Checkers
1039---------------------
1040
1041*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.*
1042
1043alpha.clone
1044^^^^^^^^^^^
1045
1046alpha.clone.CloneChecker (C, C++, ObjC)
1047"""""""""""""""""""""""""""""""""""""""
1048Reports similar pieces of code.
1049
1050.. code-block:: c
1051
1052 void log();
1053
1054 int max(int a, int b) { // warn
1055 log();
1056 if (a > b)
1057 return a;
1058 return b;
1059 }
1060
1061 int maxClone(int x, int y) { // similar code here
1062 log();
1063 if (x > y)
1064 return x;
1065 return y;
1066 }
1067
1068alpha.core.BoolAssignment (ObjC)
1069""""""""""""""""""""""""""""""""
1070Warn about assigning non-{0,1} values to boolean variables.
1071
1072.. code-block:: objc
1073
1074 void test() {
1075 BOOL b = -1; // warn
1076 }
1077
1078alpha.core
1079^^^^^^^^^^
1080
1081alpha.core.CallAndMessageUnInitRefArg (C,C++, ObjC)
1082"""""""""""""""""""""""""""""""""""""""""""""""""""
1083Check for logical errors for function calls and Objective-C
1084message expressions (e.g., uninitialized arguments, null function pointers, and pointer to undefined variables).
1085
1086.. code-block:: c
1087
1088 void test(void) {
1089 int t;
1090 int &p = t;
1091 int &s = p;
1092 int &q = s;
1093 foo(q); // warn
1094 }
1095
1096 void test(void) {
1097 int x;
1098 foo(&x); // warn
1099 }
1100
1101alpha.core.CastSize (C)
1102"""""""""""""""""""""""
1103Check when casting a malloc'ed type ``T``, whether the size is a multiple of the size of ``T``.
1104
1105.. code-block:: c
1106
1107 void test() {
1108 int *x = (int *) malloc(11); // warn
1109 }
1110
1111alpha.core.CastToStruct (C, C++)
1112""""""""""""""""""""""""""""""""
1113Check for cast from non-struct pointer to struct pointer.
1114
1115.. code-block:: cpp
1116
1117 // C
1118 struct s {};
1119
1120 void test(int *p) {
1121 struct s *ps = (struct s *) p; // warn
1122 }
1123
1124 // C++
1125 class c {};
1126
1127 void test(int *p) {
1128 c *pc = (c *) p; // warn
1129 }
1130
1131alpha.core.Conversion (C, C++, ObjC)
1132""""""""""""""""""""""""""""""""""""
1133Loss of sign/precision in implicit conversions.
1134
1135.. code-block:: c
1136
1137 void test(unsigned U, signed S) {
1138 if (S > 10) {
1139 if (U < S) {
1140 }
1141 }
1142 if (S < -10) {
1143 if (U < S) { // warn (loss of sign)
1144 }
1145 }
1146 }
1147
1148 void test() {
1149 long long A = 1LL << 60;
1150 short X = A; // warn (loss of precision)
1151 }
1152
1153alpha.core.DynamicTypeChecker (ObjC)
1154""""""""""""""""""""""""""""""""""""
1155Check for cases where the dynamic and the static type of an object are unrelated.
1156
1157
1158.. code-block:: objc
1159
1160 id date = [NSDate date];
1161
1162 // Warning: Object has a dynamic type 'NSDate *' which is
1163 // incompatible with static type 'NSNumber *'"
1164 NSNumber *number = date;
1165 [number doubleValue];
1166
1167alpha.core.FixedAddr (C)
1168""""""""""""""""""""""""
1169Check for assignment of a fixed address to a pointer.
1170
1171.. code-block:: c
1172
1173 void test() {
1174 int *p;
1175 p = (int *) 0x10000; // warn
1176 }
1177
1178alpha.core.IdenticalExpr (C, C++)
1179"""""""""""""""""""""""""""""""""
1180Warn about unintended use of identical expressions in operators.
1181
1182.. code-block:: cpp
1183
1184 // C
1185 void test() {
1186 int a = 5;
1187 int b = a | 4 | a; // warn: identical expr on both sides
1188 }
1189
1190 // C++
1191 bool f(void);
1192
1193 void test(bool b) {
1194 int i = 10;
1195 if (f()) { // warn: true and false branches are identical
1196 do {
1197 i--;
1198 } while (f());
1199 } else {
1200 do {
1201 i--;
1202 } while (f());
1203 }
1204 }
1205
1206alpha.core.PointerArithm (C)
1207""""""""""""""""""""""""""""
1208Check for pointer arithmetic on locations other than array elements.
1209
1210.. code-block:: c
1211
1212 void test() {
1213 int x;
1214 int *p;
1215 p = &x + 1; // warn
1216 }
1217
1218alpha.core.PointerSub (C)
1219"""""""""""""""""""""""""
1220Check for pointer subtractions on two pointers pointing to different memory chunks.
1221
1222.. code-block:: c
1223
1224 void test() {
1225 int x, y;
1226 int d = &y - &x; // warn
1227 }
1228
1229alpha.core.SizeofPtr (C)
1230""""""""""""""""""""""""
1231Warn about unintended use of ``sizeof()`` on pointer expressions.
1232
1233.. code-block:: c
1234
1235 struct s {};
1236
1237 int test(struct s *p) {
1238 return sizeof(p);
1239 // warn: sizeof(ptr) can produce an unexpected result
1240 }
1241
1242alpha.core.StackAddressAsyncEscape (C)
1243""""""""""""""""""""""""""""""""""""""
1244Check that addresses to stack memory do not escape the function that involves dispatch_after or dispatch_async.
1245This checker is a part of ``core.StackAddressEscape``, but is temporarily disabled until some false positives are fixed.
1246
1247.. code-block:: c
1248
1249 dispatch_block_t test_block_inside_block_async_leak() {
1250 int x = 123;
1251 void (^inner)(void) = ^void(void) {
1252 int y = x;
1253 ++y;
1254 };
1255 void (^outer)(void) = ^void(void) {
1256 int z = x;
1257 ++z;
1258 inner();
1259 };
1260 return outer; // warn: address of stack-allocated block is captured by a
1261 // returned block
1262 }
1263
1264alpha.core.TestAfterDivZero (C)
1265"""""""""""""""""""""""""""""""
1266Check for division by variable that is later compared against 0.
1267Either the comparison is useless or there is division by zero.
1268
1269.. code-block:: c
1270
1271 void test(int x) {
1272 var = 77 / x;
1273 if (x == 0) { } // warn
1274 }
1275
1276alpha.cplusplus
1277^^^^^^^^^^^^^^^
1278
1279alpha.cplusplus.DeleteWithNonVirtualDtor (C++)
1280""""""""""""""""""""""""""""""""""""""""""""""
1281Reports destructions of polymorphic objects with a non-virtual destructor in their base class.
1282
1283.. code-block:: cpp
1284
1285 NonVirtual *create() {
1286 NonVirtual *x = new NVDerived(); // note: conversion from derived to base
1287 // happened here
1288 return x;
1289 }
1290
1291 void sink(NonVirtual *x) {
1292 delete x; // warn: destruction of a polymorphic object with no virtual
1293 // destructor
1294 }
1295
1296alpha.cplusplus.EnumCastOutOfRange (C++)
1297""""""""""""""""""""""""""""""""""""""""
1298Check for integer to enumeration casts that could result in undefined values.
1299
1300.. code-block:: cpp
1301
1302 enum TestEnum {
1303 A = 0
1304 };
1305
1306 void foo() {
1307 TestEnum t = static_cast(-1);
1308 // warn: the value provided to the cast expression is not in
1309 the valid range of values for the enum
1310
1311alpha.cplusplus.InvalidatedIterator (C++)
1312"""""""""""""""""""""""""""""""""""""""""
1313Check for use of invalidated iterators.
1314
1315.. code-block:: cpp
1316
1317 void bad_copy_assign_operator_list1(std::list &L1,
1318 const std::list &L2) {
1319 auto i0 = L1.cbegin();
1320 L1 = L2;
1321 *i0; // warn: invalidated iterator accessed
1322 }
1323
1324
1325alpha.cplusplus.IteratorRange (C++)
1326"""""""""""""""""""""""""""""""""""
1327Check for iterators used outside their valid ranges.
1328
1329.. code-block:: cpp
1330
1331 void simple_bad_end(const std::vector &v) {
1332 auto i = v.end();
1333 *i; // warn: iterator accessed outside of its range
1334 }
1335
1336alpha.cplusplus.MismatchedIterator (C++)
1337""""""""""""""""""""""""""""""""""""""""
1338Check for use of iterators of different containers where iterators of the same container are expected.
1339
1340.. code-block:: cpp
1341
1342 void bad_insert3(std::vector &v1, std::vector &v2) {
1343 v2.insert(v1.cbegin(), v2.cbegin(), v2.cend()); // warn: container accessed
1344 // using foreign
1345 // iterator argument
1346 v1.insert(v1.cbegin(), v1.cbegin(), v2.cend()); // warn: iterators of
1347 // different containers
1348 // used where the same
1349 // container is
1350 // expected
1351 v1.insert(v1.cbegin(), v2.cbegin(), v1.cend()); // warn: iterators of
1352 // different containers
1353 // used where the same
1354 // container is
1355 // expected
1356 }
1357
1358alpha.cplusplus.MisusedMovedObject (C++)
1359""""""""""""""""""""""""""""""""""""""""
1360Method calls on a moved-from object and copying a moved-from object will be reported.
1361
1362
1363.. code-block:: cpp
1364
1365 struct A {
1366 void foo() {}
1367 };
1368
1369 void f() {
1370 A a;
1371 A b = std::move(a); // note: 'a' became 'moved-from' here
1372 a.foo(); // warn: method call on a 'moved-from' object 'a'
1373 }
1374
1375alpha.cplusplus.UninitializedObject (C++)
1376"""""""""""""""""""""""""""""""""""""""""
1377
1378This checker reports uninitialized fields in objects created after a constructor call.
1379It doesn't only find direct uninitialized fields, but rather makes a deep inspection
1380of the object, analyzing all of it's fields subfields.
1381The checker regards inherited fields as direct fields, so one will
1382recieve warnings for uninitialized inherited data members as well.
1383
1384.. code-block:: cpp
1385
1386 // With Pedantic and CheckPointeeInitialization set to true
1387
1388 struct A {
1389 struct B {
1390 int x; // note: uninitialized field 'this->b.x'
1391 // note: uninitialized field 'this->bptr->x'
1392 int y; // note: uninitialized field 'this->b.y'
1393 // note: uninitialized field 'this->bptr->y'
1394 };
1395 int *iptr; // note: uninitialized pointer 'this->iptr'
1396 B b;
1397 B *bptr;
1398 char *cptr; // note: uninitialized pointee 'this->cptr'
1399
1400 A (B *bptr, char *cptr) : bptr(bptr), cptr(cptr) {}
1401 };
1402
1403 void f() {
1404 A::B b;
1405 char c;
1406 A a(&b, &c); // warning: 6 uninitialized fields
1407 // after the constructor call
1408 }
1409
1410 // With Pedantic set to false and
1411 // CheckPointeeInitialization set to true
1412 // (every field is uninitialized)
1413
1414 struct A {
1415 struct B {
1416 int x;
1417 int y;
1418 };
1419 int *iptr;
1420 B b;
1421 B *bptr;
1422 char *cptr;
1423
1424 A (B *bptr, char *cptr) : bptr(bptr), cptr(cptr) {}
1425 };
1426
1427 void f() {
1428 A::B b;
1429 char c;
1430 A a(&b, &c); // no warning
1431 }
1432
1433 // With Pedantic set to true and
1434 // CheckPointeeInitialization set to false
1435 // (pointees are regarded as initialized)
1436
1437 struct A {
1438 struct B {
1439 int x; // note: uninitialized field 'this->b.x'
1440 int y; // note: uninitialized field 'this->b.y'
1441 };
1442 int *iptr; // note: uninitialized pointer 'this->iptr'
1443 B b;
1444 B *bptr;
1445 char *cptr;
1446
1447 A (B *bptr, char *cptr) : bptr(bptr), cptr(cptr) {}
1448 };
1449
1450 void f() {
1451 A::B b;
1452 char c;
1453 A a(&b, &c); // warning: 3 uninitialized fields
1454 // after the constructor call
1455 }
1456
1457
1458**Options**
1459
1460This checker has several options which can be set from command line (e.g. ``-analyzer-config alpha.cplusplus.UninitializedObject:Pedantic=true``):
1461
1462* ``Pedantic`` (boolean). If to false, the checker won't emit warnings for objects that don't have at least one initialized field. Defaults to false.
1463
1464* ``NotesAsWarnings`` (boolean). If set to true, the checker will emit a warning for each uninitalized field, as opposed to emitting one warning per constructor call, and listing the uninitialized fields that belongs to it in notes. *Defaults to false.*.
1465
1466* ``CheckPointeeInitialization`` (boolean). If set to false, the checker will not analyze the pointee of pointer/reference fields, and will only check whether the object itself is initialized. *Defaults to false.*.
1467
1468* ``IgnoreRecordsWithField`` (string). If supplied, the checker will not analyze structures that have a field with a name or type name that matches the given pattern. *Defaults to ""*. Can be set with ``-analyzer-config alpha.cplusplus.UninitializedObject:IgnoreRecordsWithField="[Tt]ag|[Kk]ind"``.
1469
1470
1471alpha.deadcode
1472^^^^^^^^^^^^^^
1473alpha.deadcode.UnreachableCode (C, C++)
1474"""""""""""""""""""""""""""""""""""""""
1475Check unreachable code.
1476
1477.. code-block:: cpp
1478
1479 // C
1480 int test() {
1481 int x = 1;
1482 while(x);
1483 return x; // warn
1484 }
1485
1486 // C++
1487 void test() {
1488 int a = 2;
1489
1490 while (a > 1)
1491 a--;
1492
1493 if (a > 1)
1494 a++; // warn
1495 }
1496
1497 // Objective-C
1498 void test(id x) {
1499 return;
1500 [x retain]; // warn
1501 }
1502
1503alpha.llvm
1504^^^^^^^^^^
1505
1506alpha.llvm.Conventions
1507""""""""""""""""""""""
1508
1509Check code for LLVM codebase conventions:
1510
1511* A StringRef should not be bound to a temporary std::string whose lifetime is shorter than the StringRef's.
1512* Clang AST nodes should not have fields that can allocate memory.
1513
1514
1515alpha.osx
1516^^^^^^^^^
1517
1518alpha.osx.cocoa.DirectIvarAssignment (ObjC)
1519"""""""""""""""""""""""""""""""""""""""""""
1520Check for direct assignments to instance variables.
1521
1522
1523.. code-block:: objc
1524
1525 @interface MyClass : NSObject {}
1526 @property (readonly) id A;
1527 - (void) foo;
1528 @end
1529
1530 @implementation MyClass
1531 - (void) foo {
1532 _A = 0; // warn
1533 }
1534 @end
1535
1536alpha.osx.cocoa.DirectIvarAssignmentForAnnotatedFunctions (ObjC)
1537""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
1538Check for direct assignments to instance variables in
1539the methods annotated with ``objc_no_direct_instance_variable_assignment``.
1540
1541.. code-block:: objc
1542
1543 @interface MyClass : NSObject {}
1544 @property (readonly) id A;
1545 - (void) fAnnotated __attribute__((
1546 annotate("objc_no_direct_instance_variable_assignment")));
1547 - (void) fNotAnnotated;
1548 @end
1549
1550 @implementation MyClass
1551 - (void) fAnnotated {
1552 _A = 0; // warn
1553 }
1554 - (void) fNotAnnotated {
1555 _A = 0; // no warn
1556 }
1557 @end
1558
1559
1560alpha.osx.cocoa.InstanceVariableInvalidation (ObjC)
1561"""""""""""""""""""""""""""""""""""""""""""""""""""
1562Check that the invalidatable instance variables are
1563invalidated in the methods annotated with objc_instance_variable_invalidator.
1564
1565.. code-block:: objc
1566
1567 @protocol Invalidation <NSObject>
1568 - (void) invalidate
1569 __attribute__((annotate("objc_instance_variable_invalidator")));
1570 @end
1571
1572 @interface InvalidationImpObj : NSObject <Invalidation>
1573 @end
1574
1575 @interface SubclassInvalidationImpObj : InvalidationImpObj {
1576 InvalidationImpObj *var;
1577 }
1578 - (void)invalidate;
1579 @end
1580
1581 @implementation SubclassInvalidationImpObj
1582 - (void) invalidate {}
1583 @end
1584 // warn: var needs to be invalidated or set to nil
1585
1586alpha.osx.cocoa.MissingInvalidationMethod (ObjC)
1587""""""""""""""""""""""""""""""""""""""""""""""""
1588Check that the invalidation methods are present in classes that contain invalidatable instance variables.
1589
1590.. code-block:: objc
1591
1592 @protocol Invalidation <NSObject>
1593 - (void)invalidate
1594 __attribute__((annotate("objc_instance_variable_invalidator")));
1595 @end
1596
1597 @interface NeedInvalidation : NSObject <Invalidation>
1598 @end
1599
1600 @interface MissingInvalidationMethodDecl : NSObject {
1601 NeedInvalidation *Var; // warn
1602 }
1603 @end
1604
1605 @implementation MissingInvalidationMethodDecl
1606 @end
1607
1608alpha.osx.cocoa.localizability.PluralMisuseChecker (ObjC)
1609"""""""""""""""""""""""""""""""""""""""""""""""""""""""""
1610Warns against using one vs. many plural pattern in code when generating localized strings.
1611
1612.. code-block:: objc
1613
1614 NSString *reminderText =
1615 NSLocalizedString(@"None", @"Indicates no reminders");
1616 if (reminderCount == 1) {
1617 // Warning: Plural cases are not supported across all languages.
1618 // Use a .stringsdict file instead
1619 reminderText =
1620 NSLocalizedString(@"1 Reminder", @"Indicates single reminder");
1621 } else if (reminderCount >= 2) {
1622 // Warning: Plural cases are not supported across all languages.
1623 // Use a .stringsdict file instead
1624 reminderText =
1625 [NSString stringWithFormat:
1626 NSLocalizedString(@"%@ Reminders", @"Indicates multiple reminders"),
1627 reminderCount];
1628 }
1629
1630alpha.security
1631^^^^^^^^^^^^^^
1632alpha.security.ArrayBound (C)
1633"""""""""""""""""""""""""""""
1634Warn about buffer overflows (older checker).
1635
1636.. code-block:: c
1637
1638 void test() {
1639 char *s = "";
1640 char c = s[1]; // warn
1641 }
1642
1643 struct seven_words {
1644 int c[7];
1645 };
1646
1647 void test() {
1648 struct seven_words a, *p;
1649 p = &a;
1650 p[0] = a;
1651 p[1] = a;
1652 p[2] = a; // warn
1653 }
1654
1655 // note: requires unix.Malloc or
1656 // alpha.unix.MallocWithAnnotations checks enabled.
1657 void test() {
1658 int *p = malloc(12);
1659 p[3] = 4; // warn
1660 }
1661
1662 void test() {
1663 char a[2];
1664 int *b = (int*)a;
1665 b[1] = 3; // warn
1666 }
1667
1668alpha.security.ArrayBoundV2 (C)
1669"""""""""""""""""""""""""""""""
1670Warn about buffer overflows (newer checker).
1671
1672.. code-block:: c
1673
1674 void test() {
1675 char *s = "";
1676 char c = s[1]; // warn
1677 }
1678
1679 void test() {
1680 int buf[100];
1681 int *p = buf;
1682 p = p + 99;
1683 p[1] = 1; // warn
1684 }
1685
1686 // note: compiler has internal check for this.
1687 // Use -Wno-array-bounds to suppress compiler warning.
1688 void test() {
1689 int buf[100][100];
1690 buf[0][-1] = 1; // warn
1691 }
1692
1693 // note: requires alpha.security.taint check turned on.
1694 void test() {
1695 char s[] = "abc";
1696 int x = getchar();
1697 char c = s[x]; // warn: index is tainted
1698 }
1699
1700alpha.security.MallocOverflow (C)
1701"""""""""""""""""""""""""""""""""
1702Check for overflows in the arguments to malloc().
1703
1704.. code-block:: c
1705
1706 void test(int n) {
1707 void *p = malloc(n * sizeof(int)); // warn
1708 }
1709
1710alpha.security.MmapWriteExec (C)
1711""""""""""""""""""""""""""""""""
1712Warn on mmap() calls that are both writable and executable.
1713
1714.. code-block:: c
1715
1716 void test(int n) {
1717 void *c = mmap(NULL, 32, PROT_READ | PROT_WRITE | PROT_EXEC,
1718 MAP_PRIVATE | MAP_ANON, -1, 0);
1719 // warn: Both PROT_WRITE and PROT_EXEC flags are set. This can lead to
1720 // exploitable memory regions, which could be overwritten with malicious
1721 // code
1722 }
1723
1724alpha.security.ReturnPtrRange (C)
1725"""""""""""""""""""""""""""""""""
1726Check for an out-of-bound pointer being returned to callers.
1727
1728.. code-block:: c
1729
1730 static int A[10];
1731
1732 int *test() {
1733 int *p = A + 10;
1734 return p; // warn
1735 }
1736
1737 int test(void) {
1738 int x;
1739 return x; // warn: undefined or garbage returned
1740 }
1741
1742alpha.security.taint.TaintPropagation (C, C++)
1743""""""""""""""""""""""""""""""""""""""""""""""
1744Generate taint information used by other checkers.
1745A data is tainted when it comes from an unreliable source.
1746
1747.. code-block:: c
1748
1749 void test() {
1750 char x = getchar(); // 'x' marked as tainted
1751 system(&x); // warn: untrusted data is passed to a system call
1752 }
1753
1754 // note: compiler internally checks if the second param to
1755 // sprintf is a string literal or not.
1756 // Use -Wno-format-security to suppress compiler warning.
1757 void test() {
1758 char s[10], buf[10];
1759 fscanf(stdin, "%s", s); // 's' marked as tainted
1760
1761 sprintf(buf, s); // warn: untrusted data as a format string
1762 }
1763
1764 void test() {
1765 size_t ts;
1766 scanf("%zd", &ts); // 'ts' marked as tainted
1767 int *p = (int *)malloc(ts * sizeof(int));
1768 // warn: untrusted data as buffer size
1769 }
1770
1771alpha.unix
1772^^^^^^^^^^^
1773
1774alpha.unix.BlockInCriticalSection (C)
1775"""""""""""""""""""""""""""""""""""""
1776Check for calls to blocking functions inside a critical section.
1777Applies to: ``lock, unlock, sleep, getc, fgets, read, recv, pthread_mutex_lock,``
1778`` pthread_mutex_unlock, mtx_lock, mtx_timedlock, mtx_trylock, mtx_unlock, lock_guard, unique_lock``
1779
1780.. code-block:: c
1781
1782 void test() {
1783 std::mutex m;
1784 m.lock();
1785 sleep(3); // warn: a blocking function sleep is called inside a critical
1786 // section
1787 m.unlock();
1788 }
1789
1790alpha.unix.Chroot (C)
1791"""""""""""""""""""""
1792Check improper use of chroot.
1793
1794.. code-block:: c
1795
1796 void f();
1797
1798 void test() {
1799 chroot("/usr/local");
1800 f(); // warn: no call of chdir("/") immediately after chroot
1801 }
1802
1803alpha.unix.PthreadLock (C)
1804""""""""""""""""""""""""""
1805Simple lock -> unlock checker.
1806Applies to: ``pthread_mutex_lock, pthread_rwlock_rdlock, pthread_rwlock_wrlock, lck_mtx_lock, lck_rw_lock_exclusive``
1807``lck_rw_lock_shared, pthread_mutex_trylock, pthread_rwlock_tryrdlock, pthread_rwlock_tryrwlock, lck_mtx_try_lock,
1808lck_rw_try_lock_exclusive, lck_rw_try_lock_shared, pthread_mutex_unlock, pthread_rwlock_unlock, lck_mtx_unlock, lck_rw_done``.
1809
1810
1811.. code-block:: c
1812
1813 pthread_mutex_t mtx;
1814
1815 void test() {
1816 pthread_mutex_lock(&mtx);
1817 pthread_mutex_lock(&mtx);
1818 // warn: this lock has already been acquired
1819 }
1820
1821 lck_mtx_t lck1, lck2;
1822
1823 void test() {
1824 lck_mtx_lock(&lck1);
1825 lck_mtx_lock(&lck2);
1826 lck_mtx_unlock(&lck1);
1827 // warn: this was not the most recently acquired lock
1828 }
1829
1830 lck_mtx_t lck1, lck2;
1831
1832 void test() {
1833 if (lck_mtx_try_lock(&lck1) == 0)
1834 return;
1835
1836 lck_mtx_lock(&lck2);
1837 lck_mtx_unlock(&lck1);
1838 // warn: this was not the most recently acquired lock
1839 }
1840
1841alpha.unix.SimpleStream (C)
1842"""""""""""""""""""""""""""
1843Check for misuses of stream APIs. Check for misuses of stream APIs: ``fopen, fclose``
1844(demo checker, the subject of the demo (`Slides <http://llvm.org/devmtg/2012-11/Zaks-Rose-Checker24Hours.pdf>`_ ,
1845`Video <https://youtu.be/kdxlsP5QVPw>`_) by Anna Zaks and Jordan Rose presented at the
1846`2012 LLVM Developers' Meeting <http://llvm.org/devmtg/2012-11/>`_).
1847
1848.. code-block:: c
1849
1850 void test() {
1851 FILE *F = fopen("myfile.txt", "w");
1852 } // warn: opened file is never closed
1853
1854 void test() {
1855 FILE *F = fopen("myfile.txt", "w");
1856
1857 if (F)
1858 fclose(F);
1859
1860 fclose(F); // warn: closing a previously closed file stream
1861 }
1862
1863alpha.unix.Stream (C)
1864"""""""""""""""""""""
1865Check stream handling functions: ``fopen, tmpfile, fclose, fread, fwrite, fseek, ftell, rewind, fgetpos,``
1866``fsetpos, clearerr, feof, ferror, fileno``.
1867
1868.. code-block:: c
1869
1870 void test() {
1871 FILE *p = fopen("foo", "r");
1872 } // warn: opened file is never closed
1873
1874 void test() {
1875 FILE *p = fopen("foo", "r");
1876 fseek(p, 1, SEEK_SET); // warn: stream pointer might be NULL
1877 fclose(p);
1878 }
1879
1880 void test() {
1881 FILE *p = fopen("foo", "r");
1882
1883 if (p)
1884 fseek(p, 1, 3);
1885 // warn: third arg should be SEEK_SET, SEEK_END, or SEEK_CUR
1886
1887 fclose(p);
1888 }
1889
1890 void test() {
1891 FILE *p = fopen("foo", "r");
1892 fclose(p);
1893 fclose(p); // warn: already closed
1894 }
1895
1896 void test() {
1897 FILE *p = tmpfile();
1898 ftell(p); // warn: stream pointer might be NULL
1899 fclose(p);
1900 }
1901
1902
1903alpha.unix.cstring.BufferOverlap (C)
1904""""""""""""""""""""""""""""""""""""
1905Checks for overlap in two buffer arguments. Applies to: ``memcpy, mempcpy``.
1906
1907.. code-block:: c
1908
1909 void test() {
1910 int a[4] = {0};
1911 memcpy(a + 2, a + 1, 8); // warn
1912 }
1913
1914alpha.unix.cstring.NotNullTerminated (C)
1915""""""""""""""""""""""""""""""""""""""""
1916Check for arguments which are not null-terminated strings; applies to: ``strlen, strnlen, strcpy, strncpy, strcat, strncat``.
1917
1918.. code-block:: c
1919
1920 void test() {
1921 int y = strlen((char *)&test); // warn
1922 }
1923
1924alpha.unix.cstring.OutOfBounds (C)
1925""""""""""""""""""""""""""""""""""
1926Check for out-of-bounds access in string functions; applies to:`` strncopy, strncat``.
1927
1928
1929.. code-block:: c
1930
1931 void test() {
1932 int y = strlen((char *)&test); // warn
1933 }
1934
1935
1936Debug Checkers
1937---------------
1938
1939.. _debug-checkers:
1940
1941
1942debug
1943^^^^^
1944
1945Checkers used for debugging the analyzer.
1946:doc:`DebugChecks` page contains a detailed description.
1947
1948debug.AnalysisOrder
1949"""""""""""""""""""
1950Print callbacks that are called during analysis in order.
1951
1952debug.ConfigDumper
1953""""""""""""""""""
1954Dump config table.
1955
1956debug.DumpCFG Display
1957"""""""""""""""""""""
1958Control-Flow Graphs.
1959
1960debug.DumpCallGraph
1961"""""""""""""""""""
1962Display Call Graph.
1963
1964debug.DumpCalls
1965"""""""""""""""
1966Print calls as they are traversed by the engine.
1967
1968debug.DumpDominators
1969""""""""""""""""""""
1970Print the dominance tree for a given CFG.
1971
1972debug.DumpLiveVars
1973""""""""""""""""""
1974Print results of live variable analysis.
1975
1976debug.DumpTraversal
1977"""""""""""""""""""
1978Print branch conditions as they are traversed by the engine.
1979
1980debug.ExprInspection
1981""""""""""""""""""""
1982Check the analyzer's understanding of expressions.
1983
1984debug.Stats
1985"""""""""""
1986Emit warnings with analyzer statistics.
1987
1988debug.TaintTest
1989"""""""""""""""
1990Mark tainted symbols as such.
1991
1992debug.ViewCFG
1993"""""""""""""
1994View Control-Flow Graphs using GraphViz.
1995
1996debug.ViewCallGraph
1997"""""""""""""""""""
1998View Call Graph using GraphViz.
1999
2000debug.ViewExplodedGraph
2001"""""""""""""""""""""""
2002View Exploded Graphs using GraphViz.
2003