Clang Project

clang_source_code/www/analyzer/alpha_checks.html
1<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
2          "http://www.w3.org/TR/html4/strict.dtd">
3<html>
4<head>
5  <title>Alpha Checks</title>
6  <link type="text/css" rel="stylesheet" href="menu.css">
7  <link type="text/css" rel="stylesheet" href="content.css">
8  <script type="text/javascript" src="scripts/menu.js"></script>
9  <script type="text/javascript" src="scripts/expandcollapse.js"></script>
10  <style type="text/css">
11  tr:first-child { width:20%; }
12  </style>
13</head>
14<body onload="initExpandCollapse()">
15
16<div id="page">
17<!--#include virtual="menu.html.incl"-->
18
19<div id="content">
20<h1>Alpha Checkers</h1>
21Experimental checkers in addition to the <a href = "available_checks.html">
22Default Checkers</a>. These are checkers with known issues or limitations that
23keep them from being on by default. They are likely to have false positives.
24Bug reports are welcome but will likely not be investigated for some time.
25Patches welcome!
26<ul>
27<li><a href="#clone_alpha_checkers">Clone Alpha Checkers</a></li>
28<li><a href="#core_alpha_checkers">Core Alpha Checkers</a></li>
29<li><a href="#cplusplus_alpha_checkers">C++ Alpha Checkers</a></li>
30<li><a href="#llvm_alpha_checkers">LLVM Checkers</a></li>
31<li><a href="#valist_alpha_checkers">Variable Argument Alpha Checkers</a></li>
32<li><a href="#deadcode_alpha_checkers">Dead Code Alpha Checkers</a></li>
33<li><a href="#osx_alpha_checkers">OS X Alpha Checkers</a></li>
34<li><a href="#security_alpha_checkers">Security Alpha Checkers</a></li>
35<li><a href="#unix_alpha_checkers">Unix Alpha Checkers</a></li>
36<li><a href="#nondeterminism_alpha_checkers">Non-determinism Alpha Checkers</a></li>
37</ul>
38
39<!-- ============================= clone alpha ============================= -->
40
41<h3 id="clone_alpha_checkers">Clone Alpha Checkers</h3>
42<table class="checkers">
43<colgroup><col class="namedescr"><col class="example"></colgroup>
44<thead><tr><td>Name, Description</td><td>Example</td></tr></thead>
45
46<tbody>
47<tr><td><a id="alpha.clone.CloneChecker"><div class="namedescr expandable"><span class="name">
48alpha.clone.CloneChecker</span><span class="lang">
49(C, C++, ObjC)</span><div class="descr">
50Reports similar pieces of code.</div></div></a></td>
51<td><div class="exampleContainer expandable">
52<div class="example"><pre>
53void log();
54
55int max(int a, int b) { // warn
56  log();
57  if (a > b)
58    return a;
59  return b;
60}
61
62int maxClone(int x, int y) { // similar code here
63  log();
64  if (x > y)
65    return x;
66  return y;
67}
68</pre></div></div></td></tr>
69</tbody></table>
70
71<!-- ============================= core alpha ============================= -->
72<h3 id="core_alpha_checkers">Core Alpha Checkers</h3>
73<table class="checkers">
74<colgroup><col class="namedescr"><col class="example"></colgroup>
75<thead><tr><td>Name, Description</td><td>Example</td></tr></thead>
76
77<tbody>
78<tr><td><a id="alpha.core.BoolAssignment"><div class="namedescr expandable"><span class="name">
79alpha.core.BoolAssignment</span><span class="lang">
80(ObjC)</span><div class="descr">
81Warn about assigning non-{0,1} values to boolean variables.</div></div></a></td>
82<td><div class="exampleContainer expandable">
83<div class="example"><pre>
84void test() {
85  BOOL b = -1; // warn
86}
87</pre></div></div></td></tr>
88
89
90<tr><td><a id="alpha.core.CallAndMessageUnInitRefArg"><div class="namedescr expandable"><span class="name">
91alpha.core.CallAndMessageUnInitRefArg</span><span class="lang">
92(C, C++)</span><div class="descr">
93Check for uninitialized arguments in function calls and Objective-C
94message expressions.</div></div></a></td>
95<td><div class="exampleContainer expandable">
96<div class="example"><pre>
97void test(void) {
98  int t;
99  int &p = t;
100  int &s = p;
101  int &q = s;
102  foo(q); // warn
103}
104</pre></div><div class="separator"></div>
105<div class="example"><pre>
106void test(void) {
107  int x;
108  foo(&x); // warn
109}
110</pre></div></div></td></tr>
111
112
113<tr><td><a id="alpha.core.CastSize"><div class="namedescr expandable"><span class="name">
114alpha.core.CastSize</span><span class="lang">
115(C)</span><div class="descr">
116Check when casting a malloc'ed type T, whether the size is a multiple of the
117size of T (Works only with <span class="name">unix.Malloc</span>
118or <span class="name">alpha.unix.MallocWithAnnotations</span>
119checks enabled).</div></div></a></td>
120<td><div class="exampleContainer expandable">
121<div class="example"><pre>
122void test() {
123  int *x = (int *)malloc(11); // warn
124}
125</pre></div></div></td></tr>
126
127
128<tr><td><a id="alpha.core.CastToStruct"><div class="namedescr expandable"><span class="name">
129alpha.core.CastToStruct</span><span class="lang">
130(C, C++)</span><div class="descr">
131Check for cast from non-struct pointer to struct pointer.</div></div></a></td>
132<td><div class="exampleContainer expandable">
133<div class="example"><pre>
134// C
135struct s {};
136
137void test(int *p) {
138  struct s *ps = (struct s *) p; // warn
139}
140</pre></div><div class="separator"></div>
141<div class="example"><pre>
142// C++
143class c {};
144
145void test(int *p) {
146  c *pc = (c *) p; // warn
147}
148</pre></div></div></td></tr>
149
150
151<tr><td><a id="alpha.core.Conversion"><div class="namedescr expandable"><span class="name">
152alpha.core.Conversion</span><span class="lang">
153(C, C++, ObjC)</span><div class="descr">
154Loss of sign or precision in implicit conversions</div></div></a></td>
155<td><div class="exampleContainer expandable">
156<div class="example"><pre>
157void test(unsigned U, signed S) {
158  if (S > 10) {
159    if (U < S) {
160    }
161  }
162  if (S < -10) {
163    if (U < S) { // warn (loss of sign)
164    }
165  }
166}
167</pre></div><div class="separator"></div>
168<div class="example"><pre>
169void test() {
170  long long A = 1LL << 60;
171  short X = A; // warn (loss of precision)
172}
173</pre></div></div></td></tr>
174
175
176<tr><td><a id="alpha.core.DynamicTypeChecker"><div class="namedescr expandable"><span class="name">
177alpha.core.DynamicTypeChecker</span><span class="lang">
178(ObjC)</span><div class="descr">
179Check for cases where the dynamic and the static type of an
180object are unrelated.</div></div></a></td>
181<td><div class="exampleContainer expandable">
182<div class="example"><pre>
183id date = [NSDate date];
184
185// Warning: Object has a dynamic type 'NSDate *' which is
186// incompatible with static type 'NSNumber *'"
187NSNumber *number = date;
188[number doubleValue];
189</pre></div></div></td></tr>
190
191
192<tr><td><a id="alpha.core.FixedAddr"><div class="namedescr expandable"><span class="name">
193alpha.core.FixedAddr</span><span class="lang">
194(C)</span><div class="descr">
195Check for assignment of a fixed address to a pointer.</div></div></a></td>
196<td><div class="exampleContainer expandable">
197<div class="example"><pre>
198void test() {
199  int *p;
200  p = (int *) 0x10000; // warn
201}
202</pre></div></div></td></tr>
203
204
205<tr><td><a id="alpha.core.IdenticalExpr"><div class="namedescr expandable"><span class="name">
206alpha.core.IdenticalExpr</span><span class="lang">
207(C, C++)</span><div class="descr">
208Warn about suspicious uses of identical expressions.</div></div></a></td>
209<td><div class="exampleContainer expandable">
210<div class="example"><pre>
211// C
212void test() {
213  int a = 5;
214  int b = a | 4 | a; // warn: identical expr on both sides
215}
216</pre></div><div class="separator"></div>
217<div class="example"><pre>
218// C++
219bool f(void);
220
221void test(bool b) {
222  int i = 10;
223  if (f()) { // warn: true and false branches are identical
224    do {
225      i--;
226    } while (f());
227  } else {
228    do {
229      i--;
230    } while (f());
231  }
232}
233</pre></div></div></td></tr>
234
235
236<tr><td><a id="alpha.core.PointerArithm"><div class="namedescr expandable"><span class="name">
237alpha.core.PointerArithm</span><span class="lang">
238(C)</span><div class="descr">
239Check for pointer arithmetic on locations other than array
240elements.</div></div></a></td>
241<td><div class="exampleContainer expandable">
242<div class="example"><pre>
243void test() {
244  int x;
245  int *p;
246  p = &amp;x + 1; // warn
247}
248</pre></div></div></td></tr>
249
250
251<tr><td><a id="alpha.core.PointerSub"><div class="namedescr expandable"><span class="name">
252alpha.core.PointerSub</span><span class="lang">
253(C)</span><div class="descr">
254Check for pointer subtractions on two pointers pointing to different memory
255chunks.</div></div></a></td>
256<td><div class="exampleContainer expandable">
257<div class="example"><pre>
258void test() {
259  int x, y;
260  int d = &amp;y - &amp;x; // warn
261}
262</pre></div></div></td></tr>
263
264
265<tr><td><a id="alpha.core.SizeofPtr"><div class="namedescr expandable"><span class="name">
266alpha.core.SizeofPtr</span><span class="lang">
267(C)</span><div class="descr">
268Warn about unintended use of <code>sizeof()</code> on pointer
269expressions.</div></div></a></td>
270<td><div class="exampleContainer expandable">
271<div class="example"><pre>
272struct s {};
273
274int test(struct s *p) {
275  return sizeof(p);
276    // warn: sizeof(ptr) can produce an unexpected result
277}
278</pre></div></div></td></tr>
279
280
281<tr><td><a id="alpha.core.StackAddressAsyncEscape"><div class="namedescr expandable"><span class="name">
282alpha.core.StackAddressAsyncEscape</span><span class="lang">
283(C)</span><div class="descr">
284Check that addresses to stack memory do not escape the function that involves
285<code>dispatch_after</code> or <code>dispatch_async</code>. This checker is
286a part of core.StackAddressEscape, but is
287<a href=https://reviews.llvm.org/D41042>temporarily disabled</a> until some
288false positives are fixed.</div></div></a></td>
289<td><div class="exampleContainer expandable">
290<div class="example"><pre>
291dispatch_block_t test_block_inside_block_async_leak() {
292  int x = 123;
293  void (^inner)(void) = ^void(void) {
294    int y = x;
295    ++y;
296  };
297  void (^outer)(void) = ^void(void) {
298    int z = x;
299    ++z;
300    inner();
301  };
302  return outer; // warn: address of stack-allocated block is captured by a
303                //       returned block
304}
305</pre></div></div></td></tr>
306
307
308<tr><td><a id="alpha.core.TestAfterDivZero"><div class="namedescr expandable"><span class="name">
309alpha.core.TestAfterDivZero</span><span class="lang">
310(C, C++, ObjC)</span><div class="descr">
311Check for division by variable that is later compared against 0.
312Either the comparison is useless or there is division by zero.
313</div></div></a></td>
314<td><div class="exampleContainer expandable">
315<div class="example"><pre>
316void test(int x) {
317  var = 77 / x;
318  if (x == 0) { } // warn
319}
320</pre></div></div></td></tr>
321
322
323</tbody></table>
324
325<!-- =========================== cplusplus alpha =========================== -->
326<h3 id="cplusplus_alpha_checkers">C++ Alpha Checkers</h3>
327<table class="checkers">
328<colgroup><col class="namedescr"><col class="example"></colgroup>
329<thead><tr><td>Name, Description</td><td>Example</td></tr></thead>
330<tbody>
331
332
333<tr><td><a id="alpha.cplusplus.DeleteWithNonVirtualDtor"><div class="namedescr expandable"><span class="name">
334alpha.cplusplus.DeleteWithNonVirtualDtor</span><span class="lang">
335(C++)</span><div class="descr">
336Reports destructions of polymorphic objects with a non-virtual destructor in
337their base class
338</div></div></a></td>
339<td><div class="exampleContainer expandable">
340<div class="example"><pre>
341NonVirtual *create() {
342  NonVirtual *x = new NVDerived(); // note: conversion from derived to base
343                                   //       happened here
344  return x;
345}
346
347void sink(NonVirtual *x) {
348  delete x; // warn: destruction of a polymorphic object with no virtual
349            //       destructor
350}
351</pre></div></div></td></tr>
352
353<tr><td><a id="alpha.cplusplus.EnumCastOutOfRange"><div class="namedescr expandable"><span class="name">
354alpha.cplusplus.EnumCastOutOfRange</span><span class="lang">
355(C++)</span><div class="descr">
356  Check for integer to enumeration casts that could result in undefined values.
357</div></div></a></td>
358  <td><div class="exampleContainer expandable">
359    <div class="example"><pre>
360enum TestEnum {
361  A = 0
362};
363
364void foo() {
365  TestEnum t = static_cast<TestEnum>(-1);
366      // warn: the value provided to the cast expression is not in
367               the valid range of values for the enum
368}
369</pre></div></div></td></tr>
370
371
372<tr><td><a id="alpha.cplusplus.InvalidatedIterator"><div class="namedescr expandable"><span class="name">
373alpha.cplusplus.InvalidatedIterator</span><span class="lang">
374(C++)</span><div class="descr">
375Check for use of invalidated iterators.
376</div></div></a></td>
377<td><div class="exampleContainer expandable">
378<div class="example"><pre>
379void bad_copy_assign_operator_list1(std::list<int> &L1,
380                                    const std::list<int> &L2) {
381  auto i0 = L1.cbegin();
382  L1 = L2;
383  *i0; // warn: invalidated iterator accessed
384}
385</pre></div></div></td></tr>
386
387
388<tr><td><a id="alpha.cplusplus.IteratorRange"><div class="namedescr expandable"><span class="name">
389alpha.cplusplus.IteratorRange</span><span class="lang">
390(C++)</span><div class="descr">
391Check for iterators used outside their valid ranges.
392</div></div></a></td>
393<td><div class="exampleContainer expandable">
394<div class="example"><pre>
395void simple_bad_end(const std::vector<int> &v) {
396  auto i = v.end();
397  *i; // warn: iterator accessed outside of its range
398}
399</pre></div></div></td></tr>
400
401
402<tr><td><a id="alpha.cplusplus.MismatchedIterator"><div class="namedescr expandable"><span class="name">
403alpha.cplusplus.MismatchedIterator</span><span class="lang">
404(C++)</span><div class="descr">
405Check for use of iterators of different containers where iterators of the same
406container are expected.
407</div></div></a></td>
408<td><div class="exampleContainer expandable">
409<div class="example"><pre>
410void bad_insert3(std::vector<int> &v1, std::vector<int> &v2) {
411  v2.insert(v1.cbegin(), v2.cbegin(), v2.cend()); // warn: container accessed
412                                                  //       using foreign
413                                                  //       iterator argument
414  v1.insert(v1.cbegin(), v1.cbegin(), v2.cend()); // warn: iterators of
415                                                  //       different containers
416                                                  //       used where the same
417                                                  //       container is
418                                                  //       expected
419  v1.insert(v1.cbegin(), v2.cbegin(), v1.cend()); // warn: iterators of
420                                                  //       different containers
421                                                  //       used where the same
422                                                  //       container is
423                                                  //       expected
424}
425</pre></div></div></td></tr>
426
427
428<tr><td><a id="alpha.cplusplus.Move"><div class="namedescr expandable"><span class="name">
429alpha.cplusplus.Move</span><span class="lang">
430(C++)</span><div class="descr">
431Method calls on a moved-from object and copying a moved-from object will be
432reported.
433</div></div></a></td>
434<td><div class="exampleContainer expandable">
435<div class="example"><pre>
436struct A {
437  void foo() {}
438};
439
440void f() {
441  A a;
442  A b = std::move(a); // note: 'a' became 'moved-from' here
443  a.foo();            // warn: method call on a 'moved-from' object 'a'
444}
445</pre></div></div></td></tr>
446
447
448<tr><td><a id="alpha.cplusplus.UninitializedObject"><div class="namedescr expandable"><span class="name">
449alpha.cplusplus.UninitializedObject</span><span class="lang">
450(C++)</span><div class="descr">
451This checker reports uninitialized fields in objects created after a constructor
452call. It doesn't only find direct uninitialized fields, but rather makes a deep
453inspection of the object, analyzing all of it's fields subfields. <br>
454The checker regards inherited fields as direct fields, so one will recieve
455warnings for uninitialized inherited data members as well. <br>
456<br>
457It has several options:
458<ul>
459  <li>
460    "<code>Pedantic</code>" (boolean). If its not set or is set to false, the
461    checker won't emit warnings for objects that don't have at least one
462    initialized field. This may be set with <br>
463    <code>-analyzer-config alpha.cplusplus.UninitializedObject:Pedantic=true</code>.
464  </li>
465  <li>
466    "<code>NotesAsWarnings</code>" (boolean). If set to true, the checker will
467    emit a warning for each uninitalized field, as opposed to emitting one
468    warning per constructor call, and listing the uninitialized fields that
469    belongs to it in notes. Defaults to false. <br>
470    <code>-analyzer-config alpha.cplusplus.UninitializedObject:NotesAsWarnings=true</code>.
471  </li>
472  <li>
473    "<code>CheckPointeeInitialization</code>" (boolean). If set to false, the
474    checker will not analyze the pointee of pointer/reference fields, and will
475    only check whether the object itself is initialized. Defaults to false. <br>
476    <code>-analyzer-config alpha.cplusplus.UninitializedObject:CheckPointeeInitialization=true</code>.
477  </li>
478  <li>
479    "<code>IgnoreRecordsWithField</code>" (string). If supplied, the checker
480    will not analyze structures that have a field with a name or type name that
481    matches the given pattern. Defaults to <code>""</code>.
482
483    <code>-analyzer-config alpha.cplusplus.UninitializedObject:IgnoreRecordsWithField="[Tt]ag|[Kk]ind"</code>.
484  </li>
485</ul></div></div></a></td>
486<td><div class="exampleContainer expandable">
487<div class="example"><pre>
488// With Pedantic and CheckPointeeInitialization set to true
489
490struct A {
491  struct B {
492    int x; // note: uninitialized field 'this->b.x'
493           // note: uninitialized field 'this->bptr->x'
494    int y; // note: uninitialized field 'this->b.y'
495           // note: uninitialized field 'this->bptr->y'
496  };
497  int *iptr; // note: uninitialized pointer 'this->iptr'
498  B b;
499  B *bptr;
500  char *cptr; // note: uninitialized pointee 'this->cptr'
501
502  A (B *bptr, char *cptr) : bptr(bptr), cptr(cptr) {}
503};
504
505void f() {
506  A::B b;
507  char c;
508  A a(&b, &c); // warning: 6 uninitialized fields
509               //          after the constructor call
510}
511</pre></div><div class="separator"></div>
512<div class="example"><pre>
513// With Pedantic set to false and
514// CheckPointeeInitialization set to true
515// (every field is uninitialized)
516
517struct A {
518  struct B {
519    int x;
520    int y;
521  };
522  int *iptr;
523  B b;
524  B *bptr;
525  char *cptr;
526
527  A (B *bptr, char *cptr) : bptr(bptr), cptr(cptr) {}
528};
529
530void f() {
531  A::B b;
532  char c;
533  A a(&b, &c); // no warning
534}
535</pre></div><div class="separator"></div>
536<div class="example"><pre>
537// With Pedantic and CheckPointeeInitialization set to false
538// (pointees are regarded as initialized)
539
540struct A {
541  struct B {
542    int x; // note: uninitialized field 'this->b.x'
543    int y; // note: uninitialized field 'this->b.y'
544  };
545  int *iptr; // note: uninitialized pointer 'this->iptr'
546  B b;
547  B *bptr;
548  char *cptr;
549
550  A (B *bptr, char *cptr) : bptr(bptr), cptr(cptr) {}
551};
552
553void f() {
554  A::B b;
555  char c;
556  A a(&b, &c); // warning: 3 uninitialized fields
557               //          after the constructor call
558}
559</pre></div></div></td></tr>
560
561
562</tbody></table>
563
564
565<!-- =========================== dead code alpha =========================== -->
566<h3 id="deadcode_alpha_checkers">Dead Code Alpha Checkers</h3>
567<table class="checkers">
568<colgroup><col class="namedescr"><col class="example"></colgroup>
569<thead><tr><td>Name, Description</td><td>Example</td></tr></thead>
570
571<tbody>
572<tr><td><a id="alpha.deadcode.UnreachableCode"><div class="namedescr expandable"><span class="name">
573alpha.deadcode.UnreachableCode</span><span class="lang">
574(C, C++, ObjC)</span><div class="descr">
575Check unreachable code.</div></div></a></td>
576<td><div class="exampleContainer expandable">
577<div class="example"><pre>
578// C
579int test() {
580  int x = 1;
581  while(x);
582  return x; // warn
583}
584</pre></div><div class="separator"></div>
585<div class="example"><pre>
586// C++
587void test() {
588  int a = 2;
589
590  while (a > 1)
591    a--;
592
593  if (a > 1)
594    a++; // warn
595}
596</pre></div><div class="separator"></div>
597<div class="example"><pre>
598// Objective-C
599void test(id x) {
600  return;
601  [x retain]; // warn
602}
603</pre></div></div></td></tr>
604</tbody></table>
605
606<!-- =========================== llvm alpha =========================== -->
607<h3 id="llvm_alpha_checkers">LLVM Checkers</h3>
608<table class="checkers">
609<colgroup><col class="namedescr"><col class="example"></colgroup>
610<thead><tr><td>Name, Description</td><td>Example</td></tr></thead>
611
612<tbody>
613<tr><td><a id="alpha.llvm.Conventions"><div class="namedescr expandable"><span class="name">
614alpha.llvm.Conventions</span><span class="lang">
615(C)</span><div class="descr">
616Check code for LLVM codebase conventions:
617<ul>
618  <li>A <code>StringRef</code> should not be bound to a temporary std::string
619  whose lifetime is shorter than the <code>StringRef</code>'s.</li>
620  <li>Clang AST nodes should not have fields that can allocate memory.</li>
621</ul>
622</div></div></a></td>
623<td><div class="exampleContainer expandable">
624<div class="example"><pre>
625<!-- TODO: Add examples, as currently it's hard to get this checker working. -->
626</pre></div></div></td></tr>
627
628</tbody></table>
629
630
631<!-- ============================== OS X alpha ============================== -->
632<h3 id="osx_alpha_checkers">OS X Alpha Checkers</h3>
633<table class="checkers">
634<colgroup><col class="namedescr"><col class="example"></colgroup>
635<thead><tr><td>Name, Description</td><td>Example</td></tr></thead>
636
637<tbody>
638<tr><td><a id="alpha.osx.cocoa.DirectIvarAssignment"><div class="namedescr expandable"><span class="name">
639alpha.osx.cocoa.DirectIvarAssignment</span><span class="lang">
640(ObjC)</span><div class="descr">
641Check that Objective C properties follow the following rule: the property
642should be set with the setter, not though a direct assignment.</div></div></a></td>
643<td><div class="exampleContainer expandable">
644<div class="example"><pre>
645@interface MyClass : NSObject {}
646@property (readonly) id A;
647- (void) foo;
648@end
649
650@implementation MyClass
651- (void) foo {
652  _A = 0; // warn
653}
654@end
655</pre></div></div></td></tr>
656
657
658<tr><td><a id="alpha.osx.cocoa.DirectIvarAssignmentForAnnotatedFunctions"><div class="namedescr expandable"><span class="name">
659alpha.osx.cocoa.DirectIvarAssignmentForAnnotatedFunctions</span><span class="lang">
660(ObjC)</span><div class="descr">
661Check for direct assignments to instance variables in the methods annotated
662with <code>objc_no_direct_instance_variable_assignment</code>.</div></div></a></td>
663<td><div class="exampleContainer expandable">
664<div class="example"><pre>
665@interface MyClass : NSObject {}
666@property (readonly) id A;
667- (void) fAnnotated __attribute__((
668    annotate("objc_no_direct_instance_variable_assignment")));
669- (void) fNotAnnotated;
670@end
671
672@implementation MyClass
673- (void) fAnnotated {
674  _A = 0; // warn
675}
676- (void) fNotAnnotated {
677  _A = 0; // no warn
678}
679@end
680</pre></div></div></td></tr>
681
682
683<tr><td><a id="alpha.osx.cocoa.InstanceVariableInvalidation"><div class="namedescr expandable"><span class="name">
684alpha.osx.cocoa.InstanceVariableInvalidation</span><span class="lang">
685(ObjC)</span><div class="descr">
686Check that the invalidatable instance variables are invalidated in the methods
687annotated with <code>objc_instance_variable_invalidator</code>.</div></div></a></td>
688<td><div class="exampleContainer expandable">
689<div class="example"><pre>
690@protocol Invalidation &lt;NSObject&gt;
691- (void) invalidate
692  __attribute__((annotate("objc_instance_variable_invalidator")));
693@end
694
695@interface InvalidationImpObj : NSObject &lt;Invalidation&gt;
696@end
697
698@interface SubclassInvalidationImpObj : InvalidationImpObj {
699  InvalidationImpObj *var;
700}
701- (void)invalidate;
702@end
703
704@implementation SubclassInvalidationImpObj
705- (void) invalidate {}
706@end
707// warn: var needs to be invalidated or set to nil
708</pre></div></div></td></tr>
709
710
711<tr><td><a id="alpha.osx.cocoa.MissingInvalidationMethod"><div class="namedescr expandable"><span class="name">
712alpha.osx.cocoa.MissingInvalidationMethod</span><span class="lang">
713(ObjC)</span><div class="descr">
714Check that the invalidation methods are present in classes that contain
715invalidatable instance variables.</div></div></a></td>
716<td><div class="exampleContainer expandable">
717<div class="example"><pre>
718@protocol Invalidation &lt;NSObject&gt;
719- (void)invalidate
720  __attribute__((annotate("objc_instance_variable_invalidator")));
721@end
722
723@interface NeedInvalidation : NSObject &lt;Invalidation&gt;
724@end
725
726@interface MissingInvalidationMethodDecl : NSObject {
727  NeedInvalidation *Var; // warn
728}
729@end
730
731@implementation MissingInvalidationMethodDecl
732@end
733</pre></div></div></td></tr>
734
735
736<tr><td><a id="alpha.osx.cocoa.localizability.PluralMisuseChecker"><div class="namedescr expandable"><span class="name">
737alpha.osx.cocoa.localizability.PluralMisuseChecker</span><span class="lang">
738(ObjC)</span><div class="descr">
739Warns against using one vs. many plural pattern in code
740when generating localized strings.
741</div></div></a></td>
742<td><div class="exampleContainer expandable">
743<div class="example"><pre>
744NSString *reminderText =
745  NSLocalizedString(@"None", @"Indicates no reminders");
746if (reminderCount == 1) {
747  // Warning: Plural cases are not supported across all languages.
748  // Use a .stringsdict file instead
749  reminderText =
750    NSLocalizedString(@"1 Reminder", @"Indicates single reminder");
751} else if (reminderCount >= 2) {
752  // Warning: Plural cases are not supported across all languages.
753  // Use a .stringsdict file instead
754  reminderText =
755    [NSString stringWithFormat:
756      NSLocalizedString(@"%@ Reminders", @"Indicates multiple reminders"),
757        reminderCount];
758}
759</pre></div></div></td></tr>
760
761</tbody></table>
762
763<!-- =========================== security alpha =========================== -->
764<h3 id="security_alpha_checkers">Security Alpha Checkers</h3>
765<table class="checkers">
766<colgroup><col class="namedescr"><col class="example"></colgroup>
767<thead><tr><td>Name, Description</td><td>Example</td></tr></thead>
768
769<tbody>
770<tr><td><a id="alpha.security.ArrayBound"><div class="namedescr expandable"><span class="name">
771alpha.security.ArrayBound</span><span class="lang">
772(C)</span><div class="descr">
773Warn about buffer overflows (older checker).</div></div></a></td>
774<td><div class="exampleContainer expandable">
775<div class="example"><pre>
776void test() {
777  char *s = "";
778  char c = s[1]; // warn
779}
780</pre></div><div class="separator"></div>
781<div class="example"><pre>
782struct seven_words {
783  int c[7];
784};
785
786void test() {
787  struct seven_words a, *p;
788  p = &a;
789  p[0] = a;
790  p[1] = a;
791  p[2] = a; // warn
792}
793</pre></div><div class="separator"></div>
794<div class="example"><pre>
795// note: requires unix.Malloc or
796// alpha.unix.MallocWithAnnotations checks enabled.
797void test() {
798  int *p = malloc(12);
799  p[3] = 4; // warn
800}
801</pre></div><div class="separator"></div>
802<div class="example"><pre>
803void test() {
804  char a[2];
805  int *b = (int*)a;
806  b[1] = 3; // warn
807}
808</pre></div></div></td></tr>
809
810
811<tr><td><a id="alpha.security.ArrayBoundV2"><div class="namedescr expandable"><span class="name">
812alpha.security.ArrayBoundV2</span><span class="lang">
813(C)</span><div class="descr">
814Warn about buffer overflows (newer checker).</div></div></a></td>
815<td><div class="exampleContainer expandable">
816<div class="example"><pre>
817void test() {
818  char *s = "";
819  char c = s[1]; // warn
820}
821</pre></div><div class="separator"></div>
822<div class="example"><pre>
823void test() {
824  int buf[100];
825  int *p = buf;
826  p = p + 99;
827  p[1] = 1; // warn
828}
829</pre></div><div class="separator"></div>
830<div class="example"><pre>
831// note: compiler has internal check for this.
832// Use -Wno-array-bounds to suppress compiler warning.
833void test() {
834  int buf[100][100];
835  buf[0][-1] = 1; // warn
836}
837</pre></div><div class="separator"></div>
838<div class="example"><pre>
839// note: requires alpha.security.taint check turned on.
840void test() {
841  char s[] = "abc";
842  int x = getchar();
843  char c = s[x]; // warn: index is tainted
844}
845</pre></div></div></td></tr>
846
847
848<tr><td><a id="alpha.security.MallocOverflow"><div class="namedescr expandable"><span class="name">
849alpha.security.MallocOverflow</span><span class="lang">
850(C)</span><div class="descr">
851Check for overflows in the arguments to <code>malloc()</code>.</div></div></a></td>
852<td><div class="exampleContainer expandable">
853<div class="example"><pre>
854void test(int n) {
855  void *p = malloc(n * sizeof(int)); // warn
856}
857</pre></div></div></td></tr>
858
859
860<tr><td><a id="alpha.security.MmapWriteExec"><div class="namedescr expandable"><span class="name">
861alpha.security.MmapWriteExec</span><span class="lang">
862(C)</span><div class="descr">
863Warn on <code>mmap()<code> calls that are both writable and executable.
864</div></div></a></td>
865<td><div class="exampleContainer expandable">
866<div class="example"><pre>
867void test(int n) {
868  void *c = mmap(NULL, 32, PROT_READ | PROT_WRITE | PROT_EXEC,
869                 MAP_PRIVATE | MAP_ANON, -1, 0);
870  // warn: Both PROT_WRITE and PROT_EXEC flags are set. This can lead to
871  //       exploitable memory regions, which could be overwritten with malicious
872  //       code
873}
874</pre></div></div></td></tr>
875
876
877<tr><td><a id="alpha.security.ReturnPtrRange"><div class="namedescr expandable"><span class="name">
878alpha.security.ReturnPtrRange</span><span class="lang">
879(C)</span><div class="descr">
880Check for an out-of-bound pointer being returned to callers.</div></div></a></td>
881<td><div class="exampleContainer expandable">
882<div class="example"><pre>
883static int A[10];
884
885int *test() {
886  int *p = A + 10;
887  return p; // warn
888}
889</pre></div><div class="separator"></div>
890<div class="example"><pre>
891int test(void) {
892  int x;
893  return x; // warn: undefined or garbage returned
894}
895</pre></div></div></td></tr>
896
897
898<tr><td><a id="alpha.security.taint.TaintPropagation"><div class="namedescr expandable"><span class="name">
899alpha.security.taint.TaintPropagation</span><span class="lang">
900(C)</span><div class="descr">
901Generate taint information used by other checkers.</div></div></a></td>
902<td><div class="exampleContainer expandable">
903<div class="example"><pre>
904void test() {
905  char x = getchar(); // 'x' marked as tainted
906  system(&x); // warn: untrusted data is passed to a system call
907}
908</pre></div><div class="separator"></div>
909<div class="example"><pre>
910// note: compiler internally checks if the second param to
911// sprintf is a string literal or not.
912// Use -Wno-format-security to suppress compiler warning.
913void test() {
914  char s[10], buf[10];
915  fscanf(stdin, "%s", s); // 's' marked as tainted
916
917  sprintf(buf, s); // warn: untrusted data as a format string
918}
919</pre></div><div class="separator"></div>
920<div class="example"><pre>
921void test() {
922  size_t ts;
923  scanf("%zd", &ts); // 'ts' marked as tainted
924  int *p = (int *)malloc(ts * sizeof(int));
925    // warn: untrusted data as buffer size
926}
927</pre></div></div></td></tr>
928
929</tbody></table>
930
931<!-- ============================= unix alpha ============================= -->
932<h3 id="unix_alpha_checkers">Unix Alpha Checkers</h3>
933<table class="checkers">
934<colgroup><col class="namedescr"><col class="example"></colgroup>
935<thead><tr><td>Name, Description</td><td>Example</td></tr></thead>
936<tbody>
937
938
939<tr><td><a id="alpha.unix.BlockInCriticalSection"><div class="namedescr expandable"><span class="name">
940alpha.unix.BlockInCriticalSection</span><span class="lang">
941(C)</span><div class="descr">
942Check for calls to blocking functions inside a critical section. Applies to:
943<div class=functions>
944lock<br>
945unlock<br>
946sleep<br>
947getc<br>
948fgets<br>
949read<br>
950revc<br>
951pthread_mutex_lock<br>
952pthread_mutex_unlock<br>
953mtx_lock<br>
954mtx_timedlock<br>
955mtx_trylock<br>
956mtx_unlock<br>
957lock_guard<br>
958unique_lock</div>
959</div></div></a></td>
960<td><div class="exampleContainer expandable">
961<div class="example"><pre>
962void test() {
963  std::mutex m;
964  m.lock();
965  sleep(3); // warn: a blocking function sleep is called inside a critical
966            //       section
967  m.unlock();
968}
969</pre></div></div></td></tr>
970
971
972<tr><td><a id="alpha.unix.Chroot"><div class="namedescr expandable"><span class="name">
973alpha.unix.Chroot</span><span class="lang">
974(C)</span><div class="descr">
975Check improper use of <code>chroot</code>.</div></div></a></td>
976<td><div class="exampleContainer expandable">
977<div class="example"><pre>
978void f();
979
980void test() {
981  chroot("/usr/local");
982  f(); // warn: no call of chdir("/") immediately after chroot
983}
984</pre></div></div></td></tr>
985
986
987<tr><td><a id="alpha.unix.PthreadLock"><div class="namedescr expandable"><span class="name">
988alpha.unix.PthreadLock</span><span class="lang">
989(C)</span><div class="descr">
990Simple lock -> unlock checker; applies to:<div class=functions>
991pthread_mutex_lock<br>
992pthread_rwlock_rdlock<br>
993pthread_rwlock_wrlock<br>
994lck_mtx_lock<br>
995lck_rw_lock_exclusive<br>
996lck_rw_lock_shared<br>
997pthread_mutex_trylock<br>
998pthread_rwlock_tryrdlock<br>
999pthread_rwlock_tryrwlock<br>
1000lck_mtx_try_lock<br>
1001lck_rw_try_lock_exclusive<br>
1002lck_rw_try_lock_shared<br>
1003pthread_mutex_unlock<br>
1004pthread_rwlock_unlock<br>
1005lck_mtx_unlock<br>
1006lck_rw_done</div></div></div></a></td>
1007<td><div class="exampleContainer expandable">
1008<div class="example"><pre>
1009pthread_mutex_t mtx;
1010
1011void test() {
1012  pthread_mutex_lock(&mtx);
1013  pthread_mutex_lock(&mtx);
1014    // warn: this lock has already been acquired
1015}
1016</pre></div><div class="separator"></div>
1017<div class="example"><pre>
1018lck_mtx_t lck1, lck2;
1019
1020void test() {
1021  lck_mtx_lock(&lck1);
1022  lck_mtx_lock(&lck2);
1023  lck_mtx_unlock(&lck1);
1024    // warn: this was not the most recently acquired lock
1025}
1026</pre></div><div class="separator"></div>
1027<div class="example"><pre>
1028lck_mtx_t lck1, lck2;
1029
1030void test() {
1031  if (lck_mtx_try_lock(&lck1) == 0)
1032    return;
1033
1034  lck_mtx_lock(&lck2);
1035  lck_mtx_unlock(&lck1);
1036    // warn: this was not the most recently acquired lock
1037}
1038</pre></div></div></td></tr>
1039
1040
1041<tr><td><a id="alpha.unix.SimpleStream"><div class="namedescr expandable"><span class="name">
1042alpha.unix.SimpleStream</span><span class="lang">
1043(C)</span><div class="descr">
1044Check for misuses of stream APIs:<div class=functions>
1045fopen<br>
1046fclose</div>(demo checker, the subject of the demo
1047(<a href="http://llvm.org/devmtg/2012-11/Zaks-Rose-Checker24Hours.pdf">Slides</a>
1048,<a href="https://youtu.be/kdxlsP5QVPw">Video</a>)
1049by Anna Zaks and Jordan Rose presented at the <a href="http://llvm.org/devmtg/2012-11/">
10502012 LLVM Developers' Meeting).</a></div></div></a></td>
1051<td><div class="exampleContainer expandable">
1052<div class="example"><pre>
1053void test() {
1054  FILE *F = fopen("myfile.txt", "w");
1055} // warn: opened file is never closed
1056</pre></div><div class="separator"></div>
1057<div class="example"><pre>
1058void test() {
1059  FILE *F = fopen("myfile.txt", "w");
1060
1061  if (F)
1062    fclose(F);
1063
1064  fclose(F); // warn: closing a previously closed file stream
1065}
1066</pre></div></div></td></tr>
1067
1068
1069<tr><td><a id="alpha.unix.Stream"><div class="namedescr expandable"><span class="name">
1070alpha.unix.Stream</span><span class="lang">
1071(C)</span><div class="descr">
1072Check stream handling functions:<div class=functions>fopen<br>
1073tmpfile<br>
1074fclose<br>
1075fread<br>
1076fwrite<br>
1077fseek<br>
1078ftell<br>
1079rewind<br>
1080fgetpos<br>
1081fsetpos<br>
1082clearerr<br>
1083feof<br>
1084ferror<br>
1085fileno</div></div></div></a></td>
1086<td><div class="exampleContainer expandable">
1087<div class="example"><pre>
1088void test() {
1089  FILE *p = fopen("foo", "r");
1090} // warn: opened file is never closed
1091</pre></div><div class="separator"></div>
1092<div class="example"><pre>
1093void test() {
1094  FILE *p = fopen("foo", "r");
1095  fseek(p, 1, SEEK_SET); // warn: stream pointer might be NULL
1096  fclose(p);
1097}
1098</pre></div><div class="separator"></div>
1099<div class="example"><pre>
1100void test() {
1101  FILE *p = fopen("foo", "r");
1102
1103  if (p)
1104    fseek(p, 1, 3);
1105     // warn: third arg should be SEEK_SET, SEEK_END, or SEEK_CUR
1106
1107  fclose(p);
1108}
1109</pre></div><div class="separator"></div>
1110<div class="example"><pre>
1111void test() {
1112  FILE *p = fopen("foo", "r");
1113  fclose(p);
1114  fclose(p); // warn: already closed
1115}
1116</pre></div><div class="separator"></div>
1117<div class="example"><pre>
1118void test() {
1119  FILE *p = tmpfile();
1120  ftell(p); // warn: stream pointer might be NULL
1121  fclose(p);
1122}
1123</pre></div></div></td></tr>
1124
1125
1126<tr><td><a id="alpha.unix.cstring.BufferOverlap"><div class="namedescr expandable"><span class="name">
1127alpha.unix.cstring.BufferOverlap</span><span class="lang">
1128(C)</span><div class="descr">
1129Checks for overlap in two buffer arguments; applies to:<div class=functions>
1130memcpy<br>
1131mempcpy</div></div></div></a></td>
1132<td><div class="exampleContainer expandable">
1133<div class="example"><pre>
1134void test() {
1135  int a[4] = {0};
1136  memcpy(a + 2, a + 1, 8); // warn
1137}
1138</pre></div></div></td></tr>
1139
1140
1141<tr><td><a id="alpha.unix.cstring.NotNullTerminated"><div class="namedescr expandable"><span class="name">
1142alpha.unix.cstring.NotNullTerminated</span><span class="lang">
1143(C)</span><div class="descr">
1144Check for arguments which are not null-terminated strings; applies
1145to:<div class=functions>
1146strlen<br>
1147strnlen<br>
1148strcpy<br>
1149strncpy<br>
1150strcat<br>
1151strncat</div></div></div></td>
1152<td><div class="exampleContainer expandable">
1153<div class="example"><pre>
1154void test() {
1155  int y = strlen((char *)&test); // warn
1156}
1157</pre></div></div></a></td></tr>
1158
1159
1160<tr><td><a id="alpha.unix.cstring.OutOfBounds"><div class="namedescr expandable"><span class="name">
1161alpha.unix.cstring.OutOfBounds</span><span class="lang">
1162(C)</span><div class="descr">
1163Check for out-of-bounds access in string functions; applies
1164to:<div class=functions>
1165strncopy<br>
1166strncat</div></div></div></a></td>
1167<td><div class="exampleContainer expandable">
1168<div class="example"><pre>
1169void test(char *y) {
1170  char x[4];
1171  if (strlen(y) == 4)
1172    strncpy(x, y, 5); // warn
1173}
1174</pre></div></div></td></tr>
1175
1176</tbody></table>
1177
1178<!-- =========================== nondeterminism alpha =========================== -->
1179<h3 id="nondeterminism_alpha_checkers">Non-determinism Alpha Checkers</h3>
1180<table class="checkers">
1181<colgroup><col class="namedescr"><col class="example"></colgroup>
1182<thead><tr><td>Name, Description</td><td>Example</td></tr></thead>
1183
1184<tbody>
1185<tr><td><a id="alpha.nondeterminism.PointerSorting"><div class="namedescr expandable"><span class="name">
1186alpha.nondeterminism.PointerSorting</span><span class="lang">
1187(C++)</span><div class="descr">
1188Check for non-determinism caused by sorting of pointers.</div></div></a></td>
1189<td><div class="exampleContainer expandable">
1190<div class="example"><pre>
1191// C++
1192void test() {
1193 int a = 1, b = 2;
1194 std::vector<int *> V = {&a, &b};
1195 std::sort(V.begin(), V.end()); // warn
1196}
1197</pre></div></div></td></tr>
1198</tbody></table>
1199
1200</div> <!-- page -->
1201</div> <!-- content -->
1202</body>
1203</html>
1204