1 <!DOCTYPE HTML PUBLIC
"-//W3C//DTD HTML 4.01//EN"
2 "http://www.w3.org/TR/html4/strict.dtd">
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%; }
14 <body onload=
"initExpandCollapse()">
17 <!--#include virtual="menu.html.incl"-->
20 <h1>Alpha Checkers
</h1>
21 Experimental checkers in addition to the
<a href =
"available_checks.html">
22 Default Checkers
</a>. These are checkers with known issues or limitations that
23 keep them from being on by default. They are likely to have false positives.
24 Bug reports are welcome but will likely not be investigated for some time.
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>
39 <!-- ============================= clone alpha ============================= -->
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>
47 <tr><td><a id=
"alpha.clone.CloneChecker"><div class=
"namedescr expandable"><span class=
"name">
48 alpha.clone.CloneChecker
</span><span class=
"lang">
49 (C, C++, ObjC)
</span><div class=
"descr">
50 Reports similar pieces of code.
</div></div></a></td>
51 <td><div class=
"exampleContainer expandable">
52 <div class=
"example"><pre>
55 int max(int a, int b) { // warn
62 int maxClone(int x, int y) { // similar code here
68 </pre></div></div></td></tr>
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>
78 <tr><td><a id=
"alpha.core.BoolAssignment"><div class=
"namedescr expandable"><span class=
"name">
79 alpha.core.BoolAssignment
</span><span class=
"lang">
80 (ObjC)
</span><div class=
"descr">
81 Warn about assigning non-{
0,
1} values to boolean variables.
</div></div></a></td>
82 <td><div class=
"exampleContainer expandable">
83 <div class=
"example"><pre>
87 </pre></div></div></td></tr>
90 <tr><td><a id=
"alpha.core.CallAndMessageUnInitRefArg"><div class=
"namedescr expandable"><span class=
"name">
91 alpha.core.CallAndMessageUnInitRefArg
</span><span class=
"lang">
92 (C, C++)
</span><div class=
"descr">
93 Check for uninitialized arguments in function calls and Objective-C
94 message expressions.
</div></div></a></td>
95 <td><div class=
"exampleContainer expandable">
96 <div class=
"example"><pre>
104 </pre></div><div class=
"separator"></div>
105 <div class=
"example"><pre>
110 </pre></div></div></td></tr>
113 <tr><td><a id=
"alpha.core.CastSize"><div class=
"namedescr expandable"><span class=
"name">
114 alpha.core.CastSize
</span><span class=
"lang">
115 (C)
</span><div class=
"descr">
116 Check when casting a malloc'ed type T, whether the size is a multiple of the
117 size of T (Works only with
<span class=
"name">unix.Malloc
</span>
118 or
<span class=
"name">alpha.unix.MallocWithAnnotations
</span>
119 checks enabled).
</div></div></a></td>
120 <td><div class=
"exampleContainer expandable">
121 <div class=
"example"><pre>
123 int *x = (int *)malloc(
11); // warn
125 </pre></div></div></td></tr>
128 <tr><td><a id=
"alpha.core.CastToStruct"><div class=
"namedescr expandable"><span class=
"name">
129 alpha.core.CastToStruct
</span><span class=
"lang">
130 (C, C++)
</span><div class=
"descr">
131 Check for cast from non-struct pointer to struct pointer.
</div></div></a></td>
132 <td><div class=
"exampleContainer expandable">
133 <div class=
"example"><pre>
138 struct s *ps = (struct s *) p; // warn
140 </pre></div><div class=
"separator"></div>
141 <div class=
"example"><pre>
146 c *pc = (c *) p; // warn
148 </pre></div></div></td></tr>
151 <tr><td><a id=
"alpha.core.Conversion"><div class=
"namedescr expandable"><span class=
"name">
152 alpha.core.Conversion
</span><span class=
"lang">
153 (C, C++, ObjC)
</span><div class=
"descr">
154 Loss of sign or precision in implicit conversions
</div></div></a></td>
155 <td><div class=
"exampleContainer expandable">
156 <div class=
"example"><pre>
157 void test(unsigned U, signed S) {
163 if (U < S) { // warn (loss of sign)
167 </pre></div><div class=
"separator"></div>
168 <div class=
"example"><pre>
170 long long A =
1LL <<
60;
171 short X = A; // warn (loss of precision)
173 </pre></div></div></td></tr>
176 <tr><td><a id=
"alpha.core.DynamicTypeChecker"><div class=
"namedescr expandable"><span class=
"name">
177 alpha.core.DynamicTypeChecker
</span><span class=
"lang">
178 (ObjC)
</span><div class=
"descr">
179 Check for cases where the dynamic and the static type of an
180 object are unrelated.
</div></div></a></td>
181 <td><div class=
"exampleContainer expandable">
182 <div class=
"example"><pre>
183 id date = [NSDate date];
185 // Warning: Object has a dynamic type 'NSDate *' which is
186 // incompatible with static type 'NSNumber *'
"
187 NSNumber *number = date;
188 [number doubleValue];
189 </pre></div></div></td></tr>
192 <tr><td><a id="alpha.core.FixedAddr
"><div class="namedescr expandable
"><span class="name
">
193 alpha.core.FixedAddr</span><span class="lang
">
194 (C)</span><div class="descr
">
195 Check for assignment of a fixed address to a pointer.</div></div></a></td>
196 <td><div class="exampleContainer expandable
">
197 <div class="example
"><pre>
200 p = (int *) 0x10000; // warn
202 </pre></div></div></td></tr>
205 <tr><td><a id="alpha.core.IdenticalExpr
"><div class="namedescr expandable
"><span class="name
">
206 alpha.core.IdenticalExpr</span><span class="lang
">
207 (C, C++)</span><div class="descr
">
208 Warn about suspicious uses of identical expressions.</div></div></a></td>
209 <td><div class="exampleContainer expandable
">
210 <div class="example
"><pre>
214 int b = a | 4 | a; // warn: identical expr on both sides
216 </pre></div><div class="separator
"></div>
217 <div class="example
"><pre>
223 if (f()) { // warn: true and false branches are identical
233 </pre></div></div></td></tr>
236 <tr><td><a id="alpha.core.PointerArithm
"><div class="namedescr expandable
"><span class="name
">
237 alpha.core.PointerArithm</span><span class="lang
">
238 (C)</span><div class="descr
">
239 Check for pointer arithmetic on locations other than array
240 elements.</div></div></a></td>
241 <td><div class="exampleContainer expandable
">
242 <div class="example
"><pre>
246 p = &x + 1; // warn
248 </pre></div></div></td></tr>
251 <tr><td><a id="alpha.core.PointerSub
"><div class="namedescr expandable
"><span class="name
">
252 alpha.core.PointerSub</span><span class="lang
">
253 (C)</span><div class="descr
">
254 Check for pointer subtractions on two pointers pointing to different memory
255 chunks.</div></div></a></td>
256 <td><div class="exampleContainer expandable
">
257 <div class="example
"><pre>
260 int d = &y - &x; // warn
262 </pre></div></div></td></tr>
265 <tr><td><a id="alpha.core.SizeofPtr
"><div class="namedescr expandable
"><span class="name
">
266 alpha.core.SizeofPtr</span><span class="lang
">
267 (C)</span><div class="descr
">
268 Warn about unintended use of <code>sizeof()</code> on pointer
269 expressions.</div></div></a></td>
270 <td><div class="exampleContainer expandable
">
271 <div class="example
"><pre>
274 int test(struct s *p) {
276 // warn: sizeof(ptr) can produce an unexpected result
278 </pre></div></div></td></tr>
281 <tr><td><a id="alpha.core.StackAddressAsyncEscape
"><div class="namedescr expandable
"><span class="name
">
282 alpha.core.StackAddressAsyncEscape</span><span class="lang
">
283 (C)</span><div class="descr
">
284 Check 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
286 a part of core.StackAddressEscape, but is
287 <a href=https://reviews.llvm.org/D41042>temporarily disabled</a> until some
288 false positives are fixed.</div></div></a></td>
289 <td><div class="exampleContainer expandable
">
290 <div class="example
"><pre>
291 dispatch_block_t test_block_inside_block_async_leak() {
293 void (^inner)(void) = ^void(void) {
297 void (^outer)(void) = ^void(void) {
302 return outer; // warn: address of stack-allocated block is captured by a
305 </pre></div></div></td></tr>
308 <tr><td><a id="alpha.core.TestAfterDivZero
"><div class="namedescr expandable
"><span class="name
">
309 alpha.core.TestAfterDivZero</span><span class="lang
">
310 (C, C++, ObjC)</span><div class="descr
">
311 Check for division by variable that is later compared against 0.
312 Either 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>
318 if (x == 0) { } // warn
320 </pre></div></div></td></tr>
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>
333 <tr><td><a id="alpha.cplusplus.ArrayDelete
"><div class="namedescr expandable
"><span class="name
">
334 alpha.cplusplus.ArrayDelete</span><span class="lang
">
335 (C++)</span><div class="descr
">
336 Reports destructions of arrays of polymorphic objects that are destructed as
338 </div></div></a></td>
339 <td><div class="exampleContainer expandable
">
340 <div class="example
"><pre>
342 Base *x = new Derived[10]; // note: Casting from 'Derived' to 'Base' here
347 delete[] x; // warn: Deleting an array of 'Derived' objects as their base class 'Base' undefined
350 </pre></div></div></td></tr>
353 <tr><td><a id="alpha.cplusplus.DeleteWithNonVirtualDtor
"><div class="namedescr expandable
"><span class="name
">
354 alpha.cplusplus.DeleteWithNonVirtualDtor</span><span class="lang
">
355 (C++)</span><div class="descr
">
356 Reports destructions of polymorphic objects with a non-virtual destructor in
358 </div></div></a></td>
359 <td><div class="exampleContainer expandable
">
360 <div class="example
"><pre>
361 NonVirtual *create() {
362 NonVirtual *x = new NVDerived(); // note: Casting from 'NVDerived' to
367 void sink(NonVirtual *x) {
368 delete x; // warn: destruction of a polymorphic object with no virtual
371 </pre></div></div></td></tr>
373 <tr><td><a id="alpha.cplusplus.InvalidatedIterator
"><div class="namedescr expandable
"><span class="name
">
374 alpha.cplusplus.InvalidatedIterator</span><span class="lang
">
375 (C++)</span><div class="descr
">
376 Check for use of invalidated iterators.
377 </div></div></a></td>
378 <td><div class="exampleContainer expandable
">
379 <div class="example
"><pre>
380 void bad_copy_assign_operator_list1(std::list<int> &L1,
381 const std::list<int> &L2) {
382 auto i0 = L1.cbegin();
384 *i0; // warn: invalidated iterator accessed
386 </pre></div></div></td></tr>
389 <tr><td><a id="alpha.cplusplus.IteratorRange
"><div class="namedescr expandable
"><span class="name
">
390 alpha.cplusplus.IteratorRange</span><span class="lang
">
391 (C++)</span><div class="descr
">
392 Check for iterators used outside their valid ranges.
393 </div></div></a></td>
394 <td><div class="exampleContainer expandable
">
395 <div class="example
"><pre>
396 void simple_bad_end(const std::vector<int> &v) {
398 *i; // warn: iterator accessed outside of its range
400 </pre></div></div></td></tr>
403 <tr><td><a id="alpha.cplusplus.MismatchedIterator
"><div class="namedescr expandable
"><span class="name
">
404 alpha.cplusplus.MismatchedIterator</span><span class="lang
">
405 (C++)</span><div class="descr
">
406 Check for use of iterators of different containers where iterators of the same
407 container are expected.
408 </div></div></a></td>
409 <td><div class="exampleContainer expandable
">
410 <div class="example
"><pre>
411 void bad_insert3(std::vector<int> &v1, std::vector<int> &v2) {
412 v2.insert(v1.cbegin(), v2.cbegin(), v2.cend()); // warn: container accessed
415 v1.insert(v1.cbegin(), v1.cbegin(), v2.cend()); // warn: iterators of
416 // different containers
417 // used where the same
420 v1.insert(v1.cbegin(), v2.cbegin(), v1.cend()); // warn: iterators of
421 // different containers
422 // used where the same
426 </pre></div></div></td></tr>
429 <tr><td><a id="alpha.cplusplus.Move
"><div class="namedescr expandable
"><span class="name
">
430 alpha.cplusplus.Move</span><span class="lang
">
431 (C++)</span><div class="descr
">
432 Method calls on a moved-from object and copying a moved-from object will be
434 </div></div></a></td>
435 <td><div class="exampleContainer expandable
">
436 <div class="example
"><pre>
443 A b = std::move(a); // note: 'a' became 'moved-from' here
444 a.foo(); // warn: method call on a 'moved-from' object 'a'
446 </pre></div></div></td></tr>
452 <!-- =========================== dead code alpha =========================== -->
453 <h3 id="deadcode_alpha_checkers
">Dead Code Alpha Checkers</h3>
454 <table class="checkers
">
455 <colgroup><col class="namedescr
"><col class="example
"></colgroup>
456 <thead><tr><td>Name, Description</td><td>Example</td></tr></thead>
459 <tr><td><a id="alpha.deadcode.UnreachableCode
"><div class="namedescr expandable
"><span class="name
">
460 alpha.deadcode.UnreachableCode</span><span class="lang
">
461 (C, C++, ObjC)</span><div class="descr
">
462 Check unreachable code.</div></div></a></td>
463 <td><div class="exampleContainer expandable
">
464 <div class="example
"><pre>
471 </pre></div><div class="separator
"></div>
472 <div class="example
"><pre>
483 </pre></div><div class="separator
"></div>
484 <div class="example
"><pre>
490 </pre></div></div></td></tr>
493 <!-- =========================== llvm alpha =========================== -->
494 <h3 id="llvm_alpha_checkers
">LLVM Checkers</h3>
495 <table class="checkers
">
496 <colgroup><col class="namedescr
"><col class="example
"></colgroup>
497 <thead><tr><td>Name, Description</td><td>Example</td></tr></thead>
500 <tr><td><a id="alpha.llvm.Conventions
"><div class="namedescr expandable
"><span class="name
">
501 alpha.llvm.Conventions</span><span class="lang
">
502 (C)</span><div class="descr
">
503 Check code for LLVM codebase conventions:
505 <li>A <code>StringRef</code> should not be bound to a temporary std::string
506 whose lifetime is shorter than the <code>StringRef</code>'s.</li>
507 <li>Clang AST nodes should not have fields that can allocate memory.</li>
509 </div></div></a></td>
510 <td><div class="exampleContainer expandable
">
511 <div class="example
"><pre>
512 <!-- TODO: Add examples, as currently it's hard to get this checker working. -->
513 </pre></div></div></td></tr>
518 <!-- ============================== OS X alpha ============================== -->
519 <h3 id="osx_alpha_checkers
">OS X Alpha Checkers</h3>
520 <table class="checkers
">
521 <colgroup><col class="namedescr
"><col class="example
"></colgroup>
522 <thead><tr><td>Name, Description</td><td>Example</td></tr></thead>
525 <tr><td><a id="alpha.osx.cocoa.DirectIvarAssignment
"><div class="namedescr expandable
"><span class="name
">
526 alpha.osx.cocoa.DirectIvarAssignment</span><span class="lang
">
527 (ObjC)</span><div class="descr
">
528 Check that Objective C properties follow the following rule: the property
529 should be set with the setter, not though a direct assignment.</div></div></a></td>
530 <td><div class="exampleContainer expandable
">
531 <div class="example
"><pre>
532 @interface MyClass : NSObject {}
533 @property (readonly) id A;
537 @implementation MyClass
542 </pre></div></div></td></tr>
545 <tr><td><a id="alpha.osx.cocoa.DirectIvarAssignmentForAnnotatedFunctions
"><div class="namedescr expandable
"><span class="name
">
546 alpha.osx.cocoa.DirectIvarAssignmentForAnnotatedFunctions</span><span class="lang
">
547 (ObjC)</span><div class="descr
">
548 Check for direct assignments to instance variables in the methods annotated
549 with <code>objc_no_direct_instance_variable_assignment</code>.</div></div></a></td>
550 <td><div class="exampleContainer expandable
">
551 <div class="example
"><pre>
552 @interface MyClass : NSObject {}
553 @property (readonly) id A;
554 - (void) fAnnotated __attribute__((
555 annotate("objc_no_direct_instance_variable_assignment
")));
556 - (void) fNotAnnotated;
559 @implementation MyClass
560 - (void) fAnnotated {
563 - (void) fNotAnnotated {
567 </pre></div></div></td></tr>
570 <tr><td><a id="alpha.osx.cocoa.InstanceVariableInvalidation
"><div class="namedescr expandable
"><span class="name
">
571 alpha.osx.cocoa.InstanceVariableInvalidation</span><span class="lang
">
572 (ObjC)</span><div class="descr
">
573 Check that the invalidatable instance variables are invalidated in the methods
574 annotated with <code>objc_instance_variable_invalidator</code>.</div></div></a></td>
575 <td><div class="exampleContainer expandable
">
576 <div class="example
"><pre>
577 @protocol Invalidation <NSObject>
579 __attribute__((annotate("objc_instance_variable_invalidator
")));
582 @interface InvalidationImpObj : NSObject <Invalidation>
585 @interface SubclassInvalidationImpObj : InvalidationImpObj {
586 InvalidationImpObj *var;
591 @implementation SubclassInvalidationImpObj
592 - (void) invalidate {}
594 // warn: var needs to be invalidated or set to nil
595 </pre></div></div></td></tr>
598 <tr><td><a id="alpha.osx.cocoa.MissingInvalidationMethod
"><div class="namedescr expandable
"><span class="name
">
599 alpha.osx.cocoa.MissingInvalidationMethod</span><span class="lang
">
600 (ObjC)</span><div class="descr
">
601 Check that the invalidation methods are present in classes that contain
602 invalidatable instance variables.</div></div></a></td>
603 <td><div class="exampleContainer expandable
">
604 <div class="example
"><pre>
605 @protocol Invalidation <NSObject>
607 __attribute__((annotate("objc_instance_variable_invalidator
")));
610 @interface NeedInvalidation : NSObject <Invalidation>
613 @interface MissingInvalidationMethodDecl : NSObject {
614 NeedInvalidation *Var; // warn
618 @implementation MissingInvalidationMethodDecl
620 </pre></div></div></td></tr>
623 <tr><td><a id="alpha.osx.cocoa.localizability.PluralMisuseChecker
"><div class="namedescr expandable
"><span class="name
">
624 alpha.osx.cocoa.localizability.PluralMisuseChecker</span><span class="lang
">
625 (ObjC)</span><div class="descr
">
626 Warns against using one vs. many plural pattern in code
627 when generating localized strings.
628 </div></div></a></td>
629 <td><div class="exampleContainer expandable
">
630 <div class="example
"><pre>
631 NSString *reminderText =
632 NSLocalizedString(@"None
", @"Indicates no reminders
");
633 if (reminderCount == 1) {
634 // Warning: Plural cases are not supported across all languages.
635 // Use a .stringsdict file instead
637 NSLocalizedString(@"1 Reminder
", @"Indicates single reminder
");
638 } else if (reminderCount >= 2) {
639 // Warning: Plural cases are not supported across all languages.
640 // Use a .stringsdict file instead
642 [NSString stringWithFormat:
643 NSLocalizedString(@"%@ Reminders
", @"Indicates multiple reminders
"),
646 </pre></div></div></td></tr>
650 <!-- =========================== security alpha =========================== -->
651 <h3 id="security_alpha_checkers
">Security Alpha Checkers</h3>
652 <table class="checkers
">
653 <colgroup><col class="namedescr
"><col class="example
"></colgroup>
654 <thead><tr><td>Name, Description</td><td>Example</td></tr></thead>
657 <tr><td><a id="alpha.security.ArrayBound
"><div class="namedescr expandable
"><span class="name
">
658 alpha.security.ArrayBound</span><span class="lang
">
659 (C)</span><div class="descr
">
660 Warn about buffer overflows (older checker).</div></div></a></td>
661 <td><div class="exampleContainer expandable
">
662 <div class="example
"><pre>
665 char c = s[1]; // warn
667 </pre></div><div class="separator
"></div>
668 <div class="example
"><pre>
674 struct seven_words a, *p;
680 </pre></div><div class="separator
"></div>
681 <div class="example
"><pre>
682 // note: requires unix.Malloc or
683 // alpha.unix.MallocWithAnnotations checks enabled.
688 </pre></div><div class="separator
"></div>
689 <div class="example
"><pre>
695 </pre></div></div></td></tr>
698 <tr><td><a id="alpha.security.ArrayBoundV2
"><div class="namedescr expandable
"><span class="name
">
699 alpha.security.ArrayBoundV2</span><span class="lang
">
700 (C)</span><div class="descr
">
701 Warn about buffer overflows (newer checker).</div></div></a></td>
702 <td><div class="exampleContainer expandable
">
703 <div class="example
"><pre>
706 char c = s[1]; // warn
708 </pre></div><div class="separator
"></div>
709 <div class="example
"><pre>
716 </pre></div><div class="separator
"></div>
717 <div class="example
"><pre>
718 // note: compiler has internal check for this.
719 // Use -Wno-array-bounds to suppress compiler warning.
722 buf[0][-1] = 1; // warn
724 </pre></div><div class="separator
"></div>
725 <div class="example
"><pre>
726 // note: requires alpha.security.taint check turned on.
730 char c = s[x]; // warn: index is tainted
732 </pre></div></div></td></tr>
735 <tr><td><a id="alpha.security.MallocOverflow
"><div class="namedescr expandable
"><span class="name
">
736 alpha.security.MallocOverflow</span><span class="lang
">
737 (C)</span><div class="descr
">
738 Check for overflows in the arguments to <code>malloc()</code>.</div></div></a></td>
739 <td><div class="exampleContainer expandable
">
740 <div class="example
"><pre>
742 void *p = malloc(n * sizeof(int)); // warn
744 </pre></div></div></td></tr>
747 <tr><td><a id="alpha.security.MmapWriteExec
"><div class="namedescr expandable
"><span class="name
">
748 alpha.security.MmapWriteExec</span><span class="lang
">
749 (C)</span><div class="descr
">
750 Warn on <code>mmap()<code> calls that are both writable and executable.
751 </div></div></a></td>
752 <td><div class="exampleContainer expandable
">
753 <div class="example
"><pre>
755 void *c = mmap(NULL, 32, PROT_READ | PROT_WRITE | PROT_EXEC,
756 MAP_PRIVATE | MAP_ANON, -1, 0);
757 // warn: Both PROT_WRITE and PROT_EXEC flags are set. This can lead to
758 // exploitable memory regions, which could be overwritten with malicious
761 </pre></div></div></td></tr>
764 <tr><td><a id="alpha.security.ReturnPtrRange
"><div class="namedescr expandable
"><span class="name
">
765 alpha.security.ReturnPtrRange</span><span class="lang
">
766 (C)</span><div class="descr
">
767 Check for an out-of-bound pointer being returned to callers.</div></div></a></td>
768 <td><div class="exampleContainer expandable
">
769 <div class="example
"><pre>
776 </pre></div><div class="separator
"></div>
777 <div class="example
"><pre>
780 return x; // warn: undefined or garbage returned
782 </pre></div></div></td></tr>
785 <tr><td><a id="alpha.security.taint.TaintPropagation
"><div class="namedescr expandable
"><span class="name
">
786 alpha.security.taint.TaintPropagation</span><span class="lang
">
787 (C)</span><div class="descr
">
788 Generate taint information used by other checkers.</div></div></a></td>
789 <td><div class="exampleContainer expandable
">
790 <div class="example
"><pre>
792 char x = getchar(); // 'x' marked as tainted
793 system(&x); // warn: untrusted data is passed to a system call
795 </pre></div><div class="separator
"></div>
796 <div class="example
"><pre>
797 // note: compiler internally checks if the second param to
798 // sprintf is a string literal or not.
799 // Use -Wno-format-security to suppress compiler warning.
802 fscanf(stdin, "%s
", s); // 's' marked as tainted
804 sprintf(buf, s); // warn: untrusted data as a format string
806 </pre></div><div class="separator
"></div>
807 <div class="example
"><pre>
810 scanf("%zd
", &ts); // 'ts' marked as tainted
811 int *p = (int *)malloc(ts * sizeof(int));
812 // warn: untrusted data as buffer size
814 </pre></div></div></td></tr>
818 <!-- ============================= unix alpha ============================= -->
819 <h3 id="unix_alpha_checkers
">Unix Alpha Checkers</h3>
820 <table class="checkers
">
821 <colgroup><col class="namedescr
"><col class="example
"></colgroup>
822 <thead><tr><td>Name, Description</td><td>Example</td></tr></thead>
826 <tr><td><a id="alpha.unix.BlockInCriticalSection
"><div class="namedescr expandable
"><span class="name
">
827 alpha.unix.BlockInCriticalSection</span><span class="lang
">
828 (C)</span><div class="descr
">
829 Check for calls to blocking functions inside a critical section. Applies to:
830 <div class=functions>
838 pthread_mutex_lock<br>
839 pthread_mutex_unlock<br>
846 </div></div></a></td>
847 <td><div class="exampleContainer expandable
">
848 <div class="example
"><pre>
852 sleep(3); // warn: a blocking function sleep is called inside a critical
856 </pre></div></div></td></tr>
859 <tr><td><a id="alpha.unix.Chroot
"><div class="namedescr expandable
"><span class="name
">
860 alpha.unix.Chroot</span><span class="lang
">
861 (C)</span><div class="descr
">
862 Check improper use of <code>chroot</code>.</div></div></a></td>
863 <td><div class="exampleContainer expandable
">
864 <div class="example
"><pre>
868 chroot("/usr/local
");
869 f(); // warn: no call of chdir("/
") immediately after chroot
871 </pre></div></div></td></tr>
874 <tr><td><a id="alpha.unix.PthreadLock
"><div class="namedescr expandable
"><span class="name
">
875 alpha.unix.PthreadLock</span><span class="lang
">
876 (C)</span><div class="descr
">
877 Simple lock -> unlock checker; applies to:<div class=functions>
878 pthread_mutex_lock<br>
879 pthread_rwlock_rdlock<br>
880 pthread_rwlock_wrlock<br>
882 lck_rw_lock_exclusive<br>
883 lck_rw_lock_shared<br>
884 pthread_mutex_trylock<br>
885 pthread_rwlock_tryrdlock<br>
886 pthread_rwlock_tryrwlock<br>
888 lck_rw_try_lock_exclusive<br>
889 lck_rw_try_lock_shared<br>
890 pthread_mutex_unlock<br>
891 pthread_rwlock_unlock<br>
893 lck_rw_done</div></div></div></a></td>
894 <td><div class="exampleContainer expandable
">
895 <div class="example
"><pre>
899 pthread_mutex_lock(&mtx);
900 pthread_mutex_lock(&mtx);
901 // warn: this lock has already been acquired
903 </pre></div><div class="separator
"></div>
904 <div class="example
"><pre>
905 lck_mtx_t lck1, lck2;
910 lck_mtx_unlock(&lck1);
911 // warn: this was not the most recently acquired lock
913 </pre></div><div class="separator
"></div>
914 <div class="example
"><pre>
915 lck_mtx_t lck1, lck2;
918 if (lck_mtx_try_lock(&lck1) == 0)
922 lck_mtx_unlock(&lck1);
923 // warn: this was not the most recently acquired lock
925 </pre></div></div></td></tr>
928 <tr><td><a id="alpha.unix.SimpleStream
"><div class="namedescr expandable
"><span class="name
">
929 alpha.unix.SimpleStream</span><span class="lang
">
930 (C)</span><div class="descr
">
931 Check for misuses of stream APIs:<div class=functions>
933 fclose</div>(demo checker, the subject of the demo
934 (<a href="https://llvm.org/devmtg/
2012-
11/Zaks-Rose-Checker24Hours.pdf
">Slides</a>
935 ,<a href="https://youtu.be/kdxlsP5QVPw
">Video</a>)
936 by Anna Zaks and Jordan Rose presented at the <a href="https://llvm.org/devmtg/
2012-
11/
">
937 2012 LLVM Developers' Meeting).</a></div></div></a></td>
938 <td><div class="exampleContainer expandable
">
939 <div class="example
"><pre>
941 FILE *F = fopen("myfile.txt
", "w
");
942 } // warn: opened file is never closed
943 </pre></div><div class="separator
"></div>
944 <div class="example
"><pre>
946 FILE *F = fopen("myfile.txt
", "w
");
951 fclose(F); // warn: closing a previously closed file stream
953 </pre></div></div></td></tr>
956 <tr><td><a id="alpha.unix.Stream
"><div class="namedescr expandable
"><span class="name
">
957 alpha.unix.Stream</span><span class="lang
">
958 (C)</span><div class="descr
">
959 Check stream handling functions:<div class=functions>fopen<br>
972 fileno</div></div></div></a></td>
973 <td><div class="exampleContainer expandable
">
974 <div class="example
"><pre>
976 FILE *p = fopen("foo
", "r
");
977 } // warn: opened file is never closed
978 </pre></div><div class="separator
"></div>
979 <div class="example
"><pre>
981 FILE *p = fopen("foo
", "r
");
982 fseek(p, 1, SEEK_SET); // warn: stream pointer might be NULL
985 </pre></div><div class="separator
"></div>
986 <div class="example
"><pre>
988 FILE *p = fopen("foo
", "r
");
992 // warn: third arg should be SEEK_SET, SEEK_END, or SEEK_CUR
996 </pre></div><div class="separator
"></div>
997 <div class="example
"><pre>
999 FILE *p = fopen("foo
", "r
");
1001 fclose(p); // warn: already closed
1003 </pre></div><div class="separator
"></div>
1004 <div class="example
"><pre>
1006 FILE *p = tmpfile();
1007 ftell(p); // warn: stream pointer might be NULL
1010 </pre></div></div></td></tr>
1013 <tr><td><a id="alpha.unix.cstring.BufferOverlap
"><div class="namedescr expandable
"><span class="name
">
1014 alpha.unix.cstring.BufferOverlap</span><span class="lang
">
1015 (C)</span><div class="descr
">
1016 Checks for overlap in two buffer arguments; applies to:<div class=functions>
1018 mempcpy</div></div></div></a></td>
1019 <td><div class="exampleContainer expandable
">
1020 <div class="example
"><pre>
1023 memcpy(a + 2, a + 1, 8); // warn
1025 </pre></div></div></td></tr>
1028 <tr><td><a id="alpha.unix.cstring.NotNullTerminated
"><div class="namedescr expandable
"><span class="name
">
1029 alpha.unix.cstring.NotNullTerminated</span><span class="lang
">
1030 (C)</span><div class="descr
">
1031 Check for arguments which are not null-terminated strings; applies
1032 to:<div class=functions>
1038 strncat</div></div></div></td>
1039 <td><div class="exampleContainer expandable
">
1040 <div class="example
"><pre>
1042 int y = strlen((char *)&test); // warn
1044 </pre></div></div></a></td></tr>
1047 <tr><td><a id="alpha.unix.cstring.OutOfBounds
"><div class="namedescr expandable
"><span class="name
">
1048 alpha.unix.cstring.OutOfBounds</span><span class="lang
">
1049 (C)</span><div class="descr
">
1050 Check for out-of-bounds access in string functions; applies
1051 to:<div class=functions>
1053 strncat</div></div></div></a></td>
1054 <td><div class="exampleContainer expandable
">
1055 <div class="example
"><pre>
1056 void test(char *y) {
1059 strncpy(x, y, 5); // warn
1061 </pre></div></div></td></tr>
1065 <!-- =========================== nondeterminism alpha =========================== -->
1066 <h3 id="nondeterminism_alpha_checkers
">Non-determinism Alpha Checkers</h3>
1067 <table class="checkers
">
1068 <colgroup><col class="namedescr
"><col class="example
"></colgroup>
1069 <thead><tr><td>Name, Description</td><td>Example</td></tr></thead>
1072 <tr><td><a id="alpha.nondeterminism.PointerIteration
"><div class="namedescr expandable
"><span class="name
">
1073 alpha.nondeterminism.PointerIteration</span><span class="lang
">
1074 (C++)</span><div class="descr
">
1075 Check for non-determinism caused by iterating unordered containers of pointers.</div></div></a></td>
1076 <td><div class="exampleContainer expandable
">
1077 <div class="example
"><pre>
1081 std::unordered_set<int *> UnorderedPtrSet = {&a, &b};
1083 for (auto i : UnorderedPtrSet) // warn
1086 </pre></div></div></td></tr>
1087 <tr><td><a id="alpha.nondeterminism.PointerSorting
"><div class="namedescr expandable
"><span class="name
">
1088 alpha.nondeterminism.PointerSorting</span><span class="lang
">
1089 (C++)</span><div class="descr
">
1090 Check for non-determinism caused by sorting of pointers.</div></div></a></td>
1091 <td><div class="exampleContainer expandable
">
1092 <div class="example
"><pre>
1096 std::vector<int *> V = {&a, &b};
1097 std::sort(V.begin(), V.end()); // warn
1099 </pre></div></div></td></tr>
1102 </div> <!-- page -->
1103 </div> <!-- content -->