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>Available Checkers</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>Available Checkers</h1> |
21 | The analyzer performs checks that are categorized into families or "checkers". The |
22 | default set of checkers covers a variety of checks targeted at finding security |
23 | and API usage bugs, dead code, and other logic errors. See the |
24 | <a href = "#default_checkers">Default Checkers</a> list below. In addition to |
25 | these, the analyzer contains a number of <a href = "alpha_checks.html"> |
26 | Experimental (Alpha) Checkers</a>. |
27 | |
28 | <h3>Writeups with examples of some of the bugs that the analyzer finds</h3> |
29 | <ul> |
30 | <li><a href="http://www.mobileorchard.com/bug-finding-with-clang-5-resources-to-get-you-started/">Bug Finding With Clang: 5 Resources To Get You Started</a></li> |
31 | <li><a href="http://fruitstandsoftware.com/blog/index.php/2008/08/finding-memory-leaks-with-the-llvmclang-static-analyzer/#comment-2">Finding Memory Leaks With The LLVM/Clang Static Analyzer</a></li> |
32 | <li><a href="http://www.rogueamoeba.com/utm/2008/07/14/the-clang-static-analyzer/">Under the Microscope - The Clang Static Analyzer</a></li> |
33 | <li><a href="http://www.mikeash.com/?page=pyblog/friday-qa-2009-03-06-using-the-clang-static-analyzer.html">Mike Ash - Using the Clang Static Analyzer</a></li> |
34 | </ul> |
35 | |
36 | <h2 id="default_checkers">Default Checkers</h2> |
37 | <ul> |
38 | <li><a href="#core_checkers">Core Checkers</a> model core language features and perform general-purpose checks such as division by zero, null pointer dereference, usage of uninitialized values, etc.</li> |
39 | <li><a href="#cplusplus_checkers">C++ Checkers</a> perform C++-specific checks</li> |
40 | <li><a href="#deadcode_checkers">Dead Code Checkers</a> check for unused code</li> |
41 | <li><a href="#nullability_checkers">Nullability Checkers</a> </li> |
42 | <li><a href="#optin_checkers">Optin Checkers</a> </li> |
43 | <li><a href="#osx_checkers">OS X Checkers</a> perform Objective-C-specific checks and check the use of Apple's SDKs (OS X and iOS)</li> |
44 | <li><a href="#security_checkers">Security Checkers</a> check for insecure API usage and perform checks based on the CERT Secure Coding Standards</li> |
45 | <li><a href="#unix_checkers">Unix Checkers</a> check the use of Unix and POSIX APIs</li> |
46 | </ul> |
47 | |
48 | <!-- =========================== core =========================== --> |
49 | <h3 id="core_checkers">Core Checkers</h3> |
50 | <table class="checkers"> |
51 | <colgroup><col class="namedescr"><col class="example"></colgroup> |
52 | <thead><tr><td>Name, Description</td><td>Example</td></tr></thead> |
53 | |
54 | <tbody> |
55 | <tr><td><a id="core.CallAndMessage"><div class="namedescr expandable"><span class="name"> |
56 | core.CallAndMessage</span><span class="lang"> |
57 | (C, C++, ObjC)</span><div class="descr"> |
58 | Check for logical errors for function calls and Objective-C message expressions |
59 | (e.g., uninitialized arguments, null function pointers).</div></div></a></td> |
60 | <td><div class="exampleContainer expandable"> |
61 | <div class="example"><pre> |
62 | // C |
63 | struct S { |
64 | int x; |
65 | }; |
66 | |
67 | void f(struct S s); |
68 | |
69 | void test() { |
70 | struct S s; |
71 | f(s); // warn: passed-by-value arg contain uninitialized data |
72 | } |
73 | </pre></div> |
74 | <div class="example"><pre> |
75 | // C |
76 | void test() { |
77 | void (*foo)(void); |
78 | foo(); // warn: function pointer is uninitialized |
79 | } |
80 | </pre></div> |
81 | <div class="example"><pre> |
82 | // C |
83 | void test() { |
84 | void (*foo)(void); |
85 | foo = 0; |
86 | foo(); // warn: function pointer is null |
87 | } |
88 | </pre></div> |
89 | <div class="example"><pre> |
90 | // C++ |
91 | class C { |
92 | public: |
93 | void f(); |
94 | }; |
95 | |
96 | void test() { |
97 | C *pc; |
98 | pc->f(); // warn: object pointer is uninitialized |
99 | } |
100 | </pre></div> |
101 | <div class="example"><pre> |
102 | // C++ |
103 | class C { |
104 | public: |
105 | void f(); |
106 | }; |
107 | |
108 | void test() { |
109 | C *pc = 0; |
110 | pc->f(); // warn: object pointer is null |
111 | } |
112 | </pre></div> |
113 | <div class="example"><pre> |
114 | // Objective-C |
115 | @interface MyClass : NSObject |
116 | @property (readwrite,assign) id x; |
117 | - (long double)longDoubleM; |
118 | @end |
119 | |
120 | void test() { |
121 | MyClass *obj1; |
122 | long double ld1 = [obj1 longDoubleM]; |
123 | // warn: receiver is uninitialized |
124 | } |
125 | </pre></div> |
126 | <div class="example"><pre> |
127 | // Objective-C |
128 | @interface MyClass : NSObject |
129 | @property (readwrite,assign) id x; |
130 | - (long double)longDoubleM; |
131 | @end |
132 | |
133 | void test() { |
134 | MyClass *obj1; |
135 | id i = obj1.x; // warn: uninitialized object pointer |
136 | } |
137 | </pre></div> |
138 | <div class="example"><pre> |
139 | // Objective-C |
140 | @interface Subscriptable : NSObject |
141 | - (id)objectAtIndexedSubscript:(unsigned int)index; |
142 | @end |
143 | |
144 | @interface MyClass : Subscriptable |
145 | @property (readwrite,assign) id x; |
146 | - (long double)longDoubleM; |
147 | @end |
148 | |
149 | void test() { |
150 | MyClass *obj1; |
151 | id i = obj1[0]; // warn: uninitialized object pointer |
152 | } |
153 | </pre></div></div></td></tr> |
154 | |
155 | |
156 | <tr><td><a id="core.DivideZero"><div class="namedescr expandable"><span class="name"> |
157 | core.DivideZero</span><span class="lang"> |
158 | (C, C++, ObjC)</span><div class="descr"> |
159 | Check for division by zero.</div></div></a>co</td> |
160 | <td><div class="exampleContainer expandable"> |
161 | <div class="example"><pre> |
162 | void test(int z) { |
163 | if (z == 0) |
164 | int x = 1 / z; // warn |
165 | } |
166 | </pre></div> |
167 | <div class="example"><pre> |
168 | void test() { |
169 | int x = 1; |
170 | int y = x % 0; // warn |
171 | } |
172 | </pre></div></div></td></tr> |
173 | |
174 | |
175 | <tr><td><a id="core.NonNullParamChecker"><div class="namedescr expandable"><span class="name"> |
176 | core.NonNullParamChecker</span><span class="lang"> |
177 | (C, C++, ObjC)</span><div class="descr"> |
178 | Check for null pointers passed as arguments to a function whose arguments are |
179 | marked with the <code>nonnull</code> attribute.</div></div></a></td> |
180 | <td><div class="exampleContainer expandable"> |
181 | <div class="example"><pre> |
182 | int f(int *p) __attribute__((nonnull)); |
183 | |
184 | void test(int *p) { |
185 | if (!p) |
186 | f(p); // warn |
187 | } |
188 | </pre></div></div></td></tr> |
189 | |
190 | |
191 | <tr><td><a id="core.NullDereference"><div class="namedescr expandable"><span class="name"> |
192 | core.NullDereference</span><span class="lang"> |
193 | (C, C++, ObjC)</span><div class="descr"> |
194 | Check for dereferences of null pointers.</div></div></a></td> |
195 | <td><div class="exampleContainer expandable"> |
196 | <div class="example"><pre> |
197 | // C |
198 | void test(int *p) { |
199 | if (p) |
200 | return; |
201 | |
202 | int x = p[0]; // warn |
203 | } |
204 | </pre></div> |
205 | <div class="example"><pre> |
206 | // C |
207 | void test(int *p) { |
208 | if (!p) |
209 | *p = 0; // warn |
210 | } |
211 | </pre></div> |
212 | <div class="example"><pre> |
213 | // C++ |
214 | class C { |
215 | public: |
216 | int x; |
217 | }; |
218 | |
219 | void test() { |
220 | C *pc = 0; |
221 | int k = pc->x; // warn |
222 | } |
223 | </pre></div> |
224 | <div class="example"><pre> |
225 | // Objective-C |
226 | @interface MyClass { |
227 | @public |
228 | int x; |
229 | } |
230 | @end |
231 | |
232 | void test() { |
233 | MyClass *obj = 0; |
234 | obj->x = 1; // warn |
235 | } |
236 | </pre></div></div></td></tr> |
237 | |
238 | |
239 | <tr><td><a id="core.StackAddressEscape"><div class="namedescr expandable"><span class="name"> |
240 | core.StackAddressEscape</span><span class="lang"> |
241 | (C)</span><div class="descr"> |
242 | Check that addresses of stack memory do not escape the function.</div></div></a></td> |
243 | <td><div class="exampleContainer expandable"> |
244 | <div class="example"><pre> |
245 | char const *p; |
246 | |
247 | void test() { |
248 | char const str[] = "string"; |
249 | p = str; // warn |
250 | } |
251 | </pre></div> |
252 | <div class="example"><pre> |
253 | void* test() { |
254 | return __builtin_alloca(12); // warn |
255 | } |
256 | </pre></div> |
257 | <div class="example"><pre> |
258 | void test() { |
259 | static int *x; |
260 | int y; |
261 | x = &y; // warn |
262 | } |
263 | </pre></div></div></td></tr> |
264 | |
265 | |
266 | <tr><td><a id="core.UndefinedBinaryOperatorResult"><div class="namedescr expandable"><span class="name"> |
267 | core.UndefinedBinaryOperatorResult</span><span class="lang"> |
268 | (C)</span><div class="descr"> |
269 | Check for undefined results of binary operators.</div></div></a></td> |
270 | <td><div class="exampleContainer expandable"> |
271 | <div class="example"><pre> |
272 | void test() { |
273 | int x; |
274 | int y = x + 1; // warn: left operand is garbage |
275 | } |
276 | </pre></div></div></td></tr> |
277 | |
278 | |
279 | <tr><td><a id="core.VLASize"><div class="namedescr expandable"><span class="name"> |
280 | core.VLASize</span><span class="lang"> |
281 | (C)</span><div class="descr"> |
282 | Check for declarations of VLA of undefined or zero size.</div></div></a></td> |
283 | <td><div class="exampleContainer expandable"> |
284 | <div class="example"><pre> |
285 | void test() { |
286 | int x; |
287 | int vla1[x]; // warn: garbage as size |
288 | } |
289 | </pre></div> |
290 | <div class="example"><pre> |
291 | void test() { |
292 | int x = 0; |
293 | int vla2[x]; // warn: zero size |
294 | } |
295 | </pre></div></div></td></tr> |
296 | |
297 | |
298 | <tr><td><a id="core.uninitialized.ArraySubscript"><div class="namedescr expandable"><span class="name"> |
299 | core.uninitialized.ArraySubscript</span><span class="lang"> |
300 | (C)</span><div class="descr"> |
301 | Check for uninitialized values used as array subscripts.</div></div></a></td> |
302 | <td><div class="exampleContainer expandable"> |
303 | <div class="example"><pre> |
304 | void test() { |
305 | int i, a[10]; |
306 | int x = a[i]; // warn: array subscript is undefined |
307 | } |
308 | </pre></div></div></td></tr> |
309 | |
310 | |
311 | <tr><td><a id="core.uninitialized.Assign"><div class="namedescr expandable"><span class="name"> |
312 | core.uninitialized.Assign</span><span class="lang"> |
313 | (C)</span><div class="descr"> |
314 | Check for assigning uninitialized values.</div></div></a></td> |
315 | <td><div class="exampleContainer expandable"> |
316 | <div class="example"><pre> |
317 | void test() { |
318 | int x; |
319 | x |= 1; // warn: left expression is uninitialized |
320 | } |
321 | </pre></div></div></td></tr> |
322 | |
323 | |
324 | <tr><td><a id="core.uninitialized.Branch"><div class="namedescr expandable"><span class="name"> |
325 | core.uninitialized.Branch</span><span class="lang"> |
326 | (C)</span><div class="descr"> |
327 | Check for uninitialized values used as branch conditions.</div></div></a></td> |
328 | <td><div class="exampleContainer expandable"> |
329 | <div class="example"><pre> |
330 | void test() { |
331 | int x; |
332 | if (x) // warn |
333 | return; |
334 | } |
335 | </pre></div></div></td></tr> |
336 | |
337 | |
338 | <tr><td><a id="core.uninitialized.CapturedBlockVariable"><div class="namedescr expandable"><span class="name"> |
339 | core.uninitialized.CapturedBlockVariable</span><span class="lang"> |
340 | (C)</span><div class="descr"> |
341 | Check for blocks that capture uninitialized values.</div></div></a></td> |
342 | <td><div class="exampleContainer expandable"> |
343 | <div class="example"><pre> |
344 | void test() { |
345 | int x; |
346 | ^{ int y = x; }(); // warn |
347 | } |
348 | </pre></div></div></td></tr> |
349 | |
350 | |
351 | <tr><td><a id="core.uninitialized.UndefReturn"><div class="namedescr expandable"><span class="name"> |
352 | core.uninitialized.UndefReturn</span><span class="lang"> |
353 | (C)</span><div class="descr"> |
354 | Check for uninitialized values being returned to the caller.</div></div></a></td> |
355 | <td><div class="exampleContainer expandable"> |
356 | <div class="example"><pre> |
357 | int test() { |
358 | int x; |
359 | return x; // warn |
360 | } |
361 | </pre></div></div></td></tr> |
362 | |
363 | </tbody></table> |
364 | |
365 | <!-- =========================== C++ =========================== --> |
366 | <h3 id="cplusplus_checkers">C++ Checkers</h3> |
367 | <table class="checkers"> |
368 | <colgroup><col class="namedescr"><col class="example"></colgroup> |
369 | <thead><tr><td>Name, Description</td><td>Example</td></tr></thead> |
370 | |
371 | <tbody> |
372 | <tr><td><a id="cplusplus.NewDelete"><div class="namedescr expandable"><span class="name"> |
373 | cplusplus.NewDelete</span><span class="lang"> |
374 | (C++)</span><div class="descr"> |
375 | Check for double-free, use-after-free and offset problems involving C++ <code> |
376 | delete</code>.</div></div></a></td> |
377 | <td><div class="exampleContainer expandable"> |
378 | <div class="example"><pre> |
379 | void f(int *p); |
380 | |
381 | void testUseMiddleArgAfterDelete(int *p) { |
382 | delete p; |
383 | f(p); // warn: use after free |
384 | } |
385 | </pre></div> |
386 | <div class="example"><pre> |
387 | class SomeClass { |
388 | public: |
389 | void f(); |
390 | }; |
391 | |
392 | void test() { |
393 | SomeClass *c = new SomeClass; |
394 | delete c; |
395 | c->f(); // warn: use after free |
396 | } |
397 | </pre></div> |
398 | <div class="example"><pre> |
399 | void test() { |
400 | int *p = (int *)__builtin_alloca(sizeof(int)); |
401 | delete p; // warn: deleting memory allocated by alloca |
402 | } |
403 | </pre></div> |
404 | <div class="example"><pre> |
405 | void test() { |
406 | int *p = new int; |
407 | delete p; |
408 | delete p; // warn: attempt to free released |
409 | } |
410 | </pre></div> |
411 | <div class="example"><pre> |
412 | void test() { |
413 | int i; |
414 | delete &i; // warn: delete address of local |
415 | } |
416 | </pre></div> |
417 | <div class="example"><pre> |
418 | void test() { |
419 | int *p = new int[1]; |
420 | delete[] (++p); |
421 | // warn: argument to 'delete[]' is offset by 4 bytes |
422 | // from the start of memory allocated by 'new[]' |
423 | } |
424 | </pre></div></div></td></tr> |
425 | |
426 | <tr><td><a id="cplusplus.NewDeleteLeaks"><div class="namedescr expandable"><span class="name"> |
427 | cplusplus.NewDeleteLeaks</span><span class="lang"> |
428 | (C++)</span><div class="descr"> |
429 | Check for memory leaks. Traces memory managed by <code>new</code>/<code> |
430 | delete</code>.</div></div></a></td> |
431 | <td><div class="exampleContainer expandable"> |
432 | <div class="example"><pre> |
433 | void test() { |
434 | int *p = new int; |
435 | } // warn |
436 | </pre></div></div></td></tr> |
437 | |
438 | </tbody></table> |
439 | |
440 | <!-- =========================== dead code =========================== --> |
441 | <h3 id="deadcode_checkers">Dead Code Checkers</h3> |
442 | <table class="checkers"> |
443 | <colgroup><col class="namedescr"><col class="example"></colgroup> |
444 | <thead><tr><td>Name, Description</td><td>Example</td></tr></thead> |
445 | |
446 | <tbody> |
447 | <tr><td><a id="deadcode.DeadStores"><div class="namedescr expandable"><span class="name"> |
448 | deadcode.DeadStores</span><span class="lang"> |
449 | (C)</span><div class="descr"> |
450 | Check for values stored to variables that are never read afterwards.</div></div></a></td> |
451 | <td><div class="exampleContainer expandable"> |
452 | <div class="example"><pre> |
453 | void test() { |
454 | int x; |
455 | x = 1; // warn |
456 | } |
457 | </pre></div></div></td></tr> |
458 | |
459 | </tbody></table> |
460 | |
461 | <!-- =========================== nullability =========================== --> |
462 | <h3 id="nullability_checkers">Nullability Checkers</h3> |
463 | <table class="checkers"> |
464 | <colgroup><col class="namedescr"><col class="example"></colgroup> |
465 | <thead><tr><td>Name, Description</td><td>Example</td></tr></thead> |
466 | |
467 | <tbody> |
468 | <tr><td><a id="nullability.NullPassedToNonnull"><div class="namedescr expandable"><span class="name"> |
469 | nullability.NullPassedToNonnull</span><span class="lang"> |
470 | (ObjC)</span><div class="descr"> |
471 | Warns when a null pointer is passed to a pointer which has a |
472 | _Nonnull type.</div></div></a></td> |
473 | <td><div class="exampleContainer expandable"> |
474 | <div class="example"><pre> |
475 | if (name != nil) |
476 | return; |
477 | // Warning: nil passed to a callee that requires a non-null 1st parameter |
478 | NSString *greeting = [@"Hello " stringByAppendingString:name]; |
479 | </pre></div></div></td></tr> |
480 | |
481 | |
482 | <tr><td><a id="nullability.NullReturnedFromNonnull"><div class="namedescr expandable"><span class="name"> |
483 | nullability.NullReturnedFromNonnull</span><span class="lang"> |
484 | (ObjC)</span><div class="descr"> |
485 | Warns when a null pointer is returned from a function that has |
486 | _Nonnull return type.</div></div></a></td> |
487 | <td><div class="exampleContainer expandable"> |
488 | <div class="example"><pre> |
489 | - (nonnull id)firstChild { |
490 | id result = nil; |
491 | if ([_children count] > 0) |
492 | result = _children[0]; |
493 | |
494 | // Warning: nil returned from a method that is expected |
495 | // to return a non-null value |
496 | return result; |
497 | } |
498 | </pre></div></div></td></tr> |
499 | |
500 | |
501 | <tr><td><a id="nullability.NullableDereferenced"><div class="namedescr expandable"><span class="name"> |
502 | nullability.NullableDereferenced</span><span class="lang"> |
503 | (ObjC)</span><div class="descr"> |
504 | Warns when a nullable pointer is dereferenced.</div></div></a></td> |
505 | <td><div class="exampleContainer expandable"> |
506 | <div class="example"><pre> |
507 | struct LinkedList { |
508 | int data; |
509 | struct LinkedList *next; |
510 | }; |
511 | |
512 | struct LinkedList * _Nullable getNext(struct LinkedList *l); |
513 | |
514 | void updateNextData(struct LinkedList *list, int newData) { |
515 | struct LinkedList *next = getNext(list); |
516 | // Warning: Nullable pointer is dereferenced |
517 | next->data = 7; |
518 | } |
519 | </pre></div></div></td></tr> |
520 | |
521 | |
522 | <tr><td><a id="nullability.NullablePassedToNonnull"><div class="namedescr expandable"><span class="name"> |
523 | nullability.NullablePassedToNonnull</span><span class="lang"> |
524 | (ObjC)</span><div class="descr"> |
525 | Warns when a nullable pointer is passed to a pointer which has a _Nonnull type.</div></div></a></td> |
526 | <td><div class="exampleContainer expandable"> |
527 | <div class="example"><pre> |
528 | typedef struct Dummy { int val; } Dummy; |
529 | Dummy *_Nullable returnsNullable(); |
530 | void takesNonnull(Dummy *_Nonnull); |
531 | |
532 | void test() { |
533 | Dummy *p = returnsNullable(); |
534 | takesNonnull(p); // warn |
535 | } |
536 | </pre></div></div></td></tr> |
537 | |
538 | </tbody></table> |
539 | |
540 | <!-- =========================== optin =========================== --> |
541 | <h3 id="optin_checkers">Optin Checkers</h3> |
542 | <table class="checkers"> |
543 | <colgroup><col class="namedescr"><col class="example"></colgroup> |
544 | <thead><tr><td>Name, Description</td><td>Example</td></tr></thead> |
545 | |
546 | |
547 | <tbody> |
548 | <tr><td><a id="optin.cplusplus.VirtualCall"><div class="namedescr expandable"><span class="name"> |
549 | optin.cplusplus.VirtualCall</span><span class="lang"> |
550 | (C++)</span><div class="descr"> |
551 | Check virtual member function calls during construction or |
552 | destruction.</div></div></a></td> |
553 | <td><div class="exampleContainer expandable"> |
554 | <div class="example"><pre> |
555 | class A { |
556 | public: |
557 | A() { |
558 | f(); // warn |
559 | } |
560 | virtual void f(); |
561 | }; |
562 | </pre></div><div class="separator"></div> |
563 | <div class="example"><pre> |
564 | class A { |
565 | public: |
566 | ~A() { |
567 | this->f(); // warn |
568 | } |
569 | virtual void f(); |
570 | }; |
571 | </pre></div></div></td></tr> |
572 | |
573 | |
574 | <tr><td><a id="optin.mpi.MPI-Checker"><div class="namedescr expandable"><span class="name"> |
575 | optin.mpi.MPI-Checker</span><span class="lang"> |
576 | (C)</span><div class="descr"> |
577 | Checks MPI code</div></div></a></td> |
578 | <td><div class="exampleContainer expandable"> |
579 | <div class="example"><pre> |
580 | void test() { |
581 | double buf = 0; |
582 | MPI_Request sendReq1; |
583 | MPI_Ireduce(MPI_IN_PLACE, &buf, 1, MPI_DOUBLE, MPI_SUM, |
584 | 0, MPI_COMM_WORLD, &sendReq1); |
585 | } // warn: request 'sendReq1' has no matching wait. |
586 | </pre></div><div class="separator"></div> |
587 | <div class="example"><pre> |
588 | void test() { |
589 | double buf = 0; |
590 | MPI_Request sendReq; |
591 | MPI_Isend(&buf, 1, MPI_DOUBLE, 0, 0, MPI_COMM_WORLD, &sendReq); |
592 | MPI_Irecv(&buf, 1, MPI_DOUBLE, 0, 0, MPI_COMM_WORLD, &sendReq); // warn |
593 | MPI_Isend(&buf, 1, MPI_DOUBLE, 0, 0, MPI_COMM_WORLD, &sendReq); // warn |
594 | MPI_Wait(&sendReq, MPI_STATUS_IGNORE); |
595 | } |
596 | </pre></div><div class="separator"></div> |
597 | <div class="example"><pre> |
598 | void missingNonBlocking() { |
599 | int rank = 0; |
600 | MPI_Comm_rank(MPI_COMM_WORLD, &rank); |
601 | MPI_Request sendReq1[10][10][10]; |
602 | MPI_Wait(&sendReq1[1][7][9], MPI_STATUS_IGNORE); // warn |
603 | } |
604 | </pre></div></div></td></tr> |
605 | |
606 | |
607 | <tr><td><a id="optin.osx.cocoa.localizability.EmptyLocalizationContextChecker"><div class="namedescr expandable"><span class="name"> |
608 | optin.osx.cocoa.localizability.EmptyLocalizationContextChecker</span><span class="lang"> |
609 | (ObjC)</span><div class="descr"> |
610 | Check that NSLocalizedString macros include a comment for context.</div></div></a></td> |
611 | <td><div class="exampleContainer expandable"> |
612 | <div class="example"><pre> |
613 | - (void)test { |
614 | NSString *string = NSLocalizedString(@"LocalizedString", nil); // warn |
615 | NSString *string2 = NSLocalizedString(@"LocalizedString", @" "); // warn |
616 | NSString *string3 = NSLocalizedStringWithDefaultValue( |
617 | @"LocalizedString", nil, [[NSBundle alloc] init], nil,@""); // warn |
618 | } |
619 | </pre></div></div></td></tr> |
620 | |
621 | |
622 | <tr><td><a id="optin.osx.cocoa.localizability.NonLocalizedStringChecker"><div class="namedescr expandable"><span class="name"> |
623 | optin.osx.cocoa.localizability.NonLocalizedStringChecker</span><span class="lang"> |
624 | (ObjC)</span><div class="descr"> |
625 | Warns about uses of non-localized NSStrings passed to UI methods |
626 | expecting localized NSStrings</div></div></a></td> |
627 | <td><div class="exampleContainer expandable"> |
628 | <div class="example"><pre> |
629 | NSString *alarmText = |
630 | NSLocalizedString(@"Enabled", @"Indicates alarm is turned on"); |
631 | if (!isEnabled) { |
632 | alarmText = @"Disabled"; |
633 | } |
634 | UILabel *alarmStateLabel = [[UILabel alloc] init]; |
635 | |
636 | // Warning: User-facing text should use localized string macro |
637 | [alarmStateLabel setText:alarmText]; |
638 | </pre></div></div></td></tr> |
639 | |
640 | </tbody></table> |
641 | |
642 | <!-- =========================== OS X =========================== --> |
643 | <h3 id="osx_checkers">OS X Checkers</h3> |
644 | <table class="checkers"> |
645 | <colgroup><col class="namedescr"><col class="example"></colgroup> |
646 | <thead><tr><td>Name, Description</td><td>Example</td></tr></thead> |
647 | |
648 | <tbody> |
649 | <tr><td><a id="osx.API"><div class="namedescr expandable"><span class="name"> |
650 | osx.API</span><span class="lang"> |
651 | (C)</span><div class="descr"> |
652 | Check for proper uses of various Apple APIs:<div class=functions> |
653 | dispatch_once</div></div></div></a></td> |
654 | <td><div class="exampleContainer expandable"> |
655 | <div class="example"><pre> |
656 | void test() { |
657 | dispatch_once_t pred = 0; |
658 | dispatch_once(&pred, ^(){}); // warn: dispatch_once uses local |
659 | } |
660 | </pre></div></div></td></tr> |
661 | |
662 | |
663 | <tr><td><a id="osx.NumberObjectConversion"><div class="namedescr expandable"><span class="name"> |
664 | osx.NumberObjectConversion</span><span class="lang"> |
665 | (C, C++, ObjC)</span><div class="descr"> |
666 | Check for erroneous conversions of objects representing numbers |
667 | into numbers</div></div></a></td> |
668 | <td><div class="exampleContainer expandable"> |
669 | <div class="example"><pre> |
670 | NSNumber *photoCount = [albumDescriptor objectForKey:@"PhotoCount"]; |
671 | // Warning: Comparing a pointer value of type 'NSNumber *' |
672 | // to a scalar integer value |
673 | if (photoCount > 0) { |
674 | [self displayPhotos]; |
675 | } |
676 | </pre></div></div></td></tr> |
677 | |
678 | |
679 | <tr><td><a id="osx.SecKeychainAPI"><div class="namedescr expandable"><span class="name"> |
680 | osx.SecKeychainAPI</span><span class="lang"> |
681 | (C)</span><div class="descr"> |
682 | Check for improper uses of the Security framework's Keychain APIs:<div class=functions> |
683 | SecKeychainItemCopyContent<br> |
684 | SecKeychainFindGenericPassword<br> |
685 | SecKeychainFindInternetPassword<br> |
686 | SecKeychainItemFreeContent<br> |
687 | SecKeychainItemCopyAttributesAndData<br> |
688 | SecKeychainItemFreeAttributesAndData</div></div></div></a></td> |
689 | <td><div class="exampleContainer expandable"> |
690 | <div class="example"><pre> |
691 | void test() { |
692 | unsigned int *ptr = 0; |
693 | UInt32 length; |
694 | |
695 | SecKeychainItemFreeContent(ptr, &length); |
696 | // warn: trying to free data which has not been allocated |
697 | } |
698 | </pre></div> |
699 | <div class="example"><pre> |
700 | void test() { |
701 | unsigned int *ptr = 0; |
702 | UInt32 *length = 0; |
703 | void *outData; |
704 | |
705 | OSStatus st = |
706 | SecKeychainItemCopyContent(2, ptr, ptr, length, outData); |
707 | // warn: data is not released |
708 | } |
709 | </pre></div> |
710 | <div class="example"><pre> |
711 | void test() { |
712 | unsigned int *ptr = 0; |
713 | UInt32 *length = 0; |
714 | void *outData; |
715 | |
716 | OSStatus st = |
717 | SecKeychainItemCopyContent(2, ptr, ptr, length, &outData); |
718 | |
719 | SecKeychainItemFreeContent(ptr, outData); |
720 | // warn: only call free if a non-NULL buffer was returned |
721 | } |
722 | </pre></div> |
723 | <div class="example"><pre> |
724 | void test() { |
725 | unsigned int *ptr = 0; |
726 | UInt32 *length = 0; |
727 | void *outData; |
728 | |
729 | OSStatus st = |
730 | SecKeychainItemCopyContent(2, ptr, ptr, length, &outData); |
731 | |
732 | st = SecKeychainItemCopyContent(2, ptr, ptr, length, &outData); |
733 | // warn: release data before another call to the allocator |
734 | |
735 | if (st == noErr) |
736 | SecKeychainItemFreeContent(ptr, outData); |
737 | } |
738 | </pre></div> |
739 | <div class="example"><pre> |
740 | void test() { |
741 | SecKeychainItemRef itemRef = 0; |
742 | SecKeychainAttributeInfo *info = 0; |
743 | SecItemClass *itemClass = 0; |
744 | SecKeychainAttributeList *attrList = 0; |
745 | UInt32 *length = 0; |
746 | void *outData = 0; |
747 | |
748 | OSStatus st = |
749 | SecKeychainItemCopyAttributesAndData(itemRef, info, |
750 | itemClass, &attrList, |
751 | length, &outData); |
752 | |
753 | SecKeychainItemFreeContent(attrList, outData); |
754 | // warn: deallocator doesn't match the allocator |
755 | } |
756 | </pre></div></div></td></tr> |
757 | |
758 | |
759 | <tr><td><a id="osx.cocoa.AtSync"><div class="namedescr expandable"><span class="name"> |
760 | osx.cocoa.AtSync</span><span class="lang"> |
761 | (ObjC)</span><div class="descr"> |
762 | Check for nil pointers used as mutexes for <code>@synchronized</code>.</div></div></a></td> |
763 | <td><div class="exampleContainer expandable"> |
764 | <div class="example"><pre> |
765 | void test(id x) { |
766 | if (!x) |
767 | @synchronized(x) {} // warn: nil value used as mutex |
768 | } |
769 | </pre></div> |
770 | <div class="example"><pre> |
771 | void test() { |
772 | id y; |
773 | @synchronized(y) {} // warn: uninitialized value used as mutex |
774 | } |
775 | </pre></div></div></td></tr> |
776 | |
777 | |
778 | <tr><td><a id="osx.cocoa.ClassRelease"><div class="namedescr expandable"><span class="name"> |
779 | osx.cocoa.ClassRelease</span><span class="lang"> |
780 | (ObjC)</span><div class="descr"> |
781 | Check for sending <code>retain</code>, <code>release</code>, or <code> |
782 | autorelease</code> directly to a class.</div></div></a></td> |
783 | <td><div class="exampleContainer expandable"> |
784 | <div class="example"><pre> |
785 | @interface MyClass : NSObject |
786 | @end |
787 | |
788 | void test(void) { |
789 | [MyClass release]; // warn |
790 | } |
791 | </pre></div></div></td></tr> |
792 | |
793 | |
794 | <tr><td><a id="osx.cocoa.Dealloc"><div class="namedescr expandable"><span class="name"> |
795 | osx.cocoa.Dealloc</span><span class="lang"> |
796 | (ObjC)</span><div class="descr"> |
797 | Warn about Objective-C classes that lack a correct implementation |
798 | of <code>-dealloc</code>. |
799 | </div></div></a></td> |
800 | <td><div class="exampleContainer expandable"> |
801 | <div class="example"><pre> |
802 | @interface MyObject : NSObject { |
803 | id _myproperty; |
804 | } |
805 | @end |
806 | |
807 | @implementation MyObject // warn: lacks 'dealloc' |
808 | @end |
809 | </pre></div><div class="separator"></div> |
810 | <div class="example"><pre> |
811 | @interface MyObject : NSObject {} |
812 | @property(assign) id myproperty; |
813 | @end |
814 | |
815 | @implementation MyObject // warn: does not send 'dealloc' to super |
816 | - (void)dealloc { |
817 | self.myproperty = 0; |
818 | } |
819 | @end |
820 | </pre></div><div class="separator"></div> |
821 | <div class="example"><pre> |
822 | @interface MyObject : NSObject { |
823 | id _myproperty; |
824 | } |
825 | @property(retain) id myproperty; |
826 | @end |
827 | |
828 | @implementation MyObject |
829 | @synthesize myproperty = _myproperty; |
830 | // warn: var was retained but wasn't released |
831 | - (void)dealloc { |
832 | [super dealloc]; |
833 | } |
834 | @end |
835 | </pre></div><div class="separator"></div> |
836 | <div class="example"><pre> |
837 | @interface MyObject : NSObject { |
838 | id _myproperty; |
839 | } |
840 | @property(assign) id myproperty; |
841 | @end |
842 | |
843 | @implementation MyObject |
844 | @synthesize myproperty = _myproperty; |
845 | // warn: var wasn't retained but was released |
846 | - (void)dealloc { |
847 | [_myproperty release]; |
848 | [super dealloc]; |
849 | } |
850 | @end |
851 | </pre></div></div></td></tr> |
852 | |
853 | |
854 | <tr><td><a id="osx.cocoa.IncompatibleMethodTypes"><div class="namedescr expandable"><span class="name"> |
855 | osx.cocoa.IncompatibleMethodTypes</span><span class="lang"> |
856 | (ObjC)</span><div class="descr"> |
857 | Check for an incompatible type signature when overriding an Objective-C method.</div></div></a></td> |
858 | <td><div class="exampleContainer expandable"> |
859 | <div class="example"><pre> |
860 | @interface MyClass1 : NSObject |
861 | - (int)foo; |
862 | @end |
863 | |
864 | @implementation MyClass1 |
865 | - (int)foo { return 1; } |
866 | @end |
867 | |
868 | @interface MyClass2 : MyClass1 |
869 | - (float)foo; |
870 | @end |
871 | |
872 | @implementation MyClass2 |
873 | - (float)foo { return 1.0; } // warn |
874 | @end |
875 | </pre></div></div></td></tr> |
876 | |
877 | |
878 | <tr><td><a id="osx.cocoa.MissingSuperCall"><div class="namedescr expandable"><span class="name"> |
879 | osx.cocoa.MissingSuperCall</span><span class="lang"> |
880 | (ObjC)</span><div class="descr"> |
881 | Warn about Objective-C methods that lack a necessary call to super. (Note: The |
882 | compiler now has a warning for methods annotated with <code>objc_requires_super</code> |
883 | attribute. The checker exists to check methods in the Cocoa frameworks |
884 | that haven't yet adopted this attribute.)</div></div></a></td> |
885 | <td><div class="example"><pre> |
886 | @interface Test : UIViewController |
887 | @end |
888 | @implementation test |
889 | - (void)viewDidLoad {} // warn |
890 | @end |
891 | </pre></div></td></tr> |
892 | |
893 | |
894 | <tr><td><a id="osx.cocoa.NSAutoreleasePool"><div class="namedescr expandable"><span class="name"> |
895 | osx.cocoa.NSAutoreleasePool</span><span class="lang"> |
896 | (ObjC)</span><div class="descr"> |
897 | Warn for suboptimal uses of NSAutoreleasePool in Objective-C |
898 | GC mode (<code>-fobjc-gc</code> compiler option).</div></div></a></td> |
899 | <td><div class="exampleContainer expandable"> |
900 | <div class="example"><pre> |
901 | void test() { |
902 | NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; |
903 | [pool release]; // warn |
904 | } |
905 | </pre></div></div></td></tr> |
906 | |
907 | |
908 | <tr><td><a id="osx.cocoa.NSError"><div class="namedescr expandable"><span class="name"> |
909 | osx.cocoa.NSError</span><span class="lang"> |
910 | (ObjC)</span><div class="descr"> |
911 | Check usage of <code>NSError**</code> parameters.</div></div></a></td> |
912 | <td><div class="exampleContainer expandable"> |
913 | <div class="example"><pre> |
914 | @interface A : NSObject |
915 | - (void)foo:(NSError **)error; |
916 | @end |
917 | |
918 | @implementation A |
919 | - (void)foo:(NSError **)error { |
920 | // warn: method accepting NSError** should have a non-void |
921 | // return value |
922 | } |
923 | @end |
924 | </pre></div> |
925 | <div class="example"><pre> |
926 | @interface A : NSObject |
927 | - (BOOL)foo:(NSError **)error; |
928 | @end |
929 | |
930 | @implementation A |
931 | - (BOOL)foo:(NSError **)error { |
932 | *error = 0; // warn: potential null dereference |
933 | return 0; |
934 | } |
935 | @end |
936 | </pre></div></div></td></tr> |
937 | |
938 | |
939 | <tr><td><a id="osx.cocoa.NilArg"><div class="namedescr expandable"><span class="name"> |
940 | osx.cocoa.NilArg</span><span class="lang"> |
941 | (ObjC)</span><div class="descr"> |
942 | Check for prohibited nil arguments in specific Objective-C method calls:<div class=functions> |
943 | - caseInsensitiveCompare:<br> |
944 | - compare:<br> |
945 | - compare:options:<br> |
946 | - compare:options:range:<br> |
947 | - compare:options:range:locale:<br> |
948 | - componentsSeparatedByCharactersInSet:<br> |
949 | - initWithFormat:</div></div></div></a></td> |
950 | <td><div class="exampleContainer expandable"> |
951 | <div class="example"><pre> |
952 | NSComparisonResult test(NSString *s) { |
953 | NSString *aString = nil; |
954 | return [s caseInsensitiveCompare:aString]; |
955 | // warn: argument to 'NSString' method |
956 | // 'caseInsensitiveCompare:' cannot be nil |
957 | } |
958 | </pre></div></div></td></tr> |
959 | |
960 | |
961 | <tr><td><a id="osx.cocoa.ObjCGenerics"><div class="namedescr expandable"><span class="name"> |
962 | osx.cocoa.ObjCGenerics</span><span class="lang"> |
963 | (ObjC)</span><div class="descr"> |
964 | Check for type errors when using Objective-C generics</div></div></a></td> |
965 | <td><div class="exampleContainer expandable"> |
966 | <div class="example"><pre> |
967 | NSMutableArray<NSString *> *names = [NSMutableArray array]; |
968 | NSMutableArray *birthDates = names; |
969 | |
970 | // Warning: Conversion from value of type 'NSDate *' |
971 | // to incompatible type 'NSString *' |
972 | [birthDates addObject: [NSDate date]]; |
973 | </pre></div></div></td></tr> |
974 | |
975 | |
976 | <tr><td><a id="osx.cocoa.RetainCount"><div class="namedescr expandable"><span class="name"> |
977 | osx.cocoa.RetainCount</span><span class="lang"> |
978 | (ObjC)</span><div class="descr"> |
979 | Check for leaks and violations of the Cocoa Memory Management rules.</div></div></a></td> |
980 | <td><div class="exampleContainer expandable"> |
981 | <div class="example"><pre> |
982 | void test() { |
983 | NSString *s = [[NSString alloc] init]; // warn |
984 | } |
985 | </pre></div> |
986 | <div class="example"><pre> |
987 | CFStringRef test(char *bytes) { |
988 | return CFStringCreateWithCStringNoCopy( |
989 | 0, bytes, NSNEXTSTEPStringEncoding, 0); // warn |
990 | } |
991 | </pre></div></div></td></tr> |
992 | |
993 | |
994 | <tr><td><a id="osx.cocoa.SelfInit"><div class="namedescr expandable"><span class="name"> |
995 | osx.cocoa.SelfInit</span><span class="lang"> |
996 | (ObjC)</span><div class="descr"> |
997 | Check that <code>self</code> is properly initialized inside an initializer |
998 | method.</div></div></a></td> |
999 | <td><div class="exampleContainer expandable"> |
1000 | <div class="example"><pre> |
1001 | @interface MyObj : NSObject { |
1002 | id x; |
1003 | } |
1004 | - (id)init; |
1005 | @end |
1006 | |
1007 | @implementation MyObj |
1008 | - (id)init { |
1009 | [super init]; |
1010 | x = 0; // warn: instance variable used while 'self' is not |
1011 | // initialized |
1012 | return 0; |
1013 | } |
1014 | @end |
1015 | </pre></div> |
1016 | <div class="example"><pre> |
1017 | @interface MyObj : NSObject |
1018 | - (id)init; |
1019 | @end |
1020 | |
1021 | @implementation MyObj |
1022 | - (id)init { |
1023 | [super init]; |
1024 | return self; // warn: returning uninitialized 'self' |
1025 | } |
1026 | @end |
1027 | </pre></div></div></td></tr> |
1028 | |
1029 | |
1030 | <tr><td><a id="osx.cocoa.SuperDealloc"><div class="namedescr expandable"><span class="name"> |
1031 | osx.cocoa.SuperDealloc</span><span class="lang"> |
1032 | (ObjC)</span><div class="descr"> |
1033 | Warn about improper use of '[super dealloc]' in Objective-C</div></div></a></td> |
1034 | <td><div class="exampleContainer expandable"> |
1035 | <div class="example"><pre> |
1036 | @interface SuperDeallocThenReleaseIvarClass : NSObject { |
1037 | NSObject *_ivar; |
1038 | } |
1039 | @end |
1040 | |
1041 | @implementation SuperDeallocThenReleaseIvarClass |
1042 | - (void)dealloc { |
1043 | [super dealloc]; |
1044 | [_ivar release]; // warn |
1045 | } |
1046 | @end |
1047 | </pre></div></div></td></tr> |
1048 | |
1049 | |
1050 | <tr><td><a id="osx.cocoa.UnusedIvars"><div class="namedescr expandable"><span class="name"> |
1051 | osx.cocoa.UnusedIvars</span><span class="lang"> |
1052 | (ObjC)</span><div class="descr"> |
1053 | Warn about private ivars that are never used.</div></div></a></td> |
1054 | <td><div class="exampleContainer expandable"> |
1055 | <div class="example"><pre> |
1056 | @interface MyObj : NSObject { |
1057 | @private |
1058 | id x; // warn |
1059 | } |
1060 | @end |
1061 | |
1062 | @implementation MyObj |
1063 | @end |
1064 | </pre></div></div></td></tr> |
1065 | |
1066 | |
1067 | <tr><td><a id="osx.cocoa.VariadicMethodTypes"><div class="namedescr expandable"><span class="name"> |
1068 | osx.cocoa.VariadicMethodTypes</span><span class="lang"> |
1069 | (ObjC)</span><div class="descr"> |
1070 | Check for passing non-Objective-C types to variadic collection initialization |
1071 | methods that expect only Objective-C types.</div></div></a></td> |
1072 | <td><div class="exampleContainer expandable"> |
1073 | <div class="example"><pre> |
1074 | void test() { |
1075 | [NSSet setWithObjects:@"Foo", "Bar", nil]; |
1076 | // warn: argument should be an ObjC pointer type, not 'char *' |
1077 | } |
1078 | </pre></div></div></td></tr> |
1079 | |
1080 | |
1081 | <tr><td><a id="osx.coreFoundation.CFError"><div class="namedescr expandable"><span class="name"> |
1082 | osx.coreFoundation.CFError</span><span class="lang"> |
1083 | (C)</span><div class="descr"> |
1084 | Check usage of <code>CFErrorRef*</code> parameters.</div></div></a></td> |
1085 | <td><div class="exampleContainer expandable"> |
1086 | <div class="example"><pre> |
1087 | void test(CFErrorRef *error) { |
1088 | // warn: function accepting CFErrorRef* should have a |
1089 | // non-void return |
1090 | } |
1091 | </pre></div> |
1092 | <div class="example"><pre> |
1093 | int foo(CFErrorRef *error) { |
1094 | *error = 0; // warn: potential null dereference |
1095 | return 0; |
1096 | } |
1097 | </pre></div></div></td></tr> |
1098 | |
1099 | |
1100 | <tr><td><a id="osx.coreFoundation.CFNumber"><div class="namedescr expandable"><span class="name"> |
1101 | osx.coreFoundation.CFNumber</span><span class="lang"> |
1102 | (C)</span><div class="descr"> |
1103 | Check for improper uses of <code>CFNumberCreate</code>.</div></div></a></td> |
1104 | <td><div class="exampleContainer expandable"> |
1105 | <div class="example"><pre> |
1106 | CFNumberRef test(unsigned char x) { |
1107 | return CFNumberCreate(0, kCFNumberSInt16Type, &x); |
1108 | // warn: 8 bit integer is used to initialize a 16 bit integer |
1109 | } |
1110 | </pre></div></div></td></tr> |
1111 | |
1112 | |
1113 | <tr><td><a id="osx.coreFoundation.CFRetainRelease"><div class="namedescr expandable"><span class="name"> |
1114 | osx.coreFoundation.CFRetainRelease</span><span class="lang"> |
1115 | (C)</span><div class="descr"> |
1116 | Check for null arguments to <code>CFRetain</code>, <code>CFRelease</code>, |
1117 | <code>CFMakeCollectable</code>.</div></div></a></td> |
1118 | <td><div class="exampleContainer expandable"> |
1119 | <div class="example"><pre> |
1120 | void test(CFTypeRef p) { |
1121 | if (!p) |
1122 | CFRetain(p); // warn |
1123 | } |
1124 | </pre></div> |
1125 | <div class="example"><pre> |
1126 | void test(int x, CFTypeRef p) { |
1127 | if (p) |
1128 | return; |
1129 | |
1130 | CFRelease(p); // warn |
1131 | } |
1132 | </pre></div></div></td></tr> |
1133 | |
1134 | |
1135 | <tr><td><a id="osx.coreFoundation.containers.OutOfBounds"><div class="namedescr expandable"><span class="name"> |
1136 | osx.coreFoundation.containers.OutOfBounds</span><span class="lang"> |
1137 | (C)</span><div class="descr"> |
1138 | Checks for index out-of-bounds when using <code>CFArray</code> API.</div></div></a></td> |
1139 | <td><div class="exampleContainer expandable"> |
1140 | <div class="example"><pre> |
1141 | void test() { |
1142 | CFArrayRef A = CFArrayCreate(0, 0, 0, &kCFTypeArrayCallBacks); |
1143 | CFArrayGetValueAtIndex(A, 0); // warn |
1144 | } |
1145 | </pre></div></div></td></tr> |
1146 | |
1147 | |
1148 | <tr><td><a id="osx.coreFoundation.containers.PointerSizedValues"><div class="namedescr expandable"><span class="name"> |
1149 | osx.coreFoundation.containers.PointerSizedValues</span><span class="lang"> |
1150 | (C)</span><div class="descr"> |
1151 | Warns if <code>CFArray</code>, <code>CFDictionary</code>, <code>CFSet</code> are |
1152 | created with non-pointer-size values.</div></div></a></td> |
1153 | <td><div class="exampleContainer expandable"> |
1154 | <div class="example"><pre> |
1155 | void test() { |
1156 | int x[] = { 1 }; |
1157 | CFArrayRef A = CFArrayCreate(0, (const void **)x, 1, |
1158 | &kCFTypeArrayCallBacks); // warn |
1159 | } |
1160 | </pre></div></div></td></tr> |
1161 | |
1162 | </tbody></table> |
1163 | |
1164 | <!-- =========================== security =========================== --> |
1165 | <h3 id="security_checkers">Security Checkers</h3> |
1166 | <table class="checkers"> |
1167 | <colgroup><col class="namedescr"><col class="example"></colgroup> |
1168 | <thead><tr><td>Name, Description</td><td>Example</td></tr></thead> |
1169 | |
1170 | <tbody> |
1171 | <tr><td><a id="security.FloatLoopCounter"><div class="namedescr expandable"><span class="name"> |
1172 | security.FloatLoopCounter</span><span class="lang"> |
1173 | (C)</span><div class="descr"> |
1174 | Warn on using a floating point value as a loop counter (CERT: FLP30-C, |
1175 | FLP30-CPP).</div></div></a></td> |
1176 | <td><div class="exampleContainer expandable"> |
1177 | <div class="example"><pre> |
1178 | void test() { |
1179 | for (float x = 0.1f; x <= 1.0f; x += 0.1f) {} // warn |
1180 | } |
1181 | </pre></div></div></td></tr> |
1182 | |
1183 | |
1184 | <tr><td><a id="security.insecureAPI.UncheckedReturn"><div class="namedescr expandable"><span class="name"> |
1185 | security.insecureAPI.UncheckedReturn</span><span class="lang"> |
1186 | (C)</span><div class="descr"> |
1187 | Warn on uses of functions whose return values must be always checked:<div class=functions> |
1188 | setuid<br> |
1189 | setgid<br> |
1190 | seteuid<br> |
1191 | setegid<br> |
1192 | setreuid<br> |
1193 | setregid</div></div></div></a></td> |
1194 | <td><div class="exampleContainer expandable"> |
1195 | <div class="example"><pre> |
1196 | void test() { |
1197 | setuid(1); // warn |
1198 | } |
1199 | </pre></div></div></td></tr> |
1200 | |
1201 | |
1202 | <tr><td><a id="security.insecureAPI.bcmp"><div class="namedescr expandable"><span class="name"> |
1203 | security.insecureAPI.bcmp</span><span class="lang"> |
1204 | (C)</span><div class="descr"> |
1205 | Warn on uses of the <code>bcmp</code> function.</div></div></a></td> |
1206 | <td><div class="exampleContainer expandable"> |
1207 | <div class="example"><pre> |
1208 | void test() { |
1209 | bcmp(ptr0, ptr1, n); // warn |
1210 | } |
1211 | </pre></div></div></td></tr> |
1212 | |
1213 | <tr><td><a id="security.insecureAPI.bcopy"><div class="namedescr expandable"><span class="name"> |
1214 | security.insecureAPI.bcopy</span><span class="lang"> |
1215 | (C)</span><div class="descr"> |
1216 | Warn on uses of the <code>bcopy</code> function.</div></div></a></td> |
1217 | <td><div class="exampleContainer expandable"> |
1218 | <div class="example"><pre> |
1219 | void test() { |
1220 | bcopy(src, dst, n); // warn |
1221 | } |
1222 | </pre></div></div></td></tr> |
1223 | |
1224 | <tr><td><a id="security.insecureAPI.bzero"><div class="namedescr expandable"><span class="name"> |
1225 | security.insecureAPI.bzero</span><span class="lang"> |
1226 | (C)</span><div class="descr"> |
1227 | Warn on uses of the <code>bzero</code> function.</div></div></a></td> |
1228 | <td><div class="exampleContainer expandable"> |
1229 | <div class="example"><pre> |
1230 | void test() { |
1231 | bzero(ptr, n); // warn |
1232 | } |
1233 | </pre></div></div></td></tr> |
1234 | |
1235 | |
1236 | <tr><td><a id="security.insecureAPI.getpw"><div class="namedescr expandable"><span class="name"> |
1237 | security.insecureAPI.getpw</span><span class="lang"> |
1238 | (C)</span><div class="descr"> |
1239 | Warn on uses of the <code>getpw</code> function.</div></div></a></td> |
1240 | <td><div class="exampleContainer expandable"> |
1241 | <div class="example"><pre> |
1242 | void test() { |
1243 | char buff[1024]; |
1244 | getpw(2, buff); // warn |
1245 | } |
1246 | </pre></div></div></td></tr> |
1247 | |
1248 | |
1249 | <tr><td><a id="security.insecureAPI.gets"><div class="namedescr expandable"><span class="name"> |
1250 | security.insecureAPI.gets</span><span class="lang"> |
1251 | (C)</span><div class="descr"> |
1252 | Warn on uses of the <code>gets</code> function.</div></div></a></td> |
1253 | <td><div class="exampleContainer expandable"> |
1254 | <div class="example"><pre> |
1255 | void test() { |
1256 | char buff[1024]; |
1257 | gets(buff); // warn |
1258 | } |
1259 | </pre></div></div></td></tr> |
1260 | |
1261 | |
1262 | <tr><td><a id="security.insecureAPI.mkstemp"><div class="namedescr expandable"><span class="name"> |
1263 | security.insecureAPI.mkstemp</span><span class="lang"> |
1264 | (C)</span><div class="descr"> |
1265 | Warn when <code>mktemp</code>, <code>mkstemp</code>, <code>mkstemps</code> or |
1266 | <code>mkdtemp</code> is passed fewer than 6 |
1267 | X's in the format string.</div></div></a></td> |
1268 | <td><div class="exampleContainer expandable"> |
1269 | <div class="example"><pre> |
1270 | void test() { |
1271 | mkstemp("XX"); // warn |
1272 | } |
1273 | </pre></div></div></td></tr> |
1274 | |
1275 | |
1276 | <tr><td><a id="security.insecureAPI.mktemp"><div class="namedescr expandable"><span class="name"> |
1277 | security.insecureAPI.mktemp</span><span class="lang"> |
1278 | (C)</span><div class="descr"> |
1279 | Warn on uses of the <code>mktemp</code> function.</div></div></a></td> |
1280 | <td><div class="exampleContainer expandable"> |
1281 | <div class="example"><pre> |
1282 | void test() { |
1283 | char *x = mktemp("/tmp/zxcv"); // warn: insecure, use mkstemp |
1284 | } |
1285 | </pre></div></div></td></tr> |
1286 | |
1287 | |
1288 | <tr><td><a id="security.insecureAPI.rand"><div class="namedescr expandable"><span class="name"> |
1289 | security.insecureAPI.rand</span><span class="lang"> |
1290 | (C)</span><div class="descr"> |
1291 | Warn on uses of inferior random number generating functions (only if <code>arc4random</code> |
1292 | function is available):<div class=functions> |
1293 | drand48<br> |
1294 | erand48<br> |
1295 | jrand48<br> |
1296 | lcong48<br> |
1297 | lrand48<br> |
1298 | mrand48<br> |
1299 | nrand48<br> |
1300 | random<br> |
1301 | rand_r</div></div></div></a></td> |
1302 | <td><div class="exampleContainer expandable"> |
1303 | <div class="example"><pre> |
1304 | void test() { |
1305 | random(); // warn |
1306 | } |
1307 | </pre></div></div></td></tr> |
1308 | |
1309 | |
1310 | <tr><td><a id="security.insecureAPI.strcpy"><div class="namedescr expandable"><span class="name"> |
1311 | security.insecureAPI.strcpy</span><span class="lang"> |
1312 | (C)</span><div class="descr"> |
1313 | Warn on uses of the <code>strcpy</code> and <code>strcat</code> functions.</div></div></a></td> |
1314 | <td><div class="exampleContainer expandable"> |
1315 | <div class="example"><pre> |
1316 | void test() { |
1317 | char x[4]; |
1318 | char *y = "abcd"; |
1319 | |
1320 | strcpy(x, y); // warn |
1321 | } |
1322 | </pre></div></div></td></tr> |
1323 | |
1324 | |
1325 | <tr><td><a id="security.insecureAPI.vfork"><div class="namedescr expandable"><span class="name"> |
1326 | security.insecureAPI.vfork</span><span class="lang"> |
1327 | (C)</span><div class="descr"> |
1328 | Warn on uses of the <code>vfork</code> function.</div></div></a></td> |
1329 | <td><div class="exampleContainer expandable"> |
1330 | <div class="example"><pre> |
1331 | void test() { |
1332 | vfork(); // warn |
1333 | } |
1334 | </pre></div></div></td></tr> |
1335 | |
1336 | </tbody></table> |
1337 | |
1338 | <!-- =========================== unix =========================== --> |
1339 | <h3 id="unix_checkers">Unix Checkers</h3> |
1340 | <table class="checkers"> |
1341 | <colgroup><col class="namedescr"><col class="example"></colgroup> |
1342 | <thead><tr><td>Name, Description</td><td>Example</td></tr></thead> |
1343 | |
1344 | <tbody> |
1345 | <tr><td><a id="unix.API"><div class="namedescr expandable"><span class="name"> |
1346 | unix.API</span><span class="lang"> |
1347 | (C)</span><div class="descr"> |
1348 | Check calls to various UNIX/POSIX functions:<div class=functions> |
1349 | open<br> |
1350 | pthread_once<br> |
1351 | calloc<br> |
1352 | malloc<br> |
1353 | realloc<br> |
1354 | alloca<br></a></td> |
1355 | <td><div class="exampleContainer expandable"> |
1356 | <div class="example"><pre> |
1357 | // Currently the check is performed for apple targets only. |
1358 | void test(const char *path) { |
1359 | int fd = open(path, O_CREAT); |
1360 | // warn: call to 'open' requires a third argument when the |
1361 | // 'O_CREAT' flag is set |
1362 | } |
1363 | </pre></div> |
1364 | <div class="example"><pre> |
1365 | void f(); |
1366 | |
1367 | void test() { |
1368 | pthread_once_t pred = {0x30B1BCBA, {0}}; |
1369 | pthread_once(&pred, f); |
1370 | // warn: call to 'pthread_once' uses the local variable |
1371 | } |
1372 | </pre></div> |
1373 | <div class="example"><pre> |
1374 | void test() { |
1375 | void *p = malloc(0); // warn: allocation size of 0 bytes |
1376 | } |
1377 | </pre></div> |
1378 | <div class="example"><pre> |
1379 | void test() { |
1380 | void *p = calloc(0, 42); // warn: allocation size of 0 bytes |
1381 | } |
1382 | </pre></div> |
1383 | <div class="example"><pre> |
1384 | void test() { |
1385 | void *p = malloc(1); |
1386 | p = realloc(p, 0); // warn: allocation size of 0 bytes |
1387 | } |
1388 | </pre></div> |
1389 | <div class="example"><pre> |
1390 | void test() { |
1391 | void *p = alloca(0); // warn: allocation size of 0 bytes |
1392 | } |
1393 | </pre></div> |
1394 | <div class="example"><pre> |
1395 | void test() { |
1396 | void *p = valloc(0); // warn: allocation size of 0 bytes |
1397 | } |
1398 | </pre></div></div></td></tr> |
1399 | |
1400 | |
1401 | <tr><td><a id="unix.Malloc"><div class="namedescr expandable"><span class="name"> |
1402 | unix.Malloc</span><span class="lang"> |
1403 | (C)</span><div class="descr"> |
1404 | Check for memory leaks, double free, and use-after-free and offset problems |
1405 | involving <code>malloc</code>.</div></div></a></td> |
1406 | <td><div class="exampleContainer expandable"> |
1407 | <div class="example"><pre> |
1408 | void test() { |
1409 | int *p = malloc(1); |
1410 | free(p); |
1411 | free(p); // warn: attempt to free released memory |
1412 | } |
1413 | </pre></div> |
1414 | <div class="example"><pre> |
1415 | void test() { |
1416 | int *p = malloc(sizeof(int)); |
1417 | free(p); |
1418 | *p = 1; // warn: use after free |
1419 | } |
1420 | </pre></div> |
1421 | <div class="example"><pre> |
1422 | void test() { |
1423 | int *p = malloc(1); |
1424 | if (p) |
1425 | return; // warn: memory is never released |
1426 | } |
1427 | </pre></div> |
1428 | <div class="example"><pre> |
1429 | void test() { |
1430 | int a[] = { 1 }; |
1431 | free(a); // warn: argument is not allocated by malloc |
1432 | } |
1433 | </pre></div> |
1434 | <div class="example"><pre> |
1435 | void test() { |
1436 | int *p = malloc(sizeof(char)); |
1437 | p = p - 1; |
1438 | free(p); // warn: argument to free() is offset by -4 bytes |
1439 | } |
1440 | </pre></div></div></td></tr> |
1441 | |
1442 | |
1443 | <tr><td><a id="unix.MallocSizeof"><div class="namedescr expandable"><span class="name"> |
1444 | unix.MallocSizeof</span><span class="lang"> |
1445 | (C)</span><div class="descr"> |
1446 | Check for dubious <code>malloc</code>, <code>calloc</code> or |
1447 | <code>realloc</code> arguments involving <code>sizeof</code>.</div></div></a></td> |
1448 | <td><div class="exampleContainer expandable"> |
1449 | <div class="example"><pre> |
1450 | void test() { |
1451 | long *p = malloc(sizeof(short)); |
1452 | // warn: result is converted to 'long *', which is |
1453 | // incompatible with operand type 'short' |
1454 | free(p); |
1455 | } |
1456 | </pre></div></div></td></tr> |
1457 | |
1458 | |
1459 | <tr><td><a id="unix.MismatchedDeallocator"><div class="namedescr expandable"><span class="name"> |
1460 | unix.MismatchedDeallocator</span><span class="lang"> |
1461 | (C, C++, ObjC)</span><div class="descr"> |
1462 | Check for mismatched deallocators (e.g. passing a pointer allocating |
1463 | with <code>new</code> to <code>free()</code>).</div></div></a></td> |
1464 | <td><div class="exampleContainer expandable"> |
1465 | <div class="example"><pre> |
1466 | // C, C++ |
1467 | void test() { |
1468 | int *p = (int *)malloc(sizeof(int)); |
1469 | delete p; // warn |
1470 | } |
1471 | </pre></div> |
1472 | <div class="example"><pre> |
1473 | // C, C++ |
1474 | void __attribute((ownership_returns(malloc))) *user_malloc(size_t); |
1475 | |
1476 | void test() { |
1477 | int *p = (int *)user_malloc(sizeof(int)); |
1478 | delete p; // warn |
1479 | } |
1480 | </pre></div> |
1481 | <div class="example"><pre> |
1482 | // C, C++ |
1483 | void test() { |
1484 | int *p = new int; |
1485 | free(p); // warn |
1486 | } |
1487 | </pre></div> |
1488 | <div class="example"><pre> |
1489 | // C, C++ |
1490 | void test() { |
1491 | int *p = new int[1]; |
1492 | realloc(p, sizeof(long)); // warn |
1493 | } |
1494 | </pre></div> |
1495 | <div class="example"><pre> |
1496 | // C, C++ |
1497 | template <typename T> |
1498 | struct SimpleSmartPointer { |
1499 | T *ptr; |
1500 | |
1501 | explicit SimpleSmartPointer(T *p = 0) : ptr(p) {} |
1502 | ~SimpleSmartPointer() { |
1503 | delete ptr; // warn |
1504 | } |
1505 | }; |
1506 | |
1507 | void test() { |
1508 | SimpleSmartPointer<int> a((int *)malloc(4)); |
1509 | } |
1510 | </pre></div> |
1511 | <div class="example"><pre> |
1512 | // C++ |
1513 | void test() { |
1514 | int *p = (int *)operator new(0); |
1515 | delete[] p; // warn |
1516 | } |
1517 | </pre></div> |
1518 | <div class="example"><pre> |
1519 | // Objective-C, C++ |
1520 | void test(NSUInteger dataLength) { |
1521 | int *p = new int; |
1522 | NSData *d = [NSData dataWithBytesNoCopy:p |
1523 | length:sizeof(int) freeWhenDone:1]; |
1524 | // warn +dataWithBytesNoCopy:length:freeWhenDone: cannot take |
1525 | // ownership of memory allocated by 'new' |
1526 | } |
1527 | </pre></div></div></td></tr> |
1528 | |
1529 | |
1530 | <tr><td><a id="unix.Vfork"><div class="namedescr expandable"><span class="name"> |
1531 | unix.Vfork</span><span class="lang"> |
1532 | (C)</span><div class="descr"> |
1533 | Check for proper usage of vfork</div></div></a></td> |
1534 | <td><div class="exampleContainer expandable"> |
1535 | <div class="example"><pre> |
1536 | int test(int x) { |
1537 | pid_t pid = vfork(); // warn |
1538 | if (pid != 0) |
1539 | return 0; |
1540 | |
1541 | switch (x) { |
1542 | case 0: |
1543 | pid = 1; |
1544 | execl("", "", 0); |
1545 | _exit(1); |
1546 | break; |
1547 | case 1: |
1548 | x = 0; // warn: this assignment is prohibited |
1549 | break; |
1550 | case 2: |
1551 | foo(); // warn: this function call is prohibited |
1552 | break; |
1553 | default: |
1554 | return 0; // warn: return is prohibited |
1555 | } |
1556 | |
1557 | while(1); |
1558 | } |
1559 | </pre></div></div></td></tr> |
1560 | |
1561 | |
1562 | <tr><td><a id="unix.cstring.BadSizeArg"><div class="namedescr expandable"><span class="name"> |
1563 | unix.cstring.BadSizeArg</span><span class="lang"> |
1564 | (C)</span><div class="descr"> |
1565 | Check the size argument passed to <code>strncat</code> for common erroneous |
1566 | patterns. Use <code>-Wno-strncat-size</code> compiler option to mute other |
1567 | <code>strncat</code>-related compiler warnings. |
1568 | </div></div></a></td> |
1569 | <td><div class="exampleContainer expandable"> |
1570 | <div class="example"><pre> |
1571 | void test() { |
1572 | char dest[3]; |
1573 | strncat(dest, "***", sizeof(dest)); |
1574 | // warn: potential buffer overflow |
1575 | } |
1576 | </pre></div></div></td></tr> |
1577 | |
1578 | |
1579 | <tr><td><a id="unix.cstring.NullArg"><div class="namedescr expandable"><span class="name"> |
1580 | unix.cstring.NullArg</span><span class="lang"> |
1581 | (C)</span><div class="descr"> |
1582 | Check for null pointers being passed as arguments to C string functions:<div class=functions> |
1583 | strlen<br> |
1584 | strnlen<br> |
1585 | strcpy<br> |
1586 | strncpy<br> |
1587 | strcat<br> |
1588 | strncat<br> |
1589 | strcmp<br> |
1590 | strncmp<br> |
1591 | strcasecmp<br> |
1592 | strncasecmp</div></div></div></a></td> |
1593 | <td><div class="example"><pre> |
1594 | int test() { |
1595 | return strlen(0); // warn |
1596 | } |
1597 | </pre></div></td></tr> |
1598 | |
1599 | </tbody></table> |
1600 | |
1601 | </div> <!-- page --> |
1602 | </div> <!-- content --> |
1603 | </body> |
1604 | </html> |
1605 | |