[docs] Add LICENSE.txt to the root of the mono-repo
[llvm-project.git] / clang / www / analyzer / alpha_checks.html
blob181ce1b9de591b3d0133ef8fe10bd6d45524fd0f
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()">
16 <div id="page">
17 <!--#include virtual="menu.html.incl"-->
19 <div id="content">
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.
25 Patches 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>
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>
46 <tbody>
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>
53 void log();
55 int max(int a, int b) { // warn
56 log();
57 if (a > b)
58 return a;
59 return b;
62 int maxClone(int x, int y) { // similar code here
63 log();
64 if (x > y)
65 return x;
66 return y;
68 </pre></div></div></td></tr>
69 </tbody></table>
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>
77 <tbody>
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>
84 void test() {
85 BOOL b = -1; // warn
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>
97 void test(void) {
98 int t;
99 int &p = t;
100 int &s = p;
101 int &q = s;
102 foo(q); // warn
104 </pre></div><div class="separator"></div>
105 <div class="example"><pre>
106 void test(void) {
107 int x;
108 foo(&x); // warn
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>
122 void test() {
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>
134 // C
135 struct s {};
137 void test(int *p) {
138 struct s *ps = (struct s *) p; // warn
140 </pre></div><div class="separator"></div>
141 <div class="example"><pre>
142 // C++
143 class c {};
145 void test(int *p) {
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) {
158 if (S > 10) {
159 if (U < S) {
162 if (S < -10) {
163 if (U < S) { // warn (loss of sign)
167 </pre></div><div class="separator"></div>
168 <div class="example"><pre>
169 void test() {
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>
198 void test() {
199 int *p;
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>
211 // C
212 void test() {
213 int a = 5;
214 int b = a | 4 | a; // warn: identical expr on both sides
216 </pre></div><div class="separator"></div>
217 <div class="example"><pre>
218 // C++
219 bool f(void);
221 void 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());
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>
243 void test() {
244 int x;
245 int *p;
246 p = &amp;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>
258 void test() {
259 int x, y;
260 int d = &amp;y - &amp;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>
272 struct s {};
274 int test(struct s *p) {
275 return sizeof(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() {
292 int x = 123;
293 void (^inner)(void) = ^void(void) {
294 int y = x;
295 ++y;
297 void (^outer)(void) = ^void(void) {
298 int z = x;
299 ++z;
300 inner();
302 return outer; // warn: address of stack-allocated block is captured by a
303 // returned block
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>
316 void test(int x) {
317 var = 77 / x;
318 if (x == 0) { } // warn
320 </pre></div></div></td></tr>
323 </tbody></table>
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>
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
337 their base class
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
343 // happened here
344 return x;
347 void sink(NonVirtual *x) {
348 delete x; // warn: destruction of a polymorphic object with no virtual
349 // destructor
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>
360 enum TestEnum {
361 A = 0
364 void 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
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();
382 L1 = L2;
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) {
396 auto i = v.end();
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
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
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
432 reported.
433 </div></div></a></td>
434 <td><div class="exampleContainer expandable">
435 <div class="example"><pre>
436 struct A {
437 void foo() {}
440 void 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'
445 </pre></div></div></td></tr>
448 </tbody></table>
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>
457 <tbody>
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>
464 // C
465 int test() {
466 int x = 1;
467 while(x);
468 return x; // warn
470 </pre></div><div class="separator"></div>
471 <div class="example"><pre>
472 // C++
473 void test() {
474 int a = 2;
476 while (a > 1)
477 a--;
479 if (a > 1)
480 a++; // warn
482 </pre></div><div class="separator"></div>
483 <div class="example"><pre>
484 // Objective-C
485 void test(id x) {
486 return;
487 [x retain]; // warn
489 </pre></div></div></td></tr>
490 </tbody></table>
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>
498 <tbody>
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:
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>
514 </tbody></table>
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>
523 <tbody>
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;
533 - (void) foo;
534 @end
536 @implementation MyClass
537 - (void) foo {
538 _A = 0; // warn
540 @end
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;
556 @end
558 @implementation MyClass
559 - (void) fAnnotated {
560 _A = 0; // warn
562 - (void) fNotAnnotated {
563 _A = 0; // no warn
565 @end
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 &lt;NSObject&gt;
577 - (void) invalidate
578 __attribute__((annotate("objc_instance_variable_invalidator")));
579 @end
581 @interface InvalidationImpObj : NSObject &lt;Invalidation&gt;
582 @end
584 @interface SubclassInvalidationImpObj : InvalidationImpObj {
585 InvalidationImpObj *var;
587 - (void)invalidate;
588 @end
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>
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 &lt;NSObject&gt;
605 - (void)invalidate
606 __attribute__((annotate("objc_instance_variable_invalidator")));
607 @end
609 @interface NeedInvalidation : NSObject &lt;Invalidation&gt;
610 @end
612 @interface MissingInvalidationMethodDecl : NSObject {
613 NeedInvalidation *Var; // warn
615 @end
617 @implementation MissingInvalidationMethodDecl
618 @end
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
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];
645 </pre></div></div></td></tr>
647 </tbody></table>
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>
655 <tbody>
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>
662 void test() {
663 char *s = "";
664 char c = s[1]; // warn
666 </pre></div><div class="separator"></div>
667 <div class="example"><pre>
668 struct seven_words {
669 int c[7];
672 void test() {
673 struct seven_words a, *p;
674 p = &a;
675 p[0] = a;
676 p[1] = a;
677 p[2] = a; // warn
679 </pre></div><div class="separator"></div>
680 <div class="example"><pre>
681 // note: requires unix.Malloc or
682 // alpha.unix.MallocWithAnnotations checks enabled.
683 void test() {
684 int *p = malloc(12);
685 p[3] = 4; // warn
687 </pre></div><div class="separator"></div>
688 <div class="example"><pre>
689 void test() {
690 char a[2];
691 int *b = (int*)a;
692 b[1] = 3; // warn
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>
703 void test() {
704 char *s = "";
705 char c = s[1]; // warn
707 </pre></div><div class="separator"></div>
708 <div class="example"><pre>
709 void test() {
710 int buf[100];
711 int *p = buf;
712 p = p + 99;
713 p[1] = 1; // warn
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.
719 void test() {
720 int buf[100][100];
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.
726 void test() {
727 char s[] = "abc";
728 int x = getchar();
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>
740 void test(int n) {
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>
753 void 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
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>
769 static int A[10];
771 int *test() {
772 int *p = A + 10;
773 return p; // warn
775 </pre></div><div class="separator"></div>
776 <div class="example"><pre>
777 int test(void) {
778 int x;
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>
790 void test() {
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.
799 void test() {
800 char s[10], buf[10];
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>
807 void 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
813 </pre></div></div></td></tr>
815 </tbody></table>
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>
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>
830 lock<br>
831 unlock<br>
832 sleep<br>
833 getc<br>
834 fgets<br>
835 read<br>
836 revc<br>
837 pthread_mutex_lock<br>
838 pthread_mutex_unlock<br>
839 mtx_lock<br>
840 mtx_timedlock<br>
841 mtx_trylock<br>
842 mtx_unlock<br>
843 lock_guard<br>
844 unique_lock</div>
845 </div></div></a></td>
846 <td><div class="exampleContainer expandable">
847 <div class="example"><pre>
848 void 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();
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>
864 void f();
866 void test() {
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>
880 lck_mtx_lock<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>
886 lck_mtx_try_lock<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>
891 lck_mtx_unlock<br>
892 lck_rw_done</div></div></div></a></td>
893 <td><div class="exampleContainer expandable">
894 <div class="example"><pre>
895 pthread_mutex_t mtx;
897 void test() {
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;
906 void 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
912 </pre></div><div class="separator"></div>
913 <div class="example"><pre>
914 lck_mtx_t lck1, lck2;
916 void test() {
917 if (lck_mtx_try_lock(&lck1) == 0)
918 return;
920 lck_mtx_lock(&lck2);
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>
931 fopen<br>
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>
939 void 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>
944 void test() {
945 FILE *F = fopen("myfile.txt", "w");
947 if (F)
948 fclose(F);
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>
959 tmpfile<br>
960 fclose<br>
961 fread<br>
962 fwrite<br>
963 fseek<br>
964 ftell<br>
965 rewind<br>
966 fgetpos<br>
967 fsetpos<br>
968 clearerr<br>
969 feof<br>
970 ferror<br>
971 fileno</div></div></div></a></td>
972 <td><div class="exampleContainer expandable">
973 <div class="example"><pre>
974 void 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>
979 void test() {
980 FILE *p = fopen("foo", "r");
981 fseek(p, 1, SEEK_SET); // warn: stream pointer might be NULL
982 fclose(p);
984 </pre></div><div class="separator"></div>
985 <div class="example"><pre>
986 void test() {
987 FILE *p = fopen("foo", "r");
989 if (p)
990 fseek(p, 1, 3);
991 // warn: third arg should be SEEK_SET, SEEK_END, or SEEK_CUR
993 fclose(p);
995 </pre></div><div class="separator"></div>
996 <div class="example"><pre>
997 void test() {
998 FILE *p = fopen("foo", "r");
999 fclose(p);
1000 fclose(p); // warn: already closed
1002 </pre></div><div class="separator"></div>
1003 <div class="example"><pre>
1004 void test() {
1005 FILE *p = tmpfile();
1006 ftell(p); // warn: stream pointer might be NULL
1007 fclose(p);
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>
1016 memcpy<br>
1017 mempcpy</div></div></div></a></td>
1018 <td><div class="exampleContainer expandable">
1019 <div class="example"><pre>
1020 void test() {
1021 int a[4] = {0};
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>
1032 strlen<br>
1033 strnlen<br>
1034 strcpy<br>
1035 strncpy<br>
1036 strcat<br>
1037 strncat</div></div></div></td>
1038 <td><div class="exampleContainer expandable">
1039 <div class="example"><pre>
1040 void test() {
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>
1051 strncopy<br>
1052 strncat</div></div></div></a></td>
1053 <td><div class="exampleContainer expandable">
1054 <div class="example"><pre>
1055 void test(char *y) {
1056 char x[4];
1057 if (strlen(y) == 4)
1058 strncpy(x, y, 5); // warn
1060 </pre></div></div></td></tr>
1062 </tbody></table>
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>
1070 <tbody>
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>
1077 // C++
1078 void test() {
1079 int a = 1, b = 2;
1080 std::unordered_set<int *> UnorderedPtrSet = {&a, &b};
1082 for (auto i : UnorderedPtrSet) // warn
1083 f(i);
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>
1092 // C++
1093 void test() {
1094 int a = 1, b = 2;
1095 std::vector<int *> V = {&a, &b};
1096 std::sort(V.begin(), V.end()); // warn
1098 </pre></div></div></td></tr>
1099 </tbody></table>
1101 </div> <!-- page -->
1102 </div> <!-- content -->
1103 </body>
1104 </html>