blob: 62f7f7bfc8ceab283cd5bdf494f06ca1fc7f0a28 [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
Kristof Umann8d239992019-02-11 13:46:43 +0000569security.insecureAPI.DeprecatedOrUnsafeBufferHandling (C)
570""""""""""""""""""""""""""""""
571 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``
572
573.. code-block:: c
574
575 void test() {
576 char buf [5];
577 strncpy(buf, "a", 1); // warn
578 }
579
Kristof Umann1a170322019-02-05 00:39:33 +0000580.. _unix-checkers:
581
582unix
583^^^^
584POSIX/Unix checkers.
585
586unix.API (C)
587""""""""""""
588Check calls to various UNIX/Posix functions: ``open, pthread_once, calloc, malloc, realloc, alloca``.
589
590.. literalinclude:: checkers/unix_api_example.c
591 :language: c
592
593unix.Malloc (C)
594"""""""""""""""
595Check for memory leaks, double free, and use-after-free problems. Traces memory managed by malloc()/free().
596
597.. literalinclude:: checkers/unix_malloc_example.c
598 :language: c
599
600unix.MallocSizeof (C)
601"""""""""""""""""""""
602Check for dubious ``malloc`` arguments involving ``sizeof``.
603
604.. code-block:: c
605
606 void test() {
607 long *p = malloc(sizeof(short));
608 // warn: result is converted to 'long *', which is
609 // incompatible with operand type 'short'
610 free(p);
611 }
612
613unix.MismatchedDeallocator (C, C++)
614"""""""""""""""""""""""""""""""""""
615Check for mismatched deallocators.
616
617.. literalinclude:: checkers/mismatched_deallocator_example.cpp
618 :language: c
619
620unix.Vfork (C)
621""""""""""""""
622Check for proper usage of ``vfork``.
623
624.. code-block:: c
625
626 int test(int x) {
627 pid_t pid = vfork(); // warn
628 if (pid != 0)
629 return 0;
630
631 switch (x) {
632 case 0:
633 pid = 1;
634 execl("", "", 0);
635 _exit(1);
636 break;
637 case 1:
638 x = 0; // warn: this assignment is prohibited
639 break;
640 case 2:
641 foo(); // warn: this function call is prohibited
642 break;
643 default:
644 return 0; // warn: return is prohibited
645 }
646
647 while(1);
648 }
649
650unix.cstring.BadSizeArg (C)
651"""""""""""""""""""""""""""
652Check 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.
653
654.. code-block:: c
655
656 void test() {
657 char dest[3];
658 strncat(dest, """""""""""""""""""""""""*", sizeof(dest));
659 // warn: potential buffer overflow
660 }
661
662unix.cstrisng.NullArg (C)
663"""""""""""""""""""""""""
664Check for null pointers being passed as arguments to C string functions:
665``strlen, strnlen, strcpy, strncpy, strcat, strncat, strcmp, strncmp, strcasecmp, strncasecmp``.
666
667.. code-block:: c
668
669 int test() {
670 return strlen(0); // warn
671 }
672
673.. _osx-checkers:
674
675osx
676^^^
677OS X checkers.
678
679osx.API (C)
680"""""""""""
681Check for proper uses of various Apple APIs.
682
683.. code-block:: objc
684
685 void test() {
686 dispatch_once_t pred = 0;
687 dispatch_once(&pred, ^(){}); // warn: dispatch_once uses local
688 }
689
690osx.NumberObjectConversion (C, C++, ObjC)
691"""""""""""""""""""""""""""""""""""""""""
692Check for erroneous conversions of objects representing numbers into numbers.
693
694.. code-block:: objc
695
696 NSNumber *photoCount = [albumDescriptor objectForKey:@"PhotoCount"];
697 // Warning: Comparing a pointer value of type 'NSNumber *'
698 // to a scalar integer value
699 if (photoCount > 0) {
700 [self displayPhotos];
701 }
702
703osx.ObjCProperty (ObjC)
704"""""""""""""""""""""""
705Check for proper uses of Objective-C properties.
706
707.. code-block:: objc
708
709 NSNumber *photoCount = [albumDescriptor objectForKey:@"PhotoCount"];
710 // Warning: Comparing a pointer value of type 'NSNumber *'
711 // to a scalar integer value
712 if (photoCount > 0) {
713 [self displayPhotos];
714 }
715
716
717osx.SecKeychainAPI (C)
718""""""""""""""""""""""
719Check for proper uses of Secure Keychain APIs.
720
721.. literalinclude:: checkers/seckeychainapi_example.m
722 :language: objc
723
724osx.cocoa.AtSync (ObjC)
725"""""""""""""""""""""""
726Check for nil pointers used as mutexes for @synchronized.
727
728.. code-block:: objc
729
730 void test(id x) {
731 if (!x)
732 @synchronized(x) {} // warn: nil value used as mutex
733 }
734
735 void test() {
736 id y;
737 @synchronized(y) {} // warn: uninitialized value used as mutex
738 }
739
740osx.cocoa.AutoreleaseWrite
741""""""""""""""""""""""""""
742Warn about potentially crashing writes to autoreleasing objects from different autoreleasing pools in Objective-C.
743
744osx.cocoa.ClassRelease (ObjC)
745"""""""""""""""""""""""""""""
746Check for sending 'retain', 'release', or 'autorelease' directly to a Class.
747
748.. code-block:: objc
749
750 @interface MyClass : NSObject
751 @end
752
753 void test(void) {
754 [MyClass release]; // warn
755 }
756
757osx.cocoa.Dealloc (ObjC)
758""""""""""""""""""""""""
759Warn about Objective-C classes that lack a correct implementation of -dealloc
760
761.. literalinclude:: checkers/dealloc_example.m
762 :language: objc
763
764osx.cocoa.IncompatibleMethodTypes (ObjC)
765""""""""""""""""""""""""""""""""""""""""
766Warn about Objective-C method signatures with type incompatibilities.
767
768.. code-block:: objc
769
770 @interface MyClass1 : NSObject
771 - (int)foo;
772 @end
773
774 @implementation MyClass1
775 - (int)foo { return 1; }
776 @end
777
778 @interface MyClass2 : MyClass1
779 - (float)foo;
780 @end
781
782 @implementation MyClass2
783 - (float)foo { return 1.0; } // warn
784 @end
785
786osx.cocoa.Loops
787"""""""""""""""
788Improved modeling of loops using Cocoa collection types.
789
790osx.cocoa.MissingSuperCall (ObjC)
791"""""""""""""""""""""""""""""""""
792Warn about Objective-C methods that lack a necessary call to super.
793
794.. code-block:: objc
795
796 @interface Test : UIViewController
797 @end
798 @implementation test
799 - (void)viewDidLoad {} // warn
800 @end
801
802
803osx.cocoa.NSAutoreleasePool (ObjC)
804""""""""""""""""""""""""""""""""""
805Warn for suboptimal uses of NSAutoreleasePool in Objective-C GC mode.
806
807.. code-block:: objc
808
809 void test() {
810 NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
811 [pool release]; // warn
812 }
813
814osx.cocoa.NSError (ObjC)
815""""""""""""""""""""""""
816Check usage of NSError parameters.
817
818.. code-block:: objc
819
820 @interface A : NSObject
821 - (void)foo:(NSError """""""""""""""""""""""")error;
822 @end
823
824 @implementation A
825 - (void)foo:(NSError """""""""""""""""""""""")error {
826 // warn: method accepting NSError"""""""""""""""""""""""" should have a non-void
827 // return value
828 }
829 @end
830
831 @interface A : NSObject
832 - (BOOL)foo:(NSError """""""""""""""""""""""")error;
833 @end
834
835 @implementation A
836 - (BOOL)foo:(NSError """""""""""""""""""""""")error {
837 *error = 0; // warn: potential null dereference
838 return 0;
839 }
840 @end
841
842osx.cocoa.NilArg (ObjC)
843"""""""""""""""""""""""
844Check for prohibited nil arguments to ObjC method calls.
845
846 - caseInsensitiveCompare:
847 - compare:
848 - compare:options:
849 - compare:options:range:
850 - compare:options:range:locale:
851 - componentsSeparatedByCharactersInSet:
852 - initWithFormat:
853
854.. code-block:: objc
855
856 NSComparisonResult test(NSString *s) {
857 NSString *aString = nil;
858 return [s caseInsensitiveCompare:aString];
859 // warn: argument to 'NSString' method
860 // 'caseInsensitiveCompare:' cannot be nil
861 }
862
863
864osx.cocoa.NonNilReturnValue
865"""""""""""""""""""""""""""
866Models the APIs that are guaranteed to return a non-nil value.
867
868osx.cocoa.ObjCGenerics (ObjC)
869"""""""""""""""""""""""""""""
870Check for type errors when using Objective-C generics.
871
872.. code-block:: objc
873
874 NSMutableArray *names = [NSMutableArray array];
875 NSMutableArray *birthDates = names;
876
877 // Warning: Conversion from value of type 'NSDate *'
878 // to incompatible type 'NSString *'
879 [birthDates addObject: [NSDate date]];
880
881osx.cocoa.RetainCount (ObjC)
882""""""""""""""""""""""""""""
883Check for leaks and improper reference count management
884
885.. code-block:: objc
886
887 void test() {
888 NSString *s = [[NSString alloc] init]; // warn
889 }
890
891 CFStringRef test(char *bytes) {
892 return CFStringCreateWithCStringNoCopy(
893 0, bytes, NSNEXTSTEPStringEncoding, 0); // warn
894 }
895
896
897osx.cocoa.RunLoopAutoreleaseLeak
898""""""""""""""""""""""""""""""""
899Check for leaked memory in autorelease pools that will never be drained.
900
901osx.cocoa.SelfInit (ObjC)
902"""""""""""""""""""""""""
903Check that 'self' is properly initialized inside an initializer method.
904
905.. code-block:: objc
906
907 @interface MyObj : NSObject {
908 id x;
909 }
910 - (id)init;
911 @end
912
913 @implementation MyObj
914 - (id)init {
915 [super init];
916 x = 0; // warn: instance variable used while 'self' is not
917 // initialized
918 return 0;
919 }
920 @end
921
922 @interface MyObj : NSObject
923 - (id)init;
924 @end
925
926 @implementation MyObj
927 - (id)init {
928 [super init];
929 return self; // warn: returning uninitialized 'self'
930 }
931 @end
932
933osx.cocoa.SuperDealloc (ObjC)
934"""""""""""""""""""""""""""""
935Warn about improper use of '[super dealloc]' in Objective-C.
936
937.. code-block:: objc
938
939 @interface SuperDeallocThenReleaseIvarClass : NSObject {
940 NSObject *_ivar;
941 }
942 @end
943
944 @implementation SuperDeallocThenReleaseIvarClass
945 - (void)dealloc {
946 [super dealloc];
947 [_ivar release]; // warn
948 }
949 @end
950
951osx.cocoa.UnusedIvars (ObjC)
952""""""""""""""""""""""""""""
953Warn about private ivars that are never used.
954
955.. code-block:: objc
956
957 @interface MyObj : NSObject {
958 @private
959 id x; // warn
960 }
961 @end
962
963 @implementation MyObj
964 @end
965
966osx.cocoa.VariadicMethodTypes (ObjC)
967""""""""""""""""""""""""""""""""""""
968Check for passing non-Objective-C types to variadic collection
969initialization methods that expect only Objective-C types.
970
971.. code-block:: objc
972
973 void test() {
974 [NSSet setWithObjects:@"Foo", "Bar", nil];
975 // warn: argument should be an ObjC pointer type, not 'char *'
976 }
977
978osx.coreFoundation.CFError (C)
979""""""""""""""""""""""""""""""
980Check usage of CFErrorRef* parameters
981
982.. code-block:: c
983
984 void test(CFErrorRef *error) {
985 // warn: function accepting CFErrorRef* should have a
986 // non-void return
987 }
988
989 int foo(CFErrorRef *error) {
990 *error = 0; // warn: potential null dereference
991 return 0;
992 }
993
994osx.coreFoundation.CFNumber (C)
995"""""""""""""""""""""""""""""""
996Check for proper uses of CFNumber APIs.
997
998.. code-block:: c
999
1000 CFNumberRef test(unsigned char x) {
1001 return CFNumberCreate(0, kCFNumberSInt16Type, &x);
1002 // warn: 8 bit integer is used to initialize a 16 bit integer
1003 }
1004
1005osx.coreFoundation.CFRetainRelease (C)
1006""""""""""""""""""""""""""""""""""""""
1007Check for null arguments to CFRetain/CFRelease/CFMakeCollectable.
1008
1009.. code-block:: c
1010
1011 void test(CFTypeRef p) {
1012 if (!p)
1013 CFRetain(p); // warn
1014 }
1015
1016 void test(int x, CFTypeRef p) {
1017 if (p)
1018 return;
1019
1020 CFRelease(p); // warn
1021 }
1022
1023osx.coreFoundation.containers.OutOfBounds (C)
1024"""""""""""""""""""""""""""""""""""""""""""""
1025Checks for index out-of-bounds when using 'CFArray' API.
1026
1027.. code-block:: c
1028
1029 void test() {
1030 CFArrayRef A = CFArrayCreate(0, 0, 0, &kCFTypeArrayCallBacks);
1031 CFArrayGetValueAtIndex(A, 0); // warn
1032 }
1033
1034osx.coreFoundation.containers.PointerSizedValues (C)
1035""""""""""""""""""""""""""""""""""""""""""""""""""""
1036Warns if 'CFArray', 'CFDictionary', 'CFSet' are created with non-pointer-size values.
1037
1038.. code-block:: c
1039
1040 void test() {
1041 int x[] = { 1 };
1042 CFArrayRef A = CFArrayCreate(0, (const void """""""""""""""""""""""")x, 1,
1043 &kCFTypeArrayCallBacks); // warn
1044 }
1045
1046
1047.. _alpha-checkers:
1048
1049Experimental Checkers
1050---------------------
1051
1052*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.*
1053
1054alpha.clone
1055^^^^^^^^^^^
1056
1057alpha.clone.CloneChecker (C, C++, ObjC)
1058"""""""""""""""""""""""""""""""""""""""
1059Reports similar pieces of code.
1060
1061.. code-block:: c
1062
1063 void log();
1064
1065 int max(int a, int b) { // warn
1066 log();
1067 if (a > b)
1068 return a;
1069 return b;
1070 }
1071
1072 int maxClone(int x, int y) { // similar code here
1073 log();
1074 if (x > y)
1075 return x;
1076 return y;
1077 }
1078
1079alpha.core.BoolAssignment (ObjC)
1080""""""""""""""""""""""""""""""""
1081Warn about assigning non-{0,1} values to boolean variables.
1082
1083.. code-block:: objc
1084
1085 void test() {
1086 BOOL b = -1; // warn
1087 }
1088
1089alpha.core
1090^^^^^^^^^^
1091
1092alpha.core.CallAndMessageUnInitRefArg (C,C++, ObjC)
1093"""""""""""""""""""""""""""""""""""""""""""""""""""
1094Check for logical errors for function calls and Objective-C
1095message expressions (e.g., uninitialized arguments, null function pointers, and pointer to undefined variables).
1096
1097.. code-block:: c
1098
1099 void test(void) {
1100 int t;
1101 int &p = t;
1102 int &s = p;
1103 int &q = s;
1104 foo(q); // warn
1105 }
1106
1107 void test(void) {
1108 int x;
1109 foo(&x); // warn
1110 }
1111
1112alpha.core.CastSize (C)
1113"""""""""""""""""""""""
1114Check when casting a malloc'ed type ``T``, whether the size is a multiple of the size of ``T``.
1115
1116.. code-block:: c
1117
1118 void test() {
1119 int *x = (int *) malloc(11); // warn
1120 }
1121
1122alpha.core.CastToStruct (C, C++)
1123""""""""""""""""""""""""""""""""
1124Check for cast from non-struct pointer to struct pointer.
1125
1126.. code-block:: cpp
1127
1128 // C
1129 struct s {};
1130
1131 void test(int *p) {
1132 struct s *ps = (struct s *) p; // warn
1133 }
1134
1135 // C++
1136 class c {};
1137
1138 void test(int *p) {
1139 c *pc = (c *) p; // warn
1140 }
1141
1142alpha.core.Conversion (C, C++, ObjC)
1143""""""""""""""""""""""""""""""""""""
1144Loss of sign/precision in implicit conversions.
1145
1146.. code-block:: c
1147
1148 void test(unsigned U, signed S) {
1149 if (S > 10) {
1150 if (U < S) {
1151 }
1152 }
1153 if (S < -10) {
1154 if (U < S) { // warn (loss of sign)
1155 }
1156 }
1157 }
1158
1159 void test() {
1160 long long A = 1LL << 60;
1161 short X = A; // warn (loss of precision)
1162 }
1163
1164alpha.core.DynamicTypeChecker (ObjC)
1165""""""""""""""""""""""""""""""""""""
1166Check for cases where the dynamic and the static type of an object are unrelated.
1167
1168
1169.. code-block:: objc
1170
1171 id date = [NSDate date];
1172
1173 // Warning: Object has a dynamic type 'NSDate *' which is
1174 // incompatible with static type 'NSNumber *'"
1175 NSNumber *number = date;
1176 [number doubleValue];
1177
1178alpha.core.FixedAddr (C)
1179""""""""""""""""""""""""
1180Check for assignment of a fixed address to a pointer.
1181
1182.. code-block:: c
1183
1184 void test() {
1185 int *p;
1186 p = (int *) 0x10000; // warn
1187 }
1188
1189alpha.core.IdenticalExpr (C, C++)
1190"""""""""""""""""""""""""""""""""
1191Warn about unintended use of identical expressions in operators.
1192
1193.. code-block:: cpp
1194
1195 // C
1196 void test() {
1197 int a = 5;
1198 int b = a | 4 | a; // warn: identical expr on both sides
1199 }
1200
1201 // C++
1202 bool f(void);
1203
1204 void test(bool b) {
1205 int i = 10;
1206 if (f()) { // warn: true and false branches are identical
1207 do {
1208 i--;
1209 } while (f());
1210 } else {
1211 do {
1212 i--;
1213 } while (f());
1214 }
1215 }
1216
1217alpha.core.PointerArithm (C)
1218""""""""""""""""""""""""""""
1219Check for pointer arithmetic on locations other than array elements.
1220
1221.. code-block:: c
1222
1223 void test() {
1224 int x;
1225 int *p;
1226 p = &x + 1; // warn
1227 }
1228
1229alpha.core.PointerSub (C)
1230"""""""""""""""""""""""""
1231Check for pointer subtractions on two pointers pointing to different memory chunks.
1232
1233.. code-block:: c
1234
1235 void test() {
1236 int x, y;
1237 int d = &y - &x; // warn
1238 }
1239
1240alpha.core.SizeofPtr (C)
1241""""""""""""""""""""""""
1242Warn about unintended use of ``sizeof()`` on pointer expressions.
1243
1244.. code-block:: c
1245
1246 struct s {};
1247
1248 int test(struct s *p) {
1249 return sizeof(p);
1250 // warn: sizeof(ptr) can produce an unexpected result
1251 }
1252
1253alpha.core.StackAddressAsyncEscape (C)
1254""""""""""""""""""""""""""""""""""""""
1255Check that addresses to stack memory do not escape the function that involves dispatch_after or dispatch_async.
1256This checker is a part of ``core.StackAddressEscape``, but is temporarily disabled until some false positives are fixed.
1257
1258.. code-block:: c
1259
1260 dispatch_block_t test_block_inside_block_async_leak() {
1261 int x = 123;
1262 void (^inner)(void) = ^void(void) {
1263 int y = x;
1264 ++y;
1265 };
1266 void (^outer)(void) = ^void(void) {
1267 int z = x;
1268 ++z;
1269 inner();
1270 };
1271 return outer; // warn: address of stack-allocated block is captured by a
1272 // returned block
1273 }
1274
1275alpha.core.TestAfterDivZero (C)
1276"""""""""""""""""""""""""""""""
1277Check for division by variable that is later compared against 0.
1278Either the comparison is useless or there is division by zero.
1279
1280.. code-block:: c
1281
1282 void test(int x) {
1283 var = 77 / x;
1284 if (x == 0) { } // warn
1285 }
1286
1287alpha.cplusplus
1288^^^^^^^^^^^^^^^
1289
1290alpha.cplusplus.DeleteWithNonVirtualDtor (C++)
1291""""""""""""""""""""""""""""""""""""""""""""""
1292Reports destructions of polymorphic objects with a non-virtual destructor in their base class.
1293
1294.. code-block:: cpp
1295
1296 NonVirtual *create() {
1297 NonVirtual *x = new NVDerived(); // note: conversion from derived to base
1298 // happened here
1299 return x;
1300 }
1301
1302 void sink(NonVirtual *x) {
1303 delete x; // warn: destruction of a polymorphic object with no virtual
1304 // destructor
1305 }
1306
1307alpha.cplusplus.EnumCastOutOfRange (C++)
1308""""""""""""""""""""""""""""""""""""""""
1309Check for integer to enumeration casts that could result in undefined values.
1310
1311.. code-block:: cpp
1312
1313 enum TestEnum {
1314 A = 0
1315 };
1316
1317 void foo() {
1318 TestEnum t = static_cast(-1);
1319 // warn: the value provided to the cast expression is not in
1320 the valid range of values for the enum
1321
1322alpha.cplusplus.InvalidatedIterator (C++)
1323"""""""""""""""""""""""""""""""""""""""""
1324Check for use of invalidated iterators.
1325
1326.. code-block:: cpp
1327
1328 void bad_copy_assign_operator_list1(std::list &L1,
1329 const std::list &L2) {
1330 auto i0 = L1.cbegin();
1331 L1 = L2;
1332 *i0; // warn: invalidated iterator accessed
1333 }
1334
1335
1336alpha.cplusplus.IteratorRange (C++)
1337"""""""""""""""""""""""""""""""""""
1338Check for iterators used outside their valid ranges.
1339
1340.. code-block:: cpp
1341
1342 void simple_bad_end(const std::vector &v) {
1343 auto i = v.end();
1344 *i; // warn: iterator accessed outside of its range
1345 }
1346
1347alpha.cplusplus.MismatchedIterator (C++)
1348""""""""""""""""""""""""""""""""""""""""
1349Check for use of iterators of different containers where iterators of the same container are expected.
1350
1351.. code-block:: cpp
1352
1353 void bad_insert3(std::vector &v1, std::vector &v2) {
1354 v2.insert(v1.cbegin(), v2.cbegin(), v2.cend()); // warn: container accessed
1355 // using foreign
1356 // iterator argument
1357 v1.insert(v1.cbegin(), v1.cbegin(), v2.cend()); // warn: iterators of
1358 // different containers
1359 // used where the same
1360 // container is
1361 // expected
1362 v1.insert(v1.cbegin(), v2.cbegin(), v1.cend()); // warn: iterators of
1363 // different containers
1364 // used where the same
1365 // container is
1366 // expected
1367 }
1368
1369alpha.cplusplus.MisusedMovedObject (C++)
1370""""""""""""""""""""""""""""""""""""""""
1371Method calls on a moved-from object and copying a moved-from object will be reported.
1372
1373
1374.. code-block:: cpp
1375
1376 struct A {
1377 void foo() {}
1378 };
1379
1380 void f() {
1381 A a;
1382 A b = std::move(a); // note: 'a' became 'moved-from' here
1383 a.foo(); // warn: method call on a 'moved-from' object 'a'
1384 }
1385
1386alpha.cplusplus.UninitializedObject (C++)
1387"""""""""""""""""""""""""""""""""""""""""
1388
1389This checker reports uninitialized fields in objects created after a constructor call.
1390It doesn't only find direct uninitialized fields, but rather makes a deep inspection
1391of the object, analyzing all of it's fields subfields.
1392The checker regards inherited fields as direct fields, so one will
1393recieve warnings for uninitialized inherited data members as well.
1394
1395.. code-block:: cpp
1396
1397 // With Pedantic and CheckPointeeInitialization set to true
1398
1399 struct A {
1400 struct B {
1401 int x; // note: uninitialized field 'this->b.x'
1402 // note: uninitialized field 'this->bptr->x'
1403 int y; // note: uninitialized field 'this->b.y'
1404 // note: uninitialized field 'this->bptr->y'
1405 };
1406 int *iptr; // note: uninitialized pointer 'this->iptr'
1407 B b;
1408 B *bptr;
1409 char *cptr; // note: uninitialized pointee 'this->cptr'
1410
1411 A (B *bptr, char *cptr) : bptr(bptr), cptr(cptr) {}
1412 };
1413
1414 void f() {
1415 A::B b;
1416 char c;
1417 A a(&b, &c); // warning: 6 uninitialized fields
1418 // after the constructor call
1419 }
1420
1421 // With Pedantic set to false and
1422 // CheckPointeeInitialization set to true
1423 // (every field is uninitialized)
1424
1425 struct A {
1426 struct B {
1427 int x;
1428 int y;
1429 };
1430 int *iptr;
1431 B b;
1432 B *bptr;
1433 char *cptr;
1434
1435 A (B *bptr, char *cptr) : bptr(bptr), cptr(cptr) {}
1436 };
1437
1438 void f() {
1439 A::B b;
1440 char c;
1441 A a(&b, &c); // no warning
1442 }
1443
1444 // With Pedantic set to true and
1445 // CheckPointeeInitialization set to false
1446 // (pointees are regarded as initialized)
1447
1448 struct A {
1449 struct B {
1450 int x; // note: uninitialized field 'this->b.x'
1451 int y; // note: uninitialized field 'this->b.y'
1452 };
1453 int *iptr; // note: uninitialized pointer 'this->iptr'
1454 B b;
1455 B *bptr;
1456 char *cptr;
1457
1458 A (B *bptr, char *cptr) : bptr(bptr), cptr(cptr) {}
1459 };
1460
1461 void f() {
1462 A::B b;
1463 char c;
1464 A a(&b, &c); // warning: 3 uninitialized fields
1465 // after the constructor call
1466 }
1467
1468
1469**Options**
1470
1471This checker has several options which can be set from command line (e.g. ``-analyzer-config alpha.cplusplus.UninitializedObject:Pedantic=true``):
1472
1473* ``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.
1474
1475* ``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.*.
1476
1477* ``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.*.
1478
1479* ``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"``.
1480
1481
1482alpha.deadcode
1483^^^^^^^^^^^^^^
1484alpha.deadcode.UnreachableCode (C, C++)
1485"""""""""""""""""""""""""""""""""""""""
1486Check unreachable code.
1487
1488.. code-block:: cpp
1489
1490 // C
1491 int test() {
1492 int x = 1;
1493 while(x);
1494 return x; // warn
1495 }
1496
1497 // C++
1498 void test() {
1499 int a = 2;
1500
1501 while (a > 1)
1502 a--;
1503
1504 if (a > 1)
1505 a++; // warn
1506 }
1507
1508 // Objective-C
1509 void test(id x) {
1510 return;
1511 [x retain]; // warn
1512 }
1513
1514alpha.llvm
1515^^^^^^^^^^
1516
1517alpha.llvm.Conventions
1518""""""""""""""""""""""
1519
1520Check code for LLVM codebase conventions:
1521
1522* A StringRef should not be bound to a temporary std::string whose lifetime is shorter than the StringRef's.
1523* Clang AST nodes should not have fields that can allocate memory.
1524
1525
1526alpha.osx
1527^^^^^^^^^
1528
1529alpha.osx.cocoa.DirectIvarAssignment (ObjC)
1530"""""""""""""""""""""""""""""""""""""""""""
1531Check for direct assignments to instance variables.
1532
1533
1534.. code-block:: objc
1535
1536 @interface MyClass : NSObject {}
1537 @property (readonly) id A;
1538 - (void) foo;
1539 @end
1540
1541 @implementation MyClass
1542 - (void) foo {
1543 _A = 0; // warn
1544 }
1545 @end
1546
1547alpha.osx.cocoa.DirectIvarAssignmentForAnnotatedFunctions (ObjC)
1548""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
1549Check for direct assignments to instance variables in
1550the methods annotated with ``objc_no_direct_instance_variable_assignment``.
1551
1552.. code-block:: objc
1553
1554 @interface MyClass : NSObject {}
1555 @property (readonly) id A;
1556 - (void) fAnnotated __attribute__((
1557 annotate("objc_no_direct_instance_variable_assignment")));
1558 - (void) fNotAnnotated;
1559 @end
1560
1561 @implementation MyClass
1562 - (void) fAnnotated {
1563 _A = 0; // warn
1564 }
1565 - (void) fNotAnnotated {
1566 _A = 0; // no warn
1567 }
1568 @end
1569
1570
1571alpha.osx.cocoa.InstanceVariableInvalidation (ObjC)
1572"""""""""""""""""""""""""""""""""""""""""""""""""""
1573Check that the invalidatable instance variables are
1574invalidated in the methods annotated with objc_instance_variable_invalidator.
1575
1576.. code-block:: objc
1577
1578 @protocol Invalidation <NSObject>
1579 - (void) invalidate
1580 __attribute__((annotate("objc_instance_variable_invalidator")));
1581 @end
1582
1583 @interface InvalidationImpObj : NSObject <Invalidation>
1584 @end
1585
1586 @interface SubclassInvalidationImpObj : InvalidationImpObj {
1587 InvalidationImpObj *var;
1588 }
1589 - (void)invalidate;
1590 @end
1591
1592 @implementation SubclassInvalidationImpObj
1593 - (void) invalidate {}
1594 @end
1595 // warn: var needs to be invalidated or set to nil
1596
1597alpha.osx.cocoa.MissingInvalidationMethod (ObjC)
1598""""""""""""""""""""""""""""""""""""""""""""""""
1599Check that the invalidation methods are present in classes that contain invalidatable instance variables.
1600
1601.. code-block:: objc
1602
1603 @protocol Invalidation <NSObject>
1604 - (void)invalidate
1605 __attribute__((annotate("objc_instance_variable_invalidator")));
1606 @end
1607
1608 @interface NeedInvalidation : NSObject <Invalidation>
1609 @end
1610
1611 @interface MissingInvalidationMethodDecl : NSObject {
1612 NeedInvalidation *Var; // warn
1613 }
1614 @end
1615
1616 @implementation MissingInvalidationMethodDecl
1617 @end
1618
1619alpha.osx.cocoa.localizability.PluralMisuseChecker (ObjC)
1620"""""""""""""""""""""""""""""""""""""""""""""""""""""""""
1621Warns against using one vs. many plural pattern in code when generating localized strings.
1622
1623.. code-block:: objc
1624
1625 NSString *reminderText =
1626 NSLocalizedString(@"None", @"Indicates no reminders");
1627 if (reminderCount == 1) {
1628 // Warning: Plural cases are not supported across all languages.
1629 // Use a .stringsdict file instead
1630 reminderText =
1631 NSLocalizedString(@"1 Reminder", @"Indicates single reminder");
1632 } else if (reminderCount >= 2) {
1633 // Warning: Plural cases are not supported across all languages.
1634 // Use a .stringsdict file instead
1635 reminderText =
1636 [NSString stringWithFormat:
1637 NSLocalizedString(@"%@ Reminders", @"Indicates multiple reminders"),
1638 reminderCount];
1639 }
1640
1641alpha.security
1642^^^^^^^^^^^^^^
1643alpha.security.ArrayBound (C)
1644"""""""""""""""""""""""""""""
1645Warn about buffer overflows (older checker).
1646
1647.. code-block:: c
1648
1649 void test() {
1650 char *s = "";
1651 char c = s[1]; // warn
1652 }
1653
1654 struct seven_words {
1655 int c[7];
1656 };
1657
1658 void test() {
1659 struct seven_words a, *p;
1660 p = &a;
1661 p[0] = a;
1662 p[1] = a;
1663 p[2] = a; // warn
1664 }
1665
1666 // note: requires unix.Malloc or
1667 // alpha.unix.MallocWithAnnotations checks enabled.
1668 void test() {
1669 int *p = malloc(12);
1670 p[3] = 4; // warn
1671 }
1672
1673 void test() {
1674 char a[2];
1675 int *b = (int*)a;
1676 b[1] = 3; // warn
1677 }
1678
1679alpha.security.ArrayBoundV2 (C)
1680"""""""""""""""""""""""""""""""
1681Warn about buffer overflows (newer checker).
1682
1683.. code-block:: c
1684
1685 void test() {
1686 char *s = "";
1687 char c = s[1]; // warn
1688 }
1689
1690 void test() {
1691 int buf[100];
1692 int *p = buf;
1693 p = p + 99;
1694 p[1] = 1; // warn
1695 }
1696
1697 // note: compiler has internal check for this.
1698 // Use -Wno-array-bounds to suppress compiler warning.
1699 void test() {
1700 int buf[100][100];
1701 buf[0][-1] = 1; // warn
1702 }
1703
1704 // note: requires alpha.security.taint check turned on.
1705 void test() {
1706 char s[] = "abc";
1707 int x = getchar();
1708 char c = s[x]; // warn: index is tainted
1709 }
1710
1711alpha.security.MallocOverflow (C)
1712"""""""""""""""""""""""""""""""""
1713Check for overflows in the arguments to malloc().
1714
1715.. code-block:: c
1716
1717 void test(int n) {
1718 void *p = malloc(n * sizeof(int)); // warn
1719 }
1720
1721alpha.security.MmapWriteExec (C)
1722""""""""""""""""""""""""""""""""
1723Warn on mmap() calls that are both writable and executable.
1724
1725.. code-block:: c
1726
1727 void test(int n) {
1728 void *c = mmap(NULL, 32, PROT_READ | PROT_WRITE | PROT_EXEC,
1729 MAP_PRIVATE | MAP_ANON, -1, 0);
1730 // warn: Both PROT_WRITE and PROT_EXEC flags are set. This can lead to
1731 // exploitable memory regions, which could be overwritten with malicious
1732 // code
1733 }
1734
1735alpha.security.ReturnPtrRange (C)
1736"""""""""""""""""""""""""""""""""
1737Check for an out-of-bound pointer being returned to callers.
1738
1739.. code-block:: c
1740
1741 static int A[10];
1742
1743 int *test() {
1744 int *p = A + 10;
1745 return p; // warn
1746 }
1747
1748 int test(void) {
1749 int x;
1750 return x; // warn: undefined or garbage returned
1751 }
1752
1753alpha.security.taint.TaintPropagation (C, C++)
1754""""""""""""""""""""""""""""""""""""""""""""""
1755Generate taint information used by other checkers.
1756A data is tainted when it comes from an unreliable source.
1757
1758.. code-block:: c
1759
1760 void test() {
1761 char x = getchar(); // 'x' marked as tainted
1762 system(&x); // warn: untrusted data is passed to a system call
1763 }
1764
1765 // note: compiler internally checks if the second param to
1766 // sprintf is a string literal or not.
1767 // Use -Wno-format-security to suppress compiler warning.
1768 void test() {
1769 char s[10], buf[10];
1770 fscanf(stdin, "%s", s); // 's' marked as tainted
1771
1772 sprintf(buf, s); // warn: untrusted data as a format string
1773 }
1774
1775 void test() {
1776 size_t ts;
1777 scanf("%zd", &ts); // 'ts' marked as tainted
1778 int *p = (int *)malloc(ts * sizeof(int));
1779 // warn: untrusted data as buffer size
1780 }
1781
1782alpha.unix
1783^^^^^^^^^^^
1784
1785alpha.unix.BlockInCriticalSection (C)
1786"""""""""""""""""""""""""""""""""""""
1787Check for calls to blocking functions inside a critical section.
1788Applies to: ``lock, unlock, sleep, getc, fgets, read, recv, pthread_mutex_lock,``
1789`` pthread_mutex_unlock, mtx_lock, mtx_timedlock, mtx_trylock, mtx_unlock, lock_guard, unique_lock``
1790
1791.. code-block:: c
1792
1793 void test() {
1794 std::mutex m;
1795 m.lock();
1796 sleep(3); // warn: a blocking function sleep is called inside a critical
1797 // section
1798 m.unlock();
1799 }
1800
1801alpha.unix.Chroot (C)
1802"""""""""""""""""""""
1803Check improper use of chroot.
1804
1805.. code-block:: c
1806
1807 void f();
1808
1809 void test() {
1810 chroot("/usr/local");
1811 f(); // warn: no call of chdir("/") immediately after chroot
1812 }
1813
1814alpha.unix.PthreadLock (C)
1815""""""""""""""""""""""""""
1816Simple lock -> unlock checker.
1817Applies to: ``pthread_mutex_lock, pthread_rwlock_rdlock, pthread_rwlock_wrlock, lck_mtx_lock, lck_rw_lock_exclusive``
1818``lck_rw_lock_shared, pthread_mutex_trylock, pthread_rwlock_tryrdlock, pthread_rwlock_tryrwlock, lck_mtx_try_lock,
1819lck_rw_try_lock_exclusive, lck_rw_try_lock_shared, pthread_mutex_unlock, pthread_rwlock_unlock, lck_mtx_unlock, lck_rw_done``.
1820
1821
1822.. code-block:: c
1823
1824 pthread_mutex_t mtx;
1825
1826 void test() {
1827 pthread_mutex_lock(&mtx);
1828 pthread_mutex_lock(&mtx);
1829 // warn: this lock has already been acquired
1830 }
1831
1832 lck_mtx_t lck1, lck2;
1833
1834 void test() {
1835 lck_mtx_lock(&lck1);
1836 lck_mtx_lock(&lck2);
1837 lck_mtx_unlock(&lck1);
1838 // warn: this was not the most recently acquired lock
1839 }
1840
1841 lck_mtx_t lck1, lck2;
1842
1843 void test() {
1844 if (lck_mtx_try_lock(&lck1) == 0)
1845 return;
1846
1847 lck_mtx_lock(&lck2);
1848 lck_mtx_unlock(&lck1);
1849 // warn: this was not the most recently acquired lock
1850 }
1851
1852alpha.unix.SimpleStream (C)
1853"""""""""""""""""""""""""""
1854Check for misuses of stream APIs. Check for misuses of stream APIs: ``fopen, fclose``
1855(demo checker, the subject of the demo (`Slides <http://llvm.org/devmtg/2012-11/Zaks-Rose-Checker24Hours.pdf>`_ ,
1856`Video <https://youtu.be/kdxlsP5QVPw>`_) by Anna Zaks and Jordan Rose presented at the
1857`2012 LLVM Developers' Meeting <http://llvm.org/devmtg/2012-11/>`_).
1858
1859.. code-block:: c
1860
1861 void test() {
1862 FILE *F = fopen("myfile.txt", "w");
1863 } // warn: opened file is never closed
1864
1865 void test() {
1866 FILE *F = fopen("myfile.txt", "w");
1867
1868 if (F)
1869 fclose(F);
1870
1871 fclose(F); // warn: closing a previously closed file stream
1872 }
1873
1874alpha.unix.Stream (C)
1875"""""""""""""""""""""
1876Check stream handling functions: ``fopen, tmpfile, fclose, fread, fwrite, fseek, ftell, rewind, fgetpos,``
1877``fsetpos, clearerr, feof, ferror, fileno``.
1878
1879.. code-block:: c
1880
1881 void test() {
1882 FILE *p = fopen("foo", "r");
1883 } // warn: opened file is never closed
1884
1885 void test() {
1886 FILE *p = fopen("foo", "r");
1887 fseek(p, 1, SEEK_SET); // warn: stream pointer might be NULL
1888 fclose(p);
1889 }
1890
1891 void test() {
1892 FILE *p = fopen("foo", "r");
1893
1894 if (p)
1895 fseek(p, 1, 3);
1896 // warn: third arg should be SEEK_SET, SEEK_END, or SEEK_CUR
1897
1898 fclose(p);
1899 }
1900
1901 void test() {
1902 FILE *p = fopen("foo", "r");
1903 fclose(p);
1904 fclose(p); // warn: already closed
1905 }
1906
1907 void test() {
1908 FILE *p = tmpfile();
1909 ftell(p); // warn: stream pointer might be NULL
1910 fclose(p);
1911 }
1912
1913
1914alpha.unix.cstring.BufferOverlap (C)
1915""""""""""""""""""""""""""""""""""""
1916Checks for overlap in two buffer arguments. Applies to: ``memcpy, mempcpy``.
1917
1918.. code-block:: c
1919
1920 void test() {
1921 int a[4] = {0};
1922 memcpy(a + 2, a + 1, 8); // warn
1923 }
1924
1925alpha.unix.cstring.NotNullTerminated (C)
1926""""""""""""""""""""""""""""""""""""""""
1927Check for arguments which are not null-terminated strings; applies to: ``strlen, strnlen, strcpy, strncpy, strcat, strncat``.
1928
1929.. code-block:: c
1930
1931 void test() {
1932 int y = strlen((char *)&test); // warn
1933 }
1934
1935alpha.unix.cstring.OutOfBounds (C)
1936""""""""""""""""""""""""""""""""""
1937Check for out-of-bounds access in string functions; applies to:`` strncopy, strncat``.
1938
1939
1940.. code-block:: c
1941
1942 void test() {
1943 int y = strlen((char *)&test); // warn
1944 }
1945
1946
1947Debug Checkers
1948---------------
1949
1950.. _debug-checkers:
1951
1952
1953debug
1954^^^^^
1955
1956Checkers used for debugging the analyzer.
Kristof Umanndccfaff2019-02-05 10:19:39 +00001957:doc:`developer-docs/DebugChecks` page contains a detailed description.
Kristof Umann1a170322019-02-05 00:39:33 +00001958
1959debug.AnalysisOrder
1960"""""""""""""""""""
1961Print callbacks that are called during analysis in order.
1962
1963debug.ConfigDumper
1964""""""""""""""""""
1965Dump config table.
1966
1967debug.DumpCFG Display
1968"""""""""""""""""""""
1969Control-Flow Graphs.
1970
1971debug.DumpCallGraph
1972"""""""""""""""""""
1973Display Call Graph.
1974
1975debug.DumpCalls
1976"""""""""""""""
1977Print calls as they are traversed by the engine.
1978
1979debug.DumpDominators
1980""""""""""""""""""""
1981Print the dominance tree for a given CFG.
1982
1983debug.DumpLiveVars
1984""""""""""""""""""
1985Print results of live variable analysis.
1986
1987debug.DumpTraversal
1988"""""""""""""""""""
1989Print branch conditions as they are traversed by the engine.
1990
1991debug.ExprInspection
1992""""""""""""""""""""
1993Check the analyzer's understanding of expressions.
1994
1995debug.Stats
1996"""""""""""
1997Emit warnings with analyzer statistics.
1998
1999debug.TaintTest
2000"""""""""""""""
2001Mark tainted symbols as such.
2002
2003debug.ViewCFG
2004"""""""""""""
2005View Control-Flow Graphs using GraphViz.
2006
2007debug.ViewCallGraph
2008"""""""""""""""""""
2009View Call Graph using GraphViz.
2010
2011debug.ViewExplodedGraph
2012"""""""""""""""""""""""
2013View Exploded Graphs using GraphViz.
2014