blob: f50fff918cda7aed4d4f136c9ab074ae99176a8f [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
322.. _nullability-checkers:
323
324nullability
325^^^^^^^^^^^
326
327Objective C checkers that warn for null pointer passing and dereferencing errors.
328
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +0000329.. _nullability-NullPassedToNonnull:
330
Kristof Umann1a170322019-02-05 00:39:33 +0000331nullability.NullPassedToNonnull (ObjC)
332""""""""""""""""""""""""""""""""""""""
333Warns when a null pointer is passed to a pointer which has a _Nonnull type.
334
335.. code-block:: objc
336
337 if (name != nil)
338 return;
339 // Warning: nil passed to a callee that requires a non-null 1st parameter
340 NSString *greeting = [@"Hello " stringByAppendingString:name];
341
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +0000342.. _nullability-NullReturnedFromNonnull:
343
Alexander Kornienko9a857d22019-02-11 15:17:13 +0000344nullability.NullReturnedFromNonnull (ObjC)
Kristof Umann1a170322019-02-05 00:39:33 +0000345""""""""""""""""""""""""""""""""""""""""""
346Warns when a null pointer is returned from a function that has _Nonnull return type.
347
348.. code-block:: objc
349
350 - (nonnull id)firstChild {
351 id result = nil;
352 if ([_children count] > 0)
353 result = _children[0];
Alexander Kornienko9a857d22019-02-11 15:17:13 +0000354
Kristof Umann1a170322019-02-05 00:39:33 +0000355 // Warning: nil returned from a method that is expected
356 // to return a non-null value
357 return result;
358 }
359
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +0000360.. _nullability-NullableDereferenced:
361
Kristof Umann1a170322019-02-05 00:39:33 +0000362nullability.NullableDereferenced (ObjC)
363"""""""""""""""""""""""""""""""""""""""
364Warns when a nullable pointer is dereferenced.
365
366.. code-block:: objc
Alexander Kornienko9a857d22019-02-11 15:17:13 +0000367
Kristof Umann1a170322019-02-05 00:39:33 +0000368 struct LinkedList {
369 int data;
370 struct LinkedList *next;
371 };
Alexander Kornienko9a857d22019-02-11 15:17:13 +0000372
Kristof Umann1a170322019-02-05 00:39:33 +0000373 struct LinkedList * _Nullable getNext(struct LinkedList *l);
Alexander Kornienko9a857d22019-02-11 15:17:13 +0000374
Kristof Umann1a170322019-02-05 00:39:33 +0000375 void updateNextData(struct LinkedList *list, int newData) {
376 struct LinkedList *next = getNext(list);
377 // Warning: Nullable pointer is dereferenced
378 next->data = 7;
379 }
380
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +0000381.. _nullability-NullablePassedToNonnull:
382
Kristof Umann1a170322019-02-05 00:39:33 +0000383nullability.NullablePassedToNonnull (ObjC)
384""""""""""""""""""""""""""""""""""""""""""
385Warns when a nullable pointer is passed to a pointer which has a _Nonnull type.
386
387.. code-block:: objc
Alexander Kornienko9a857d22019-02-11 15:17:13 +0000388
Kristof Umann1a170322019-02-05 00:39:33 +0000389 typedef struct Dummy { int val; } Dummy;
390 Dummy *_Nullable returnsNullable();
391 void takesNonnull(Dummy *_Nonnull);
Alexander Kornienko9a857d22019-02-11 15:17:13 +0000392
Kristof Umann1a170322019-02-05 00:39:33 +0000393 void test() {
394 Dummy *p = returnsNullable();
395 takesNonnull(p); // warn
396 }
397
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +0000398.. _nullability-NullableReturnedFromNonnull:
399
Alexander Kornienko9a857d22019-02-11 15:17:13 +0000400nullability.NullableReturnedFromNonnull (ObjC)
Kristof Umann1a170322019-02-05 00:39:33 +0000401""""""""""""""""""""""""""""""""""""""""""""""
402Warns when a nullable pointer is returned from a function that has _Nonnull return type.
403
404.. _optin-checkers:
405
406optin
407^^^^^
408
409Checkers for portability, performance or coding style specific rules.
410
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +0000411.. _optin-cplusplus-UninitializedObject:
412
Kristof Umann85e0ff72019-04-19 23:33:50 +0000413optin.cplusplus.UninitializedObject (C++)
Nico Weber83c95b12019-05-03 18:54:18 +0000414"""""""""""""""""""""""""""""""""""""""""
Kristof Umann85e0ff72019-04-19 23:33:50 +0000415
416This checker reports uninitialized fields in objects created after a constructor
417call. It doesn't only find direct uninitialized fields, but rather makes a deep
418inspection of the object, analyzing all of it's fields subfields.
419The checker regards inherited fields as direct fields, so one will recieve
420warnings for uninitialized inherited data members as well.
421
422.. code-block:: cpp
423
424 // With Pedantic and CheckPointeeInitialization set to true
425
426 struct A {
427 struct B {
428 int x; // note: uninitialized field 'this->b.x'
429 // note: uninitialized field 'this->bptr->x'
430 int y; // note: uninitialized field 'this->b.y'
431 // note: uninitialized field 'this->bptr->y'
432 };
433 int *iptr; // note: uninitialized pointer 'this->iptr'
434 B b;
435 B *bptr;
436 char *cptr; // note: uninitialized pointee 'this->cptr'
437
438 A (B *bptr, char *cptr) : bptr(bptr), cptr(cptr) {}
439 };
440
441 void f() {
442 A::B b;
443 char c;
444 A a(&b, &c); // warning: 6 uninitialized fields
445 // after the constructor call
446 }
447
448 // With Pedantic set to false and
449 // CheckPointeeInitialization set to true
450 // (every field is uninitialized)
451
452 struct A {
453 struct B {
454 int x;
455 int y;
456 };
457 int *iptr;
458 B b;
459 B *bptr;
460 char *cptr;
461
462 A (B *bptr, char *cptr) : bptr(bptr), cptr(cptr) {}
463 };
464
465 void f() {
466 A::B b;
467 char c;
468 A a(&b, &c); // no warning
469 }
470
471 // With Pedantic set to true and
472 // CheckPointeeInitialization set to false
473 // (pointees are regarded as initialized)
474
475 struct A {
476 struct B {
477 int x; // note: uninitialized field 'this->b.x'
478 int y; // note: uninitialized field 'this->b.y'
479 };
480 int *iptr; // note: uninitialized pointer 'this->iptr'
481 B b;
482 B *bptr;
483 char *cptr;
484
485 A (B *bptr, char *cptr) : bptr(bptr), cptr(cptr) {}
486 };
487
488 void f() {
489 A::B b;
490 char c;
491 A a(&b, &c); // warning: 3 uninitialized fields
492 // after the constructor call
493 }
494
495
496**Options**
497
498This checker has several options which can be set from command line (e.g.
499``-analyzer-config optin.cplusplus.UninitializedObject:Pedantic=true``):
500
501* ``Pedantic`` (boolean). If to false, the checker won't emit warnings for
502 objects that don't have at least one initialized field. Defaults to false.
503
504* ``NotesAsWarnings`` (boolean). If set to true, the checker will emit a
505 warning for each uninitalized field, as opposed to emitting one warning per
506 constructor call, and listing the uninitialized fields that belongs to it in
507 notes. *Defaults to false*.
508
509* ``CheckPointeeInitialization`` (boolean). If set to false, the checker will
510 not analyze the pointee of pointer/reference fields, and will only check
511 whether the object itself is initialized. *Defaults to false*.
512
513* ``IgnoreRecordsWithField`` (string). If supplied, the checker will not analyze
514 structures that have a field with a name or type name that matches the given
515 pattern. *Defaults to ""*.
516
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +0000517.. _optin-cplusplus-VirtualCall:
518
Kristof Umann1a170322019-02-05 00:39:33 +0000519optin.cplusplus.VirtualCall (C++)
520"""""""""""""""""""""""""""""""""
521Check virtual function calls during construction or destruction.
522
523.. code-block:: cpp
524
525 class A {
526 public:
527 A() {
528 f(); // warn
529 }
530 virtual void f();
531 };
Alexander Kornienko9a857d22019-02-11 15:17:13 +0000532
Kristof Umann1a170322019-02-05 00:39:33 +0000533 class A {
534 public:
535 ~A() {
536 this->f(); // warn
537 }
538 virtual void f();
539 };
540
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +0000541.. _optin-mpi-MPI-Checker:
542
Kristof Umann1a170322019-02-05 00:39:33 +0000543optin.mpi.MPI-Checker (C)
544"""""""""""""""""""""""""
545Checks MPI code.
546
547.. code-block:: c
548
549 void test() {
550 double buf = 0;
551 MPI_Request sendReq1;
552 MPI_Ireduce(MPI_IN_PLACE, &buf, 1, MPI_DOUBLE, MPI_SUM,
553 0, MPI_COMM_WORLD, &sendReq1);
554 } // warn: request 'sendReq1' has no matching wait.
Alexander Kornienko9a857d22019-02-11 15:17:13 +0000555
Kristof Umann1a170322019-02-05 00:39:33 +0000556 void test() {
557 double buf = 0;
558 MPI_Request sendReq;
559 MPI_Isend(&buf, 1, MPI_DOUBLE, 0, 0, MPI_COMM_WORLD, &sendReq);
560 MPI_Irecv(&buf, 1, MPI_DOUBLE, 0, 0, MPI_COMM_WORLD, &sendReq); // warn
561 MPI_Isend(&buf, 1, MPI_DOUBLE, 0, 0, MPI_COMM_WORLD, &sendReq); // warn
562 MPI_Wait(&sendReq, MPI_STATUS_IGNORE);
563 }
Alexander Kornienko9a857d22019-02-11 15:17:13 +0000564
Kristof Umann1a170322019-02-05 00:39:33 +0000565 void missingNonBlocking() {
566 int rank = 0;
567 MPI_Comm_rank(MPI_COMM_WORLD, &rank);
568 MPI_Request sendReq1[10][10][10];
569 MPI_Wait(&sendReq1[1][7][9], MPI_STATUS_IGNORE); // warn
570 }
571
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +0000572.. _optin-osx-cocoa-localizability-EmptyLocalizationContextChecker:
573
Kristof Umann1a170322019-02-05 00:39:33 +0000574optin.osx.cocoa.localizability.EmptyLocalizationContextChecker (ObjC)
575"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
576Check that NSLocalizedString macros include a comment for context.
577
578.. code-block:: objc
579
580 - (void)test {
581 NSString *string = NSLocalizedString(@"LocalizedString", nil); // warn
582 NSString *string2 = NSLocalizedString(@"LocalizedString", @" "); // warn
583 NSString *string3 = NSLocalizedStringWithDefaultValue(
584 @"LocalizedString", nil, [[NSBundle alloc] init], nil,@""); // warn
585 }
586
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +0000587.. _optin-osx-cocoa-localizability-NonLocalizedStringChecker:
588
Alexander Kornienko9a857d22019-02-11 15:17:13 +0000589optin.osx.cocoa.localizability.NonLocalizedStringChecker (ObjC)
Kristof Umann1a170322019-02-05 00:39:33 +0000590"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
591Warns about uses of non-localized NSStrings passed to UI methods expecting localized NSStrings.
592
593.. code-block:: objc
Alexander Kornienko9a857d22019-02-11 15:17:13 +0000594
Kristof Umann1a170322019-02-05 00:39:33 +0000595 NSString *alarmText =
596 NSLocalizedString(@"Enabled", @"Indicates alarm is turned on");
597 if (!isEnabled) {
598 alarmText = @"Disabled";
599 }
600 UILabel *alarmStateLabel = [[UILabel alloc] init];
Alexander Kornienko9a857d22019-02-11 15:17:13 +0000601
Kristof Umann1a170322019-02-05 00:39:33 +0000602 // Warning: User-facing text should use localized string macro
603 [alarmStateLabel setText:alarmText];
604
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +0000605.. _optin-performance-GCDAntipattern:
606
Kristof Umann1a170322019-02-05 00:39:33 +0000607optin.performance.GCDAntipattern
608""""""""""""""""""""""""""""""""
609Check for performance anti-patterns when using Grand Central Dispatch.
610
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +0000611.. _optin-performance-Padding:
612
Kristof Umann1a170322019-02-05 00:39:33 +0000613optin.performance.Padding
614"""""""""""""""""""""""""
615Check for excessively padded structs.
616
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +0000617.. _optin-portability-UnixAPI:
618
Kristof Umann1a170322019-02-05 00:39:33 +0000619optin.portability.UnixAPI
620"""""""""""""""""""""""""
621Finds implementation-defined behavior in UNIX/Posix functions.
622
623
624.. _security-checkers:
625
626security
627^^^^^^^^
628
629Security related checkers.
630
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +0000631.. _security-FloatLoopCounter:
632
Alexander Kornienko9a857d22019-02-11 15:17:13 +0000633security.FloatLoopCounter (C)
Kristof Umann1a170322019-02-05 00:39:33 +0000634"""""""""""""""""""""""""""""
635Warn on using a floating point value as a loop counter (CERT: FLP30-C, FLP30-CPP).
636
637.. code-block:: c
Alexander Kornienko9a857d22019-02-11 15:17:13 +0000638
Kristof Umann1a170322019-02-05 00:39:33 +0000639 void test() {
640 for (float x = 0.1f; x <= 1.0f; x += 0.1f) {} // warn
641 }
642
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +0000643.. _security-insecureAPI-UncheckedReturn:
644
Alexander Kornienko9a857d22019-02-11 15:17:13 +0000645security.insecureAPI.UncheckedReturn (C)
Kristof Umann1a170322019-02-05 00:39:33 +0000646""""""""""""""""""""""""""""""""""""""""
647Warn on uses of functions whose return values must be always checked.
648
649.. code-block:: c
Alexander Kornienko9a857d22019-02-11 15:17:13 +0000650
Kristof Umann1a170322019-02-05 00:39:33 +0000651 void test() {
652 setuid(1); // warn
653 }
654
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +0000655.. _security-insecureAPI-bcmp:
656
Kristof Umann1a170322019-02-05 00:39:33 +0000657security.insecureAPI.bcmp (C)
658"""""""""""""""""""""""""""""
659Warn on uses of the 'bcmp' function.
660
661.. code-block:: c
Alexander Kornienko9a857d22019-02-11 15:17:13 +0000662
Kristof Umann1a170322019-02-05 00:39:33 +0000663 void test() {
664 bcmp(ptr0, ptr1, n); // warn
665 }
666
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +0000667.. _security-insecureAPI-bcopy:
668
Kristof Umann1a170322019-02-05 00:39:33 +0000669security.insecureAPI.bcopy (C)
670""""""""""""""""""""""""""""""
671Warn on uses of the 'bcopy' function.
672
673.. code-block:: c
674
675 void test() {
676 bcopy(src, dst, n); // warn
677 }
678
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +0000679.. _security-insecureAPI-bzero:
680
Kristof Umann1a170322019-02-05 00:39:33 +0000681security.insecureAPI.bzero (C)
682""""""""""""""""""""""""""""""
683Warn on uses of the 'bzero' function.
684
685.. code-block:: c
Alexander Kornienko9a857d22019-02-11 15:17:13 +0000686
Kristof Umann1a170322019-02-05 00:39:33 +0000687 void test() {
688 bzero(ptr, n); // warn
689 }
690
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +0000691.. _security-insecureAPI-getpw:
692
Alexander Kornienko9a857d22019-02-11 15:17:13 +0000693security.insecureAPI.getpw (C)
Kristof Umann1a170322019-02-05 00:39:33 +0000694""""""""""""""""""""""""""""""
695Warn on uses of the 'getpw' function.
696
697.. code-block:: c
Alexander Kornienko9a857d22019-02-11 15:17:13 +0000698
Kristof Umann1a170322019-02-05 00:39:33 +0000699 void test() {
700 char buff[1024];
701 getpw(2, buff); // warn
702 }
703
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +0000704.. _security-insecureAPI-gets:
705
Kristof Umann1a170322019-02-05 00:39:33 +0000706security.insecureAPI.gets (C)
707"""""""""""""""""""""""""""""
708Warn on uses of the 'gets' function.
709
710.. code-block:: c
Alexander Kornienko9a857d22019-02-11 15:17:13 +0000711
Kristof Umann1a170322019-02-05 00:39:33 +0000712 void test() {
713 char buff[1024];
714 gets(buff); // warn
715 }
716
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +0000717.. _security-insecureAPI-mkstemp:
718
Kristof Umann1a170322019-02-05 00:39:33 +0000719security.insecureAPI.mkstemp (C)
720""""""""""""""""""""""""""""""""
721Warn when 'mkstemp' is passed fewer than 6 X's in the format string.
722
723.. code-block:: c
724
725 void test() {
726 mkstemp("XX"); // warn
727 }
Alexander Kornienko9a857d22019-02-11 15:17:13 +0000728
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +0000729.. _security-insecureAPI-mktemp:
730
Alexander Kornienko9a857d22019-02-11 15:17:13 +0000731security.insecureAPI.mktemp (C)
Kristof Umann1a170322019-02-05 00:39:33 +0000732"""""""""""""""""""""""""""""""
733Warn on uses of the ``mktemp`` function.
734
735.. code-block:: c
Alexander Kornienko9a857d22019-02-11 15:17:13 +0000736
Kristof Umann1a170322019-02-05 00:39:33 +0000737 void test() {
738 char *x = mktemp("/tmp/zxcv"); // warn: insecure, use mkstemp
739 }
740
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +0000741.. _security-insecureAPI-rand:
742
Alexander Kornienko9a857d22019-02-11 15:17:13 +0000743security.insecureAPI.rand (C)
Kristof Umann1a170322019-02-05 00:39:33 +0000744"""""""""""""""""""""""""""""
Alexander Kornienko9a857d22019-02-11 15:17:13 +0000745Warn on uses of inferior random number generating functions (only if arc4random function is available):
Kristof Umann1a170322019-02-05 00:39:33 +0000746``drand48, erand48, jrand48, lcong48, lrand48, mrand48, nrand48, random, rand_r``.
747
748.. code-block:: c
Alexander Kornienko9a857d22019-02-11 15:17:13 +0000749
Kristof Umann1a170322019-02-05 00:39:33 +0000750 void test() {
751 random(); // warn
752 }
Alexander Kornienko9a857d22019-02-11 15:17:13 +0000753
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +0000754.. _security-insecureAPI-strcpy:
755
Kristof Umann1a170322019-02-05 00:39:33 +0000756security.insecureAPI.strcpy (C)
757"""""""""""""""""""""""""""""""
758Warn on uses of the ``strcpy`` and ``strcat`` functions.
759
760.. code-block:: c
Alexander Kornienko9a857d22019-02-11 15:17:13 +0000761
Kristof Umann1a170322019-02-05 00:39:33 +0000762 void test() {
763 char x[4];
764 char *y = "abcd";
Alexander Kornienko9a857d22019-02-11 15:17:13 +0000765
Kristof Umann1a170322019-02-05 00:39:33 +0000766 strcpy(x, y); // warn
767 }
768
769
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +0000770.. _security-insecureAPI-vfork:
771
Alexander Kornienko9a857d22019-02-11 15:17:13 +0000772security.insecureAPI.vfork (C)
Kristof Umann1a170322019-02-05 00:39:33 +0000773""""""""""""""""""""""""""""""
774 Warn on uses of the 'vfork' function.
775
776.. code-block:: c
Alexander Kornienko9a857d22019-02-11 15:17:13 +0000777
Kristof Umann1a170322019-02-05 00:39:33 +0000778 void test() {
779 vfork(); // warn
780 }
781
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +0000782.. _security-insecureAPI-DeprecatedOrUnsafeBufferHandling:
783
Alexander Kornienko9a857d22019-02-11 15:17:13 +0000784security.insecureAPI.DeprecatedOrUnsafeBufferHandling (C)
785"""""""""""""""""""""""""""""""""""""""""""""""""""""""""
Kristof Umann8d239992019-02-11 13:46:43 +0000786 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``
787
788.. code-block:: c
Alexander Kornienko9a857d22019-02-11 15:17:13 +0000789
Kristof Umann8d239992019-02-11 13:46:43 +0000790 void test() {
791 char buf [5];
792 strncpy(buf, "a", 1); // warn
793 }
794
Kristof Umann1a170322019-02-05 00:39:33 +0000795.. _unix-checkers:
796
797unix
798^^^^
799POSIX/Unix checkers.
800
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +0000801.. _unix-API:
802
Alexander Kornienko9a857d22019-02-11 15:17:13 +0000803unix.API (C)
Kristof Umann1a170322019-02-05 00:39:33 +0000804""""""""""""
805Check calls to various UNIX/Posix functions: ``open, pthread_once, calloc, malloc, realloc, alloca``.
806
Alexander Kornienko9a857d22019-02-11 15:17:13 +0000807.. literalinclude:: checkers/unix_api_example.c
Kristof Umann1a170322019-02-05 00:39:33 +0000808 :language: c
809
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +0000810.. _unix-Malloc:
811
Alexander Kornienko9a857d22019-02-11 15:17:13 +0000812unix.Malloc (C)
Kristof Umann1a170322019-02-05 00:39:33 +0000813"""""""""""""""
814Check for memory leaks, double free, and use-after-free problems. Traces memory managed by malloc()/free().
815
Alexander Kornienko9a857d22019-02-11 15:17:13 +0000816.. literalinclude:: checkers/unix_malloc_example.c
Kristof Umann1a170322019-02-05 00:39:33 +0000817 :language: c
Alexander Kornienko9a857d22019-02-11 15:17:13 +0000818
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +0000819.. _unix-MallocSizeof:
820
Alexander Kornienko9a857d22019-02-11 15:17:13 +0000821unix.MallocSizeof (C)
Kristof Umann1a170322019-02-05 00:39:33 +0000822"""""""""""""""""""""
823Check for dubious ``malloc`` arguments involving ``sizeof``.
824
825.. code-block:: c
Alexander Kornienko9a857d22019-02-11 15:17:13 +0000826
Kristof Umann1a170322019-02-05 00:39:33 +0000827 void test() {
828 long *p = malloc(sizeof(short));
829 // warn: result is converted to 'long *', which is
830 // incompatible with operand type 'short'
831 free(p);
832 }
833
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +0000834.. _unix-MismatchedDeallocator:
835
Kristof Umann1a170322019-02-05 00:39:33 +0000836unix.MismatchedDeallocator (C, C++)
837"""""""""""""""""""""""""""""""""""
838Check for mismatched deallocators.
839
Alexander Kornienko9a857d22019-02-11 15:17:13 +0000840.. literalinclude:: checkers/mismatched_deallocator_example.cpp
Kristof Umann1a170322019-02-05 00:39:33 +0000841 :language: c
842
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +0000843.. _unix-Vfork:
844
Alexander Kornienko9a857d22019-02-11 15:17:13 +0000845unix.Vfork (C)
Kristof Umann1a170322019-02-05 00:39:33 +0000846""""""""""""""
847Check for proper usage of ``vfork``.
848
849.. code-block:: c
Alexander Kornienko9a857d22019-02-11 15:17:13 +0000850
Kristof Umann1a170322019-02-05 00:39:33 +0000851 int test(int x) {
852 pid_t pid = vfork(); // warn
853 if (pid != 0)
854 return 0;
Alexander Kornienko9a857d22019-02-11 15:17:13 +0000855
Kristof Umann1a170322019-02-05 00:39:33 +0000856 switch (x) {
857 case 0:
858 pid = 1;
859 execl("", "", 0);
860 _exit(1);
861 break;
862 case 1:
863 x = 0; // warn: this assignment is prohibited
864 break;
865 case 2:
866 foo(); // warn: this function call is prohibited
867 break;
868 default:
869 return 0; // warn: return is prohibited
870 }
Alexander Kornienko9a857d22019-02-11 15:17:13 +0000871
Kristof Umann1a170322019-02-05 00:39:33 +0000872 while(1);
873 }
874
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +0000875.. _unix-cstring-BadSizeArg:
876
Alexander Kornienko9a857d22019-02-11 15:17:13 +0000877unix.cstring.BadSizeArg (C)
Kristof Umann1a170322019-02-05 00:39:33 +0000878"""""""""""""""""""""""""""
Alexander Kornienko9a857d22019-02-11 15:17:13 +0000879Check 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 +0000880
881.. code-block:: c
Alexander Kornienko9a857d22019-02-11 15:17:13 +0000882
Kristof Umann1a170322019-02-05 00:39:33 +0000883 void test() {
884 char dest[3];
885 strncat(dest, """""""""""""""""""""""""*", sizeof(dest));
886 // warn: potential buffer overflow
887 }
888
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +0000889.. _unix-cstrisng-NullArg:
890
Alexander Kornienko9a857d22019-02-11 15:17:13 +0000891unix.cstrisng.NullArg (C)
Kristof Umann1a170322019-02-05 00:39:33 +0000892"""""""""""""""""""""""""
Alexander Kornienko9a857d22019-02-11 15:17:13 +0000893Check for null pointers being passed as arguments to C string functions:
Kristof Umann1a170322019-02-05 00:39:33 +0000894``strlen, strnlen, strcpy, strncpy, strcat, strncat, strcmp, strncmp, strcasecmp, strncasecmp``.
895
896.. code-block:: c
897
898 int test() {
899 return strlen(0); // warn
900 }
901
902.. _osx-checkers:
903
904osx
905^^^
J. Ryan Stinnettd45eaf92019-05-30 16:46:22 +0000906macOS checkers.
Alexander Kornienko9a857d22019-02-11 15:17:13 +0000907
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +0000908.. _osx-API:
909
Alexander Kornienko9a857d22019-02-11 15:17:13 +0000910osx.API (C)
Kristof Umann1a170322019-02-05 00:39:33 +0000911"""""""""""
912Check for proper uses of various Apple APIs.
913
914.. code-block:: objc
915
916 void test() {
917 dispatch_once_t pred = 0;
918 dispatch_once(&pred, ^(){}); // warn: dispatch_once uses local
919 }
920
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +0000921.. _osx-NumberObjectConversion:
922
Kristof Umann1a170322019-02-05 00:39:33 +0000923osx.NumberObjectConversion (C, C++, ObjC)
924"""""""""""""""""""""""""""""""""""""""""
925Check for erroneous conversions of objects representing numbers into numbers.
926
927.. code-block:: objc
Alexander Kornienko9a857d22019-02-11 15:17:13 +0000928
Kristof Umann1a170322019-02-05 00:39:33 +0000929 NSNumber *photoCount = [albumDescriptor objectForKey:@"PhotoCount"];
930 // Warning: Comparing a pointer value of type 'NSNumber *'
931 // to a scalar integer value
932 if (photoCount > 0) {
933 [self displayPhotos];
934 }
935
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +0000936.. _osx-ObjCProperty:
937
Kristof Umann1a170322019-02-05 00:39:33 +0000938osx.ObjCProperty (ObjC)
939"""""""""""""""""""""""
940Check for proper uses of Objective-C properties.
941
942.. code-block:: objc
Alexander Kornienko9a857d22019-02-11 15:17:13 +0000943
Kristof Umann1a170322019-02-05 00:39:33 +0000944 NSNumber *photoCount = [albumDescriptor objectForKey:@"PhotoCount"];
945 // Warning: Comparing a pointer value of type 'NSNumber *'
946 // to a scalar integer value
947 if (photoCount > 0) {
948 [self displayPhotos];
949 }
950
951
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +0000952.. _osx-SecKeychainAPI:
953
Alexander Kornienko9a857d22019-02-11 15:17:13 +0000954osx.SecKeychainAPI (C)
Kristof Umann1a170322019-02-05 00:39:33 +0000955""""""""""""""""""""""
956Check for proper uses of Secure Keychain APIs.
957
Alexander Kornienko9a857d22019-02-11 15:17:13 +0000958.. literalinclude:: checkers/seckeychainapi_example.m
Kristof Umann1a170322019-02-05 00:39:33 +0000959 :language: objc
960
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +0000961.. _osx-cocoa-AtSync:
962
Kristof Umann1a170322019-02-05 00:39:33 +0000963osx.cocoa.AtSync (ObjC)
964"""""""""""""""""""""""
965Check for nil pointers used as mutexes for @synchronized.
966
967.. code-block:: objc
968
969 void test(id x) {
970 if (!x)
971 @synchronized(x) {} // warn: nil value used as mutex
972 }
Alexander Kornienko9a857d22019-02-11 15:17:13 +0000973
Kristof Umann1a170322019-02-05 00:39:33 +0000974 void test() {
975 id y;
976 @synchronized(y) {} // warn: uninitialized value used as mutex
977 }
978
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +0000979.. _osx-cocoa-AutoreleaseWrite:
980
Kristof Umann1a170322019-02-05 00:39:33 +0000981osx.cocoa.AutoreleaseWrite
Alexander Kornienko9a857d22019-02-11 15:17:13 +0000982""""""""""""""""""""""""""
Kristof Umann1a170322019-02-05 00:39:33 +0000983Warn about potentially crashing writes to autoreleasing objects from different autoreleasing pools in Objective-C.
984
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +0000985.. _osx-cocoa-ClassRelease:
986
Kristof Umann1a170322019-02-05 00:39:33 +0000987osx.cocoa.ClassRelease (ObjC)
988"""""""""""""""""""""""""""""
989Check for sending 'retain', 'release', or 'autorelease' directly to a Class.
990
991.. code-block:: objc
Alexander Kornienko9a857d22019-02-11 15:17:13 +0000992
Kristof Umann1a170322019-02-05 00:39:33 +0000993 @interface MyClass : NSObject
994 @end
Alexander Kornienko9a857d22019-02-11 15:17:13 +0000995
Kristof Umann1a170322019-02-05 00:39:33 +0000996 void test(void) {
997 [MyClass release]; // warn
998 }
999
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +00001000.. _osx-cocoa-Dealloc:
1001
Kristof Umann1a170322019-02-05 00:39:33 +00001002osx.cocoa.Dealloc (ObjC)
1003""""""""""""""""""""""""
1004Warn about Objective-C classes that lack a correct implementation of -dealloc
1005
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001006.. literalinclude:: checkers/dealloc_example.m
Kristof Umann1a170322019-02-05 00:39:33 +00001007 :language: objc
1008
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +00001009.. _osx-cocoa-IncompatibleMethodTypes:
1010
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001011osx.cocoa.IncompatibleMethodTypes (ObjC)
Kristof Umann1a170322019-02-05 00:39:33 +00001012""""""""""""""""""""""""""""""""""""""""
1013Warn about Objective-C method signatures with type incompatibilities.
1014
1015.. code-block:: objc
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001016
Kristof Umann1a170322019-02-05 00:39:33 +00001017 @interface MyClass1 : NSObject
1018 - (int)foo;
1019 @end
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001020
Kristof Umann1a170322019-02-05 00:39:33 +00001021 @implementation MyClass1
1022 - (int)foo { return 1; }
1023 @end
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001024
Kristof Umann1a170322019-02-05 00:39:33 +00001025 @interface MyClass2 : MyClass1
1026 - (float)foo;
1027 @end
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001028
Kristof Umann1a170322019-02-05 00:39:33 +00001029 @implementation MyClass2
1030 - (float)foo { return 1.0; } // warn
1031 @end
1032
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +00001033.. _osx-cocoa-Loops:
1034
Kristof Umann1a170322019-02-05 00:39:33 +00001035osx.cocoa.Loops
1036"""""""""""""""
1037Improved modeling of loops using Cocoa collection types.
1038
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +00001039.. _osx-cocoa-MissingSuperCall:
1040
Kristof Umann1a170322019-02-05 00:39:33 +00001041osx.cocoa.MissingSuperCall (ObjC)
1042"""""""""""""""""""""""""""""""""
1043Warn about Objective-C methods that lack a necessary call to super.
1044
1045.. code-block:: objc
1046
1047 @interface Test : UIViewController
1048 @end
1049 @implementation test
1050 - (void)viewDidLoad {} // warn
1051 @end
1052
1053
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +00001054.. _osx-cocoa-NSAutoreleasePool:
1055
Kristof Umann1a170322019-02-05 00:39:33 +00001056osx.cocoa.NSAutoreleasePool (ObjC)
1057""""""""""""""""""""""""""""""""""
1058Warn for suboptimal uses of NSAutoreleasePool in Objective-C GC mode.
1059
1060.. code-block:: objc
1061
1062 void test() {
1063 NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
1064 [pool release]; // warn
1065 }
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001066
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +00001067.. _osx-cocoa-NSError:
1068
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001069osx.cocoa.NSError (ObjC)
Kristof Umann1a170322019-02-05 00:39:33 +00001070""""""""""""""""""""""""
1071Check usage of NSError parameters.
1072
1073.. code-block:: objc
1074
1075 @interface A : NSObject
1076 - (void)foo:(NSError """""""""""""""""""""""")error;
1077 @end
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001078
Kristof Umann1a170322019-02-05 00:39:33 +00001079 @implementation A
1080 - (void)foo:(NSError """""""""""""""""""""""")error {
1081 // warn: method accepting NSError"""""""""""""""""""""""" should have a non-void
1082 // return value
1083 }
1084 @end
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001085
Kristof Umann1a170322019-02-05 00:39:33 +00001086 @interface A : NSObject
1087 - (BOOL)foo:(NSError """""""""""""""""""""""")error;
1088 @end
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001089
Kristof Umann1a170322019-02-05 00:39:33 +00001090 @implementation A
1091 - (BOOL)foo:(NSError """""""""""""""""""""""")error {
1092 *error = 0; // warn: potential null dereference
1093 return 0;
1094 }
1095 @end
1096
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +00001097.. _osx-cocoa-NilArg:
1098
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001099osx.cocoa.NilArg (ObjC)
Kristof Umann1a170322019-02-05 00:39:33 +00001100"""""""""""""""""""""""
1101Check for prohibited nil arguments to ObjC method calls.
1102
1103 - caseInsensitiveCompare:
1104 - compare:
1105 - compare:options:
1106 - compare:options:range:
1107 - compare:options:range:locale:
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001108 - componentsSeparatedByCharactersInSet:
Kristof Umann1a170322019-02-05 00:39:33 +00001109 - initWithFormat:
1110
1111.. code-block:: objc
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001112
Kristof Umann1a170322019-02-05 00:39:33 +00001113 NSComparisonResult test(NSString *s) {
1114 NSString *aString = nil;
1115 return [s caseInsensitiveCompare:aString];
1116 // warn: argument to 'NSString' method
1117 // 'caseInsensitiveCompare:' cannot be nil
1118 }
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001119
Kristof Umann1a170322019-02-05 00:39:33 +00001120
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +00001121.. _osx-cocoa-NonNilReturnValue:
1122
Kristof Umann1a170322019-02-05 00:39:33 +00001123osx.cocoa.NonNilReturnValue
1124"""""""""""""""""""""""""""
1125Models the APIs that are guaranteed to return a non-nil value.
1126
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +00001127.. _osx-cocoa-ObjCGenerics:
1128
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001129osx.cocoa.ObjCGenerics (ObjC)
Kristof Umann1a170322019-02-05 00:39:33 +00001130"""""""""""""""""""""""""""""
1131Check for type errors when using Objective-C generics.
1132
1133.. code-block:: objc
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001134
Kristof Umann1a170322019-02-05 00:39:33 +00001135 NSMutableArray *names = [NSMutableArray array];
1136 NSMutableArray *birthDates = names;
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001137
Kristof Umann1a170322019-02-05 00:39:33 +00001138 // Warning: Conversion from value of type 'NSDate *'
1139 // to incompatible type 'NSString *'
1140 [birthDates addObject: [NSDate date]];
1141
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +00001142.. _osx-cocoa-RetainCount:
1143
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001144osx.cocoa.RetainCount (ObjC)
Kristof Umann1a170322019-02-05 00:39:33 +00001145""""""""""""""""""""""""""""
1146Check for leaks and improper reference count management
1147
1148.. code-block:: objc
1149
1150 void test() {
1151 NSString *s = [[NSString alloc] init]; // warn
1152 }
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001153
Kristof Umann1a170322019-02-05 00:39:33 +00001154 CFStringRef test(char *bytes) {
1155 return CFStringCreateWithCStringNoCopy(
1156 0, bytes, NSNEXTSTEPStringEncoding, 0); // warn
1157 }
1158
1159
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +00001160.. _osx-cocoa-RunLoopAutoreleaseLeak:
1161
Kristof Umann1a170322019-02-05 00:39:33 +00001162osx.cocoa.RunLoopAutoreleaseLeak
1163""""""""""""""""""""""""""""""""
1164Check for leaked memory in autorelease pools that will never be drained.
1165
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +00001166.. _osx-cocoa-SelfInit:
1167
Kristof Umann1a170322019-02-05 00:39:33 +00001168osx.cocoa.SelfInit (ObjC)
1169"""""""""""""""""""""""""
1170Check that 'self' is properly initialized inside an initializer method.
1171
1172.. code-block:: objc
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001173
Kristof Umann1a170322019-02-05 00:39:33 +00001174 @interface MyObj : NSObject {
1175 id x;
1176 }
1177 - (id)init;
1178 @end
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001179
Kristof Umann1a170322019-02-05 00:39:33 +00001180 @implementation MyObj
1181 - (id)init {
1182 [super init];
1183 x = 0; // warn: instance variable used while 'self' is not
1184 // initialized
1185 return 0;
1186 }
1187 @end
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001188
Kristof Umann1a170322019-02-05 00:39:33 +00001189 @interface MyObj : NSObject
1190 - (id)init;
1191 @end
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001192
Kristof Umann1a170322019-02-05 00:39:33 +00001193 @implementation MyObj
1194 - (id)init {
1195 [super init];
1196 return self; // warn: returning uninitialized 'self'
1197 }
1198 @end
1199
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +00001200.. _osx-cocoa-SuperDealloc:
1201
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001202osx.cocoa.SuperDealloc (ObjC)
Kristof Umann1a170322019-02-05 00:39:33 +00001203"""""""""""""""""""""""""""""
1204Warn about improper use of '[super dealloc]' in Objective-C.
1205
1206.. code-block:: objc
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001207
Kristof Umann1a170322019-02-05 00:39:33 +00001208 @interface SuperDeallocThenReleaseIvarClass : NSObject {
1209 NSObject *_ivar;
1210 }
1211 @end
1212
1213 @implementation SuperDeallocThenReleaseIvarClass
1214 - (void)dealloc {
1215 [super dealloc];
1216 [_ivar release]; // warn
1217 }
1218 @end
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001219
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +00001220.. _osx-cocoa-UnusedIvars:
1221
Kristof Umann1a170322019-02-05 00:39:33 +00001222osx.cocoa.UnusedIvars (ObjC)
1223""""""""""""""""""""""""""""
1224Warn about private ivars that are never used.
1225
1226.. code-block:: objc
1227
1228 @interface MyObj : NSObject {
1229 @private
1230 id x; // warn
1231 }
1232 @end
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001233
Kristof Umann1a170322019-02-05 00:39:33 +00001234 @implementation MyObj
1235 @end
1236
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +00001237.. _osx-cocoa-VariadicMethodTypes:
1238
Kristof Umann1a170322019-02-05 00:39:33 +00001239osx.cocoa.VariadicMethodTypes (ObjC)
1240""""""""""""""""""""""""""""""""""""
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001241Check for passing non-Objective-C types to variadic collection
Kristof Umann1a170322019-02-05 00:39:33 +00001242initialization methods that expect only Objective-C types.
1243
1244.. code-block:: objc
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001245
Kristof Umann1a170322019-02-05 00:39:33 +00001246 void test() {
1247 [NSSet setWithObjects:@"Foo", "Bar", nil];
1248 // warn: argument should be an ObjC pointer type, not 'char *'
1249 }
1250
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +00001251.. _osx-coreFoundation-CFError:
1252
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001253osx.coreFoundation.CFError (C)
Kristof Umann1a170322019-02-05 00:39:33 +00001254""""""""""""""""""""""""""""""
1255Check usage of CFErrorRef* parameters
1256
1257.. code-block:: c
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001258
Kristof Umann1a170322019-02-05 00:39:33 +00001259 void test(CFErrorRef *error) {
1260 // warn: function accepting CFErrorRef* should have a
1261 // non-void return
1262 }
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001263
Kristof Umann1a170322019-02-05 00:39:33 +00001264 int foo(CFErrorRef *error) {
1265 *error = 0; // warn: potential null dereference
1266 return 0;
1267 }
1268
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +00001269.. _osx-coreFoundation-CFNumber:
1270
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001271osx.coreFoundation.CFNumber (C)
Kristof Umann1a170322019-02-05 00:39:33 +00001272"""""""""""""""""""""""""""""""
1273Check for proper uses of CFNumber APIs.
1274
1275.. code-block:: c
1276
1277 CFNumberRef test(unsigned char x) {
1278 return CFNumberCreate(0, kCFNumberSInt16Type, &x);
1279 // warn: 8 bit integer is used to initialize a 16 bit integer
1280 }
1281
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +00001282.. _osx-coreFoundation-CFRetainRelease:
1283
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001284osx.coreFoundation.CFRetainRelease (C)
Kristof Umann1a170322019-02-05 00:39:33 +00001285""""""""""""""""""""""""""""""""""""""
1286Check for null arguments to CFRetain/CFRelease/CFMakeCollectable.
1287
1288.. code-block:: c
1289
1290 void test(CFTypeRef p) {
1291 if (!p)
1292 CFRetain(p); // warn
1293 }
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001294
Kristof Umann1a170322019-02-05 00:39:33 +00001295 void test(int x, CFTypeRef p) {
1296 if (p)
1297 return;
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001298
Kristof Umann1a170322019-02-05 00:39:33 +00001299 CFRelease(p); // warn
1300 }
1301
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +00001302.. _osx-coreFoundation-containers-OutOfBounds:
1303
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001304osx.coreFoundation.containers.OutOfBounds (C)
Kristof Umann1a170322019-02-05 00:39:33 +00001305"""""""""""""""""""""""""""""""""""""""""""""
1306Checks for index out-of-bounds when using 'CFArray' API.
1307
1308.. code-block:: c
1309
1310 void test() {
1311 CFArrayRef A = CFArrayCreate(0, 0, 0, &kCFTypeArrayCallBacks);
1312 CFArrayGetValueAtIndex(A, 0); // warn
1313 }
1314
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +00001315.. _osx-coreFoundation-containers-PointerSizedValues:
1316
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001317osx.coreFoundation.containers.PointerSizedValues (C)
Kristof Umann1a170322019-02-05 00:39:33 +00001318""""""""""""""""""""""""""""""""""""""""""""""""""""
1319Warns if 'CFArray', 'CFDictionary', 'CFSet' are created with non-pointer-size values.
1320
1321.. code-block:: c
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001322
Kristof Umann1a170322019-02-05 00:39:33 +00001323 void test() {
1324 int x[] = { 1 };
1325 CFArrayRef A = CFArrayCreate(0, (const void """""""""""""""""""""""")x, 1,
1326 &kCFTypeArrayCallBacks); // warn
1327 }
1328
1329
1330.. _alpha-checkers:
1331
1332Experimental Checkers
1333---------------------
1334
1335*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.*
1336
1337alpha.clone
1338^^^^^^^^^^^
1339
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +00001340.. _alpha-clone-CloneChecker:
1341
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001342alpha.clone.CloneChecker (C, C++, ObjC)
Kristof Umann1a170322019-02-05 00:39:33 +00001343"""""""""""""""""""""""""""""""""""""""
1344Reports similar pieces of code.
1345
1346.. code-block:: c
1347
1348 void log();
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001349
Kristof Umann1a170322019-02-05 00:39:33 +00001350 int max(int a, int b) { // warn
1351 log();
1352 if (a > b)
1353 return a;
1354 return b;
1355 }
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001356
Kristof Umann1a170322019-02-05 00:39:33 +00001357 int maxClone(int x, int y) { // similar code here
1358 log();
1359 if (x > y)
1360 return x;
1361 return y;
1362 }
1363
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +00001364.. _alpha-core-BoolAssignment:
1365
Kristof Umann1a170322019-02-05 00:39:33 +00001366alpha.core.BoolAssignment (ObjC)
1367""""""""""""""""""""""""""""""""
1368Warn about assigning non-{0,1} values to boolean variables.
1369
1370.. code-block:: objc
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001371
Kristof Umann1a170322019-02-05 00:39:33 +00001372 void test() {
1373 BOOL b = -1; // warn
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001374 }
Kristof Umann1a170322019-02-05 00:39:33 +00001375
1376alpha.core
1377^^^^^^^^^^
1378
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +00001379.. _alpha-core-CallAndMessageUnInitRefArg:
1380
Kristof Umann1a170322019-02-05 00:39:33 +00001381alpha.core.CallAndMessageUnInitRefArg (C,C++, ObjC)
1382"""""""""""""""""""""""""""""""""""""""""""""""""""
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001383Check for logical errors for function calls and Objective-C
Kristof Umann1a170322019-02-05 00:39:33 +00001384message expressions (e.g., uninitialized arguments, null function pointers, and pointer to undefined variables).
1385
1386.. code-block:: c
1387
1388 void test(void) {
1389 int t;
1390 int &p = t;
1391 int &s = p;
1392 int &q = s;
1393 foo(q); // warn
1394 }
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001395
Kristof Umann1a170322019-02-05 00:39:33 +00001396 void test(void) {
1397 int x;
1398 foo(&x); // warn
1399 }
1400
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +00001401.. _alpha-core-CastSize:
1402
Kristof Umann1a170322019-02-05 00:39:33 +00001403alpha.core.CastSize (C)
1404"""""""""""""""""""""""
1405Check when casting a malloc'ed type ``T``, whether the size is a multiple of the size of ``T``.
1406
1407.. code-block:: c
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001408
Kristof Umann1a170322019-02-05 00:39:33 +00001409 void test() {
1410 int *x = (int *) malloc(11); // warn
1411 }
1412
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +00001413.. _alpha-core-CastToStruct:
1414
Kristof Umann1a170322019-02-05 00:39:33 +00001415alpha.core.CastToStruct (C, C++)
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001416""""""""""""""""""""""""""""""""
Kristof Umann1a170322019-02-05 00:39:33 +00001417Check for cast from non-struct pointer to struct pointer.
1418
1419.. code-block:: cpp
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001420
Kristof Umann1a170322019-02-05 00:39:33 +00001421 // C
1422 struct s {};
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001423
Kristof Umann1a170322019-02-05 00:39:33 +00001424 void test(int *p) {
1425 struct s *ps = (struct s *) p; // warn
1426 }
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001427
Kristof Umann1a170322019-02-05 00:39:33 +00001428 // C++
1429 class c {};
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001430
Kristof Umann1a170322019-02-05 00:39:33 +00001431 void test(int *p) {
1432 c *pc = (c *) p; // warn
1433 }
1434
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +00001435.. _alpha-core-Conversion:
1436
Kristof Umann1a170322019-02-05 00:39:33 +00001437alpha.core.Conversion (C, C++, ObjC)
1438""""""""""""""""""""""""""""""""""""
1439Loss of sign/precision in implicit conversions.
1440
1441.. code-block:: c
1442
1443 void test(unsigned U, signed S) {
1444 if (S > 10) {
1445 if (U < S) {
1446 }
1447 }
1448 if (S < -10) {
1449 if (U < S) { // warn (loss of sign)
1450 }
1451 }
1452 }
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001453
Kristof Umann1a170322019-02-05 00:39:33 +00001454 void test() {
1455 long long A = 1LL << 60;
1456 short X = A; // warn (loss of precision)
1457 }
1458
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +00001459.. _alpha-core-DynamicTypeChecker:
1460
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001461alpha.core.DynamicTypeChecker (ObjC)
Kristof Umann1a170322019-02-05 00:39:33 +00001462""""""""""""""""""""""""""""""""""""
1463Check for cases where the dynamic and the static type of an object are unrelated.
1464
1465
1466.. code-block:: objc
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001467
Kristof Umann1a170322019-02-05 00:39:33 +00001468 id date = [NSDate date];
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001469
Kristof Umann1a170322019-02-05 00:39:33 +00001470 // Warning: Object has a dynamic type 'NSDate *' which is
1471 // incompatible with static type 'NSNumber *'"
1472 NSNumber *number = date;
1473 [number doubleValue];
1474
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +00001475.. _alpha-core-FixedAddr:
1476
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001477alpha.core.FixedAddr (C)
Kristof Umann1a170322019-02-05 00:39:33 +00001478""""""""""""""""""""""""
1479Check for assignment of a fixed address to a pointer.
1480
1481.. code-block:: c
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001482
Kristof Umann1a170322019-02-05 00:39:33 +00001483 void test() {
1484 int *p;
1485 p = (int *) 0x10000; // warn
1486 }
1487
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +00001488.. _alpha-core-IdenticalExpr:
1489
Kristof Umann1a170322019-02-05 00:39:33 +00001490alpha.core.IdenticalExpr (C, C++)
1491"""""""""""""""""""""""""""""""""
1492Warn about unintended use of identical expressions in operators.
1493
1494.. code-block:: cpp
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001495
Kristof Umann1a170322019-02-05 00:39:33 +00001496 // C
1497 void test() {
1498 int a = 5;
1499 int b = a | 4 | a; // warn: identical expr on both sides
1500 }
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001501
Kristof Umann1a170322019-02-05 00:39:33 +00001502 // C++
1503 bool f(void);
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001504
Kristof Umann1a170322019-02-05 00:39:33 +00001505 void test(bool b) {
1506 int i = 10;
1507 if (f()) { // warn: true and false branches are identical
1508 do {
1509 i--;
1510 } while (f());
1511 } else {
1512 do {
1513 i--;
1514 } while (f());
1515 }
1516 }
1517
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +00001518.. _alpha-core-PointerArithm:
1519
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001520alpha.core.PointerArithm (C)
Kristof Umann1a170322019-02-05 00:39:33 +00001521""""""""""""""""""""""""""""
1522Check for pointer arithmetic on locations other than array elements.
1523
1524.. code-block:: c
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001525
Kristof Umann1a170322019-02-05 00:39:33 +00001526 void test() {
1527 int x;
1528 int *p;
1529 p = &x + 1; // warn
1530 }
1531
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +00001532.. _alpha-core-PointerSub:
1533
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001534alpha.core.PointerSub (C)
Kristof Umann1a170322019-02-05 00:39:33 +00001535"""""""""""""""""""""""""
1536Check for pointer subtractions on two pointers pointing to different memory chunks.
1537
1538.. code-block:: c
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001539
Kristof Umann1a170322019-02-05 00:39:33 +00001540 void test() {
1541 int x, y;
1542 int d = &y - &x; // warn
1543 }
1544
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +00001545.. _alpha-core-SizeofPtr:
1546
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001547alpha.core.SizeofPtr (C)
Kristof Umann1a170322019-02-05 00:39:33 +00001548""""""""""""""""""""""""
1549Warn about unintended use of ``sizeof()`` on pointer expressions.
1550
1551.. code-block:: c
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001552
Kristof Umann1a170322019-02-05 00:39:33 +00001553 struct s {};
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001554
Kristof Umann1a170322019-02-05 00:39:33 +00001555 int test(struct s *p) {
1556 return sizeof(p);
1557 // warn: sizeof(ptr) can produce an unexpected result
1558 }
1559
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +00001560.. _alpha-core-StackAddressAsyncEscape:
1561
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001562alpha.core.StackAddressAsyncEscape (C)
Kristof Umann1a170322019-02-05 00:39:33 +00001563""""""""""""""""""""""""""""""""""""""
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001564Check that addresses to stack memory do not escape the function that involves dispatch_after or dispatch_async.
Kristof Umann1a170322019-02-05 00:39:33 +00001565This checker is a part of ``core.StackAddressEscape``, but is temporarily disabled until some false positives are fixed.
1566
1567.. code-block:: c
1568
1569 dispatch_block_t test_block_inside_block_async_leak() {
1570 int x = 123;
1571 void (^inner)(void) = ^void(void) {
1572 int y = x;
1573 ++y;
1574 };
1575 void (^outer)(void) = ^void(void) {
1576 int z = x;
1577 ++z;
1578 inner();
1579 };
1580 return outer; // warn: address of stack-allocated block is captured by a
1581 // returned block
1582 }
1583
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +00001584.. _alpha-core-TestAfterDivZero:
1585
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001586alpha.core.TestAfterDivZero (C)
Kristof Umann1a170322019-02-05 00:39:33 +00001587"""""""""""""""""""""""""""""""
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001588Check for division by variable that is later compared against 0.
Kristof Umann1a170322019-02-05 00:39:33 +00001589Either the comparison is useless or there is division by zero.
1590
1591.. code-block:: c
1592
1593 void test(int x) {
1594 var = 77 / x;
1595 if (x == 0) { } // warn
1596 }
1597
1598alpha.cplusplus
1599^^^^^^^^^^^^^^^
1600
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +00001601.. _alpha-cplusplus-DeleteWithNonVirtualDtor:
1602
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001603alpha.cplusplus.DeleteWithNonVirtualDtor (C++)
Kristof Umann1a170322019-02-05 00:39:33 +00001604""""""""""""""""""""""""""""""""""""""""""""""
1605Reports destructions of polymorphic objects with a non-virtual destructor in their base class.
1606
1607.. code-block:: cpp
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001608
Kristof Umann1a170322019-02-05 00:39:33 +00001609 NonVirtual *create() {
1610 NonVirtual *x = new NVDerived(); // note: conversion from derived to base
1611 // happened here
1612 return x;
1613 }
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001614
Kristof Umann1a170322019-02-05 00:39:33 +00001615 void sink(NonVirtual *x) {
1616 delete x; // warn: destruction of a polymorphic object with no virtual
1617 // destructor
1618 }
1619
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +00001620.. _alpha-cplusplus-EnumCastOutOfRange:
1621
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001622alpha.cplusplus.EnumCastOutOfRange (C++)
Kristof Umann1a170322019-02-05 00:39:33 +00001623""""""""""""""""""""""""""""""""""""""""
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001624Check for integer to enumeration casts that could result in undefined values.
Kristof Umann1a170322019-02-05 00:39:33 +00001625
1626.. code-block:: cpp
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001627
Kristof Umann1a170322019-02-05 00:39:33 +00001628 enum TestEnum {
1629 A = 0
1630 };
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001631
Kristof Umann1a170322019-02-05 00:39:33 +00001632 void foo() {
1633 TestEnum t = static_cast(-1);
1634 // warn: the value provided to the cast expression is not in
1635 the valid range of values for the enum
1636
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +00001637.. _alpha-cplusplus-InvalidatedIterator:
1638
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001639alpha.cplusplus.InvalidatedIterator (C++)
Kristof Umann1a170322019-02-05 00:39:33 +00001640"""""""""""""""""""""""""""""""""""""""""
1641Check for use of invalidated iterators.
1642
1643.. code-block:: cpp
1644
1645 void bad_copy_assign_operator_list1(std::list &L1,
1646 const std::list &L2) {
1647 auto i0 = L1.cbegin();
1648 L1 = L2;
1649 *i0; // warn: invalidated iterator accessed
1650 }
1651
1652
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +00001653.. _alpha-cplusplus-IteratorRange:
1654
Kristof Umann1a170322019-02-05 00:39:33 +00001655alpha.cplusplus.IteratorRange (C++)
1656"""""""""""""""""""""""""""""""""""
1657Check for iterators used outside their valid ranges.
1658
1659.. code-block:: cpp
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001660
Kristof Umann1a170322019-02-05 00:39:33 +00001661 void simple_bad_end(const std::vector &v) {
1662 auto i = v.end();
1663 *i; // warn: iterator accessed outside of its range
1664 }
1665
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +00001666.. _alpha-cplusplus-MismatchedIterator:
1667
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001668alpha.cplusplus.MismatchedIterator (C++)
Kristof Umann1a170322019-02-05 00:39:33 +00001669""""""""""""""""""""""""""""""""""""""""
1670Check for use of iterators of different containers where iterators of the same container are expected.
1671
1672.. code-block:: cpp
1673
1674 void bad_insert3(std::vector &v1, std::vector &v2) {
1675 v2.insert(v1.cbegin(), v2.cbegin(), v2.cend()); // warn: container accessed
1676 // using foreign
1677 // iterator argument
1678 v1.insert(v1.cbegin(), v1.cbegin(), v2.cend()); // warn: iterators of
1679 // different containers
1680 // used where the same
1681 // container is
1682 // expected
1683 v1.insert(v1.cbegin(), v2.cbegin(), v1.cend()); // warn: iterators of
1684 // different containers
1685 // used where the same
1686 // container is
1687 // expected
1688 }
1689
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +00001690.. _alpha-cplusplus-MisusedMovedObject:
1691
Kristof Umann1a170322019-02-05 00:39:33 +00001692alpha.cplusplus.MisusedMovedObject (C++)
1693""""""""""""""""""""""""""""""""""""""""
1694Method calls on a moved-from object and copying a moved-from object will be reported.
1695
1696
1697.. code-block:: cpp
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001698
Kristof Umann1a170322019-02-05 00:39:33 +00001699 struct A {
1700 void foo() {}
1701 };
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001702
Kristof Umann1a170322019-02-05 00:39:33 +00001703 void f() {
1704 A a;
1705 A b = std::move(a); // note: 'a' became 'moved-from' here
1706 a.foo(); // warn: method call on a 'moved-from' object 'a'
1707 }
1708
Kristof Umann1a170322019-02-05 00:39:33 +00001709alpha.deadcode
1710^^^^^^^^^^^^^^
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +00001711.. _alpha-deadcode-UnreachableCode:
1712
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001713alpha.deadcode.UnreachableCode (C, C++)
Kristof Umann1a170322019-02-05 00:39:33 +00001714"""""""""""""""""""""""""""""""""""""""
1715Check unreachable code.
1716
1717.. code-block:: cpp
1718
1719 // C
1720 int test() {
1721 int x = 1;
1722 while(x);
1723 return x; // warn
1724 }
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001725
Kristof Umann1a170322019-02-05 00:39:33 +00001726 // C++
1727 void test() {
1728 int a = 2;
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001729
Kristof Umann1a170322019-02-05 00:39:33 +00001730 while (a > 1)
1731 a--;
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001732
Kristof Umann1a170322019-02-05 00:39:33 +00001733 if (a > 1)
1734 a++; // warn
1735 }
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001736
Kristof Umann1a170322019-02-05 00:39:33 +00001737 // Objective-C
1738 void test(id x) {
1739 return;
1740 [x retain]; // warn
1741 }
1742
1743alpha.llvm
1744^^^^^^^^^^
1745
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +00001746.. _alpha-llvm-Conventions:
1747
Kristof Umann1a170322019-02-05 00:39:33 +00001748alpha.llvm.Conventions
1749""""""""""""""""""""""
1750
1751Check code for LLVM codebase conventions:
1752
1753* A StringRef should not be bound to a temporary std::string whose lifetime is shorter than the StringRef's.
1754* Clang AST nodes should not have fields that can allocate memory.
1755
1756
1757alpha.osx
1758^^^^^^^^^
1759
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +00001760.. _alpha-osx-cocoa-DirectIvarAssignment:
1761
Kristof Umann1a170322019-02-05 00:39:33 +00001762alpha.osx.cocoa.DirectIvarAssignment (ObjC)
1763"""""""""""""""""""""""""""""""""""""""""""
1764Check for direct assignments to instance variables.
1765
1766
1767.. code-block:: objc
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001768
Kristof Umann1a170322019-02-05 00:39:33 +00001769 @interface MyClass : NSObject {}
1770 @property (readonly) id A;
1771 - (void) foo;
1772 @end
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001773
Kristof Umann1a170322019-02-05 00:39:33 +00001774 @implementation MyClass
1775 - (void) foo {
1776 _A = 0; // warn
1777 }
1778 @end
1779
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +00001780.. _alpha-osx-cocoa-DirectIvarAssignmentForAnnotatedFunctions:
1781
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001782alpha.osx.cocoa.DirectIvarAssignmentForAnnotatedFunctions (ObjC)
Kristof Umann1a170322019-02-05 00:39:33 +00001783""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001784Check for direct assignments to instance variables in
Kristof Umann1a170322019-02-05 00:39:33 +00001785the methods annotated with ``objc_no_direct_instance_variable_assignment``.
1786
1787.. code-block:: objc
1788
1789 @interface MyClass : NSObject {}
1790 @property (readonly) id A;
1791 - (void) fAnnotated __attribute__((
1792 annotate("objc_no_direct_instance_variable_assignment")));
1793 - (void) fNotAnnotated;
1794 @end
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001795
Kristof Umann1a170322019-02-05 00:39:33 +00001796 @implementation MyClass
1797 - (void) fAnnotated {
1798 _A = 0; // warn
1799 }
1800 - (void) fNotAnnotated {
1801 _A = 0; // no warn
1802 }
1803 @end
1804
1805
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +00001806.. _alpha-osx-cocoa-InstanceVariableInvalidation:
1807
Kristof Umann1a170322019-02-05 00:39:33 +00001808alpha.osx.cocoa.InstanceVariableInvalidation (ObjC)
1809"""""""""""""""""""""""""""""""""""""""""""""""""""
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001810Check that the invalidatable instance variables are
Kristof Umann1a170322019-02-05 00:39:33 +00001811invalidated in the methods annotated with objc_instance_variable_invalidator.
1812
1813.. code-block:: objc
1814
1815 @protocol Invalidation <NSObject>
1816 - (void) invalidate
1817 __attribute__((annotate("objc_instance_variable_invalidator")));
1818 @end
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001819
Kristof Umann1a170322019-02-05 00:39:33 +00001820 @interface InvalidationImpObj : NSObject <Invalidation>
1821 @end
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001822
Kristof Umann1a170322019-02-05 00:39:33 +00001823 @interface SubclassInvalidationImpObj : InvalidationImpObj {
1824 InvalidationImpObj *var;
1825 }
1826 - (void)invalidate;
1827 @end
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001828
Kristof Umann1a170322019-02-05 00:39:33 +00001829 @implementation SubclassInvalidationImpObj
1830 - (void) invalidate {}
1831 @end
1832 // warn: var needs to be invalidated or set to nil
1833
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +00001834.. _alpha-osx-cocoa-MissingInvalidationMethod:
1835
Kristof Umann1a170322019-02-05 00:39:33 +00001836alpha.osx.cocoa.MissingInvalidationMethod (ObjC)
1837""""""""""""""""""""""""""""""""""""""""""""""""
1838Check that the invalidation methods are present in classes that contain invalidatable instance variables.
1839
1840.. code-block:: objc
1841
1842 @protocol Invalidation <NSObject>
1843 - (void)invalidate
1844 __attribute__((annotate("objc_instance_variable_invalidator")));
1845 @end
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001846
Kristof Umann1a170322019-02-05 00:39:33 +00001847 @interface NeedInvalidation : NSObject <Invalidation>
1848 @end
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001849
Kristof Umann1a170322019-02-05 00:39:33 +00001850 @interface MissingInvalidationMethodDecl : NSObject {
1851 NeedInvalidation *Var; // warn
1852 }
1853 @end
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001854
Kristof Umann1a170322019-02-05 00:39:33 +00001855 @implementation MissingInvalidationMethodDecl
1856 @end
1857
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +00001858.. _alpha-osx-cocoa-localizability-PluralMisuseChecker:
1859
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001860alpha.osx.cocoa.localizability.PluralMisuseChecker (ObjC)
Kristof Umann1a170322019-02-05 00:39:33 +00001861"""""""""""""""""""""""""""""""""""""""""""""""""""""""""
1862Warns against using one vs. many plural pattern in code when generating localized strings.
1863
1864.. code-block:: objc
1865
1866 NSString *reminderText =
1867 NSLocalizedString(@"None", @"Indicates no reminders");
1868 if (reminderCount == 1) {
1869 // Warning: Plural cases are not supported across all languages.
1870 // Use a .stringsdict file instead
1871 reminderText =
1872 NSLocalizedString(@"1 Reminder", @"Indicates single reminder");
1873 } else if (reminderCount >= 2) {
1874 // Warning: Plural cases are not supported across all languages.
1875 // Use a .stringsdict file instead
1876 reminderText =
1877 [NSString stringWithFormat:
1878 NSLocalizedString(@"%@ Reminders", @"Indicates multiple reminders"),
1879 reminderCount];
1880 }
1881
1882alpha.security
1883^^^^^^^^^^^^^^
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +00001884.. _alpha-security-ArrayBound:
1885
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001886alpha.security.ArrayBound (C)
Kristof Umann1a170322019-02-05 00:39:33 +00001887"""""""""""""""""""""""""""""
1888Warn about buffer overflows (older checker).
1889
1890.. code-block:: c
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001891
Kristof Umann1a170322019-02-05 00:39:33 +00001892 void test() {
1893 char *s = "";
1894 char c = s[1]; // warn
1895 }
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001896
Kristof Umann1a170322019-02-05 00:39:33 +00001897 struct seven_words {
1898 int c[7];
1899 };
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001900
Kristof Umann1a170322019-02-05 00:39:33 +00001901 void test() {
1902 struct seven_words a, *p;
1903 p = &a;
1904 p[0] = a;
1905 p[1] = a;
1906 p[2] = a; // warn
1907 }
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001908
Kristof Umann1a170322019-02-05 00:39:33 +00001909 // note: requires unix.Malloc or
1910 // alpha.unix.MallocWithAnnotations checks enabled.
1911 void test() {
1912 int *p = malloc(12);
1913 p[3] = 4; // warn
1914 }
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001915
Kristof Umann1a170322019-02-05 00:39:33 +00001916 void test() {
1917 char a[2];
1918 int *b = (int*)a;
1919 b[1] = 3; // warn
1920 }
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001921
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +00001922.. _alpha-security-ArrayBoundV2:
1923
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001924alpha.security.ArrayBoundV2 (C)
Kristof Umann1a170322019-02-05 00:39:33 +00001925"""""""""""""""""""""""""""""""
1926Warn about buffer overflows (newer checker).
1927
1928.. code-block:: c
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001929
Kristof Umann1a170322019-02-05 00:39:33 +00001930 void test() {
1931 char *s = "";
1932 char c = s[1]; // warn
1933 }
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001934
Kristof Umann1a170322019-02-05 00:39:33 +00001935 void test() {
1936 int buf[100];
1937 int *p = buf;
1938 p = p + 99;
1939 p[1] = 1; // warn
1940 }
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001941
Kristof Umann1a170322019-02-05 00:39:33 +00001942 // note: compiler has internal check for this.
1943 // Use -Wno-array-bounds to suppress compiler warning.
1944 void test() {
1945 int buf[100][100];
1946 buf[0][-1] = 1; // warn
1947 }
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001948
Kristof Umann1a170322019-02-05 00:39:33 +00001949 // note: requires alpha.security.taint check turned on.
1950 void test() {
1951 char s[] = "abc";
1952 int x = getchar();
1953 char c = s[x]; // warn: index is tainted
1954 }
1955
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +00001956.. _alpha-security-MallocOverflow:
1957
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001958alpha.security.MallocOverflow (C)
Kristof Umann1a170322019-02-05 00:39:33 +00001959"""""""""""""""""""""""""""""""""
1960Check for overflows in the arguments to malloc().
1961
1962.. code-block:: c
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001963
Kristof Umann1a170322019-02-05 00:39:33 +00001964 void test(int n) {
1965 void *p = malloc(n * sizeof(int)); // warn
1966 }
1967
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +00001968.. _alpha-security-MmapWriteExec:
1969
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001970alpha.security.MmapWriteExec (C)
Kristof Umann1a170322019-02-05 00:39:33 +00001971""""""""""""""""""""""""""""""""
1972Warn on mmap() calls that are both writable and executable.
1973
1974.. code-block:: c
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001975
Kristof Umann1a170322019-02-05 00:39:33 +00001976 void test(int n) {
1977 void *c = mmap(NULL, 32, PROT_READ | PROT_WRITE | PROT_EXEC,
1978 MAP_PRIVATE | MAP_ANON, -1, 0);
1979 // warn: Both PROT_WRITE and PROT_EXEC flags are set. This can lead to
1980 // exploitable memory regions, which could be overwritten with malicious
1981 // code
1982 }
1983
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +00001984.. _alpha-security-ReturnPtrRange:
1985
Kristof Umann1a170322019-02-05 00:39:33 +00001986alpha.security.ReturnPtrRange (C)
1987"""""""""""""""""""""""""""""""""
1988Check for an out-of-bound pointer being returned to callers.
1989
1990.. code-block:: c
1991
1992 static int A[10];
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001993
Kristof Umann1a170322019-02-05 00:39:33 +00001994 int *test() {
1995 int *p = A + 10;
1996 return p; // warn
1997 }
Alexander Kornienko9a857d22019-02-11 15:17:13 +00001998
Kristof Umann1a170322019-02-05 00:39:33 +00001999 int test(void) {
2000 int x;
2001 return x; // warn: undefined or garbage returned
2002 }
2003
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +00002004.. _alpha-security-taint-TaintPropagation:
2005
Kristof Umann1a170322019-02-05 00:39:33 +00002006alpha.security.taint.TaintPropagation (C, C++)
Alexander Kornienko9a857d22019-02-11 15:17:13 +00002007""""""""""""""""""""""""""""""""""""""""""""""
2008Generate taint information used by other checkers.
Kristof Umann1a170322019-02-05 00:39:33 +00002009A data is tainted when it comes from an unreliable source.
2010
2011.. code-block:: c
Alexander Kornienko9a857d22019-02-11 15:17:13 +00002012
Kristof Umann1a170322019-02-05 00:39:33 +00002013 void test() {
2014 char x = getchar(); // 'x' marked as tainted
2015 system(&x); // warn: untrusted data is passed to a system call
2016 }
Alexander Kornienko9a857d22019-02-11 15:17:13 +00002017
Kristof Umann1a170322019-02-05 00:39:33 +00002018 // note: compiler internally checks if the second param to
2019 // sprintf is a string literal or not.
2020 // Use -Wno-format-security to suppress compiler warning.
2021 void test() {
2022 char s[10], buf[10];
2023 fscanf(stdin, "%s", s); // 's' marked as tainted
Alexander Kornienko9a857d22019-02-11 15:17:13 +00002024
Kristof Umann1a170322019-02-05 00:39:33 +00002025 sprintf(buf, s); // warn: untrusted data as a format string
2026 }
Alexander Kornienko9a857d22019-02-11 15:17:13 +00002027
Kristof Umann1a170322019-02-05 00:39:33 +00002028 void test() {
2029 size_t ts;
2030 scanf("%zd", &ts); // 'ts' marked as tainted
2031 int *p = (int *)malloc(ts * sizeof(int));
2032 // warn: untrusted data as buffer size
2033 }
2034
2035alpha.unix
2036^^^^^^^^^^^
2037
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +00002038.. _alpha-unix-BlockInCriticalSection:
2039
Alexander Kornienko9a857d22019-02-11 15:17:13 +00002040alpha.unix.BlockInCriticalSection (C)
Kristof Umann1a170322019-02-05 00:39:33 +00002041"""""""""""""""""""""""""""""""""""""
Alexander Kornienko9a857d22019-02-11 15:17:13 +00002042Check for calls to blocking functions inside a critical section.
Kristof Umann1a170322019-02-05 00:39:33 +00002043Applies to: ``lock, unlock, sleep, getc, fgets, read, recv, pthread_mutex_lock,``
2044`` pthread_mutex_unlock, mtx_lock, mtx_timedlock, mtx_trylock, mtx_unlock, lock_guard, unique_lock``
2045
2046.. code-block:: c
Alexander Kornienko9a857d22019-02-11 15:17:13 +00002047
Kristof Umann1a170322019-02-05 00:39:33 +00002048 void test() {
2049 std::mutex m;
2050 m.lock();
2051 sleep(3); // warn: a blocking function sleep is called inside a critical
2052 // section
2053 m.unlock();
2054 }
2055
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +00002056.. _alpha-unix-Chroot:
2057
Kristof Umann1a170322019-02-05 00:39:33 +00002058alpha.unix.Chroot (C)
2059"""""""""""""""""""""
2060Check improper use of chroot.
2061
2062.. code-block:: c
2063
2064 void f();
Alexander Kornienko9a857d22019-02-11 15:17:13 +00002065
Kristof Umann1a170322019-02-05 00:39:33 +00002066 void test() {
2067 chroot("/usr/local");
2068 f(); // warn: no call of chdir("/") immediately after chroot
2069 }
2070
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +00002071.. _alpha-unix-PthreadLock:
2072
Alexander Kornienko9a857d22019-02-11 15:17:13 +00002073alpha.unix.PthreadLock (C)
Kristof Umann1a170322019-02-05 00:39:33 +00002074""""""""""""""""""""""""""
2075Simple lock -> unlock checker.
2076Applies to: ``pthread_mutex_lock, pthread_rwlock_rdlock, pthread_rwlock_wrlock, lck_mtx_lock, lck_rw_lock_exclusive``
Alexander Kornienko9a857d22019-02-11 15:17:13 +00002077``lck_rw_lock_shared, pthread_mutex_trylock, pthread_rwlock_tryrdlock, pthread_rwlock_tryrwlock, lck_mtx_try_lock,
Kristof Umann1a170322019-02-05 00:39:33 +00002078lck_rw_try_lock_exclusive, lck_rw_try_lock_shared, pthread_mutex_unlock, pthread_rwlock_unlock, lck_mtx_unlock, lck_rw_done``.
2079
2080
2081.. code-block:: c
Alexander Kornienko9a857d22019-02-11 15:17:13 +00002082
Kristof Umann1a170322019-02-05 00:39:33 +00002083 pthread_mutex_t mtx;
Alexander Kornienko9a857d22019-02-11 15:17:13 +00002084
Kristof Umann1a170322019-02-05 00:39:33 +00002085 void test() {
2086 pthread_mutex_lock(&mtx);
2087 pthread_mutex_lock(&mtx);
2088 // warn: this lock has already been acquired
2089 }
Alexander Kornienko9a857d22019-02-11 15:17:13 +00002090
Kristof Umann1a170322019-02-05 00:39:33 +00002091 lck_mtx_t lck1, lck2;
Alexander Kornienko9a857d22019-02-11 15:17:13 +00002092
Kristof Umann1a170322019-02-05 00:39:33 +00002093 void test() {
2094 lck_mtx_lock(&lck1);
2095 lck_mtx_lock(&lck2);
2096 lck_mtx_unlock(&lck1);
2097 // warn: this was not the most recently acquired lock
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 if (lck_mtx_try_lock(&lck1) == 0)
2104 return;
Alexander Kornienko9a857d22019-02-11 15:17:13 +00002105
Kristof Umann1a170322019-02-05 00:39:33 +00002106 lck_mtx_lock(&lck2);
2107 lck_mtx_unlock(&lck1);
2108 // warn: this was not the most recently acquired lock
2109 }
2110
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +00002111.. _alpha-unix-SimpleStream:
2112
Kristof Umann1a170322019-02-05 00:39:33 +00002113alpha.unix.SimpleStream (C)
2114"""""""""""""""""""""""""""
2115Check for misuses of stream APIs. Check for misuses of stream APIs: ``fopen, fclose``
Alexander Kornienko9a857d22019-02-11 15:17:13 +00002116(demo checker, the subject of the demo (`Slides <http://llvm.org/devmtg/2012-11/Zaks-Rose-Checker24Hours.pdf>`_ ,
2117`Video <https://youtu.be/kdxlsP5QVPw>`_) by Anna Zaks and Jordan Rose presented at the
Kristof Umann1a170322019-02-05 00:39:33 +00002118`2012 LLVM Developers' Meeting <http://llvm.org/devmtg/2012-11/>`_).
2119
2120.. code-block:: c
2121
2122 void test() {
2123 FILE *F = fopen("myfile.txt", "w");
2124 } // warn: opened file is never closed
Alexander Kornienko9a857d22019-02-11 15:17:13 +00002125
Kristof Umann1a170322019-02-05 00:39:33 +00002126 void test() {
2127 FILE *F = fopen("myfile.txt", "w");
Alexander Kornienko9a857d22019-02-11 15:17:13 +00002128
Kristof Umann1a170322019-02-05 00:39:33 +00002129 if (F)
2130 fclose(F);
Alexander Kornienko9a857d22019-02-11 15:17:13 +00002131
Kristof Umann1a170322019-02-05 00:39:33 +00002132 fclose(F); // warn: closing a previously closed file stream
2133 }
2134
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +00002135.. _alpha-unix-Stream:
2136
Kristof Umann1a170322019-02-05 00:39:33 +00002137alpha.unix.Stream (C)
2138"""""""""""""""""""""
2139Check stream handling functions: ``fopen, tmpfile, fclose, fread, fwrite, fseek, ftell, rewind, fgetpos,``
2140``fsetpos, clearerr, feof, ferror, fileno``.
2141
2142.. code-block:: c
2143
2144 void test() {
2145 FILE *p = fopen("foo", "r");
2146 } // warn: opened file is never closed
Alexander Kornienko9a857d22019-02-11 15:17:13 +00002147
Kristof Umann1a170322019-02-05 00:39:33 +00002148 void test() {
2149 FILE *p = fopen("foo", "r");
2150 fseek(p, 1, SEEK_SET); // warn: stream pointer might be NULL
2151 fclose(p);
2152 }
Alexander Kornienko9a857d22019-02-11 15:17:13 +00002153
Kristof Umann1a170322019-02-05 00:39:33 +00002154 void test() {
2155 FILE *p = fopen("foo", "r");
Alexander Kornienko9a857d22019-02-11 15:17:13 +00002156
Kristof Umann1a170322019-02-05 00:39:33 +00002157 if (p)
2158 fseek(p, 1, 3);
2159 // warn: third arg should be SEEK_SET, SEEK_END, or SEEK_CUR
Alexander Kornienko9a857d22019-02-11 15:17:13 +00002160
Kristof Umann1a170322019-02-05 00:39:33 +00002161 fclose(p);
2162 }
Alexander Kornienko9a857d22019-02-11 15:17:13 +00002163
Kristof Umann1a170322019-02-05 00:39:33 +00002164 void test() {
2165 FILE *p = fopen("foo", "r");
2166 fclose(p);
2167 fclose(p); // warn: already closed
2168 }
Alexander Kornienko9a857d22019-02-11 15:17:13 +00002169
Kristof Umann1a170322019-02-05 00:39:33 +00002170 void test() {
2171 FILE *p = tmpfile();
2172 ftell(p); // warn: stream pointer might be NULL
2173 fclose(p);
2174 }
2175
2176
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +00002177.. _alpha-unix-cstring-BufferOverlap:
2178
Kristof Umann1a170322019-02-05 00:39:33 +00002179alpha.unix.cstring.BufferOverlap (C)
2180""""""""""""""""""""""""""""""""""""
2181Checks for overlap in two buffer arguments. Applies to: ``memcpy, mempcpy``.
2182
2183.. code-block:: c
2184
2185 void test() {
2186 int a[4] = {0};
2187 memcpy(a + 2, a + 1, 8); // warn
2188 }
2189
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +00002190.. _alpha-unix-cstring-NotNullTerminated:
2191
Kristof Umann1a170322019-02-05 00:39:33 +00002192alpha.unix.cstring.NotNullTerminated (C)
2193""""""""""""""""""""""""""""""""""""""""
2194Check for arguments which are not null-terminated strings; applies to: ``strlen, strnlen, strcpy, strncpy, strcat, strncat``.
2195
2196.. code-block:: c
Alexander Kornienko9a857d22019-02-11 15:17:13 +00002197
Kristof Umann1a170322019-02-05 00:39:33 +00002198 void test() {
2199 int y = strlen((char *)&test); // warn
2200 }
2201
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +00002202.. _alpha-unix-cstring-OutOfBounds:
2203
Kristof Umann1a170322019-02-05 00:39:33 +00002204alpha.unix.cstring.OutOfBounds (C)
2205""""""""""""""""""""""""""""""""""
2206Check for out-of-bounds access in string functions; applies to:`` strncopy, strncat``.
2207
2208
2209.. code-block:: c
Alexander Kornienko9a857d22019-02-11 15:17:13 +00002210
Kristof Umann1a170322019-02-05 00:39:33 +00002211 void test() {
2212 int y = strlen((char *)&test); // warn
2213 }
2214
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +00002215.. _alpha-nondeterminism-PointerIteration:
2216
Mandeep Singh Grang0cdc5dd2019-05-24 19:24:08 +00002217alpha.nondeterminism.PointerIteration (C++)
2218"""""""""""""""""""""""""""""""""""""""""""
2219Check for non-determinism caused by iterating unordered containers of pointers.
2220
2221.. code-block:: c
2222
2223 void test() {
2224 int a = 1, b = 2;
2225 std::unordered_set<int *> UnorderedPtrSet = {&a, &b};
2226
2227 for (auto i : UnorderedPtrSet) // warn
2228 f(i);
2229 }
2230
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +00002231.. _alpha-nondeterminism-PointerSorting:
2232
Mandeep Singh Grangc0773ab2019-03-08 20:13:53 +00002233alpha.nondeterminism.PointerSorting (C++)
Mandeep Singh Grangd4c4f742019-03-08 20:35:25 +00002234"""""""""""""""""""""""""""""""""""""""""
Mandeep Singh Grangc0773ab2019-03-08 20:13:53 +00002235Check for non-determinism caused by sorting of pointers.
2236
2237.. code-block:: c
2238
2239 void test() {
2240 int a = 1, b = 2;
2241 std::vector<int *> V = {&a, &b};
2242 std::sort(V.begin(), V.end()); // warn
2243 }
2244
Kristof Umann1a170322019-02-05 00:39:33 +00002245
2246Debug Checkers
2247---------------
2248
2249.. _debug-checkers:
2250
2251
2252debug
2253^^^^^
2254
2255Checkers used for debugging the analyzer.
Kristof Umanndccfaff2019-02-05 10:19:39 +00002256:doc:`developer-docs/DebugChecks` page contains a detailed description.
Kristof Umann1a170322019-02-05 00:39:33 +00002257
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +00002258.. _debug-AnalysisOrder:
2259
Kristof Umann1a170322019-02-05 00:39:33 +00002260debug.AnalysisOrder
2261"""""""""""""""""""
2262Print callbacks that are called during analysis in order.
2263
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +00002264.. _debug-ConfigDumper:
2265
Kristof Umann1a170322019-02-05 00:39:33 +00002266debug.ConfigDumper
2267""""""""""""""""""
2268Dump config table.
2269
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +00002270.. _debug-DumpCFG Display:
2271
Kristof Umann1a170322019-02-05 00:39:33 +00002272debug.DumpCFG Display
2273"""""""""""""""""""""
2274Control-Flow Graphs.
2275
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +00002276.. _debug-DumpCallGraph:
2277
Kristof Umann1a170322019-02-05 00:39:33 +00002278debug.DumpCallGraph
2279"""""""""""""""""""
2280Display Call Graph.
2281
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +00002282.. _debug-DumpCalls:
2283
Kristof Umann1a170322019-02-05 00:39:33 +00002284debug.DumpCalls
2285"""""""""""""""
2286Print calls as they are traversed by the engine.
2287
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +00002288.. _debug-DumpDominators:
2289
Kristof Umann1a170322019-02-05 00:39:33 +00002290debug.DumpDominators
2291""""""""""""""""""""
2292Print the dominance tree for a given CFG.
2293
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +00002294.. _debug-DumpLiveVars:
2295
Kristof Umann1a170322019-02-05 00:39:33 +00002296debug.DumpLiveVars
2297""""""""""""""""""
2298Print results of live variable analysis.
2299
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +00002300.. _debug-DumpTraversal:
2301
Kristof Umann1a170322019-02-05 00:39:33 +00002302debug.DumpTraversal
2303"""""""""""""""""""
2304Print branch conditions as they are traversed by the engine.
2305
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +00002306.. _debug-ExprInspection:
2307
Kristof Umann1a170322019-02-05 00:39:33 +00002308debug.ExprInspection
2309""""""""""""""""""""
2310Check the analyzer's understanding of expressions.
2311
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +00002312.. _debug-Stats:
2313
Kristof Umann1a170322019-02-05 00:39:33 +00002314debug.Stats
2315"""""""""""
2316Emit warnings with analyzer statistics.
2317
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +00002318.. _debug-TaintTest:
2319
Kristof Umann1a170322019-02-05 00:39:33 +00002320debug.TaintTest
2321"""""""""""""""
2322Mark tainted symbols as such.
2323
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +00002324.. _debug-ViewCFG:
2325
Kristof Umann1a170322019-02-05 00:39:33 +00002326debug.ViewCFG
2327"""""""""""""
2328View Control-Flow Graphs using GraphViz.
2329
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +00002330.. _debug-ViewCallGraph:
2331
Kristof Umann1a170322019-02-05 00:39:33 +00002332debug.ViewCallGraph
2333"""""""""""""""""""
2334View Call Graph using GraphViz.
2335
Nathan Huckleberry83c94bf2019-07-11 17:12:05 +00002336.. _debug-ViewExplodedGraph:
2337
Kristof Umann1a170322019-02-05 00:39:33 +00002338debug.ViewExplodedGraph
2339"""""""""""""""""""""""
2340View Exploded Graphs using GraphViz.
2341