Evaluate "panic" functions that are known to not return to the caller.
-
-
-
core.uninitialized.ArraySubscript
Check for uninitialized values used as array subscripts.
-
-
-
core.uninitialized.Assign
Check for assigning uninitialized values.
-
-
-
core.uninitialized.Branch
Check for uninitialized values used as branch conditions.
-
-
-
core.uninitialized.CapturedBlockVariable
Check for blocks that capture uninitialized values.
-
-
-
core.uninitialized.UndefReturn
Check for uninitialized values being returned to the caller.
-
-
-
cplusplus.NewDelete
Check for double-free and use-after-free problems involving C++ delete.
-
-
-
deadcode.DeadStores
Check for values stored to variables that are never read afterwards.
-
-
-
-
osx.API
Check for proper uses of various Apple APIs.
-
-
-
osx.SecKeychainAPI
Check for proper uses of Secure Keychain APIs.
-
-
-
osx.cocoa.AtSync
Check for nil pointers used as mutexes for @synchronized.
-
-
-
osx.cocoa.ClassRelease
Check for sending 'retain', 'release', or 'autorelease' directly to a Class.
-
-
-
osx.cocoa.IncompatibleMethodTypes
Warn about Objective-C method signatures with type incompatibilities.
-
-
-
osx.cocoa.NSAutoreleasePool
Warn for suboptimal uses of NSAutoreleasePool in Objective-C GC mode.
-
-
-
osx.cocoa.NSError
Check usage of NSError** parameters.
-
-
-
osx.cocoa.NilArg
Check for prohibited nil arguments to ObjC method calls.
-
-
-
osx.cocoa.RetainCount
Check for leaks and improper reference count management.
-
-
-
osx.cocoa.SelfInit
Check that 'self' is properly initialized inside an initializer method.
-
-
-
osx.cocoa.UnusedIvars
Warn about private ivars that are never used.
-
-
-
osx.cocoa.VariadicMethodTypes
Check for passing non-Objective-C types to variadic methods that expect only Objective-C types.
-
-
-
osx.coreFoundation.CFError
Check usage of CFErrorRef* parameters.
-
-
-
osx.coreFoundation.CFNumber
Check for proper uses of CFNumberCreate.
-
-
-
osx.coreFoundation.CFRetainRelease
Check for null arguments to CFRetain/CFRelease/CFMakeCollectable.
-
-
-
osx.coreFoundation.containers.OutOfBounds
Checks for index out-of-bounds when using 'CFArray' API.
-
-
-
osx.coreFoundation.containers.PointerSizedValues
Warns if 'CFArray', 'CFDictionary', 'CFSet' are created with non-pointer-size values.
-
-
-
security.FloatLoopCounter
Warn on using a floating point value as a loop counter (CERT: FLP30-C, FLP30-CPP).
-
-
-
security.insecureAPI.UncheckedReturn
Warn on uses of functions whose return values must be always checked.
-
-
-
security.insecureAPI.getpw
Warn on uses of the 'getpw' function.
-
-
-
security.insecureAPI.gets
Warn on uses of the 'gets' function.
-
-
-
security.insecureAPI.mkstemp
Warn when 'mkstemp' is passed fewer than 6 X's in the format string.
-
-
-
security.insecureAPI.mktemp
Warn on uses of the 'mktemp' function.
-
-
-
security.insecureAPI.rand
Warn on uses of the 'rand', 'random', and related functions.
-
-
-
security.insecureAPI.strcpy
Warn on uses of the 'strcpy' and 'strcat' functions.
-
-
-
security.insecureAPI.vfork
Warn on uses of the 'vfork' function.
-
-
-
unix.API
Check calls to various UNIX/Posix functions.
-
-
-
unix.Malloc
Check for memory leaks, double free, and use-after-free problems involving malloc.
-
-
-
unix.MallocSizeof
Check for dubious malloc arguments involving sizeof.
-
-
-
unix.MismatchedDeallocator
Check for mismatched deallocators (e.g. passing a pointer allocating with new to free()).
-
-
-
unix.cstring.BadSizeArg
Check the size argument passed into C string functions for common erroneous patterns.
-
-
-
unix.cstring.NullArg
Check for null pointers being passed as arguments to C string functions.
-
-
-
In addition to these the analyzer contains numerous experimental (alpha) checkers.
+
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
Core Checkers model core language features and perform general-purpose checks such as division by zero, null pointer dereference, usage of uninitialized values, etc.
+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:
+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);
+}
+
+Warn about Objective-C methods that lack a necessary call to super (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-only compiler option).
+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.
+// 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
+}
+
+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++
+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.
+
This page contains a list of potential checkers to implement in the static analyzer. If you are interested in contributing to the analyzer's development, this is a good resource to help you get started. The specific names of the checkers are subject to review, and are provided here as suggestions.
-
allocation/deallocation
+
memory
Name, Description
Example
Progress
-
memory.LeakNeverReleased
-(C, C++)
-Memory may be never released, potential leak of memory
-
-
-#include <stdlib.h>
-
-int f() {};
-
-void test() {
- int *p1 = (int*)malloc(sizeof(int)); // warn
- int *p2 = new int; // warn
- int x = f();
- if (x==1)
- return;
- delete p2;
-}
-
+void f(int, int);
+int g(void *);
+int h() __attribute__((noreturn));
void test() {
- int *p1 = new int;
- int *p2 = new int[1];
-
- free(p1); // warn
- free(p2); // warn
+ // It is possible that 'malloc(1)' is called first,
+ // then 'h()', that is (or calls) noreturn and eventually
+ // 'g()' is never called.
+ f(g(malloc(1)), h()); // warn: 'g()' may never be called.
}
-
-#include <string.h>
-
+ // It is possible that 'new int' is called first,
+ // then 'h()', that throws an exception and eventually
+ // 'g()' is never called.
+ f(g(new int), h()); // warn: 'g()' may never be called.
+}
+
+
+
+
+
+memory.DstBufferTooSmall
+(C, C++)
+Destination buffer passed to memory function is too small.
+ Note: security.insecureAPI.strcpy currently warns
+on usage of strcpy and suggests to replace it.
+
Every va_start must be matched by a va_end. A va_list
can only be ended once.
-This should be folded into the generalized "ownership checker" described on the Open Projects page.
-
+This should be folded into the generalized "ownership checker"
+described on the
+Open Projects page.
+
+
#include <stdarg.h>
void test(int x, ...) {
va_list args;
va_start(args, x);
int y = x + va_arg(args, int);
- // missing va_end
-}
-
-C++03: auto_ptr should store a pointer to an object obtained via new as allocated
-memory will be cleaned using delete
-C++11: one should use unique_ptr<T[]> to keep a pointer to memory
-allocated by new[]
-C++11: to keep a pointer to memory allocated by new[] in a shared_ptr one
-should use a custom deleter that calls delete[]
-
+
+smartptr.SmartPtrInit
+(C++)
+C++03: auto_ptr should store a pointer to an object obtained via
+new as allocated memory will be cleaned using delete.
+C++11: one should use unique_ptr<type[]> to keep a
+pointer to memory allocated by new[].
+C++11: to keep a pointer to memory allocated by new[] in
+a shared_ptr one should use a custom deleter that calls
+delete[]..
+
Source: C++03 20.4.5p1; C++11 auto_ptr is deprecated (D.10).
-Undefined behavior: std::exit is called to end the program during the
-destruction of an object with static storage duration
-
+
+undefbehavior.ExitInDtor
+(C++)
+Undefined behavior: std::exit() is called to end the program during
+the destruction of an object with static storage duration.
+
Source: C++11 3.6.1p4.
+
+
#include <cstdlib>
class A {
@@ -361,17 +417,20 @@
std::exit(1); // warn
}
};
+
+
-A a;
-
-
undefbehavior.LocalStaticDestroyed
- (C++)
+
+undefbehavior.LocalStaticDestroyed
+(C++)
Undefined behavior: function containing a definition of static local object is
called during the destruction of an object with static storage duration so that
flow of control passes through the definition of the previously destroyed
-static local object
-
+static local object.
+
Source: C++11 3.6.3p2.
+
+
void f();
class A {
@@ -386,70 +445,126 @@
A a;
void f() {
- static B b; // <-
-}
-
-
-
undefbehavior.UseAfterRelease
- enhancement to unix.Malloc (C, C++)
-Pointer to deleted object is referenced (The effect of using an invalid pointer
-value is undefined)
-
-#include <stdlib.h>
-
-void test() {
- int *p = new int;
- delete p;
- int i = *p; // warn
+ static B b;
}
+
+
-
-
undefbehavior.ZeroAllocDereference
- enhancement to unix.Malloc (C, C++)
+
+undefbehavior.ZeroAllocDereference
+(C, C++)
The effect of dereferencing a pointer returned as a request for zero size is
-undefined
-
-#include <stdlib.h>
-
+undefined.
+Note: possibly an enhancement to
+unix.Malloc.
+
Source: C++03 3.7.3.1p2; C++11 3.7.4.1p2.
+
+
int *p = new int[0];
int i = p[0]; // warn
-
+
+
+
-
undefbehavior.DeadReferenced
- (C++)
+
+undefbehavior.DeadReferenced
+(C++)
Undefined behavior: the following usage of the pointer to the object whose
-lifetime has ended can result in undefined behavior
-
-// C++03
+lifetime has ended can result in undefined behavior.
+
Source: C++03 3.8p5, p7; C++11 3.8p5, p7.
+
+
#include <new>
class A {
public:
int i;
- void f() {};
};
-class B : public A {
+class B : public A {};
+
+int test() {
+ B *b = new B;
+ new(b) A;
+ return b->i; // warn
+}
+
+
+#include <new>
+
+class A {
+public:
+ void f() {};
};
+class B : public A {};
+
void test() {
B *b = new B;
new(b) A;
- b->i; // warn
- b->f(); // warn
+ b->f(); // warn
+}
+
+
+#include <new>
+
+class A {};
+
+class B : public A {};
+
+A* test() {
+ B *b = new B;
+ new(b) A;
static_cast<A*>(b); // warn
+}
+
+
+#include <new>
+
+class A {};
+
+class B : public A {};
+
+A* test() {
+ B *b = new B;
+ new(b) A;
+ dynamic_cast<A*>(b); // warn
+}
+
+
+#include <new>
+
+class A {};
+
+class B : public A {};
+
+A* test() {
+ B *b = new B;
+ new(b) A;
dynamic_cast<A*>(b); // warn
- delete b; // warn
}
+
+
+#include <new>
+class A {};
+
+class B : public A {};
+
+void test() {
+ B *b = new B;
+ new(b) A;
+ delete b; // warn
+}
+
+
// C++11
#include <new>
class A {
public:
int i;
- void f() {};
};
class B : public A {
@@ -457,228 +572,257 @@
~B() {};
};
-void test() {
+int test() {
A *a = new A;
new(a) B;
- a->i; // warn
- a->f(); // warn
- B *b = new B;
- new(b) A;
- b->i; // warn
- b->f(); // warn
- static_cast<A*>(b); // warn
- dynamic_cast<A*>(b); // warn
- delete b; // warn
+ return a->i; // warn
}
-
+
+
+
-
undefbehavior.ObjLocChanges
- (C++)
+
+undefbehavior.ObjLocChanges
+(C++)
Undefined behavior: the program must ensure that an object occupies the same
-storage location when the implicit or explicit destructor call takes place
-
+storage location when the implicit or explicit destructor call takes place.
+
Source: C++11 3.8p8.
+
+
#include <new>
-class T { };
-struct B {
+class A {};
+
+class B {
+public:
~B();
};
void test() {
- B *b1 = new B;
- B b2;
- new (b1) T;
- new (&b2) T;
- delete b1; // warn
+ B b;
+ new (&b) A;
} // warn
-
+
+
+#include <new>
+
+class A {};
-
undefbehavior.ExprEvalOrderUndef
- (C, C++03)
+class B {
+public:
+ ~B();
+};
+
+void test() {
+ B *b = new B;
+ new (b) A;
+ delete b; // warn
+}
+
+
+
+
+
+undefbehavior.ExprEvalOrderUndef
+(C, C++03)
Undefined behavior: a scalar object shall have its stored value modified at
-most once by the evaluation of an expression
-
-void test () {
+most once by the evaluation of an expression.
+Note: most cases are currently handled by the Clang core (search for 'multiple
+unsequenced modifications' warning in Clang tests).
+
Source: C++03 5p4.
+
+
+int test () {
int i = 0;
- int v[1] = {0};
- i = v[i++]; // warn
i = ++i + 1; // warn
+ return i;
}
-
+
+
-
undefbehavior.StaticInitReentered
- (C)
+
+
+undefbehavior.StaticInitReentered
+(C++)
Undefined behavior: static declaration is re-entered while the object is being
-initialized
-
+initialized.
+
Source: C++11 6.7p4.
+
+
int test(int i) {
- static int s = test(2*i); // warn
- return i+1;
+ static int s = test(2 * i); // warn
+ return i + 1;
}
-
+
+
-
undefbehavior.ConstModified
- (C, C++)
-Undefined behavior: const object is being modified
-
-#include <stdlib.h>
-class X {
-public :
- mutable int i;
- int j;
-};
-class Y {
+
+undefbehavior.ConstModified
+(C, C++)
+Undefined behavior: const object is being modified.
+
Source: C++03 7.1.5.1p4, C++11 7.1.6.1p4.
+
+
+void test() {
+ const int *cp = new const int (0);
+ int *p = const_cast<int *>(cp);
+ *p = 1; // warn
+ delete p;
+}
+
+
+class C {
public :
- X x;
- Y();
+ int i;
+ C();
};
void test() {
- const int *ciq =
- (int *)malloc(sizeof(int));
- int *iq = const_cast<int *>(ciq);
- *iq = 1; // warn
+ const C cb;
- const Y y;
- Y* p = const_cast<Y*>(&y);
- p->x.i = 1; // ok
- p->x.j = 1; // warn
+ C* cp = const_cast<C *>(&cb);
+ cp->i = 1; // warn
}
-
+
+
+
-
undefbehavior.DeadDestructed
- (C++)
+
+undefbehavior.DeadDestructed
+(C++)
Undefined behavior: the destructor is invoked for an object whose lifetime
-has ended
-
-Undefined behavior: calls member function but base not yet initialized
-
+
+
+undefbehavior.MethodCallBeforeBaseInit
+(C++)
+Undefined behavior: calls member function but base not yet initialized.
+
Source: C++03 12.6.2p8; C++11 12.6.2p13.
+
+
class A {
public :
- A(int );
+ A(int);
};
+
class B : public A {
public :
int f();
B() : A(f()) {} // warn
};
-
+
+
+
-
undefbehavior.MemberOrBaseRefBeforeCtor
- (C++)
+
+undefbehavior.MemberOrBaseRefBeforeCtor
+(C++)
C++ Undefined behavior: non-static member or base class of non-POD class type
-is referred before constructor begins execution
+is referred before constructor begins execution.
C++11 Undefined behavior: non-static member or base class of a class with a
-non-trivial constructor is referred before constructor begins execution
-
-// C++03
+non-trivial constructor is referred before constructor begins execution.
+
C++03: Undefined behavior: non-static member of non-POD class type is referred
-after destructor ends execution
+after destructor ends execution.
C++11: Undefined behavior: non-static member of a class with a non-trivial
-destructor is referred after destructor ends execution
-
-// C++03
-struct non_POD {
- virtual void f() {};
+destructor is referred after destructor ends execution.
+
Source: C++03 12.7p1; C++11 12.7p1.
+
+
+class C {
+public:
+ C();
+ void f();
};
void test() {
- non_POD *non_pod = new non_POD();
- non_pod->~non_POD();
- non_pod->f(); // warn
+ C *c = new C();
+ c->~C();
+ c->f(); // warn
}
+
+
-// C++11
-struct S {
- ~S() {};
- void f() {};
-};
-void test() {
- S *s = new S();
- s->~S();
- s->f(); // warn
-}
-
-
-
undefbehavior.CtorForeignCall
- (C++)
+
+undefbehavior.CtorForeignCall
+(C++)
Undefined behavior: call to virtual function of an object under construction
-whose type is neither the constructors own class or one of its bases
-
+whose type is neither the constructors own class or one of its bases.
+
Source: C++11 12.7p4.
+
+
class A {
public:
virtual void f() {};
@@ -693,15 +837,47 @@
public:
C() : B((A*)this) {}
};
-
-Undefined behavior: the operand of typeid/dynamic_cast is an object under
+
+
+undefbehavior.CtorForeignTypeid
+(C++)
+Undefined behavior: the operand of typeid is an object under
construction whose type is neither the constructors own class or one of its
-bases
-
+bases.
+
Source: C++11 12.7p5.
+
+
+#include <typeinfo>
+
+class A {};
+
+class B {
+public:
+ B(A* a) {
+ (void)typeid(*a); // warn
+ }
+};
+
+class C : public A, B {
+public:
+ C() : B((A*)this) {}
+};
+
+
+
+
+
+undefbehavior.CtorForeignCast
+(C++)
+Undefined behavior: the operand of dynamic_cast is an object under
+construction whose type is neither the constructors own class or one of its
+bases.
+
Source: C++11 12.7p6.
+
+
#include <typeinfo>
class A {
@@ -712,8 +888,7 @@
class B {
public:
B(A* a) {
- typeid(*a); // warn
- dynamic_cast<B*>(a); //warn
+ (void)dynamic_cast<B*>(a); //warn
}
};
@@ -721,45 +896,83 @@
public:
C() : B((A*)this) {}
};
-
Undefined behavior: referring to any non-static member or base class of an
object in the handler for a function-try-block of a constructor or destructor
-for that object results in undefined behavior
-
undefbehavior.QsortNonPOD
-undefbehavior.QsortNonTrivial
- C++
+
+
+undefbehavior.QsortNonPODNonTrivial
+(C++)
C++03: Undefined behavior: the objects in the array passed to qsort are of
-non-POD type
+non-POD type.
C++11: Undefined behavior: the objects in the array passed to qsort are of
-non-trivial type
-
Undefined behavior: copy constructor/assignment operator can throw an exception.
-The effects are undefined if an exception is thrown.
-
-struct S {
+The effects are undefined if an exception is thrown.
+
+
+class C {
+public:
int i, j;
- S (const S &s) {
- i = s.i;
+ C (const C &c) {
+ i = c.i;
throw 1; // warn
- j = s.j;
+ j = c.j;
};
- S &operator=(const S &s) {
- i = s.i;
+};
+
+
+class C {
+public:
+ int i, j;
+ C &operator=(const C &c) {
+ i = c.i;
throw 1; // warn
- j = s.j;
- }
+ j = c.j;
+ };
};
-
+
+
-
undefbehavior.ValarrayArgBound
- (C++)
-Undefined behavior: the value of the second argument is greater than the number
-of values pointed to by the first argument
-
+
+
+undefbehavior.ValarrayArgBound
+(C++)
+Undefined behavior: the value of the n argument passed
+to valarray constructor is greater than the number of values
+pointed to by the first argument (source).
+
#include <valarray>
void test() {
- size_t addr[] = {0, 1, 1}; // N is 1
+ // '1' is specified more then once
+ size_t addr[] = {0, 1, 1};
std::valarray<size_t>indirect(addr, 3);
std::valarray<int> a(0, 5), b(1, 3);
a[indirect] = b; //warn
+}
+
+
+#include <valarray>
+
+void test() {
+ // '1' is specified more then once
+ size_t addr[] = {0, 1, 1};
+ std::valarray<size_t>indirect(addr, 3);
+ std::valarray<int> a(0, 5), b(1, 3);
a[indirect] *= b; //warn
}
-
+
+
+
-
undefbehavior.IosBaseDestroyedBeforeInit
- (C++)
- Undefined behavior: ios_base object is destroyed before initialization have
-taken place. basic_ios::init should be call to initialize ios_base
-members
-
+
+undefbehavior.IosBaseDestroyedBeforeInit
+(C++)
+Undefined behavior: ios_base object is destroyed before
+initialization have taken place. basic_ios::init should be call to
+initialize ios_base members.
+
#include <ios>
using namespace std;
-template <class T, class Traits = std::char_traits<T>>
+template <class T, class Traits = std::char_traits<T> >
class my_stream1 : public std::basic_ios<T, Traits> {
};
-template <class T, class Traits = std::char_traits<T>>
+template <class T, class Traits = std::char_traits<T> >
class my_stream2 : public std::basic_ios<T, Traits> {
- class my_streambuf : public std::basic_streambuf<T, Traits> {
+ class my_streambuf
+ : public std::basic_streambuf<T, Traits> {
};
public:
my_stream2() {
@@ -995,28 +1272,35 @@
};
void test() {
- my_stream1<char> *p1 = new my_stream1<char>
- my_stream2<char> *p2 = new my_stream2<char>
+ my_stream1<char> *p1 = new my_stream1<char>;
+ my_stream2<char> *p2 = new my_stream2<char>;
delete p1; // warn
delete p2; // ok
}
-
+
+
+
-
undefbehavior.IosBaseUsedBeforeInit
- (C++11)
-Undefined behavior: ios_base object is used before initialization have taken
-place. basic_ios::init should be call to initialize ios_base members
-
+
+undefbehavior.IosBaseUsedBeforeInit
+(C++11)
+Undefined behavior: ios_base object is used before initialization
+have taken place. basic_ios::init should be call to
+initialize ios_base members.
+
Source: C++11 27.5.3.7p1, 27.5.5.2p2.
+
+
#include <ios>
using namespace std;
-template <class T, class Traits = std::char_traits<T>>
+template <class T, class Traits = std::char_traits<T> >
class my_stream1 : public std::basic_ios<T, Traits> {
};
-template <class T, class Traits = std::char_traits<T>>
+template <class T, class Traits = std::char_traits<T> >
class my_stream2 : public std::basic_ios<T, Traits> {
- class my_streambuf : public std::basic_streambuf<T, Traits> {
+ class my_streambuf
+ : public std::basic_streambuf<T, Traits> {
};
public:
my_stream2() {
@@ -1025,20 +1309,24 @@
};
void test() {
- my_stream1<char> *p1 = new my_stream1<char>
- my_stream2<char> *p2 = new my_stream2<char>
+ my_stream1<char> *p1 = new my_stream1<char>;
+ my_stream2<char> *p2 = new my_stream2<char>;
p1->narrow('a', 'b'); // warn
p2->narrow('a', 'b'); // ok
- delete p1; // warn
- delete p2; // ok
}
-
+
+
+
-
undefbehavior.MinusOnePosType
- (C++)
-Undefined behavior: passing -1 to any streambuf/istream/ostream member that
-accepts a value of type traits::pos_type result in undefined behavior
-
+
+undefbehavior.MinusOnePosType
+(C++)
+Undefined behavior: passing -1 to any streambuf/
+istream/ostream member that accepts a value of
+type traits::pos_type result in undefined behavior.
+
Source: C++03 27.4.3.2p3; C++11 27.5.4.2p3.
+
+
#include <fstream>
class my_streambuf : public std::streambuf {
@@ -1046,16 +1334,19 @@
seekpos(-1); // warn
}
};
+
-Possibly wrong variable is used in the loop/cond-expression of the 'for'
-statement. Did you mean 'proper_variable_name'?
-
+
+different.WrongVarForStmt
+(C, C++)
+Wrong variable is possibly used in the loop/cond-expression of
+the for statement. Did you mean
+'proper_variable_name'?
+
+
void test() {
- int i;
- int j;
- for (j=0; j<3; ++i); // warn
- for (int j=0; i<3; ++j); // warn
+ int i = 0;
+ int j = 0;
+ for (i = 0; i < 3; j += 1); // warn
+}
+
+
+void test() {
+ int i = 0;
+ int j = 0;
+ for (int j = 0; i < 3; ++j); // warn
}
-
+
+
+
-
different.FloatingCompare
- (C)
-Comparing floating point numbers may be not precise
-
+
+different.FloatingCompare
+(C)
+Comparing floating point numbers may be not precise.
+
+
#include <math.h>
-void test() {
+double test() {
double b = sin(M_PI / 6.0);
if (b == 0.5) // warn
b = 0;
+ return b;
}
-
+
+
-
different.BoolCompare
- maybe merge with experimental.core.BoolAssignment (C, C++)
-Comparing boolean to a value other then 0 or 1
-
-void test() {
- int i;
- if (0 < i < 3) {}; // warn
- bool b;
- if (b == 3) {}; // warn
-}
-
-
different.BitwiseOpBoolArg
- maybe join with experimental.core.BoolAssignment (C, C++)
-bool value is used at the left/right part of the & (|) operator. Did you mean
-&& (||) ?
-
+
+different.BitwiseOpBoolArg
+(C, C++)
+Boolean value met at the left/right part of the bitwise &
+or | operator.
+Did you mean && (||) ?
+
+
int f();
void test() {
bool b = true;
if (b & f()) {} // warn
}
-
+
+
-
different.LabelInsideSwitch
- (C)
-Possible misprint: label found inside the switch() statement. (* did you mean
-'default'?)
-
-void test() {
- int c = 7;
+
+
+different.LabelInsideSwitch
+(C)
+Possibly a misprint: label found inside a switch()
+statement.
+
+
+void test(int c) {
switch(c){
case 1:
c += 1; break;
- defalt: // warn
+ defalt: // warn (did you mean 'default'?)
c -= 1; break;
}
}
-
+
+
-
different.IdenticalCondIfIf
- (C)
-The conditions of two subsequent 'if' statements are identical
-
-void test() {
- int c = 7;
- if (c > 5) // <-
+
+
+different.IdenticalCondIfIf
+(C)
+The conditions of two subsequent if statements are
+identical.
+
+
+int test(int c) {
+ if (c > 5)
c += 1;
if (c > 5) // warn
c -= 1;
+ return c;
}
-
+
+
-
different.LogicalOpUselessArg
- (C)
-The second operand of the && operator has no impact on expression result
-
-void test() {
- unsigned a;
+
+
+different.LogicalOpUselessArg
+(C)
+The second operand of a && operator has no impact on
+expression result.
+
+
+void test(unsigned a) {
if (a<7 && a<10) {}; // warn
}
-
+
+
-
different.SameResLogicalExpr
- (C)
-The expression always evaluates to true/false
-
-void test() {
- int i=0;
- if (i!=0) {}; // warn
- if (i==0 && i==1) {}; // warn
- if (i<0 || i>=0) {}; // warn
-}
-
-
-
different.SameResUnsignedCmp
- (C)
-Comparison of unsigned expression 'op expr' is always true/false
-
-void test() {
- unsigned u;
- if (u < -1) {}; // warn
- if (u >= 0) {}; // warn
-}
-
-
-
different.OpPrecedenceAssignCmp
- (C)
-Comparison operation has higher precedence then assignment. Bool value is
-assigned to variable of type 'type'. Parenthesis may bee required around an
-assignment
-
-int f();
+
+different.SameResLogicalExpr
+(C)
+An expression is always evaluated to true/false.
+
+
void test() {
+ int i = 0;
+ if (i != 0) {}; // warn
+}
+
+
+void test(int i) {
+ if (i == 0 && i == 1) {}; // warn
+}
+
+
+void test(int i) {
+ if (i < 0 || i >= 0) {}; // warn
+}
+
+
+
+
+
+different.OpPrecedenceAssignCmp
+(C, C++)
+Comparison operation has higher precedence then assignment. Boolean value is
+assigned to a variable of other type. Parenthesis may bee required around an
+assignment.
+
+
+int f();
+
+void test(int x, int y) {
bool b;
- int x, y;
if((b = x != y)) {} // ok
if((x = f() != y)) {} // warn
}
-
+
+
+
-
different.OpPrecedenceIifShift
- (C)
-?: has lower precedence then <<
-
+
+different.OpPrecedenceIifShift
+(C, C++)
+?: has lower precedence then <<.
+
Source: Stephen C. Dewhurst "C++ Gotchas: Avoiding Common Problems in Coding
+and Design", advise 15.
+
+
#include <iostream>
-void test() {
- int a;
+void test(int a) {
std::cout << a ? "a" : "b"; // warn
- a << a>7 ? 1 : 2; // warn
}
-
+
+
+void test(int a) {
+ a << a > 7 ? 1 : 2; // warn
+}
+
+
-
different.ObjectUnused
- (C++)
-The object was created but is not being used
-The exception object was created but is not being used. Did you mean
-'throw std::exception();'?
-
-#include <exception>
+
+different.ObjectUnused
+(C++)
+The object was created but is not being used.
+
+
struct S {
int x, y;
- S(int xx, int yy) : x(xx), y(yy) {
- }
+ S(int xx, int yy) : x(xx), y(yy) {}
S(int xx) {
S(xx, 0); // warn
}
};
+
+unsigned long long test(long long sll) {
unsigned long long ull = sll; // warn
- long sl;
- unsigned long ul = sl; // warn
- int si;
- unsigned int ui = si; // warn
- short ss;
- unsigned short us = ss; // warn
- signed char sc;
- unsigned char uc = sc; // warn
+ return ull;
+}
+
-The class has dynamically allocated data members but do not define a copy
-constructor/assignment operator
-
-class C { // warn
- int *p; // <-
+short test(long long sll) {
+ short ss = f();
+ return ss;
+}
+
+
+
+
+
+different.MissingCopyCtorAssignOp
+(C++)
+A class has dynamically allocated data members but do not define a copy
+constructor/assignment operator.
+
Source: Scott Meyers "Effective C++", item 11: Prevent exceptions from
+leaving destructors.
+
+
+class C {
+ int *p; // warn
public:
C() { p = new int; }
~C() { delete p; }
};
-
+
+
@@ -1477,57 +1864,73 @@
Name, Description
Example
Progress
-
WinAPI.CreateProcess
- (C)
-After calling CreateProcess(), ensure that process and thread handles get closed
-(* for the given example: examine data flow from pi, pi.hProcess and pi.hThread)
-
+
+WinAPI.CreateProcess
+(C)
+CreateProcess(): if the first parameter
+lpApplicationName is NULL then the executable name must be in the
+white space-delimited string pointed to by lpCommandLine.
+If the executable or path name has a space in it, there is a risk that a
+different executable could be run because of the way the function parses
+spaces.
+
+Buffer overrun while calling WideCharToMultiByte(). The size of
+the input buffer equals the number of characters in the Unicode string, while
+the size of the output buffer equals the number of bytes.
+
-Optimization: multiple calls to strlen for a given string in the given
-expression. It is more effective to hold strlen result in a temporary
-variable
-
+
+
+optimization.MultipleCallsStrlen
+(C)
+Optimization: multiple calls to strlen() for a string in an
+expression. It is more effective to hold a value returned
+from strlen() in a temporary variable.