2009-06-09 05:21:24 +08:00
< !DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
< html >
< head >
2014-04-29 08:46:17 +08:00
< title > Available Checkers< / title >
2012-01-15 23:26:07 +08:00
< link type = "text/css" rel = "stylesheet" href = "menu.css" >
< link type = "text/css" rel = "stylesheet" href = "content.css" >
2010-02-13 05:05:44 +08:00
< script type = "text/javascript" src = "scripts/menu.js" > < / script >
2014-04-29 08:46:17 +08:00
< script type = "text/javascript" src = "scripts/expandcollapse.js" > < / script >
2012-01-15 23:26:07 +08:00
< style type = "text/css" >
tr:first-child { width:20%; }
< / style >
2009-06-09 05:21:24 +08:00
< / head >
2014-04-29 08:46:17 +08:00
< body onload = "initExpandCollapse()" >
2009-06-09 05:21:24 +08:00
2010-02-10 07:05:59 +08:00
< div id = "page" >
2009-06-09 05:21:24 +08:00
<!-- #include virtual="menu.html.incl" -->
< div id = "content" >
2014-04-29 08:46:17 +08:00
< 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 > .
2011-11-05 13:20:54 +08:00
< h3 > Writeups with examples of some of the bugs that the analyzer finds< / h3 >
2009-06-09 05:21:24 +08:00
< 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 >
2014-04-29 08:46:17 +08:00
< 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 >
2017-07-18 08:34:57 +08:00
< li > < a href = "#nullability_checkers" > Nullability Checkers< / a > < / li >
< li > < a href = "#optin_checkers" > Optin Checkers< / a > < / li >
2014-04-29 08:46:17 +08:00
< 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 >
2017-07-18 08:34:57 +08:00
<!-- =========================== core =========================== -->
2014-04-29 08:46:17 +08:00
< h3 id = "core_checkers" > Core Checkers< / h3 >
< table class = "checkers" >
< colgroup > < col class = "namedescr" > < col class = "example" > < / colgroup >
2014-05-19 23:04:55 +08:00
< thead > < tr > < td > Name, Description< / td > < td > Example< / td > < / tr > < / thead >
2014-04-29 08:46:17 +08:00
< tbody >
2018-12-21 04:20:20 +08:00
< tr > < td > < a id = "core.CallAndMessage" > < div class = "namedescr expandable" > < span class = "name" >
2014-04-29 08:46:17 +08:00
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
2018-12-21 04:20:20 +08:00
(e.g., uninitialized arguments, null function pointers).< / div > < / div > < / a > < / td >
2014-04-29 08:46:17 +08:00
< 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 >
2018-12-21 04:20:20 +08:00
< tr > < td > < a id = "core.DivideZero" > < div class = "namedescr expandable" > < span class = "name" >
2014-04-29 08:46:17 +08:00
core.DivideZero< / span > < span class = "lang" >
(C, C++, ObjC)< / span > < div class = "descr" >
2018-12-21 04:20:20 +08:00
Check for division by zero.< / div > < / div > < / a > co< / td >
2014-04-29 08:46:17 +08:00
< 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 >
2018-12-21 04:20:20 +08:00
< tr > < td > < a id = "core.NonNullParamChecker" > < div class = "namedescr expandable" > < span class = "name" >
2014-04-29 08:46:17 +08:00
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
2018-12-21 04:20:20 +08:00
marked with the < code > nonnull< / code > attribute.< / div > < / div > < / a > < / td >
2014-04-29 08:46:17 +08:00
< 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 >
2018-12-21 04:20:20 +08:00
< tr > < td > < a id = "core.NullDereference" > < div class = "namedescr expandable" > < span class = "name" >
2014-04-29 08:46:17 +08:00
core.NullDereference< / span > < span class = "lang" >
(C, C++, ObjC)< / span > < div class = "descr" >
2018-12-21 04:20:20 +08:00
Check for dereferences of null pointers.< / div > < / div > < / a > < / td >
2014-04-29 08:46:17 +08:00
< 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 >
2018-12-21 04:20:20 +08:00
< tr > < td > < a id = "core.StackAddressEscape" > < div class = "namedescr expandable" > < span class = "name" >
2014-04-29 08:46:17 +08:00
core.StackAddressEscape< / span > < span class = "lang" >
(C)< / span > < div class = "descr" >
2018-12-21 04:20:20 +08:00
Check that addresses of stack memory do not escape the function.< / div > < / div > < / a > < / td >
2014-04-29 08:46:17 +08:00
< 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 >
2018-12-21 04:20:20 +08:00
< tr > < td > < a id = "core.UndefinedBinaryOperatorResult" > < div class = "namedescr expandable" > < span class = "name" >
2014-04-29 08:46:17 +08:00
core.UndefinedBinaryOperatorResult< / span > < span class = "lang" >
(C)< / span > < div class = "descr" >
2018-12-21 04:20:20 +08:00
Check for undefined results of binary operators.< / div > < / div > < / a > < / td >
2014-04-29 08:46:17 +08:00
< 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 >
2018-12-21 04:20:20 +08:00
< tr > < td > < a id = "core.VLASize" > < div class = "namedescr expandable" > < span class = "name" >
2014-04-29 08:46:17 +08:00
core.VLASize< / span > < span class = "lang" >
(C)< / span > < div class = "descr" >
2018-12-21 04:20:20 +08:00
Check for declarations of VLA of undefined or zero size.< / div > < / div > < / a > < / td >
2014-04-29 08:46:17 +08:00
< 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 >
2018-12-21 04:20:20 +08:00
< tr > < td > < a id = "core.uninitialized.ArraySubscript" > < div class = "namedescr expandable" > < span class = "name" >
2014-04-29 08:46:17 +08:00
core.uninitialized.ArraySubscript< / span > < span class = "lang" >
(C)< / span > < div class = "descr" >
2018-12-21 04:20:20 +08:00
Check for uninitialized values used as array subscripts.< / div > < / div > < / a > < / td >
2014-04-29 08:46:17 +08:00
< 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 >
2018-12-21 04:20:20 +08:00
< tr > < td > < a id = "core.uninitialized.Assign" > < div class = "namedescr expandable" > < span class = "name" >
2014-04-29 08:46:17 +08:00
core.uninitialized.Assign< / span > < span class = "lang" >
(C)< / span > < div class = "descr" >
2018-12-21 04:20:20 +08:00
Check for assigning uninitialized values.< / div > < / div > < / a > < / td >
2014-04-29 08:46:17 +08:00
< td > < div class = "exampleContainer expandable" >
< div class = "example" > < pre >
void test() {
int x;
2018-04-06 23:14:32 +08:00
x |= 1; // warn: left expression is uninitialized
2014-04-29 08:46:17 +08:00
}
< / pre > < / div > < / div > < / td > < / tr >
2018-12-21 04:20:20 +08:00
< tr > < td > < a id = "core.uninitialized.Branch" > < div class = "namedescr expandable" > < span class = "name" >
2014-04-29 08:46:17 +08:00
core.uninitialized.Branch< / span > < span class = "lang" >
(C)< / span > < div class = "descr" >
2018-12-21 04:20:20 +08:00
Check for uninitialized values used as branch conditions.< / div > < / div > < / a > < / td >
2014-04-29 08:46:17 +08:00
< td > < div class = "exampleContainer expandable" >
< div class = "example" > < pre >
void test() {
int x;
if (x) // warn
return;
}
< / pre > < / div > < / div > < / td > < / tr >
2018-12-21 04:20:20 +08:00
< tr > < td > < a id = "core.uninitialized.CapturedBlockVariable" > < div class = "namedescr expandable" > < span class = "name" >
2014-04-29 08:46:17 +08:00
core.uninitialized.CapturedBlockVariable< / span > < span class = "lang" >
(C)< / span > < div class = "descr" >
2018-12-21 04:20:20 +08:00
Check for blocks that capture uninitialized values.< / div > < / div > < / a > < / td >
2014-04-29 08:46:17 +08:00
< td > < div class = "exampleContainer expandable" >
< div class = "example" > < pre >
void test() {
int x;
^{ int y = x; }(); // warn
}
< / pre > < / div > < / div > < / td > < / tr >
2018-12-21 04:20:20 +08:00
< tr > < td > < a id = "core.uninitialized.UndefReturn" > < div class = "namedescr expandable" > < span class = "name" >
2014-04-29 08:46:17 +08:00
core.uninitialized.UndefReturn< / span > < span class = "lang" >
(C)< / span > < div class = "descr" >
2018-12-21 04:20:20 +08:00
Check for uninitialized values being returned to the caller.< / div > < / div > < / a > < / td >
2014-04-29 08:46:17 +08:00
< td > < div class = "exampleContainer expandable" >
< div class = "example" > < pre >
int test() {
int x;
return x; // warn
}
< / pre > < / div > < / div > < / td > < / tr >
< / tbody > < / table >
2017-07-18 08:34:57 +08:00
<!-- =========================== C++ =========================== -->
2014-04-29 08:46:17 +08:00
< h3 id = "cplusplus_checkers" > C++ Checkers< / h3 >
< table class = "checkers" >
< colgroup > < col class = "namedescr" > < col class = "example" > < / colgroup >
2014-05-19 23:04:55 +08:00
< thead > < tr > < td > Name, Description< / td > < td > Example< / td > < / tr > < / thead >
2014-04-29 08:46:17 +08:00
< tbody >
2018-12-21 04:20:20 +08:00
< tr > < td > < a id = "cplusplus.NewDelete" > < div class = "namedescr expandable" > < span class = "name" >
2014-04-29 08:46:17 +08:00
cplusplus.NewDelete< / span > < span class = "lang" >
(C++)< / span > < div class = "descr" >
Check for double-free, use-after-free and offset problems involving C++ < code >
2018-12-21 04:20:20 +08:00
delete< / code > .< / div > < / div > < / a > < / td >
2014-04-29 08:46:17 +08:00
< 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 >
2018-12-21 04:20:20 +08:00
< tr > < td > < a id = "cplusplus.NewDeleteLeaks" > < div class = "namedescr expandable" > < span class = "name" >
2017-07-18 08:34:57 +08:00
cplusplus.NewDeleteLeaks< / span > < span class = "lang" >
(C++)< / span > < div class = "descr" >
Check for memory leaks. Traces memory managed by < code > new< / code > /< code >
2018-12-21 04:20:20 +08:00
delete< / code > .< / div > < / div > < / a > < / td >
2017-07-18 08:34:57 +08:00
< td > < div class = "exampleContainer expandable" >
< div class = "example" > < pre >
void test() {
int *p = new int;
} // warn
< / pre > < / div > < / div > < / td > < / tr >
2014-04-29 08:46:17 +08:00
< / tbody > < / table >
2017-07-18 08:34:57 +08:00
<!-- =========================== dead code =========================== -->
2014-04-29 08:46:17 +08:00
< h3 id = "deadcode_checkers" > Dead Code Checkers< / h3 >
< table class = "checkers" >
< colgroup > < col class = "namedescr" > < col class = "example" > < / colgroup >
2014-05-19 23:04:55 +08:00
< thead > < tr > < td > Name, Description< / td > < td > Example< / td > < / tr > < / thead >
2014-04-29 08:46:17 +08:00
< tbody >
2018-12-21 04:20:20 +08:00
< tr > < td > < a id = "deadcode.DeadStores" > < div class = "namedescr expandable" > < span class = "name" >
2014-04-29 08:46:17 +08:00
deadcode.DeadStores< / span > < span class = "lang" >
(C)< / span > < div class = "descr" >
2018-12-21 04:20:20 +08:00
Check for values stored to variables that are never read afterwards.< / div > < / div > < / a > < / td >
2014-04-29 08:46:17 +08:00
< td > < div class = "exampleContainer expandable" >
< div class = "example" > < pre >
void test() {
int x;
x = 1; // warn
}
< / pre > < / div > < / div > < / td > < / tr >
< / tbody > < / table >
2017-07-18 08:34:57 +08:00
<!-- =========================== 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 >
2018-12-21 04:20:20 +08:00
< tr > < td > < a id = "nullability.NullPassedToNonnull" > < div class = "namedescr expandable" > < span class = "name" >
2017-07-18 08:34:57 +08:00
nullability.NullPassedToNonnull< / span > < span class = "lang" >
(ObjC)< / span > < div class = "descr" >
2018-12-21 04:20:20 +08:00
Warns when a null pointer is passed to a pointer which has a
_Nonnull type.< / div > < / div > < / a > < / td >
2017-07-18 08:34:57 +08:00
< 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 >
2018-12-21 04:20:20 +08:00
< tr > < td > < a id = "nullability.NullReturnedFromNonnull" > < div class = "namedescr expandable" > < span class = "name" >
2017-07-18 08:34:57 +08:00
nullability.NullReturnedFromNonnull< / span > < span class = "lang" >
(ObjC)< / span > < div class = "descr" >
2018-12-21 04:20:20 +08:00
Warns when a null pointer is returned from a function that has
_Nonnull return type.< / div > < / div > < / a > < / td >
2017-07-18 08:34:57 +08:00
< td > < div class = "exampleContainer expandable" >
< div class = "example" > < pre >
- (nonnull id)firstChild {
id result = nil;
if ([_children count] > 0)
result = _children[0];
2018-12-21 04:20:20 +08:00
// Warning: nil returned from a method that is expected
2017-07-18 08:34:57 +08:00
// to return a non-null value
return result;
}
< / pre > < / div > < / div > < / td > < / tr >
2018-12-21 04:20:20 +08:00
< tr > < td > < a id = "nullability.NullableDereferenced" > < div class = "namedescr expandable" > < span class = "name" >
2017-07-18 08:34:57 +08:00
nullability.NullableDereferenced< / span > < span class = "lang" >
(ObjC)< / span > < div class = "descr" >
2018-12-21 04:20:20 +08:00
Warns when a nullable pointer is dereferenced.< / div > < / div > < / a > < / td >
2017-07-18 08:34:57 +08:00
< 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 >
2018-12-21 04:20:20 +08:00
< tr > < td > < a id = "nullability.NullablePassedToNonnull" > < div class = "namedescr expandable" > < span class = "name" >
2017-07-18 08:34:57 +08:00
nullability.NullablePassedToNonnull< / span > < span class = "lang" >
(ObjC)< / span > < div class = "descr" >
2018-12-21 04:20:20 +08:00
Warns when a nullable pointer is passed to a pointer which has a _Nonnull type.< / div > < / div > < / a > < / td >
2017-07-18 08:34:57 +08:00
< 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 >
2018-10-22 06:10:15 +08:00
2017-07-18 08:34:57 +08:00
< tbody >
2018-12-21 04:20:20 +08:00
< tr > < td > < a id = "optin.cplusplus.VirtualCall" > < div class = "namedescr expandable" > < span class = "name" >
2018-10-22 06:10:15 +08:00
optin.cplusplus.VirtualCall< / span > < span class = "lang" >
(C++)< / span > < div class = "descr" >
2018-12-21 04:20:20 +08:00
Check virtual member function calls during construction or
destruction.< / div > < / div > < / a > < / td >
2018-10-22 06:10:15 +08:00
< td > < div class = "exampleContainer expandable" >
< div class = "example" > < pre >
class A {
public:
2018-12-21 04:20:20 +08:00
A() {
2018-10-22 06:10:15 +08:00
f(); // warn
}
virtual void f();
};
< / pre > < / div > < div class = "separator" > < / div >
< div class = "example" > < pre >
class A {
public:
~A() {
this-> f(); // warn
}
virtual void f();
};
< / pre > < / div > < / div > < / td > < / tr >
2018-12-21 04:20:20 +08:00
< tr > < td > < a id = "optin.mpi.MPI-Checker" > < div class = "namedescr expandable" > < span class = "name" >
2017-07-18 08:34:57 +08:00
optin.mpi.MPI-Checker< / span > < span class = "lang" >
(C)< / span > < div class = "descr" >
2018-12-21 04:20:20 +08:00
Checks MPI code< / div > < / div > < / a > < / td >
2017-07-18 08:34:57 +08:00
< td > < div class = "exampleContainer expandable" >
< div class = "example" > < pre >
void test() {
double buf = 0;
MPI_Request sendReq1;
2018-12-21 04:20:20 +08:00
MPI_Ireduce(MPI_IN_PLACE, & buf, 1, MPI_DOUBLE, MPI_SUM,
2017-07-18 08:34:57 +08:00
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 >
2018-12-21 04:20:20 +08:00
< tr > < td > < a id = "optin.osx.cocoa.localizability.EmptyLocalizationContextChecker" > < div class = "namedescr expandable" > < span class = "name" >
2017-07-18 08:34:57 +08:00
optin.osx.cocoa.localizability.EmptyLocalizationContextChecker< / span > < span class = "lang" >
(ObjC)< / span > < div class = "descr" >
2018-12-21 04:20:20 +08:00
Check that NSLocalizedString macros include a comment for context.< / div > < / div > < / a > < / td >
2017-07-18 08:34:57 +08:00
< 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 >
2018-12-21 04:20:20 +08:00
< tr > < td > < a id = "optin.osx.cocoa.localizability.NonLocalizedStringChecker" > < div class = "namedescr expandable" > < span class = "name" >
2017-07-18 08:34:57 +08:00
optin.osx.cocoa.localizability.NonLocalizedStringChecker< / span > < span class = "lang" >
(ObjC)< / span > < div class = "descr" >
2018-12-21 04:20:20 +08:00
Warns about uses of non-localized NSStrings passed to UI methods
expecting localized NSStrings< / div > < / div > < / a > < / td >
2017-07-18 08:34:57 +08:00
< td > < div class = "exampleContainer expandable" >
< div class = "example" > < pre >
2018-12-21 04:20:20 +08:00
NSString *alarmText =
2017-07-18 08:34:57 +08:00
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 =========================== -->
2014-04-29 08:46:17 +08:00
< h3 id = "osx_checkers" > OS X Checkers< / h3 >
< table class = "checkers" >
< colgroup > < col class = "namedescr" > < col class = "example" > < / colgroup >
2014-05-19 23:04:55 +08:00
< thead > < tr > < td > Name, Description< / td > < td > Example< / td > < / tr > < / thead >
2014-04-29 08:46:17 +08:00
< tbody >
2018-12-21 04:20:20 +08:00
< tr > < td > < a id = "osx.API" > < div class = "namedescr expandable" > < span class = "name" >
2014-04-29 08:46:17 +08:00
osx.API< / span > < span class = "lang" >
(C)< / span > < div class = "descr" >
Check for proper uses of various Apple APIs:< div class = functions >
2018-12-21 04:20:20 +08:00
dispatch_once< / div > < / div > < / div > < / a > < / td >
2014-04-29 08:46:17 +08:00
< 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 >
2018-12-21 04:20:20 +08:00
< tr > < td > < a id = "osx.NumberObjectConversion" > < div class = "namedescr expandable" > < span class = "name" >
2017-07-18 08:34:57 +08:00
osx.NumberObjectConversion< / span > < span class = "lang" >
(C, C++, ObjC)< / span > < div class = "descr" >
2018-12-21 04:20:20 +08:00
Check for erroneous conversions of objects representing numbers
into numbers< / div > < / div > < / a > < / td >
2017-07-18 08:34:57 +08:00
< td > < div class = "exampleContainer expandable" >
< div class = "example" > < pre >
NSNumber *photoCount = [albumDescriptor objectForKey:@"PhotoCount"];
2018-12-21 04:20:20 +08:00
// Warning: Comparing a pointer value of type 'NSNumber *'
2017-07-18 08:34:57 +08:00
// to a scalar integer value
if (photoCount > 0) {
[self displayPhotos];
}
< / pre > < / div > < / div > < / td > < / tr >
2018-12-21 04:20:20 +08:00
< tr > < td > < a id = "osx.SecKeychainAPI" > < div class = "namedescr expandable" > < span class = "name" >
2014-04-29 08:46:17 +08:00
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 >
2018-12-21 04:20:20 +08:00
SecKeychainItemFreeAttributesAndData< / div > < / div > < / div > < / a > < / td >
2014-04-29 08:46:17 +08:00
< 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 >
2018-12-21 04:20:20 +08:00
< tr > < td > < a id = "osx.cocoa.AtSync" > < div class = "namedescr expandable" > < span class = "name" >
2014-04-29 08:46:17 +08:00
osx.cocoa.AtSync< / span > < span class = "lang" >
(ObjC)< / span > < div class = "descr" >
2018-12-21 04:20:20 +08:00
Check for nil pointers used as mutexes for < code > @synchronized< / code > .< / div > < / div > < / a > < / td >
2014-04-29 08:46:17 +08:00
< 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 >
2018-12-21 04:20:20 +08:00
< tr > < td > < a id = "osx.cocoa.ClassRelease" > < div class = "namedescr expandable" > < span class = "name" >
2014-04-29 08:46:17 +08:00
osx.cocoa.ClassRelease< / span > < span class = "lang" >
(ObjC)< / span > < div class = "descr" >
Check for sending < code > retain< / code > , < code > release< / code > , or < code >
2018-12-21 04:20:20 +08:00
autorelease< / code > directly to a class.< / div > < / div > < / a > < / td >
2014-04-29 08:46:17 +08:00
< td > < div class = "exampleContainer expandable" >
< div class = "example" > < pre >
@interface MyClass : NSObject
@end
void test(void) {
[MyClass release]; // warn
}
< / pre > < / div > < / div > < / td > < / tr >
2018-12-21 04:20:20 +08:00
< tr > < td > < a id = "osx.cocoa.Dealloc" > < div class = "namedescr expandable" > < span class = "name" >
2017-07-18 08:34:57 +08:00
osx.cocoa.Dealloc< / span > < span class = "lang" >
(ObjC)< / span > < div class = "descr" >
2018-12-21 04:20:20 +08:00
Warn about Objective-C classes that lack a correct implementation
2017-07-18 08:34:57 +08:00
of < code > -dealloc< / code > .
2018-12-21 04:20:20 +08:00
< / div > < / div > < / a > < / td >
2017-07-18 08:34:57 +08:00
< td > < div class = "exampleContainer expandable" >
< div class = "example" > < pre >
@interface MyObject : NSObject {
2018-12-21 04:20:20 +08:00
id _myproperty;
2017-07-18 08:34:57 +08:00
}
@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 >
2018-12-21 04:20:20 +08:00
< tr > < td > < a id = "osx.cocoa.IncompatibleMethodTypes" > < div class = "namedescr expandable" > < span class = "name" >
2014-04-29 08:46:17 +08:00
osx.cocoa.IncompatibleMethodTypes< / span > < span class = "lang" >
(ObjC)< / span > < div class = "descr" >
2018-12-21 04:20:20 +08:00
Check for an incompatible type signature when overriding an Objective-C method.< / div > < / div > < / a > < / td >
2014-04-29 08:46:17 +08:00
< td > < div class = "exampleContainer expandable" >
< div class = "example" > < pre >
@interface MyClass1 : NSObject
- (int)foo;
@end
2009-06-09 05:21:24 +08:00
2014-04-29 08:46:17 +08:00
@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 >
2018-12-21 04:20:20 +08:00
< tr > < td > < a id = "osx.cocoa.MissingSuperCall" > < div class = "namedescr expandable" > < span class = "name" >
osx.cocoa.MissingSuperCall< / span > < span class = "lang" >
2014-04-29 08:46:17 +08:00
(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
2018-12-21 04:20:20 +08:00
that haven't yet adopted this attribute.)< / div > < / div > < / a > < / td >
2014-04-29 08:46:17 +08:00
< td > < div class = "example" > < pre >
@interface Test : UIViewController
@end
@implementation test
- (void)viewDidLoad {} // warn
@end
< / pre > < / div > < / td > < / tr >
2018-12-21 04:20:20 +08:00
< tr > < td > < a id = "osx.cocoa.NSAutoreleasePool" > < div class = "namedescr expandable" > < span class = "name" >
2014-04-29 08:46:17 +08:00
osx.cocoa.NSAutoreleasePool< / span > < span class = "lang" >
(ObjC)< / span > < div class = "descr" >
Warn for suboptimal uses of NSAutoreleasePool in Objective-C
2018-12-21 04:20:20 +08:00
GC mode (< code > -fobjc-gc< / code > compiler option).< / div > < / div > < / a > < / td >
2014-04-29 08:46:17 +08:00
< td > < div class = "exampleContainer expandable" >
< div class = "example" > < pre >
void test() {
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
[pool release]; // warn
}
< / pre > < / div > < / div > < / td > < / tr >
2018-12-21 04:20:20 +08:00
< tr > < td > < a id = "osx.cocoa.NSError" > < div class = "namedescr expandable" > < span class = "name" >
2014-04-29 08:46:17 +08:00
osx.cocoa.NSError< / span > < span class = "lang" >
(ObjC)< / span > < div class = "descr" >
2018-12-21 04:20:20 +08:00
Check usage of < code > NSError**< / code > parameters.< / div > < / div > < / a > < / td >
2014-04-29 08:46:17 +08:00
< 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 >
2018-12-21 04:20:20 +08:00
< tr > < td > < a id = "osx.cocoa.NilArg" > < div class = "namedescr expandable" > < span class = "name" >
2014-04-29 08:46:17 +08:00
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 >
2018-12-21 04:20:20 +08:00
- initWithFormat:< / div > < / div > < / div > < / a > < / td >
2014-04-29 08:46:17 +08:00
< 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 >
2018-12-21 04:20:20 +08:00
< tr > < td > < a id = "osx.cocoa.ObjCGenerics" > < div class = "namedescr expandable" > < span class = "name" >
2017-07-18 08:34:57 +08:00
osx.cocoa.ObjCGenerics< / span > < span class = "lang" >
(ObjC)< / span > < div class = "descr" >
2018-12-21 04:20:20 +08:00
Check for type errors when using Objective-C generics< / div > < / div > < / a > < / td >
2017-07-18 08:34:57 +08:00
< td > < div class = "exampleContainer expandable" >
< div class = "example" > < pre >
NSMutableArray< NSString * > *names = [NSMutableArray array];
NSMutableArray *birthDates = names;
2018-12-21 04:20:20 +08:00
// Warning: Conversion from value of type 'NSDate *'
2017-07-18 08:34:57 +08:00
// to incompatible type 'NSString *'
[birthDates addObject: [NSDate date]];
< / pre > < / div > < / div > < / td > < / tr >
2018-12-21 04:20:20 +08:00
< tr > < td > < a id = "osx.cocoa.RetainCount" > < div class = "namedescr expandable" > < span class = "name" >
2014-04-29 08:46:17 +08:00
osx.cocoa.RetainCount< / span > < span class = "lang" >
(ObjC)< / span > < div class = "descr" >
2018-12-21 04:20:20 +08:00
Check for leaks and violations of the Cocoa Memory Management rules.< / div > < / div > < / a > < / td >
2014-04-29 08:46:17 +08:00
< 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 >
2018-12-21 04:20:20 +08:00
< tr > < td > < a id = "osx.cocoa.SelfInit" > < div class = "namedescr expandable" > < span class = "name" >
2014-04-29 08:46:17 +08:00
osx.cocoa.SelfInit< / span > < span class = "lang" >
(ObjC)< / span > < div class = "descr" >
Check that < code > self< / code > is properly initialized inside an initializer
2018-12-21 04:20:20 +08:00
method.< / div > < / div > < / a > < / td >
2014-04-29 08:46:17 +08:00
< 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 >
2018-12-21 04:20:20 +08:00
< tr > < td > < a id = "osx.cocoa.SuperDealloc" > < div class = "namedescr expandable" > < span class = "name" >
2017-07-18 08:34:57 +08:00
osx.cocoa.SuperDealloc< / span > < span class = "lang" >
(ObjC)< / span > < div class = "descr" >
2018-12-21 04:20:20 +08:00
Warn about improper use of '[super dealloc]' in Objective-C< / div > < / div > < / a > < / td >
2017-07-18 08:34:57 +08:00
< 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 >
2018-12-21 04:20:20 +08:00
< tr > < td > < a id = "osx.cocoa.UnusedIvars" > < div class = "namedescr expandable" > < span class = "name" >
2014-04-29 08:46:17 +08:00
osx.cocoa.UnusedIvars< / span > < span class = "lang" >
(ObjC)< / span > < div class = "descr" >
2018-12-21 04:20:20 +08:00
Warn about private ivars that are never used.< / div > < / div > < / a > < / td >
2014-04-29 08:46:17 +08:00
< 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 >
2018-12-21 04:20:20 +08:00
< tr > < td > < a id = "osx.cocoa.VariadicMethodTypes" > < div class = "namedescr expandable" > < span class = "name" >
2014-04-29 08:46:17 +08:00
osx.cocoa.VariadicMethodTypes< / span > < span class = "lang" >
(ObjC)< / span > < div class = "descr" >
Check for passing non-Objective-C types to variadic collection initialization
2018-12-21 04:20:20 +08:00
methods that expect only Objective-C types.< / div > < / div > < / a > < / td >
2014-04-29 08:46:17 +08:00
< 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 >
2018-12-21 04:20:20 +08:00
< tr > < td > < a id = "osx.coreFoundation.CFError" > < div class = "namedescr expandable" > < span class = "name" >
2014-04-29 08:46:17 +08:00
osx.coreFoundation.CFError< / span > < span class = "lang" >
(C)< / span > < div class = "descr" >
2018-12-21 04:20:20 +08:00
Check usage of < code > CFErrorRef*< / code > parameters.< / div > < / div > < / a > < / td >
2014-04-29 08:46:17 +08:00
< 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 >
2018-12-21 04:20:20 +08:00
< tr > < td > < a id = "osx.coreFoundation.CFNumber" > < div class = "namedescr expandable" > < span class = "name" >
2014-04-29 08:46:17 +08:00
osx.coreFoundation.CFNumber< / span > < span class = "lang" >
(C)< / span > < div class = "descr" >
2018-12-21 04:20:20 +08:00
Check for improper uses of < code > CFNumberCreate< / code > .< / div > < / div > < / a > < / td >
2014-04-29 08:46:17 +08:00
< 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 >
2018-12-21 04:20:20 +08:00
< tr > < td > < a id = "osx.coreFoundation.CFRetainRelease" > < div class = "namedescr expandable" > < span class = "name" >
2014-04-29 08:46:17 +08:00
osx.coreFoundation.CFRetainRelease< / span > < span class = "lang" >
(C)< / span > < div class = "descr" >
Check for null arguments to < code > CFRetain< / code > , < code > CFRelease< / code > ,
2018-12-21 04:20:20 +08:00
< code > CFMakeCollectable< / code > .< / div > < / div > < / a > < / td >
2014-04-29 08:46:17 +08:00
< 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 >
2018-12-21 04:20:20 +08:00
< tr > < td > < a id = "osx.coreFoundation.containers.OutOfBounds" > < div class = "namedescr expandable" > < span class = "name" >
2014-04-29 08:46:17 +08:00
osx.coreFoundation.containers.OutOfBounds< / span > < span class = "lang" >
(C)< / span > < div class = "descr" >
2018-12-21 04:20:20 +08:00
Checks for index out-of-bounds when using < code > CFArray< / code > API.< / div > < / div > < / a > < / td >
2014-04-29 08:46:17 +08:00
< 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 >
2018-12-21 04:20:20 +08:00
< tr > < td > < a id = "osx.coreFoundation.containers.PointerSizedValues" > < div class = "namedescr expandable" > < span class = "name" >
2014-04-29 08:46:17 +08:00
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
2018-12-21 04:20:20 +08:00
created with non-pointer-size values.< / div > < / div > < / a > < / td >
2014-04-29 08:46:17 +08:00
< 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 >
2017-07-18 08:34:57 +08:00
<!-- =========================== security =========================== -->
2014-04-29 08:46:17 +08:00
< h3 id = "security_checkers" > Security Checkers< / h3 >
< table class = "checkers" >
< colgroup > < col class = "namedescr" > < col class = "example" > < / colgroup >
2014-05-19 23:04:55 +08:00
< thead > < tr > < td > Name, Description< / td > < td > Example< / td > < / tr > < / thead >
2014-04-29 08:46:17 +08:00
< tbody >
2018-12-21 04:20:20 +08:00
< tr > < td > < a id = "security.FloatLoopCounter" > < div class = "namedescr expandable" > < span class = "name" >
2014-04-29 08:46:17 +08:00
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,
2018-12-21 04:20:20 +08:00
FLP30-CPP).< / div > < / div > < / a > < / td >
2014-04-29 08:46:17 +08:00
< 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 >
2018-12-21 04:20:20 +08:00
< tr > < td > < a id = "security.insecureAPI.UncheckedReturn" > < div class = "namedescr expandable" > < span class = "name" >
2014-04-29 08:46:17 +08:00
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 >
2018-12-21 04:20:20 +08:00
setregid< / div > < / div > < / div > < / a > < / td >
2014-04-29 08:46:17 +08:00
< td > < div class = "exampleContainer expandable" >
< div class = "example" > < pre >
void test() {
setuid(1); // warn
}
< / pre > < / div > < / div > < / td > < / tr >
2018-12-21 04:20:20 +08:00
< tr > < td > < a id = "security.insecureAPI.bcmp" > < div class = "namedescr expandable" > < span class = "name" >
2018-05-26 08:04:26 +08:00
security.insecureAPI.bcmp< / span > < span class = "lang" >
(C)< / span > < div class = "descr" >
2018-12-21 04:20:20 +08:00
Warn on uses of the < code > bcmp< / code > function.< / div > < / div > < / a > < / td >
2018-05-26 08:04:26 +08:00
< td > < div class = "exampleContainer expandable" >
< div class = "example" > < pre >
void test() {
bcmp(ptr0, ptr1, n); // warn
}
< / pre > < / div > < / div > < / td > < / tr >
2018-12-21 04:20:20 +08:00
< tr > < td > < a id = "security.insecureAPI.bcopy" > < div class = "namedescr expandable" > < span class = "name" >
2018-05-26 08:04:26 +08:00
security.insecureAPI.bcopy< / span > < span class = "lang" >
(C)< / span > < div class = "descr" >
2018-12-21 04:20:20 +08:00
Warn on uses of the < code > bcopy< / code > function.< / div > < / div > < / a > < / td >
2018-05-26 08:04:26 +08:00
< td > < div class = "exampleContainer expandable" >
< div class = "example" > < pre >
void test() {
bcopy(src, dst, n); // warn
}
< / pre > < / div > < / div > < / td > < / tr >
2018-12-21 04:20:20 +08:00
< tr > < td > < a id = "security.insecureAPI.bzero" > < div class = "namedescr expandable" > < span class = "name" >
2018-05-26 08:04:26 +08:00
security.insecureAPI.bzero< / span > < span class = "lang" >
(C)< / span > < div class = "descr" >
2018-12-21 04:20:20 +08:00
Warn on uses of the < code > bzero< / code > function.< / div > < / div > < / a > < / td >
2018-05-26 08:04:26 +08:00
< td > < div class = "exampleContainer expandable" >
< div class = "example" > < pre >
void test() {
bzero(ptr, n); // warn
}
< / pre > < / div > < / div > < / td > < / tr >
2018-12-21 04:20:20 +08:00
< tr > < td > < a id = "security.insecureAPI.getpw" > < div class = "namedescr expandable" > < span class = "name" >
2014-04-29 08:46:17 +08:00
security.insecureAPI.getpw< / span > < span class = "lang" >
(C)< / span > < div class = "descr" >
2018-12-21 04:20:20 +08:00
Warn on uses of the < code > getpw< / code > function.< / div > < / div > < / a > < / td >
2014-04-29 08:46:17 +08:00
< td > < div class = "exampleContainer expandable" >
< div class = "example" > < pre >
void test() {
char buff[1024];
getpw(2, buff); // warn
}
< / pre > < / div > < / div > < / td > < / tr >
2018-12-21 04:20:20 +08:00
< tr > < td > < a id = "security.insecureAPI.gets" > < div class = "namedescr expandable" > < span class = "name" >
2014-04-29 08:46:17 +08:00
security.insecureAPI.gets< / span > < span class = "lang" >
(C)< / span > < div class = "descr" >
2018-12-21 04:20:20 +08:00
Warn on uses of the < code > gets< / code > function.< / div > < / div > < / a > < / td >
2014-04-29 08:46:17 +08:00
< td > < div class = "exampleContainer expandable" >
< div class = "example" > < pre >
void test() {
char buff[1024];
gets(buff); // warn
}
< / pre > < / div > < / div > < / td > < / tr >
2018-12-21 04:20:20 +08:00
< tr > < td > < a id = "security.insecureAPI.mkstemp" > < div class = "namedescr expandable" > < span class = "name" >
2014-04-29 08:46:17 +08:00
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
2018-12-21 04:20:20 +08:00
X's in the format string.< / div > < / div > < / a > < / td >
2014-04-29 08:46:17 +08:00
< td > < div class = "exampleContainer expandable" >
< div class = "example" > < pre >
void test() {
mkstemp("XX"); // warn
}
< / pre > < / div > < / div > < / td > < / tr >
2018-12-21 04:20:20 +08:00
< tr > < td > < a id = "security.insecureAPI.mktemp" > < div class = "namedescr expandable" > < span class = "name" >
2014-04-29 08:46:17 +08:00
security.insecureAPI.mktemp< / span > < span class = "lang" >
(C)< / span > < div class = "descr" >
2018-12-21 04:20:20 +08:00
Warn on uses of the < code > mktemp< / code > function.< / div > < / div > < / a > < / td >
2014-04-29 08:46:17 +08:00
< 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 >
2018-12-21 04:20:20 +08:00
< tr > < td > < a id = "security.insecureAPI.rand" > < div class = "namedescr expandable" > < span class = "name" >
2014-04-29 08:46:17 +08:00
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 >
2018-12-21 04:20:20 +08:00
rand_r< / div > < / div > < / div > < / a > < / td >
2014-04-29 08:46:17 +08:00
< td > < div class = "exampleContainer expandable" >
< div class = "example" > < pre >
void test() {
random(); // warn
}
< / pre > < / div > < / div > < / td > < / tr >
2018-12-21 04:20:20 +08:00
< tr > < td > < a id = "security.insecureAPI.strcpy" > < div class = "namedescr expandable" > < span class = "name" >
2014-04-29 08:46:17 +08:00
security.insecureAPI.strcpy< / span > < span class = "lang" >
(C)< / span > < div class = "descr" >
2018-12-21 04:20:20 +08:00
Warn on uses of the < code > strcpy< / code > and < code > strcat< / code > functions.< / div > < / div > < / a > < / td >
2014-04-29 08:46:17 +08:00
< 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 >
2018-12-21 04:20:20 +08:00
< tr > < td > < a id = "security.insecureAPI.vfork" > < div class = "namedescr expandable" > < span class = "name" >
2014-04-29 08:46:17 +08:00
security.insecureAPI.vfork< / span > < span class = "lang" >
(C)< / span > < div class = "descr" >
2018-12-21 04:20:20 +08:00
Warn on uses of the < code > vfork< / code > function.< / div > < / div > < / a > < / td >
2014-04-29 08:46:17 +08:00
< td > < div class = "exampleContainer expandable" >
< div class = "example" > < pre >
void test() {
vfork(); // warn
}
< / pre > < / div > < / div > < / td > < / tr >
< / tbody > < / table >
2017-07-18 08:34:57 +08:00
<!-- =========================== unix =========================== -->
2014-04-29 08:46:17 +08:00
< h3 id = "unix_checkers" > Unix Checkers< / h3 >
< table class = "checkers" >
< colgroup > < col class = "namedescr" > < col class = "example" > < / colgroup >
2014-05-19 23:04:55 +08:00
< thead > < tr > < td > Name, Description< / td > < td > Example< / td > < / tr > < / thead >
2014-04-29 08:46:17 +08:00
< tbody >
2018-12-21 04:20:20 +08:00
< tr > < td > < a id = "unix.API" > < div class = "namedescr expandable" > < span class = "name" >
2014-04-29 08:46:17 +08:00
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 >
2018-12-21 04:20:20 +08:00
alloca< br > < / a > < / td >
2014-04-29 08:46:17 +08:00
< 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 >
2018-12-21 04:20:20 +08:00
< tr > < td > < a id = "unix.Malloc" > < div class = "namedescr expandable" > < span class = "name" >
2014-04-29 08:46:17 +08:00
unix.Malloc< / span > < span class = "lang" >
(C)< / span > < div class = "descr" >
Check for memory leaks, double free, and use-after-free and offset problems
2018-12-21 04:20:20 +08:00
involving < code > malloc< / code > .< / div > < / div > < / a > < / td >
2014-04-29 08:46:17 +08:00
< 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 >
2018-12-21 04:20:20 +08:00
< tr > < td > < a id = "unix.MallocSizeof" > < div class = "namedescr expandable" > < span class = "name" >
2014-04-29 08:46:17 +08:00
unix.MallocSizeof< / span > < span class = "lang" >
(C)< / span > < div class = "descr" >
Check for dubious < code > malloc< / code > , < code > calloc< / code > or
2018-12-21 04:20:20 +08:00
< code > realloc< / code > arguments involving < code > sizeof< / code > .< / div > < / div > < / a > < / td >
2014-04-29 08:46:17 +08:00
< 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 >
2018-12-21 04:20:20 +08:00
< tr > < td > < a id = "unix.MismatchedDeallocator" > < div class = "namedescr expandable" > < span class = "name" >
2014-04-29 08:46:17 +08:00
unix.MismatchedDeallocator< / span > < span class = "lang" >
(C, C++, ObjC)< / span > < div class = "descr" >
Check for mismatched deallocators (e.g. passing a pointer allocating
2018-12-21 04:20:20 +08:00
with < code > new< / code > to < code > free()< / code > ).< / div > < / div > < / a > < / td >
2014-04-29 08:46:17 +08:00
< 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 >
2018-12-21 04:20:20 +08:00
< tr > < td > < a id = "unix.Vfork" > < div class = "namedescr expandable" > < span class = "name" >
2017-07-18 08:34:57 +08:00
unix.Vfork< / span > < span class = "lang" >
(C)< / span > < div class = "descr" >
2018-12-21 04:20:20 +08:00
Check for proper usage of vfork< / div > < / div > < / a > < / td >
2017-07-18 08:34:57 +08:00
< 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 >
2018-12-21 04:20:20 +08:00
< tr > < td > < a id = "unix.cstring.BadSizeArg" > < div class = "namedescr expandable" > < span class = "name" >
2014-04-29 08:46:17 +08:00
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.
2018-12-21 04:20:20 +08:00
< / div > < / div > < / a > < / td >
2014-04-29 08:46:17 +08:00
< 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 >
2018-12-21 04:20:20 +08:00
< tr > < td > < a id = "unix.cstring.NullArg" > < div class = "namedescr expandable" > < span class = "name" >
2014-04-29 08:46:17 +08:00
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 >
2018-12-21 04:20:20 +08:00
strncasecmp< / div > < / div > < / div > < / a > < / td >
2014-04-29 08:46:17 +08:00
< td > < div class = "example" > < pre >
int test() {
return strlen(0); // warn
}
< / pre > < / div > < / td > < / tr >
< / tbody > < / table >
< / div > <!-- page -->
< / div > <!-- content -->
2009-06-09 05:21:24 +08:00
< / body >
< / html >