blob: a751b14809752945fa0fda2e60efac6b6403b9e8 [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 Umanne6e133b2019-08-15 08:52:10 +0000245cplusplus.InnerPointer (C++)
246""""""""""""""""""""""""""""
Kristof Umann1a170322019-02-05 00:39:33 +0000247Check for inner pointers of C++ containers used after re/deallocation.
248
Kristof Umanne6e133b2019-08-15 08:52:10 +0000249Many container methods in the C++ standard library are known to invalidate
250"references" (including actual references, iterators and raw pointers) to
251elements of the container. Using such references after they are invalidated
252causes undefined behavior, which is a common source of memory errors in C++ that
253this checker is capable of finding.
254
255The checker is currently limited to ``std::string`` objects and doesn't
256recognize some of the more sophisticated approaches to passing unowned pointers
257around, such as ``std::string_view``.
258
259.. code-block:: cpp
260
261 void deref_after_assignment() {
262 std::string s = "llvm";
263 const char *c = s.data(); // note: pointer to inner buffer of 'std::string' obtained here
264 s = "clang"; // note: inner buffer of 'std::string' reallocated by call to 'operator='
265 consume(c); // warn: inner pointer of container used after re/deallocation
266 }
267
268 const char *return_temp(int x) {
269 return std::to_string(x).c_str(); // warn: inner pointer of container used after re/deallocation
270 // note: pointer to inner buffer of 'std::string' obtained here
271 // note: inner buffer of 'std::string' deallocated by call to destructor
272 }
273
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +0000274.. _cplusplus-NewDelete:
275
Alexander Kornienko9a857d22019-02-11 15:17:13 +0000276cplusplus.NewDelete (C++)
Kristof Umann1a170322019-02-05 00:39:33 +0000277"""""""""""""""""""""""""
278Check for double-free and use-after-free problems. Traces memory managed by new/delete.
279
280.. literalinclude:: checkers/newdelete_example.cpp
281 :language: cpp
Alexander Kornienko9a857d22019-02-11 15:17:13 +0000282
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +0000283.. _cplusplus-NewDeleteLeaks:
284
Alexander Kornienko9a857d22019-02-11 15:17:13 +0000285cplusplus.NewDeleteLeaks (C++)
Kristof Umann1a170322019-02-05 00:39:33 +0000286""""""""""""""""""""""""""""""
287Check for memory leaks. Traces memory managed by new/delete.
288
289.. code-block:: cpp
290
291 void test() {
292 int *p = new int;
293 } // warn
294
295
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +0000296.. _cplusplus-SelfAssignment:
297
Alexander Kornienko9a857d22019-02-11 15:17:13 +0000298cplusplus.SelfAssignment (C++)
Kristof Umann1a170322019-02-05 00:39:33 +0000299""""""""""""""""""""""""""""""
300Checks C++ copy and move assignment operators for self assignment.
301
302.. _deadcode-checkers:
303
304deadcode
305^^^^^^^^
306
307Dead Code Checkers.
Alexander Kornienko9a857d22019-02-11 15:17:13 +0000308
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +0000309.. _deadcode-DeadStores:
310
Alexander Kornienko9a857d22019-02-11 15:17:13 +0000311deadcode.DeadStores (C)
Kristof Umann1a170322019-02-05 00:39:33 +0000312"""""""""""""""""""""""
313Check for values stored to variables that are never read afterwards.
314
315.. code-block:: c
316
317 void test() {
318 int x;
319 x = 1; // warn
320 }
321
Kristof Umann3b18b052019-09-03 15:22:43 +0000322The ``WarnForDeadNestedAssignments`` option enables the checker to emit
323warnings for nested dead assignments. You can disable with the
324``-analyzer-config deadcode.DeadStores:WarnForDeadNestedAssignments=false``.
325*Defaults to true*.
326
327Would warn for this e.g.:
328if ((y = make_int())) {
329}
330
Kristof Umann1a170322019-02-05 00:39:33 +0000331.. _nullability-checkers:
332
333nullability
334^^^^^^^^^^^
335
336Objective C checkers that warn for null pointer passing and dereferencing errors.
337
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +0000338.. _nullability-NullPassedToNonnull:
339
Kristof Umann1a170322019-02-05 00:39:33 +0000340nullability.NullPassedToNonnull (ObjC)
341""""""""""""""""""""""""""""""""""""""
342Warns when a null pointer is passed to a pointer which has a _Nonnull type.
343
344.. code-block:: objc
345
346 if (name != nil)
347 return;
348 // Warning: nil passed to a callee that requires a non-null 1st parameter
349 NSString *greeting = [@"Hello " stringByAppendingString:name];
350
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +0000351.. _nullability-NullReturnedFromNonnull:
352
Alexander Kornienko9a857d22019-02-11 15:17:13 +0000353nullability.NullReturnedFromNonnull (ObjC)
Kristof Umann1a170322019-02-05 00:39:33 +0000354""""""""""""""""""""""""""""""""""""""""""
355Warns when a null pointer is returned from a function that has _Nonnull return type.
356
357.. code-block:: objc
358
359 - (nonnull id)firstChild {
360 id result = nil;
361 if ([_children count] > 0)
362 result = _children[0];
Alexander Kornienko9a857d22019-02-11 15:17:13 +0000363
Kristof Umann1a170322019-02-05 00:39:33 +0000364 // Warning: nil returned from a method that is expected
365 // to return a non-null value
366 return result;
367 }
368
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +0000369.. _nullability-NullableDereferenced:
370
Kristof Umann1a170322019-02-05 00:39:33 +0000371nullability.NullableDereferenced (ObjC)
372"""""""""""""""""""""""""""""""""""""""
373Warns when a nullable pointer is dereferenced.
374
375.. code-block:: objc
Alexander Kornienko9a857d22019-02-11 15:17:13 +0000376
Kristof Umann1a170322019-02-05 00:39:33 +0000377 struct LinkedList {
378 int data;
379 struct LinkedList *next;
380 };
Alexander Kornienko9a857d22019-02-11 15:17:13 +0000381
Kristof Umann1a170322019-02-05 00:39:33 +0000382 struct LinkedList * _Nullable getNext(struct LinkedList *l);
Alexander Kornienko9a857d22019-02-11 15:17:13 +0000383
Kristof Umann1a170322019-02-05 00:39:33 +0000384 void updateNextData(struct LinkedList *list, int newData) {
385 struct LinkedList *next = getNext(list);
386 // Warning: Nullable pointer is dereferenced
387 next->data = 7;
388 }
389
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +0000390.. _nullability-NullablePassedToNonnull:
391
Kristof Umann1a170322019-02-05 00:39:33 +0000392nullability.NullablePassedToNonnull (ObjC)
393""""""""""""""""""""""""""""""""""""""""""
394Warns when a nullable pointer is passed to a pointer which has a _Nonnull type.
395
396.. code-block:: objc
Alexander Kornienko9a857d22019-02-11 15:17:13 +0000397
Kristof Umann1a170322019-02-05 00:39:33 +0000398 typedef struct Dummy { int val; } Dummy;
399 Dummy *_Nullable returnsNullable();
400 void takesNonnull(Dummy *_Nonnull);
Alexander Kornienko9a857d22019-02-11 15:17:13 +0000401
Kristof Umann1a170322019-02-05 00:39:33 +0000402 void test() {
403 Dummy *p = returnsNullable();
404 takesNonnull(p); // warn
405 }
406
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +0000407.. _nullability-NullableReturnedFromNonnull:
408
Alexander Kornienko9a857d22019-02-11 15:17:13 +0000409nullability.NullableReturnedFromNonnull (ObjC)
Kristof Umann1a170322019-02-05 00:39:33 +0000410""""""""""""""""""""""""""""""""""""""""""""""
411Warns when a nullable pointer is returned from a function that has _Nonnull return type.
412
413.. _optin-checkers:
414
415optin
416^^^^^
417
418Checkers for portability, performance or coding style specific rules.
419
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +0000420.. _optin-cplusplus-UninitializedObject:
421
Kristof Umann85e0ff72019-04-19 23:33:50 +0000422optin.cplusplus.UninitializedObject (C++)
Nico Weber83c95b12019-05-03 18:54:18 +0000423"""""""""""""""""""""""""""""""""""""""""
Kristof Umann85e0ff72019-04-19 23:33:50 +0000424
425This checker reports uninitialized fields in objects created after a constructor
426call. It doesn't only find direct uninitialized fields, but rather makes a deep
427inspection of the object, analyzing all of it's fields subfields.
428The checker regards inherited fields as direct fields, so one will recieve
429warnings for uninitialized inherited data members as well.
430
431.. code-block:: cpp
432
433 // With Pedantic and CheckPointeeInitialization set to true
434
435 struct A {
436 struct B {
437 int x; // note: uninitialized field 'this->b.x'
438 // note: uninitialized field 'this->bptr->x'
439 int y; // note: uninitialized field 'this->b.y'
440 // note: uninitialized field 'this->bptr->y'
441 };
442 int *iptr; // note: uninitialized pointer 'this->iptr'
443 B b;
444 B *bptr;
445 char *cptr; // note: uninitialized pointee 'this->cptr'
446
447 A (B *bptr, char *cptr) : bptr(bptr), cptr(cptr) {}
448 };
449
450 void f() {
451 A::B b;
452 char c;
453 A a(&b, &c); // warning: 6 uninitialized fields
454 // after the constructor call
455 }
456
457 // With Pedantic set to false and
458 // CheckPointeeInitialization set to true
459 // (every field is uninitialized)
460
461 struct A {
462 struct B {
463 int x;
464 int y;
465 };
466 int *iptr;
467 B b;
468 B *bptr;
469 char *cptr;
470
471 A (B *bptr, char *cptr) : bptr(bptr), cptr(cptr) {}
472 };
473
474 void f() {
475 A::B b;
476 char c;
477 A a(&b, &c); // no warning
478 }
479
480 // With Pedantic set to true and
481 // CheckPointeeInitialization set to false
482 // (pointees are regarded as initialized)
483
484 struct A {
485 struct B {
486 int x; // note: uninitialized field 'this->b.x'
487 int y; // note: uninitialized field 'this->b.y'
488 };
489 int *iptr; // note: uninitialized pointer 'this->iptr'
490 B b;
491 B *bptr;
492 char *cptr;
493
494 A (B *bptr, char *cptr) : bptr(bptr), cptr(cptr) {}
495 };
496
497 void f() {
498 A::B b;
499 char c;
500 A a(&b, &c); // warning: 3 uninitialized fields
501 // after the constructor call
502 }
503
504
505**Options**
506
507This checker has several options which can be set from command line (e.g.
508``-analyzer-config optin.cplusplus.UninitializedObject:Pedantic=true``):
509
510* ``Pedantic`` (boolean). If to false, the checker won't emit warnings for
511 objects that don't have at least one initialized field. Defaults to false.
512
513* ``NotesAsWarnings`` (boolean). If set to true, the checker will emit a
514 warning for each uninitalized field, as opposed to emitting one warning per
515 constructor call, and listing the uninitialized fields that belongs to it in
516 notes. *Defaults to false*.
517
518* ``CheckPointeeInitialization`` (boolean). If set to false, the checker will
519 not analyze the pointee of pointer/reference fields, and will only check
520 whether the object itself is initialized. *Defaults to false*.
521
522* ``IgnoreRecordsWithField`` (string). If supplied, the checker will not analyze
523 structures that have a field with a name or type name that matches the given
524 pattern. *Defaults to ""*.
525
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +0000526.. _optin-cplusplus-VirtualCall:
527
Kristof Umann1a170322019-02-05 00:39:33 +0000528optin.cplusplus.VirtualCall (C++)
529"""""""""""""""""""""""""""""""""
530Check virtual function calls during construction or destruction.
531
532.. code-block:: cpp
533
534 class A {
535 public:
536 A() {
537 f(); // warn
538 }
539 virtual void f();
540 };
Alexander Kornienko9a857d22019-02-11 15:17:13 +0000541
Kristof Umann1a170322019-02-05 00:39:33 +0000542 class A {
543 public:
544 ~A() {
545 this->f(); // warn
546 }
547 virtual void f();
548 };
549
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +0000550.. _optin-mpi-MPI-Checker:
551
Kristof Umann1a170322019-02-05 00:39:33 +0000552optin.mpi.MPI-Checker (C)
553"""""""""""""""""""""""""
554Checks MPI code.
555
556.. code-block:: c
557
558 void test() {
559 double buf = 0;
560 MPI_Request sendReq1;
561 MPI_Ireduce(MPI_IN_PLACE, &buf, 1, MPI_DOUBLE, MPI_SUM,
562 0, MPI_COMM_WORLD, &sendReq1);
563 } // warn: request 'sendReq1' has no matching wait.
Alexander Kornienko9a857d22019-02-11 15:17:13 +0000564
Kristof Umann1a170322019-02-05 00:39:33 +0000565 void test() {
566 double buf = 0;
567 MPI_Request sendReq;
568 MPI_Isend(&buf, 1, MPI_DOUBLE, 0, 0, MPI_COMM_WORLD, &sendReq);
569 MPI_Irecv(&buf, 1, MPI_DOUBLE, 0, 0, MPI_COMM_WORLD, &sendReq); // warn
570 MPI_Isend(&buf, 1, MPI_DOUBLE, 0, 0, MPI_COMM_WORLD, &sendReq); // warn
571 MPI_Wait(&sendReq, MPI_STATUS_IGNORE);
572 }
Alexander Kornienko9a857d22019-02-11 15:17:13 +0000573
Kristof Umann1a170322019-02-05 00:39:33 +0000574 void missingNonBlocking() {
575 int rank = 0;
576 MPI_Comm_rank(MPI_COMM_WORLD, &rank);
577 MPI_Request sendReq1[10][10][10];
578 MPI_Wait(&sendReq1[1][7][9], MPI_STATUS_IGNORE); // warn
579 }
580
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +0000581.. _optin-osx-cocoa-localizability-EmptyLocalizationContextChecker:
582
Kristof Umann1a170322019-02-05 00:39:33 +0000583optin.osx.cocoa.localizability.EmptyLocalizationContextChecker (ObjC)
584"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
585Check that NSLocalizedString macros include a comment for context.
586
587.. code-block:: objc
588
589 - (void)test {
590 NSString *string = NSLocalizedString(@"LocalizedString", nil); // warn
591 NSString *string2 = NSLocalizedString(@"LocalizedString", @" "); // warn
592 NSString *string3 = NSLocalizedStringWithDefaultValue(
593 @"LocalizedString", nil, [[NSBundle alloc] init], nil,@""); // warn
594 }
595
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +0000596.. _optin-osx-cocoa-localizability-NonLocalizedStringChecker:
597
Alexander Kornienko9a857d22019-02-11 15:17:13 +0000598optin.osx.cocoa.localizability.NonLocalizedStringChecker (ObjC)
Kristof Umann1a170322019-02-05 00:39:33 +0000599"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
600Warns about uses of non-localized NSStrings passed to UI methods expecting localized NSStrings.
601
602.. code-block:: objc
Alexander Kornienko9a857d22019-02-11 15:17:13 +0000603
Kristof Umann1a170322019-02-05 00:39:33 +0000604 NSString *alarmText =
605 NSLocalizedString(@"Enabled", @"Indicates alarm is turned on");
606 if (!isEnabled) {
607 alarmText = @"Disabled";
608 }
609 UILabel *alarmStateLabel = [[UILabel alloc] init];
Alexander Kornienko9a857d22019-02-11 15:17:13 +0000610
Kristof Umann1a170322019-02-05 00:39:33 +0000611 // Warning: User-facing text should use localized string macro
612 [alarmStateLabel setText:alarmText];
613
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +0000614.. _optin-performance-GCDAntipattern:
615
Kristof Umann1a170322019-02-05 00:39:33 +0000616optin.performance.GCDAntipattern
617""""""""""""""""""""""""""""""""
618Check for performance anti-patterns when using Grand Central Dispatch.
619
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +0000620.. _optin-performance-Padding:
621
Kristof Umann1a170322019-02-05 00:39:33 +0000622optin.performance.Padding
623"""""""""""""""""""""""""
624Check for excessively padded structs.
625
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +0000626.. _optin-portability-UnixAPI:
627
Kristof Umann1a170322019-02-05 00:39:33 +0000628optin.portability.UnixAPI
629"""""""""""""""""""""""""
630Finds implementation-defined behavior in UNIX/Posix functions.
631
632
633.. _security-checkers:
634
635security
636^^^^^^^^
637
638Security related checkers.
639
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +0000640.. _security-FloatLoopCounter:
641
Alexander Kornienko9a857d22019-02-11 15:17:13 +0000642security.FloatLoopCounter (C)
Kristof Umann1a170322019-02-05 00:39:33 +0000643"""""""""""""""""""""""""""""
644Warn on using a floating point value as a loop counter (CERT: FLP30-C, FLP30-CPP).
645
646.. code-block:: c
Alexander Kornienko9a857d22019-02-11 15:17:13 +0000647
Kristof Umann1a170322019-02-05 00:39:33 +0000648 void test() {
649 for (float x = 0.1f; x <= 1.0f; x += 0.1f) {} // warn
650 }
651
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +0000652.. _security-insecureAPI-UncheckedReturn:
653
Alexander Kornienko9a857d22019-02-11 15:17:13 +0000654security.insecureAPI.UncheckedReturn (C)
Kristof Umann1a170322019-02-05 00:39:33 +0000655""""""""""""""""""""""""""""""""""""""""
656Warn on uses of functions whose return values must be always checked.
657
658.. code-block:: c
Alexander Kornienko9a857d22019-02-11 15:17:13 +0000659
Kristof Umann1a170322019-02-05 00:39:33 +0000660 void test() {
661 setuid(1); // warn
662 }
663
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +0000664.. _security-insecureAPI-bcmp:
665
Kristof Umann1a170322019-02-05 00:39:33 +0000666security.insecureAPI.bcmp (C)
667"""""""""""""""""""""""""""""
668Warn on uses of the 'bcmp' function.
669
670.. code-block:: c
Alexander Kornienko9a857d22019-02-11 15:17:13 +0000671
Kristof Umann1a170322019-02-05 00:39:33 +0000672 void test() {
673 bcmp(ptr0, ptr1, n); // warn
674 }
675
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +0000676.. _security-insecureAPI-bcopy:
677
Kristof Umann1a170322019-02-05 00:39:33 +0000678security.insecureAPI.bcopy (C)
679""""""""""""""""""""""""""""""
680Warn on uses of the 'bcopy' function.
681
682.. code-block:: c
683
684 void test() {
685 bcopy(src, dst, n); // warn
686 }
687
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +0000688.. _security-insecureAPI-bzero:
689
Kristof Umann1a170322019-02-05 00:39:33 +0000690security.insecureAPI.bzero (C)
691""""""""""""""""""""""""""""""
692Warn on uses of the 'bzero' function.
693
694.. code-block:: c
Alexander Kornienko9a857d22019-02-11 15:17:13 +0000695
Kristof Umann1a170322019-02-05 00:39:33 +0000696 void test() {
697 bzero(ptr, n); // warn
698 }
699
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +0000700.. _security-insecureAPI-getpw:
701
Alexander Kornienko9a857d22019-02-11 15:17:13 +0000702security.insecureAPI.getpw (C)
Kristof Umann1a170322019-02-05 00:39:33 +0000703""""""""""""""""""""""""""""""
704Warn on uses of the 'getpw' function.
705
706.. code-block:: c
Alexander Kornienko9a857d22019-02-11 15:17:13 +0000707
Kristof Umann1a170322019-02-05 00:39:33 +0000708 void test() {
709 char buff[1024];
710 getpw(2, buff); // warn
711 }
712
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +0000713.. _security-insecureAPI-gets:
714
Kristof Umann1a170322019-02-05 00:39:33 +0000715security.insecureAPI.gets (C)
716"""""""""""""""""""""""""""""
717Warn on uses of the 'gets' function.
718
719.. code-block:: c
Alexander Kornienko9a857d22019-02-11 15:17:13 +0000720
Kristof Umann1a170322019-02-05 00:39:33 +0000721 void test() {
722 char buff[1024];
723 gets(buff); // warn
724 }
725
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +0000726.. _security-insecureAPI-mkstemp:
727
Kristof Umann1a170322019-02-05 00:39:33 +0000728security.insecureAPI.mkstemp (C)
729""""""""""""""""""""""""""""""""
730Warn when 'mkstemp' is passed fewer than 6 X's in the format string.
731
732.. code-block:: c
733
734 void test() {
735 mkstemp("XX"); // warn
736 }
Alexander Kornienko9a857d22019-02-11 15:17:13 +0000737
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +0000738.. _security-insecureAPI-mktemp:
739
Alexander Kornienko9a857d22019-02-11 15:17:13 +0000740security.insecureAPI.mktemp (C)
Kristof Umann1a170322019-02-05 00:39:33 +0000741"""""""""""""""""""""""""""""""
742Warn on uses of the ``mktemp`` function.
743
744.. code-block:: c
Alexander Kornienko9a857d22019-02-11 15:17:13 +0000745
Kristof Umann1a170322019-02-05 00:39:33 +0000746 void test() {
747 char *x = mktemp("/tmp/zxcv"); // warn: insecure, use mkstemp
748 }
749
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +0000750.. _security-insecureAPI-rand:
751
Alexander Kornienko9a857d22019-02-11 15:17:13 +0000752security.insecureAPI.rand (C)
Kristof Umann1a170322019-02-05 00:39:33 +0000753"""""""""""""""""""""""""""""
Alexander Kornienko9a857d22019-02-11 15:17:13 +0000754Warn on uses of inferior random number generating functions (only if arc4random function is available):
Kristof Umann1a170322019-02-05 00:39:33 +0000755``drand48, erand48, jrand48, lcong48, lrand48, mrand48, nrand48, random, rand_r``.
756
757.. code-block:: c
Alexander Kornienko9a857d22019-02-11 15:17:13 +0000758
Kristof Umann1a170322019-02-05 00:39:33 +0000759 void test() {
760 random(); // warn
761 }
Alexander Kornienko9a857d22019-02-11 15:17:13 +0000762
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +0000763.. _security-insecureAPI-strcpy:
764
Kristof Umann1a170322019-02-05 00:39:33 +0000765security.insecureAPI.strcpy (C)
766"""""""""""""""""""""""""""""""
767Warn on uses of the ``strcpy`` and ``strcat`` functions.
768
769.. code-block:: c
Alexander Kornienko9a857d22019-02-11 15:17:13 +0000770
Kristof Umann1a170322019-02-05 00:39:33 +0000771 void test() {
772 char x[4];
773 char *y = "abcd";
Alexander Kornienko9a857d22019-02-11 15:17:13 +0000774
Kristof Umann1a170322019-02-05 00:39:33 +0000775 strcpy(x, y); // warn
776 }
777
778
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +0000779.. _security-insecureAPI-vfork:
780
Alexander Kornienko9a857d22019-02-11 15:17:13 +0000781security.insecureAPI.vfork (C)
Kristof Umann1a170322019-02-05 00:39:33 +0000782""""""""""""""""""""""""""""""
783 Warn on uses of the 'vfork' function.
784
785.. code-block:: c
Alexander Kornienko9a857d22019-02-11 15:17:13 +0000786
Kristof Umann1a170322019-02-05 00:39:33 +0000787 void test() {
788 vfork(); // warn
789 }
790
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +0000791.. _security-insecureAPI-DeprecatedOrUnsafeBufferHandling:
792
Alexander Kornienko9a857d22019-02-11 15:17:13 +0000793security.insecureAPI.DeprecatedOrUnsafeBufferHandling (C)
794"""""""""""""""""""""""""""""""""""""""""""""""""""""""""
Kristof Umann8d239992019-02-11 13:46:43 +0000795 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``
796
797.. code-block:: c
Alexander Kornienko9a857d22019-02-11 15:17:13 +0000798
Kristof Umann8d239992019-02-11 13:46:43 +0000799 void test() {
800 char buf [5];
801 strncpy(buf, "a", 1); // warn
802 }
803
Kristof Umann1a170322019-02-05 00:39:33 +0000804.. _unix-checkers:
805
806unix
807^^^^
808POSIX/Unix checkers.
809
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +0000810.. _unix-API:
811
Alexander Kornienko9a857d22019-02-11 15:17:13 +0000812unix.API (C)
Kristof Umann1a170322019-02-05 00:39:33 +0000813""""""""""""
814Check calls to various UNIX/Posix functions: ``open, pthread_once, calloc, malloc, realloc, alloca``.
815
Alexander Kornienko9a857d22019-02-11 15:17:13 +0000816.. literalinclude:: checkers/unix_api_example.c
Kristof Umann1a170322019-02-05 00:39:33 +0000817 :language: c
818
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +0000819.. _unix-Malloc:
820
Alexander Kornienko9a857d22019-02-11 15:17:13 +0000821unix.Malloc (C)
Kristof Umann1a170322019-02-05 00:39:33 +0000822"""""""""""""""
823Check for memory leaks, double free, and use-after-free problems. Traces memory managed by malloc()/free().
824
Alexander Kornienko9a857d22019-02-11 15:17:13 +0000825.. literalinclude:: checkers/unix_malloc_example.c
Kristof Umann1a170322019-02-05 00:39:33 +0000826 :language: c
Alexander Kornienko9a857d22019-02-11 15:17:13 +0000827
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +0000828.. _unix-MallocSizeof:
829
Alexander Kornienko9a857d22019-02-11 15:17:13 +0000830unix.MallocSizeof (C)
Kristof Umann1a170322019-02-05 00:39:33 +0000831"""""""""""""""""""""
832Check for dubious ``malloc`` arguments involving ``sizeof``.
833
834.. code-block:: c
Alexander Kornienko9a857d22019-02-11 15:17:13 +0000835
Kristof Umann1a170322019-02-05 00:39:33 +0000836 void test() {
837 long *p = malloc(sizeof(short));
838 // warn: result is converted to 'long *', which is
839 // incompatible with operand type 'short'
840 free(p);
841 }
842
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +0000843.. _unix-MismatchedDeallocator:
844
Kristof Umann1a170322019-02-05 00:39:33 +0000845unix.MismatchedDeallocator (C, C++)
846"""""""""""""""""""""""""""""""""""
847Check for mismatched deallocators.
848
Alexander Kornienko9a857d22019-02-11 15:17:13 +0000849.. literalinclude:: checkers/mismatched_deallocator_example.cpp
Kristof Umann1a170322019-02-05 00:39:33 +0000850 :language: c
851
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +0000852.. _unix-Vfork:
853
Alexander Kornienko9a857d22019-02-11 15:17:13 +0000854unix.Vfork (C)
Kristof Umann1a170322019-02-05 00:39:33 +0000855""""""""""""""
856Check for proper usage of ``vfork``.
857
858.. code-block:: c
Alexander Kornienko9a857d22019-02-11 15:17:13 +0000859
Kristof Umann1a170322019-02-05 00:39:33 +0000860 int test(int x) {
861 pid_t pid = vfork(); // warn
862 if (pid != 0)
863 return 0;
Alexander Kornienko9a857d22019-02-11 15:17:13 +0000864
Kristof Umann1a170322019-02-05 00:39:33 +0000865 switch (x) {
866 case 0:
867 pid = 1;
868 execl("", "", 0);
869 _exit(1);
870 break;
871 case 1:
872 x = 0; // warn: this assignment is prohibited
873 break;
874 case 2:
875 foo(); // warn: this function call is prohibited
876 break;
877 default:
878 return 0; // warn: return is prohibited
879 }
Alexander Kornienko9a857d22019-02-11 15:17:13 +0000880
Kristof Umann1a170322019-02-05 00:39:33 +0000881 while(1);
882 }
883
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +0000884.. _unix-cstring-BadSizeArg:
885
Alexander Kornienko9a857d22019-02-11 15:17:13 +0000886unix.cstring.BadSizeArg (C)
Kristof Umann1a170322019-02-05 00:39:33 +0000887"""""""""""""""""""""""""""
Alexander Kornienko9a857d22019-02-11 15:17:13 +0000888Check 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 +0000889
890.. code-block:: c
Alexander Kornienko9a857d22019-02-11 15:17:13 +0000891
Kristof Umann1a170322019-02-05 00:39:33 +0000892 void test() {
893 char dest[3];
894 strncat(dest, """""""""""""""""""""""""*", sizeof(dest));
895 // warn: potential buffer overflow
896 }
897
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +0000898.. _unix-cstrisng-NullArg:
899
Alexander Kornienko9a857d22019-02-11 15:17:13 +0000900unix.cstrisng.NullArg (C)
Kristof Umann1a170322019-02-05 00:39:33 +0000901"""""""""""""""""""""""""
Alexander Kornienko9a857d22019-02-11 15:17:13 +0000902Check for null pointers being passed as arguments to C string functions:
Kristof Umann1a170322019-02-05 00:39:33 +0000903``strlen, strnlen, strcpy, strncpy, strcat, strncat, strcmp, strncmp, strcasecmp, strncasecmp``.
904
905.. code-block:: c
906
907 int test() {
908 return strlen(0); // warn
909 }
910
911.. _osx-checkers:
912
913osx
914^^^
J. Ryan Stinnettd45eaf92019-05-30 16:46:22 +0000915macOS checkers.
Alexander Kornienko9a857d22019-02-11 15:17:13 +0000916
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +0000917.. _osx-API:
918
Alexander Kornienko9a857d22019-02-11 15:17:13 +0000919osx.API (C)
Kristof Umann1a170322019-02-05 00:39:33 +0000920"""""""""""
921Check for proper uses of various Apple APIs.
922
923.. code-block:: objc
924
925 void test() {
926 dispatch_once_t pred = 0;
927 dispatch_once(&pred, ^(){}); // warn: dispatch_once uses local
928 }
929
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +0000930.. _osx-NumberObjectConversion:
931
Kristof Umann1a170322019-02-05 00:39:33 +0000932osx.NumberObjectConversion (C, C++, ObjC)
933"""""""""""""""""""""""""""""""""""""""""
934Check for erroneous conversions of objects representing numbers into numbers.
935
936.. code-block:: objc
Alexander Kornienko9a857d22019-02-11 15:17:13 +0000937
Kristof Umann1a170322019-02-05 00:39:33 +0000938 NSNumber *photoCount = [albumDescriptor objectForKey:@"PhotoCount"];
939 // Warning: Comparing a pointer value of type 'NSNumber *'
940 // to a scalar integer value
941 if (photoCount > 0) {
942 [self displayPhotos];
943 }
944
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +0000945.. _osx-ObjCProperty:
946
Kristof Umann1a170322019-02-05 00:39:33 +0000947osx.ObjCProperty (ObjC)
948"""""""""""""""""""""""
949Check for proper uses of Objective-C properties.
950
951.. code-block:: objc
Alexander Kornienko9a857d22019-02-11 15:17:13 +0000952
Kristof Umann1a170322019-02-05 00:39:33 +0000953 NSNumber *photoCount = [albumDescriptor objectForKey:@"PhotoCount"];
954 // Warning: Comparing a pointer value of type 'NSNumber *'
955 // to a scalar integer value
956 if (photoCount > 0) {
957 [self displayPhotos];
958 }
959
960
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +0000961.. _osx-SecKeychainAPI:
962
Alexander Kornienko9a857d22019-02-11 15:17:13 +0000963osx.SecKeychainAPI (C)
Kristof Umann1a170322019-02-05 00:39:33 +0000964""""""""""""""""""""""
965Check for proper uses of Secure Keychain APIs.
966
Alexander Kornienko9a857d22019-02-11 15:17:13 +0000967.. literalinclude:: checkers/seckeychainapi_example.m
Kristof Umann1a170322019-02-05 00:39:33 +0000968 :language: objc
969
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +0000970.. _osx-cocoa-AtSync:
971
Kristof Umann1a170322019-02-05 00:39:33 +0000972osx.cocoa.AtSync (ObjC)
973"""""""""""""""""""""""
974Check for nil pointers used as mutexes for @synchronized.
975
976.. code-block:: objc
977
978 void test(id x) {
979 if (!x)
980 @synchronized(x) {} // warn: nil value used as mutex
981 }
Alexander Kornienko9a857d22019-02-11 15:17:13 +0000982
Kristof Umann1a170322019-02-05 00:39:33 +0000983 void test() {
984 id y;
985 @synchronized(y) {} // warn: uninitialized value used as mutex
986 }
987
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +0000988.. _osx-cocoa-AutoreleaseWrite:
989
Kristof Umann1a170322019-02-05 00:39:33 +0000990osx.cocoa.AutoreleaseWrite
Alexander Kornienko9a857d22019-02-11 15:17:13 +0000991""""""""""""""""""""""""""
Kristof Umann1a170322019-02-05 00:39:33 +0000992Warn about potentially crashing writes to autoreleasing objects from different autoreleasing pools in Objective-C.
993
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +0000994.. _osx-cocoa-ClassRelease:
995
Kristof Umann1a170322019-02-05 00:39:33 +0000996osx.cocoa.ClassRelease (ObjC)
997"""""""""""""""""""""""""""""
998Check for sending 'retain', 'release', or 'autorelease' directly to a Class.
999
1000.. code-block:: objc
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001001
Kristof Umann1a170322019-02-05 00:39:33 +00001002 @interface MyClass : NSObject
1003 @end
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001004
Kristof Umann1a170322019-02-05 00:39:33 +00001005 void test(void) {
1006 [MyClass release]; // warn
1007 }
1008
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +00001009.. _osx-cocoa-Dealloc:
1010
Kristof Umann1a170322019-02-05 00:39:33 +00001011osx.cocoa.Dealloc (ObjC)
1012""""""""""""""""""""""""
1013Warn about Objective-C classes that lack a correct implementation of -dealloc
1014
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001015.. literalinclude:: checkers/dealloc_example.m
Kristof Umann1a170322019-02-05 00:39:33 +00001016 :language: objc
1017
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +00001018.. _osx-cocoa-IncompatibleMethodTypes:
1019
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001020osx.cocoa.IncompatibleMethodTypes (ObjC)
Kristof Umann1a170322019-02-05 00:39:33 +00001021""""""""""""""""""""""""""""""""""""""""
1022Warn about Objective-C method signatures with type incompatibilities.
1023
1024.. code-block:: objc
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001025
Kristof Umann1a170322019-02-05 00:39:33 +00001026 @interface MyClass1 : NSObject
1027 - (int)foo;
1028 @end
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001029
Kristof Umann1a170322019-02-05 00:39:33 +00001030 @implementation MyClass1
1031 - (int)foo { return 1; }
1032 @end
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001033
Kristof Umann1a170322019-02-05 00:39:33 +00001034 @interface MyClass2 : MyClass1
1035 - (float)foo;
1036 @end
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001037
Kristof Umann1a170322019-02-05 00:39:33 +00001038 @implementation MyClass2
1039 - (float)foo { return 1.0; } // warn
1040 @end
1041
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +00001042.. _osx-cocoa-Loops:
1043
Kristof Umann1a170322019-02-05 00:39:33 +00001044osx.cocoa.Loops
1045"""""""""""""""
1046Improved modeling of loops using Cocoa collection types.
1047
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +00001048.. _osx-cocoa-MissingSuperCall:
1049
Kristof Umann1a170322019-02-05 00:39:33 +00001050osx.cocoa.MissingSuperCall (ObjC)
1051"""""""""""""""""""""""""""""""""
1052Warn about Objective-C methods that lack a necessary call to super.
1053
1054.. code-block:: objc
1055
1056 @interface Test : UIViewController
1057 @end
1058 @implementation test
1059 - (void)viewDidLoad {} // warn
1060 @end
1061
1062
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +00001063.. _osx-cocoa-NSAutoreleasePool:
1064
Kristof Umann1a170322019-02-05 00:39:33 +00001065osx.cocoa.NSAutoreleasePool (ObjC)
1066""""""""""""""""""""""""""""""""""
1067Warn for suboptimal uses of NSAutoreleasePool in Objective-C GC mode.
1068
1069.. code-block:: objc
1070
1071 void test() {
1072 NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
1073 [pool release]; // warn
1074 }
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001075
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +00001076.. _osx-cocoa-NSError:
1077
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001078osx.cocoa.NSError (ObjC)
Kristof Umann1a170322019-02-05 00:39:33 +00001079""""""""""""""""""""""""
1080Check usage of NSError parameters.
1081
1082.. code-block:: objc
1083
1084 @interface A : NSObject
1085 - (void)foo:(NSError """""""""""""""""""""""")error;
1086 @end
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001087
Kristof Umann1a170322019-02-05 00:39:33 +00001088 @implementation A
1089 - (void)foo:(NSError """""""""""""""""""""""")error {
1090 // warn: method accepting NSError"""""""""""""""""""""""" should have a non-void
1091 // return value
1092 }
1093 @end
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001094
Kristof Umann1a170322019-02-05 00:39:33 +00001095 @interface A : NSObject
1096 - (BOOL)foo:(NSError """""""""""""""""""""""")error;
1097 @end
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001098
Kristof Umann1a170322019-02-05 00:39:33 +00001099 @implementation A
1100 - (BOOL)foo:(NSError """""""""""""""""""""""")error {
1101 *error = 0; // warn: potential null dereference
1102 return 0;
1103 }
1104 @end
1105
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +00001106.. _osx-cocoa-NilArg:
1107
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001108osx.cocoa.NilArg (ObjC)
Kristof Umann1a170322019-02-05 00:39:33 +00001109"""""""""""""""""""""""
1110Check for prohibited nil arguments to ObjC method calls.
1111
1112 - caseInsensitiveCompare:
1113 - compare:
1114 - compare:options:
1115 - compare:options:range:
1116 - compare:options:range:locale:
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001117 - componentsSeparatedByCharactersInSet:
Kristof Umann1a170322019-02-05 00:39:33 +00001118 - initWithFormat:
1119
1120.. code-block:: objc
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001121
Kristof Umann1a170322019-02-05 00:39:33 +00001122 NSComparisonResult test(NSString *s) {
1123 NSString *aString = nil;
1124 return [s caseInsensitiveCompare:aString];
1125 // warn: argument to 'NSString' method
1126 // 'caseInsensitiveCompare:' cannot be nil
1127 }
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001128
Kristof Umann1a170322019-02-05 00:39:33 +00001129
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +00001130.. _osx-cocoa-NonNilReturnValue:
1131
Kristof Umann1a170322019-02-05 00:39:33 +00001132osx.cocoa.NonNilReturnValue
1133"""""""""""""""""""""""""""
1134Models the APIs that are guaranteed to return a non-nil value.
1135
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +00001136.. _osx-cocoa-ObjCGenerics:
1137
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001138osx.cocoa.ObjCGenerics (ObjC)
Kristof Umann1a170322019-02-05 00:39:33 +00001139"""""""""""""""""""""""""""""
1140Check for type errors when using Objective-C generics.
1141
1142.. code-block:: objc
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001143
Kristof Umann1a170322019-02-05 00:39:33 +00001144 NSMutableArray *names = [NSMutableArray array];
1145 NSMutableArray *birthDates = names;
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001146
Kristof Umann1a170322019-02-05 00:39:33 +00001147 // Warning: Conversion from value of type 'NSDate *'
1148 // to incompatible type 'NSString *'
1149 [birthDates addObject: [NSDate date]];
1150
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +00001151.. _osx-cocoa-RetainCount:
1152
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001153osx.cocoa.RetainCount (ObjC)
Kristof Umann1a170322019-02-05 00:39:33 +00001154""""""""""""""""""""""""""""
1155Check for leaks and improper reference count management
1156
1157.. code-block:: objc
1158
1159 void test() {
1160 NSString *s = [[NSString alloc] init]; // warn
1161 }
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001162
Kristof Umann1a170322019-02-05 00:39:33 +00001163 CFStringRef test(char *bytes) {
1164 return CFStringCreateWithCStringNoCopy(
1165 0, bytes, NSNEXTSTEPStringEncoding, 0); // warn
1166 }
1167
1168
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +00001169.. _osx-cocoa-RunLoopAutoreleaseLeak:
1170
Kristof Umann1a170322019-02-05 00:39:33 +00001171osx.cocoa.RunLoopAutoreleaseLeak
1172""""""""""""""""""""""""""""""""
1173Check for leaked memory in autorelease pools that will never be drained.
1174
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +00001175.. _osx-cocoa-SelfInit:
1176
Kristof Umann1a170322019-02-05 00:39:33 +00001177osx.cocoa.SelfInit (ObjC)
1178"""""""""""""""""""""""""
1179Check that 'self' is properly initialized inside an initializer method.
1180
1181.. code-block:: objc
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001182
Kristof Umann1a170322019-02-05 00:39:33 +00001183 @interface MyObj : NSObject {
1184 id x;
1185 }
1186 - (id)init;
1187 @end
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001188
Kristof Umann1a170322019-02-05 00:39:33 +00001189 @implementation MyObj
1190 - (id)init {
1191 [super init];
1192 x = 0; // warn: instance variable used while 'self' is not
1193 // initialized
1194 return 0;
1195 }
1196 @end
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001197
Kristof Umann1a170322019-02-05 00:39:33 +00001198 @interface MyObj : NSObject
1199 - (id)init;
1200 @end
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001201
Kristof Umann1a170322019-02-05 00:39:33 +00001202 @implementation MyObj
1203 - (id)init {
1204 [super init];
1205 return self; // warn: returning uninitialized 'self'
1206 }
1207 @end
1208
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +00001209.. _osx-cocoa-SuperDealloc:
1210
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001211osx.cocoa.SuperDealloc (ObjC)
Kristof Umann1a170322019-02-05 00:39:33 +00001212"""""""""""""""""""""""""""""
1213Warn about improper use of '[super dealloc]' in Objective-C.
1214
1215.. code-block:: objc
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001216
Kristof Umann1a170322019-02-05 00:39:33 +00001217 @interface SuperDeallocThenReleaseIvarClass : NSObject {
1218 NSObject *_ivar;
1219 }
1220 @end
1221
1222 @implementation SuperDeallocThenReleaseIvarClass
1223 - (void)dealloc {
1224 [super dealloc];
1225 [_ivar release]; // warn
1226 }
1227 @end
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001228
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +00001229.. _osx-cocoa-UnusedIvars:
1230
Kristof Umann1a170322019-02-05 00:39:33 +00001231osx.cocoa.UnusedIvars (ObjC)
1232""""""""""""""""""""""""""""
1233Warn about private ivars that are never used.
1234
1235.. code-block:: objc
1236
1237 @interface MyObj : NSObject {
1238 @private
1239 id x; // warn
1240 }
1241 @end
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001242
Kristof Umann1a170322019-02-05 00:39:33 +00001243 @implementation MyObj
1244 @end
1245
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +00001246.. _osx-cocoa-VariadicMethodTypes:
1247
Kristof Umann1a170322019-02-05 00:39:33 +00001248osx.cocoa.VariadicMethodTypes (ObjC)
1249""""""""""""""""""""""""""""""""""""
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001250Check for passing non-Objective-C types to variadic collection
Kristof Umann1a170322019-02-05 00:39:33 +00001251initialization methods that expect only Objective-C types.
1252
1253.. code-block:: objc
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001254
Kristof Umann1a170322019-02-05 00:39:33 +00001255 void test() {
1256 [NSSet setWithObjects:@"Foo", "Bar", nil];
1257 // warn: argument should be an ObjC pointer type, not 'char *'
1258 }
1259
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +00001260.. _osx-coreFoundation-CFError:
1261
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001262osx.coreFoundation.CFError (C)
Kristof Umann1a170322019-02-05 00:39:33 +00001263""""""""""""""""""""""""""""""
1264Check usage of CFErrorRef* parameters
1265
1266.. code-block:: c
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001267
Kristof Umann1a170322019-02-05 00:39:33 +00001268 void test(CFErrorRef *error) {
1269 // warn: function accepting CFErrorRef* should have a
1270 // non-void return
1271 }
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001272
Kristof Umann1a170322019-02-05 00:39:33 +00001273 int foo(CFErrorRef *error) {
1274 *error = 0; // warn: potential null dereference
1275 return 0;
1276 }
1277
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +00001278.. _osx-coreFoundation-CFNumber:
1279
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001280osx.coreFoundation.CFNumber (C)
Kristof Umann1a170322019-02-05 00:39:33 +00001281"""""""""""""""""""""""""""""""
1282Check for proper uses of CFNumber APIs.
1283
1284.. code-block:: c
1285
1286 CFNumberRef test(unsigned char x) {
1287 return CFNumberCreate(0, kCFNumberSInt16Type, &x);
1288 // warn: 8 bit integer is used to initialize a 16 bit integer
1289 }
1290
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +00001291.. _osx-coreFoundation-CFRetainRelease:
1292
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001293osx.coreFoundation.CFRetainRelease (C)
Kristof Umann1a170322019-02-05 00:39:33 +00001294""""""""""""""""""""""""""""""""""""""
1295Check for null arguments to CFRetain/CFRelease/CFMakeCollectable.
1296
1297.. code-block:: c
1298
1299 void test(CFTypeRef p) {
1300 if (!p)
1301 CFRetain(p); // warn
1302 }
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001303
Kristof Umann1a170322019-02-05 00:39:33 +00001304 void test(int x, CFTypeRef p) {
1305 if (p)
1306 return;
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001307
Kristof Umann1a170322019-02-05 00:39:33 +00001308 CFRelease(p); // warn
1309 }
1310
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +00001311.. _osx-coreFoundation-containers-OutOfBounds:
1312
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001313osx.coreFoundation.containers.OutOfBounds (C)
Kristof Umann1a170322019-02-05 00:39:33 +00001314"""""""""""""""""""""""""""""""""""""""""""""
1315Checks for index out-of-bounds when using 'CFArray' API.
1316
1317.. code-block:: c
1318
1319 void test() {
1320 CFArrayRef A = CFArrayCreate(0, 0, 0, &kCFTypeArrayCallBacks);
1321 CFArrayGetValueAtIndex(A, 0); // warn
1322 }
1323
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +00001324.. _osx-coreFoundation-containers-PointerSizedValues:
1325
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001326osx.coreFoundation.containers.PointerSizedValues (C)
Kristof Umann1a170322019-02-05 00:39:33 +00001327""""""""""""""""""""""""""""""""""""""""""""""""""""
1328Warns if 'CFArray', 'CFDictionary', 'CFSet' are created with non-pointer-size values.
1329
1330.. code-block:: c
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001331
Kristof Umann1a170322019-02-05 00:39:33 +00001332 void test() {
1333 int x[] = { 1 };
1334 CFArrayRef A = CFArrayCreate(0, (const void """""""""""""""""""""""")x, 1,
1335 &kCFTypeArrayCallBacks); // warn
1336 }
1337
1338
1339.. _alpha-checkers:
1340
1341Experimental Checkers
1342---------------------
1343
1344*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.*
1345
1346alpha.clone
1347^^^^^^^^^^^
1348
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +00001349.. _alpha-clone-CloneChecker:
1350
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001351alpha.clone.CloneChecker (C, C++, ObjC)
Kristof Umann1a170322019-02-05 00:39:33 +00001352"""""""""""""""""""""""""""""""""""""""
1353Reports similar pieces of code.
1354
1355.. code-block:: c
1356
1357 void log();
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001358
Kristof Umann1a170322019-02-05 00:39:33 +00001359 int max(int a, int b) { // warn
1360 log();
1361 if (a > b)
1362 return a;
1363 return b;
1364 }
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001365
Kristof Umann1a170322019-02-05 00:39:33 +00001366 int maxClone(int x, int y) { // similar code here
1367 log();
1368 if (x > y)
1369 return x;
1370 return y;
1371 }
1372
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +00001373.. _alpha-core-BoolAssignment:
1374
Kristof Umann1a170322019-02-05 00:39:33 +00001375alpha.core.BoolAssignment (ObjC)
1376""""""""""""""""""""""""""""""""
1377Warn about assigning non-{0,1} values to boolean variables.
1378
1379.. code-block:: objc
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001380
Kristof Umann1a170322019-02-05 00:39:33 +00001381 void test() {
1382 BOOL b = -1; // warn
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001383 }
Kristof Umann1a170322019-02-05 00:39:33 +00001384
1385alpha.core
1386^^^^^^^^^^
1387
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +00001388.. _alpha-core-CallAndMessageUnInitRefArg:
1389
Kristof Umann1a170322019-02-05 00:39:33 +00001390alpha.core.CallAndMessageUnInitRefArg (C,C++, ObjC)
1391"""""""""""""""""""""""""""""""""""""""""""""""""""
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001392Check for logical errors for function calls and Objective-C
Kristof Umann1a170322019-02-05 00:39:33 +00001393message expressions (e.g., uninitialized arguments, null function pointers, and pointer to undefined variables).
1394
1395.. code-block:: c
1396
1397 void test(void) {
1398 int t;
1399 int &p = t;
1400 int &s = p;
1401 int &q = s;
1402 foo(q); // warn
1403 }
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001404
Kristof Umann1a170322019-02-05 00:39:33 +00001405 void test(void) {
1406 int x;
1407 foo(&x); // warn
1408 }
1409
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +00001410.. _alpha-core-CastSize:
1411
Kristof Umann1a170322019-02-05 00:39:33 +00001412alpha.core.CastSize (C)
1413"""""""""""""""""""""""
1414Check when casting a malloc'ed type ``T``, whether the size is a multiple of the size of ``T``.
1415
1416.. code-block:: c
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001417
Kristof Umann1a170322019-02-05 00:39:33 +00001418 void test() {
1419 int *x = (int *) malloc(11); // warn
1420 }
1421
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +00001422.. _alpha-core-CastToStruct:
1423
Kristof Umann1a170322019-02-05 00:39:33 +00001424alpha.core.CastToStruct (C, C++)
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001425""""""""""""""""""""""""""""""""
Kristof Umann1a170322019-02-05 00:39:33 +00001426Check for cast from non-struct pointer to struct pointer.
1427
1428.. code-block:: cpp
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001429
Kristof Umann1a170322019-02-05 00:39:33 +00001430 // C
1431 struct s {};
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001432
Kristof Umann1a170322019-02-05 00:39:33 +00001433 void test(int *p) {
1434 struct s *ps = (struct s *) p; // warn
1435 }
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001436
Kristof Umann1a170322019-02-05 00:39:33 +00001437 // C++
1438 class c {};
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001439
Kristof Umann1a170322019-02-05 00:39:33 +00001440 void test(int *p) {
1441 c *pc = (c *) p; // warn
1442 }
1443
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +00001444.. _alpha-core-Conversion:
1445
Kristof Umann1a170322019-02-05 00:39:33 +00001446alpha.core.Conversion (C, C++, ObjC)
1447""""""""""""""""""""""""""""""""""""
1448Loss of sign/precision in implicit conversions.
1449
1450.. code-block:: c
1451
1452 void test(unsigned U, signed S) {
1453 if (S > 10) {
1454 if (U < S) {
1455 }
1456 }
1457 if (S < -10) {
1458 if (U < S) { // warn (loss of sign)
1459 }
1460 }
1461 }
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001462
Kristof Umann1a170322019-02-05 00:39:33 +00001463 void test() {
1464 long long A = 1LL << 60;
1465 short X = A; // warn (loss of precision)
1466 }
1467
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +00001468.. _alpha-core-DynamicTypeChecker:
1469
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001470alpha.core.DynamicTypeChecker (ObjC)
Kristof Umann1a170322019-02-05 00:39:33 +00001471""""""""""""""""""""""""""""""""""""
1472Check for cases where the dynamic and the static type of an object are unrelated.
1473
1474
1475.. code-block:: objc
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001476
Kristof Umann1a170322019-02-05 00:39:33 +00001477 id date = [NSDate date];
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001478
Kristof Umann1a170322019-02-05 00:39:33 +00001479 // Warning: Object has a dynamic type 'NSDate *' which is
1480 // incompatible with static type 'NSNumber *'"
1481 NSNumber *number = date;
1482 [number doubleValue];
1483
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +00001484.. _alpha-core-FixedAddr:
1485
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001486alpha.core.FixedAddr (C)
Kristof Umann1a170322019-02-05 00:39:33 +00001487""""""""""""""""""""""""
1488Check for assignment of a fixed address to a pointer.
1489
1490.. code-block:: c
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001491
Kristof Umann1a170322019-02-05 00:39:33 +00001492 void test() {
1493 int *p;
1494 p = (int *) 0x10000; // warn
1495 }
1496
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +00001497.. _alpha-core-IdenticalExpr:
1498
Kristof Umann1a170322019-02-05 00:39:33 +00001499alpha.core.IdenticalExpr (C, C++)
1500"""""""""""""""""""""""""""""""""
1501Warn about unintended use of identical expressions in operators.
1502
1503.. code-block:: cpp
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001504
Kristof Umann1a170322019-02-05 00:39:33 +00001505 // C
1506 void test() {
1507 int a = 5;
1508 int b = a | 4 | a; // warn: identical expr on both sides
1509 }
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001510
Kristof Umann1a170322019-02-05 00:39:33 +00001511 // C++
1512 bool f(void);
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001513
Kristof Umann1a170322019-02-05 00:39:33 +00001514 void test(bool b) {
1515 int i = 10;
1516 if (f()) { // warn: true and false branches are identical
1517 do {
1518 i--;
1519 } while (f());
1520 } else {
1521 do {
1522 i--;
1523 } while (f());
1524 }
1525 }
1526
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +00001527.. _alpha-core-PointerArithm:
1528
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001529alpha.core.PointerArithm (C)
Kristof Umann1a170322019-02-05 00:39:33 +00001530""""""""""""""""""""""""""""
1531Check for pointer arithmetic on locations other than array elements.
1532
1533.. code-block:: c
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001534
Kristof Umann1a170322019-02-05 00:39:33 +00001535 void test() {
1536 int x;
1537 int *p;
1538 p = &x + 1; // warn
1539 }
1540
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +00001541.. _alpha-core-PointerSub:
1542
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001543alpha.core.PointerSub (C)
Kristof Umann1a170322019-02-05 00:39:33 +00001544"""""""""""""""""""""""""
1545Check for pointer subtractions on two pointers pointing to different memory chunks.
1546
1547.. code-block:: c
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001548
Kristof Umann1a170322019-02-05 00:39:33 +00001549 void test() {
1550 int x, y;
1551 int d = &y - &x; // warn
1552 }
1553
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +00001554.. _alpha-core-SizeofPtr:
1555
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001556alpha.core.SizeofPtr (C)
Kristof Umann1a170322019-02-05 00:39:33 +00001557""""""""""""""""""""""""
1558Warn about unintended use of ``sizeof()`` on pointer expressions.
1559
1560.. code-block:: c
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001561
Kristof Umann1a170322019-02-05 00:39:33 +00001562 struct s {};
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001563
Kristof Umann1a170322019-02-05 00:39:33 +00001564 int test(struct s *p) {
1565 return sizeof(p);
1566 // warn: sizeof(ptr) can produce an unexpected result
1567 }
1568
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +00001569.. _alpha-core-StackAddressAsyncEscape:
1570
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001571alpha.core.StackAddressAsyncEscape (C)
Kristof Umann1a170322019-02-05 00:39:33 +00001572""""""""""""""""""""""""""""""""""""""
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001573Check that addresses to stack memory do not escape the function that involves dispatch_after or dispatch_async.
Kristof Umann1a170322019-02-05 00:39:33 +00001574This checker is a part of ``core.StackAddressEscape``, but is temporarily disabled until some false positives are fixed.
1575
1576.. code-block:: c
1577
1578 dispatch_block_t test_block_inside_block_async_leak() {
1579 int x = 123;
1580 void (^inner)(void) = ^void(void) {
1581 int y = x;
1582 ++y;
1583 };
1584 void (^outer)(void) = ^void(void) {
1585 int z = x;
1586 ++z;
1587 inner();
1588 };
1589 return outer; // warn: address of stack-allocated block is captured by a
1590 // returned block
1591 }
1592
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +00001593.. _alpha-core-TestAfterDivZero:
1594
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001595alpha.core.TestAfterDivZero (C)
Kristof Umann1a170322019-02-05 00:39:33 +00001596"""""""""""""""""""""""""""""""
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001597Check for division by variable that is later compared against 0.
Kristof Umann1a170322019-02-05 00:39:33 +00001598Either the comparison is useless or there is division by zero.
1599
1600.. code-block:: c
1601
1602 void test(int x) {
1603 var = 77 / x;
1604 if (x == 0) { } // warn
1605 }
1606
1607alpha.cplusplus
1608^^^^^^^^^^^^^^^
1609
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +00001610.. _alpha-cplusplus-DeleteWithNonVirtualDtor:
1611
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001612alpha.cplusplus.DeleteWithNonVirtualDtor (C++)
Kristof Umann1a170322019-02-05 00:39:33 +00001613""""""""""""""""""""""""""""""""""""""""""""""
1614Reports destructions of polymorphic objects with a non-virtual destructor in their base class.
1615
1616.. code-block:: cpp
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001617
Kristof Umann1a170322019-02-05 00:39:33 +00001618 NonVirtual *create() {
1619 NonVirtual *x = new NVDerived(); // note: conversion from derived to base
1620 // happened here
1621 return x;
1622 }
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001623
Kristof Umann1a170322019-02-05 00:39:33 +00001624 void sink(NonVirtual *x) {
1625 delete x; // warn: destruction of a polymorphic object with no virtual
1626 // destructor
1627 }
1628
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +00001629.. _alpha-cplusplus-EnumCastOutOfRange:
1630
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001631alpha.cplusplus.EnumCastOutOfRange (C++)
Kristof Umann1a170322019-02-05 00:39:33 +00001632""""""""""""""""""""""""""""""""""""""""
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001633Check for integer to enumeration casts that could result in undefined values.
Kristof Umann1a170322019-02-05 00:39:33 +00001634
1635.. code-block:: cpp
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001636
Kristof Umann1a170322019-02-05 00:39:33 +00001637 enum TestEnum {
1638 A = 0
1639 };
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001640
Kristof Umann1a170322019-02-05 00:39:33 +00001641 void foo() {
1642 TestEnum t = static_cast(-1);
1643 // warn: the value provided to the cast expression is not in
1644 the valid range of values for the enum
1645
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +00001646.. _alpha-cplusplus-InvalidatedIterator:
1647
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001648alpha.cplusplus.InvalidatedIterator (C++)
Kristof Umann1a170322019-02-05 00:39:33 +00001649"""""""""""""""""""""""""""""""""""""""""
1650Check for use of invalidated iterators.
1651
1652.. code-block:: cpp
1653
1654 void bad_copy_assign_operator_list1(std::list &L1,
1655 const std::list &L2) {
1656 auto i0 = L1.cbegin();
1657 L1 = L2;
1658 *i0; // warn: invalidated iterator accessed
1659 }
1660
1661
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +00001662.. _alpha-cplusplus-IteratorRange:
1663
Kristof Umann1a170322019-02-05 00:39:33 +00001664alpha.cplusplus.IteratorRange (C++)
1665"""""""""""""""""""""""""""""""""""
1666Check for iterators used outside their valid ranges.
1667
1668.. code-block:: cpp
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001669
Kristof Umann1a170322019-02-05 00:39:33 +00001670 void simple_bad_end(const std::vector &v) {
1671 auto i = v.end();
1672 *i; // warn: iterator accessed outside of its range
1673 }
1674
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +00001675.. _alpha-cplusplus-MismatchedIterator:
1676
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001677alpha.cplusplus.MismatchedIterator (C++)
Kristof Umann1a170322019-02-05 00:39:33 +00001678""""""""""""""""""""""""""""""""""""""""
1679Check for use of iterators of different containers where iterators of the same container are expected.
1680
1681.. code-block:: cpp
1682
1683 void bad_insert3(std::vector &v1, std::vector &v2) {
1684 v2.insert(v1.cbegin(), v2.cbegin(), v2.cend()); // warn: container accessed
1685 // using foreign
1686 // iterator argument
1687 v1.insert(v1.cbegin(), v1.cbegin(), v2.cend()); // warn: iterators of
1688 // different containers
1689 // used where the same
1690 // container is
1691 // expected
1692 v1.insert(v1.cbegin(), v2.cbegin(), v1.cend()); // warn: iterators of
1693 // different containers
1694 // used where the same
1695 // container is
1696 // expected
1697 }
1698
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +00001699.. _alpha-cplusplus-MisusedMovedObject:
1700
Kristof Umann1a170322019-02-05 00:39:33 +00001701alpha.cplusplus.MisusedMovedObject (C++)
1702""""""""""""""""""""""""""""""""""""""""
1703Method calls on a moved-from object and copying a moved-from object will be reported.
1704
1705
1706.. code-block:: cpp
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001707
Kristof Umann1a170322019-02-05 00:39:33 +00001708 struct A {
1709 void foo() {}
1710 };
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001711
Kristof Umann1a170322019-02-05 00:39:33 +00001712 void f() {
1713 A a;
1714 A b = std::move(a); // note: 'a' became 'moved-from' here
1715 a.foo(); // warn: method call on a 'moved-from' object 'a'
1716 }
1717
Kristof Umann1a170322019-02-05 00:39:33 +00001718alpha.deadcode
1719^^^^^^^^^^^^^^
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +00001720.. _alpha-deadcode-UnreachableCode:
1721
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001722alpha.deadcode.UnreachableCode (C, C++)
Kristof Umann1a170322019-02-05 00:39:33 +00001723"""""""""""""""""""""""""""""""""""""""
1724Check unreachable code.
1725
1726.. code-block:: cpp
1727
1728 // C
1729 int test() {
1730 int x = 1;
1731 while(x);
1732 return x; // warn
1733 }
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001734
Kristof Umann1a170322019-02-05 00:39:33 +00001735 // C++
1736 void test() {
1737 int a = 2;
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001738
Kristof Umann1a170322019-02-05 00:39:33 +00001739 while (a > 1)
1740 a--;
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001741
Kristof Umann1a170322019-02-05 00:39:33 +00001742 if (a > 1)
1743 a++; // warn
1744 }
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001745
Kristof Umann1a170322019-02-05 00:39:33 +00001746 // Objective-C
1747 void test(id x) {
1748 return;
1749 [x retain]; // warn
1750 }
1751
1752alpha.llvm
1753^^^^^^^^^^
1754
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +00001755.. _alpha-llvm-Conventions:
1756
Kristof Umann1a170322019-02-05 00:39:33 +00001757alpha.llvm.Conventions
1758""""""""""""""""""""""
1759
1760Check code for LLVM codebase conventions:
1761
1762* A StringRef should not be bound to a temporary std::string whose lifetime is shorter than the StringRef's.
1763* Clang AST nodes should not have fields that can allocate memory.
1764
1765
1766alpha.osx
1767^^^^^^^^^
1768
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +00001769.. _alpha-osx-cocoa-DirectIvarAssignment:
1770
Kristof Umann1a170322019-02-05 00:39:33 +00001771alpha.osx.cocoa.DirectIvarAssignment (ObjC)
1772"""""""""""""""""""""""""""""""""""""""""""
1773Check for direct assignments to instance variables.
1774
1775
1776.. code-block:: objc
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001777
Kristof Umann1a170322019-02-05 00:39:33 +00001778 @interface MyClass : NSObject {}
1779 @property (readonly) id A;
1780 - (void) foo;
1781 @end
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001782
Kristof Umann1a170322019-02-05 00:39:33 +00001783 @implementation MyClass
1784 - (void) foo {
1785 _A = 0; // warn
1786 }
1787 @end
1788
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +00001789.. _alpha-osx-cocoa-DirectIvarAssignmentForAnnotatedFunctions:
1790
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001791alpha.osx.cocoa.DirectIvarAssignmentForAnnotatedFunctions (ObjC)
Kristof Umann1a170322019-02-05 00:39:33 +00001792""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001793Check for direct assignments to instance variables in
Kristof Umann1a170322019-02-05 00:39:33 +00001794the methods annotated with ``objc_no_direct_instance_variable_assignment``.
1795
1796.. code-block:: objc
1797
1798 @interface MyClass : NSObject {}
1799 @property (readonly) id A;
1800 - (void) fAnnotated __attribute__((
1801 annotate("objc_no_direct_instance_variable_assignment")));
1802 - (void) fNotAnnotated;
1803 @end
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001804
Kristof Umann1a170322019-02-05 00:39:33 +00001805 @implementation MyClass
1806 - (void) fAnnotated {
1807 _A = 0; // warn
1808 }
1809 - (void) fNotAnnotated {
1810 _A = 0; // no warn
1811 }
1812 @end
1813
1814
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +00001815.. _alpha-osx-cocoa-InstanceVariableInvalidation:
1816
Kristof Umann1a170322019-02-05 00:39:33 +00001817alpha.osx.cocoa.InstanceVariableInvalidation (ObjC)
1818"""""""""""""""""""""""""""""""""""""""""""""""""""
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001819Check that the invalidatable instance variables are
Kristof Umann1a170322019-02-05 00:39:33 +00001820invalidated in the methods annotated with objc_instance_variable_invalidator.
1821
1822.. code-block:: objc
1823
1824 @protocol Invalidation <NSObject>
1825 - (void) invalidate
1826 __attribute__((annotate("objc_instance_variable_invalidator")));
1827 @end
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001828
Kristof Umann1a170322019-02-05 00:39:33 +00001829 @interface InvalidationImpObj : NSObject <Invalidation>
1830 @end
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001831
Kristof Umann1a170322019-02-05 00:39:33 +00001832 @interface SubclassInvalidationImpObj : InvalidationImpObj {
1833 InvalidationImpObj *var;
1834 }
1835 - (void)invalidate;
1836 @end
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001837
Kristof Umann1a170322019-02-05 00:39:33 +00001838 @implementation SubclassInvalidationImpObj
1839 - (void) invalidate {}
1840 @end
1841 // warn: var needs to be invalidated or set to nil
1842
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +00001843.. _alpha-osx-cocoa-MissingInvalidationMethod:
1844
Kristof Umann1a170322019-02-05 00:39:33 +00001845alpha.osx.cocoa.MissingInvalidationMethod (ObjC)
1846""""""""""""""""""""""""""""""""""""""""""""""""
1847Check that the invalidation methods are present in classes that contain invalidatable instance variables.
1848
1849.. code-block:: objc
1850
1851 @protocol Invalidation <NSObject>
1852 - (void)invalidate
1853 __attribute__((annotate("objc_instance_variable_invalidator")));
1854 @end
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001855
Kristof Umann1a170322019-02-05 00:39:33 +00001856 @interface NeedInvalidation : NSObject <Invalidation>
1857 @end
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001858
Kristof Umann1a170322019-02-05 00:39:33 +00001859 @interface MissingInvalidationMethodDecl : NSObject {
1860 NeedInvalidation *Var; // warn
1861 }
1862 @end
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001863
Kristof Umann1a170322019-02-05 00:39:33 +00001864 @implementation MissingInvalidationMethodDecl
1865 @end
1866
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +00001867.. _alpha-osx-cocoa-localizability-PluralMisuseChecker:
1868
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001869alpha.osx.cocoa.localizability.PluralMisuseChecker (ObjC)
Kristof Umann1a170322019-02-05 00:39:33 +00001870"""""""""""""""""""""""""""""""""""""""""""""""""""""""""
1871Warns against using one vs. many plural pattern in code when generating localized strings.
1872
1873.. code-block:: objc
1874
1875 NSString *reminderText =
1876 NSLocalizedString(@"None", @"Indicates no reminders");
1877 if (reminderCount == 1) {
1878 // Warning: Plural cases are not supported across all languages.
1879 // Use a .stringsdict file instead
1880 reminderText =
1881 NSLocalizedString(@"1 Reminder", @"Indicates single reminder");
1882 } else if (reminderCount >= 2) {
1883 // Warning: Plural cases are not supported across all languages.
1884 // Use a .stringsdict file instead
1885 reminderText =
1886 [NSString stringWithFormat:
1887 NSLocalizedString(@"%@ Reminders", @"Indicates multiple reminders"),
1888 reminderCount];
1889 }
1890
1891alpha.security
1892^^^^^^^^^^^^^^
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +00001893.. _alpha-security-ArrayBound:
1894
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001895alpha.security.ArrayBound (C)
Kristof Umann1a170322019-02-05 00:39:33 +00001896"""""""""""""""""""""""""""""
1897Warn about buffer overflows (older checker).
1898
1899.. code-block:: c
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001900
Kristof Umann1a170322019-02-05 00:39:33 +00001901 void test() {
1902 char *s = "";
1903 char c = s[1]; // warn
1904 }
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001905
Kristof Umann1a170322019-02-05 00:39:33 +00001906 struct seven_words {
1907 int c[7];
1908 };
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001909
Kristof Umann1a170322019-02-05 00:39:33 +00001910 void test() {
1911 struct seven_words a, *p;
1912 p = &a;
1913 p[0] = a;
1914 p[1] = a;
1915 p[2] = a; // warn
1916 }
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001917
Kristof Umann1a170322019-02-05 00:39:33 +00001918 // note: requires unix.Malloc or
1919 // alpha.unix.MallocWithAnnotations checks enabled.
1920 void test() {
1921 int *p = malloc(12);
1922 p[3] = 4; // warn
1923 }
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001924
Kristof Umann1a170322019-02-05 00:39:33 +00001925 void test() {
1926 char a[2];
1927 int *b = (int*)a;
1928 b[1] = 3; // warn
1929 }
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001930
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +00001931.. _alpha-security-ArrayBoundV2:
1932
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001933alpha.security.ArrayBoundV2 (C)
Kristof Umann1a170322019-02-05 00:39:33 +00001934"""""""""""""""""""""""""""""""
1935Warn about buffer overflows (newer checker).
1936
1937.. code-block:: c
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001938
Kristof Umann1a170322019-02-05 00:39:33 +00001939 void test() {
1940 char *s = "";
1941 char c = s[1]; // warn
1942 }
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001943
Kristof Umann1a170322019-02-05 00:39:33 +00001944 void test() {
1945 int buf[100];
1946 int *p = buf;
1947 p = p + 99;
1948 p[1] = 1; // warn
1949 }
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001950
Kristof Umann1a170322019-02-05 00:39:33 +00001951 // note: compiler has internal check for this.
1952 // Use -Wno-array-bounds to suppress compiler warning.
1953 void test() {
1954 int buf[100][100];
1955 buf[0][-1] = 1; // warn
1956 }
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001957
Kristof Umann1a170322019-02-05 00:39:33 +00001958 // note: requires alpha.security.taint check turned on.
1959 void test() {
1960 char s[] = "abc";
1961 int x = getchar();
1962 char c = s[x]; // warn: index is tainted
1963 }
1964
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +00001965.. _alpha-security-MallocOverflow:
1966
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001967alpha.security.MallocOverflow (C)
Kristof Umann1a170322019-02-05 00:39:33 +00001968"""""""""""""""""""""""""""""""""
1969Check for overflows in the arguments to malloc().
1970
1971.. code-block:: c
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001972
Kristof Umann1a170322019-02-05 00:39:33 +00001973 void test(int n) {
1974 void *p = malloc(n * sizeof(int)); // warn
1975 }
1976
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +00001977.. _alpha-security-MmapWriteExec:
1978
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001979alpha.security.MmapWriteExec (C)
Kristof Umann1a170322019-02-05 00:39:33 +00001980""""""""""""""""""""""""""""""""
1981Warn on mmap() calls that are both writable and executable.
1982
1983.. code-block:: c
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001984
Kristof Umann1a170322019-02-05 00:39:33 +00001985 void test(int n) {
1986 void *c = mmap(NULL, 32, PROT_READ | PROT_WRITE | PROT_EXEC,
1987 MAP_PRIVATE | MAP_ANON, -1, 0);
1988 // warn: Both PROT_WRITE and PROT_EXEC flags are set. This can lead to
1989 // exploitable memory regions, which could be overwritten with malicious
1990 // code
1991 }
1992
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +00001993.. _alpha-security-ReturnPtrRange:
1994
Kristof Umann1a170322019-02-05 00:39:33 +00001995alpha.security.ReturnPtrRange (C)
1996"""""""""""""""""""""""""""""""""
1997Check for an out-of-bound pointer being returned to callers.
1998
1999.. code-block:: c
2000
2001 static int A[10];
Alexander Kornienko9a857d22019-02-11 15:17:13 +00002002
Kristof Umann1a170322019-02-05 00:39:33 +00002003 int *test() {
2004 int *p = A + 10;
2005 return p; // warn
2006 }
Alexander Kornienko9a857d22019-02-11 15:17:13 +00002007
Kristof Umann1a170322019-02-05 00:39:33 +00002008 int test(void) {
2009 int x;
2010 return x; // warn: undefined or garbage returned
2011 }
2012
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +00002013.. _alpha-security-taint-TaintPropagation:
2014
Kristof Umann1a170322019-02-05 00:39:33 +00002015alpha.security.taint.TaintPropagation (C, C++)
Alexander Kornienko9a857d22019-02-11 15:17:13 +00002016""""""""""""""""""""""""""""""""""""""""""""""
2017Generate taint information used by other checkers.
Kristof Umann1a170322019-02-05 00:39:33 +00002018A data is tainted when it comes from an unreliable source.
2019
2020.. code-block:: c
Alexander Kornienko9a857d22019-02-11 15:17:13 +00002021
Kristof Umann1a170322019-02-05 00:39:33 +00002022 void test() {
2023 char x = getchar(); // 'x' marked as tainted
2024 system(&x); // warn: untrusted data is passed to a system call
2025 }
Alexander Kornienko9a857d22019-02-11 15:17:13 +00002026
Kristof Umann1a170322019-02-05 00:39:33 +00002027 // note: compiler internally checks if the second param to
2028 // sprintf is a string literal or not.
2029 // Use -Wno-format-security to suppress compiler warning.
2030 void test() {
2031 char s[10], buf[10];
2032 fscanf(stdin, "%s", s); // 's' marked as tainted
Alexander Kornienko9a857d22019-02-11 15:17:13 +00002033
Kristof Umann1a170322019-02-05 00:39:33 +00002034 sprintf(buf, s); // warn: untrusted data as a format string
2035 }
Alexander Kornienko9a857d22019-02-11 15:17:13 +00002036
Kristof Umann1a170322019-02-05 00:39:33 +00002037 void test() {
2038 size_t ts;
2039 scanf("%zd", &ts); // 'ts' marked as tainted
2040 int *p = (int *)malloc(ts * sizeof(int));
2041 // warn: untrusted data as buffer size
2042 }
2043
2044alpha.unix
2045^^^^^^^^^^^
2046
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +00002047.. _alpha-unix-BlockInCriticalSection:
2048
Alexander Kornienko9a857d22019-02-11 15:17:13 +00002049alpha.unix.BlockInCriticalSection (C)
Kristof Umann1a170322019-02-05 00:39:33 +00002050"""""""""""""""""""""""""""""""""""""
Alexander Kornienko9a857d22019-02-11 15:17:13 +00002051Check for calls to blocking functions inside a critical section.
Kristof Umann1a170322019-02-05 00:39:33 +00002052Applies to: ``lock, unlock, sleep, getc, fgets, read, recv, pthread_mutex_lock,``
2053`` pthread_mutex_unlock, mtx_lock, mtx_timedlock, mtx_trylock, mtx_unlock, lock_guard, unique_lock``
2054
2055.. code-block:: c
Alexander Kornienko9a857d22019-02-11 15:17:13 +00002056
Kristof Umann1a170322019-02-05 00:39:33 +00002057 void test() {
2058 std::mutex m;
2059 m.lock();
2060 sleep(3); // warn: a blocking function sleep is called inside a critical
2061 // section
2062 m.unlock();
2063 }
2064
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +00002065.. _alpha-unix-Chroot:
2066
Kristof Umann1a170322019-02-05 00:39:33 +00002067alpha.unix.Chroot (C)
2068"""""""""""""""""""""
2069Check improper use of chroot.
2070
2071.. code-block:: c
2072
2073 void f();
Alexander Kornienko9a857d22019-02-11 15:17:13 +00002074
Kristof Umann1a170322019-02-05 00:39:33 +00002075 void test() {
2076 chroot("/usr/local");
2077 f(); // warn: no call of chdir("/") immediately after chroot
2078 }
2079
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +00002080.. _alpha-unix-PthreadLock:
2081
Alexander Kornienko9a857d22019-02-11 15:17:13 +00002082alpha.unix.PthreadLock (C)
Kristof Umann1a170322019-02-05 00:39:33 +00002083""""""""""""""""""""""""""
2084Simple lock -> unlock checker.
2085Applies to: ``pthread_mutex_lock, pthread_rwlock_rdlock, pthread_rwlock_wrlock, lck_mtx_lock, lck_rw_lock_exclusive``
Alexander Kornienko9a857d22019-02-11 15:17:13 +00002086``lck_rw_lock_shared, pthread_mutex_trylock, pthread_rwlock_tryrdlock, pthread_rwlock_tryrwlock, lck_mtx_try_lock,
Kristof Umann1a170322019-02-05 00:39:33 +00002087lck_rw_try_lock_exclusive, lck_rw_try_lock_shared, pthread_mutex_unlock, pthread_rwlock_unlock, lck_mtx_unlock, lck_rw_done``.
2088
2089
2090.. code-block:: c
Alexander Kornienko9a857d22019-02-11 15:17:13 +00002091
Kristof Umann1a170322019-02-05 00:39:33 +00002092 pthread_mutex_t mtx;
Alexander Kornienko9a857d22019-02-11 15:17:13 +00002093
Kristof Umann1a170322019-02-05 00:39:33 +00002094 void test() {
2095 pthread_mutex_lock(&mtx);
2096 pthread_mutex_lock(&mtx);
2097 // warn: this lock has already been acquired
2098 }
Alexander Kornienko9a857d22019-02-11 15:17:13 +00002099
Kristof Umann1a170322019-02-05 00:39:33 +00002100 lck_mtx_t lck1, lck2;
Alexander Kornienko9a857d22019-02-11 15:17:13 +00002101
Kristof Umann1a170322019-02-05 00:39:33 +00002102 void test() {
2103 lck_mtx_lock(&lck1);
2104 lck_mtx_lock(&lck2);
2105 lck_mtx_unlock(&lck1);
2106 // warn: this was not the most recently acquired lock
2107 }
Alexander Kornienko9a857d22019-02-11 15:17:13 +00002108
Kristof Umann1a170322019-02-05 00:39:33 +00002109 lck_mtx_t lck1, lck2;
Alexander Kornienko9a857d22019-02-11 15:17:13 +00002110
Kristof Umann1a170322019-02-05 00:39:33 +00002111 void test() {
2112 if (lck_mtx_try_lock(&lck1) == 0)
2113 return;
Alexander Kornienko9a857d22019-02-11 15:17:13 +00002114
Kristof Umann1a170322019-02-05 00:39:33 +00002115 lck_mtx_lock(&lck2);
2116 lck_mtx_unlock(&lck1);
2117 // warn: this was not the most recently acquired lock
2118 }
2119
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +00002120.. _alpha-unix-SimpleStream:
2121
Kristof Umann1a170322019-02-05 00:39:33 +00002122alpha.unix.SimpleStream (C)
2123"""""""""""""""""""""""""""
2124Check for misuses of stream APIs. Check for misuses of stream APIs: ``fopen, fclose``
Alexander Kornienko9a857d22019-02-11 15:17:13 +00002125(demo checker, the subject of the demo (`Slides <http://llvm.org/devmtg/2012-11/Zaks-Rose-Checker24Hours.pdf>`_ ,
2126`Video <https://youtu.be/kdxlsP5QVPw>`_) by Anna Zaks and Jordan Rose presented at the
Kristof Umann1a170322019-02-05 00:39:33 +00002127`2012 LLVM Developers' Meeting <http://llvm.org/devmtg/2012-11/>`_).
2128
2129.. code-block:: c
2130
2131 void test() {
2132 FILE *F = fopen("myfile.txt", "w");
2133 } // warn: opened file is never closed
Alexander Kornienko9a857d22019-02-11 15:17:13 +00002134
Kristof Umann1a170322019-02-05 00:39:33 +00002135 void test() {
2136 FILE *F = fopen("myfile.txt", "w");
Alexander Kornienko9a857d22019-02-11 15:17:13 +00002137
Kristof Umann1a170322019-02-05 00:39:33 +00002138 if (F)
2139 fclose(F);
Alexander Kornienko9a857d22019-02-11 15:17:13 +00002140
Kristof Umann1a170322019-02-05 00:39:33 +00002141 fclose(F); // warn: closing a previously closed file stream
2142 }
2143
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +00002144.. _alpha-unix-Stream:
2145
Kristof Umann1a170322019-02-05 00:39:33 +00002146alpha.unix.Stream (C)
2147"""""""""""""""""""""
2148Check stream handling functions: ``fopen, tmpfile, fclose, fread, fwrite, fseek, ftell, rewind, fgetpos,``
2149``fsetpos, clearerr, feof, ferror, fileno``.
2150
2151.. code-block:: c
2152
2153 void test() {
2154 FILE *p = fopen("foo", "r");
2155 } // warn: opened file is never closed
Alexander Kornienko9a857d22019-02-11 15:17:13 +00002156
Kristof Umann1a170322019-02-05 00:39:33 +00002157 void test() {
2158 FILE *p = fopen("foo", "r");
2159 fseek(p, 1, SEEK_SET); // warn: stream pointer might be NULL
2160 fclose(p);
2161 }
Alexander Kornienko9a857d22019-02-11 15:17:13 +00002162
Kristof Umann1a170322019-02-05 00:39:33 +00002163 void test() {
2164 FILE *p = fopen("foo", "r");
Alexander Kornienko9a857d22019-02-11 15:17:13 +00002165
Kristof Umann1a170322019-02-05 00:39:33 +00002166 if (p)
2167 fseek(p, 1, 3);
2168 // warn: third arg should be SEEK_SET, SEEK_END, or SEEK_CUR
Alexander Kornienko9a857d22019-02-11 15:17:13 +00002169
Kristof Umann1a170322019-02-05 00:39:33 +00002170 fclose(p);
2171 }
Alexander Kornienko9a857d22019-02-11 15:17:13 +00002172
Kristof Umann1a170322019-02-05 00:39:33 +00002173 void test() {
2174 FILE *p = fopen("foo", "r");
2175 fclose(p);
2176 fclose(p); // warn: already closed
2177 }
Alexander Kornienko9a857d22019-02-11 15:17:13 +00002178
Kristof Umann1a170322019-02-05 00:39:33 +00002179 void test() {
2180 FILE *p = tmpfile();
2181 ftell(p); // warn: stream pointer might be NULL
2182 fclose(p);
2183 }
2184
2185
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +00002186.. _alpha-unix-cstring-BufferOverlap:
2187
Kristof Umann1a170322019-02-05 00:39:33 +00002188alpha.unix.cstring.BufferOverlap (C)
2189""""""""""""""""""""""""""""""""""""
2190Checks for overlap in two buffer arguments. Applies to: ``memcpy, mempcpy``.
2191
2192.. code-block:: c
2193
2194 void test() {
2195 int a[4] = {0};
2196 memcpy(a + 2, a + 1, 8); // warn
2197 }
2198
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +00002199.. _alpha-unix-cstring-NotNullTerminated:
2200
Kristof Umann1a170322019-02-05 00:39:33 +00002201alpha.unix.cstring.NotNullTerminated (C)
2202""""""""""""""""""""""""""""""""""""""""
2203Check for arguments which are not null-terminated strings; applies to: ``strlen, strnlen, strcpy, strncpy, strcat, strncat``.
2204
2205.. code-block:: c
Alexander Kornienko9a857d22019-02-11 15:17:13 +00002206
Kristof Umann1a170322019-02-05 00:39:33 +00002207 void test() {
2208 int y = strlen((char *)&test); // warn
2209 }
2210
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +00002211.. _alpha-unix-cstring-OutOfBounds:
2212
Kristof Umann1a170322019-02-05 00:39:33 +00002213alpha.unix.cstring.OutOfBounds (C)
2214""""""""""""""""""""""""""""""""""
2215Check for out-of-bounds access in string functions; applies to:`` strncopy, strncat``.
2216
2217
2218.. code-block:: c
Alexander Kornienko9a857d22019-02-11 15:17:13 +00002219
Kristof Umann1a170322019-02-05 00:39:33 +00002220 void test() {
2221 int y = strlen((char *)&test); // warn
2222 }
2223
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +00002224.. _alpha-nondeterminism-PointerIteration:
2225
Mandeep Singh Grang0cdc5dd2019-05-24 19:24:08 +00002226alpha.nondeterminism.PointerIteration (C++)
2227"""""""""""""""""""""""""""""""""""""""""""
2228Check for non-determinism caused by iterating unordered containers of pointers.
2229
2230.. code-block:: c
2231
2232 void test() {
2233 int a = 1, b = 2;
2234 std::unordered_set<int *> UnorderedPtrSet = {&a, &b};
2235
2236 for (auto i : UnorderedPtrSet) // warn
2237 f(i);
2238 }
2239
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +00002240.. _alpha-nondeterminism-PointerSorting:
2241
Mandeep Singh Grangc0773ab2019-03-08 20:13:53 +00002242alpha.nondeterminism.PointerSorting (C++)
Mandeep Singh Grangd4c4f742019-03-08 20:35:25 +00002243"""""""""""""""""""""""""""""""""""""""""
Mandeep Singh Grangc0773ab2019-03-08 20:13:53 +00002244Check for non-determinism caused by sorting of pointers.
2245
2246.. code-block:: c
2247
2248 void test() {
2249 int a = 1, b = 2;
2250 std::vector<int *> V = {&a, &b};
2251 std::sort(V.begin(), V.end()); // warn
2252 }
2253
Kristof Umann1a170322019-02-05 00:39:33 +00002254
2255Debug Checkers
2256---------------
2257
2258.. _debug-checkers:
2259
2260
2261debug
2262^^^^^
2263
2264Checkers used for debugging the analyzer.
Kristof Umanndccfaff2019-02-05 10:19:39 +00002265:doc:`developer-docs/DebugChecks` page contains a detailed description.
Kristof Umann1a170322019-02-05 00:39:33 +00002266
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +00002267.. _debug-AnalysisOrder:
2268
Kristof Umann1a170322019-02-05 00:39:33 +00002269debug.AnalysisOrder
2270"""""""""""""""""""
2271Print callbacks that are called during analysis in order.
2272
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +00002273.. _debug-ConfigDumper:
2274
Kristof Umann1a170322019-02-05 00:39:33 +00002275debug.ConfigDumper
2276""""""""""""""""""
2277Dump config table.
2278
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +00002279.. _debug-DumpCFG Display:
2280
Kristof Umann1a170322019-02-05 00:39:33 +00002281debug.DumpCFG Display
2282"""""""""""""""""""""
2283Control-Flow Graphs.
2284
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +00002285.. _debug-DumpCallGraph:
2286
Kristof Umann1a170322019-02-05 00:39:33 +00002287debug.DumpCallGraph
2288"""""""""""""""""""
2289Display Call Graph.
2290
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +00002291.. _debug-DumpCalls:
2292
Kristof Umann1a170322019-02-05 00:39:33 +00002293debug.DumpCalls
2294"""""""""""""""
2295Print calls as they are traversed by the engine.
2296
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +00002297.. _debug-DumpDominators:
2298
Kristof Umann1a170322019-02-05 00:39:33 +00002299debug.DumpDominators
2300""""""""""""""""""""
2301Print the dominance tree for a given CFG.
2302
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +00002303.. _debug-DumpLiveVars:
2304
Kristof Umann1a170322019-02-05 00:39:33 +00002305debug.DumpLiveVars
2306""""""""""""""""""
2307Print results of live variable analysis.
2308
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +00002309.. _debug-DumpTraversal:
2310
Kristof Umann1a170322019-02-05 00:39:33 +00002311debug.DumpTraversal
2312"""""""""""""""""""
2313Print branch conditions as they are traversed by the engine.
2314
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +00002315.. _debug-ExprInspection:
2316
Kristof Umann1a170322019-02-05 00:39:33 +00002317debug.ExprInspection
2318""""""""""""""""""""
2319Check the analyzer's understanding of expressions.
2320
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +00002321.. _debug-Stats:
2322
Kristof Umann1a170322019-02-05 00:39:33 +00002323debug.Stats
2324"""""""""""
2325Emit warnings with analyzer statistics.
2326
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +00002327.. _debug-TaintTest:
2328
Kristof Umann1a170322019-02-05 00:39:33 +00002329debug.TaintTest
2330"""""""""""""""
2331Mark tainted symbols as such.
2332
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +00002333.. _debug-ViewCFG:
2334
Kristof Umann1a170322019-02-05 00:39:33 +00002335debug.ViewCFG
2336"""""""""""""
2337View Control-Flow Graphs using GraphViz.
2338
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +00002339.. _debug-ViewCallGraph:
2340
Kristof Umann1a170322019-02-05 00:39:33 +00002341debug.ViewCallGraph
2342"""""""""""""""""""
2343View Call Graph using GraphViz.
2344
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +00002345.. _debug-ViewExplodedGraph:
2346
Kristof Umann1a170322019-02-05 00:39:33 +00002347debug.ViewExplodedGraph
2348"""""""""""""""""""""""
2349View Exploded Graphs using GraphViz.
2350