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.DeleteWithNonVirtualDtor
"><div class="namedescr expandable
"><span class="name
">
334 alpha.cplusplus.DeleteWithNonVirtualDtor</span><span class="lang
">
335 (C++)</span><div class="descr
">
336 Reports destructions of polymorphic objects with a non-virtual destructor in
338 </div></div></a></td>
339 <td><div class="exampleContainer expandable
">
340 <div class="example
"><pre>
341 NonVirtual *create() {
342 NonVirtual *x = new NVDerived(); // note: conversion from derived to base
347 void sink(NonVirtual *x) {
348 delete x; // warn: destruction of a polymorphic object with no virtual
351 </pre></div></div></td></tr>
353 <tr><td><a id="alpha.cplusplus.EnumCastOutOfRange
"><div class="namedescr expandable
"><span class="name
">
354 alpha.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>
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
369 </pre></div></div></td></tr>
372 <tr><td><a id="alpha.cplusplus.InvalidatedIterator
"><div class="namedescr expandable
"><span class="name
">
373 alpha.cplusplus.InvalidatedIterator</span><span class="lang
">
374 (C++)</span><div class="descr
">
375 Check for use of invalidated iterators.
376 </div></div></a></td>
377 <td><div class="exampleContainer expandable
">
378 <div class="example
"><pre>
379 void bad_copy_assign_operator_list1(std::list<int> &L1,
380 const std::list<int> &L2) {
381 auto i0 = L1.cbegin();
383 *i0; // warn: invalidated iterator accessed
385 </pre></div></div></td></tr>
388 <tr><td><a id="alpha.cplusplus.IteratorRange
"><div class="namedescr expandable
"><span class="name
">
389 alpha.cplusplus.IteratorRange</span><span class="lang
">
390 (C++)</span><div class="descr
">
391 Check for iterators used outside their valid ranges.
392 </div></div></a></td>
393 <td><div class="exampleContainer expandable
">
394 <div class="example
"><pre>
395 void simple_bad_end(const std::vector<int> &v) {
397 *i; // warn: iterator accessed outside of its range
399 </pre></div></div></td></tr>
402 <tr><td><a id="alpha.cplusplus.MismatchedIterator
"><div class="namedescr expandable
"><span class="name
">
403 alpha.cplusplus.MismatchedIterator</span><span class="lang
">
404 (C++)</span><div class="descr
">
405 Check for use of iterators of different containers where iterators of the same
406 container are expected.
407 </div></div></a></td>
408 <td><div class="exampleContainer expandable
">
409 <div class="example
"><pre>
410 void bad_insert3(std::vector<int> &v1, std::vector<int> &v2) {
411 v2.insert(v1.cbegin(), v2.cbegin(), v2.cend()); // warn: container accessed
414 v1.insert(v1.cbegin(), v1.cbegin(), v2.cend()); // warn: iterators of
415 // different containers
416 // used where the same
419 v1.insert(v1.cbegin(), v2.cbegin(), v1.cend()); // warn: iterators of
420 // different containers
421 // used where the same
425 </pre></div></div></td></tr>
428 <tr><td><a id="alpha.cplusplus.Move
"><div class="namedescr expandable
"><span class="name
">
429 alpha.cplusplus.Move</span><span class="lang
">
430 (C++)</span><div class="descr
">
431 Method calls on a moved-from object and copying a moved-from object will be
433 </div></div></a></td>
434 <td><div class="exampleContainer expandable
">
435 <div class="example
"><pre>
442 A b = std::move(a); // note: 'a' became 'moved-from' here
443 a.foo(); // warn: method call on a 'moved-from' object 'a'
445 </pre></div></div></td></tr>
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>
458 <tr><td><a id="alpha.deadcode.UnreachableCode
"><div class="namedescr expandable
"><span class="name
">
459 alpha.deadcode.UnreachableCode</span><span class="lang
">
460 (C, C++, ObjC)</span><div class="descr
">
461 Check unreachable code.</div></div></a></td>
462 <td><div class="exampleContainer expandable
">
463 <div class="example
"><pre>
470 </pre></div><div class="separator
"></div>
471 <div class="example
"><pre>
482 </pre></div><div class="separator
"></div>
483 <div class="example
"><pre>
489 </pre></div></div></td></tr>
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>
499 <tr><td><a id="alpha.llvm.Conventions
"><div class="namedescr expandable
"><span class="name
">
500 alpha.llvm.Conventions</span><span class="lang
">
501 (C)</span><div class="descr
">
502 Check code for LLVM codebase conventions:
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>
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>
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>
524 <tr><td><a id="alpha.osx.cocoa.DirectIvarAssignment
"><div class="namedescr expandable
"><span class="name
">
525 alpha.osx.cocoa.DirectIvarAssignment</span><span class="lang
">
526 (ObjC)</span><div class="descr
">
527 Check that Objective C properties follow the following rule: the property
528 should 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;
536 @implementation MyClass
541 </pre></div></div></td></tr>
544 <tr><td><a id="alpha.osx.cocoa.DirectIvarAssignmentForAnnotatedFunctions
"><div class="namedescr expandable
"><span class="name
">
545 alpha.osx.cocoa.DirectIvarAssignmentForAnnotatedFunctions</span><span class="lang
">
546 (ObjC)</span><div class="descr
">
547 Check for direct assignments to instance variables in the methods annotated
548 with <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;
558 @implementation MyClass
559 - (void) fAnnotated {
562 - (void) fNotAnnotated {
566 </pre></div></div></td></tr>
569 <tr><td><a id="alpha.osx.cocoa.InstanceVariableInvalidation
"><div class="namedescr expandable
"><span class="name
">
570 alpha.osx.cocoa.InstanceVariableInvalidation</span><span class="lang
">
571 (ObjC)</span><div class="descr
">
572 Check that the invalidatable instance variables are invalidated in the methods
573 annotated 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 <NSObject>
578 __attribute__((annotate("objc_instance_variable_invalidator
")));
581 @interface InvalidationImpObj : NSObject <Invalidation>
584 @interface SubclassInvalidationImpObj : InvalidationImpObj {
585 InvalidationImpObj *var;
590 @implementation SubclassInvalidationImpObj
591 - (void) invalidate {}
593 // warn: var needs to be invalidated or set to nil
594 </pre></div></div></td></tr>
597 <tr><td><a id="alpha.osx.cocoa.MissingInvalidationMethod
"><div class="namedescr expandable
"><span class="name
">
598 alpha.osx.cocoa.MissingInvalidationMethod</span><span class="lang
">
599 (ObjC)</span><div class="descr
">
600 Check that the invalidation methods are present in classes that contain
601 invalidatable instance variables.</div></div></a></td>
602 <td><div class="exampleContainer expandable
">
603 <div class="example
"><pre>
604 @protocol Invalidation <NSObject>
606 __attribute__((annotate("objc_instance_variable_invalidator
")));
609 @interface NeedInvalidation : NSObject <Invalidation>
612 @interface MissingInvalidationMethodDecl : NSObject {
613 NeedInvalidation *Var; // warn
617 @implementation MissingInvalidationMethodDecl
619 </pre></div></div></td></tr>
622 <tr><td><a id="alpha.osx.cocoa.localizability.PluralMisuseChecker
"><div class="namedescr expandable
"><span class="name
">
623 alpha.osx.cocoa.localizability.PluralMisuseChecker</span><span class="lang
">
624 (ObjC)</span><div class="descr
">
625 Warns against using one vs. many plural pattern in code
626 when generating localized strings.
627 </div></div></a></td>
628 <td><div class="exampleContainer expandable
">
629 <div class="example
"><pre>
630 NSString *reminderText =
631 NSLocalizedString(@"None
", @"Indicates no reminders
");
632 if (reminderCount == 1) {
633 // Warning: Plural cases are not supported across all languages.
634 // Use a .stringsdict file instead
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
641 [NSString stringWithFormat:
642 NSLocalizedString(@"%@ Reminders
", @"Indicates multiple reminders
"),
645 </pre></div></div></td></tr>
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>
656 <tr><td><a id="alpha.security.ArrayBound
"><div class="namedescr expandable
"><span class="name
">
657 alpha.security.ArrayBound</span><span class="lang
">
658 (C)</span><div class="descr
">
659 Warn about buffer overflows (older checker).</div></div></a></td>
660 <td><div class="exampleContainer expandable
">
661 <div class="example
"><pre>
664 char c = s[1]; // warn
666 </pre></div><div class="separator
"></div>
667 <div class="example
"><pre>
673 struct seven_words a, *p;
679 </pre></div><div class="separator
"></div>
680 <div class="example
"><pre>
681 // note: requires unix.Malloc or
682 // alpha.unix.MallocWithAnnotations checks enabled.
687 </pre></div><div class="separator
"></div>
688 <div class="example
"><pre>
694 </pre></div></div></td></tr>
697 <tr><td><a id="alpha.security.ArrayBoundV2
"><div class="namedescr expandable
"><span class="name
">
698 alpha.security.ArrayBoundV2</span><span class="lang
">
699 (C)</span><div class="descr
">
700 Warn about buffer overflows (newer checker).</div></div></a></td>
701 <td><div class="exampleContainer expandable
">
702 <div class="example
"><pre>
705 char c = s[1]; // warn
707 </pre></div><div class="separator
"></div>
708 <div class="example
"><pre>
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.
721 buf[0][-1] = 1; // warn
723 </pre></div><div class="separator
"></div>
724 <div class="example
"><pre>
725 // note: requires alpha.security.taint check turned on.
729 char c = s[x]; // warn: index is tainted
731 </pre></div></div></td></tr>
734 <tr><td><a id="alpha.security.MallocOverflow
"><div class="namedescr expandable
"><span class="name
">
735 alpha.security.MallocOverflow</span><span class="lang
">
736 (C)</span><div class="descr
">
737 Check for overflows in the arguments to <code>malloc()</code>.</div></div></a></td>
738 <td><div class="exampleContainer expandable
">
739 <div class="example
"><pre>
741 void *p = malloc(n * sizeof(int)); // warn
743 </pre></div></div></td></tr>
746 <tr><td><a id="alpha.security.MmapWriteExec
"><div class="namedescr expandable
"><span class="name
">
747 alpha.security.MmapWriteExec</span><span class="lang
">
748 (C)</span><div class="descr
">
749 Warn 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>
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
760 </pre></div></div></td></tr>
763 <tr><td><a id="alpha.security.ReturnPtrRange
"><div class="namedescr expandable
"><span class="name
">
764 alpha.security.ReturnPtrRange</span><span class="lang
">
765 (C)</span><div class="descr
">
766 Check 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>
775 </pre></div><div class="separator
"></div>
776 <div class="example
"><pre>
779 return x; // warn: undefined or garbage returned
781 </pre></div></div></td></tr>
784 <tr><td><a id="alpha.security.taint.TaintPropagation
"><div class="namedescr expandable
"><span class="name
">
785 alpha.security.taint.TaintPropagation</span><span class="lang
">
786 (C)</span><div class="descr
">
787 Generate taint information used by other checkers.</div></div></a></td>
788 <td><div class="exampleContainer expandable
">
789 <div class="example
"><pre>
791 char x = getchar(); // 'x' marked as tainted
792 system(&x); // warn: untrusted data is passed to a system call
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.
801 fscanf(stdin, "%s
", s); // 's' marked as tainted
803 sprintf(buf, s); // warn: untrusted data as a format string
805 </pre></div><div class="separator
"></div>
806 <div class="example
"><pre>
809 scanf("%zd
", &ts); // 'ts' marked as tainted
810 int *p = (int *)malloc(ts * sizeof(int));
811 // warn: untrusted data as buffer size
813 </pre></div></div></td></tr>
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>
825 <tr><td><a id="alpha.unix.BlockInCriticalSection
"><div class="namedescr expandable
"><span class="name
">
826 alpha.unix.BlockInCriticalSection</span><span class="lang
">
827 (C)</span><div class="descr
">
828 Check for calls to blocking functions inside a critical section. Applies to:
829 <div class=functions>
837 pthread_mutex_lock<br>
838 pthread_mutex_unlock<br>
845 </div></div></a></td>
846 <td><div class="exampleContainer expandable
">
847 <div class="example
"><pre>
851 sleep(3); // warn: a blocking function sleep is called inside a critical
855 </pre></div></div></td></tr>
858 <tr><td><a id="alpha.unix.Chroot
"><div class="namedescr expandable
"><span class="name
">
859 alpha.unix.Chroot</span><span class="lang
">
860 (C)</span><div class="descr
">
861 Check improper use of <code>chroot</code>.</div></div></a></td>
862 <td><div class="exampleContainer expandable
">
863 <div class="example
"><pre>
867 chroot("/usr/local
");
868 f(); // warn: no call of chdir("/
") immediately after chroot
870 </pre></div></div></td></tr>
873 <tr><td><a id="alpha.unix.PthreadLock
"><div class="namedescr expandable
"><span class="name
">
874 alpha.unix.PthreadLock</span><span class="lang
">
875 (C)</span><div class="descr
">
876 Simple lock -> unlock checker; applies to:<div class=functions>
877 pthread_mutex_lock<br>
878 pthread_rwlock_rdlock<br>
879 pthread_rwlock_wrlock<br>
881 lck_rw_lock_exclusive<br>
882 lck_rw_lock_shared<br>
883 pthread_mutex_trylock<br>
884 pthread_rwlock_tryrdlock<br>
885 pthread_rwlock_tryrwlock<br>
887 lck_rw_try_lock_exclusive<br>
888 lck_rw_try_lock_shared<br>
889 pthread_mutex_unlock<br>
890 pthread_rwlock_unlock<br>
892 lck_rw_done</div></div></div></a></td>
893 <td><div class="exampleContainer expandable
">
894 <div class="example
"><pre>
898 pthread_mutex_lock(&mtx);
899 pthread_mutex_lock(&mtx);
900 // warn: this lock has already been acquired
902 </pre></div><div class="separator
"></div>
903 <div class="example
"><pre>
904 lck_mtx_t lck1, lck2;
909 lck_mtx_unlock(&lck1);
910 // warn: this was not the most recently acquired lock
912 </pre></div><div class="separator
"></div>
913 <div class="example
"><pre>
914 lck_mtx_t lck1, lck2;
917 if (lck_mtx_try_lock(&lck1) == 0)
921 lck_mtx_unlock(&lck1);
922 // warn: this was not the most recently acquired lock
924 </pre></div></div></td></tr>
927 <tr><td><a id="alpha.unix.SimpleStream
"><div class="namedescr expandable
"><span class="name
">
928 alpha.unix.SimpleStream</span><span class="lang
">
929 (C)</span><div class="descr
">
930 Check for misuses of stream APIs:<div class=functions>
932 fclose</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>)
935 by Anna Zaks and Jordan Rose presented at the <a href="https://llvm.org/devmtg/
2012-
11/
">
936 2012 LLVM Developers' Meeting).</a></div></div></a></td>
937 <td><div class="exampleContainer expandable
">
938 <div class="example
"><pre>
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>
945 FILE *F = fopen("myfile.txt
", "w
");
950 fclose(F); // warn: closing a previously closed file stream
952 </pre></div></div></td></tr>
955 <tr><td><a id="alpha.unix.Stream
"><div class="namedescr expandable
"><span class="name
">
956 alpha.unix.Stream</span><span class="lang
">
957 (C)</span><div class="descr
">
958 Check stream handling functions:<div class=functions>fopen<br>
971 fileno</div></div></div></a></td>
972 <td><div class="exampleContainer expandable
">
973 <div class="example
"><pre>
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>
980 FILE *p = fopen("foo
", "r
");
981 fseek(p, 1, SEEK_SET); // warn: stream pointer might be NULL
984 </pre></div><div class="separator
"></div>
985 <div class="example
"><pre>
987 FILE *p = fopen("foo
", "r
");
991 // warn: third arg should be SEEK_SET, SEEK_END, or SEEK_CUR
995 </pre></div><div class="separator
"></div>
996 <div class="example
"><pre>
998 FILE *p = fopen("foo
", "r
");
1000 fclose(p); // warn: already closed
1002 </pre></div><div class="separator
"></div>
1003 <div class="example
"><pre>
1005 FILE *p = tmpfile();
1006 ftell(p); // warn: stream pointer might be NULL
1009 </pre></div></div></td></tr>
1012 <tr><td><a id="alpha.unix.cstring.BufferOverlap
"><div class="namedescr expandable
"><span class="name
">
1013 alpha.unix.cstring.BufferOverlap</span><span class="lang
">
1014 (C)</span><div class="descr
">
1015 Checks for overlap in two buffer arguments; applies to:<div class=functions>
1017 mempcpy</div></div></div></a></td>
1018 <td><div class="exampleContainer expandable
">
1019 <div class="example
"><pre>
1022 memcpy(a + 2, a + 1, 8); // warn
1024 </pre></div></div></td></tr>
1027 <tr><td><a id="alpha.unix.cstring.NotNullTerminated
"><div class="namedescr expandable
"><span class="name
">
1028 alpha.unix.cstring.NotNullTerminated</span><span class="lang
">
1029 (C)</span><div class="descr
">
1030 Check for arguments which are not null-terminated strings; applies
1031 to:<div class=functions>
1037 strncat</div></div></div></td>
1038 <td><div class="exampleContainer expandable
">
1039 <div class="example
"><pre>
1041 int y = strlen((char *)&test); // warn
1043 </pre></div></div></a></td></tr>
1046 <tr><td><a id="alpha.unix.cstring.OutOfBounds
"><div class="namedescr expandable
"><span class="name
">
1047 alpha.unix.cstring.OutOfBounds</span><span class="lang
">
1048 (C)</span><div class="descr
">
1049 Check for out-of-bounds access in string functions; applies
1050 to:<div class=functions>
1052 strncat</div></div></div></a></td>
1053 <td><div class="exampleContainer expandable
">
1054 <div class="example
"><pre>
1055 void test(char *y) {
1058 strncpy(x, y, 5); // warn
1060 </pre></div></div></td></tr>
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>
1071 <tr><td><a id="alpha.nondeterminism.PointerIteration
"><div class="namedescr expandable
"><span class="name
">
1072 alpha.nondeterminism.PointerIteration</span><span class="lang
">
1073 (C++)</span><div class="descr
">
1074 Check 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>
1080 std::unordered_set<int *> UnorderedPtrSet = {&a, &b};
1082 for (auto i : UnorderedPtrSet) // warn
1085 </pre></div></div></td></tr>
1086 <tr><td><a id="alpha.nondeterminism.PointerSorting
"><div class="namedescr expandable
"><span class="name
">
1087 alpha.nondeterminism.PointerSorting</span><span class="lang
">
1088 (C++)</span><div class="descr
">
1089 Check for non-determinism caused by sorting of pointers.</div></div></a></td>
1090 <td><div class="exampleContainer expandable
">
1091 <div class="example
"><pre>
1095 std::vector<int *> V = {&a, &b};
1096 std::sort(V.begin(), V.end()); // warn
1098 </pre></div></div></td></tr>
1101 </div> <!-- page -->
1102 </div> <!-- content -->