You've already forked linux-packaging-mono
							
							
		
			
				
	
	
		
			1544 lines
		
	
	
		
			43 KiB
		
	
	
	
		
			HTML
		
	
	
	
	
	
			
		
		
	
	
			1544 lines
		
	
	
		
			43 KiB
		
	
	
	
		
			HTML
		
	
	
	
	
	
| <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
 | |
|           "http://www.w3.org/TR/html4/strict.dtd">
 | |
| <html>
 | |
| <head>
 | |
|   <title>Available Checkers</title>
 | |
|   <link type="text/css" rel="stylesheet" href="menu.css">
 | |
|   <link type="text/css" rel="stylesheet" href="content.css">
 | |
|   <script type="text/javascript" src="scripts/menu.js"></script>
 | |
|   <script type="text/javascript" src="scripts/expandcollapse.js"></script>
 | |
|   <style type="text/css">
 | |
|   tr:first-child { width:20%; }
 | |
|   </style>
 | |
| </head>
 | |
| <body onload="initExpandCollapse()">
 | |
| 
 | |
| <div id="page">
 | |
| <!--#include virtual="menu.html.incl"-->
 | |
| 
 | |
| <div id="content">
 | |
| <h1>Available Checkers</h1>
 | |
| The analyzer performs checks that are categorized into families or "checkers". The
 | |
| default set of checkers covers a variety of checks targeted at finding security
 | |
| and API usage bugs, dead code, and other logic errors. See the
 | |
| <a href = "#default_checkers">Default Checkers</a> list below. In addition to
 | |
| these, the analyzer contains a number of <a href = "alpha_checks.html">
 | |
| Experimental (Alpha) Checkers</a>.
 | |
| 
 | |
| <h3>Writeups with examples of some of the bugs that the analyzer finds</h3>
 | |
| <ul>
 | |
| <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>
 | |
| <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>
 | |
| <li><a href="http://www.rogueamoeba.com/utm/2008/07/14/the-clang-static-analyzer/">Under the Microscope - The Clang Static Analyzer</a></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>
 | |
| </ul>
 | |
| 
 | |
| <h2 id="default_checkers">Default Checkers</h2>
 | |
| <ul>
 | |
| <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>
 | |
| <li><a href="#cplusplus_checkers">C++ Checkers</a> perform C++-specific checks</li>
 | |
| <li><a href="#deadcode_checkers">Dead Code Checkers</a> check for unused code</li>
 | |
| <li><a href="#nullability_checkers">Nullability Checkers</a> </li>
 | |
| <li><a href="#optin_checkers">Optin Checkers</a> </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>
 | |
| <li><a href="#security_checkers">Security Checkers</a> check for insecure API usage and perform checks based on the CERT Secure Coding Standards</li>
 | |
| <li><a href="#unix_checkers">Unix Checkers</a> check the use of Unix and POSIX APIs</li>
 | |
| </ul>
 | |
| 
 | |
| <!-- =========================== core =========================== -->
 | |
| <h3 id="core_checkers">Core Checkers</h3>
 | |
| <table class="checkers">
 | |
| <colgroup><col class="namedescr"><col class="example"></colgroup>
 | |
| <thead><tr><td>Name, Description</td><td>Example</td></tr></thead>
 | |
| 
 | |
| <tbody>
 | |
| <tr><td><div class="namedescr expandable"><span class="name">
 | |
| core.CallAndMessage</span><span class="lang">
 | |
| (C, C++, ObjC)</span><div class="descr">
 | |
| Check for logical errors for function calls and Objective-C message expressions
 | |
| (e.g., uninitialized arguments, null function pointers).</div></div></td>
 | |
| <td><div class="exampleContainer expandable">
 | |
| <div class="example"><pre>
 | |
| // C
 | |
| struct S {
 | |
|   int x;
 | |
| };
 | |
| 
 | |
| void f(struct S s);
 | |
| 
 | |
| void test() {
 | |
|   struct S s;
 | |
|   f(s); // warn: passed-by-value arg contain uninitialized data
 | |
| }
 | |
| </pre></div>
 | |
| <div class="example"><pre>
 | |
| // C
 | |
| void test() {
 | |
|   void (*foo)(void);
 | |
|   foo(); // warn: function pointer is uninitialized
 | |
| }
 | |
| </pre></div>
 | |
| <div class="example"><pre>
 | |
| // C
 | |
| void test() {
 | |
|   void (*foo)(void);
 | |
|   foo = 0;
 | |
|   foo(); // warn: function pointer is null
 | |
| }
 | |
| </pre></div>
 | |
| <div class="example"><pre>
 | |
| // C++
 | |
| class C {
 | |
| public:
 | |
|   void f();
 | |
| };
 | |
| 
 | |
| void test() {
 | |
|   C *pc;
 | |
|   pc->f(); // warn: object pointer is uninitialized
 | |
| }
 | |
| </pre></div>
 | |
| <div class="example"><pre>
 | |
| // C++
 | |
| class C {
 | |
| public:
 | |
|   void f();
 | |
| };
 | |
| 
 | |
| void test() {
 | |
|   C *pc = 0;
 | |
|   pc->f(); // warn: object pointer is null
 | |
| }
 | |
| </pre></div>
 | |
| <div class="example"><pre>
 | |
| // Objective-C
 | |
| @interface MyClass : NSObject
 | |
| @property (readwrite,assign) id x;
 | |
| - (long double)longDoubleM;
 | |
| @end
 | |
| 
 | |
| void test() {
 | |
|   MyClass *obj1;
 | |
|   long double ld1 = [obj1 longDoubleM];
 | |
|     // warn: receiver is uninitialized
 | |
| }
 | |
| </pre></div>
 | |
| <div class="example"><pre>
 | |
| // Objective-C
 | |
| @interface MyClass : NSObject
 | |
| @property (readwrite,assign) id x;
 | |
| - (long double)longDoubleM;
 | |
| @end
 | |
| 
 | |
| void test() {
 | |
|   MyClass *obj1;
 | |
|   id i = obj1.x; // warn: uninitialized object pointer
 | |
| }
 | |
| </pre></div>
 | |
| <div class="example"><pre>
 | |
| // Objective-C
 | |
| @interface Subscriptable : NSObject
 | |
| - (id)objectAtIndexedSubscript:(unsigned int)index;
 | |
| @end
 | |
| 
 | |
| @interface MyClass : Subscriptable
 | |
| @property (readwrite,assign) id x;
 | |
| - (long double)longDoubleM;
 | |
| @end
 | |
| 
 | |
| void test() {
 | |
|   MyClass *obj1;
 | |
|   id i = obj1[0]; // warn: uninitialized object pointer
 | |
| }
 | |
| </pre></div></div></td></tr>
 | |
| 
 | |
| 
 | |
| <tr><td><div class="namedescr expandable"><span class="name">
 | |
| core.DivideZero</span><span class="lang">
 | |
| (C, C++, ObjC)</span><div class="descr">
 | |
| Check for division by zero.</div></div></td>
 | |
| <td><div class="exampleContainer expandable">
 | |
| <div class="example"><pre>
 | |
| void test(int z) {
 | |
|   if (z == 0)
 | |
|     int x = 1 / z; // warn
 | |
| }
 | |
| </pre></div>
 | |
| <div class="example"><pre>
 | |
| void test() {
 | |
|   int x = 1;
 | |
|   int y = x % 0; // warn
 | |
| }
 | |
| </pre></div></div></td></tr>
 | |
| 
 | |
| 
 | |
| <tr><td><div class="namedescr expandable"><span class="name">
 | |
| core.NonNullParamChecker</span><span class="lang">
 | |
| (C, C++, ObjC)</span><div class="descr">
 | |
| Check for null pointers passed as arguments to a function whose arguments are
 | |
| marked with the <code>nonnull</code> attribute.</div></div></td>
 | |
| <td><div class="exampleContainer expandable">
 | |
| <div class="example"><pre>
 | |
| int f(int *p) __attribute__((nonnull));
 | |
| 
 | |
| void test(int *p) {
 | |
|   if (!p)
 | |
|     f(p); // warn
 | |
| }
 | |
| </pre></div></div></td></tr>
 | |
| 
 | |
| 
 | |
| <tr><td><div class="namedescr expandable"><span class="name">
 | |
| core.NullDereference</span><span class="lang">
 | |
| (C, C++, ObjC)</span><div class="descr">
 | |
| Check for dereferences of null pointers.</div></div></td>
 | |
| <td><div class="exampleContainer expandable">
 | |
| <div class="example"><pre>
 | |
| // C
 | |
| void test(int *p) {
 | |
|   if (p)
 | |
|     return;
 | |
| 
 | |
|   int x = p[0]; // warn
 | |
| }
 | |
| </pre></div>
 | |
| <div class="example"><pre>
 | |
| // C
 | |
| void test(int *p) {
 | |
|   if (!p)
 | |
|     *p = 0; // warn
 | |
| }
 | |
| </pre></div>
 | |
| <div class="example"><pre>
 | |
| // C++
 | |
| class C {
 | |
| public:
 | |
|   int x;
 | |
| };
 | |
| 
 | |
| void test() {
 | |
|   C *pc = 0;
 | |
|   int k = pc->x; // warn
 | |
| }
 | |
| </pre></div>
 | |
| <div class="example"><pre>
 | |
| // Objective-C
 | |
| @interface MyClass {
 | |
| @public
 | |
|   int x;
 | |
| }
 | |
| @end
 | |
| 
 | |
| void test() {
 | |
|   MyClass *obj = 0;
 | |
|   obj->x = 1; // warn
 | |
| }
 | |
| </pre></div></div></td></tr>
 | |
| 
 | |
| 
 | |
| <tr><td><div class="namedescr expandable"><span class="name">
 | |
| core.StackAddressEscape</span><span class="lang">
 | |
| (C)</span><div class="descr">
 | |
| Check that addresses of stack memory do not escape the function.</div></div></td>
 | |
| <td><div class="exampleContainer expandable">
 | |
| <div class="example"><pre>
 | |
| char const *p;
 | |
| 
 | |
| void test() {
 | |
|   char const str[] = "string";
 | |
|   p = str; // warn
 | |
| }
 | |
| </pre></div>
 | |
| <div class="example"><pre>
 | |
| void* test() {
 | |
|    return __builtin_alloca(12); // warn
 | |
| }
 | |
| </pre></div>
 | |
| <div class="example"><pre>
 | |
| void test() {
 | |
|   static int *x;
 | |
|   int y;
 | |
|   x = &y; // warn
 | |
| }
 | |
| </pre></div></div></td></tr>
 | |
| 
 | |
| 
 | |
| <tr><td><div class="namedescr expandable"><span class="name">
 | |
| core.UndefinedBinaryOperatorResult</span><span class="lang">
 | |
| (C)</span><div class="descr">
 | |
| Check for undefined results of binary operators.</div></div></td>
 | |
| <td><div class="exampleContainer expandable">
 | |
| <div class="example"><pre>
 | |
| void test() {
 | |
|   int x;
 | |
|   int y = x + 1; // warn: left operand is garbage
 | |
| }
 | |
| </pre></div></div></td></tr>
 | |
| 
 | |
| 
 | |
| <tr><td><div class="namedescr expandable"><span class="name">
 | |
| core.VLASize</span><span class="lang">
 | |
| (C)</span><div class="descr">
 | |
| Check for declarations of VLA of undefined or zero size.</div></div></td>
 | |
| <td><div class="exampleContainer expandable">
 | |
| <div class="example"><pre>
 | |
| void test() {
 | |
|   int x;
 | |
|   int vla1[x]; // warn: garbage as size
 | |
| }
 | |
| </pre></div>
 | |
| <div class="example"><pre>
 | |
| void test() {
 | |
|   int x = 0;
 | |
|   int vla2[x]; // warn: zero size
 | |
| }
 | |
| </pre></div></div></td></tr>
 | |
| 
 | |
| 
 | |
| <tr><td><div class="namedescr expandable"><span class="name">
 | |
| core.uninitialized.ArraySubscript</span><span class="lang">
 | |
| (C)</span><div class="descr">
 | |
| Check for uninitialized values used as array subscripts.</div></div></td>
 | |
| <td><div class="exampleContainer expandable">
 | |
| <div class="example"><pre>
 | |
| void test() {
 | |
|   int i, a[10];
 | |
|   int x = a[i]; // warn: array subscript is undefined
 | |
| }
 | |
| </pre></div></div></td></tr>
 | |
| 
 | |
| 
 | |
| <tr><td><div class="namedescr expandable"><span class="name">
 | |
| core.uninitialized.Assign</span><span class="lang">
 | |
| (C)</span><div class="descr">
 | |
| Check for assigning uninitialized values.</div></div></td>
 | |
| <td><div class="exampleContainer expandable">
 | |
| <div class="example"><pre>
 | |
| void test() {
 | |
|   int x;
 | |
|   x |= 1; // warn: left expression is unitialized
 | |
| }
 | |
| </pre></div></div></td></tr>
 | |
| 
 | |
| 
 | |
| <tr><td><div class="namedescr expandable"><span class="name">
 | |
| core.uninitialized.Branch</span><span class="lang">
 | |
| (C)</span><div class="descr">
 | |
| Check for uninitialized values used as branch conditions.</div></div></td>
 | |
| <td><div class="exampleContainer expandable">
 | |
| <div class="example"><pre>
 | |
| void test() {
 | |
|   int x;
 | |
|   if (x) // warn
 | |
|     return;
 | |
| }
 | |
| </pre></div></div></td></tr>
 | |
| 
 | |
| 
 | |
| <tr><td><div class="namedescr expandable"><span class="name">
 | |
| core.uninitialized.CapturedBlockVariable</span><span class="lang">
 | |
| (C)</span><div class="descr">
 | |
| Check for blocks that capture uninitialized values.</div></div></td>
 | |
| <td><div class="exampleContainer expandable">
 | |
| <div class="example"><pre>
 | |
| void test() {
 | |
|   int x;
 | |
|   ^{ int y = x; }(); // warn
 | |
| }
 | |
| </pre></div></div></td></tr>
 | |
| 
 | |
| 
 | |
| <tr><td><div class="namedescr expandable"><span class="name">
 | |
| core.uninitialized.UndefReturn</span><span class="lang">
 | |
| (C)</span><div class="descr">
 | |
| Check for uninitialized values being returned to the caller.</div></div></td>
 | |
| <td><div class="exampleContainer expandable">
 | |
| <div class="example"><pre>
 | |
| int test() {
 | |
|   int x;
 | |
|   return x; // warn
 | |
| }
 | |
| </pre></div></div></td></tr>
 | |
| 
 | |
| </tbody></table>
 | |
| 
 | |
| <!-- =========================== C++ =========================== -->
 | |
| <h3 id="cplusplus_checkers">C++ Checkers</h3>
 | |
| <table class="checkers">
 | |
| <colgroup><col class="namedescr"><col class="example"></colgroup>
 | |
| <thead><tr><td>Name, Description</td><td>Example</td></tr></thead>
 | |
| 
 | |
| <tbody>
 | |
| <tr><td><div class="namedescr expandable"><span class="name">
 | |
| cplusplus.NewDelete</span><span class="lang">
 | |
| (C++)</span><div class="descr">
 | |
| Check for double-free, use-after-free and offset problems involving C++ <code>
 | |
| delete</code>.</div></div></td>
 | |
| <td><div class="exampleContainer expandable">
 | |
| <div class="example"><pre>
 | |
| void f(int *p);
 | |
| 
 | |
| void testUseMiddleArgAfterDelete(int *p) {
 | |
|   delete p;
 | |
|   f(p); // warn: use after free
 | |
| }
 | |
| </pre></div>
 | |
| <div class="example"><pre>
 | |
| class SomeClass {
 | |
| public:
 | |
|   void f();
 | |
| };
 | |
| 
 | |
| void test() {
 | |
|   SomeClass *c = new SomeClass;
 | |
|   delete c;
 | |
|   c->f(); // warn: use after free
 | |
| }
 | |
| </pre></div>
 | |
| <div class="example"><pre>
 | |
| void test() {
 | |
|   int *p = (int *)__builtin_alloca(sizeof(int));
 | |
|   delete p; // warn: deleting memory allocated by alloca
 | |
| }
 | |
| </pre></div>
 | |
| <div class="example"><pre>
 | |
| void test() {
 | |
|   int *p = new int;
 | |
|   delete p;
 | |
|   delete p; // warn: attempt to free released
 | |
| }
 | |
| </pre></div>
 | |
| <div class="example"><pre>
 | |
| void test() {
 | |
|   int i;
 | |
|   delete &i; // warn: delete address of local
 | |
| }
 | |
| </pre></div>
 | |
| <div class="example"><pre>
 | |
| void test() {
 | |
|   int *p = new int[1];
 | |
|   delete[] (++p);
 | |
|     // warn: argument to 'delete[]' is offset by 4 bytes
 | |
|     // from the start of memory allocated by 'new[]'
 | |
| }
 | |
| </pre></div></div></td></tr>
 | |
| 
 | |
| <tr><td><div class="namedescr expandable"><span class="name">
 | |
| cplusplus.NewDeleteLeaks</span><span class="lang">
 | |
| (C++)</span><div class="descr">
 | |
| Check for memory leaks. Traces memory managed by <code>new</code>/<code>
 | |
| delete</code>.</div></div></td>
 | |
| <td><div class="exampleContainer expandable">
 | |
| <div class="example"><pre>
 | |
| void test() {
 | |
|   int *p = new int;
 | |
| } // warn
 | |
| </pre></div></div></td></tr>
 | |
| 
 | |
| </tbody></table>
 | |
| 
 | |
| <!-- =========================== dead code =========================== -->
 | |
| <h3 id="deadcode_checkers">Dead Code Checkers</h3>
 | |
| <table class="checkers">
 | |
| <colgroup><col class="namedescr"><col class="example"></colgroup>
 | |
| <thead><tr><td>Name, Description</td><td>Example</td></tr></thead>
 | |
| 
 | |
| <tbody>
 | |
| <tr><td><div class="namedescr expandable"><span class="name">
 | |
| deadcode.DeadStores</span><span class="lang">
 | |
| (C)</span><div class="descr">
 | |
| Check for values stored to variables that are never read afterwards.</div></div></td>
 | |
| <td><div class="exampleContainer expandable">
 | |
| <div class="example"><pre>
 | |
| void test() {
 | |
|   int x;
 | |
|   x = 1; // warn
 | |
| }
 | |
| </pre></div></div></td></tr>
 | |
| 
 | |
| </tbody></table>
 | |
| 
 | |
| <!-- =========================== nullability =========================== -->
 | |
| <h3 id="nullability_checkers">Nullability Checkers</h3>
 | |
| <table class="checkers">
 | |
| <colgroup><col class="namedescr"><col class="example"></colgroup>
 | |
| <thead><tr><td>Name, Description</td><td>Example</td></tr></thead>
 | |
| 
 | |
| <tbody>
 | |
| <tr><td><div class="namedescr expandable"><span class="name">
 | |
| nullability.NullPassedToNonnull</span><span class="lang">
 | |
| (ObjC)</span><div class="descr">
 | |
| Warns when a null pointer is passed to a pointer which has a 
 | |
| _Nonnull type.</div></div></td>
 | |
| <td><div class="exampleContainer expandable">
 | |
| <div class="example"><pre>
 | |
| if (name != nil)
 | |
|   return;
 | |
| // Warning: nil passed to a callee that requires a non-null 1st parameter
 | |
| NSString *greeting = [@"Hello " stringByAppendingString:name];
 | |
| </pre></div></div></td></tr>
 | |
| 
 | |
| 
 | |
| <tr><td><div class="namedescr expandable"><span class="name">
 | |
| nullability.NullReturnedFromNonnull</span><span class="lang">
 | |
| (ObjC)</span><div class="descr">
 | |
| Warns when a null pointer is returned from a function that has 
 | |
| _Nonnull return type.</div></div></td>
 | |
| <td><div class="exampleContainer expandable">
 | |
| <div class="example"><pre>
 | |
| - (nonnull id)firstChild {
 | |
|   id result = nil;
 | |
|   if ([_children count] > 0)
 | |
|     result = _children[0];
 | |
| 
 | |
|   // Warning: nil returned from a method that is expected 
 | |
|   // to return a non-null value
 | |
|   return result;
 | |
| }
 | |
| </pre></div></div></td></tr>
 | |
| 
 | |
| 
 | |
| <tr><td><div class="namedescr expandable"><span class="name">
 | |
| nullability.NullableDereferenced</span><span class="lang">
 | |
| (ObjC)</span><div class="descr">
 | |
| Warns when a nullable pointer is dereferenced.</div></div></td>
 | |
| <td><div class="exampleContainer expandable">
 | |
| <div class="example"><pre>
 | |
| struct LinkedList {
 | |
|   int data;
 | |
|   struct LinkedList *next;
 | |
| };
 | |
| 
 | |
| struct LinkedList * _Nullable getNext(struct LinkedList *l);
 | |
| 
 | |
| void updateNextData(struct LinkedList *list, int newData) {
 | |
|   struct LinkedList *next = getNext(list);
 | |
|   // Warning: Nullable pointer is dereferenced
 | |
|   next->data = 7;
 | |
| }
 | |
| </pre></div></div></td></tr>
 | |
| 
 | |
| 
 | |
| <tr><td><div class="namedescr expandable"><span class="name">
 | |
| nullability.NullablePassedToNonnull</span><span class="lang">
 | |
| (ObjC)</span><div class="descr">
 | |
| Warns when a nullable pointer is passed to a pointer which has a _Nonnull type.</div></div></td>
 | |
| <td><div class="exampleContainer expandable">
 | |
| <div class="example"><pre>
 | |
| typedef struct Dummy { int val; } Dummy;
 | |
| Dummy *_Nullable returnsNullable();
 | |
| void takesNonnull(Dummy *_Nonnull);
 | |
| 
 | |
| void test() {
 | |
|   Dummy *p = returnsNullable();
 | |
|   takesNonnull(p); // warn
 | |
| }
 | |
| </pre></div></div></td></tr>
 | |
| 
 | |
| </tbody></table>
 | |
| 
 | |
| <!-- =========================== optin =========================== -->
 | |
| <h3 id="optin_checkers">Optin Checkers</h3>
 | |
| <table class="checkers">
 | |
| <colgroup><col class="namedescr"><col class="example"></colgroup>
 | |
| <thead><tr><td>Name, Description</td><td>Example</td></tr></thead>
 | |
| 
 | |
| <tbody>
 | |
| <tr><td><div class="namedescr expandable"><span class="name">
 | |
| optin.mpi.MPI-Checker</span><span class="lang">
 | |
| (C)</span><div class="descr">
 | |
| Checks MPI code</div></div></td>
 | |
| <td><div class="exampleContainer expandable">
 | |
| <div class="example"><pre>
 | |
| void test() {
 | |
|   double buf = 0;
 | |
|   MPI_Request sendReq1;
 | |
|   MPI_Ireduce(MPI_IN_PLACE, &buf, 1, MPI_DOUBLE, MPI_SUM, 
 | |
|       0, MPI_COMM_WORLD, &sendReq1);
 | |
| } // warn: request 'sendReq1' has no matching wait.
 | |
| </pre></div><div class="separator"></div>
 | |
| <div class="example"><pre>
 | |
| void test() {
 | |
|   double buf = 0;
 | |
|   MPI_Request sendReq;
 | |
|   MPI_Isend(&buf, 1, MPI_DOUBLE, 0, 0, MPI_COMM_WORLD, &sendReq);
 | |
|   MPI_Irecv(&buf, 1, MPI_DOUBLE, 0, 0, MPI_COMM_WORLD, &sendReq); // warn
 | |
|   MPI_Isend(&buf, 1, MPI_DOUBLE, 0, 0, MPI_COMM_WORLD, &sendReq); // warn
 | |
|   MPI_Wait(&sendReq, MPI_STATUS_IGNORE);
 | |
| }
 | |
| </pre></div><div class="separator"></div>
 | |
| <div class="example"><pre>
 | |
| void missingNonBlocking() {
 | |
|   int rank = 0;
 | |
|   MPI_Comm_rank(MPI_COMM_WORLD, &rank);
 | |
|   MPI_Request sendReq1[10][10][10];
 | |
|   MPI_Wait(&sendReq1[1][7][9], MPI_STATUS_IGNORE); // warn
 | |
| }
 | |
| </pre></div></div></td></tr>
 | |
| 
 | |
| 
 | |
| <tr><td><div class="namedescr expandable"><span class="name">
 | |
| optin.osx.cocoa.localizability.EmptyLocalizationContextChecker</span><span class="lang">
 | |
| (ObjC)</span><div class="descr">
 | |
| Check that NSLocalizedString macros include a comment for context.</div></div></td>
 | |
| <td><div class="exampleContainer expandable">
 | |
| <div class="example"><pre>
 | |
| - (void)test {
 | |
|   NSString *string = NSLocalizedString(@"LocalizedString", nil); // warn
 | |
|   NSString *string2 = NSLocalizedString(@"LocalizedString", @" "); // warn
 | |
|   NSString *string3 = NSLocalizedStringWithDefaultValue(
 | |
|     @"LocalizedString", nil, [[NSBundle alloc] init], nil,@""); // warn
 | |
| }
 | |
| </pre></div></div></td></tr>
 | |
| 
 | |
| 
 | |
| <tr><td><div class="namedescr expandable"><span class="name">
 | |
| optin.osx.cocoa.localizability.NonLocalizedStringChecker</span><span class="lang">
 | |
| (ObjC)</span><div class="descr">
 | |
| Warns about uses of non-localized NSStrings passed to UI methods 
 | |
| expecting localized NSStrings</div></div></td>
 | |
| <td><div class="exampleContainer expandable">
 | |
| <div class="example"><pre>
 | |
| NSString *alarmText = 
 | |
|   NSLocalizedString(@"Enabled", @"Indicates alarm is turned on");
 | |
| if (!isEnabled) {
 | |
|   alarmText = @"Disabled";
 | |
| }
 | |
| UILabel *alarmStateLabel = [[UILabel alloc] init];
 | |
| 
 | |
| // Warning: User-facing text should use localized string macro
 | |
| [alarmStateLabel setText:alarmText];
 | |
| </pre></div></div></td></tr>
 | |
| 
 | |
| </tbody></table>
 | |
| 
 | |
| <!-- =========================== OS X =========================== -->
 | |
| <h3 id="osx_checkers">OS X Checkers</h3>
 | |
| <table class="checkers">
 | |
| <colgroup><col class="namedescr"><col class="example"></colgroup>
 | |
| <thead><tr><td>Name, Description</td><td>Example</td></tr></thead>
 | |
| 
 | |
| <tbody>
 | |
| <tr><td><div class="namedescr expandable"><span class="name">
 | |
| osx.API</span><span class="lang">
 | |
| (C)</span><div class="descr">
 | |
| Check for proper uses of various Apple APIs:<div class=functions>
 | |
| dispatch_once</div></div></div></td>
 | |
| <td><div class="exampleContainer expandable">
 | |
| <div class="example"><pre>
 | |
| void test() {
 | |
|   dispatch_once_t pred = 0;
 | |
|   dispatch_once(&pred, ^(){}); // warn: dispatch_once uses local
 | |
| }
 | |
| </pre></div></div></td></tr>
 | |
| 
 | |
| 
 | |
| <tr><td><div class="namedescr expandable"><span class="name">
 | |
| osx.NumberObjectConversion</span><span class="lang">
 | |
| (C, C++, ObjC)</span><div class="descr">
 | |
| Check for erroneous conversions of objects representing numbers 
 | |
| into numbers</div></div></td>
 | |
| <td><div class="exampleContainer expandable">
 | |
| <div class="example"><pre>
 | |
| NSNumber *photoCount = [albumDescriptor objectForKey:@"PhotoCount"];
 | |
| // Warning: Comparing a pointer value of type 'NSNumber *' 
 | |
| // to a scalar integer value
 | |
| if (photoCount > 0) {
 | |
|   [self displayPhotos];
 | |
| }
 | |
| </pre></div></div></td></tr>
 | |
| 
 | |
| 
 | |
| <tr><td><div class="namedescr expandable"><span class="name">
 | |
| osx.SecKeychainAPI</span><span class="lang">
 | |
| (C)</span><div class="descr">
 | |
| Check for improper uses of the Security framework's Keychain APIs:<div class=functions>
 | |
| SecKeychainItemCopyContent<br>
 | |
| SecKeychainFindGenericPassword<br>
 | |
| SecKeychainFindInternetPassword<br>
 | |
| SecKeychainItemFreeContent<br>
 | |
| SecKeychainItemCopyAttributesAndData<br>
 | |
| SecKeychainItemFreeAttributesAndData</div></div></div></td>
 | |
| <td><div class="exampleContainer expandable">
 | |
| <div class="example"><pre>
 | |
| void test() {
 | |
|   unsigned int *ptr = 0;
 | |
|   UInt32 length;
 | |
| 
 | |
|   SecKeychainItemFreeContent(ptr, &length);
 | |
|     // warn: trying to free data which has not been allocated
 | |
| }
 | |
| </pre></div>
 | |
| <div class="example"><pre>
 | |
| void test() {
 | |
|   unsigned int *ptr = 0;
 | |
|   UInt32 *length = 0;
 | |
|   void *outData;
 | |
| 
 | |
|   OSStatus st =
 | |
|     SecKeychainItemCopyContent(2, ptr, ptr, length, outData);
 | |
|     // warn: data is not released
 | |
| }
 | |
| </pre></div>
 | |
| <div class="example"><pre>
 | |
| void test() {
 | |
|   unsigned int *ptr = 0;
 | |
|   UInt32 *length = 0;
 | |
|   void *outData;
 | |
| 
 | |
|   OSStatus st =
 | |
|     SecKeychainItemCopyContent(2, ptr, ptr, length, &outData);
 | |
| 
 | |
|   SecKeychainItemFreeContent(ptr, outData);
 | |
|     // warn: only call free if a non-NULL buffer was returned
 | |
| }
 | |
| </pre></div>
 | |
| <div class="example"><pre>
 | |
| void test() {
 | |
|   unsigned int *ptr = 0;
 | |
|   UInt32 *length = 0;
 | |
|   void *outData;
 | |
| 
 | |
|   OSStatus st =
 | |
|     SecKeychainItemCopyContent(2, ptr, ptr, length, &outData);
 | |
| 
 | |
|   st = SecKeychainItemCopyContent(2, ptr, ptr, length, &outData);
 | |
|     // warn: release data before another call to the allocator
 | |
| 
 | |
|   if (st == noErr)
 | |
|     SecKeychainItemFreeContent(ptr, outData);
 | |
| }
 | |
| </pre></div>
 | |
| <div class="example"><pre>
 | |
| void test() {
 | |
|   SecKeychainItemRef itemRef = 0;
 | |
|   SecKeychainAttributeInfo *info = 0;
 | |
|   SecItemClass *itemClass = 0;
 | |
|   SecKeychainAttributeList *attrList = 0;
 | |
|   UInt32 *length = 0;
 | |
|   void *outData = 0;
 | |
| 
 | |
|   OSStatus st =
 | |
|     SecKeychainItemCopyAttributesAndData(itemRef, info,
 | |
|                                          itemClass, &attrList,
 | |
|                                          length, &outData);
 | |
| 
 | |
|   SecKeychainItemFreeContent(attrList, outData);
 | |
|     // warn: deallocator doesn't match the allocator
 | |
| }
 | |
| </pre></div></div></td></tr>
 | |
| 
 | |
| 
 | |
| <tr><td><div class="namedescr expandable"><span class="name">
 | |
| osx.cocoa.AtSync</span><span class="lang">
 | |
| (ObjC)</span><div class="descr">
 | |
| Check for nil pointers used as mutexes for <code>@synchronized</code>.</div></div></td>
 | |
| <td><div class="exampleContainer expandable">
 | |
| <div class="example"><pre>
 | |
| void test(id x) {
 | |
|   if (!x)
 | |
|     @synchronized(x) {} // warn: nil value used as mutex
 | |
| }
 | |
| </pre></div>
 | |
| <div class="example"><pre>
 | |
| void test() {
 | |
|   id y;
 | |
|   @synchronized(y) {} // warn: uninitialized value used as mutex
 | |
| }
 | |
| </pre></div></div></td></tr>
 | |
| 
 | |
| 
 | |
| <tr><td><div class="namedescr expandable"><span class="name">
 | |
| osx.cocoa.ClassRelease</span><span class="lang">
 | |
| (ObjC)</span><div class="descr">
 | |
| Check for sending <code>retain</code>, <code>release</code>, or <code>
 | |
| autorelease</code> directly to a class.</div></div></td>
 | |
| <td><div class="exampleContainer expandable">
 | |
| <div class="example"><pre>
 | |
| @interface MyClass : NSObject
 | |
| @end
 | |
| 
 | |
| void test(void) {
 | |
|   [MyClass release]; // warn
 | |
| }
 | |
| </pre></div></div></td></tr>
 | |
| 
 | |
| 
 | |
| <tr><td><div class="namedescr expandable"><span class="name">
 | |
| osx.cocoa.Dealloc</span><span class="lang">
 | |
| (ObjC)</span><div class="descr">
 | |
| Warn about Objective-C classes that lack a correct implementation 
 | |
| of <code>-dealloc</code>.
 | |
| </div></div></td>
 | |
| <td><div class="exampleContainer expandable">
 | |
| <div class="example"><pre>
 | |
| @interface MyObject : NSObject {
 | |
|   id _myproperty;  
 | |
| }
 | |
| @end
 | |
| 
 | |
| @implementation MyObject // warn: lacks 'dealloc'
 | |
| @end
 | |
| </pre></div><div class="separator"></div>
 | |
| <div class="example"><pre>
 | |
| @interface MyObject : NSObject {}
 | |
| @property(assign) id myproperty;
 | |
| @end
 | |
| 
 | |
| @implementation MyObject // warn: does not send 'dealloc' to super
 | |
| - (void)dealloc {
 | |
|   self.myproperty = 0;
 | |
| }
 | |
| @end
 | |
| </pre></div><div class="separator"></div>
 | |
| <div class="example"><pre>
 | |
| @interface MyObject : NSObject {
 | |
|   id _myproperty;
 | |
| }
 | |
| @property(retain) id myproperty;
 | |
| @end
 | |
| 
 | |
| @implementation MyObject
 | |
| @synthesize myproperty = _myproperty;
 | |
|   // warn: var was retained but wasn't released
 | |
| - (void)dealloc {
 | |
|   [super dealloc];
 | |
| }
 | |
| @end
 | |
| </pre></div><div class="separator"></div>
 | |
| <div class="example"><pre>
 | |
| @interface MyObject : NSObject {
 | |
|   id _myproperty;
 | |
| }
 | |
| @property(assign) id myproperty;
 | |
| @end
 | |
| 
 | |
| @implementation MyObject
 | |
| @synthesize myproperty = _myproperty;
 | |
|   // warn: var wasn't retained but was released
 | |
| - (void)dealloc {
 | |
|   [_myproperty release];
 | |
|   [super dealloc];
 | |
| }
 | |
| @end
 | |
| </pre></div></div></td></tr>
 | |
| 
 | |
| 
 | |
| <tr><td><div class="namedescr expandable"><span class="name">
 | |
| osx.cocoa.IncompatibleMethodTypes</span><span class="lang">
 | |
| (ObjC)</span><div class="descr">
 | |
| Check for an incompatible type signature when overriding an Objective-C method.</div></div></td>
 | |
| <td><div class="exampleContainer expandable">
 | |
| <div class="example"><pre>
 | |
| @interface MyClass1 : NSObject
 | |
| - (int)foo;
 | |
| @end
 | |
| 
 | |
| @implementation MyClass1
 | |
| - (int)foo { return 1; }
 | |
| @end
 | |
| 
 | |
| @interface MyClass2 : MyClass1
 | |
| - (float)foo;
 | |
| @end
 | |
| 
 | |
| @implementation MyClass2
 | |
| - (float)foo { return 1.0; } // warn
 | |
| @end
 | |
| </pre></div></div></td></tr>
 | |
| 
 | |
| 
 | |
| <tr><td><div class="namedescr expandable"><span class="name">
 | |
| alpha.osx.cocoa.MissingSuperCall</span><span class="lang">
 | |
| (ObjC)</span><div class="descr">
 | |
| Warn about Objective-C methods that lack a necessary call to super. (Note: The
 | |
| compiler now has a warning for methods annotated with <code>objc_requires_super</code>
 | |
| attribute. The checker exists to check methods in the Cocoa frameworks
 | |
| that haven't yet adopted this attribute.)</div></div></td>
 | |
| <td><div class="example"><pre>
 | |
| @interface Test : UIViewController
 | |
| @end
 | |
| @implementation test
 | |
| - (void)viewDidLoad {} // warn
 | |
| @end
 | |
| </pre></div></td></tr>
 | |
| 
 | |
| 
 | |
| <tr><td><div class="namedescr expandable"><span class="name">
 | |
| osx.cocoa.NSAutoreleasePool</span><span class="lang">
 | |
| (ObjC)</span><div class="descr">
 | |
| Warn for suboptimal uses of NSAutoreleasePool in Objective-C
 | |
| GC mode (<code>-fobjc-gc</code> compiler option).</div></div></td>
 | |
| <td><div class="exampleContainer expandable">
 | |
| <div class="example"><pre>
 | |
| void test() {
 | |
|   NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
 | |
|   [pool release]; // warn
 | |
| }
 | |
| </pre></div></div></td></tr>
 | |
| 
 | |
| 
 | |
| <tr><td><div class="namedescr expandable"><span class="name">
 | |
| osx.cocoa.NSError</span><span class="lang">
 | |
| (ObjC)</span><div class="descr">
 | |
| Check usage of <code>NSError**</code> parameters.</div></div></td>
 | |
| <td><div class="exampleContainer expandable">
 | |
| <div class="example"><pre>
 | |
| @interface A : NSObject
 | |
| - (void)foo:(NSError **)error;
 | |
| @end
 | |
| 
 | |
| @implementation A
 | |
| - (void)foo:(NSError **)error {
 | |
|   // warn: method accepting NSError** should have a non-void
 | |
|   // return value
 | |
| }
 | |
| @end
 | |
| </pre></div>
 | |
| <div class="example"><pre>
 | |
| @interface A : NSObject
 | |
| - (BOOL)foo:(NSError **)error;
 | |
| @end
 | |
| 
 | |
| @implementation A
 | |
| - (BOOL)foo:(NSError **)error {
 | |
|   *error = 0; // warn: potential null dereference
 | |
|   return 0;
 | |
| }
 | |
| @end
 | |
| </pre></div></div></td></tr>
 | |
| 
 | |
| 
 | |
| <tr><td><div class="namedescr expandable"><span class="name">
 | |
| osx.cocoa.NilArg</span><span class="lang">
 | |
| (ObjC)</span><div class="descr">
 | |
| Check for prohibited nil arguments in specific Objective-C method calls:<div class=functions>
 | |
| - caseInsensitiveCompare:<br>
 | |
| - compare:<br>
 | |
| - compare:options:<br>
 | |
| - compare:options:range:<br>
 | |
| - compare:options:range:locale:<br>
 | |
| - componentsSeparatedByCharactersInSet:<br>
 | |
| - initWithFormat:</div></div></div></td>
 | |
| <td><div class="exampleContainer expandable">
 | |
| <div class="example"><pre>
 | |
| NSComparisonResult test(NSString *s) {
 | |
|   NSString *aString = nil;
 | |
|   return [s caseInsensitiveCompare:aString];
 | |
|     // warn: argument to 'NSString' method
 | |
|     // 'caseInsensitiveCompare:' cannot be nil
 | |
| }
 | |
| </pre></div></div></td></tr>
 | |
| 
 | |
| 
 | |
| <tr><td><div class="namedescr expandable"><span class="name">
 | |
| osx.cocoa.ObjCGenerics</span><span class="lang">
 | |
| (ObjC)</span><div class="descr">
 | |
| Check for type errors when using Objective-C generics</div></div></td>
 | |
| <td><div class="exampleContainer expandable">
 | |
| <div class="example"><pre>
 | |
| NSMutableArray<NSString *> *names = [NSMutableArray array];
 | |
| NSMutableArray *birthDates = names;
 | |
| 
 | |
| // Warning: Conversion from value of type 'NSDate *' 
 | |
| // to incompatible type 'NSString *'
 | |
| [birthDates addObject: [NSDate date]];
 | |
| </pre></div></div></td></tr>
 | |
| 
 | |
| 
 | |
| <tr><td><div class="namedescr expandable"><span class="name">
 | |
| osx.cocoa.RetainCount</span><span class="lang">
 | |
| (ObjC)</span><div class="descr">
 | |
| Check for leaks and violations of the Cocoa Memory Management rules.</div></div></td>
 | |
| <td><div class="exampleContainer expandable">
 | |
| <div class="example"><pre>
 | |
| void test() {
 | |
|   NSString *s = [[NSString alloc] init]; // warn
 | |
| }
 | |
| </pre></div>
 | |
| <div class="example"><pre>
 | |
| CFStringRef test(char *bytes) {
 | |
|   return CFStringCreateWithCStringNoCopy(
 | |
|            0, bytes, NSNEXTSTEPStringEncoding, 0); // warn
 | |
| }
 | |
| </pre></div></div></td></tr>
 | |
| 
 | |
| 
 | |
| <tr><td><div class="namedescr expandable"><span class="name">
 | |
| osx.cocoa.SelfInit</span><span class="lang">
 | |
| (ObjC)</span><div class="descr">
 | |
| Check that <code>self</code> is properly initialized inside an initializer
 | |
| method.</div></div></td>
 | |
| <td><div class="exampleContainer expandable">
 | |
| <div class="example"><pre>
 | |
| @interface MyObj : NSObject {
 | |
|   id x;
 | |
| }
 | |
| - (id)init;
 | |
| @end
 | |
| 
 | |
| @implementation MyObj
 | |
| - (id)init {
 | |
|   [super init];
 | |
|   x = 0; // warn: instance variable used while 'self' is not
 | |
|          // initialized
 | |
|   return 0;
 | |
| }
 | |
| @end
 | |
| </pre></div>
 | |
| <div class="example"><pre>
 | |
| @interface MyObj : NSObject
 | |
| - (id)init;
 | |
| @end
 | |
| 
 | |
| @implementation MyObj
 | |
| - (id)init {
 | |
|   [super init];
 | |
|   return self; // warn: returning uninitialized 'self'
 | |
| }
 | |
| @end
 | |
| </pre></div></div></td></tr>
 | |
| 
 | |
| 
 | |
| <tr><td><div class="namedescr expandable"><span class="name">
 | |
| osx.cocoa.SuperDealloc</span><span class="lang">
 | |
| (ObjC)</span><div class="descr">
 | |
| Warn about improper use of '[super dealloc]' in Objective-C</div></div></td>
 | |
| <td><div class="exampleContainer expandable">
 | |
| <div class="example"><pre>
 | |
| @interface SuperDeallocThenReleaseIvarClass : NSObject {
 | |
|   NSObject *_ivar;
 | |
| }
 | |
| @end
 | |
| 
 | |
| @implementation SuperDeallocThenReleaseIvarClass
 | |
| - (void)dealloc {
 | |
|   [super dealloc];
 | |
|   [_ivar release]; // warn
 | |
| }
 | |
| @end
 | |
| </pre></div></div></td></tr>
 | |
| 
 | |
| 
 | |
| <tr><td><div class="namedescr expandable"><span class="name">
 | |
| osx.cocoa.UnusedIvars</span><span class="lang">
 | |
| (ObjC)</span><div class="descr">
 | |
| Warn about private ivars that are never used.</div></div></td>
 | |
| <td><div class="exampleContainer expandable">
 | |
| <div class="example"><pre>
 | |
| @interface MyObj : NSObject {
 | |
| @private
 | |
|   id x; // warn
 | |
| }
 | |
| @end
 | |
| 
 | |
| @implementation MyObj
 | |
| @end
 | |
| </pre></div></div></td></tr>
 | |
| 
 | |
| 
 | |
| <tr><td><div class="namedescr expandable"><span class="name">
 | |
| osx.cocoa.VariadicMethodTypes</span><span class="lang">
 | |
| (ObjC)</span><div class="descr">
 | |
| Check for passing non-Objective-C types to variadic collection initialization
 | |
| methods that expect only Objective-C types.</div></div></td>
 | |
| <td><div class="exampleContainer expandable">
 | |
| <div class="example"><pre>
 | |
| void test() {
 | |
|   [NSSet setWithObjects:@"Foo", "Bar", nil];
 | |
|     // warn: argument should be an ObjC pointer type, not 'char *'
 | |
| }
 | |
| </pre></div></div></td></tr>
 | |
| 
 | |
| 
 | |
| <tr><td><div class="namedescr expandable"><span class="name">
 | |
| osx.coreFoundation.CFError</span><span class="lang">
 | |
| (C)</span><div class="descr">
 | |
| Check usage of <code>CFErrorRef*</code> parameters.</div></div></td>
 | |
| <td><div class="exampleContainer expandable">
 | |
| <div class="example"><pre>
 | |
| void test(CFErrorRef *error) {
 | |
|   // warn: function accepting CFErrorRef* should have a
 | |
|   // non-void return
 | |
| }
 | |
| </pre></div>
 | |
| <div class="example"><pre>
 | |
| int foo(CFErrorRef *error) {
 | |
|   *error = 0; // warn: potential null dereference
 | |
|   return 0;
 | |
| }
 | |
| </pre></div></div></td></tr>
 | |
| 
 | |
| 
 | |
| <tr><td><div class="namedescr expandable"><span class="name">
 | |
| osx.coreFoundation.CFNumber</span><span class="lang">
 | |
| (C)</span><div class="descr">
 | |
| Check for improper uses of <code>CFNumberCreate</code>.</div></div></td>
 | |
| <td><div class="exampleContainer expandable">
 | |
| <div class="example"><pre>
 | |
| CFNumberRef test(unsigned char x) {
 | |
|   return CFNumberCreate(0, kCFNumberSInt16Type, &x);
 | |
|    // warn: 8 bit integer is used to initialize a 16 bit integer
 | |
| }
 | |
| </pre></div></div></td></tr>
 | |
| 
 | |
| 
 | |
| <tr><td><div class="namedescr expandable"><span class="name">
 | |
| osx.coreFoundation.CFRetainRelease</span><span class="lang">
 | |
| (C)</span><div class="descr">
 | |
| Check for null arguments to <code>CFRetain</code>, <code>CFRelease</code>,
 | |
| <code>CFMakeCollectable</code>.</div></div></td>
 | |
| <td><div class="exampleContainer expandable">
 | |
| <div class="example"><pre>
 | |
| void test(CFTypeRef p) {
 | |
|   if (!p)
 | |
|     CFRetain(p); // warn
 | |
| }
 | |
| </pre></div>
 | |
| <div class="example"><pre>
 | |
| void test(int x, CFTypeRef p) {
 | |
|   if (p)
 | |
|     return;
 | |
| 
 | |
|   CFRelease(p); // warn
 | |
| }
 | |
| </pre></div></div></td></tr>
 | |
| 
 | |
| 
 | |
| <tr><td><div class="namedescr expandable"><span class="name">
 | |
| osx.coreFoundation.containers.OutOfBounds</span><span class="lang">
 | |
| (C)</span><div class="descr">
 | |
| Checks for index out-of-bounds when using <code>CFArray</code> API.</div></div></td>
 | |
| <td><div class="exampleContainer expandable">
 | |
| <div class="example"><pre>
 | |
| void test() {
 | |
|   CFArrayRef A = CFArrayCreate(0, 0, 0, &kCFTypeArrayCallBacks);
 | |
|   CFArrayGetValueAtIndex(A, 0); // warn
 | |
| }
 | |
| </pre></div></div></td></tr>
 | |
| 
 | |
| 
 | |
| <tr><td><div class="namedescr expandable"><span class="name">
 | |
| osx.coreFoundation.containers.PointerSizedValues</span><span class="lang">
 | |
| (C)</span><div class="descr">
 | |
| Warns if <code>CFArray</code>, <code>CFDictionary</code>, <code>CFSet</code> are
 | |
| created with non-pointer-size values.</div></div></td>
 | |
| <td><div class="exampleContainer expandable">
 | |
| <div class="example"><pre>
 | |
| void test() {
 | |
|   int x[] = { 1 };
 | |
|   CFArrayRef A = CFArrayCreate(0, (const void **)x, 1,
 | |
|                                &kCFTypeArrayCallBacks); // warn
 | |
| }
 | |
| </pre></div></div></td></tr>
 | |
| 
 | |
| </tbody></table>
 | |
| 
 | |
| <!-- =========================== security =========================== -->
 | |
| <h3 id="security_checkers">Security Checkers</h3>
 | |
| <table class="checkers">
 | |
| <colgroup><col class="namedescr"><col class="example"></colgroup>
 | |
| <thead><tr><td>Name, Description</td><td>Example</td></tr></thead>
 | |
| 
 | |
| <tbody>
 | |
| <tr><td><div class="namedescr expandable"><span class="name">
 | |
| security.FloatLoopCounter</span><span class="lang">
 | |
| (C)</span><div class="descr">
 | |
| Warn on using a floating point value as a loop counter (CERT: FLP30-C,
 | |
| FLP30-CPP).</div></div></td>
 | |
| <td><div class="exampleContainer expandable">
 | |
| <div class="example"><pre>
 | |
| void test() {
 | |
|   for (float x = 0.1f; x <= 1.0f; x += 0.1f) {} // warn
 | |
| }
 | |
| </pre></div></div></td></tr>
 | |
| 
 | |
| 
 | |
| <tr><td><div class="namedescr expandable"><span class="name">
 | |
| security.insecureAPI.UncheckedReturn</span><span class="lang">
 | |
| (C)</span><div class="descr">
 | |
| Warn on uses of functions whose return values must be always checked:<div class=functions>
 | |
| setuid<br>
 | |
| setgid<br>
 | |
| seteuid<br>
 | |
| setegid<br>
 | |
| setreuid<br>
 | |
| setregid</div></div></div></td>
 | |
| <td><div class="exampleContainer expandable">
 | |
| <div class="example"><pre>
 | |
| void test() {
 | |
|   setuid(1); // warn
 | |
| }
 | |
| </pre></div></div></td></tr>
 | |
| 
 | |
| 
 | |
| <tr><td><div class="namedescr expandable"><span class="name">
 | |
| security.insecureAPI.getpw</span><span class="lang">
 | |
| (C)</span><div class="descr">
 | |
| Warn on uses of the <code>getpw</code> function.</div></div></td>
 | |
| <td><div class="exampleContainer expandable">
 | |
| <div class="example"><pre>
 | |
| void test() {
 | |
|   char buff[1024];
 | |
|   getpw(2, buff); // warn
 | |
| }
 | |
| </pre></div></div></td></tr>
 | |
| 
 | |
| 
 | |
| <tr><td><div class="namedescr expandable"><span class="name">
 | |
| security.insecureAPI.gets</span><span class="lang">
 | |
| (C)</span><div class="descr">
 | |
| Warn on uses of the <code>gets</code> function.</div></div></td>
 | |
| <td><div class="exampleContainer expandable">
 | |
| <div class="example"><pre>
 | |
| void test() {
 | |
|   char buff[1024];
 | |
|   gets(buff); // warn
 | |
| }
 | |
| </pre></div></div></td></tr>
 | |
| 
 | |
| 
 | |
| <tr><td><div class="namedescr expandable"><span class="name">
 | |
| security.insecureAPI.mkstemp</span><span class="lang">
 | |
| (C)</span><div class="descr">
 | |
| Warn when <code>mktemp</code>, <code>mkstemp</code>, <code>mkstemps</code> or
 | |
| <code>mkdtemp</code> is passed fewer than 6
 | |
| X's in the format string.</div></div></td>
 | |
| <td><div class="exampleContainer expandable">
 | |
| <div class="example"><pre>
 | |
| void test() {
 | |
|   mkstemp("XX"); // warn
 | |
| }
 | |
| </pre></div></div></td></tr>
 | |
| 
 | |
| 
 | |
| <tr><td><div class="namedescr expandable"><span class="name">
 | |
| security.insecureAPI.mktemp</span><span class="lang">
 | |
| (C)</span><div class="descr">
 | |
| Warn on uses of the <code>mktemp</code> function.</div></div></td>
 | |
| <td><div class="exampleContainer expandable">
 | |
| <div class="example"><pre>
 | |
| void test() {
 | |
|   char *x = mktemp("/tmp/zxcv"); // warn: insecure, use mkstemp
 | |
| }
 | |
| </pre></div></div></td></tr>
 | |
| 
 | |
| 
 | |
| <tr><td><div class="namedescr expandable"><span class="name">
 | |
| security.insecureAPI.rand</span><span class="lang">
 | |
| (C)</span><div class="descr">
 | |
| Warn on uses of inferior random number generating functions (only if <code>arc4random</code>
 | |
| function is available):<div class=functions>
 | |
| drand48<br>
 | |
| erand48<br>
 | |
| jrand48<br>
 | |
| lcong48<br>
 | |
| lrand48<br>
 | |
| mrand48<br>
 | |
| nrand48<br>
 | |
| random<br>
 | |
| rand_r</div></div></div></td>
 | |
| <td><div class="exampleContainer expandable">
 | |
| <div class="example"><pre>
 | |
| void test() {
 | |
|   random(); // warn
 | |
| }
 | |
| </pre></div></div></td></tr>
 | |
| 
 | |
| 
 | |
| <tr><td><div class="namedescr expandable"><span class="name">
 | |
| security.insecureAPI.strcpy</span><span class="lang">
 | |
| (C)</span><div class="descr">
 | |
| Warn on uses of the <code>strcpy</code> and <code>strcat</code> functions.</div></div></td>
 | |
| <td><div class="exampleContainer expandable">
 | |
| <div class="example"><pre>
 | |
| void test() {
 | |
|   char x[4];
 | |
|   char *y = "abcd";
 | |
| 
 | |
|   strcpy(x, y); // warn
 | |
| }
 | |
| </pre></div></div></td></tr>
 | |
| 
 | |
| 
 | |
| <tr><td><div class="namedescr expandable"><span class="name">
 | |
| security.insecureAPI.vfork</span><span class="lang">
 | |
| (C)</span><div class="descr">
 | |
| Warn on uses of the <code>vfork</code> function.</div></div></td>
 | |
| <td><div class="exampleContainer expandable">
 | |
| <div class="example"><pre>
 | |
| void test() {
 | |
|   vfork(); // warn
 | |
| }
 | |
| </pre></div></div></td></tr>
 | |
| 
 | |
| </tbody></table>
 | |
| 
 | |
| <!-- =========================== unix =========================== -->
 | |
| <h3 id="unix_checkers">Unix Checkers</h3>
 | |
| <table class="checkers">
 | |
| <colgroup><col class="namedescr"><col class="example"></colgroup>
 | |
| <thead><tr><td>Name, Description</td><td>Example</td></tr></thead>
 | |
| 
 | |
| <tbody>
 | |
| <tr><td><div class="namedescr expandable"><span class="name">
 | |
| unix.API</span><span class="lang">
 | |
| (C)</span><div class="descr">
 | |
| Check calls to various UNIX/POSIX functions:<div class=functions>
 | |
| open<br>
 | |
| pthread_once<br>
 | |
| calloc<br>
 | |
| malloc<br>
 | |
| realloc<br>
 | |
| alloca<br>
 | |
| <td><div class="exampleContainer expandable">
 | |
| <div class="example"><pre>
 | |
| // Currently the check is performed for apple targets only.
 | |
| void test(const char *path) {
 | |
|   int fd = open(path, O_CREAT);
 | |
|     // warn: call to 'open' requires a third argument when the
 | |
|     // 'O_CREAT' flag is set
 | |
| }
 | |
| </pre></div>
 | |
| <div class="example"><pre>
 | |
| void f();
 | |
| 
 | |
| void test() {
 | |
|   pthread_once_t pred = {0x30B1BCBA, {0}};
 | |
|   pthread_once(&pred, f);
 | |
|     // warn: call to 'pthread_once' uses the local variable
 | |
| }
 | |
| </pre></div>
 | |
| <div class="example"><pre>
 | |
| void test() {
 | |
|   void *p = malloc(0); // warn: allocation size of 0 bytes
 | |
| }
 | |
| </pre></div>
 | |
| <div class="example"><pre>
 | |
| void test() {
 | |
|   void *p = calloc(0, 42); // warn: allocation size of 0 bytes
 | |
| }
 | |
| </pre></div>
 | |
| <div class="example"><pre>
 | |
| void test() {
 | |
|   void *p = malloc(1);
 | |
|   p = realloc(p, 0); // warn: allocation size of 0 bytes
 | |
| }
 | |
| </pre></div>
 | |
| <div class="example"><pre>
 | |
| void test() {
 | |
|   void *p = alloca(0); // warn: allocation size of 0 bytes
 | |
| }
 | |
| </pre></div>
 | |
| <div class="example"><pre>
 | |
| void test() {
 | |
|   void *p = valloc(0); // warn: allocation size of 0 bytes
 | |
| }
 | |
| </pre></div></div></td></tr>
 | |
| 
 | |
| 
 | |
| <tr><td><div class="namedescr expandable"><span class="name">
 | |
| unix.Malloc</span><span class="lang">
 | |
| (C)</span><div class="descr">
 | |
| Check for memory leaks, double free, and use-after-free and offset problems
 | |
| involving <code>malloc</code>.</div></div></td>
 | |
| <td><div class="exampleContainer expandable">
 | |
| <div class="example"><pre>
 | |
| void test() {
 | |
|   int *p = malloc(1);
 | |
|   free(p);
 | |
|   free(p); // warn: attempt to free released memory
 | |
| }
 | |
| </pre></div>
 | |
| <div class="example"><pre>
 | |
| void test() {
 | |
|   int *p = malloc(sizeof(int));
 | |
|   free(p);
 | |
|   *p = 1; // warn: use after free
 | |
| }
 | |
| </pre></div>
 | |
| <div class="example"><pre>
 | |
| void test() {
 | |
|   int *p = malloc(1);
 | |
|   if (p)
 | |
|     return; // warn: memory is never released
 | |
| }
 | |
| </pre></div>
 | |
| <div class="example"><pre>
 | |
| void test() {
 | |
|   int a[] = { 1 };
 | |
|   free(a); // warn: argument is not allocated by malloc
 | |
| }
 | |
| </pre></div>
 | |
| <div class="example"><pre>
 | |
| void test() {
 | |
|   int *p = malloc(sizeof(char));
 | |
|   p = p - 1;
 | |
|   free(p); // warn: argument to free() is offset by -4 bytes
 | |
| }
 | |
| </pre></div></div></td></tr>
 | |
| 
 | |
| 
 | |
| <tr><td><div class="namedescr expandable"><span class="name">
 | |
| unix.MallocSizeof</span><span class="lang">
 | |
| (C)</span><div class="descr">
 | |
| Check for dubious <code>malloc</code>, <code>calloc</code> or
 | |
| <code>realloc</code> arguments involving <code>sizeof</code>.</div></div></td>
 | |
| <td><div class="exampleContainer expandable">
 | |
| <div class="example"><pre>
 | |
| void test() {
 | |
|   long *p = malloc(sizeof(short));
 | |
|     // warn: result is converted to 'long *', which is
 | |
|     // incompatible with operand type 'short'
 | |
|   free(p);
 | |
| }
 | |
| </pre></div></div></td></tr>
 | |
| 
 | |
| 
 | |
| <tr><td><div class="namedescr expandable"><span class="name">
 | |
| unix.MismatchedDeallocator</span><span class="lang">
 | |
| (C, C++, ObjC)</span><div class="descr">
 | |
| Check for mismatched deallocators (e.g. passing a pointer allocating
 | |
| with <code>new</code> to <code>free()</code>).</div></div></td>
 | |
| <td><div class="exampleContainer expandable">
 | |
| <div class="example"><pre>
 | |
| // C, C++
 | |
| void test() {
 | |
|   int *p = (int *)malloc(sizeof(int));
 | |
|   delete p; // warn
 | |
| }
 | |
| </pre></div>
 | |
| <div class="example"><pre>
 | |
| // C, C++
 | |
| void __attribute((ownership_returns(malloc))) *user_malloc(size_t);
 | |
| 
 | |
| void test() {
 | |
|   int *p = (int *)user_malloc(sizeof(int));
 | |
|   delete p; // warn
 | |
| }
 | |
| </pre></div>
 | |
| <div class="example"><pre>
 | |
| // C, C++
 | |
| void test() {
 | |
|   int *p = new int;
 | |
|   free(p); // warn
 | |
| }
 | |
| </pre></div>
 | |
| <div class="example"><pre>
 | |
| // C, C++
 | |
| void test() {
 | |
|   int *p = new int[1];
 | |
|   realloc(p, sizeof(long)); // warn
 | |
| }
 | |
| </pre></div>
 | |
| <div class="example"><pre>
 | |
| // C, C++
 | |
| template <typename T>
 | |
| struct SimpleSmartPointer {
 | |
|   T *ptr;
 | |
| 
 | |
|   explicit SimpleSmartPointer(T *p = 0) : ptr(p) {}
 | |
|   ~SimpleSmartPointer() {
 | |
|     delete ptr; // warn
 | |
|   }
 | |
| };
 | |
| 
 | |
| void test() {
 | |
|   SimpleSmartPointer<int> a((int *)malloc(4));
 | |
| }
 | |
| </pre></div>
 | |
| <div class="example"><pre>
 | |
| // C++
 | |
| void test() {
 | |
|   int *p = (int *)operator new(0);
 | |
|   delete[] p; // warn
 | |
| }
 | |
| </pre></div>
 | |
| <div class="example"><pre>
 | |
| // Objective-C, C++
 | |
| void test(NSUInteger dataLength) {
 | |
|   int *p = new int;
 | |
|   NSData *d = [NSData dataWithBytesNoCopy:p
 | |
|                length:sizeof(int) freeWhenDone:1];
 | |
|     // warn +dataWithBytesNoCopy:length:freeWhenDone: cannot take
 | |
|     // ownership of memory allocated by 'new'
 | |
| }
 | |
| </pre></div></div></td></tr>
 | |
| 
 | |
| 
 | |
| <tr><td><div class="namedescr expandable"><span class="name">
 | |
| unix.Vfork</span><span class="lang">
 | |
| (C)</span><div class="descr">
 | |
| Check for proper usage of vfork</div></div></td>
 | |
| <td><div class="exampleContainer expandable">
 | |
| <div class="example"><pre>
 | |
| int test(int x) {
 | |
|   pid_t pid = vfork(); // warn
 | |
|   if (pid != 0)
 | |
|     return 0;
 | |
| 
 | |
|   switch (x) {
 | |
|   case 0:
 | |
|     pid = 1;
 | |
|     execl("", "", 0);
 | |
|     _exit(1);
 | |
|     break;
 | |
|   case 1:
 | |
|     x = 0; // warn: this assignment is prohibited
 | |
|     break;
 | |
|   case 2:
 | |
|     foo(); // warn: this function call is prohibited
 | |
|     break;
 | |
|   default:
 | |
|     return 0; // warn: return is prohibited
 | |
|   }
 | |
| 
 | |
|   while(1);
 | |
| }
 | |
| </pre></div></div></td></tr>
 | |
| 
 | |
| 
 | |
| <tr><td><div class="namedescr expandable"><span class="name">
 | |
| unix.cstring.BadSizeArg</span><span class="lang">
 | |
| (C)</span><div class="descr">
 | |
| Check the size argument passed to <code>strncat</code> for common erroneous
 | |
| patterns. Use <code>-Wno-strncat-size</code> compiler option to mute other
 | |
| <code>strncat</code>-related compiler warnings.
 | |
| </div></div></td>
 | |
| <td><div class="exampleContainer expandable">
 | |
| <div class="example"><pre>
 | |
| void test() {
 | |
|   char dest[3];
 | |
|   strncat(dest, "***", sizeof(dest));
 | |
|     // warn: potential buffer overflow
 | |
| }
 | |
| </pre></div></div></td></tr>
 | |
| 
 | |
| 
 | |
| <tr><td><div class="namedescr expandable"><span class="name">
 | |
| unix.cstring.NullArg</span><span class="lang">
 | |
| (C)</span><div class="descr">
 | |
| Check for null pointers being passed as arguments to C string functions:<div class=functions>
 | |
| strlen<br>
 | |
| strnlen<br>
 | |
| strcpy<br>
 | |
| strncpy<br>
 | |
| strcat<br>
 | |
| strncat<br>
 | |
| strcmp<br>
 | |
| strncmp<br>
 | |
| strcasecmp<br>
 | |
| strncasecmp</div></div></div></td>
 | |
| <td><div class="example"><pre>
 | |
| int test() {
 | |
|   return strlen(0); // warn
 | |
| }
 | |
| </pre></div></td></tr>
 | |
| 
 | |
| </tbody></table>
 | |
| 
 | |
| </div> <!-- page -->
 | |
| </div> <!-- content -->
 | |
| </body>
 | |
| </html>
 |