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