| 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 | |