# Available Checkers

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 Default Checkers list below. In addition to these, the analyzer contains a number of Experimental (Alpha) Checkers.

### Writeups with examples of some of the bugs that the analyzer finds

- Bug Finding With Clang: 5 Resources To Get You Started
- Finding Memory Leaks With The LLVM/Clang Static Analyzer
- Under the Microscope - The Clang Static Analyzer
- Mike Ash - Using the Clang Static Analyzer

## Default Checkers

- Core Checkers model core language features and perform general-purpose checks such as division by zero, null pointer dereference, usage of uninitialized values, etc.
- C++ Checkers perform C++-specific checks
- Dead Code Checkers check for unused code
- OS X Checkers perform Objective-C-specific checks and check the use of Apple's SDKs (OS X and iOS)
- Security Checkers check for insecure API usage and perform checks based on the CERT Secure Coding Standards
- Unix Checkers check the use of Unix and POSIX APIs

### Core Checkers

Name, Description | Example

core.CallAndMessage (C, C++, ObjC)
Check for logical errors for function calls and Objective-C message expressions (e.g., uninitialized arguments, null function pointers).

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

    // C
    void test() {
      void (*foo)(void);
      foo(); // warn: function pointer is uninitialized
    }

    // C
    void test() {
      void (*foo)(void);
      foo = 0;
      foo(); // warn: function pointer is null
    }

    // C++
    class C {
    public:
      void f();
    };

    void test() {
      C *pc;
      pc->f(); // warn: object pointer is uninitialized
    }

    // C++
    class C {
    public:
      void f();
    };

    void test() {
      C *pc = 0;
      pc->f(); // warn: object pointer is null
    }

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

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

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

core.DivideZero (C, C++, ObjC)
Check for division by zero.

    void test(int z) {
      if (z == 0)
        int x = 1 / z; // warn
    }

    void test() {
      int x = 1;
      int y = x % 0; // warn
    }

core.NonNullParamChecker (C, C++, ObjC)
Check for null pointers passed as arguments to a function whose arguments are marked with the `nonnull` attribute.

    int f(int *p) __attribute__((nonnull));

    void test(int *p) {
      if (!p)
        f(p); // warn
    }

core.NullDereference (C, C++, ObjC)
Check for dereferences of null pointers.

    // C
    void test(int *p) {
      if (p)
        return;

      int x = p[0]; // warn
    }

    // C
    void test(int *p) {
      if (!p)
        *p = 0; // warn
    }

    // C++
    class C {
    public:
      int x;
    };

    void test() {
      C *pc = 0;
      int k = pc->x; // warn
    }

    // Objective-C
    @interface MyClass {
    @public
      int x;
    }
    @end

    void test() {
      MyClass *obj = 0;
      obj->x = 1; // warn
    }

core.StackAddressEscape (C)
Check that addresses of stack memory do not escape the function.

    char const *p;

    void test() {
      char const str[] = "string";
      p = str; // warn
    }

    void* test() {
       return __builtin_alloca(12); // warn
    }

    void test() {
      static int *x;
      int y;
      x = &y; // warn
    }

core.UndefinedBinaryOperatorResult (C)
Check for undefined results of binary operators.

    void test() {
      int x;
      int y = x + 1; // warn: left operand is garbage
    }

core.VLASize (C)
Check for declarations of VLA of undefined or zero size.

    void test() {
      int x;
      int vla1[x]; // warn: garbage as size
    }

    void test() {
      int x = 0;
      int vla2[x]; // warn: zero size
    }

core.uninitialized.ArraySubscript (C)
Check for uninitialized values used as array subscripts.

    void test() {
      int i, a[10];
      int x = a[i]; // warn: array subscript is undefined
    }

core.uninitialized.Assign (C)
Check for assigning uninitialized values.

    void test() {
      int x;
      x |= 1; // warn: left expression is unitialized
    }

core.uninitialized.Branch (C)
Check for uninitialized values used as branch conditions.

    void test() {
      int x;
      if (x) // warn
        return;
    }

core.uninitialized.CapturedBlockVariable (C)
Check for blocks that capture uninitialized values.

    void test() {
      int x;
      ^{ int y = x; }(); // warn
    }

core.uninitialized.UndefReturn (C)
Check for uninitialized values being returned to the caller.

    int test() {
      int x;
      return x; // warn
    }

### C++ Checkers

Name, Description | Example

cplusplus.NewDelete (C++)
Check for double-free, use-after-free and offset problems involving C++ `delete`.

    void f(int *p);

    void testUseMiddleArgAfterDelete(int *p) {
      delete p;
      f(p); // warn: use after free
    }

    class SomeClass {
    public:
      void f();
    };

    void test() {
      SomeClass *c = new SomeClass;
      delete c;
      c->f(); // warn: use after free
    }

    void test() {
      int *p = (int *)__builtin_alloca(sizeof(int));
      delete p; // warn: deleting memory allocated by alloca
    }

    void test() {
      int *p = new int;
      delete p;
      delete p; // warn: attempt to free released
    }

    void test() {
      int i;
      delete &i; // warn: delete address of local
    }

    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[]'
    }

### Dead Code Checkers

Name, Description | Example

deadcode.DeadStores (C)
Check for values stored to variables that are never read afterwards.

    void test() {
      int x;
      x = 1; // warn
    }

### OS X Checkers

Name, Description | Example

osx.API (C)
Check for proper uses of various Apple APIs:
dispatch_once

    void test() {
      dispatch_once_t pred = 0;
      dispatch_once(&pred, ^(){}); // warn: dispatch_once uses local
    }

osx.SecKeychainAPI (C)
Check for improper uses of the Security framework's Keychain APIs:
SecKeychainItemCopyContent
SecKeychainFindGenericPassword
SecKeychainFindInternetPassword
SecKeychainItemFreeContent
SecKeychainItemCopyAttributesAndData
SecKeychainItemFreeAttributesAndData

    void test() {
      unsigned int *ptr = 0;
      UInt32 length;

      SecKeychainItemFreeContent(ptr, &length);
        // warn: trying to free data which has not been allocated
    }

    void test() {
      unsigned int *ptr = 0;
      UInt32 *length = 0;
      void *outData;

      OSStatus st =
        SecKeychainItemCopyContent(2, ptr, ptr, length, outData);
        // warn: data is not released
    }

    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
    }

    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);
    }

    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
    }

osx.cocoa.AtSync (ObjC)
Check for nil pointers used as mutexes for `@synchronized`.

    void test(id x) {
      if (!x)
        @synchronized(x) {} // warn: nil value used as mutex
    }

    void test() {
      id y;
      @synchronized(y) {} // warn: uninitialized value used as mutex
    }

osx.cocoa.ClassRelease (ObjC)
Check for sending `retain`, `release`, or `autorelease` directly to a class.

    @interface MyClass : NSObject
    @end

    void test(void) {
      [MyClass release]; // warn
    }

osx.cocoa.IncompatibleMethodTypes (ObjC)
Check for an incompatible type signature when overriding an Objective-C method.

    @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

alpha.osx.cocoa.MissingSuperCall (ObjC)
Warn about Objective-C methods that lack a necessary call to super. (Note: The compiler now has a warning for methods annotated with `objc_requires_super` attribute. The checker exists to check methods in the Cocoa frameworks that haven't yet adopted this attribute.)

    @interface Test : UIViewController
    @end
    @implementation test
    - (void)viewDidLoad {} // warn
    @end

osx.cocoa.NSAutoreleasePool (ObjC)
Warn for suboptimal uses of NSAutoreleasePool in Objective-C GC mode (`-fobjc-gc` compiler option).

    void test() {
      NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
      [pool release]; // warn
    }

osx.cocoa.NSError (ObjC)
Check usage of `NSError**` parameters.

    @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

    @interface A : NSObject
    - (BOOL)foo:(NSError **)error;
    @end

    @implementation A
    - (BOOL)foo:(NSError **)error {
      *error = 0; // warn: potential null dereference
      return 0;
    }
    @end

osx.cocoa.NilArg (ObjC)
Check for prohibited nil arguments in specific Objective-C method calls:
- caseInsensitiveCompare:
- compare:
- compare:options:
- compare:options:range:
- compare:options:range:locale:
- componentsSeparatedByCharactersInSet:
- initWithFormat:

    NSComparisonResult test(NSString *s) {
      NSString *aString = nil;
      return [s caseInsensitiveCompare:aString];
        // warn: argument to 'NSString' method
        // 'caseInsensitiveCompare:' cannot be nil
    }

osx.cocoa.RetainCount (ObjC)
Check for leaks and violations of the Cocoa Memory Management rules.

    void test() {
      NSString *s = [[NSString alloc] init]; // warn
    }

    CFStringRef test(char *bytes) {
      return CFStringCreateWithCStringNoCopy(
               0, bytes, NSNEXTSTEPStringEncoding, 0); // warn
    }

osx.cocoa.SelfInit (ObjC)
Check that `self` is properly initialized inside an initializer method.

    @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

    @interface MyObj : NSObject
    - (id)init;
    @end

    @implementation MyObj
    - (id)init {
      [super init];
      return self; // warn: returning uninitialized 'self'
    }
    @end

osx.cocoa.UnusedIvars (ObjC)
Warn about private ivars that are never used.

    @interface MyObj : NSObject {
    @private
      id x; // warn
    }
    @end

    @implementation MyObj
    @end

osx.cocoa.VariadicMethodTypes (ObjC)
Check for passing non-Objective-C types to variadic collection initialization methods that expect only Objective-C types.

    void test() {
      [NSSet setWithObjects:@"Foo", "Bar", nil];
        // warn: argument should be an ObjC pointer type, not 'char *'
    }

osx.coreFoundation.CFError (C)
Check usage of `CFErrorRef*` parameters.

    void test(CFErrorRef *error) {
      // warn: function accepting CFErrorRef* should have a
      // non-void return
    }

    int foo(CFErrorRef *error) {
      *error = 0; // warn: potential null dereference
      return 0;
    }

osx.coreFoundation.CFNumber (C)
Check for improper uses of `CFNumberCreate`.

    CFNumberRef test(unsigned char x) {
      return CFNumberCreate(0, kCFNumberSInt16Type, &x);
       // warn: 8 bit integer is used to initialize a 16 bit integer
    }

osx.coreFoundation.CFRetainRelease (C)
Check for null arguments to `CFRetain`, `CFRelease`, `CFMakeCollectable`.

    void test(CFTypeRef p) {
      if (!p)
        CFRetain(p); // warn
    }

    void test(int x, CFTypeRef p) {
      if (p)
        return;

      CFRelease(p); // warn
    }

osx.coreFoundation.containers.OutOfBounds (C)
Checks for index out-of-bounds when using `CFArray` API.

    void test() {
      CFArrayRef A = CFArrayCreate(0, 0, 0, &kCFTypeArrayCallBacks);
      CFArrayGetValueAtIndex(A, 0); // warn
    }

osx.coreFoundation.containers.PointerSizedValues (C)
Warns if `CFArray`, `CFDictionary`, `CFSet` are created with non-pointer-size values.

    void test() {
      int x[] = { 1 };
      CFArrayRef A = CFArrayCreate(0, (const void **)x, 1,
                                   &kCFTypeArrayCallBacks); // warn
    }

### Security Checkers

Name, Description | Example

security.FloatLoopCounter (C)
Warn on using a floating point value as a loop counter (CERT: FLP30-C, FLP30-CPP).

    void test() {
      for (float x = 0.1f; x <= 1.0f; x += 0.1f) {} // warn
    }

security.insecureAPI.UncheckedReturn (C)
Warn on uses of functions whose return values must be always checked:
setuid
setgid
seteuid
setegid
setreuid
setregid

    void test() {
      setuid(1); // warn
    }

security.insecureAPI.getpw (C)
Warn on uses of the `getpw` function.

    void test() {
      char buff[1024];
      getpw(2, buff); // warn
    }

security.insecureAPI.gets (C)
Warn on uses of the `gets` function.

    void test() {
      char buff[1024];
      gets(buff); // warn
    }

security.insecureAPI.mkstemp (C)
Warn when `mktemp`, `mkstemp`, `mkstemps` or `mkdtemp` is passed fewer than 6 X's in the format string.

    void test() {
      mkstemp("XX"); // warn
    }

security.insecureAPI.mktemp (C)
Warn on uses of the `mktemp` function.

    void test() {
      char *x = mktemp("/tmp/zxcv"); // warn: insecure, use mkstemp
    }

security.insecureAPI.rand (C)
Warn on uses of inferior random number generating functions (only if `arc4random` function is available):
drand48
erand48
jrand48
lcong48
lrand48
mrand48
nrand48
random
rand_r

    void test() {
      random(); // warn
    }

security.insecureAPI.strcpy (C)
Warn on uses of the `strcpy` and `strcat` functions.

    void test() {
      char x[4];
      char *y = "abcd";

      strcpy(x, y); // warn
    }

security.insecureAPI.vfork (C)
Warn on uses of the `vfork` function.

    void test() {
      vfork(); // warn
    }

### Unix Checkers

Name, Description | Example

unix.API (C)
Check calls to various UNIX/POSIX functions:
open
pthread_once
calloc
malloc
realloc
alloca

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

    void f();

    void test() {
      pthread_once_t pred = {0x30B1BCBA, {0}};
      pthread_once(&pred, f);
        // warn: call to 'pthread_once' uses the local variable
    }

    void test() {
      void *p = malloc(0); // warn: allocation size of 0 bytes
    }

    void test() {
      void *p = calloc(0, 42); // warn: allocation size of 0 bytes
    }

    void test() {
      void *p = malloc(1);
      p = realloc(p, 0); // warn: allocation size of 0 bytes
    }

    void test() {
      void *p = alloca(0); // warn: allocation size of 0 bytes
    }

    void test() {
      void *p = valloc(0); // warn: allocation size of 0 bytes
    }

unix.Malloc (C)
Check for memory leaks, double free, and use-after-free and offset problems involving `malloc`.

    void test() {
      int *p = malloc(1);
      free(p);
      free(p); // warn: attempt to free released memory
    }

    void test() {
      int *p = malloc(sizeof(int));
      free(p);
      *p = 1; // warn: use after free
    }

    void test() {
      int *p = malloc(1);
      if (p)
        return; // warn: memory is never released
    }

    void test() {
      int a[] = { 1 };
      free(a); // warn: argument is not allocated by malloc
    }

    void test() {
      int *p = malloc(sizeof(char));
      p = p - 1;
      free(p); // warn: argument to free() is offset by -4 bytes
    }

unix.MallocSizeof (C)
Check for dubious `malloc`, `calloc` or `realloc` arguments involving `sizeof`.

    void test() {
      long *p = malloc(sizeof(short));
        // warn: result is converted to 'long *', which is
        // incompatible with operand type 'short'
      free(p);
    }

unix.MismatchedDeallocator (C, C++, ObjC)
Check for mismatched deallocators (e.g. passing a pointer allocating with `new` to `free()`).

    // C, C++
    void test() {
      int *p = (int *)malloc(sizeof(int));
      delete p; // warn
    }

    // C, C++
    void __attribute((ownership_returns(malloc))) *user_malloc(size_t);

    void test() {
      int *p = (int *)user_malloc(sizeof(int));
      delete p; // warn
    }

    // C, C++
    void test() {
      int *p = new int;
      free(p); // warn
    }

    // C, C++
    void test() {
      int *p = new int[1];
      realloc(p, sizeof(long)); // warn
    }

    // 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));
    }

    // C++
    void test() {
      int *p = (int *)operator new(0);
      delete[] p; // warn
    }

    // 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'
    }

unix.cstring.BadSizeArg (C)
Check the size argument passed to `strncat` for common erroneous patterns. Use `-Wno-strncat-size` compiler option to mute other `strncat`-related compiler warnings.

    void test() {
      char dest[3];
      strncat(dest, "***", sizeof(dest));
        // warn: potential buffer overflow
    }

unix.cstring.NullArg (C)
Check for null pointers being passed as arguments to C string functions:
strlen
strnlen
strcpy
strncpy
strcat
strncat
strcmp
strncmp
strcasecmp
strncasecmp

    int test() {
      return strlen(0); // warn
    }