xref: /aosp_15_r20/external/clang/www/analyzer/available_checks.html (revision 67e74705e28f6214e480b399dd47ea732279e315)
1*67e74705SXin Li<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
2*67e74705SXin Li          "http://www.w3.org/TR/html4/strict.dtd">
3*67e74705SXin Li<html>
4*67e74705SXin Li<head>
5*67e74705SXin Li  <title>Available Checkers</title>
6*67e74705SXin Li  <link type="text/css" rel="stylesheet" href="menu.css">
7*67e74705SXin Li  <link type="text/css" rel="stylesheet" href="content.css">
8*67e74705SXin Li  <script type="text/javascript" src="scripts/menu.js"></script>
9*67e74705SXin Li  <script type="text/javascript" src="scripts/expandcollapse.js"></script>
10*67e74705SXin Li  <style type="text/css">
11*67e74705SXin Li  tr:first-child { width:20%; }
12*67e74705SXin Li  </style>
13*67e74705SXin Li</head>
14*67e74705SXin Li<body onload="initExpandCollapse()">
15*67e74705SXin Li
16*67e74705SXin Li<div id="page">
17*67e74705SXin Li<!--#include virtual="menu.html.incl"-->
18*67e74705SXin Li
19*67e74705SXin Li<div id="content">
20*67e74705SXin Li<h1>Available Checkers</h1>
21*67e74705SXin LiThe analyzer performs checks that are categorized into families or "checkers". The
22*67e74705SXin Lidefault set of checkers covers a variety of checks targeted at finding security
23*67e74705SXin Liand API usage bugs, dead code, and other logic errors. See the
24*67e74705SXin Li<a href = "#default_checkers">Default Checkers</a> list below. In addition to
25*67e74705SXin Lithese, the analyzer contains a number of <a href = "alpha_checks.html">
26*67e74705SXin LiExperimental (Alpha) Checkers</a>.
27*67e74705SXin Li
28*67e74705SXin Li<h3>Writeups with examples of some of the bugs that the analyzer finds</h3>
29*67e74705SXin Li<ul>
30*67e74705SXin Li<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*67e74705SXin Li<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*67e74705SXin Li<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*67e74705SXin Li<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*67e74705SXin Li</ul>
35*67e74705SXin Li
36*67e74705SXin Li<h2 id="default_checkers">Default Checkers</h2>
37*67e74705SXin Li<ul>
38*67e74705SXin Li<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*67e74705SXin Li<li><a href="#cplusplus_checkers">C++ Checkers</a> perform C++-specific checks</li>
40*67e74705SXin Li<li><a href="#deadcode_checkers">Dead Code Checkers</a> check for unused code</li>
41*67e74705SXin Li<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>
42*67e74705SXin Li<li><a href="#security_checkers">Security Checkers</a> check for insecure API usage and perform checks based on the CERT Secure Coding Standards</li>
43*67e74705SXin Li<li><a href="#unix_checkers">Unix Checkers</a> check the use of Unix and POSIX APIs</li>
44*67e74705SXin Li</ul>
45*67e74705SXin Li
46*67e74705SXin Li<!------------------------------------ core ----------------------------------->
47*67e74705SXin Li<h3 id="core_checkers">Core Checkers</h3>
48*67e74705SXin Li<table class="checkers">
49*67e74705SXin Li<colgroup><col class="namedescr"><col class="example"></colgroup>
50*67e74705SXin Li<thead><tr><td>Name, Description</td><td>Example</td></tr></thead>
51*67e74705SXin Li
52*67e74705SXin Li<tbody>
53*67e74705SXin Li<tr><td><div class="namedescr expandable"><span class="name">
54*67e74705SXin Licore.CallAndMessage</span><span class="lang">
55*67e74705SXin Li(C, C++, ObjC)</span><div class="descr">
56*67e74705SXin LiCheck for logical errors for function calls and Objective-C message expressions
57*67e74705SXin Li(e.g., uninitialized arguments, null function pointers).</div></div></td>
58*67e74705SXin Li<td><div class="exampleContainer expandable">
59*67e74705SXin Li<div class="example"><pre>
60*67e74705SXin Li// C
61*67e74705SXin Listruct S {
62*67e74705SXin Li  int x;
63*67e74705SXin Li};
64*67e74705SXin Li
65*67e74705SXin Livoid f(struct S s);
66*67e74705SXin Li
67*67e74705SXin Livoid test() {
68*67e74705SXin Li  struct S s;
69*67e74705SXin Li  f(s); // warn: passed-by-value arg contain uninitialized data
70*67e74705SXin Li}
71*67e74705SXin Li</pre></div>
72*67e74705SXin Li<div class="example"><pre>
73*67e74705SXin Li// C
74*67e74705SXin Livoid test() {
75*67e74705SXin Li  void (*foo)(void);
76*67e74705SXin Li  foo(); // warn: function pointer is uninitialized
77*67e74705SXin Li}
78*67e74705SXin Li</pre></div>
79*67e74705SXin Li<div class="example"><pre>
80*67e74705SXin Li// C
81*67e74705SXin Livoid test() {
82*67e74705SXin Li  void (*foo)(void);
83*67e74705SXin Li  foo = 0;
84*67e74705SXin Li  foo(); // warn: function pointer is null
85*67e74705SXin Li}
86*67e74705SXin Li</pre></div>
87*67e74705SXin Li<div class="example"><pre>
88*67e74705SXin Li// C++
89*67e74705SXin Liclass C {
90*67e74705SXin Lipublic:
91*67e74705SXin Li  void f();
92*67e74705SXin Li};
93*67e74705SXin Li
94*67e74705SXin Livoid test() {
95*67e74705SXin Li  C *pc;
96*67e74705SXin Li  pc-&gt;f(); // warn: object pointer is uninitialized
97*67e74705SXin Li}
98*67e74705SXin Li</pre></div>
99*67e74705SXin Li<div class="example"><pre>
100*67e74705SXin Li// C++
101*67e74705SXin Liclass C {
102*67e74705SXin Lipublic:
103*67e74705SXin Li  void f();
104*67e74705SXin Li};
105*67e74705SXin Li
106*67e74705SXin Livoid test() {
107*67e74705SXin Li  C *pc = 0;
108*67e74705SXin Li  pc-&gt;f(); // warn: object pointer is null
109*67e74705SXin Li}
110*67e74705SXin Li</pre></div>
111*67e74705SXin Li<div class="example"><pre>
112*67e74705SXin Li// Objective-C
113*67e74705SXin Li@interface MyClass : NSObject
114*67e74705SXin Li@property (readwrite,assign) id x;
115*67e74705SXin Li- (long double)longDoubleM;
116*67e74705SXin Li@end
117*67e74705SXin Li
118*67e74705SXin Livoid test() {
119*67e74705SXin Li  MyClass *obj1;
120*67e74705SXin Li  long double ld1 = [obj1 longDoubleM];
121*67e74705SXin Li    // warn: receiver is uninitialized
122*67e74705SXin Li}
123*67e74705SXin Li</pre></div>
124*67e74705SXin Li<div class="example"><pre>
125*67e74705SXin Li// Objective-C
126*67e74705SXin Li@interface MyClass : NSObject
127*67e74705SXin Li@property (readwrite,assign) id x;
128*67e74705SXin Li- (long double)longDoubleM;
129*67e74705SXin Li@end
130*67e74705SXin Li
131*67e74705SXin Livoid test() {
132*67e74705SXin Li  MyClass *obj1;
133*67e74705SXin Li  id i = obj1.x; // warn: uninitialized object pointer
134*67e74705SXin Li}
135*67e74705SXin Li</pre></div>
136*67e74705SXin Li<div class="example"><pre>
137*67e74705SXin Li// Objective-C
138*67e74705SXin Li@interface Subscriptable : NSObject
139*67e74705SXin Li- (id)objectAtIndexedSubscript:(unsigned int)index;
140*67e74705SXin Li@end
141*67e74705SXin Li
142*67e74705SXin Li@interface MyClass : Subscriptable
143*67e74705SXin Li@property (readwrite,assign) id x;
144*67e74705SXin Li- (long double)longDoubleM;
145*67e74705SXin Li@end
146*67e74705SXin Li
147*67e74705SXin Livoid test() {
148*67e74705SXin Li  MyClass *obj1;
149*67e74705SXin Li  id i = obj1[0]; // warn: uninitialized object pointer
150*67e74705SXin Li}
151*67e74705SXin Li</pre></div></div></td></tr>
152*67e74705SXin Li
153*67e74705SXin Li
154*67e74705SXin Li<tr><td><div class="namedescr expandable"><span class="name">
155*67e74705SXin Licore.DivideZero</span><span class="lang">
156*67e74705SXin Li(C, C++, ObjC)</span><div class="descr">
157*67e74705SXin LiCheck for division by zero.</div></div></td>
158*67e74705SXin Li<td><div class="exampleContainer expandable">
159*67e74705SXin Li<div class="example"><pre>
160*67e74705SXin Livoid test(int z) {
161*67e74705SXin Li  if (z == 0)
162*67e74705SXin Li    int x = 1 / z; // warn
163*67e74705SXin Li}
164*67e74705SXin Li</pre></div>
165*67e74705SXin Li<div class="example"><pre>
166*67e74705SXin Livoid test() {
167*67e74705SXin Li  int x = 1;
168*67e74705SXin Li  int y = x % 0; // warn
169*67e74705SXin Li}
170*67e74705SXin Li</pre></div></div></td></tr>
171*67e74705SXin Li
172*67e74705SXin Li
173*67e74705SXin Li<tr><td><div class="namedescr expandable"><span class="name">
174*67e74705SXin Licore.NonNullParamChecker</span><span class="lang">
175*67e74705SXin Li(C, C++, ObjC)</span><div class="descr">
176*67e74705SXin LiCheck for null pointers passed as arguments to a function whose arguments are
177*67e74705SXin Limarked with the <code>nonnull</code> attribute.</div></div></td>
178*67e74705SXin Li<td><div class="exampleContainer expandable">
179*67e74705SXin Li<div class="example"><pre>
180*67e74705SXin Liint f(int *p) __attribute__((nonnull));
181*67e74705SXin Li
182*67e74705SXin Livoid test(int *p) {
183*67e74705SXin Li  if (!p)
184*67e74705SXin Li    f(p); // warn
185*67e74705SXin Li}
186*67e74705SXin Li</pre></div></div></td></tr>
187*67e74705SXin Li
188*67e74705SXin Li
189*67e74705SXin Li<tr><td><div class="namedescr expandable"><span class="name">
190*67e74705SXin Licore.NullDereference</span><span class="lang">
191*67e74705SXin Li(C, C++, ObjC)</span><div class="descr">
192*67e74705SXin LiCheck for dereferences of null pointers.</div></div></td>
193*67e74705SXin Li<td><div class="exampleContainer expandable">
194*67e74705SXin Li<div class="example"><pre>
195*67e74705SXin Li// C
196*67e74705SXin Livoid test(int *p) {
197*67e74705SXin Li  if (p)
198*67e74705SXin Li    return;
199*67e74705SXin Li
200*67e74705SXin Li  int x = p[0]; // warn
201*67e74705SXin Li}
202*67e74705SXin Li</pre></div>
203*67e74705SXin Li<div class="example"><pre>
204*67e74705SXin Li// C
205*67e74705SXin Livoid test(int *p) {
206*67e74705SXin Li  if (!p)
207*67e74705SXin Li    *p = 0; // warn
208*67e74705SXin Li}
209*67e74705SXin Li</pre></div>
210*67e74705SXin Li<div class="example"><pre>
211*67e74705SXin Li// C++
212*67e74705SXin Liclass C {
213*67e74705SXin Lipublic:
214*67e74705SXin Li  int x;
215*67e74705SXin Li};
216*67e74705SXin Li
217*67e74705SXin Livoid test() {
218*67e74705SXin Li  C *pc = 0;
219*67e74705SXin Li  int k = pc->x; // warn
220*67e74705SXin Li}
221*67e74705SXin Li</pre></div>
222*67e74705SXin Li<div class="example"><pre>
223*67e74705SXin Li// Objective-C
224*67e74705SXin Li@interface MyClass {
225*67e74705SXin Li@public
226*67e74705SXin Li  int x;
227*67e74705SXin Li}
228*67e74705SXin Li@end
229*67e74705SXin Li
230*67e74705SXin Livoid test() {
231*67e74705SXin Li  MyClass *obj = 0;
232*67e74705SXin Li  obj-&gt;x = 1; // warn
233*67e74705SXin Li}
234*67e74705SXin Li</pre></div></div></td></tr>
235*67e74705SXin Li
236*67e74705SXin Li
237*67e74705SXin Li<tr><td><div class="namedescr expandable"><span class="name">
238*67e74705SXin Licore.StackAddressEscape</span><span class="lang">
239*67e74705SXin Li(C)</span><div class="descr">
240*67e74705SXin LiCheck that addresses of stack memory do not escape the function.</div></div></td>
241*67e74705SXin Li<td><div class="exampleContainer expandable">
242*67e74705SXin Li<div class="example"><pre>
243*67e74705SXin Lichar const *p;
244*67e74705SXin Li
245*67e74705SXin Livoid test() {
246*67e74705SXin Li  char const str[] = "string";
247*67e74705SXin Li  p = str; // warn
248*67e74705SXin Li}
249*67e74705SXin Li</pre></div>
250*67e74705SXin Li<div class="example"><pre>
251*67e74705SXin Livoid* test() {
252*67e74705SXin Li   return __builtin_alloca(12); // warn
253*67e74705SXin Li}
254*67e74705SXin Li</pre></div>
255*67e74705SXin Li<div class="example"><pre>
256*67e74705SXin Livoid test() {
257*67e74705SXin Li  static int *x;
258*67e74705SXin Li  int y;
259*67e74705SXin Li  x = &amp;y; // warn
260*67e74705SXin Li}
261*67e74705SXin Li</pre></div></div></td></tr>
262*67e74705SXin Li
263*67e74705SXin Li
264*67e74705SXin Li<tr><td><div class="namedescr expandable"><span class="name">
265*67e74705SXin Licore.UndefinedBinaryOperatorResult</span><span class="lang">
266*67e74705SXin Li(C)</span><div class="descr">
267*67e74705SXin LiCheck for undefined results of binary operators.</div></div></td>
268*67e74705SXin Li<td><div class="exampleContainer expandable">
269*67e74705SXin Li<div class="example"><pre>
270*67e74705SXin Livoid test() {
271*67e74705SXin Li  int x;
272*67e74705SXin Li  int y = x + 1; // warn: left operand is garbage
273*67e74705SXin Li}
274*67e74705SXin Li</pre></div></div></td></tr>
275*67e74705SXin Li
276*67e74705SXin Li
277*67e74705SXin Li<tr><td><div class="namedescr expandable"><span class="name">
278*67e74705SXin Licore.VLASize</span><span class="lang">
279*67e74705SXin Li(C)</span><div class="descr">
280*67e74705SXin LiCheck for declarations of VLA of undefined or zero size.</div></div></td>
281*67e74705SXin Li<td><div class="exampleContainer expandable">
282*67e74705SXin Li<div class="example"><pre>
283*67e74705SXin Livoid test() {
284*67e74705SXin Li  int x;
285*67e74705SXin Li  int vla1[x]; // warn: garbage as size
286*67e74705SXin Li}
287*67e74705SXin Li</pre></div>
288*67e74705SXin Li<div class="example"><pre>
289*67e74705SXin Livoid test() {
290*67e74705SXin Li  int x = 0;
291*67e74705SXin Li  int vla2[x]; // warn: zero size
292*67e74705SXin Li}
293*67e74705SXin Li</pre></div></div></td></tr>
294*67e74705SXin Li
295*67e74705SXin Li
296*67e74705SXin Li<tr><td><div class="namedescr expandable"><span class="name">
297*67e74705SXin Licore.uninitialized.ArraySubscript</span><span class="lang">
298*67e74705SXin Li(C)</span><div class="descr">
299*67e74705SXin LiCheck for uninitialized values used as array subscripts.</div></div></td>
300*67e74705SXin Li<td><div class="exampleContainer expandable">
301*67e74705SXin Li<div class="example"><pre>
302*67e74705SXin Livoid test() {
303*67e74705SXin Li  int i, a[10];
304*67e74705SXin Li  int x = a[i]; // warn: array subscript is undefined
305*67e74705SXin Li}
306*67e74705SXin Li</pre></div></div></td></tr>
307*67e74705SXin Li
308*67e74705SXin Li
309*67e74705SXin Li<tr><td><div class="namedescr expandable"><span class="name">
310*67e74705SXin Licore.uninitialized.Assign</span><span class="lang">
311*67e74705SXin Li(C)</span><div class="descr">
312*67e74705SXin LiCheck for assigning uninitialized values.</div></div></td>
313*67e74705SXin Li<td><div class="exampleContainer expandable">
314*67e74705SXin Li<div class="example"><pre>
315*67e74705SXin Livoid test() {
316*67e74705SXin Li  int x;
317*67e74705SXin Li  x |= 1; // warn: left expression is unitialized
318*67e74705SXin Li}
319*67e74705SXin Li</pre></div></div></td></tr>
320*67e74705SXin Li
321*67e74705SXin Li
322*67e74705SXin Li<tr><td><div class="namedescr expandable"><span class="name">
323*67e74705SXin Licore.uninitialized.Branch</span><span class="lang">
324*67e74705SXin Li(C)</span><div class="descr">
325*67e74705SXin LiCheck for uninitialized values used as branch conditions.</div></div></td>
326*67e74705SXin Li<td><div class="exampleContainer expandable">
327*67e74705SXin Li<div class="example"><pre>
328*67e74705SXin Livoid test() {
329*67e74705SXin Li  int x;
330*67e74705SXin Li  if (x) // warn
331*67e74705SXin Li    return;
332*67e74705SXin Li}
333*67e74705SXin Li</pre></div></div></td></tr>
334*67e74705SXin Li
335*67e74705SXin Li
336*67e74705SXin Li<tr><td><div class="namedescr expandable"><span class="name">
337*67e74705SXin Licore.uninitialized.CapturedBlockVariable</span><span class="lang">
338*67e74705SXin Li(C)</span><div class="descr">
339*67e74705SXin LiCheck for blocks that capture uninitialized values.</div></div></td>
340*67e74705SXin Li<td><div class="exampleContainer expandable">
341*67e74705SXin Li<div class="example"><pre>
342*67e74705SXin Livoid test() {
343*67e74705SXin Li  int x;
344*67e74705SXin Li  ^{ int y = x; }(); // warn
345*67e74705SXin Li}
346*67e74705SXin Li</pre></div></div></td></tr>
347*67e74705SXin Li
348*67e74705SXin Li
349*67e74705SXin Li<tr><td><div class="namedescr expandable"><span class="name">
350*67e74705SXin Licore.uninitialized.UndefReturn</span><span class="lang">
351*67e74705SXin Li(C)</span><div class="descr">
352*67e74705SXin LiCheck for uninitialized values being returned to the caller.</div></div></td>
353*67e74705SXin Li<td><div class="exampleContainer expandable">
354*67e74705SXin Li<div class="example"><pre>
355*67e74705SXin Liint test() {
356*67e74705SXin Li  int x;
357*67e74705SXin Li  return x; // warn
358*67e74705SXin Li}
359*67e74705SXin Li</pre></div></div></td></tr>
360*67e74705SXin Li
361*67e74705SXin Li</tbody></table>
362*67e74705SXin Li
363*67e74705SXin Li<!------------------------------------ C++ ------------------------------------>
364*67e74705SXin Li<h3 id="cplusplus_checkers">C++ Checkers</h3>
365*67e74705SXin Li<table class="checkers">
366*67e74705SXin Li<colgroup><col class="namedescr"><col class="example"></colgroup>
367*67e74705SXin Li<thead><tr><td>Name, Description</td><td>Example</td></tr></thead>
368*67e74705SXin Li
369*67e74705SXin Li<tbody>
370*67e74705SXin Li<tr><td><div class="namedescr expandable"><span class="name">
371*67e74705SXin Licplusplus.NewDelete</span><span class="lang">
372*67e74705SXin Li(C++)</span><div class="descr">
373*67e74705SXin LiCheck for double-free, use-after-free and offset problems involving C++ <code>
374*67e74705SXin Lidelete</code>.</div></div></td>
375*67e74705SXin Li<td><div class="exampleContainer expandable">
376*67e74705SXin Li<div class="example"><pre>
377*67e74705SXin Livoid f(int *p);
378*67e74705SXin Li
379*67e74705SXin Livoid testUseMiddleArgAfterDelete(int *p) {
380*67e74705SXin Li  delete p;
381*67e74705SXin Li  f(p); // warn: use after free
382*67e74705SXin Li}
383*67e74705SXin Li</pre></div>
384*67e74705SXin Li<div class="example"><pre>
385*67e74705SXin Liclass SomeClass {
386*67e74705SXin Lipublic:
387*67e74705SXin Li  void f();
388*67e74705SXin Li};
389*67e74705SXin Li
390*67e74705SXin Livoid test() {
391*67e74705SXin Li  SomeClass *c = new SomeClass;
392*67e74705SXin Li  delete c;
393*67e74705SXin Li  c-&gt;f(); // warn: use after free
394*67e74705SXin Li}
395*67e74705SXin Li</pre></div>
396*67e74705SXin Li<div class="example"><pre>
397*67e74705SXin Livoid test() {
398*67e74705SXin Li  int *p = (int *)__builtin_alloca(sizeof(int));
399*67e74705SXin Li  delete p; // warn: deleting memory allocated by alloca
400*67e74705SXin Li}
401*67e74705SXin Li</pre></div>
402*67e74705SXin Li<div class="example"><pre>
403*67e74705SXin Livoid test() {
404*67e74705SXin Li  int *p = new int;
405*67e74705SXin Li  delete p;
406*67e74705SXin Li  delete p; // warn: attempt to free released
407*67e74705SXin Li}
408*67e74705SXin Li</pre></div>
409*67e74705SXin Li<div class="example"><pre>
410*67e74705SXin Livoid test() {
411*67e74705SXin Li  int i;
412*67e74705SXin Li  delete &amp;i; // warn: delete address of local
413*67e74705SXin Li}
414*67e74705SXin Li</pre></div>
415*67e74705SXin Li<div class="example"><pre>
416*67e74705SXin Livoid test() {
417*67e74705SXin Li  int *p = new int[1];
418*67e74705SXin Li  delete[] (++p);
419*67e74705SXin Li    // warn: argument to 'delete[]' is offset by 4 bytes
420*67e74705SXin Li    // from the start of memory allocated by 'new[]'
421*67e74705SXin Li}
422*67e74705SXin Li</pre></div></div></td></tr>
423*67e74705SXin Li
424*67e74705SXin Li</tbody></table>
425*67e74705SXin Li
426*67e74705SXin Li<!--------------------------------- dead code --------------------------------->
427*67e74705SXin Li<h3 id="deadcode_checkers">Dead Code Checkers</h3>
428*67e74705SXin Li<table class="checkers">
429*67e74705SXin Li<colgroup><col class="namedescr"><col class="example"></colgroup>
430*67e74705SXin Li<thead><tr><td>Name, Description</td><td>Example</td></tr></thead>
431*67e74705SXin Li
432*67e74705SXin Li<tbody>
433*67e74705SXin Li<tr><td><div class="namedescr expandable"><span class="name">
434*67e74705SXin Lideadcode.DeadStores</span><span class="lang">
435*67e74705SXin Li(C)</span><div class="descr">
436*67e74705SXin LiCheck for values stored to variables that are never read afterwards.</div></div></td>
437*67e74705SXin Li<td><div class="exampleContainer expandable">
438*67e74705SXin Li<div class="example"><pre>
439*67e74705SXin Livoid test() {
440*67e74705SXin Li  int x;
441*67e74705SXin Li  x = 1; // warn
442*67e74705SXin Li}
443*67e74705SXin Li</pre></div></div></td></tr>
444*67e74705SXin Li
445*67e74705SXin Li</tbody></table>
446*67e74705SXin Li
447*67e74705SXin Li<!---------------------------------- OS X ------------------------------------>
448*67e74705SXin Li<h3 id="osx_checkers">OS X Checkers</h3>
449*67e74705SXin Li<table class="checkers">
450*67e74705SXin Li<colgroup><col class="namedescr"><col class="example"></colgroup>
451*67e74705SXin Li<thead><tr><td>Name, Description</td><td>Example</td></tr></thead>
452*67e74705SXin Li
453*67e74705SXin Li<tbody>
454*67e74705SXin Li<tr><td><div class="namedescr expandable"><span class="name">
455*67e74705SXin Liosx.API</span><span class="lang">
456*67e74705SXin Li(C)</span><div class="descr">
457*67e74705SXin LiCheck for proper uses of various Apple APIs:<div class=functions>
458*67e74705SXin Lidispatch_once</div></div></div></td>
459*67e74705SXin Li<td><div class="exampleContainer expandable">
460*67e74705SXin Li<div class="example"><pre>
461*67e74705SXin Livoid test() {
462*67e74705SXin Li  dispatch_once_t pred = 0;
463*67e74705SXin Li  dispatch_once(&amp;pred, ^(){}); // warn: dispatch_once uses local
464*67e74705SXin Li}
465*67e74705SXin Li</pre></div></div></td></tr>
466*67e74705SXin Li
467*67e74705SXin Li
468*67e74705SXin Li<tr><td><div class="namedescr expandable"><span class="name">
469*67e74705SXin Liosx.SecKeychainAPI</span><span class="lang">
470*67e74705SXin Li(C)</span><div class="descr">
471*67e74705SXin LiCheck for improper uses of the Security framework's Keychain APIs:<div class=functions>
472*67e74705SXin LiSecKeychainItemCopyContent<br>
473*67e74705SXin LiSecKeychainFindGenericPassword<br>
474*67e74705SXin LiSecKeychainFindInternetPassword<br>
475*67e74705SXin LiSecKeychainItemFreeContent<br>
476*67e74705SXin LiSecKeychainItemCopyAttributesAndData<br>
477*67e74705SXin LiSecKeychainItemFreeAttributesAndData</div></div></div></td>
478*67e74705SXin Li<td><div class="exampleContainer expandable">
479*67e74705SXin Li<div class="example"><pre>
480*67e74705SXin Livoid test() {
481*67e74705SXin Li  unsigned int *ptr = 0;
482*67e74705SXin Li  UInt32 length;
483*67e74705SXin Li
484*67e74705SXin Li  SecKeychainItemFreeContent(ptr, &amp;length);
485*67e74705SXin Li    // warn: trying to free data which has not been allocated
486*67e74705SXin Li}
487*67e74705SXin Li</pre></div>
488*67e74705SXin Li<div class="example"><pre>
489*67e74705SXin Livoid test() {
490*67e74705SXin Li  unsigned int *ptr = 0;
491*67e74705SXin Li  UInt32 *length = 0;
492*67e74705SXin Li  void *outData;
493*67e74705SXin Li
494*67e74705SXin Li  OSStatus st =
495*67e74705SXin Li    SecKeychainItemCopyContent(2, ptr, ptr, length, outData);
496*67e74705SXin Li    // warn: data is not released
497*67e74705SXin Li}
498*67e74705SXin Li</pre></div>
499*67e74705SXin Li<div class="example"><pre>
500*67e74705SXin Livoid test() {
501*67e74705SXin Li  unsigned int *ptr = 0;
502*67e74705SXin Li  UInt32 *length = 0;
503*67e74705SXin Li  void *outData;
504*67e74705SXin Li
505*67e74705SXin Li  OSStatus st =
506*67e74705SXin Li    SecKeychainItemCopyContent(2, ptr, ptr, length, &amp;outData);
507*67e74705SXin Li
508*67e74705SXin Li  SecKeychainItemFreeContent(ptr, outData);
509*67e74705SXin Li    // warn: only call free if a non-NULL buffer was returned
510*67e74705SXin Li}
511*67e74705SXin Li</pre></div>
512*67e74705SXin Li<div class="example"><pre>
513*67e74705SXin Livoid test() {
514*67e74705SXin Li  unsigned int *ptr = 0;
515*67e74705SXin Li  UInt32 *length = 0;
516*67e74705SXin Li  void *outData;
517*67e74705SXin Li
518*67e74705SXin Li  OSStatus st =
519*67e74705SXin Li    SecKeychainItemCopyContent(2, ptr, ptr, length, &amp;outData);
520*67e74705SXin Li
521*67e74705SXin Li  st = SecKeychainItemCopyContent(2, ptr, ptr, length, &amp;outData);
522*67e74705SXin Li    // warn: release data before another call to the allocator
523*67e74705SXin Li
524*67e74705SXin Li  if (st == noErr)
525*67e74705SXin Li    SecKeychainItemFreeContent(ptr, outData);
526*67e74705SXin Li}
527*67e74705SXin Li</pre></div>
528*67e74705SXin Li<div class="example"><pre>
529*67e74705SXin Livoid test() {
530*67e74705SXin Li  SecKeychainItemRef itemRef = 0;
531*67e74705SXin Li  SecKeychainAttributeInfo *info = 0;
532*67e74705SXin Li  SecItemClass *itemClass = 0;
533*67e74705SXin Li  SecKeychainAttributeList *attrList = 0;
534*67e74705SXin Li  UInt32 *length = 0;
535*67e74705SXin Li  void *outData = 0;
536*67e74705SXin Li
537*67e74705SXin Li  OSStatus st =
538*67e74705SXin Li    SecKeychainItemCopyAttributesAndData(itemRef, info,
539*67e74705SXin Li                                         itemClass, &amp;attrList,
540*67e74705SXin Li                                         length, &amp;outData);
541*67e74705SXin Li
542*67e74705SXin Li  SecKeychainItemFreeContent(attrList, outData);
543*67e74705SXin Li    // warn: deallocator doesn't match the allocator
544*67e74705SXin Li}
545*67e74705SXin Li</pre></div></div></td></tr>
546*67e74705SXin Li
547*67e74705SXin Li
548*67e74705SXin Li<tr><td><div class="namedescr expandable"><span class="name">
549*67e74705SXin Liosx.cocoa.AtSync</span><span class="lang">
550*67e74705SXin Li(ObjC)</span><div class="descr">
551*67e74705SXin LiCheck for nil pointers used as mutexes for <code>@synchronized</code>.</div></div></td>
552*67e74705SXin Li<td><div class="exampleContainer expandable">
553*67e74705SXin Li<div class="example"><pre>
554*67e74705SXin Livoid test(id x) {
555*67e74705SXin Li  if (!x)
556*67e74705SXin Li    @synchronized(x) {} // warn: nil value used as mutex
557*67e74705SXin Li}
558*67e74705SXin Li</pre></div>
559*67e74705SXin Li<div class="example"><pre>
560*67e74705SXin Livoid test() {
561*67e74705SXin Li  id y;
562*67e74705SXin Li  @synchronized(y) {} // warn: uninitialized value used as mutex
563*67e74705SXin Li}
564*67e74705SXin Li</pre></div></div></td></tr>
565*67e74705SXin Li
566*67e74705SXin Li
567*67e74705SXin Li<tr><td><div class="namedescr expandable"><span class="name">
568*67e74705SXin Liosx.cocoa.ClassRelease</span><span class="lang">
569*67e74705SXin Li(ObjC)</span><div class="descr">
570*67e74705SXin LiCheck for sending <code>retain</code>, <code>release</code>, or <code>
571*67e74705SXin Liautorelease</code> directly to a class.</div></div></td>
572*67e74705SXin Li<td><div class="exampleContainer expandable">
573*67e74705SXin Li<div class="example"><pre>
574*67e74705SXin Li@interface MyClass : NSObject
575*67e74705SXin Li@end
576*67e74705SXin Li
577*67e74705SXin Livoid test(void) {
578*67e74705SXin Li  [MyClass release]; // warn
579*67e74705SXin Li}
580*67e74705SXin Li</pre></div></div></td></tr>
581*67e74705SXin Li
582*67e74705SXin Li
583*67e74705SXin Li<tr><td><div class="namedescr expandable"><span class="name">
584*67e74705SXin Liosx.cocoa.IncompatibleMethodTypes</span><span class="lang">
585*67e74705SXin Li(ObjC)</span><div class="descr">
586*67e74705SXin LiCheck for an incompatible type signature when overriding an Objective-C method.</div></div></td>
587*67e74705SXin Li<td><div class="exampleContainer expandable">
588*67e74705SXin Li<div class="example"><pre>
589*67e74705SXin Li@interface MyClass1 : NSObject
590*67e74705SXin Li- (int)foo;
591*67e74705SXin Li@end
592*67e74705SXin Li
593*67e74705SXin Li@implementation MyClass1
594*67e74705SXin Li- (int)foo { return 1; }
595*67e74705SXin Li@end
596*67e74705SXin Li
597*67e74705SXin Li@interface MyClass2 : MyClass1
598*67e74705SXin Li- (float)foo;
599*67e74705SXin Li@end
600*67e74705SXin Li
601*67e74705SXin Li@implementation MyClass2
602*67e74705SXin Li- (float)foo { return 1.0; } // warn
603*67e74705SXin Li@end
604*67e74705SXin Li</pre></div></div></td></tr>
605*67e74705SXin Li
606*67e74705SXin Li
607*67e74705SXin Li<tr><td><div class="namedescr expandable"><span class="name">
608*67e74705SXin Lialpha.osx.cocoa.MissingSuperCall</span><span class="lang">
609*67e74705SXin Li(ObjC)</span><div class="descr">
610*67e74705SXin LiWarn about Objective-C methods that lack a necessary call to super. (Note: The
611*67e74705SXin Licompiler now has a warning for methods annotated with <code>objc_requires_super</code>
612*67e74705SXin Liattribute. The checker exists to check methods in the Cocoa frameworks
613*67e74705SXin Lithat haven't yet adopted this attribute.)</div></div></td>
614*67e74705SXin Li<td><div class="example"><pre>
615*67e74705SXin Li@interface Test : UIViewController
616*67e74705SXin Li@end
617*67e74705SXin Li@implementation test
618*67e74705SXin Li- (void)viewDidLoad {} // warn
619*67e74705SXin Li@end
620*67e74705SXin Li</pre></div></td></tr>
621*67e74705SXin Li
622*67e74705SXin Li
623*67e74705SXin Li<tr><td><div class="namedescr expandable"><span class="name">
624*67e74705SXin Liosx.cocoa.NSAutoreleasePool</span><span class="lang">
625*67e74705SXin Li(ObjC)</span><div class="descr">
626*67e74705SXin LiWarn for suboptimal uses of NSAutoreleasePool in Objective-C
627*67e74705SXin LiGC mode (<code>-fobjc-gc</code> compiler option).</div></div></td>
628*67e74705SXin Li<td><div class="exampleContainer expandable">
629*67e74705SXin Li<div class="example"><pre>
630*67e74705SXin Livoid test() {
631*67e74705SXin Li  NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
632*67e74705SXin Li  [pool release]; // warn
633*67e74705SXin Li}
634*67e74705SXin Li</pre></div></div></td></tr>
635*67e74705SXin Li
636*67e74705SXin Li
637*67e74705SXin Li<tr><td><div class="namedescr expandable"><span class="name">
638*67e74705SXin Liosx.cocoa.NSError</span><span class="lang">
639*67e74705SXin Li(ObjC)</span><div class="descr">
640*67e74705SXin LiCheck usage of <code>NSError**</code> parameters.</div></div></td>
641*67e74705SXin Li<td><div class="exampleContainer expandable">
642*67e74705SXin Li<div class="example"><pre>
643*67e74705SXin Li@interface A : NSObject
644*67e74705SXin Li- (void)foo:(NSError **)error;
645*67e74705SXin Li@end
646*67e74705SXin Li
647*67e74705SXin Li@implementation A
648*67e74705SXin Li- (void)foo:(NSError **)error {
649*67e74705SXin Li  // warn: method accepting NSError** should have a non-void
650*67e74705SXin Li  // return value
651*67e74705SXin Li}
652*67e74705SXin Li@end
653*67e74705SXin Li</pre></div>
654*67e74705SXin Li<div class="example"><pre>
655*67e74705SXin Li@interface A : NSObject
656*67e74705SXin Li- (BOOL)foo:(NSError **)error;
657*67e74705SXin Li@end
658*67e74705SXin Li
659*67e74705SXin Li@implementation A
660*67e74705SXin Li- (BOOL)foo:(NSError **)error {
661*67e74705SXin Li  *error = 0; // warn: potential null dereference
662*67e74705SXin Li  return 0;
663*67e74705SXin Li}
664*67e74705SXin Li@end
665*67e74705SXin Li</pre></div></div></td></tr>
666*67e74705SXin Li
667*67e74705SXin Li
668*67e74705SXin Li<tr><td><div class="namedescr expandable"><span class="name">
669*67e74705SXin Liosx.cocoa.NilArg</span><span class="lang">
670*67e74705SXin Li(ObjC)</span><div class="descr">
671*67e74705SXin LiCheck for prohibited nil arguments in specific Objective-C method calls:<div class=functions>
672*67e74705SXin Li- caseInsensitiveCompare:<br>
673*67e74705SXin Li- compare:<br>
674*67e74705SXin Li- compare:options:<br>
675*67e74705SXin Li- compare:options:range:<br>
676*67e74705SXin Li- compare:options:range:locale:<br>
677*67e74705SXin Li- componentsSeparatedByCharactersInSet:<br>
678*67e74705SXin Li- initWithFormat:</div></div></div></td>
679*67e74705SXin Li<td><div class="exampleContainer expandable">
680*67e74705SXin Li<div class="example"><pre>
681*67e74705SXin LiNSComparisonResult test(NSString *s) {
682*67e74705SXin Li  NSString *aString = nil;
683*67e74705SXin Li  return [s caseInsensitiveCompare:aString];
684*67e74705SXin Li    // warn: argument to 'NSString' method
685*67e74705SXin Li    // 'caseInsensitiveCompare:' cannot be nil
686*67e74705SXin Li}
687*67e74705SXin Li</pre></div></div></td></tr>
688*67e74705SXin Li
689*67e74705SXin Li
690*67e74705SXin Li<tr><td><div class="namedescr expandable"><span class="name">
691*67e74705SXin Liosx.cocoa.RetainCount</span><span class="lang">
692*67e74705SXin Li(ObjC)</span><div class="descr">
693*67e74705SXin LiCheck for leaks and violations of the Cocoa Memory Management rules.</div></div></td>
694*67e74705SXin Li<td><div class="exampleContainer expandable">
695*67e74705SXin Li<div class="example"><pre>
696*67e74705SXin Livoid test() {
697*67e74705SXin Li  NSString *s = [[NSString alloc] init]; // warn
698*67e74705SXin Li}
699*67e74705SXin Li</pre></div>
700*67e74705SXin Li<div class="example"><pre>
701*67e74705SXin LiCFStringRef test(char *bytes) {
702*67e74705SXin Li  return CFStringCreateWithCStringNoCopy(
703*67e74705SXin Li           0, bytes, NSNEXTSTEPStringEncoding, 0); // warn
704*67e74705SXin Li}
705*67e74705SXin Li</pre></div></div></td></tr>
706*67e74705SXin Li
707*67e74705SXin Li
708*67e74705SXin Li<tr><td><div class="namedescr expandable"><span class="name">
709*67e74705SXin Liosx.cocoa.SelfInit</span><span class="lang">
710*67e74705SXin Li(ObjC)</span><div class="descr">
711*67e74705SXin LiCheck that <code>self</code> is properly initialized inside an initializer
712*67e74705SXin Limethod.</div></div></td>
713*67e74705SXin Li<td><div class="exampleContainer expandable">
714*67e74705SXin Li<div class="example"><pre>
715*67e74705SXin Li@interface MyObj : NSObject {
716*67e74705SXin Li  id x;
717*67e74705SXin Li}
718*67e74705SXin Li- (id)init;
719*67e74705SXin Li@end
720*67e74705SXin Li
721*67e74705SXin Li@implementation MyObj
722*67e74705SXin Li- (id)init {
723*67e74705SXin Li  [super init];
724*67e74705SXin Li  x = 0; // warn: instance variable used while 'self' is not
725*67e74705SXin Li         // initialized
726*67e74705SXin Li  return 0;
727*67e74705SXin Li}
728*67e74705SXin Li@end
729*67e74705SXin Li</pre></div>
730*67e74705SXin Li<div class="example"><pre>
731*67e74705SXin Li@interface MyObj : NSObject
732*67e74705SXin Li- (id)init;
733*67e74705SXin Li@end
734*67e74705SXin Li
735*67e74705SXin Li@implementation MyObj
736*67e74705SXin Li- (id)init {
737*67e74705SXin Li  [super init];
738*67e74705SXin Li  return self; // warn: returning uninitialized 'self'
739*67e74705SXin Li}
740*67e74705SXin Li@end
741*67e74705SXin Li</pre></div></div></td></tr>
742*67e74705SXin Li
743*67e74705SXin Li
744*67e74705SXin Li<tr><td><div class="namedescr expandable"><span class="name">
745*67e74705SXin Liosx.cocoa.UnusedIvars</span><span class="lang">
746*67e74705SXin Li(ObjC)</span><div class="descr">
747*67e74705SXin LiWarn about private ivars that are never used.</div></div></td>
748*67e74705SXin Li<td><div class="exampleContainer expandable">
749*67e74705SXin Li<div class="example"><pre>
750*67e74705SXin Li@interface MyObj : NSObject {
751*67e74705SXin Li@private
752*67e74705SXin Li  id x; // warn
753*67e74705SXin Li}
754*67e74705SXin Li@end
755*67e74705SXin Li
756*67e74705SXin Li@implementation MyObj
757*67e74705SXin Li@end
758*67e74705SXin Li</pre></div></div></td></tr>
759*67e74705SXin Li
760*67e74705SXin Li
761*67e74705SXin Li<tr><td><div class="namedescr expandable"><span class="name">
762*67e74705SXin Liosx.cocoa.VariadicMethodTypes</span><span class="lang">
763*67e74705SXin Li(ObjC)</span><div class="descr">
764*67e74705SXin LiCheck for passing non-Objective-C types to variadic collection initialization
765*67e74705SXin Limethods that expect only Objective-C types.</div></div></td>
766*67e74705SXin Li<td><div class="exampleContainer expandable">
767*67e74705SXin Li<div class="example"><pre>
768*67e74705SXin Livoid test() {
769*67e74705SXin Li  [NSSet setWithObjects:@"Foo", "Bar", nil];
770*67e74705SXin Li    // warn: argument should be an ObjC pointer type, not 'char *'
771*67e74705SXin Li}
772*67e74705SXin Li</pre></div></div></td></tr>
773*67e74705SXin Li
774*67e74705SXin Li
775*67e74705SXin Li<tr><td><div class="namedescr expandable"><span class="name">
776*67e74705SXin Liosx.coreFoundation.CFError</span><span class="lang">
777*67e74705SXin Li(C)</span><div class="descr">
778*67e74705SXin LiCheck usage of <code>CFErrorRef*</code> parameters.</div></div></td>
779*67e74705SXin Li<td><div class="exampleContainer expandable">
780*67e74705SXin Li<div class="example"><pre>
781*67e74705SXin Livoid test(CFErrorRef *error) {
782*67e74705SXin Li  // warn: function accepting CFErrorRef* should have a
783*67e74705SXin Li  // non-void return
784*67e74705SXin Li}
785*67e74705SXin Li</pre></div>
786*67e74705SXin Li<div class="example"><pre>
787*67e74705SXin Liint foo(CFErrorRef *error) {
788*67e74705SXin Li  *error = 0; // warn: potential null dereference
789*67e74705SXin Li  return 0;
790*67e74705SXin Li}
791*67e74705SXin Li</pre></div></div></td></tr>
792*67e74705SXin Li
793*67e74705SXin Li
794*67e74705SXin Li<tr><td><div class="namedescr expandable"><span class="name">
795*67e74705SXin Liosx.coreFoundation.CFNumber</span><span class="lang">
796*67e74705SXin Li(C)</span><div class="descr">
797*67e74705SXin LiCheck for improper uses of <code>CFNumberCreate</code>.</div></div></td>
798*67e74705SXin Li<td><div class="exampleContainer expandable">
799*67e74705SXin Li<div class="example"><pre>
800*67e74705SXin LiCFNumberRef test(unsigned char x) {
801*67e74705SXin Li  return CFNumberCreate(0, kCFNumberSInt16Type, &amp;x);
802*67e74705SXin Li   // warn: 8 bit integer is used to initialize a 16 bit integer
803*67e74705SXin Li}
804*67e74705SXin Li</pre></div></div></td></tr>
805*67e74705SXin Li
806*67e74705SXin Li
807*67e74705SXin Li<tr><td><div class="namedescr expandable"><span class="name">
808*67e74705SXin Liosx.coreFoundation.CFRetainRelease</span><span class="lang">
809*67e74705SXin Li(C)</span><div class="descr">
810*67e74705SXin LiCheck for null arguments to <code>CFRetain</code>, <code>CFRelease</code>,
811*67e74705SXin Li<code>CFMakeCollectable</code>.</div></div></td>
812*67e74705SXin Li<td><div class="exampleContainer expandable">
813*67e74705SXin Li<div class="example"><pre>
814*67e74705SXin Livoid test(CFTypeRef p) {
815*67e74705SXin Li  if (!p)
816*67e74705SXin Li    CFRetain(p); // warn
817*67e74705SXin Li}
818*67e74705SXin Li</pre></div>
819*67e74705SXin Li<div class="example"><pre>
820*67e74705SXin Livoid test(int x, CFTypeRef p) {
821*67e74705SXin Li  if (p)
822*67e74705SXin Li    return;
823*67e74705SXin Li
824*67e74705SXin Li  CFRelease(p); // warn
825*67e74705SXin Li}
826*67e74705SXin Li</pre></div></div></td></tr>
827*67e74705SXin Li
828*67e74705SXin Li
829*67e74705SXin Li<tr><td><div class="namedescr expandable"><span class="name">
830*67e74705SXin Liosx.coreFoundation.containers.OutOfBounds</span><span class="lang">
831*67e74705SXin Li(C)</span><div class="descr">
832*67e74705SXin LiChecks for index out-of-bounds when using <code>CFArray</code> API.</div></div></td>
833*67e74705SXin Li<td><div class="exampleContainer expandable">
834*67e74705SXin Li<div class="example"><pre>
835*67e74705SXin Livoid test() {
836*67e74705SXin Li  CFArrayRef A = CFArrayCreate(0, 0, 0, &amp;kCFTypeArrayCallBacks);
837*67e74705SXin Li  CFArrayGetValueAtIndex(A, 0); // warn
838*67e74705SXin Li}
839*67e74705SXin Li</pre></div></div></td></tr>
840*67e74705SXin Li
841*67e74705SXin Li
842*67e74705SXin Li<tr><td><div class="namedescr expandable"><span class="name">
843*67e74705SXin Liosx.coreFoundation.containers.PointerSizedValues</span><span class="lang">
844*67e74705SXin Li(C)</span><div class="descr">
845*67e74705SXin LiWarns if <code>CFArray</code>, <code>CFDictionary</code>, <code>CFSet</code> are
846*67e74705SXin Licreated with non-pointer-size values.</div></div></td>
847*67e74705SXin Li<td><div class="exampleContainer expandable">
848*67e74705SXin Li<div class="example"><pre>
849*67e74705SXin Livoid test() {
850*67e74705SXin Li  int x[] = { 1 };
851*67e74705SXin Li  CFArrayRef A = CFArrayCreate(0, (const void **)x, 1,
852*67e74705SXin Li                               &amp;kCFTypeArrayCallBacks); // warn
853*67e74705SXin Li}
854*67e74705SXin Li</pre></div></div></td></tr>
855*67e74705SXin Li
856*67e74705SXin Li</tbody></table>
857*67e74705SXin Li
858*67e74705SXin Li<!------------------------------- security ------------------------------------>
859*67e74705SXin Li<h3 id="security_checkers">Security Checkers</h3>
860*67e74705SXin Li<table class="checkers">
861*67e74705SXin Li<colgroup><col class="namedescr"><col class="example"></colgroup>
862*67e74705SXin Li<thead><tr><td>Name, Description</td><td>Example</td></tr></thead>
863*67e74705SXin Li
864*67e74705SXin Li<tbody>
865*67e74705SXin Li<tr><td><div class="namedescr expandable"><span class="name">
866*67e74705SXin Lisecurity.FloatLoopCounter</span><span class="lang">
867*67e74705SXin Li(C)</span><div class="descr">
868*67e74705SXin LiWarn on using a floating point value as a loop counter (CERT: FLP30-C,
869*67e74705SXin LiFLP30-CPP).</div></div></td>
870*67e74705SXin Li<td><div class="exampleContainer expandable">
871*67e74705SXin Li<div class="example"><pre>
872*67e74705SXin Livoid test() {
873*67e74705SXin Li  for (float x = 0.1f; x <= 1.0f; x += 0.1f) {} // warn
874*67e74705SXin Li}
875*67e74705SXin Li</pre></div></div></td></tr>
876*67e74705SXin Li
877*67e74705SXin Li
878*67e74705SXin Li<tr><td><div class="namedescr expandable"><span class="name">
879*67e74705SXin Lisecurity.insecureAPI.UncheckedReturn</span><span class="lang">
880*67e74705SXin Li(C)</span><div class="descr">
881*67e74705SXin LiWarn on uses of functions whose return values must be always checked:<div class=functions>
882*67e74705SXin Lisetuid<br>
883*67e74705SXin Lisetgid<br>
884*67e74705SXin Liseteuid<br>
885*67e74705SXin Lisetegid<br>
886*67e74705SXin Lisetreuid<br>
887*67e74705SXin Lisetregid</div></div></div></td>
888*67e74705SXin Li<td><div class="exampleContainer expandable">
889*67e74705SXin Li<div class="example"><pre>
890*67e74705SXin Livoid test() {
891*67e74705SXin Li  setuid(1); // warn
892*67e74705SXin Li}
893*67e74705SXin Li</pre></div></div></td></tr>
894*67e74705SXin Li
895*67e74705SXin Li
896*67e74705SXin Li<tr><td><div class="namedescr expandable"><span class="name">
897*67e74705SXin Lisecurity.insecureAPI.getpw</span><span class="lang">
898*67e74705SXin Li(C)</span><div class="descr">
899*67e74705SXin LiWarn on uses of the <code>getpw</code> function.</div></div></td>
900*67e74705SXin Li<td><div class="exampleContainer expandable">
901*67e74705SXin Li<div class="example"><pre>
902*67e74705SXin Livoid test() {
903*67e74705SXin Li  char buff[1024];
904*67e74705SXin Li  getpw(2, buff); // warn
905*67e74705SXin Li}
906*67e74705SXin Li</pre></div></div></td></tr>
907*67e74705SXin Li
908*67e74705SXin Li
909*67e74705SXin Li<tr><td><div class="namedescr expandable"><span class="name">
910*67e74705SXin Lisecurity.insecureAPI.gets</span><span class="lang">
911*67e74705SXin Li(C)</span><div class="descr">
912*67e74705SXin LiWarn on uses of the <code>gets</code> function.</div></div></td>
913*67e74705SXin Li<td><div class="exampleContainer expandable">
914*67e74705SXin Li<div class="example"><pre>
915*67e74705SXin Livoid test() {
916*67e74705SXin Li  char buff[1024];
917*67e74705SXin Li  gets(buff); // warn
918*67e74705SXin Li}
919*67e74705SXin Li</pre></div></div></td></tr>
920*67e74705SXin Li
921*67e74705SXin Li
922*67e74705SXin Li<tr><td><div class="namedescr expandable"><span class="name">
923*67e74705SXin Lisecurity.insecureAPI.mkstemp</span><span class="lang">
924*67e74705SXin Li(C)</span><div class="descr">
925*67e74705SXin LiWarn when <code>mktemp</code>, <code>mkstemp</code>, <code>mkstemps</code> or
926*67e74705SXin Li<code>mkdtemp</code> is passed fewer than 6
927*67e74705SXin LiX's in the format string.</div></div></td>
928*67e74705SXin Li<td><div class="exampleContainer expandable">
929*67e74705SXin Li<div class="example"><pre>
930*67e74705SXin Livoid test() {
931*67e74705SXin Li  mkstemp("XX"); // warn
932*67e74705SXin Li}
933*67e74705SXin Li</pre></div></div></td></tr>
934*67e74705SXin Li
935*67e74705SXin Li
936*67e74705SXin Li<tr><td><div class="namedescr expandable"><span class="name">
937*67e74705SXin Lisecurity.insecureAPI.mktemp</span><span class="lang">
938*67e74705SXin Li(C)</span><div class="descr">
939*67e74705SXin LiWarn on uses of the <code>mktemp</code> function.</div></div></td>
940*67e74705SXin Li<td><div class="exampleContainer expandable">
941*67e74705SXin Li<div class="example"><pre>
942*67e74705SXin Livoid test() {
943*67e74705SXin Li  char *x = mktemp("/tmp/zxcv"); // warn: insecure, use mkstemp
944*67e74705SXin Li}
945*67e74705SXin Li</pre></div></div></td></tr>
946*67e74705SXin Li
947*67e74705SXin Li
948*67e74705SXin Li<tr><td><div class="namedescr expandable"><span class="name">
949*67e74705SXin Lisecurity.insecureAPI.rand</span><span class="lang">
950*67e74705SXin Li(C)</span><div class="descr">
951*67e74705SXin LiWarn on uses of inferior random number generating functions (only if <code>arc4random</code>
952*67e74705SXin Lifunction is available):<div class=functions>
953*67e74705SXin Lidrand48<br>
954*67e74705SXin Lierand48<br>
955*67e74705SXin Lijrand48<br>
956*67e74705SXin Lilcong48<br>
957*67e74705SXin Lilrand48<br>
958*67e74705SXin Limrand48<br>
959*67e74705SXin Linrand48<br>
960*67e74705SXin Lirandom<br>
961*67e74705SXin Lirand_r</div></div></div></td>
962*67e74705SXin Li<td><div class="exampleContainer expandable">
963*67e74705SXin Li<div class="example"><pre>
964*67e74705SXin Livoid test() {
965*67e74705SXin Li  random(); // warn
966*67e74705SXin Li}
967*67e74705SXin Li</pre></div></div></td></tr>
968*67e74705SXin Li
969*67e74705SXin Li
970*67e74705SXin Li<tr><td><div class="namedescr expandable"><span class="name">
971*67e74705SXin Lisecurity.insecureAPI.strcpy</span><span class="lang">
972*67e74705SXin Li(C)</span><div class="descr">
973*67e74705SXin LiWarn on uses of the <code>strcpy</code> and <code>strcat</code> functions.</div></div></td>
974*67e74705SXin Li<td><div class="exampleContainer expandable">
975*67e74705SXin Li<div class="example"><pre>
976*67e74705SXin Livoid test() {
977*67e74705SXin Li  char x[4];
978*67e74705SXin Li  char *y = "abcd";
979*67e74705SXin Li
980*67e74705SXin Li  strcpy(x, y); // warn
981*67e74705SXin Li}
982*67e74705SXin Li</pre></div></div></td></tr>
983*67e74705SXin Li
984*67e74705SXin Li
985*67e74705SXin Li<tr><td><div class="namedescr expandable"><span class="name">
986*67e74705SXin Lisecurity.insecureAPI.vfork</span><span class="lang">
987*67e74705SXin Li(C)</span><div class="descr">
988*67e74705SXin LiWarn on uses of the <code>vfork</code> function.</div></div></td>
989*67e74705SXin Li<td><div class="exampleContainer expandable">
990*67e74705SXin Li<div class="example"><pre>
991*67e74705SXin Livoid test() {
992*67e74705SXin Li  vfork(); // warn
993*67e74705SXin Li}
994*67e74705SXin Li</pre></div></div></td></tr>
995*67e74705SXin Li
996*67e74705SXin Li</tbody></table>
997*67e74705SXin Li
998*67e74705SXin Li<!--------------------------------- unix -------------------------------------->
999*67e74705SXin Li<h3 id="unix_checkers">Unix Checkers</h3>
1000*67e74705SXin Li<table class="checkers">
1001*67e74705SXin Li<colgroup><col class="namedescr"><col class="example"></colgroup>
1002*67e74705SXin Li<thead><tr><td>Name, Description</td><td>Example</td></tr></thead>
1003*67e74705SXin Li
1004*67e74705SXin Li<tbody>
1005*67e74705SXin Li<tr><td><div class="namedescr expandable"><span class="name">
1006*67e74705SXin Liunix.API</span><span class="lang">
1007*67e74705SXin Li(C)</span><div class="descr">
1008*67e74705SXin LiCheck calls to various UNIX/POSIX functions:<div class=functions>
1009*67e74705SXin Liopen<br>
1010*67e74705SXin Lipthread_once<br>
1011*67e74705SXin Licalloc<br>
1012*67e74705SXin Limalloc<br>
1013*67e74705SXin Lirealloc<br>
1014*67e74705SXin Lialloca<br>
1015*67e74705SXin Li<td><div class="exampleContainer expandable">
1016*67e74705SXin Li<div class="example"><pre>
1017*67e74705SXin Li// Currently the check is performed for apple targets only.
1018*67e74705SXin Livoid test(const char *path) {
1019*67e74705SXin Li  int fd = open(path, O_CREAT);
1020*67e74705SXin Li    // warn: call to 'open' requires a third argument when the
1021*67e74705SXin Li    // 'O_CREAT' flag is set
1022*67e74705SXin Li}
1023*67e74705SXin Li</pre></div>
1024*67e74705SXin Li<div class="example"><pre>
1025*67e74705SXin Livoid f();
1026*67e74705SXin Li
1027*67e74705SXin Livoid test() {
1028*67e74705SXin Li  pthread_once_t pred = {0x30B1BCBA, {0}};
1029*67e74705SXin Li  pthread_once(&amp;pred, f);
1030*67e74705SXin Li    // warn: call to 'pthread_once' uses the local variable
1031*67e74705SXin Li}
1032*67e74705SXin Li</pre></div>
1033*67e74705SXin Li<div class="example"><pre>
1034*67e74705SXin Livoid test() {
1035*67e74705SXin Li  void *p = malloc(0); // warn: allocation size of 0 bytes
1036*67e74705SXin Li}
1037*67e74705SXin Li</pre></div>
1038*67e74705SXin Li<div class="example"><pre>
1039*67e74705SXin Livoid test() {
1040*67e74705SXin Li  void *p = calloc(0, 42); // warn: allocation size of 0 bytes
1041*67e74705SXin Li}
1042*67e74705SXin Li</pre></div>
1043*67e74705SXin Li<div class="example"><pre>
1044*67e74705SXin Livoid test() {
1045*67e74705SXin Li  void *p = malloc(1);
1046*67e74705SXin Li  p = realloc(p, 0); // warn: allocation size of 0 bytes
1047*67e74705SXin Li}
1048*67e74705SXin Li</pre></div>
1049*67e74705SXin Li<div class="example"><pre>
1050*67e74705SXin Livoid test() {
1051*67e74705SXin Li  void *p = alloca(0); // warn: allocation size of 0 bytes
1052*67e74705SXin Li}
1053*67e74705SXin Li</pre></div>
1054*67e74705SXin Li<div class="example"><pre>
1055*67e74705SXin Livoid test() {
1056*67e74705SXin Li  void *p = valloc(0); // warn: allocation size of 0 bytes
1057*67e74705SXin Li}
1058*67e74705SXin Li</pre></div></div></td></tr>
1059*67e74705SXin Li
1060*67e74705SXin Li
1061*67e74705SXin Li<tr><td><div class="namedescr expandable"><span class="name">
1062*67e74705SXin Liunix.Malloc</span><span class="lang">
1063*67e74705SXin Li(C)</span><div class="descr">
1064*67e74705SXin LiCheck for memory leaks, double free, and use-after-free and offset problems
1065*67e74705SXin Liinvolving <code>malloc</code>.</div></div></td>
1066*67e74705SXin Li<td><div class="exampleContainer expandable">
1067*67e74705SXin Li<div class="example"><pre>
1068*67e74705SXin Livoid test() {
1069*67e74705SXin Li  int *p = malloc(1);
1070*67e74705SXin Li  free(p);
1071*67e74705SXin Li  free(p); // warn: attempt to free released memory
1072*67e74705SXin Li}
1073*67e74705SXin Li</pre></div>
1074*67e74705SXin Li<div class="example"><pre>
1075*67e74705SXin Livoid test() {
1076*67e74705SXin Li  int *p = malloc(sizeof(int));
1077*67e74705SXin Li  free(p);
1078*67e74705SXin Li  *p = 1; // warn: use after free
1079*67e74705SXin Li}
1080*67e74705SXin Li</pre></div>
1081*67e74705SXin Li<div class="example"><pre>
1082*67e74705SXin Livoid test() {
1083*67e74705SXin Li  int *p = malloc(1);
1084*67e74705SXin Li  if (p)
1085*67e74705SXin Li    return; // warn: memory is never released
1086*67e74705SXin Li}
1087*67e74705SXin Li</pre></div>
1088*67e74705SXin Li<div class="example"><pre>
1089*67e74705SXin Livoid test() {
1090*67e74705SXin Li  int a[] = { 1 };
1091*67e74705SXin Li  free(a); // warn: argument is not allocated by malloc
1092*67e74705SXin Li}
1093*67e74705SXin Li</pre></div>
1094*67e74705SXin Li<div class="example"><pre>
1095*67e74705SXin Livoid test() {
1096*67e74705SXin Li  int *p = malloc(sizeof(char));
1097*67e74705SXin Li  p = p - 1;
1098*67e74705SXin Li  free(p); // warn: argument to free() is offset by -4 bytes
1099*67e74705SXin Li}
1100*67e74705SXin Li</pre></div></div></td></tr>
1101*67e74705SXin Li
1102*67e74705SXin Li
1103*67e74705SXin Li<tr><td><div class="namedescr expandable"><span class="name">
1104*67e74705SXin Liunix.MallocSizeof</span><span class="lang">
1105*67e74705SXin Li(C)</span><div class="descr">
1106*67e74705SXin LiCheck for dubious <code>malloc</code>, <code>calloc</code> or
1107*67e74705SXin Li<code>realloc</code> arguments involving <code>sizeof</code>.</div></div></td>
1108*67e74705SXin Li<td><div class="exampleContainer expandable">
1109*67e74705SXin Li<div class="example"><pre>
1110*67e74705SXin Livoid test() {
1111*67e74705SXin Li  long *p = malloc(sizeof(short));
1112*67e74705SXin Li    // warn: result is converted to 'long *', which is
1113*67e74705SXin Li    // incompatible with operand type 'short'
1114*67e74705SXin Li  free(p);
1115*67e74705SXin Li}
1116*67e74705SXin Li</pre></div></div></td></tr>
1117*67e74705SXin Li
1118*67e74705SXin Li
1119*67e74705SXin Li<tr><td><div class="namedescr expandable"><span class="name">
1120*67e74705SXin Liunix.MismatchedDeallocator</span><span class="lang">
1121*67e74705SXin Li(C, C++, ObjC)</span><div class="descr">
1122*67e74705SXin LiCheck for mismatched deallocators (e.g. passing a pointer allocating
1123*67e74705SXin Liwith <code>new</code> to <code>free()</code>).</div></div></td>
1124*67e74705SXin Li<td><div class="exampleContainer expandable">
1125*67e74705SXin Li<div class="example"><pre>
1126*67e74705SXin Li// C, C++
1127*67e74705SXin Livoid test() {
1128*67e74705SXin Li  int *p = (int *)malloc(sizeof(int));
1129*67e74705SXin Li  delete p; // warn
1130*67e74705SXin Li}
1131*67e74705SXin Li</pre></div>
1132*67e74705SXin Li<div class="example"><pre>
1133*67e74705SXin Li// C, C++
1134*67e74705SXin Livoid __attribute((ownership_returns(malloc))) *user_malloc(size_t);
1135*67e74705SXin Li
1136*67e74705SXin Livoid test() {
1137*67e74705SXin Li  int *p = (int *)user_malloc(sizeof(int));
1138*67e74705SXin Li  delete p; // warn
1139*67e74705SXin Li}
1140*67e74705SXin Li</pre></div>
1141*67e74705SXin Li<div class="example"><pre>
1142*67e74705SXin Li// C, C++
1143*67e74705SXin Livoid test() {
1144*67e74705SXin Li  int *p = new int;
1145*67e74705SXin Li  free(p); // warn
1146*67e74705SXin Li}
1147*67e74705SXin Li</pre></div>
1148*67e74705SXin Li<div class="example"><pre>
1149*67e74705SXin Li// C, C++
1150*67e74705SXin Livoid test() {
1151*67e74705SXin Li  int *p = new int[1];
1152*67e74705SXin Li  realloc(p, sizeof(long)); // warn
1153*67e74705SXin Li}
1154*67e74705SXin Li</pre></div>
1155*67e74705SXin Li<div class="example"><pre>
1156*67e74705SXin Li// C, C++
1157*67e74705SXin Litemplate &lt;typename T&gt;
1158*67e74705SXin Listruct SimpleSmartPointer {
1159*67e74705SXin Li  T *ptr;
1160*67e74705SXin Li
1161*67e74705SXin Li  explicit SimpleSmartPointer(T *p = 0) : ptr(p) {}
1162*67e74705SXin Li  ~SimpleSmartPointer() {
1163*67e74705SXin Li    delete ptr; // warn
1164*67e74705SXin Li  }
1165*67e74705SXin Li};
1166*67e74705SXin Li
1167*67e74705SXin Livoid test() {
1168*67e74705SXin Li  SimpleSmartPointer&lt;int&gt; a((int *)malloc(4));
1169*67e74705SXin Li}
1170*67e74705SXin Li</pre></div>
1171*67e74705SXin Li<div class="example"><pre>
1172*67e74705SXin Li// C++
1173*67e74705SXin Livoid test() {
1174*67e74705SXin Li  int *p = (int *)operator new(0);
1175*67e74705SXin Li  delete[] p; // warn
1176*67e74705SXin Li}
1177*67e74705SXin Li</pre></div>
1178*67e74705SXin Li<div class="example"><pre>
1179*67e74705SXin Li// Objective-C, C++
1180*67e74705SXin Livoid test(NSUInteger dataLength) {
1181*67e74705SXin Li  int *p = new int;
1182*67e74705SXin Li  NSData *d = [NSData dataWithBytesNoCopy:p
1183*67e74705SXin Li               length:sizeof(int) freeWhenDone:1];
1184*67e74705SXin Li    // warn +dataWithBytesNoCopy:length:freeWhenDone: cannot take
1185*67e74705SXin Li    // ownership of memory allocated by 'new'
1186*67e74705SXin Li}
1187*67e74705SXin Li</pre></div></div></td></tr>
1188*67e74705SXin Li
1189*67e74705SXin Li
1190*67e74705SXin Li<tr><td><div class="namedescr expandable"><span class="name">
1191*67e74705SXin Liunix.cstring.BadSizeArg</span><span class="lang">
1192*67e74705SXin Li(C)</span><div class="descr">
1193*67e74705SXin LiCheck the size argument passed to <code>strncat</code> for common erroneous
1194*67e74705SXin Lipatterns. Use <code>-Wno-strncat-size</code> compiler option to mute other
1195*67e74705SXin Li<code>strncat</code>-related compiler warnings.
1196*67e74705SXin Li</div></div></td>
1197*67e74705SXin Li<td><div class="exampleContainer expandable">
1198*67e74705SXin Li<div class="example"><pre>
1199*67e74705SXin Livoid test() {
1200*67e74705SXin Li  char dest[3];
1201*67e74705SXin Li  strncat(dest, "***", sizeof(dest));
1202*67e74705SXin Li    // warn: potential buffer overflow
1203*67e74705SXin Li}
1204*67e74705SXin Li</pre></div></div></td></tr>
1205*67e74705SXin Li
1206*67e74705SXin Li
1207*67e74705SXin Li<tr><td><div class="namedescr expandable"><span class="name">
1208*67e74705SXin Liunix.cstring.NullArg</span><span class="lang">
1209*67e74705SXin Li(C)</span><div class="descr">
1210*67e74705SXin LiCheck for null pointers being passed as arguments to C string functions:<div class=functions>
1211*67e74705SXin Listrlen<br>
1212*67e74705SXin Listrnlen<br>
1213*67e74705SXin Listrcpy<br>
1214*67e74705SXin Listrncpy<br>
1215*67e74705SXin Listrcat<br>
1216*67e74705SXin Listrncat<br>
1217*67e74705SXin Listrcmp<br>
1218*67e74705SXin Listrncmp<br>
1219*67e74705SXin Listrcasecmp<br>
1220*67e74705SXin Listrncasecmp</div></div></div></td>
1221*67e74705SXin Li<td><div class="example"><pre>
1222*67e74705SXin Liint test() {
1223*67e74705SXin Li  return strlen(0); // warn
1224*67e74705SXin Li}
1225*67e74705SXin Li</pre></div></td></tr>
1226*67e74705SXin Li
1227*67e74705SXin Li</tbody></table>
1228*67e74705SXin Li
1229*67e74705SXin Li</div> <!-- page -->
1230*67e74705SXin Li</div> <!-- content -->
1231*67e74705SXin Li</body>
1232*67e74705SXin Li</html>
1233