blob: e5b60bbf15ba8b898745a40b46b6bd8514ffd34e [file] [log] [blame]
Kristof Umann1a170322019-02-05 00:39:33 +00001==================
2Available Checkers
3==================
4
Alexander Kornienko9a857d22019-02-11 15:17:13 +00005The analyzer performs checks that are categorized into families or "checkers".
Kristof Umann1a170322019-02-05 00:39:33 +00006
Alexander Kornienko9a857d22019-02-11 15:17:13 +00007The 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
Kristof Umann1a170322019-02-05 00:39:33 +000010In 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^^^^
Alexander Kornienko9a857d22019-02-11 15:17:13 +000028Models core language features and contains general-purpose checkers such as division by zero,
29null pointer dereference, usage of uninitialized values, etc.
Kristof Umann1a170322019-02-05 00:39:33 +000030*These checkers must be always switched on as other checker rely on them.*
31
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +000032.. _core-CallAndMessage:
33
Kristof Umann1a170322019-02-05 00:39:33 +000034core.CallAndMessage (C, C++, ObjC)
35""""""""""""""""""""""""""""""""""
36 Check for logical errors for function calls and Objective-C message expressions (e.g., uninitialized arguments, null function pointers).
37
Alexander Kornienko9a857d22019-02-11 15:17:13 +000038.. literalinclude:: checkers/callandmessage_example.c
Kristof Umann1a170322019-02-05 00:39:33 +000039 :language: objc
Alexander Kornienko9a857d22019-02-11 15:17:13 +000040
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +000041.. _core-DivideZero:
42
Kristof Umann1a170322019-02-05 00:39:33 +000043core.DivideZero (C, C++, ObjC)
44""""""""""""""""""""""""""""""
45 Check for division by zero.
46
47.. literalinclude:: checkers/dividezero_example.c
48 :language: c
Alexander Kornienko9a857d22019-02-11 15:17:13 +000049
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +000050.. _core-NonNullParamChecker:
51
Alexander Kornienko9a857d22019-02-11 15:17:13 +000052core.NonNullParamChecker (C, C++, ObjC)
Kristof Umann1a170322019-02-05 00:39:33 +000053"""""""""""""""""""""""""""""""""""""""
54Check for null pointers passed as arguments to a function whose arguments are references or marked with the 'nonnull' attribute.
55
Alexander Kornienko9a857d22019-02-11 15:17:13 +000056.. code-block:: cpp
57
Kristof Umann1a170322019-02-05 00:39:33 +000058 int f(int *p) __attribute__((nonnull));
Alexander Kornienko9a857d22019-02-11 15:17:13 +000059
Kristof Umann1a170322019-02-05 00:39:33 +000060 void test(int *p) {
61 if (!p)
62 f(p); // warn
63 }
64
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +000065.. _core-NullDereference:
66
Kristof Umann1a170322019-02-05 00:39:33 +000067core.NullDereference (C, C++, ObjC)
68"""""""""""""""""""""""""""""""""""
69Check for dereferences of null pointers.
70
71.. code-block:: objc
72
73 // C
74 void test(int *p) {
75 if (p)
76 return;
Alexander Kornienko9a857d22019-02-11 15:17:13 +000077
Kristof Umann1a170322019-02-05 00:39:33 +000078 int x = p[0]; // warn
79 }
Alexander Kornienko9a857d22019-02-11 15:17:13 +000080
Kristof Umann1a170322019-02-05 00:39:33 +000081 // C
82 void test(int *p) {
83 if (!p)
84 *p = 0; // warn
85 }
Alexander Kornienko9a857d22019-02-11 15:17:13 +000086
Kristof Umann1a170322019-02-05 00:39:33 +000087 // C++
88 class C {
89 public:
90 int x;
91 };
Alexander Kornienko9a857d22019-02-11 15:17:13 +000092
Kristof Umann1a170322019-02-05 00:39:33 +000093 void test() {
94 C *pc = 0;
95 int k = pc->x; // warn
96 }
Alexander Kornienko9a857d22019-02-11 15:17:13 +000097
Kristof Umann1a170322019-02-05 00:39:33 +000098 // Objective-C
99 @interface MyClass {
100 @public
101 int x;
102 }
103 @end
Alexander Kornienko9a857d22019-02-11 15:17:13 +0000104
Kristof Umann1a170322019-02-05 00:39:33 +0000105 void test() {
106 MyClass *obj = 0;
107 obj->x = 1; // warn
108 }
109
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +0000110.. _core-StackAddressEscape:
111
Kristof Umann1a170322019-02-05 00:39:33 +0000112core.StackAddressEscape (C)
113"""""""""""""""""""""""""""
114Check that addresses to stack memory do not escape the function.
115
116.. code-block:: c
117
118 char const *p;
Alexander Kornienko9a857d22019-02-11 15:17:13 +0000119
Kristof Umann1a170322019-02-05 00:39:33 +0000120 void test() {
121 char const str[] = "string";
122 p = str; // warn
123 }
Alexander Kornienko9a857d22019-02-11 15:17:13 +0000124
Kristof Umann1a170322019-02-05 00:39:33 +0000125 void* test() {
126 return __builtin_alloca(12); // warn
127 }
Alexander Kornienko9a857d22019-02-11 15:17:13 +0000128
Kristof Umann1a170322019-02-05 00:39:33 +0000129 void test() {
130 static int *x;
131 int y;
132 x = &y; // warn
133 }
134
135
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +0000136.. _core-UndefinedBinaryOperatorResult:
137
Kristof Umann1a170322019-02-05 00:39:33 +0000138core.UndefinedBinaryOperatorResult (C)
139""""""""""""""""""""""""""""""""""""""
140Check for undefined results of binary operators.
141
142.. code-block:: c
143
144 void test() {
145 int x;
146 int y = x + 1; // warn: left operand is garbage
147 }
148
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +0000149.. _core-VLASize:
150
Alexander Kornienko9a857d22019-02-11 15:17:13 +0000151core.VLASize (C)
Kristof Umann1a170322019-02-05 00:39:33 +0000152""""""""""""""""
153Check for declarations of Variable Length Arrays of undefined or zero size.
154
155 Check for declarations of VLA of undefined or zero size.
Alexander Kornienko9a857d22019-02-11 15:17:13 +0000156
Kristof Umann1a170322019-02-05 00:39:33 +0000157.. code-block:: c
158
159 void test() {
160 int x;
161 int vla1[x]; // warn: garbage as size
162 }
Alexander Kornienko9a857d22019-02-11 15:17:13 +0000163
Kristof Umann1a170322019-02-05 00:39:33 +0000164 void test() {
165 int x = 0;
166 int vla2[x]; // warn: zero size
167 }
168
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +0000169.. _core-uninitialized-ArraySubscript:
170
Kristof Umann1a170322019-02-05 00:39:33 +0000171core.uninitialized.ArraySubscript (C)
172"""""""""""""""""""""""""""""""""""""
173Check for uninitialized values used as array subscripts.
174
175.. code-block:: c
176
177 void test() {
178 int i, a[10];
179 int x = a[i]; // warn: array subscript is undefined
180 }
181
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +0000182.. _core-uninitialized-Assign:
183
Kristof Umann1a170322019-02-05 00:39:33 +0000184core.uninitialized.Assign (C)
185"""""""""""""""""""""""""""""
186Check for assigning uninitialized values.
187
188.. code-block:: c
189
190 void test() {
191 int x;
192 x |= 1; // warn: left expression is uninitialized
193 }
194
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +0000195.. _core-uninitialized-Branch:
196
Kristof Umann1a170322019-02-05 00:39:33 +0000197core.uninitialized.Branch (C)
198"""""""""""""""""""""""""""""
199Check for uninitialized values used as branch conditions.
200
201.. code-block:: c
202
203 void test() {
204 int x;
205 if (x) // warn
206 return;
207 }
208
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +0000209.. _core-uninitialized-CapturedBlockVariable:
210
Kristof Umann1a170322019-02-05 00:39:33 +0000211core.uninitialized.CapturedBlockVariable (C)
212""""""""""""""""""""""""""""""""""""""""""""
213Check for blocks that capture uninitialized values.
214
215.. code-block:: c
216
217 void test() {
218 int x;
219 ^{ int y = x; }(); // warn
220 }
221
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +0000222.. _core-uninitialized-UndefReturn:
223
Kristof Umann1a170322019-02-05 00:39:33 +0000224core.uninitialized.UndefReturn (C)
225""""""""""""""""""""""""""""""""""
226Check for uninitialized values being returned to the caller.
227
228.. code-block:: c
229
230 int test() {
231 int x;
232 return x; // warn
233 }
234
235.. _cplusplus-checkers:
236
237
Mandeep Singh Grang0cdc5dd2019-05-24 19:24:08 +0000238cplusplus
239^^^^^^^^^
Kristof Umann1a170322019-02-05 00:39:33 +0000240
241C++ Checkers.
242
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +0000243.. _cplusplus-InnerPointer:
244
Kristof Umann1a170322019-02-05 00:39:33 +0000245cplusplus.InnerPointer
246""""""""""""""""""""""
247Check for inner pointers of C++ containers used after re/deallocation.
248
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +0000249.. _cplusplus-NewDelete:
250
Alexander Kornienko9a857d22019-02-11 15:17:13 +0000251cplusplus.NewDelete (C++)
Kristof Umann1a170322019-02-05 00:39:33 +0000252"""""""""""""""""""""""""
253Check for double-free and use-after-free problems. Traces memory managed by new/delete.
254
255.. literalinclude:: checkers/newdelete_example.cpp
256 :language: cpp
Alexander Kornienko9a857d22019-02-11 15:17:13 +0000257
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +0000258.. _cplusplus-NewDeleteLeaks:
259
Alexander Kornienko9a857d22019-02-11 15:17:13 +0000260cplusplus.NewDeleteLeaks (C++)
Kristof Umann1a170322019-02-05 00:39:33 +0000261""""""""""""""""""""""""""""""
262Check for memory leaks. Traces memory managed by new/delete.
263
264.. code-block:: cpp
265
266 void test() {
267 int *p = new int;
268 } // warn
269
270
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +0000271.. _cplusplus-SelfAssignment:
272
Alexander Kornienko9a857d22019-02-11 15:17:13 +0000273cplusplus.SelfAssignment (C++)
Kristof Umann1a170322019-02-05 00:39:33 +0000274""""""""""""""""""""""""""""""
275Checks C++ copy and move assignment operators for self assignment.
276
277.. _deadcode-checkers:
278
279deadcode
280^^^^^^^^
281
282Dead Code Checkers.
Alexander Kornienko9a857d22019-02-11 15:17:13 +0000283
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +0000284.. _deadcode-DeadStores:
285
Alexander Kornienko9a857d22019-02-11 15:17:13 +0000286deadcode.DeadStores (C)
Kristof Umann1a170322019-02-05 00:39:33 +0000287"""""""""""""""""""""""
288Check for values stored to variables that are never read afterwards.
289
290.. code-block:: c
291
292 void test() {
293 int x;
294 x = 1; // warn
295 }
296
297.. _nullability-checkers:
298
299nullability
300^^^^^^^^^^^
301
302Objective C checkers that warn for null pointer passing and dereferencing errors.
303
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +0000304.. _nullability-NullPassedToNonnull:
305
Kristof Umann1a170322019-02-05 00:39:33 +0000306nullability.NullPassedToNonnull (ObjC)
307""""""""""""""""""""""""""""""""""""""
308Warns when a null pointer is passed to a pointer which has a _Nonnull type.
309
310.. code-block:: objc
311
312 if (name != nil)
313 return;
314 // Warning: nil passed to a callee that requires a non-null 1st parameter
315 NSString *greeting = [@"Hello " stringByAppendingString:name];
316
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +0000317.. _nullability-NullReturnedFromNonnull:
318
Alexander Kornienko9a857d22019-02-11 15:17:13 +0000319nullability.NullReturnedFromNonnull (ObjC)
Kristof Umann1a170322019-02-05 00:39:33 +0000320""""""""""""""""""""""""""""""""""""""""""
321Warns when a null pointer is returned from a function that has _Nonnull return type.
322
323.. code-block:: objc
324
325 - (nonnull id)firstChild {
326 id result = nil;
327 if ([_children count] > 0)
328 result = _children[0];
Alexander Kornienko9a857d22019-02-11 15:17:13 +0000329
Kristof Umann1a170322019-02-05 00:39:33 +0000330 // Warning: nil returned from a method that is expected
331 // to return a non-null value
332 return result;
333 }
334
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +0000335.. _nullability-NullableDereferenced:
336
Kristof Umann1a170322019-02-05 00:39:33 +0000337nullability.NullableDereferenced (ObjC)
338"""""""""""""""""""""""""""""""""""""""
339Warns when a nullable pointer is dereferenced.
340
341.. code-block:: objc
Alexander Kornienko9a857d22019-02-11 15:17:13 +0000342
Kristof Umann1a170322019-02-05 00:39:33 +0000343 struct LinkedList {
344 int data;
345 struct LinkedList *next;
346 };
Alexander Kornienko9a857d22019-02-11 15:17:13 +0000347
Kristof Umann1a170322019-02-05 00:39:33 +0000348 struct LinkedList * _Nullable getNext(struct LinkedList *l);
Alexander Kornienko9a857d22019-02-11 15:17:13 +0000349
Kristof Umann1a170322019-02-05 00:39:33 +0000350 void updateNextData(struct LinkedList *list, int newData) {
351 struct LinkedList *next = getNext(list);
352 // Warning: Nullable pointer is dereferenced
353 next->data = 7;
354 }
355
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +0000356.. _nullability-NullablePassedToNonnull:
357
Kristof Umann1a170322019-02-05 00:39:33 +0000358nullability.NullablePassedToNonnull (ObjC)
359""""""""""""""""""""""""""""""""""""""""""
360Warns when a nullable pointer is passed to a pointer which has a _Nonnull type.
361
362.. code-block:: objc
Alexander Kornienko9a857d22019-02-11 15:17:13 +0000363
Kristof Umann1a170322019-02-05 00:39:33 +0000364 typedef struct Dummy { int val; } Dummy;
365 Dummy *_Nullable returnsNullable();
366 void takesNonnull(Dummy *_Nonnull);
Alexander Kornienko9a857d22019-02-11 15:17:13 +0000367
Kristof Umann1a170322019-02-05 00:39:33 +0000368 void test() {
369 Dummy *p = returnsNullable();
370 takesNonnull(p); // warn
371 }
372
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +0000373.. _nullability-NullableReturnedFromNonnull:
374
Alexander Kornienko9a857d22019-02-11 15:17:13 +0000375nullability.NullableReturnedFromNonnull (ObjC)
Kristof Umann1a170322019-02-05 00:39:33 +0000376""""""""""""""""""""""""""""""""""""""""""""""
377Warns when a nullable pointer is returned from a function that has _Nonnull return type.
378
379.. _optin-checkers:
380
381optin
382^^^^^
383
384Checkers for portability, performance or coding style specific rules.
385
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +0000386.. _optin-cplusplus-UninitializedObject:
387
Kristof Umann85e0ff72019-04-19 23:33:50 +0000388optin.cplusplus.UninitializedObject (C++)
Nico Weber83c95b12019-05-03 18:54:18 +0000389"""""""""""""""""""""""""""""""""""""""""
Kristof Umann85e0ff72019-04-19 23:33:50 +0000390
391This checker reports uninitialized fields in objects created after a constructor
392call. It doesn't only find direct uninitialized fields, but rather makes a deep
393inspection of the object, analyzing all of it's fields subfields.
394The checker regards inherited fields as direct fields, so one will recieve
395warnings for uninitialized inherited data members as well.
396
397.. code-block:: cpp
398
399 // With Pedantic and CheckPointeeInitialization set to true
400
401 struct A {
402 struct B {
403 int x; // note: uninitialized field 'this->b.x'
404 // note: uninitialized field 'this->bptr->x'
405 int y; // note: uninitialized field 'this->b.y'
406 // note: uninitialized field 'this->bptr->y'
407 };
408 int *iptr; // note: uninitialized pointer 'this->iptr'
409 B b;
410 B *bptr;
411 char *cptr; // note: uninitialized pointee 'this->cptr'
412
413 A (B *bptr, char *cptr) : bptr(bptr), cptr(cptr) {}
414 };
415
416 void f() {
417 A::B b;
418 char c;
419 A a(&b, &c); // warning: 6 uninitialized fields
420 // after the constructor call
421 }
422
423 // With Pedantic set to false and
424 // CheckPointeeInitialization set to true
425 // (every field is uninitialized)
426
427 struct A {
428 struct B {
429 int x;
430 int y;
431 };
432 int *iptr;
433 B b;
434 B *bptr;
435 char *cptr;
436
437 A (B *bptr, char *cptr) : bptr(bptr), cptr(cptr) {}
438 };
439
440 void f() {
441 A::B b;
442 char c;
443 A a(&b, &c); // no warning
444 }
445
446 // With Pedantic set to true and
447 // CheckPointeeInitialization set to false
448 // (pointees are regarded as initialized)
449
450 struct A {
451 struct B {
452 int x; // note: uninitialized field 'this->b.x'
453 int y; // note: uninitialized field 'this->b.y'
454 };
455 int *iptr; // note: uninitialized pointer 'this->iptr'
456 B b;
457 B *bptr;
458 char *cptr;
459
460 A (B *bptr, char *cptr) : bptr(bptr), cptr(cptr) {}
461 };
462
463 void f() {
464 A::B b;
465 char c;
466 A a(&b, &c); // warning: 3 uninitialized fields
467 // after the constructor call
468 }
469
470
471**Options**
472
473This checker has several options which can be set from command line (e.g.
474``-analyzer-config optin.cplusplus.UninitializedObject:Pedantic=true``):
475
476* ``Pedantic`` (boolean). If to false, the checker won't emit warnings for
477 objects that don't have at least one initialized field. Defaults to false.
478
479* ``NotesAsWarnings`` (boolean). If set to true, the checker will emit a
480 warning for each uninitalized field, as opposed to emitting one warning per
481 constructor call, and listing the uninitialized fields that belongs to it in
482 notes. *Defaults to false*.
483
484* ``CheckPointeeInitialization`` (boolean). If set to false, the checker will
485 not analyze the pointee of pointer/reference fields, and will only check
486 whether the object itself is initialized. *Defaults to false*.
487
488* ``IgnoreRecordsWithField`` (string). If supplied, the checker will not analyze
489 structures that have a field with a name or type name that matches the given
490 pattern. *Defaults to ""*.
491
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +0000492.. _optin-cplusplus-VirtualCall:
493
Kristof Umann1a170322019-02-05 00:39:33 +0000494optin.cplusplus.VirtualCall (C++)
495"""""""""""""""""""""""""""""""""
496Check virtual function calls during construction or destruction.
497
498.. code-block:: cpp
499
500 class A {
501 public:
502 A() {
503 f(); // warn
504 }
505 virtual void f();
506 };
Alexander Kornienko9a857d22019-02-11 15:17:13 +0000507
Kristof Umann1a170322019-02-05 00:39:33 +0000508 class A {
509 public:
510 ~A() {
511 this->f(); // warn
512 }
513 virtual void f();
514 };
515
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +0000516.. _optin-mpi-MPI-Checker:
517
Kristof Umann1a170322019-02-05 00:39:33 +0000518optin.mpi.MPI-Checker (C)
519"""""""""""""""""""""""""
520Checks MPI code.
521
522.. code-block:: c
523
524 void test() {
525 double buf = 0;
526 MPI_Request sendReq1;
527 MPI_Ireduce(MPI_IN_PLACE, &buf, 1, MPI_DOUBLE, MPI_SUM,
528 0, MPI_COMM_WORLD, &sendReq1);
529 } // warn: request 'sendReq1' has no matching wait.
Alexander Kornienko9a857d22019-02-11 15:17:13 +0000530
Kristof Umann1a170322019-02-05 00:39:33 +0000531 void test() {
532 double buf = 0;
533 MPI_Request sendReq;
534 MPI_Isend(&buf, 1, MPI_DOUBLE, 0, 0, MPI_COMM_WORLD, &sendReq);
535 MPI_Irecv(&buf, 1, MPI_DOUBLE, 0, 0, MPI_COMM_WORLD, &sendReq); // warn
536 MPI_Isend(&buf, 1, MPI_DOUBLE, 0, 0, MPI_COMM_WORLD, &sendReq); // warn
537 MPI_Wait(&sendReq, MPI_STATUS_IGNORE);
538 }
Alexander Kornienko9a857d22019-02-11 15:17:13 +0000539
Kristof Umann1a170322019-02-05 00:39:33 +0000540 void missingNonBlocking() {
541 int rank = 0;
542 MPI_Comm_rank(MPI_COMM_WORLD, &rank);
543 MPI_Request sendReq1[10][10][10];
544 MPI_Wait(&sendReq1[1][7][9], MPI_STATUS_IGNORE); // warn
545 }
546
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +0000547.. _optin-osx-cocoa-localizability-EmptyLocalizationContextChecker:
548
Kristof Umann1a170322019-02-05 00:39:33 +0000549optin.osx.cocoa.localizability.EmptyLocalizationContextChecker (ObjC)
550"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
551Check that NSLocalizedString macros include a comment for context.
552
553.. code-block:: objc
554
555 - (void)test {
556 NSString *string = NSLocalizedString(@"LocalizedString", nil); // warn
557 NSString *string2 = NSLocalizedString(@"LocalizedString", @" "); // warn
558 NSString *string3 = NSLocalizedStringWithDefaultValue(
559 @"LocalizedString", nil, [[NSBundle alloc] init], nil,@""); // warn
560 }
561
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +0000562.. _optin-osx-cocoa-localizability-NonLocalizedStringChecker:
563
Alexander Kornienko9a857d22019-02-11 15:17:13 +0000564optin.osx.cocoa.localizability.NonLocalizedStringChecker (ObjC)
Kristof Umann1a170322019-02-05 00:39:33 +0000565"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
566Warns about uses of non-localized NSStrings passed to UI methods expecting localized NSStrings.
567
568.. code-block:: objc
Alexander Kornienko9a857d22019-02-11 15:17:13 +0000569
Kristof Umann1a170322019-02-05 00:39:33 +0000570 NSString *alarmText =
571 NSLocalizedString(@"Enabled", @"Indicates alarm is turned on");
572 if (!isEnabled) {
573 alarmText = @"Disabled";
574 }
575 UILabel *alarmStateLabel = [[UILabel alloc] init];
Alexander Kornienko9a857d22019-02-11 15:17:13 +0000576
Kristof Umann1a170322019-02-05 00:39:33 +0000577 // Warning: User-facing text should use localized string macro
578 [alarmStateLabel setText:alarmText];
579
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +0000580.. _optin-performance-GCDAntipattern:
581
Kristof Umann1a170322019-02-05 00:39:33 +0000582optin.performance.GCDAntipattern
583""""""""""""""""""""""""""""""""
584Check for performance anti-patterns when using Grand Central Dispatch.
585
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +0000586.. _optin-performance-Padding:
587
Kristof Umann1a170322019-02-05 00:39:33 +0000588optin.performance.Padding
589"""""""""""""""""""""""""
590Check for excessively padded structs.
591
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +0000592.. _optin-portability-UnixAPI:
593
Kristof Umann1a170322019-02-05 00:39:33 +0000594optin.portability.UnixAPI
595"""""""""""""""""""""""""
596Finds implementation-defined behavior in UNIX/Posix functions.
597
598
599.. _security-checkers:
600
601security
602^^^^^^^^
603
604Security related checkers.
605
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +0000606.. _security-FloatLoopCounter:
607
Alexander Kornienko9a857d22019-02-11 15:17:13 +0000608security.FloatLoopCounter (C)
Kristof Umann1a170322019-02-05 00:39:33 +0000609"""""""""""""""""""""""""""""
610Warn on using a floating point value as a loop counter (CERT: FLP30-C, FLP30-CPP).
611
612.. code-block:: c
Alexander Kornienko9a857d22019-02-11 15:17:13 +0000613
Kristof Umann1a170322019-02-05 00:39:33 +0000614 void test() {
615 for (float x = 0.1f; x <= 1.0f; x += 0.1f) {} // warn
616 }
617
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +0000618.. _security-insecureAPI-UncheckedReturn:
619
Alexander Kornienko9a857d22019-02-11 15:17:13 +0000620security.insecureAPI.UncheckedReturn (C)
Kristof Umann1a170322019-02-05 00:39:33 +0000621""""""""""""""""""""""""""""""""""""""""
622Warn on uses of functions whose return values must be always checked.
623
624.. code-block:: c
Alexander Kornienko9a857d22019-02-11 15:17:13 +0000625
Kristof Umann1a170322019-02-05 00:39:33 +0000626 void test() {
627 setuid(1); // warn
628 }
629
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +0000630.. _security-insecureAPI-bcmp:
631
Kristof Umann1a170322019-02-05 00:39:33 +0000632security.insecureAPI.bcmp (C)
633"""""""""""""""""""""""""""""
634Warn on uses of the 'bcmp' function.
635
636.. code-block:: c
Alexander Kornienko9a857d22019-02-11 15:17:13 +0000637
Kristof Umann1a170322019-02-05 00:39:33 +0000638 void test() {
639 bcmp(ptr0, ptr1, n); // warn
640 }
641
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +0000642.. _security-insecureAPI-bcopy:
643
Kristof Umann1a170322019-02-05 00:39:33 +0000644security.insecureAPI.bcopy (C)
645""""""""""""""""""""""""""""""
646Warn on uses of the 'bcopy' function.
647
648.. code-block:: c
649
650 void test() {
651 bcopy(src, dst, n); // warn
652 }
653
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +0000654.. _security-insecureAPI-bzero:
655
Kristof Umann1a170322019-02-05 00:39:33 +0000656security.insecureAPI.bzero (C)
657""""""""""""""""""""""""""""""
658Warn on uses of the 'bzero' function.
659
660.. code-block:: c
Alexander Kornienko9a857d22019-02-11 15:17:13 +0000661
Kristof Umann1a170322019-02-05 00:39:33 +0000662 void test() {
663 bzero(ptr, n); // warn
664 }
665
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +0000666.. _security-insecureAPI-getpw:
667
Alexander Kornienko9a857d22019-02-11 15:17:13 +0000668security.insecureAPI.getpw (C)
Kristof Umann1a170322019-02-05 00:39:33 +0000669""""""""""""""""""""""""""""""
670Warn on uses of the 'getpw' function.
671
672.. code-block:: c
Alexander Kornienko9a857d22019-02-11 15:17:13 +0000673
Kristof Umann1a170322019-02-05 00:39:33 +0000674 void test() {
675 char buff[1024];
676 getpw(2, buff); // warn
677 }
678
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +0000679.. _security-insecureAPI-gets:
680
Kristof Umann1a170322019-02-05 00:39:33 +0000681security.insecureAPI.gets (C)
682"""""""""""""""""""""""""""""
683Warn on uses of the 'gets' function.
684
685.. code-block:: c
Alexander Kornienko9a857d22019-02-11 15:17:13 +0000686
Kristof Umann1a170322019-02-05 00:39:33 +0000687 void test() {
688 char buff[1024];
689 gets(buff); // warn
690 }
691
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +0000692.. _security-insecureAPI-mkstemp:
693
Kristof Umann1a170322019-02-05 00:39:33 +0000694security.insecureAPI.mkstemp (C)
695""""""""""""""""""""""""""""""""
696Warn when 'mkstemp' is passed fewer than 6 X's in the format string.
697
698.. code-block:: c
699
700 void test() {
701 mkstemp("XX"); // warn
702 }
Alexander Kornienko9a857d22019-02-11 15:17:13 +0000703
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +0000704.. _security-insecureAPI-mktemp:
705
Alexander Kornienko9a857d22019-02-11 15:17:13 +0000706security.insecureAPI.mktemp (C)
Kristof Umann1a170322019-02-05 00:39:33 +0000707"""""""""""""""""""""""""""""""
708Warn on uses of the ``mktemp`` function.
709
710.. code-block:: c
Alexander Kornienko9a857d22019-02-11 15:17:13 +0000711
Kristof Umann1a170322019-02-05 00:39:33 +0000712 void test() {
713 char *x = mktemp("/tmp/zxcv"); // warn: insecure, use mkstemp
714 }
715
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +0000716.. _security-insecureAPI-rand:
717
Alexander Kornienko9a857d22019-02-11 15:17:13 +0000718security.insecureAPI.rand (C)
Kristof Umann1a170322019-02-05 00:39:33 +0000719"""""""""""""""""""""""""""""
Alexander Kornienko9a857d22019-02-11 15:17:13 +0000720Warn on uses of inferior random number generating functions (only if arc4random function is available):
Kristof Umann1a170322019-02-05 00:39:33 +0000721``drand48, erand48, jrand48, lcong48, lrand48, mrand48, nrand48, random, rand_r``.
722
723.. code-block:: c
Alexander Kornienko9a857d22019-02-11 15:17:13 +0000724
Kristof Umann1a170322019-02-05 00:39:33 +0000725 void test() {
726 random(); // warn
727 }
Alexander Kornienko9a857d22019-02-11 15:17:13 +0000728
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +0000729.. _security-insecureAPI-strcpy:
730
Kristof Umann1a170322019-02-05 00:39:33 +0000731security.insecureAPI.strcpy (C)
732"""""""""""""""""""""""""""""""
733Warn on uses of the ``strcpy`` and ``strcat`` functions.
734
735.. code-block:: c
Alexander Kornienko9a857d22019-02-11 15:17:13 +0000736
Kristof Umann1a170322019-02-05 00:39:33 +0000737 void test() {
738 char x[4];
739 char *y = "abcd";
Alexander Kornienko9a857d22019-02-11 15:17:13 +0000740
Kristof Umann1a170322019-02-05 00:39:33 +0000741 strcpy(x, y); // warn
742 }
743
744
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +0000745.. _security-insecureAPI-vfork:
746
Alexander Kornienko9a857d22019-02-11 15:17:13 +0000747security.insecureAPI.vfork (C)
Kristof Umann1a170322019-02-05 00:39:33 +0000748""""""""""""""""""""""""""""""
749 Warn on uses of the 'vfork' function.
750
751.. code-block:: c
Alexander Kornienko9a857d22019-02-11 15:17:13 +0000752
Kristof Umann1a170322019-02-05 00:39:33 +0000753 void test() {
754 vfork(); // warn
755 }
756
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +0000757.. _security-insecureAPI-DeprecatedOrUnsafeBufferHandling:
758
Alexander Kornienko9a857d22019-02-11 15:17:13 +0000759security.insecureAPI.DeprecatedOrUnsafeBufferHandling (C)
760"""""""""""""""""""""""""""""""""""""""""""""""""""""""""
Kristof Umann8d239992019-02-11 13:46:43 +0000761 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``
762
763.. code-block:: c
Alexander Kornienko9a857d22019-02-11 15:17:13 +0000764
Kristof Umann8d239992019-02-11 13:46:43 +0000765 void test() {
766 char buf [5];
767 strncpy(buf, "a", 1); // warn
768 }
769
Kristof Umann1a170322019-02-05 00:39:33 +0000770.. _unix-checkers:
771
772unix
773^^^^
774POSIX/Unix checkers.
775
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +0000776.. _unix-API:
777
Alexander Kornienko9a857d22019-02-11 15:17:13 +0000778unix.API (C)
Kristof Umann1a170322019-02-05 00:39:33 +0000779""""""""""""
780Check calls to various UNIX/Posix functions: ``open, pthread_once, calloc, malloc, realloc, alloca``.
781
Alexander Kornienko9a857d22019-02-11 15:17:13 +0000782.. literalinclude:: checkers/unix_api_example.c
Kristof Umann1a170322019-02-05 00:39:33 +0000783 :language: c
784
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +0000785.. _unix-Malloc:
786
Alexander Kornienko9a857d22019-02-11 15:17:13 +0000787unix.Malloc (C)
Kristof Umann1a170322019-02-05 00:39:33 +0000788"""""""""""""""
789Check for memory leaks, double free, and use-after-free problems. Traces memory managed by malloc()/free().
790
Alexander Kornienko9a857d22019-02-11 15:17:13 +0000791.. literalinclude:: checkers/unix_malloc_example.c
Kristof Umann1a170322019-02-05 00:39:33 +0000792 :language: c
Alexander Kornienko9a857d22019-02-11 15:17:13 +0000793
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +0000794.. _unix-MallocSizeof:
795
Alexander Kornienko9a857d22019-02-11 15:17:13 +0000796unix.MallocSizeof (C)
Kristof Umann1a170322019-02-05 00:39:33 +0000797"""""""""""""""""""""
798Check for dubious ``malloc`` arguments involving ``sizeof``.
799
800.. code-block:: c
Alexander Kornienko9a857d22019-02-11 15:17:13 +0000801
Kristof Umann1a170322019-02-05 00:39:33 +0000802 void test() {
803 long *p = malloc(sizeof(short));
804 // warn: result is converted to 'long *', which is
805 // incompatible with operand type 'short'
806 free(p);
807 }
808
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +0000809.. _unix-MismatchedDeallocator:
810
Kristof Umann1a170322019-02-05 00:39:33 +0000811unix.MismatchedDeallocator (C, C++)
812"""""""""""""""""""""""""""""""""""
813Check for mismatched deallocators.
814
Alexander Kornienko9a857d22019-02-11 15:17:13 +0000815.. literalinclude:: checkers/mismatched_deallocator_example.cpp
Kristof Umann1a170322019-02-05 00:39:33 +0000816 :language: c
817
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +0000818.. _unix-Vfork:
819
Alexander Kornienko9a857d22019-02-11 15:17:13 +0000820unix.Vfork (C)
Kristof Umann1a170322019-02-05 00:39:33 +0000821""""""""""""""
822Check for proper usage of ``vfork``.
823
824.. code-block:: c
Alexander Kornienko9a857d22019-02-11 15:17:13 +0000825
Kristof Umann1a170322019-02-05 00:39:33 +0000826 int test(int x) {
827 pid_t pid = vfork(); // warn
828 if (pid != 0)
829 return 0;
Alexander Kornienko9a857d22019-02-11 15:17:13 +0000830
Kristof Umann1a170322019-02-05 00:39:33 +0000831 switch (x) {
832 case 0:
833 pid = 1;
834 execl("", "", 0);
835 _exit(1);
836 break;
837 case 1:
838 x = 0; // warn: this assignment is prohibited
839 break;
840 case 2:
841 foo(); // warn: this function call is prohibited
842 break;
843 default:
844 return 0; // warn: return is prohibited
845 }
Alexander Kornienko9a857d22019-02-11 15:17:13 +0000846
Kristof Umann1a170322019-02-05 00:39:33 +0000847 while(1);
848 }
849
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +0000850.. _unix-cstring-BadSizeArg:
851
Alexander Kornienko9a857d22019-02-11 15:17:13 +0000852unix.cstring.BadSizeArg (C)
Kristof Umann1a170322019-02-05 00:39:33 +0000853"""""""""""""""""""""""""""
Alexander Kornienko9a857d22019-02-11 15:17:13 +0000854Check 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.
Kristof Umann1a170322019-02-05 00:39:33 +0000855
856.. code-block:: c
Alexander Kornienko9a857d22019-02-11 15:17:13 +0000857
Kristof Umann1a170322019-02-05 00:39:33 +0000858 void test() {
859 char dest[3];
860 strncat(dest, """""""""""""""""""""""""*", sizeof(dest));
861 // warn: potential buffer overflow
862 }
863
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +0000864.. _unix-cstrisng-NullArg:
865
Alexander Kornienko9a857d22019-02-11 15:17:13 +0000866unix.cstrisng.NullArg (C)
Kristof Umann1a170322019-02-05 00:39:33 +0000867"""""""""""""""""""""""""
Alexander Kornienko9a857d22019-02-11 15:17:13 +0000868Check for null pointers being passed as arguments to C string functions:
Kristof Umann1a170322019-02-05 00:39:33 +0000869``strlen, strnlen, strcpy, strncpy, strcat, strncat, strcmp, strncmp, strcasecmp, strncasecmp``.
870
871.. code-block:: c
872
873 int test() {
874 return strlen(0); // warn
875 }
876
877.. _osx-checkers:
878
879osx
880^^^
J. Ryan Stinnettd45eaf92019-05-30 16:46:22 +0000881macOS checkers.
Alexander Kornienko9a857d22019-02-11 15:17:13 +0000882
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +0000883.. _osx-API:
884
Alexander Kornienko9a857d22019-02-11 15:17:13 +0000885osx.API (C)
Kristof Umann1a170322019-02-05 00:39:33 +0000886"""""""""""
887Check for proper uses of various Apple APIs.
888
889.. code-block:: objc
890
891 void test() {
892 dispatch_once_t pred = 0;
893 dispatch_once(&pred, ^(){}); // warn: dispatch_once uses local
894 }
895
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +0000896.. _osx-NumberObjectConversion:
897
Kristof Umann1a170322019-02-05 00:39:33 +0000898osx.NumberObjectConversion (C, C++, ObjC)
899"""""""""""""""""""""""""""""""""""""""""
900Check for erroneous conversions of objects representing numbers into numbers.
901
902.. code-block:: objc
Alexander Kornienko9a857d22019-02-11 15:17:13 +0000903
Kristof Umann1a170322019-02-05 00:39:33 +0000904 NSNumber *photoCount = [albumDescriptor objectForKey:@"PhotoCount"];
905 // Warning: Comparing a pointer value of type 'NSNumber *'
906 // to a scalar integer value
907 if (photoCount > 0) {
908 [self displayPhotos];
909 }
910
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +0000911.. _osx-ObjCProperty:
912
Kristof Umann1a170322019-02-05 00:39:33 +0000913osx.ObjCProperty (ObjC)
914"""""""""""""""""""""""
915Check for proper uses of Objective-C properties.
916
917.. code-block:: objc
Alexander Kornienko9a857d22019-02-11 15:17:13 +0000918
Kristof Umann1a170322019-02-05 00:39:33 +0000919 NSNumber *photoCount = [albumDescriptor objectForKey:@"PhotoCount"];
920 // Warning: Comparing a pointer value of type 'NSNumber *'
921 // to a scalar integer value
922 if (photoCount > 0) {
923 [self displayPhotos];
924 }
925
926
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +0000927.. _osx-SecKeychainAPI:
928
Alexander Kornienko9a857d22019-02-11 15:17:13 +0000929osx.SecKeychainAPI (C)
Kristof Umann1a170322019-02-05 00:39:33 +0000930""""""""""""""""""""""
931Check for proper uses of Secure Keychain APIs.
932
Alexander Kornienko9a857d22019-02-11 15:17:13 +0000933.. literalinclude:: checkers/seckeychainapi_example.m
Kristof Umann1a170322019-02-05 00:39:33 +0000934 :language: objc
935
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +0000936.. _osx-cocoa-AtSync:
937
Kristof Umann1a170322019-02-05 00:39:33 +0000938osx.cocoa.AtSync (ObjC)
939"""""""""""""""""""""""
940Check for nil pointers used as mutexes for @synchronized.
941
942.. code-block:: objc
943
944 void test(id x) {
945 if (!x)
946 @synchronized(x) {} // warn: nil value used as mutex
947 }
Alexander Kornienko9a857d22019-02-11 15:17:13 +0000948
Kristof Umann1a170322019-02-05 00:39:33 +0000949 void test() {
950 id y;
951 @synchronized(y) {} // warn: uninitialized value used as mutex
952 }
953
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +0000954.. _osx-cocoa-AutoreleaseWrite:
955
Kristof Umann1a170322019-02-05 00:39:33 +0000956osx.cocoa.AutoreleaseWrite
Alexander Kornienko9a857d22019-02-11 15:17:13 +0000957""""""""""""""""""""""""""
Kristof Umann1a170322019-02-05 00:39:33 +0000958Warn about potentially crashing writes to autoreleasing objects from different autoreleasing pools in Objective-C.
959
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +0000960.. _osx-cocoa-ClassRelease:
961
Kristof Umann1a170322019-02-05 00:39:33 +0000962osx.cocoa.ClassRelease (ObjC)
963"""""""""""""""""""""""""""""
964Check for sending 'retain', 'release', or 'autorelease' directly to a Class.
965
966.. code-block:: objc
Alexander Kornienko9a857d22019-02-11 15:17:13 +0000967
Kristof Umann1a170322019-02-05 00:39:33 +0000968 @interface MyClass : NSObject
969 @end
Alexander Kornienko9a857d22019-02-11 15:17:13 +0000970
Kristof Umann1a170322019-02-05 00:39:33 +0000971 void test(void) {
972 [MyClass release]; // warn
973 }
974
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +0000975.. _osx-cocoa-Dealloc:
976
Kristof Umann1a170322019-02-05 00:39:33 +0000977osx.cocoa.Dealloc (ObjC)
978""""""""""""""""""""""""
979Warn about Objective-C classes that lack a correct implementation of -dealloc
980
Alexander Kornienko9a857d22019-02-11 15:17:13 +0000981.. literalinclude:: checkers/dealloc_example.m
Kristof Umann1a170322019-02-05 00:39:33 +0000982 :language: objc
983
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +0000984.. _osx-cocoa-IncompatibleMethodTypes:
985
Alexander Kornienko9a857d22019-02-11 15:17:13 +0000986osx.cocoa.IncompatibleMethodTypes (ObjC)
Kristof Umann1a170322019-02-05 00:39:33 +0000987""""""""""""""""""""""""""""""""""""""""
988Warn about Objective-C method signatures with type incompatibilities.
989
990.. code-block:: objc
Alexander Kornienko9a857d22019-02-11 15:17:13 +0000991
Kristof Umann1a170322019-02-05 00:39:33 +0000992 @interface MyClass1 : NSObject
993 - (int)foo;
994 @end
Alexander Kornienko9a857d22019-02-11 15:17:13 +0000995
Kristof Umann1a170322019-02-05 00:39:33 +0000996 @implementation MyClass1
997 - (int)foo { return 1; }
998 @end
Alexander Kornienko9a857d22019-02-11 15:17:13 +0000999
Kristof Umann1a170322019-02-05 00:39:33 +00001000 @interface MyClass2 : MyClass1
1001 - (float)foo;
1002 @end
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001003
Kristof Umann1a170322019-02-05 00:39:33 +00001004 @implementation MyClass2
1005 - (float)foo { return 1.0; } // warn
1006 @end
1007
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +00001008.. _osx-cocoa-Loops:
1009
Kristof Umann1a170322019-02-05 00:39:33 +00001010osx.cocoa.Loops
1011"""""""""""""""
1012Improved modeling of loops using Cocoa collection types.
1013
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +00001014.. _osx-cocoa-MissingSuperCall:
1015
Kristof Umann1a170322019-02-05 00:39:33 +00001016osx.cocoa.MissingSuperCall (ObjC)
1017"""""""""""""""""""""""""""""""""
1018Warn about Objective-C methods that lack a necessary call to super.
1019
1020.. code-block:: objc
1021
1022 @interface Test : UIViewController
1023 @end
1024 @implementation test
1025 - (void)viewDidLoad {} // warn
1026 @end
1027
1028
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +00001029.. _osx-cocoa-NSAutoreleasePool:
1030
Kristof Umann1a170322019-02-05 00:39:33 +00001031osx.cocoa.NSAutoreleasePool (ObjC)
1032""""""""""""""""""""""""""""""""""
1033Warn for suboptimal uses of NSAutoreleasePool in Objective-C GC mode.
1034
1035.. code-block:: objc
1036
1037 void test() {
1038 NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
1039 [pool release]; // warn
1040 }
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001041
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +00001042.. _osx-cocoa-NSError:
1043
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001044osx.cocoa.NSError (ObjC)
Kristof Umann1a170322019-02-05 00:39:33 +00001045""""""""""""""""""""""""
1046Check usage of NSError parameters.
1047
1048.. code-block:: objc
1049
1050 @interface A : NSObject
1051 - (void)foo:(NSError """""""""""""""""""""""")error;
1052 @end
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001053
Kristof Umann1a170322019-02-05 00:39:33 +00001054 @implementation A
1055 - (void)foo:(NSError """""""""""""""""""""""")error {
1056 // warn: method accepting NSError"""""""""""""""""""""""" should have a non-void
1057 // return value
1058 }
1059 @end
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001060
Kristof Umann1a170322019-02-05 00:39:33 +00001061 @interface A : NSObject
1062 - (BOOL)foo:(NSError """""""""""""""""""""""")error;
1063 @end
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001064
Kristof Umann1a170322019-02-05 00:39:33 +00001065 @implementation A
1066 - (BOOL)foo:(NSError """""""""""""""""""""""")error {
1067 *error = 0; // warn: potential null dereference
1068 return 0;
1069 }
1070 @end
1071
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +00001072.. _osx-cocoa-NilArg:
1073
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001074osx.cocoa.NilArg (ObjC)
Kristof Umann1a170322019-02-05 00:39:33 +00001075"""""""""""""""""""""""
1076Check for prohibited nil arguments to ObjC method calls.
1077
1078 - caseInsensitiveCompare:
1079 - compare:
1080 - compare:options:
1081 - compare:options:range:
1082 - compare:options:range:locale:
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001083 - componentsSeparatedByCharactersInSet:
Kristof Umann1a170322019-02-05 00:39:33 +00001084 - initWithFormat:
1085
1086.. code-block:: objc
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001087
Kristof Umann1a170322019-02-05 00:39:33 +00001088 NSComparisonResult test(NSString *s) {
1089 NSString *aString = nil;
1090 return [s caseInsensitiveCompare:aString];
1091 // warn: argument to 'NSString' method
1092 // 'caseInsensitiveCompare:' cannot be nil
1093 }
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001094
Kristof Umann1a170322019-02-05 00:39:33 +00001095
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +00001096.. _osx-cocoa-NonNilReturnValue:
1097
Kristof Umann1a170322019-02-05 00:39:33 +00001098osx.cocoa.NonNilReturnValue
1099"""""""""""""""""""""""""""
1100Models the APIs that are guaranteed to return a non-nil value.
1101
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +00001102.. _osx-cocoa-ObjCGenerics:
1103
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001104osx.cocoa.ObjCGenerics (ObjC)
Kristof Umann1a170322019-02-05 00:39:33 +00001105"""""""""""""""""""""""""""""
1106Check for type errors when using Objective-C generics.
1107
1108.. code-block:: objc
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001109
Kristof Umann1a170322019-02-05 00:39:33 +00001110 NSMutableArray *names = [NSMutableArray array];
1111 NSMutableArray *birthDates = names;
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001112
Kristof Umann1a170322019-02-05 00:39:33 +00001113 // Warning: Conversion from value of type 'NSDate *'
1114 // to incompatible type 'NSString *'
1115 [birthDates addObject: [NSDate date]];
1116
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +00001117.. _osx-cocoa-RetainCount:
1118
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001119osx.cocoa.RetainCount (ObjC)
Kristof Umann1a170322019-02-05 00:39:33 +00001120""""""""""""""""""""""""""""
1121Check for leaks and improper reference count management
1122
1123.. code-block:: objc
1124
1125 void test() {
1126 NSString *s = [[NSString alloc] init]; // warn
1127 }
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001128
Kristof Umann1a170322019-02-05 00:39:33 +00001129 CFStringRef test(char *bytes) {
1130 return CFStringCreateWithCStringNoCopy(
1131 0, bytes, NSNEXTSTEPStringEncoding, 0); // warn
1132 }
1133
1134
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +00001135.. _osx-cocoa-RunLoopAutoreleaseLeak:
1136
Kristof Umann1a170322019-02-05 00:39:33 +00001137osx.cocoa.RunLoopAutoreleaseLeak
1138""""""""""""""""""""""""""""""""
1139Check for leaked memory in autorelease pools that will never be drained.
1140
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +00001141.. _osx-cocoa-SelfInit:
1142
Kristof Umann1a170322019-02-05 00:39:33 +00001143osx.cocoa.SelfInit (ObjC)
1144"""""""""""""""""""""""""
1145Check that 'self' is properly initialized inside an initializer method.
1146
1147.. code-block:: objc
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001148
Kristof Umann1a170322019-02-05 00:39:33 +00001149 @interface MyObj : NSObject {
1150 id x;
1151 }
1152 - (id)init;
1153 @end
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001154
Kristof Umann1a170322019-02-05 00:39:33 +00001155 @implementation MyObj
1156 - (id)init {
1157 [super init];
1158 x = 0; // warn: instance variable used while 'self' is not
1159 // initialized
1160 return 0;
1161 }
1162 @end
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001163
Kristof Umann1a170322019-02-05 00:39:33 +00001164 @interface MyObj : NSObject
1165 - (id)init;
1166 @end
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001167
Kristof Umann1a170322019-02-05 00:39:33 +00001168 @implementation MyObj
1169 - (id)init {
1170 [super init];
1171 return self; // warn: returning uninitialized 'self'
1172 }
1173 @end
1174
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +00001175.. _osx-cocoa-SuperDealloc:
1176
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001177osx.cocoa.SuperDealloc (ObjC)
Kristof Umann1a170322019-02-05 00:39:33 +00001178"""""""""""""""""""""""""""""
1179Warn about improper use of '[super dealloc]' in Objective-C.
1180
1181.. code-block:: objc
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001182
Kristof Umann1a170322019-02-05 00:39:33 +00001183 @interface SuperDeallocThenReleaseIvarClass : NSObject {
1184 NSObject *_ivar;
1185 }
1186 @end
1187
1188 @implementation SuperDeallocThenReleaseIvarClass
1189 - (void)dealloc {
1190 [super dealloc];
1191 [_ivar release]; // warn
1192 }
1193 @end
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001194
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +00001195.. _osx-cocoa-UnusedIvars:
1196
Kristof Umann1a170322019-02-05 00:39:33 +00001197osx.cocoa.UnusedIvars (ObjC)
1198""""""""""""""""""""""""""""
1199Warn about private ivars that are never used.
1200
1201.. code-block:: objc
1202
1203 @interface MyObj : NSObject {
1204 @private
1205 id x; // warn
1206 }
1207 @end
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001208
Kristof Umann1a170322019-02-05 00:39:33 +00001209 @implementation MyObj
1210 @end
1211
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +00001212.. _osx-cocoa-VariadicMethodTypes:
1213
Kristof Umann1a170322019-02-05 00:39:33 +00001214osx.cocoa.VariadicMethodTypes (ObjC)
1215""""""""""""""""""""""""""""""""""""
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001216Check for passing non-Objective-C types to variadic collection
Kristof Umann1a170322019-02-05 00:39:33 +00001217initialization methods that expect only Objective-C types.
1218
1219.. code-block:: objc
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001220
Kristof Umann1a170322019-02-05 00:39:33 +00001221 void test() {
1222 [NSSet setWithObjects:@"Foo", "Bar", nil];
1223 // warn: argument should be an ObjC pointer type, not 'char *'
1224 }
1225
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +00001226.. _osx-coreFoundation-CFError:
1227
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001228osx.coreFoundation.CFError (C)
Kristof Umann1a170322019-02-05 00:39:33 +00001229""""""""""""""""""""""""""""""
1230Check usage of CFErrorRef* parameters
1231
1232.. code-block:: c
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001233
Kristof Umann1a170322019-02-05 00:39:33 +00001234 void test(CFErrorRef *error) {
1235 // warn: function accepting CFErrorRef* should have a
1236 // non-void return
1237 }
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001238
Kristof Umann1a170322019-02-05 00:39:33 +00001239 int foo(CFErrorRef *error) {
1240 *error = 0; // warn: potential null dereference
1241 return 0;
1242 }
1243
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +00001244.. _osx-coreFoundation-CFNumber:
1245
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001246osx.coreFoundation.CFNumber (C)
Kristof Umann1a170322019-02-05 00:39:33 +00001247"""""""""""""""""""""""""""""""
1248Check for proper uses of CFNumber APIs.
1249
1250.. code-block:: c
1251
1252 CFNumberRef test(unsigned char x) {
1253 return CFNumberCreate(0, kCFNumberSInt16Type, &x);
1254 // warn: 8 bit integer is used to initialize a 16 bit integer
1255 }
1256
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +00001257.. _osx-coreFoundation-CFRetainRelease:
1258
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001259osx.coreFoundation.CFRetainRelease (C)
Kristof Umann1a170322019-02-05 00:39:33 +00001260""""""""""""""""""""""""""""""""""""""
1261Check for null arguments to CFRetain/CFRelease/CFMakeCollectable.
1262
1263.. code-block:: c
1264
1265 void test(CFTypeRef p) {
1266 if (!p)
1267 CFRetain(p); // warn
1268 }
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001269
Kristof Umann1a170322019-02-05 00:39:33 +00001270 void test(int x, CFTypeRef p) {
1271 if (p)
1272 return;
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001273
Kristof Umann1a170322019-02-05 00:39:33 +00001274 CFRelease(p); // warn
1275 }
1276
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +00001277.. _osx-coreFoundation-containers-OutOfBounds:
1278
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001279osx.coreFoundation.containers.OutOfBounds (C)
Kristof Umann1a170322019-02-05 00:39:33 +00001280"""""""""""""""""""""""""""""""""""""""""""""
1281Checks for index out-of-bounds when using 'CFArray' API.
1282
1283.. code-block:: c
1284
1285 void test() {
1286 CFArrayRef A = CFArrayCreate(0, 0, 0, &kCFTypeArrayCallBacks);
1287 CFArrayGetValueAtIndex(A, 0); // warn
1288 }
1289
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +00001290.. _osx-coreFoundation-containers-PointerSizedValues:
1291
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001292osx.coreFoundation.containers.PointerSizedValues (C)
Kristof Umann1a170322019-02-05 00:39:33 +00001293""""""""""""""""""""""""""""""""""""""""""""""""""""
1294Warns if 'CFArray', 'CFDictionary', 'CFSet' are created with non-pointer-size values.
1295
1296.. code-block:: c
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001297
Kristof Umann1a170322019-02-05 00:39:33 +00001298 void test() {
1299 int x[] = { 1 };
1300 CFArrayRef A = CFArrayCreate(0, (const void """""""""""""""""""""""")x, 1,
1301 &kCFTypeArrayCallBacks); // warn
1302 }
1303
1304
1305.. _alpha-checkers:
1306
1307Experimental Checkers
1308---------------------
1309
1310*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.*
1311
1312alpha.clone
1313^^^^^^^^^^^
1314
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +00001315.. _alpha-clone-CloneChecker:
1316
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001317alpha.clone.CloneChecker (C, C++, ObjC)
Kristof Umann1a170322019-02-05 00:39:33 +00001318"""""""""""""""""""""""""""""""""""""""
1319Reports similar pieces of code.
1320
1321.. code-block:: c
1322
1323 void log();
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001324
Kristof Umann1a170322019-02-05 00:39:33 +00001325 int max(int a, int b) { // warn
1326 log();
1327 if (a > b)
1328 return a;
1329 return b;
1330 }
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001331
Kristof Umann1a170322019-02-05 00:39:33 +00001332 int maxClone(int x, int y) { // similar code here
1333 log();
1334 if (x > y)
1335 return x;
1336 return y;
1337 }
1338
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +00001339.. _alpha-core-BoolAssignment:
1340
Kristof Umann1a170322019-02-05 00:39:33 +00001341alpha.core.BoolAssignment (ObjC)
1342""""""""""""""""""""""""""""""""
1343Warn about assigning non-{0,1} values to boolean variables.
1344
1345.. code-block:: objc
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001346
Kristof Umann1a170322019-02-05 00:39:33 +00001347 void test() {
1348 BOOL b = -1; // warn
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001349 }
Kristof Umann1a170322019-02-05 00:39:33 +00001350
1351alpha.core
1352^^^^^^^^^^
1353
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +00001354.. _alpha-core-CallAndMessageUnInitRefArg:
1355
Kristof Umann1a170322019-02-05 00:39:33 +00001356alpha.core.CallAndMessageUnInitRefArg (C,C++, ObjC)
1357"""""""""""""""""""""""""""""""""""""""""""""""""""
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001358Check for logical errors for function calls and Objective-C
Kristof Umann1a170322019-02-05 00:39:33 +00001359message expressions (e.g., uninitialized arguments, null function pointers, and pointer to undefined variables).
1360
1361.. code-block:: c
1362
1363 void test(void) {
1364 int t;
1365 int &p = t;
1366 int &s = p;
1367 int &q = s;
1368 foo(q); // warn
1369 }
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001370
Kristof Umann1a170322019-02-05 00:39:33 +00001371 void test(void) {
1372 int x;
1373 foo(&x); // warn
1374 }
1375
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +00001376.. _alpha-core-CastSize:
1377
Kristof Umann1a170322019-02-05 00:39:33 +00001378alpha.core.CastSize (C)
1379"""""""""""""""""""""""
1380Check when casting a malloc'ed type ``T``, whether the size is a multiple of the size of ``T``.
1381
1382.. code-block:: c
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001383
Kristof Umann1a170322019-02-05 00:39:33 +00001384 void test() {
1385 int *x = (int *) malloc(11); // warn
1386 }
1387
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +00001388.. _alpha-core-CastToStruct:
1389
Kristof Umann1a170322019-02-05 00:39:33 +00001390alpha.core.CastToStruct (C, C++)
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001391""""""""""""""""""""""""""""""""
Kristof Umann1a170322019-02-05 00:39:33 +00001392Check for cast from non-struct pointer to struct pointer.
1393
1394.. code-block:: cpp
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001395
Kristof Umann1a170322019-02-05 00:39:33 +00001396 // C
1397 struct s {};
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001398
Kristof Umann1a170322019-02-05 00:39:33 +00001399 void test(int *p) {
1400 struct s *ps = (struct s *) p; // warn
1401 }
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001402
Kristof Umann1a170322019-02-05 00:39:33 +00001403 // C++
1404 class c {};
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001405
Kristof Umann1a170322019-02-05 00:39:33 +00001406 void test(int *p) {
1407 c *pc = (c *) p; // warn
1408 }
1409
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +00001410.. _alpha-core-Conversion:
1411
Kristof Umann1a170322019-02-05 00:39:33 +00001412alpha.core.Conversion (C, C++, ObjC)
1413""""""""""""""""""""""""""""""""""""
1414Loss of sign/precision in implicit conversions.
1415
1416.. code-block:: c
1417
1418 void test(unsigned U, signed S) {
1419 if (S > 10) {
1420 if (U < S) {
1421 }
1422 }
1423 if (S < -10) {
1424 if (U < S) { // warn (loss of sign)
1425 }
1426 }
1427 }
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001428
Kristof Umann1a170322019-02-05 00:39:33 +00001429 void test() {
1430 long long A = 1LL << 60;
1431 short X = A; // warn (loss of precision)
1432 }
1433
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +00001434.. _alpha-core-DynamicTypeChecker:
1435
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001436alpha.core.DynamicTypeChecker (ObjC)
Kristof Umann1a170322019-02-05 00:39:33 +00001437""""""""""""""""""""""""""""""""""""
1438Check for cases where the dynamic and the static type of an object are unrelated.
1439
1440
1441.. code-block:: objc
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001442
Kristof Umann1a170322019-02-05 00:39:33 +00001443 id date = [NSDate date];
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001444
Kristof Umann1a170322019-02-05 00:39:33 +00001445 // Warning: Object has a dynamic type 'NSDate *' which is
1446 // incompatible with static type 'NSNumber *'"
1447 NSNumber *number = date;
1448 [number doubleValue];
1449
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +00001450.. _alpha-core-FixedAddr:
1451
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001452alpha.core.FixedAddr (C)
Kristof Umann1a170322019-02-05 00:39:33 +00001453""""""""""""""""""""""""
1454Check for assignment of a fixed address to a pointer.
1455
1456.. code-block:: c
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001457
Kristof Umann1a170322019-02-05 00:39:33 +00001458 void test() {
1459 int *p;
1460 p = (int *) 0x10000; // warn
1461 }
1462
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +00001463.. _alpha-core-IdenticalExpr:
1464
Kristof Umann1a170322019-02-05 00:39:33 +00001465alpha.core.IdenticalExpr (C, C++)
1466"""""""""""""""""""""""""""""""""
1467Warn about unintended use of identical expressions in operators.
1468
1469.. code-block:: cpp
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001470
Kristof Umann1a170322019-02-05 00:39:33 +00001471 // C
1472 void test() {
1473 int a = 5;
1474 int b = a | 4 | a; // warn: identical expr on both sides
1475 }
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001476
Kristof Umann1a170322019-02-05 00:39:33 +00001477 // C++
1478 bool f(void);
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001479
Kristof Umann1a170322019-02-05 00:39:33 +00001480 void test(bool b) {
1481 int i = 10;
1482 if (f()) { // warn: true and false branches are identical
1483 do {
1484 i--;
1485 } while (f());
1486 } else {
1487 do {
1488 i--;
1489 } while (f());
1490 }
1491 }
1492
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +00001493.. _alpha-core-PointerArithm:
1494
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001495alpha.core.PointerArithm (C)
Kristof Umann1a170322019-02-05 00:39:33 +00001496""""""""""""""""""""""""""""
1497Check for pointer arithmetic on locations other than array elements.
1498
1499.. code-block:: c
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001500
Kristof Umann1a170322019-02-05 00:39:33 +00001501 void test() {
1502 int x;
1503 int *p;
1504 p = &x + 1; // warn
1505 }
1506
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +00001507.. _alpha-core-PointerSub:
1508
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001509alpha.core.PointerSub (C)
Kristof Umann1a170322019-02-05 00:39:33 +00001510"""""""""""""""""""""""""
1511Check for pointer subtractions on two pointers pointing to different memory chunks.
1512
1513.. code-block:: c
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001514
Kristof Umann1a170322019-02-05 00:39:33 +00001515 void test() {
1516 int x, y;
1517 int d = &y - &x; // warn
1518 }
1519
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +00001520.. _alpha-core-SizeofPtr:
1521
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001522alpha.core.SizeofPtr (C)
Kristof Umann1a170322019-02-05 00:39:33 +00001523""""""""""""""""""""""""
1524Warn about unintended use of ``sizeof()`` on pointer expressions.
1525
1526.. code-block:: c
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001527
Kristof Umann1a170322019-02-05 00:39:33 +00001528 struct s {};
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001529
Kristof Umann1a170322019-02-05 00:39:33 +00001530 int test(struct s *p) {
1531 return sizeof(p);
1532 // warn: sizeof(ptr) can produce an unexpected result
1533 }
1534
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +00001535.. _alpha-core-StackAddressAsyncEscape:
1536
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001537alpha.core.StackAddressAsyncEscape (C)
Kristof Umann1a170322019-02-05 00:39:33 +00001538""""""""""""""""""""""""""""""""""""""
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001539Check that addresses to stack memory do not escape the function that involves dispatch_after or dispatch_async.
Kristof Umann1a170322019-02-05 00:39:33 +00001540This checker is a part of ``core.StackAddressEscape``, but is temporarily disabled until some false positives are fixed.
1541
1542.. code-block:: c
1543
1544 dispatch_block_t test_block_inside_block_async_leak() {
1545 int x = 123;
1546 void (^inner)(void) = ^void(void) {
1547 int y = x;
1548 ++y;
1549 };
1550 void (^outer)(void) = ^void(void) {
1551 int z = x;
1552 ++z;
1553 inner();
1554 };
1555 return outer; // warn: address of stack-allocated block is captured by a
1556 // returned block
1557 }
1558
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +00001559.. _alpha-core-TestAfterDivZero:
1560
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001561alpha.core.TestAfterDivZero (C)
Kristof Umann1a170322019-02-05 00:39:33 +00001562"""""""""""""""""""""""""""""""
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001563Check for division by variable that is later compared against 0.
Kristof Umann1a170322019-02-05 00:39:33 +00001564Either the comparison is useless or there is division by zero.
1565
1566.. code-block:: c
1567
1568 void test(int x) {
1569 var = 77 / x;
1570 if (x == 0) { } // warn
1571 }
1572
1573alpha.cplusplus
1574^^^^^^^^^^^^^^^
1575
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +00001576.. _alpha-cplusplus-DeleteWithNonVirtualDtor:
1577
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001578alpha.cplusplus.DeleteWithNonVirtualDtor (C++)
Kristof Umann1a170322019-02-05 00:39:33 +00001579""""""""""""""""""""""""""""""""""""""""""""""
1580Reports destructions of polymorphic objects with a non-virtual destructor in their base class.
1581
1582.. code-block:: cpp
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001583
Kristof Umann1a170322019-02-05 00:39:33 +00001584 NonVirtual *create() {
1585 NonVirtual *x = new NVDerived(); // note: conversion from derived to base
1586 // happened here
1587 return x;
1588 }
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001589
Kristof Umann1a170322019-02-05 00:39:33 +00001590 void sink(NonVirtual *x) {
1591 delete x; // warn: destruction of a polymorphic object with no virtual
1592 // destructor
1593 }
1594
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +00001595.. _alpha-cplusplus-EnumCastOutOfRange:
1596
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001597alpha.cplusplus.EnumCastOutOfRange (C++)
Kristof Umann1a170322019-02-05 00:39:33 +00001598""""""""""""""""""""""""""""""""""""""""
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001599Check for integer to enumeration casts that could result in undefined values.
Kristof Umann1a170322019-02-05 00:39:33 +00001600
1601.. code-block:: cpp
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001602
Kristof Umann1a170322019-02-05 00:39:33 +00001603 enum TestEnum {
1604 A = 0
1605 };
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001606
Kristof Umann1a170322019-02-05 00:39:33 +00001607 void foo() {
1608 TestEnum t = static_cast(-1);
1609 // warn: the value provided to the cast expression is not in
1610 the valid range of values for the enum
1611
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +00001612.. _alpha-cplusplus-InvalidatedIterator:
1613
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001614alpha.cplusplus.InvalidatedIterator (C++)
Kristof Umann1a170322019-02-05 00:39:33 +00001615"""""""""""""""""""""""""""""""""""""""""
1616Check for use of invalidated iterators.
1617
1618.. code-block:: cpp
1619
1620 void bad_copy_assign_operator_list1(std::list &L1,
1621 const std::list &L2) {
1622 auto i0 = L1.cbegin();
1623 L1 = L2;
1624 *i0; // warn: invalidated iterator accessed
1625 }
1626
1627
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +00001628.. _alpha-cplusplus-IteratorRange:
1629
Kristof Umann1a170322019-02-05 00:39:33 +00001630alpha.cplusplus.IteratorRange (C++)
1631"""""""""""""""""""""""""""""""""""
1632Check for iterators used outside their valid ranges.
1633
1634.. code-block:: cpp
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001635
Kristof Umann1a170322019-02-05 00:39:33 +00001636 void simple_bad_end(const std::vector &v) {
1637 auto i = v.end();
1638 *i; // warn: iterator accessed outside of its range
1639 }
1640
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +00001641.. _alpha-cplusplus-MismatchedIterator:
1642
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001643alpha.cplusplus.MismatchedIterator (C++)
Kristof Umann1a170322019-02-05 00:39:33 +00001644""""""""""""""""""""""""""""""""""""""""
1645Check for use of iterators of different containers where iterators of the same container are expected.
1646
1647.. code-block:: cpp
1648
1649 void bad_insert3(std::vector &v1, std::vector &v2) {
1650 v2.insert(v1.cbegin(), v2.cbegin(), v2.cend()); // warn: container accessed
1651 // using foreign
1652 // iterator argument
1653 v1.insert(v1.cbegin(), v1.cbegin(), v2.cend()); // warn: iterators of
1654 // different containers
1655 // used where the same
1656 // container is
1657 // expected
1658 v1.insert(v1.cbegin(), v2.cbegin(), v1.cend()); // warn: iterators of
1659 // different containers
1660 // used where the same
1661 // container is
1662 // expected
1663 }
1664
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +00001665.. _alpha-cplusplus-MisusedMovedObject:
1666
Kristof Umann1a170322019-02-05 00:39:33 +00001667alpha.cplusplus.MisusedMovedObject (C++)
1668""""""""""""""""""""""""""""""""""""""""
1669Method calls on a moved-from object and copying a moved-from object will be reported.
1670
1671
1672.. code-block:: cpp
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001673
Kristof Umann1a170322019-02-05 00:39:33 +00001674 struct A {
1675 void foo() {}
1676 };
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001677
Kristof Umann1a170322019-02-05 00:39:33 +00001678 void f() {
1679 A a;
1680 A b = std::move(a); // note: 'a' became 'moved-from' here
1681 a.foo(); // warn: method call on a 'moved-from' object 'a'
1682 }
1683
Kristof Umann1a170322019-02-05 00:39:33 +00001684alpha.deadcode
1685^^^^^^^^^^^^^^
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +00001686.. _alpha-deadcode-UnreachableCode:
1687
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001688alpha.deadcode.UnreachableCode (C, C++)
Kristof Umann1a170322019-02-05 00:39:33 +00001689"""""""""""""""""""""""""""""""""""""""
1690Check unreachable code.
1691
1692.. code-block:: cpp
1693
1694 // C
1695 int test() {
1696 int x = 1;
1697 while(x);
1698 return x; // warn
1699 }
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001700
Kristof Umann1a170322019-02-05 00:39:33 +00001701 // C++
1702 void test() {
1703 int a = 2;
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001704
Kristof Umann1a170322019-02-05 00:39:33 +00001705 while (a > 1)
1706 a--;
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001707
Kristof Umann1a170322019-02-05 00:39:33 +00001708 if (a > 1)
1709 a++; // warn
1710 }
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001711
Kristof Umann1a170322019-02-05 00:39:33 +00001712 // Objective-C
1713 void test(id x) {
1714 return;
1715 [x retain]; // warn
1716 }
1717
1718alpha.llvm
1719^^^^^^^^^^
1720
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +00001721.. _alpha-llvm-Conventions:
1722
Kristof Umann1a170322019-02-05 00:39:33 +00001723alpha.llvm.Conventions
1724""""""""""""""""""""""
1725
1726Check code for LLVM codebase conventions:
1727
1728* A StringRef should not be bound to a temporary std::string whose lifetime is shorter than the StringRef's.
1729* Clang AST nodes should not have fields that can allocate memory.
1730
1731
1732alpha.osx
1733^^^^^^^^^
1734
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +00001735.. _alpha-osx-cocoa-DirectIvarAssignment:
1736
Kristof Umann1a170322019-02-05 00:39:33 +00001737alpha.osx.cocoa.DirectIvarAssignment (ObjC)
1738"""""""""""""""""""""""""""""""""""""""""""
1739Check for direct assignments to instance variables.
1740
1741
1742.. code-block:: objc
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001743
Kristof Umann1a170322019-02-05 00:39:33 +00001744 @interface MyClass : NSObject {}
1745 @property (readonly) id A;
1746 - (void) foo;
1747 @end
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001748
Kristof Umann1a170322019-02-05 00:39:33 +00001749 @implementation MyClass
1750 - (void) foo {
1751 _A = 0; // warn
1752 }
1753 @end
1754
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +00001755.. _alpha-osx-cocoa-DirectIvarAssignmentForAnnotatedFunctions:
1756
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001757alpha.osx.cocoa.DirectIvarAssignmentForAnnotatedFunctions (ObjC)
Kristof Umann1a170322019-02-05 00:39:33 +00001758""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001759Check for direct assignments to instance variables in
Kristof Umann1a170322019-02-05 00:39:33 +00001760the methods annotated with ``objc_no_direct_instance_variable_assignment``.
1761
1762.. code-block:: objc
1763
1764 @interface MyClass : NSObject {}
1765 @property (readonly) id A;
1766 - (void) fAnnotated __attribute__((
1767 annotate("objc_no_direct_instance_variable_assignment")));
1768 - (void) fNotAnnotated;
1769 @end
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001770
Kristof Umann1a170322019-02-05 00:39:33 +00001771 @implementation MyClass
1772 - (void) fAnnotated {
1773 _A = 0; // warn
1774 }
1775 - (void) fNotAnnotated {
1776 _A = 0; // no warn
1777 }
1778 @end
1779
1780
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +00001781.. _alpha-osx-cocoa-InstanceVariableInvalidation:
1782
Kristof Umann1a170322019-02-05 00:39:33 +00001783alpha.osx.cocoa.InstanceVariableInvalidation (ObjC)
1784"""""""""""""""""""""""""""""""""""""""""""""""""""
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001785Check that the invalidatable instance variables are
Kristof Umann1a170322019-02-05 00:39:33 +00001786invalidated in the methods annotated with objc_instance_variable_invalidator.
1787
1788.. code-block:: objc
1789
1790 @protocol Invalidation <NSObject>
1791 - (void) invalidate
1792 __attribute__((annotate("objc_instance_variable_invalidator")));
1793 @end
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001794
Kristof Umann1a170322019-02-05 00:39:33 +00001795 @interface InvalidationImpObj : NSObject <Invalidation>
1796 @end
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001797
Kristof Umann1a170322019-02-05 00:39:33 +00001798 @interface SubclassInvalidationImpObj : InvalidationImpObj {
1799 InvalidationImpObj *var;
1800 }
1801 - (void)invalidate;
1802 @end
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001803
Kristof Umann1a170322019-02-05 00:39:33 +00001804 @implementation SubclassInvalidationImpObj
1805 - (void) invalidate {}
1806 @end
1807 // warn: var needs to be invalidated or set to nil
1808
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +00001809.. _alpha-osx-cocoa-MissingInvalidationMethod:
1810
Kristof Umann1a170322019-02-05 00:39:33 +00001811alpha.osx.cocoa.MissingInvalidationMethod (ObjC)
1812""""""""""""""""""""""""""""""""""""""""""""""""
1813Check that the invalidation methods are present in classes that contain invalidatable instance variables.
1814
1815.. code-block:: objc
1816
1817 @protocol Invalidation <NSObject>
1818 - (void)invalidate
1819 __attribute__((annotate("objc_instance_variable_invalidator")));
1820 @end
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001821
Kristof Umann1a170322019-02-05 00:39:33 +00001822 @interface NeedInvalidation : NSObject <Invalidation>
1823 @end
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001824
Kristof Umann1a170322019-02-05 00:39:33 +00001825 @interface MissingInvalidationMethodDecl : NSObject {
1826 NeedInvalidation *Var; // warn
1827 }
1828 @end
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001829
Kristof Umann1a170322019-02-05 00:39:33 +00001830 @implementation MissingInvalidationMethodDecl
1831 @end
1832
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +00001833.. _alpha-osx-cocoa-localizability-PluralMisuseChecker:
1834
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001835alpha.osx.cocoa.localizability.PluralMisuseChecker (ObjC)
Kristof Umann1a170322019-02-05 00:39:33 +00001836"""""""""""""""""""""""""""""""""""""""""""""""""""""""""
1837Warns against using one vs. many plural pattern in code when generating localized strings.
1838
1839.. code-block:: objc
1840
1841 NSString *reminderText =
1842 NSLocalizedString(@"None", @"Indicates no reminders");
1843 if (reminderCount == 1) {
1844 // Warning: Plural cases are not supported across all languages.
1845 // Use a .stringsdict file instead
1846 reminderText =
1847 NSLocalizedString(@"1 Reminder", @"Indicates single reminder");
1848 } else if (reminderCount >= 2) {
1849 // Warning: Plural cases are not supported across all languages.
1850 // Use a .stringsdict file instead
1851 reminderText =
1852 [NSString stringWithFormat:
1853 NSLocalizedString(@"%@ Reminders", @"Indicates multiple reminders"),
1854 reminderCount];
1855 }
1856
1857alpha.security
1858^^^^^^^^^^^^^^
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +00001859.. _alpha-security-ArrayBound:
1860
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001861alpha.security.ArrayBound (C)
Kristof Umann1a170322019-02-05 00:39:33 +00001862"""""""""""""""""""""""""""""
1863Warn about buffer overflows (older checker).
1864
1865.. code-block:: c
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001866
Kristof Umann1a170322019-02-05 00:39:33 +00001867 void test() {
1868 char *s = "";
1869 char c = s[1]; // warn
1870 }
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001871
Kristof Umann1a170322019-02-05 00:39:33 +00001872 struct seven_words {
1873 int c[7];
1874 };
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001875
Kristof Umann1a170322019-02-05 00:39:33 +00001876 void test() {
1877 struct seven_words a, *p;
1878 p = &a;
1879 p[0] = a;
1880 p[1] = a;
1881 p[2] = a; // warn
1882 }
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001883
Kristof Umann1a170322019-02-05 00:39:33 +00001884 // note: requires unix.Malloc or
1885 // alpha.unix.MallocWithAnnotations checks enabled.
1886 void test() {
1887 int *p = malloc(12);
1888 p[3] = 4; // warn
1889 }
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001890
Kristof Umann1a170322019-02-05 00:39:33 +00001891 void test() {
1892 char a[2];
1893 int *b = (int*)a;
1894 b[1] = 3; // warn
1895 }
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001896
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +00001897.. _alpha-security-ArrayBoundV2:
1898
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001899alpha.security.ArrayBoundV2 (C)
Kristof Umann1a170322019-02-05 00:39:33 +00001900"""""""""""""""""""""""""""""""
1901Warn about buffer overflows (newer checker).
1902
1903.. code-block:: c
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001904
Kristof Umann1a170322019-02-05 00:39:33 +00001905 void test() {
1906 char *s = "";
1907 char c = s[1]; // warn
1908 }
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001909
Kristof Umann1a170322019-02-05 00:39:33 +00001910 void test() {
1911 int buf[100];
1912 int *p = buf;
1913 p = p + 99;
1914 p[1] = 1; // warn
1915 }
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001916
Kristof Umann1a170322019-02-05 00:39:33 +00001917 // note: compiler has internal check for this.
1918 // Use -Wno-array-bounds to suppress compiler warning.
1919 void test() {
1920 int buf[100][100];
1921 buf[0][-1] = 1; // warn
1922 }
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001923
Kristof Umann1a170322019-02-05 00:39:33 +00001924 // note: requires alpha.security.taint check turned on.
1925 void test() {
1926 char s[] = "abc";
1927 int x = getchar();
1928 char c = s[x]; // warn: index is tainted
1929 }
1930
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +00001931.. _alpha-security-MallocOverflow:
1932
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001933alpha.security.MallocOverflow (C)
Kristof Umann1a170322019-02-05 00:39:33 +00001934"""""""""""""""""""""""""""""""""
1935Check for overflows in the arguments to malloc().
1936
1937.. code-block:: c
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001938
Kristof Umann1a170322019-02-05 00:39:33 +00001939 void test(int n) {
1940 void *p = malloc(n * sizeof(int)); // warn
1941 }
1942
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +00001943.. _alpha-security-MmapWriteExec:
1944
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001945alpha.security.MmapWriteExec (C)
Kristof Umann1a170322019-02-05 00:39:33 +00001946""""""""""""""""""""""""""""""""
1947Warn on mmap() calls that are both writable and executable.
1948
1949.. code-block:: c
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001950
Kristof Umann1a170322019-02-05 00:39:33 +00001951 void test(int n) {
1952 void *c = mmap(NULL, 32, PROT_READ | PROT_WRITE | PROT_EXEC,
1953 MAP_PRIVATE | MAP_ANON, -1, 0);
1954 // warn: Both PROT_WRITE and PROT_EXEC flags are set. This can lead to
1955 // exploitable memory regions, which could be overwritten with malicious
1956 // code
1957 }
1958
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +00001959.. _alpha-security-ReturnPtrRange:
1960
Kristof Umann1a170322019-02-05 00:39:33 +00001961alpha.security.ReturnPtrRange (C)
1962"""""""""""""""""""""""""""""""""
1963Check for an out-of-bound pointer being returned to callers.
1964
1965.. code-block:: c
1966
1967 static int A[10];
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001968
Kristof Umann1a170322019-02-05 00:39:33 +00001969 int *test() {
1970 int *p = A + 10;
1971 return p; // warn
1972 }
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001973
Kristof Umann1a170322019-02-05 00:39:33 +00001974 int test(void) {
1975 int x;
1976 return x; // warn: undefined or garbage returned
1977 }
1978
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +00001979.. _alpha-security-taint-TaintPropagation:
1980
Kristof Umann1a170322019-02-05 00:39:33 +00001981alpha.security.taint.TaintPropagation (C, C++)
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001982""""""""""""""""""""""""""""""""""""""""""""""
1983Generate taint information used by other checkers.
Kristof Umann1a170322019-02-05 00:39:33 +00001984A data is tainted when it comes from an unreliable source.
1985
1986.. code-block:: c
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001987
Kristof Umann1a170322019-02-05 00:39:33 +00001988 void test() {
1989 char x = getchar(); // 'x' marked as tainted
1990 system(&x); // warn: untrusted data is passed to a system call
1991 }
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001992
Kristof Umann1a170322019-02-05 00:39:33 +00001993 // note: compiler internally checks if the second param to
1994 // sprintf is a string literal or not.
1995 // Use -Wno-format-security to suppress compiler warning.
1996 void test() {
1997 char s[10], buf[10];
1998 fscanf(stdin, "%s", s); // 's' marked as tainted
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001999
Kristof Umann1a170322019-02-05 00:39:33 +00002000 sprintf(buf, s); // warn: untrusted data as a format string
2001 }
Alexander Kornienko9a857d22019-02-11 15:17:13 +00002002
Kristof Umann1a170322019-02-05 00:39:33 +00002003 void test() {
2004 size_t ts;
2005 scanf("%zd", &ts); // 'ts' marked as tainted
2006 int *p = (int *)malloc(ts * sizeof(int));
2007 // warn: untrusted data as buffer size
2008 }
2009
2010alpha.unix
2011^^^^^^^^^^^
2012
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +00002013.. _alpha-unix-BlockInCriticalSection:
2014
Alexander Kornienko9a857d22019-02-11 15:17:13 +00002015alpha.unix.BlockInCriticalSection (C)
Kristof Umann1a170322019-02-05 00:39:33 +00002016"""""""""""""""""""""""""""""""""""""
Alexander Kornienko9a857d22019-02-11 15:17:13 +00002017Check for calls to blocking functions inside a critical section.
Kristof Umann1a170322019-02-05 00:39:33 +00002018Applies to: ``lock, unlock, sleep, getc, fgets, read, recv, pthread_mutex_lock,``
2019`` pthread_mutex_unlock, mtx_lock, mtx_timedlock, mtx_trylock, mtx_unlock, lock_guard, unique_lock``
2020
2021.. code-block:: c
Alexander Kornienko9a857d22019-02-11 15:17:13 +00002022
Kristof Umann1a170322019-02-05 00:39:33 +00002023 void test() {
2024 std::mutex m;
2025 m.lock();
2026 sleep(3); // warn: a blocking function sleep is called inside a critical
2027 // section
2028 m.unlock();
2029 }
2030
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +00002031.. _alpha-unix-Chroot:
2032
Kristof Umann1a170322019-02-05 00:39:33 +00002033alpha.unix.Chroot (C)
2034"""""""""""""""""""""
2035Check improper use of chroot.
2036
2037.. code-block:: c
2038
2039 void f();
Alexander Kornienko9a857d22019-02-11 15:17:13 +00002040
Kristof Umann1a170322019-02-05 00:39:33 +00002041 void test() {
2042 chroot("/usr/local");
2043 f(); // warn: no call of chdir("/") immediately after chroot
2044 }
2045
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +00002046.. _alpha-unix-PthreadLock:
2047
Alexander Kornienko9a857d22019-02-11 15:17:13 +00002048alpha.unix.PthreadLock (C)
Kristof Umann1a170322019-02-05 00:39:33 +00002049""""""""""""""""""""""""""
2050Simple lock -> unlock checker.
2051Applies to: ``pthread_mutex_lock, pthread_rwlock_rdlock, pthread_rwlock_wrlock, lck_mtx_lock, lck_rw_lock_exclusive``
Alexander Kornienko9a857d22019-02-11 15:17:13 +00002052``lck_rw_lock_shared, pthread_mutex_trylock, pthread_rwlock_tryrdlock, pthread_rwlock_tryrwlock, lck_mtx_try_lock,
Kristof Umann1a170322019-02-05 00:39:33 +00002053lck_rw_try_lock_exclusive, lck_rw_try_lock_shared, pthread_mutex_unlock, pthread_rwlock_unlock, lck_mtx_unlock, lck_rw_done``.
2054
2055
2056.. code-block:: c
Alexander Kornienko9a857d22019-02-11 15:17:13 +00002057
Kristof Umann1a170322019-02-05 00:39:33 +00002058 pthread_mutex_t mtx;
Alexander Kornienko9a857d22019-02-11 15:17:13 +00002059
Kristof Umann1a170322019-02-05 00:39:33 +00002060 void test() {
2061 pthread_mutex_lock(&mtx);
2062 pthread_mutex_lock(&mtx);
2063 // warn: this lock has already been acquired
2064 }
Alexander Kornienko9a857d22019-02-11 15:17:13 +00002065
Kristof Umann1a170322019-02-05 00:39:33 +00002066 lck_mtx_t lck1, lck2;
Alexander Kornienko9a857d22019-02-11 15:17:13 +00002067
Kristof Umann1a170322019-02-05 00:39:33 +00002068 void test() {
2069 lck_mtx_lock(&lck1);
2070 lck_mtx_lock(&lck2);
2071 lck_mtx_unlock(&lck1);
2072 // warn: this was not the most recently acquired lock
2073 }
Alexander Kornienko9a857d22019-02-11 15:17:13 +00002074
Kristof Umann1a170322019-02-05 00:39:33 +00002075 lck_mtx_t lck1, lck2;
Alexander Kornienko9a857d22019-02-11 15:17:13 +00002076
Kristof Umann1a170322019-02-05 00:39:33 +00002077 void test() {
2078 if (lck_mtx_try_lock(&lck1) == 0)
2079 return;
Alexander Kornienko9a857d22019-02-11 15:17:13 +00002080
Kristof Umann1a170322019-02-05 00:39:33 +00002081 lck_mtx_lock(&lck2);
2082 lck_mtx_unlock(&lck1);
2083 // warn: this was not the most recently acquired lock
2084 }
2085
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +00002086.. _alpha-unix-SimpleStream:
2087
Kristof Umann1a170322019-02-05 00:39:33 +00002088alpha.unix.SimpleStream (C)
2089"""""""""""""""""""""""""""
2090Check for misuses of stream APIs. Check for misuses of stream APIs: ``fopen, fclose``
Alexander Kornienko9a857d22019-02-11 15:17:13 +00002091(demo checker, the subject of the demo (`Slides <http://llvm.org/devmtg/2012-11/Zaks-Rose-Checker24Hours.pdf>`_ ,
2092`Video <https://youtu.be/kdxlsP5QVPw>`_) by Anna Zaks and Jordan Rose presented at the
Kristof Umann1a170322019-02-05 00:39:33 +00002093`2012 LLVM Developers' Meeting <http://llvm.org/devmtg/2012-11/>`_).
2094
2095.. code-block:: c
2096
2097 void test() {
2098 FILE *F = fopen("myfile.txt", "w");
2099 } // warn: opened file is never closed
Alexander Kornienko9a857d22019-02-11 15:17:13 +00002100
Kristof Umann1a170322019-02-05 00:39:33 +00002101 void test() {
2102 FILE *F = fopen("myfile.txt", "w");
Alexander Kornienko9a857d22019-02-11 15:17:13 +00002103
Kristof Umann1a170322019-02-05 00:39:33 +00002104 if (F)
2105 fclose(F);
Alexander Kornienko9a857d22019-02-11 15:17:13 +00002106
Kristof Umann1a170322019-02-05 00:39:33 +00002107 fclose(F); // warn: closing a previously closed file stream
2108 }
2109
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +00002110.. _alpha-unix-Stream:
2111
Kristof Umann1a170322019-02-05 00:39:33 +00002112alpha.unix.Stream (C)
2113"""""""""""""""""""""
2114Check stream handling functions: ``fopen, tmpfile, fclose, fread, fwrite, fseek, ftell, rewind, fgetpos,``
2115``fsetpos, clearerr, feof, ferror, fileno``.
2116
2117.. code-block:: c
2118
2119 void test() {
2120 FILE *p = fopen("foo", "r");
2121 } // warn: opened file is never closed
Alexander Kornienko9a857d22019-02-11 15:17:13 +00002122
Kristof Umann1a170322019-02-05 00:39:33 +00002123 void test() {
2124 FILE *p = fopen("foo", "r");
2125 fseek(p, 1, SEEK_SET); // warn: stream pointer might be NULL
2126 fclose(p);
2127 }
Alexander Kornienko9a857d22019-02-11 15:17:13 +00002128
Kristof Umann1a170322019-02-05 00:39:33 +00002129 void test() {
2130 FILE *p = fopen("foo", "r");
Alexander Kornienko9a857d22019-02-11 15:17:13 +00002131
Kristof Umann1a170322019-02-05 00:39:33 +00002132 if (p)
2133 fseek(p, 1, 3);
2134 // warn: third arg should be SEEK_SET, SEEK_END, or SEEK_CUR
Alexander Kornienko9a857d22019-02-11 15:17:13 +00002135
Kristof Umann1a170322019-02-05 00:39:33 +00002136 fclose(p);
2137 }
Alexander Kornienko9a857d22019-02-11 15:17:13 +00002138
Kristof Umann1a170322019-02-05 00:39:33 +00002139 void test() {
2140 FILE *p = fopen("foo", "r");
2141 fclose(p);
2142 fclose(p); // warn: already closed
2143 }
Alexander Kornienko9a857d22019-02-11 15:17:13 +00002144
Kristof Umann1a170322019-02-05 00:39:33 +00002145 void test() {
2146 FILE *p = tmpfile();
2147 ftell(p); // warn: stream pointer might be NULL
2148 fclose(p);
2149 }
2150
2151
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +00002152.. _alpha-unix-cstring-BufferOverlap:
2153
Kristof Umann1a170322019-02-05 00:39:33 +00002154alpha.unix.cstring.BufferOverlap (C)
2155""""""""""""""""""""""""""""""""""""
2156Checks for overlap in two buffer arguments. Applies to: ``memcpy, mempcpy``.
2157
2158.. code-block:: c
2159
2160 void test() {
2161 int a[4] = {0};
2162 memcpy(a + 2, a + 1, 8); // warn
2163 }
2164
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +00002165.. _alpha-unix-cstring-NotNullTerminated:
2166
Kristof Umann1a170322019-02-05 00:39:33 +00002167alpha.unix.cstring.NotNullTerminated (C)
2168""""""""""""""""""""""""""""""""""""""""
2169Check for arguments which are not null-terminated strings; applies to: ``strlen, strnlen, strcpy, strncpy, strcat, strncat``.
2170
2171.. code-block:: c
Alexander Kornienko9a857d22019-02-11 15:17:13 +00002172
Kristof Umann1a170322019-02-05 00:39:33 +00002173 void test() {
2174 int y = strlen((char *)&test); // warn
2175 }
2176
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +00002177.. _alpha-unix-cstring-OutOfBounds:
2178
Kristof Umann1a170322019-02-05 00:39:33 +00002179alpha.unix.cstring.OutOfBounds (C)
2180""""""""""""""""""""""""""""""""""
2181Check for out-of-bounds access in string functions; applies to:`` strncopy, strncat``.
2182
2183
2184.. code-block:: c
Alexander Kornienko9a857d22019-02-11 15:17:13 +00002185
Kristof Umann1a170322019-02-05 00:39:33 +00002186 void test() {
2187 int y = strlen((char *)&test); // warn
2188 }
2189
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +00002190.. _alpha-nondeterminism-PointerIteration:
2191
Mandeep Singh Grang0cdc5dd2019-05-24 19:24:08 +00002192alpha.nondeterminism.PointerIteration (C++)
2193"""""""""""""""""""""""""""""""""""""""""""
2194Check for non-determinism caused by iterating unordered containers of pointers.
2195
2196.. code-block:: c
2197
2198 void test() {
2199 int a = 1, b = 2;
2200 std::unordered_set<int *> UnorderedPtrSet = {&a, &b};
2201
2202 for (auto i : UnorderedPtrSet) // warn
2203 f(i);
2204 }
2205
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +00002206.. _alpha-nondeterminism-PointerSorting:
2207
Mandeep Singh Grangc0773ab2019-03-08 20:13:53 +00002208alpha.nondeterminism.PointerSorting (C++)
Mandeep Singh Grangd4c4f742019-03-08 20:35:25 +00002209"""""""""""""""""""""""""""""""""""""""""
Mandeep Singh Grangc0773ab2019-03-08 20:13:53 +00002210Check for non-determinism caused by sorting of pointers.
2211
2212.. code-block:: c
2213
2214 void test() {
2215 int a = 1, b = 2;
2216 std::vector<int *> V = {&a, &b};
2217 std::sort(V.begin(), V.end()); // warn
2218 }
2219
Kristof Umann1a170322019-02-05 00:39:33 +00002220
2221Debug Checkers
2222---------------
2223
2224.. _debug-checkers:
2225
2226
2227debug
2228^^^^^
2229
2230Checkers used for debugging the analyzer.
Kristof Umanndccfaff2019-02-05 10:19:39 +00002231:doc:`developer-docs/DebugChecks` page contains a detailed description.
Kristof Umann1a170322019-02-05 00:39:33 +00002232
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +00002233.. _debug-AnalysisOrder:
2234
Kristof Umann1a170322019-02-05 00:39:33 +00002235debug.AnalysisOrder
2236"""""""""""""""""""
2237Print callbacks that are called during analysis in order.
2238
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +00002239.. _debug-ConfigDumper:
2240
Kristof Umann1a170322019-02-05 00:39:33 +00002241debug.ConfigDumper
2242""""""""""""""""""
2243Dump config table.
2244
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +00002245.. _debug-DumpCFG Display:
2246
Kristof Umann1a170322019-02-05 00:39:33 +00002247debug.DumpCFG Display
2248"""""""""""""""""""""
2249Control-Flow Graphs.
2250
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +00002251.. _debug-DumpCallGraph:
2252
Kristof Umann1a170322019-02-05 00:39:33 +00002253debug.DumpCallGraph
2254"""""""""""""""""""
2255Display Call Graph.
2256
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +00002257.. _debug-DumpCalls:
2258
Kristof Umann1a170322019-02-05 00:39:33 +00002259debug.DumpCalls
2260"""""""""""""""
2261Print calls as they are traversed by the engine.
2262
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +00002263.. _debug-DumpDominators:
2264
Kristof Umann1a170322019-02-05 00:39:33 +00002265debug.DumpDominators
2266""""""""""""""""""""
2267Print the dominance tree for a given CFG.
2268
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +00002269.. _debug-DumpLiveVars:
2270
Kristof Umann1a170322019-02-05 00:39:33 +00002271debug.DumpLiveVars
2272""""""""""""""""""
2273Print results of live variable analysis.
2274
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +00002275.. _debug-DumpTraversal:
2276
Kristof Umann1a170322019-02-05 00:39:33 +00002277debug.DumpTraversal
2278"""""""""""""""""""
2279Print branch conditions as they are traversed by the engine.
2280
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +00002281.. _debug-ExprInspection:
2282
Kristof Umann1a170322019-02-05 00:39:33 +00002283debug.ExprInspection
2284""""""""""""""""""""
2285Check the analyzer's understanding of expressions.
2286
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +00002287.. _debug-Stats:
2288
Kristof Umann1a170322019-02-05 00:39:33 +00002289debug.Stats
2290"""""""""""
2291Emit warnings with analyzer statistics.
2292
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +00002293.. _debug-TaintTest:
2294
Kristof Umann1a170322019-02-05 00:39:33 +00002295debug.TaintTest
2296"""""""""""""""
2297Mark tainted symbols as such.
2298
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +00002299.. _debug-ViewCFG:
2300
Kristof Umann1a170322019-02-05 00:39:33 +00002301debug.ViewCFG
2302"""""""""""""
2303View Control-Flow Graphs using GraphViz.
2304
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +00002305.. _debug-ViewCallGraph:
2306
Kristof Umann1a170322019-02-05 00:39:33 +00002307debug.ViewCallGraph
2308"""""""""""""""""""
2309View Call Graph using GraphViz.
2310
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +00002311.. _debug-ViewExplodedGraph:
2312
Kristof Umann1a170322019-02-05 00:39:33 +00002313debug.ViewExplodedGraph
2314"""""""""""""""""""""""
2315View Exploded Graphs using GraphViz.
2316