Index: www/analyzer/available_checks.html
===================================================================
--- www/analyzer/available_checks.html
+++ www/analyzer/available_checks.html
@@ -38,11 +38,13 @@
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
+LLVM Checkers for LLVM developers
Nullability Checkers
Optin Checkers
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
+Variable Argument Checkers
@@ -369,6 +371,25 @@
Name, Description | Example |
+
+
+
+cplusplus.InnerPointer
+(C++)
+Check for inner pointers of C++ containers used after re/deallocation.
+ |
+
+
+void log(const char *str);
+
+void test(int value) {
+ const char *msg = std::to_string(value).c_str();
+ // msg points to the buffer of a temporary that is now destroyed
+ log(msg); // warn: inner pointer of container used after re/deallocation
+}
+ |
+
+
cplusplus.NewDelete
(C++)
@@ -435,6 +456,7 @@
} // warn
|
+
@@ -458,6 +480,31 @@
+
+LLVM Checkers
+
+
+Name, Description | Example |
+
+
+
+llvm.Conventions
+(C)
+Check code for LLVM codebase conventions:
+
+ - A
StringRef should not be bound to a temporary std::string
+ whose lifetime is shorter than the StringRef 's.
+ - Clang AST nodes should not have fields that can allocate memory.
+
+ |
+ |
+
+
+
+
Nullability Checkers
@@ -535,6 +582,21 @@
}
+
+
+nullability.NullableReturnedFromNonnull
+(ObjC)
+Warns when a nullable pointer is returned from a function that has _Nonnull return type. |
+
+
+typedef struct Dummy { int val; } Dummy;
+
+Dummy *_Nonnull test(Dummy *_Nullable a) {
+ Dummy *p = a;
+ return p; // warn
+}
+ |
+
@@ -610,6 +672,95 @@
[alarmStateLabel setText:alarmText];
+
+
+optin.performance.GCDAntipattern
+(ObjC)
+This checker finds a common performance anti-pattern in a code that uses Grand
+Central dispatch. The anti-pattern involves emulating a synchronous call from an
+asynchronous API using semaphores, as in the snippet below, where the
+ requestCurrentTaskName function makes an XPC call and then uses the
+semaphore to block until the XPC call returns (example 1.).
+Usage of such a pattern in production code running on the main thread is
+discouraged, as the main queue gets blocked waiting for the background queue,
+which could be running at a lower priority, and unnecessary threads are spawned
+in the process.
+In order to avoid the anti-pattern, the available alternatives are:
+
+ - Use the synchronous version of the API, if available (as seen on example
+ 2.)
+ - Alternatively, the API can be used in the asynchronous way.
+
+ |
+
+
+// Example 1.
++ (NSString *)requestCurrentTaskName {
+ __block NSString *taskName = nil;
+ dispatch_semaphore_t sema = dispatch_semaphore_create(0);
+ NSXPCConnection *connection = [[NSXPCConnection alloc] initWithServiceName:@"MyConnection"];
+ id remoteObjectProxy = connection.remoteObjectProxy;
+ [remoteObjectProxy requestCurrentTaskName:^(NSString *task) {
+ taskName = task;
+ dispatch_semaphore_signal(sema);
+ }];
+ dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER);
+ return taskName;
+}
+
+
+// Example 2.
++ (NSString *)requestCurrentTaskName {
+ __block NSString *taskName = nil;
+ NSXPCConnection *connection = [[NSXPCConnection alloc] initWithServiceName:@"MyConnection"];
+ id remoteObjectProxy = [connection synchronousRemoteObjectProxyWithErrorHandler:^(NSError *error) {
+ NSLog(@"Error = %@", error);
+
+ }];
+ [remoteObjectProxy requestCurrentTaskName:^(NSString *task) {
+ taskName = task;
+ }];
+ return taskName;
+}
+ |
+
+
+
+optin.performance.Padding
+(C)
+Check for excessively padded structs.
+ |
+
+
+class PaddedA { // warn: excessive padding
+ char c1;
+ int i;
+ char c2;
+};
+ |
+
+
+
+optin.portability.UnixAPI
+(C)
+Finds implementation-defined behavior in UNIX/Posix functions.
+
+calloc
+malloc
+realloc
+reallocf
+alloca, __builtin_alloca
+__builtin_alloca_with_align
+valloc
+ |
+
+
+void *f(int n) {
+ return malloc(n * 0 * sizeof(int)); // warn: Call to 'malloc' has an
+ // allocation size of 0 bytes
+}
+ |
+
@@ -649,6 +800,9 @@
+
+
+
osx.SecKeychainAPI
(C)
@@ -732,7 +886,8 @@
osx.cocoa.AtSync
(ObjC)
-Check for nil pointers used as mutexes for @synchronized . |
+Check for nil pointers used as mutexes for @synchronized .
+
void test(id x) {
@@ -749,6 +904,38 @@
+osx.cocoa.AutoreleaseWrite
+(ObjC)
+Under ARC, function parameters which are pointers to pointers (e.g.
+NSError ** ) are __autoreleasing . Writing to such
+parameters inside autoreleasing pools might crash whenever the parameter
+outlives the pool. Detecting such crashes may be difficult, as usage of
+autorelease pool is usually hidden inside the called functions implementation.
+ |
+
+
+BOOL writeToErrorWithIterator(NSError *__autoreleasing* error, NSArray *a) { [a enumerateObjectsUsingBlock:^{
+ *error = [NSError errorWithDomain:1];
+ }];
+}
+
+
+BOOL writeToErrorInBlockFromCFunc(NSError *__autoreleasing* error) {
+ dispatch_semaphore_t sem = dispatch_semaphore_create(0l);
+ dispatch_async(queue, ^{
+ if (error) {
+ *error = [NSError errorWithDomain:1];
+ }
+ dispatch_semaphore_signal(sem);
+ });
+
+ dispatch_semaphore_wait(sem, 100);
+ return 0;
+}
+ |
+
+
+
osx.cocoa.ClassRelease
(ObjC)
Check for sending retain , release , or
@@ -965,6 +1152,29 @@
+osx.cocoa.RunLoopAutoreleaseLeak
+(ObjC)
+Detects leaks resulting from allocating temporary autoreleased objects before
+starting the main run loop.
+
+Checks for two antipatterns:
+
+ - ObjCMessageExpr followed by
[[NSRunLoop mainRunLoop] run] in
+ the same autorelease pool.
+ - ObjCMessageExpr followed by
[[NSRunLoop mainRunLoop] run] in
+ no autorelease pool.
+
+
+Any temporary objects autoreleased in code called in those expressions will not
+be deallocated until the program exits, and are effectively leaks.
+ |
+ |
+
+
+
osx.cocoa.SelfInit
(ObjC)
Check that self is properly initialized inside an initializer
@@ -1571,6 +1781,74 @@
+
+
+ Variable Argument Checkers
+
+
+Name, Description | Example |
+
+
+
+valist.CopyToSelf
+(C)
+Calls to the va_copy macro should not copy onto itself. |
+
+
+#include <stdarg.h>
+
+void test(int x, ...) {
+ va_list args;
+ va_start(args, x);
+ va_copy(args, args); // warn
+ va_end(args);
+}
+ |
+
+
+valist.Uninitialized
+(C)
+Calls to the va_arg , va_copy , or
+va_end macro must happen after calling va_start and
+before calling va_end . |
+
+
+#include <stdarg.h>
+
+void test(int x, ...) {
+ va_list args;
+ int y = va_arg(args, int); // warn
+}
+
+
+#include <stdarg.h>
+
+void test(int x, ...) {
+ va_list args;
+ va_start(args, x);
+ va_end(args);
+ int z = va_arg(args, int); // warn
+}
+ |
+
+
+valist.Unterminated
+(C)
+Every va_start must be matched by a va_end . A va_list
+can only be ended once. |
+
+
+#include <stdarg.h>
+
+void test(int x, ...) {
+ va_list args;
+ va_start(args, x);
+ int y = x + va_arg(args, int);
+} // warn: missing va_end
+ |
+
+
+
| | | |