• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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</tbody></table>
449
450
451<!-- =========================== dead code alpha =========================== -->
452<h3 id="deadcode_alpha_checkers">Dead Code Alpha Checkers</h3>
453<table class="checkers">
454<colgroup><col class="namedescr"><col class="example"></colgroup>
455<thead><tr><td>Name, Description</td><td>Example</td></tr></thead>
456
457<tbody>
458<tr><td><a id="alpha.deadcode.UnreachableCode"><div class="namedescr expandable"><span class="name">
459alpha.deadcode.UnreachableCode</span><span class="lang">
460(C, C++, ObjC)</span><div class="descr">
461Check unreachable code.</div></div></a></td>
462<td><div class="exampleContainer expandable">
463<div class="example"><pre>
464// C
465int test() {
466  int x = 1;
467  while(x);
468  return x; // warn
469}
470</pre></div><div class="separator"></div>
471<div class="example"><pre>
472// C++
473void test() {
474  int a = 2;
475
476  while (a > 1)
477    a--;
478
479  if (a > 1)
480    a++; // warn
481}
482</pre></div><div class="separator"></div>
483<div class="example"><pre>
484// Objective-C
485void test(id x) {
486  return;
487  [x retain]; // warn
488}
489</pre></div></div></td></tr>
490</tbody></table>
491
492<!-- =========================== llvm alpha =========================== -->
493<h3 id="llvm_alpha_checkers">LLVM Checkers</h3>
494<table class="checkers">
495<colgroup><col class="namedescr"><col class="example"></colgroup>
496<thead><tr><td>Name, Description</td><td>Example</td></tr></thead>
497
498<tbody>
499<tr><td><a id="alpha.llvm.Conventions"><div class="namedescr expandable"><span class="name">
500alpha.llvm.Conventions</span><span class="lang">
501(C)</span><div class="descr">
502Check code for LLVM codebase conventions:
503<ul>
504  <li>A <code>StringRef</code> should not be bound to a temporary std::string
505  whose lifetime is shorter than the <code>StringRef</code>'s.</li>
506  <li>Clang AST nodes should not have fields that can allocate memory.</li>
507</ul>
508</div></div></a></td>
509<td><div class="exampleContainer expandable">
510<div class="example"><pre>
511<!-- TODO: Add examples, as currently it's hard to get this checker working. -->
512</pre></div></div></td></tr>
513
514</tbody></table>
515
516
517<!-- ============================== OS X alpha ============================== -->
518<h3 id="osx_alpha_checkers">OS X Alpha Checkers</h3>
519<table class="checkers">
520<colgroup><col class="namedescr"><col class="example"></colgroup>
521<thead><tr><td>Name, Description</td><td>Example</td></tr></thead>
522
523<tbody>
524<tr><td><a id="alpha.osx.cocoa.DirectIvarAssignment"><div class="namedescr expandable"><span class="name">
525alpha.osx.cocoa.DirectIvarAssignment</span><span class="lang">
526(ObjC)</span><div class="descr">
527Check that Objective C properties follow the following rule: the property
528should be set with the setter, not though a direct assignment.</div></div></a></td>
529<td><div class="exampleContainer expandable">
530<div class="example"><pre>
531@interface MyClass : NSObject {}
532@property (readonly) id A;
533- (void) foo;
534@end
535
536@implementation MyClass
537- (void) foo {
538  _A = 0; // warn
539}
540@end
541</pre></div></div></td></tr>
542
543
544<tr><td><a id="alpha.osx.cocoa.DirectIvarAssignmentForAnnotatedFunctions"><div class="namedescr expandable"><span class="name">
545alpha.osx.cocoa.DirectIvarAssignmentForAnnotatedFunctions</span><span class="lang">
546(ObjC)</span><div class="descr">
547Check for direct assignments to instance variables in the methods annotated
548with <code>objc_no_direct_instance_variable_assignment</code>.</div></div></a></td>
549<td><div class="exampleContainer expandable">
550<div class="example"><pre>
551@interface MyClass : NSObject {}
552@property (readonly) id A;
553- (void) fAnnotated __attribute__((
554    annotate("objc_no_direct_instance_variable_assignment")));
555- (void) fNotAnnotated;
556@end
557
558@implementation MyClass
559- (void) fAnnotated {
560  _A = 0; // warn
561}
562- (void) fNotAnnotated {
563  _A = 0; // no warn
564}
565@end
566</pre></div></div></td></tr>
567
568
569<tr><td><a id="alpha.osx.cocoa.InstanceVariableInvalidation"><div class="namedescr expandable"><span class="name">
570alpha.osx.cocoa.InstanceVariableInvalidation</span><span class="lang">
571(ObjC)</span><div class="descr">
572Check that the invalidatable instance variables are invalidated in the methods
573annotated with <code>objc_instance_variable_invalidator</code>.</div></div></a></td>
574<td><div class="exampleContainer expandable">
575<div class="example"><pre>
576@protocol Invalidation &lt;NSObject&gt;
577- (void) invalidate
578  __attribute__((annotate("objc_instance_variable_invalidator")));
579@end
580
581@interface InvalidationImpObj : NSObject &lt;Invalidation&gt;
582@end
583
584@interface SubclassInvalidationImpObj : InvalidationImpObj {
585  InvalidationImpObj *var;
586}
587- (void)invalidate;
588@end
589
590@implementation SubclassInvalidationImpObj
591- (void) invalidate {}
592@end
593// warn: var needs to be invalidated or set to nil
594</pre></div></div></td></tr>
595
596
597<tr><td><a id="alpha.osx.cocoa.MissingInvalidationMethod"><div class="namedescr expandable"><span class="name">
598alpha.osx.cocoa.MissingInvalidationMethod</span><span class="lang">
599(ObjC)</span><div class="descr">
600Check that the invalidation methods are present in classes that contain
601invalidatable instance variables.</div></div></a></td>
602<td><div class="exampleContainer expandable">
603<div class="example"><pre>
604@protocol Invalidation &lt;NSObject&gt;
605- (void)invalidate
606  __attribute__((annotate("objc_instance_variable_invalidator")));
607@end
608
609@interface NeedInvalidation : NSObject &lt;Invalidation&gt;
610@end
611
612@interface MissingInvalidationMethodDecl : NSObject {
613  NeedInvalidation *Var; // warn
614}
615@end
616
617@implementation MissingInvalidationMethodDecl
618@end
619</pre></div></div></td></tr>
620
621
622<tr><td><a id="alpha.osx.cocoa.localizability.PluralMisuseChecker"><div class="namedescr expandable"><span class="name">
623alpha.osx.cocoa.localizability.PluralMisuseChecker</span><span class="lang">
624(ObjC)</span><div class="descr">
625Warns against using one vs. many plural pattern in code
626when generating localized strings.
627</div></div></a></td>
628<td><div class="exampleContainer expandable">
629<div class="example"><pre>
630NSString *reminderText =
631  NSLocalizedString(@"None", @"Indicates no reminders");
632if (reminderCount == 1) {
633  // Warning: Plural cases are not supported across all languages.
634  // Use a .stringsdict file instead
635  reminderText =
636    NSLocalizedString(@"1 Reminder", @"Indicates single reminder");
637} else if (reminderCount >= 2) {
638  // Warning: Plural cases are not supported across all languages.
639  // Use a .stringsdict file instead
640  reminderText =
641    [NSString stringWithFormat:
642      NSLocalizedString(@"%@ Reminders", @"Indicates multiple reminders"),
643        reminderCount];
644}
645</pre></div></div></td></tr>
646
647</tbody></table>
648
649<!-- =========================== security alpha =========================== -->
650<h3 id="security_alpha_checkers">Security Alpha Checkers</h3>
651<table class="checkers">
652<colgroup><col class="namedescr"><col class="example"></colgroup>
653<thead><tr><td>Name, Description</td><td>Example</td></tr></thead>
654
655<tbody>
656<tr><td><a id="alpha.security.ArrayBound"><div class="namedescr expandable"><span class="name">
657alpha.security.ArrayBound</span><span class="lang">
658(C)</span><div class="descr">
659Warn about buffer overflows (older checker).</div></div></a></td>
660<td><div class="exampleContainer expandable">
661<div class="example"><pre>
662void test() {
663  char *s = "";
664  char c = s[1]; // warn
665}
666</pre></div><div class="separator"></div>
667<div class="example"><pre>
668struct seven_words {
669  int c[7];
670};
671
672void test() {
673  struct seven_words a, *p;
674  p = &a;
675  p[0] = a;
676  p[1] = a;
677  p[2] = a; // warn
678}
679</pre></div><div class="separator"></div>
680<div class="example"><pre>
681// note: requires unix.Malloc or
682// alpha.unix.MallocWithAnnotations checks enabled.
683void test() {
684  int *p = malloc(12);
685  p[3] = 4; // warn
686}
687</pre></div><div class="separator"></div>
688<div class="example"><pre>
689void test() {
690  char a[2];
691  int *b = (int*)a;
692  b[1] = 3; // warn
693}
694</pre></div></div></td></tr>
695
696
697<tr><td><a id="alpha.security.ArrayBoundV2"><div class="namedescr expandable"><span class="name">
698alpha.security.ArrayBoundV2</span><span class="lang">
699(C)</span><div class="descr">
700Warn about buffer overflows (newer checker).</div></div></a></td>
701<td><div class="exampleContainer expandable">
702<div class="example"><pre>
703void test() {
704  char *s = "";
705  char c = s[1]; // warn
706}
707</pre></div><div class="separator"></div>
708<div class="example"><pre>
709void test() {
710  int buf[100];
711  int *p = buf;
712  p = p + 99;
713  p[1] = 1; // warn
714}
715</pre></div><div class="separator"></div>
716<div class="example"><pre>
717// note: compiler has internal check for this.
718// Use -Wno-array-bounds to suppress compiler warning.
719void test() {
720  int buf[100][100];
721  buf[0][-1] = 1; // warn
722}
723</pre></div><div class="separator"></div>
724<div class="example"><pre>
725// note: requires alpha.security.taint check turned on.
726void test() {
727  char s[] = "abc";
728  int x = getchar();
729  char c = s[x]; // warn: index is tainted
730}
731</pre></div></div></td></tr>
732
733
734<tr><td><a id="alpha.security.MallocOverflow"><div class="namedescr expandable"><span class="name">
735alpha.security.MallocOverflow</span><span class="lang">
736(C)</span><div class="descr">
737Check for overflows in the arguments to <code>malloc()</code>.</div></div></a></td>
738<td><div class="exampleContainer expandable">
739<div class="example"><pre>
740void test(int n) {
741  void *p = malloc(n * sizeof(int)); // warn
742}
743</pre></div></div></td></tr>
744
745
746<tr><td><a id="alpha.security.MmapWriteExec"><div class="namedescr expandable"><span class="name">
747alpha.security.MmapWriteExec</span><span class="lang">
748(C)</span><div class="descr">
749Warn on <code>mmap()<code> calls that are both writable and executable.
750</div></div></a></td>
751<td><div class="exampleContainer expandable">
752<div class="example"><pre>
753void test(int n) {
754  void *c = mmap(NULL, 32, PROT_READ | PROT_WRITE | PROT_EXEC,
755                 MAP_PRIVATE | MAP_ANON, -1, 0);
756  // warn: Both PROT_WRITE and PROT_EXEC flags are set. This can lead to
757  //       exploitable memory regions, which could be overwritten with malicious
758  //       code
759}
760</pre></div></div></td></tr>
761
762
763<tr><td><a id="alpha.security.ReturnPtrRange"><div class="namedescr expandable"><span class="name">
764alpha.security.ReturnPtrRange</span><span class="lang">
765(C)</span><div class="descr">
766Check for an out-of-bound pointer being returned to callers.</div></div></a></td>
767<td><div class="exampleContainer expandable">
768<div class="example"><pre>
769static int A[10];
770
771int *test() {
772  int *p = A + 10;
773  return p; // warn
774}
775</pre></div><div class="separator"></div>
776<div class="example"><pre>
777int test(void) {
778  int x;
779  return x; // warn: undefined or garbage returned
780}
781</pre></div></div></td></tr>
782
783
784<tr><td><a id="alpha.security.taint.TaintPropagation"><div class="namedescr expandable"><span class="name">
785alpha.security.taint.TaintPropagation</span><span class="lang">
786(C)</span><div class="descr">
787Generate taint information used by other checkers.</div></div></a></td>
788<td><div class="exampleContainer expandable">
789<div class="example"><pre>
790void test() {
791  char x = getchar(); // 'x' marked as tainted
792  system(&x); // warn: untrusted data is passed to a system call
793}
794</pre></div><div class="separator"></div>
795<div class="example"><pre>
796// note: compiler internally checks if the second param to
797// sprintf is a string literal or not.
798// Use -Wno-format-security to suppress compiler warning.
799void test() {
800  char s[10], buf[10];
801  fscanf(stdin, "%s", s); // 's' marked as tainted
802
803  sprintf(buf, s); // warn: untrusted data as a format string
804}
805</pre></div><div class="separator"></div>
806<div class="example"><pre>
807void test() {
808  size_t ts;
809  scanf("%zd", &ts); // 'ts' marked as tainted
810  int *p = (int *)malloc(ts * sizeof(int));
811    // warn: untrusted data as buffer size
812}
813</pre></div></div></td></tr>
814
815</tbody></table>
816
817<!-- ============================= unix alpha ============================= -->
818<h3 id="unix_alpha_checkers">Unix Alpha Checkers</h3>
819<table class="checkers">
820<colgroup><col class="namedescr"><col class="example"></colgroup>
821<thead><tr><td>Name, Description</td><td>Example</td></tr></thead>
822<tbody>
823
824
825<tr><td><a id="alpha.unix.BlockInCriticalSection"><div class="namedescr expandable"><span class="name">
826alpha.unix.BlockInCriticalSection</span><span class="lang">
827(C)</span><div class="descr">
828Check for calls to blocking functions inside a critical section. Applies to:
829<div class=functions>
830lock<br>
831unlock<br>
832sleep<br>
833getc<br>
834fgets<br>
835read<br>
836revc<br>
837pthread_mutex_lock<br>
838pthread_mutex_unlock<br>
839mtx_lock<br>
840mtx_timedlock<br>
841mtx_trylock<br>
842mtx_unlock<br>
843lock_guard<br>
844unique_lock</div>
845</div></div></a></td>
846<td><div class="exampleContainer expandable">
847<div class="example"><pre>
848void test() {
849  std::mutex m;
850  m.lock();
851  sleep(3); // warn: a blocking function sleep is called inside a critical
852            //       section
853  m.unlock();
854}
855</pre></div></div></td></tr>
856
857
858<tr><td><a id="alpha.unix.Chroot"><div class="namedescr expandable"><span class="name">
859alpha.unix.Chroot</span><span class="lang">
860(C)</span><div class="descr">
861Check improper use of <code>chroot</code>.</div></div></a></td>
862<td><div class="exampleContainer expandable">
863<div class="example"><pre>
864void f();
865
866void test() {
867  chroot("/usr/local");
868  f(); // warn: no call of chdir("/") immediately after chroot
869}
870</pre></div></div></td></tr>
871
872
873<tr><td><a id="alpha.unix.PthreadLock"><div class="namedescr expandable"><span class="name">
874alpha.unix.PthreadLock</span><span class="lang">
875(C)</span><div class="descr">
876Simple lock -> unlock checker; applies to:<div class=functions>
877pthread_mutex_lock<br>
878pthread_rwlock_rdlock<br>
879pthread_rwlock_wrlock<br>
880lck_mtx_lock<br>
881lck_rw_lock_exclusive<br>
882lck_rw_lock_shared<br>
883pthread_mutex_trylock<br>
884pthread_rwlock_tryrdlock<br>
885pthread_rwlock_tryrwlock<br>
886lck_mtx_try_lock<br>
887lck_rw_try_lock_exclusive<br>
888lck_rw_try_lock_shared<br>
889pthread_mutex_unlock<br>
890pthread_rwlock_unlock<br>
891lck_mtx_unlock<br>
892lck_rw_done</div></div></div></a></td>
893<td><div class="exampleContainer expandable">
894<div class="example"><pre>
895pthread_mutex_t mtx;
896
897void test() {
898  pthread_mutex_lock(&mtx);
899  pthread_mutex_lock(&mtx);
900    // warn: this lock has already been acquired
901}
902</pre></div><div class="separator"></div>
903<div class="example"><pre>
904lck_mtx_t lck1, lck2;
905
906void test() {
907  lck_mtx_lock(&lck1);
908  lck_mtx_lock(&lck2);
909  lck_mtx_unlock(&lck1);
910    // warn: this was not the most recently acquired lock
911}
912</pre></div><div class="separator"></div>
913<div class="example"><pre>
914lck_mtx_t lck1, lck2;
915
916void test() {
917  if (lck_mtx_try_lock(&lck1) == 0)
918    return;
919
920  lck_mtx_lock(&lck2);
921  lck_mtx_unlock(&lck1);
922    // warn: this was not the most recently acquired lock
923}
924</pre></div></div></td></tr>
925
926
927<tr><td><a id="alpha.unix.SimpleStream"><div class="namedescr expandable"><span class="name">
928alpha.unix.SimpleStream</span><span class="lang">
929(C)</span><div class="descr">
930Check for misuses of stream APIs:<div class=functions>
931fopen<br>
932fclose</div>(demo checker, the subject of the demo
933(<a href="https://llvm.org/devmtg/2012-11/Zaks-Rose-Checker24Hours.pdf">Slides</a>
934,<a href="https://youtu.be/kdxlsP5QVPw">Video</a>)
935by Anna Zaks and Jordan Rose presented at the <a href="https://llvm.org/devmtg/2012-11/">
9362012 LLVM Developers' Meeting).</a></div></div></a></td>
937<td><div class="exampleContainer expandable">
938<div class="example"><pre>
939void test() {
940  FILE *F = fopen("myfile.txt", "w");
941} // warn: opened file is never closed
942</pre></div><div class="separator"></div>
943<div class="example"><pre>
944void test() {
945  FILE *F = fopen("myfile.txt", "w");
946
947  if (F)
948    fclose(F);
949
950  fclose(F); // warn: closing a previously closed file stream
951}
952</pre></div></div></td></tr>
953
954
955<tr><td><a id="alpha.unix.Stream"><div class="namedescr expandable"><span class="name">
956alpha.unix.Stream</span><span class="lang">
957(C)</span><div class="descr">
958Check stream handling functions:<div class=functions>fopen<br>
959tmpfile<br>
960fclose<br>
961fread<br>
962fwrite<br>
963fseek<br>
964ftell<br>
965rewind<br>
966fgetpos<br>
967fsetpos<br>
968clearerr<br>
969feof<br>
970ferror<br>
971fileno</div></div></div></a></td>
972<td><div class="exampleContainer expandable">
973<div class="example"><pre>
974void test() {
975  FILE *p = fopen("foo", "r");
976} // warn: opened file is never closed
977</pre></div><div class="separator"></div>
978<div class="example"><pre>
979void test() {
980  FILE *p = fopen("foo", "r");
981  fseek(p, 1, SEEK_SET); // warn: stream pointer might be NULL
982  fclose(p);
983}
984</pre></div><div class="separator"></div>
985<div class="example"><pre>
986void test() {
987  FILE *p = fopen("foo", "r");
988
989  if (p)
990    fseek(p, 1, 3);
991     // warn: third arg should be SEEK_SET, SEEK_END, or SEEK_CUR
992
993  fclose(p);
994}
995</pre></div><div class="separator"></div>
996<div class="example"><pre>
997void test() {
998  FILE *p = fopen("foo", "r");
999  fclose(p);
1000  fclose(p); // warn: already closed
1001}
1002</pre></div><div class="separator"></div>
1003<div class="example"><pre>
1004void test() {
1005  FILE *p = tmpfile();
1006  ftell(p); // warn: stream pointer might be NULL
1007  fclose(p);
1008}
1009</pre></div></div></td></tr>
1010
1011
1012<tr><td><a id="alpha.unix.cstring.BufferOverlap"><div class="namedescr expandable"><span class="name">
1013alpha.unix.cstring.BufferOverlap</span><span class="lang">
1014(C)</span><div class="descr">
1015Checks for overlap in two buffer arguments; applies to:<div class=functions>
1016memcpy<br>
1017mempcpy</div></div></div></a></td>
1018<td><div class="exampleContainer expandable">
1019<div class="example"><pre>
1020void test() {
1021  int a[4] = {0};
1022  memcpy(a + 2, a + 1, 8); // warn
1023}
1024</pre></div></div></td></tr>
1025
1026
1027<tr><td><a id="alpha.unix.cstring.NotNullTerminated"><div class="namedescr expandable"><span class="name">
1028alpha.unix.cstring.NotNullTerminated</span><span class="lang">
1029(C)</span><div class="descr">
1030Check for arguments which are not null-terminated strings; applies
1031to:<div class=functions>
1032strlen<br>
1033strnlen<br>
1034strcpy<br>
1035strncpy<br>
1036strcat<br>
1037strncat</div></div></div></td>
1038<td><div class="exampleContainer expandable">
1039<div class="example"><pre>
1040void test() {
1041  int y = strlen((char *)&test); // warn
1042}
1043</pre></div></div></a></td></tr>
1044
1045
1046<tr><td><a id="alpha.unix.cstring.OutOfBounds"><div class="namedescr expandable"><span class="name">
1047alpha.unix.cstring.OutOfBounds</span><span class="lang">
1048(C)</span><div class="descr">
1049Check for out-of-bounds access in string functions; applies
1050to:<div class=functions>
1051strncopy<br>
1052strncat</div></div></div></a></td>
1053<td><div class="exampleContainer expandable">
1054<div class="example"><pre>
1055void test(char *y) {
1056  char x[4];
1057  if (strlen(y) == 4)
1058    strncpy(x, y, 5); // warn
1059}
1060</pre></div></div></td></tr>
1061
1062</tbody></table>
1063
1064<!-- =========================== nondeterminism alpha =========================== -->
1065<h3 id="nondeterminism_alpha_checkers">Non-determinism Alpha Checkers</h3>
1066<table class="checkers">
1067<colgroup><col class="namedescr"><col class="example"></colgroup>
1068<thead><tr><td>Name, Description</td><td>Example</td></tr></thead>
1069
1070<tbody>
1071<tr><td><a id="alpha.nondeterminism.PointerIteration"><div class="namedescr expandable"><span class="name">
1072alpha.nondeterminism.PointerIteration</span><span class="lang">
1073(C++)</span><div class="descr">
1074Check for non-determinism caused by iterating unordered containers of pointers.</div></div></a></td>
1075<td><div class="exampleContainer expandable">
1076<div class="example"><pre>
1077// C++
1078void test() {
1079 int a = 1, b = 2;
1080 std::unordered_set<int *> UnorderedPtrSet = {&a, &b};
1081
1082 for (auto i : UnorderedPtrSet) // warn
1083   f(i);
1084}
1085</pre></div></div></td></tr>
1086<tr><td><a id="alpha.nondeterminism.PointerSorting"><div class="namedescr expandable"><span class="name">
1087alpha.nondeterminism.PointerSorting</span><span class="lang">
1088(C++)</span><div class="descr">
1089Check for non-determinism caused by sorting of pointers.</div></div></a></td>
1090<td><div class="exampleContainer expandable">
1091<div class="example"><pre>
1092// C++
1093void test() {
1094 int a = 1, b = 2;
1095 std::vector<int *> V = {&a, &b};
1096 std::sort(V.begin(), V.end()); // warn
1097}
1098</pre></div></div></td></tr>
1099</tbody></table>
1100
1101</div> <!-- page -->
1102</div> <!-- content -->
1103</body>
1104</html>
1105