2012-10-06 13:09:43 +08:00
< !DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
< html >
< head >
< title > List of potential checkers< / title >
< link type = "text/css" rel = "stylesheet" href = "content.css" >
< link type = "text/css" rel = "stylesheet" href = "menu.css" >
2014-05-19 23:04:55 +08:00
< script type = "text/javascript" src = "scripts/expandcollapse.js" > < / script >
2012-10-06 13:09:43 +08:00
< script type = "text/javascript" src = "scripts/menu.js" > < / script >
< / head >
2014-05-19 23:04:55 +08:00
< body onload = "initExpandCollapse()" >
2012-10-06 13:09:43 +08:00
< div id = "page" >
<!-- menu -->
<!-- #include virtual="menu.html.incl" -->
<!-- page content -->
< div id = "content" >
< h1 > List of potential checkers< / h1 >
2012-10-11 14:26:56 +08:00
< p > 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.< / p >
2012-10-07 01:14:39 +08:00
<!-- ========================= allocation/deallocation ======================= -->
2014-04-29 08:46:17 +08:00
< h3 > memory< / h3 >
2012-10-06 13:09:43 +08:00
< table class = "checkers" >
< col class = "namedescr" > < col class = "example" > < col class = "progress" >
< thead > < tr > < td > Name, Description< / td > < td > Example< / td > < td > Progress< / td > < / tr > < / thead >
2014-04-29 08:46:17 +08:00
< tr > < td > < div class = "namedescr expandable" > < span class = "name" >
memory.LeakEvalOrder< / span > < span class = "lang" >
(C, C++)< / span > < div class = "descr" >
Potential memory leaks caused by an undefined argument evaluation order.
< p > Source: < a href = "http://www.boost.org/doc/libs/1_49_0/libs/smart_ptr/shared_ptr.htm#BestPractices" >
boost docs: shared_ptr< / a > .< / p > < / div > < / div > < / td >
< td > < div class = "exampleContainer expandable" >
< div class = "example" > < pre >
void f(int, int);
int g(void *);
int h() __attribute__((noreturn));
2012-10-06 13:09:43 +08:00
void test() {
2014-04-29 08:46:17 +08:00
// 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.
2012-10-06 13:09:43 +08:00
}
2014-04-29 08:46:17 +08:00
< / pre > < / div >
< div class = "example" > < pre >
void f(int, int);
int g(int *);
int h() { throw 1; };
2012-10-06 13:09:43 +08:00
void test() {
2014-04-29 08:46:17 +08:00
// 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.
}
< / pre > < / div > < / div > < / td >
< td class = "aligned" > < / td > < / tr >
< tr > < td > < div class = "namedescr expandable" > < span class = "name" >
memory.DstBufferTooSmall< / span > < span class = "lang" >
(C, C++)< / span > < div class = "descr" >
Destination buffer passed to memory function is too small.
< br > Note: < span class = "name" > security.insecureAPI.strcpy< / span > currently warns
on usage of < code > strcpy< / code > and suggests to replace it.
< br > Note: < span class = "name" > alpha.unix.CStringChecker< / span > contains some similar checks.
< p > Source: < a href = "https://cwe.mitre.org/data/definitions/120.html" > CWE-120< / a > .< / p > < / div > < / div > < / td >
< td > < div class = "exampleContainer expandable" >
< div class = "example" > < pre >
2012-10-06 13:09:43 +08:00
void test() {
const char* s1 = "abc";
char *s2 = new char;
strcpy(s2, s1); // warn
2014-04-29 08:46:17 +08:00
}
< / pre > < / div >
< div class = "example" > < pre >
void test() {
2012-10-06 13:09:43 +08:00
int* p1 = new int[3];
int* p2 = new int;
memcpy(p2, p1, 3); // warn
}
2014-04-29 08:46:17 +08:00
< / pre > < / div > < / div > < / td >
< td class = "aligned" > < / td > < / tr >
2012-10-06 13:09:43 +08:00
2014-04-29 08:46:17 +08:00
< tr > < td > < div class = "namedescr expandable" > < span class = "name" >
memory.NegativeArraySize< / span > < span class = "lang" >
(C, C++)< / span > < div class = "descr" >
'n' is used to specify the buffer size may be negative.
< br > Note: possibly an enhancement to < span class = "name" >
alpha.security.MallocOverflow< / span > .
< p > Source: < a href = "http://cwe.mitre.org/data/definitions/20.html" > CWE-20,
Example 2< / a > .< / p > < / div > < / div > < / td >
< td > < div class = "exampleContainer expandable" >
< div class = "example" > < pre >
2012-10-06 13:09:43 +08:00
void test() {
int *p;
int n1 = -1;
p = new int[n1]; // warn
}
2014-04-29 08:46:17 +08:00
< / pre > < / div > < / div > < / td >
< td class = "aligned" > < / td > < / tr >
2012-10-06 13:09:43 +08:00
< / table >
2012-10-07 01:14:39 +08:00
<!-- ======================= constructors/destructors ====================== -->
2012-10-06 13:09:43 +08:00
< h3 > constructors/destructors< / h3 >
< table class = "checkers" >
< col class = "namedescr" > < col class = "example" > < col class = "progress" >
< thead > < tr > < td > Name, Description< / td > < td > Example< / td > < td > Progress< / td > < / tr > < / thead >
2014-04-29 08:46:17 +08:00
< tr > < td > < div class = "namedescr expandable" > < span class = "name" >
ctordtor.ExptInsideDtor< / span > < span class = "lang" >
(C++)< / span > < div class = "descr" >
It is dangerous to let an exception leave a destructor.
Using < code > try..catch< / code > solves the problem.
< p > Source: Scott Meyers "More Effective C++", item 11: Prevent exceptions from
leaving destructors.< / p > < / div > < / div > < / td >
< td > < div class = "exampleContainer expandable" >
< div class = "example" > < pre >
2012-10-06 13:09:43 +08:00
class A {
A() {}
~A() { throw 1; } // warn
};
2014-04-29 08:46:17 +08:00
< / pre > < / div >
< div class = "example" > < pre >
void f() throw(int);
2012-10-06 13:09:43 +08:00
class A {
A() {}
~A() { f(); } // warn
};
2014-04-29 08:46:17 +08:00
< / pre > < / div > < / div > < / td >
< td class = "aligned" > < / td > < / tr >
2012-10-06 13:09:43 +08:00
2014-04-29 08:46:17 +08:00
< tr > < td > < div class = "namedescr expandable" > < span class = "name" >
ctordtor.PlacementSelfCopy< / span > < span class = "lang" >
(C++11)< / span > < div class = "descr" >
For a placement copy or move, it is almost certainly an error if the
constructed object is also the object being copied from.< / div > < / div > < / td >
< td > < div class = "exampleContainer expandable" >
< div class = "example" > < pre >
2013-04-20 06:19:14 +08:00
class A {};
void test(A *dst, A *src) {
::new (dst) A(*dst); // warn (should be 'src')
}
2014-04-29 08:46:17 +08:00
< / pre > < / div > < / div > < / td >
< td class = "aligned" > <!-- rdar://problem/13688366 --> < / td > < / tr >
2013-04-20 06:19:14 +08:00
2012-10-06 13:09:43 +08:00
< / table >
2013-08-10 09:24:35 +08:00
<!-- =============================== va_list =============================== -->
< h3 > va_list< / h3 >
< table class = "checkers" >
< col class = "namedescr" > < col class = "example" > < col class = "progress" >
< thead > < tr > < td > Name, Description< / td > < td > Example< / td > < td > Progress< / td > < / tr > < / thead >
2014-04-29 08:46:17 +08:00
< tr > < td > < div class = "namedescr expandable" > < span class = "name" >
valist.Uninitialized< / span > < span class = "lang" >
(C)< / span > < div class = "descr" >
2013-08-10 09:24:35 +08:00
Calls to the < code > va_arg< / code > , < code > va_copy< / code > , or
< code > va_end< / code > macro must happen after calling < code > va_start< / code > and
2014-04-29 08:46:17 +08:00
before calling < code > va_end< / code > .< / div > < / div > < / td >
< td > < div class = "exampleContainer expandable" >
< div class = "example" > < pre >
2013-08-10 09:24:35 +08:00
#include < stdarg.h>
void test(int x, ...) {
va_list args;
int y = va_arg(args, int); // warn
2014-04-29 08:46:17 +08:00
}
< / pre > < / div >
< div class = "example" > < pre >
#include < stdarg.h>
void test(int x, ...) {
va_list args;
2013-08-10 09:24:35 +08:00
va_start(args, x);
2014-04-29 08:46:17 +08:00
va_end(args);
2013-08-10 09:24:35 +08:00
int z = va_arg(args, int); // warn
}
2014-04-29 08:46:17 +08:00
< / pre > < / div > < / div > < / td >
< td class = "aligned" > < a href = "http://llvm.org/bugs/show_bug.cgi?id=16812" >
PR16811< / a > < / td > < / tr >
2013-08-10 09:24:35 +08:00
2014-04-29 08:46:17 +08:00
< tr > < td > < div class = "namedescr expandable" > < span class = "name" >
valist.Unterminated< / span > < span class = "lang" >
(C)< / span > < div class = "descr" >
2013-08-10 09:24:35 +08:00
Every < code > va_start< / code > must be matched by a < code > va_end< / code > . A va_list
can only be ended once.
2014-04-29 08:46:17 +08:00
< i > This should be folded into the generalized "ownership checker"
described on the < a href = "open_projects.html" >
Open Projects< / a > page.< / i > < / div > < / div > < / td >
< td > < div class = "exampleContainer expandable" >
< div class = "example" > < pre >
2013-08-10 09:24:35 +08:00
#include < stdarg.h>
void test(int x, ...) {
va_list args;
va_start(args, x);
int y = x + va_arg(args, int);
2014-04-29 08:46:17 +08:00
} // warn: missing va_end
< / pre > < / div > < / div > < / td >
< td class = "aligned" > < a href = "http://llvm.org/bugs/show_bug.cgi?id=16812" >
PR16812< / a > < / td > < / tr >
2013-08-10 09:24:35 +08:00
< / table >
2012-10-07 01:14:39 +08:00
<!-- ============================== exceptions ============================= -->
2012-10-06 13:09:43 +08:00
< h3 > exceptions< / h3 >
< table class = "checkers" >
< col class = "namedescr" > < col class = "example" > < col class = "progress" >
< thead > < tr > < td > Name, Description< / td > < td > Example< / td > < td > Progress< / td > < / tr > < / thead >
2014-04-29 08:46:17 +08:00
< tr > < td > < div class = "namedescr expandable" > < span class = "name" >
exceptions.ThrowSpecButNotThrow< / span > < span class = "lang" >
(C++)< / span > < div class = "descr" >
Function declaration has a < code > throw(< i > type< / i > )< / code > specifier but the
function do not throw exceptions.< / div > < / div > < / td >
< td > < div class = "exampleContainer expandable" >
< div class = "example" > < pre >
void test() throw(int) {
} // warn
< / pre > < / div > < / div > < / td >
< td class = "aligned" > < / td > < / tr >
< tr > < td > < div class = "namedescr expandable" > < span class = "name" >
exceptions.NoThrowSpecButThrows< / span > < span class = "lang" >
(C++)< / span > < div class = "descr" >
An exception is throw from a function having a < code > throw()< / code >
specifier.< / div > < / div > < / td >
< td > < div class = "exampleContainer expandable" >
< div class = "example" > < pre >
void test() throw() {
2012-10-06 13:09:43 +08:00
throw(1); // warn
}
2014-04-29 08:46:17 +08:00
< / pre > < / div > < / div > < / td >
< td class = "aligned" > < / td > < / tr >
2012-10-06 13:09:43 +08:00
2014-04-29 08:46:17 +08:00
< tr > < td > < div class = "namedescr expandable" > < span class = "name" >
exceptions.ThrownTypeDiffersSpec< / span > < span class = "lang" >
(C++)< / span > < div class = "descr" >
The type of a thrown exception differs from those specified in
a < code > throw(< i > type< / i > )< / code > specifier.< / div > < / div > < / td >
< td > < div class = "exampleContainer expandable" >
< div class = "example" > < pre >
2012-10-06 13:09:43 +08:00
struct S{};
2014-04-29 08:46:17 +08:00
void test() throw(int) {
2012-10-06 13:09:43 +08:00
S s;
throw (s); // warn
}
2014-04-29 08:46:17 +08:00
< / pre > < / div > < / div > < / td >
< td class = "aligned" > < / td > < / tr >
2012-10-06 13:09:43 +08:00
< / table >
2012-10-07 01:14:39 +08:00
<!-- ========================= smart pointers ============================== -->
2012-10-06 13:09:43 +08:00
< h3 > smart pointers< / h3 >
< table class = "checkers" >
< col class = "namedescr" > < col class = "example" > < col class = "progress" >
< thead > < tr > < td > Name, Description< / td > < td > Example< / td > < td > Progress< / td > < / tr > < / thead >
2014-04-29 08:46:17 +08:00
< tr > < td > < div class = "namedescr expandable" > < span class = "name" >
smartptr.SmartPtrInit< / span > < span class = "lang" >
(C++)< / span > < div class = "descr" >
C++03: < code > auto_ptr< / code > should store a pointer to an object obtained via
new as allocated memory will be cleaned using < code > delete< / code > .< br >
C++11: one should use < code > unique_ptr< < i > type< / i > []> < / code > to keep a
pointer to memory allocated by < code > new[]< / code > .< br >
C++11: to keep a pointer to memory allocated by < code > new[]< / code > in
a < code > shared_ptr< / code > one should use a custom deleter that calls < code >
delete[].< / code > .
< p > Source: C++03 20.4.5p1; C++11 < code > auto_ptr< / code > is deprecated (D.10).< / p > < / div > < / div > < / td >
< td > < div class = "exampleContainer expandable" >
< div class = "example" > < pre >
2012-10-06 13:09:43 +08:00
#include < stdlib.h>
#include < memory>
void test() {
std::auto_ptr< int> p1(new int); // Ok
std::auto_ptr< int> p2(new int[3]); // warn
}
2014-04-29 08:46:17 +08:00
< / pre > < / div >
< div class = "example" > < pre >
#include < stdlib.h>
#include < memory>
void test() {
std::auto_ptr< int> p((int *)malloc(sizeof(int))); // warn
}
< / pre > < / div > < / div > < / td >
< td class = "aligned" > < / td > < / tr >
2012-10-06 13:09:43 +08:00
< / table >
2013-08-20 00:27:37 +08:00
<!-- ============================== dead code ============================== -->
< h3 > dead code< / h3 >
< table class = "checkers" >
< col class = "namedescr" > < col class = "example" > < col class = "progress" >
< thead > < tr > < td > Name, Description< / td > < td > Example< / td > < td > Progress< / td > < / tr > < / thead >
2014-04-29 08:46:17 +08:00
< tr > < td > < div class = "namedescr expandable" > < span class = "name" >
deadcode.UnmodifiedVariable< / span > < span class = "lang" >
(C, C++)< / span > < div class = "descr" >
A variable is never modified but was not declared const and is not a
reference.< br > < br > < i > (opt-in checker)< / i > < / div > < / div > < / td >
< td > < div class = "exampleContainer expandable" >
< div class = "example" > < pre >
2013-08-20 00:27:37 +08:00
extern int computeDelta();
2014-04-29 08:46:17 +08:00
int test(bool cond) {
2013-08-20 00:27:37 +08:00
int i = 0;
if (cond) {
const int delta = computeDelta();
2014-04-29 08:46:17 +08:00
// warn: forgot to modify 'i'
2013-08-20 00:27:37 +08:00
}
return i;
}
2014-04-29 08:46:17 +08:00
< / pre > < / div > < / div > < / td >
< td class = "aligned" > < a href = "http://llvm.org/bugs/show_bug.cgi?id=16890" > PR16890< / a > < / td > < / tr >
< tr > < td > < div class = "namedescr expandable" > < span class = "name" >
deadcode.IdempotentOperations< / span > < span class = "lang" >
(C)< / span > < div class = "descr" >
Warn about idempotent operations.< / div > < / div > < / td >
< td > < div class = "exampleContainer expandable" >
< div class = "example" > < pre >
void test() {
int x = 7;
x = x; // warn: value is always the same
}
< / pre > < / div >
< div class = "example" > < pre >
void test() {
int x = 7;
x /= x; // warn: value is always 1
}
< / pre > < / div >
< div class = "example" > < pre >
void test() {
int x = 7, one = 1;
x *= one; // warn: right op is always 1
}
< / pre > < / div >
< div class = "example" > < pre >
void test() {
int x = 7, zero = 0;
x = x - zero;
// warn: the right operand to '-' is always 0
}
< / pre > < / div > < / div > < / td >
< td class = "aligned" > removed from alpha.deadcode.* at r198476< / td > < / tr >
2013-08-20 00:27:37 +08:00
< / table >
2014-04-29 08:46:17 +08:00
<!-- ================================ POSIX ================================ -->
2014-04-05 14:10:28 +08:00
< h3 > POSIX< / h3 >
< table class = "checkers" >
< col class = "namedescr" > < col class = "example" > < col class = "progress" >
< thead > < tr > < td > Name, Description< / td > < td > Example< / td > < td > Progress< / td > < / tr > < / thead >
2014-04-29 08:46:17 +08:00
< tr > < td > < div class = "namedescr expandable" > < span class = "name" >
posix.Errno< / span > < span class = "lang" >
(C)< / span > < div class = "descr" >
Record that < code > errno< / code > is non-zero when certain functions
fail.< / div > < / div > < / td >
< td > < div class = "exampleContainer expandable" >
< div class = "example" > < pre >
2014-04-05 14:10:28 +08:00
#include < stdlib.h>
int readWrapper(int fd, int *count) {
int lcount = read(fd, globalBuf, sizeof(globalBuf));
2014-04-29 08:46:17 +08:00
if (lcount < 0 )
2014-04-05 14:10:28 +08:00
return errno;
*count = lcount;
return 0;
}
void use(int fd) {
int count;
2014-04-08 00:36:15 +08:00
if (!readWrapper(fd, & count))
2014-04-05 14:10:28 +08:00
print("%d", count); // should not warn
}
2014-04-29 08:46:17 +08:00
< / pre > < / div > < / div > < / td >
< td class = "aligned" > < a href = "http://llvm.org/bugs/show_bug.cgi?id=18701" > PR18701< / a > < / td > < / tr >
2014-04-05 14:10:28 +08:00
< / table >
2012-10-07 01:14:39 +08:00
<!-- ========================= undefined behavior ========================== -->
2012-10-06 13:09:43 +08:00
< h3 > undefined behavior< / h3 >
< table class = "checkers" >
< col class = "namedescr" > < col class = "example" > < col class = "progress" >
< thead > < tr > < td > Name, Description< / td > < td > Example< / td > < td > Progress< / td > < / tr > < / thead >
2014-04-29 08:46:17 +08:00
< tr > < td > < div class = "namedescr expandable" > < span class = "name" >
undefbehavior.ExitInDtor< / span > < span class = "lang" >
(C++)< / span > < div class = "descr" >
Undefined behavior: < code > std::exit()< / code > is called to end the program during
the destruction of an object with static storage duration.
< p > Source: C++11 3.6.1p4.< / p > < / div > < / div > < / td >
< td > < div class = "exampleContainer expandable" >
< div class = "example" > < pre >
2012-10-06 13:09:43 +08:00
#include < cstdlib>
class A {
public:
~A() {
std::exit(1); // warn
}
};
2014-04-29 08:46:17 +08:00
< / pre > < / div > < / div > < / td >
< td class = "aligned" > < / td > < / tr >
2012-10-06 13:09:43 +08:00
2014-04-29 08:46:17 +08:00
< tr > < td > < div class = "namedescr expandable" > < span class = "name" >
undefbehavior.LocalStaticDestroyed< / span > < span class = "lang" >
(C++)< / span > < div class = "descr" >
2012-10-06 13:09:43 +08:00
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
2014-04-29 08:46:17 +08:00
static local object.
< p > Source: C++11 3.6.3p2.< / p > < / div > < / div > < / td >
< td > < div class = "exampleContainer expandable" >
< div class = "example" > < pre >
2012-10-06 13:09:43 +08:00
void f();
class A {
public:
~A() {
f(); // warn
}
};
class B {};
A a;
void f() {
2014-04-29 08:46:17 +08:00
static B b;
2012-10-06 13:09:43 +08:00
}
2014-04-29 08:46:17 +08:00
< / pre > < / div > < / div > < / td >
< td class = "aligned" > < / td > < / tr >
2012-10-06 13:09:43 +08:00
2014-04-29 08:46:17 +08:00
< tr > < td > < div class = "namedescr expandable" > < span class = "name" >
undefbehavior.ZeroAllocDereference< / span > < span class = "lang" >
(C, C++)< / span > < div class = "descr" >
2012-10-06 13:09:43 +08:00
The effect of dereferencing a pointer returned as a request for zero size is
2014-04-29 08:46:17 +08:00
undefined.< br >
Note: possibly an enhancement to < span class = "name" >
unix.Malloc< / span > .
< p > Source: C++03 3.7.3.1p2; C++11 3.7.4.1p2.< / p > < / div > < / div > < / td >
< td > < div class = "exampleContainer expandable" >
< div class = "example" > < pre >
2014-10-30 23:16:26 +08:00
#include < memory>
void test() {
int *p = (int *)malloc(0);
*p = 1; // warn
free(p);
}
2014-04-29 08:46:17 +08:00
< / pre > < / div >
< div class = "example" > < pre >
2014-10-30 23:16:26 +08:00
void f(int);
void test() {
int *p = new int[0];
f(*p); // warn
delete[] p;
}
2014-04-29 08:46:17 +08:00
< / pre > < / div > < / div > < / td >
< td class = "aligned" > < / td > < / tr >
2014-05-19 23:04:55 +08:00
< tr > < td > < div class = "namedescr expandable" > < span class = "name" >
2014-04-29 08:46:17 +08:00
undefbehavior.DeadReferenced< / span > < span class = "lang" >
(C++)< / span > < div class = "descr" >
2014-05-19 23:04:55 +08:00
Undefined behavior: the following usage of the pointer to the object whose
lifetime has ended can result in undefined behavior:< br >
The object will be or was of a class type with a non-trivial destructor and
< ul > < li > the pointer is used as the operand of a delete-expression< / li > < / ul >
The object will be or was of a non-POD class type (C++11: any class type) and
< ul > < li > the pointer is used to access a non-static data member or call a
non-static member function of the object< / li >
< li > the pointer is implicitly converted to a pointer to a base class
type< / li >
< li > the pointer is used as the operand of a < code > static_cast< / code > (except
when the conversion is to < code > void*< / code > , or to < code > void*< / code > and
subsequently to < code > char*< / code > , or < code > unsigned char*< / code > )< / li >
< li > the pointer is used as the operand of a < code > dynamic_cast< / code > < / li > < / ul >
2014-04-29 08:46:17 +08:00
< p > Source: C++03 3.8p5, p7; C++11 3.8p5, p7.< / p > < / div > < / div > < / td >
< td > < div class = "exampleContainer expandable" >
< div class = "example" > < pre >
2012-10-06 13:09:43 +08:00
#include < new>
class A {
public:
2014-05-19 23:04:55 +08:00
~A();
2012-10-06 13:09:43 +08:00
};
2014-04-29 08:46:17 +08:00
class B : public A {};
2014-05-19 23:04:55 +08:00
void test() {
A *a = new A;
new(a) B;
delete a; // warn
2014-04-29 08:46:17 +08:00
}
< / pre > < / div >
< div class = "example" > < pre >
#include < new>
class A {
public:
2014-05-19 23:04:55 +08:00
~A();
2012-10-06 13:09:43 +08:00
};
2014-05-19 23:04:55 +08:00
class B {};
2014-04-29 08:46:17 +08:00
2012-10-06 13:09:43 +08:00
void test() {
2014-05-19 23:04:55 +08:00
A *a = new A;
new(a) B;
a->~A();
2014-04-29 08:46:17 +08:00
}
< / pre > < / div >
< div class = "example" > < pre >
#include < new>
2014-05-19 23:04:55 +08:00
class A {
public:
~A();
};
2014-04-29 08:46:17 +08:00
class B : public A {};
2014-05-19 23:04:55 +08:00
class C {};
2014-04-29 08:46:17 +08:00
2014-05-19 23:04:55 +08:00
void f(A*);
2014-04-29 08:46:17 +08:00
2014-05-19 23:04:55 +08:00
void test() {
2014-04-29 08:46:17 +08:00
B *b = new B;
2014-05-19 23:04:55 +08:00
new(b) C;
f(b); // warn
2012-10-06 13:09:43 +08:00
}
2014-04-29 08:46:17 +08:00
< / pre > < / div >
< div class = "example" > < pre >
#include < new>
2012-10-06 13:09:43 +08:00
2014-05-19 23:04:55 +08:00
class A {
public:
~A();
};
2014-04-29 08:46:17 +08:00
class B : public A {};
2014-05-19 23:04:55 +08:00
class C {};
2014-04-29 08:46:17 +08:00
2014-05-19 23:04:55 +08:00
A* test() {
2014-04-29 08:46:17 +08:00
B *b = new B;
2014-05-19 23:04:55 +08:00
new(b) C;
return static_cast< A*> (b); // warn
2014-04-29 08:46:17 +08:00
}
< / pre > < / div >
< div class = "example" > < pre >
2012-10-06 13:09:43 +08:00
#include < new>
class A {
public:
2014-05-19 23:04:55 +08:00
~A();
2012-10-06 13:09:43 +08:00
};
2014-05-19 23:04:55 +08:00
class B : public A {};
2012-10-06 13:09:43 +08:00
2014-05-19 23:04:55 +08:00
class C {};
A* test() {
B *b = new B;
new(b) C;
return dynamic_cast< A*> (b); // warn
2012-10-06 13:09:43 +08:00
}
2014-04-29 08:46:17 +08:00
< / pre > < / div > < / div > < / td >
2014-05-19 23:04:55 +08:00
< td class = "aligned" > < / td > < / tr >
2012-10-06 13:09:43 +08:00
2014-04-29 08:46:17 +08:00
< tr > < td > < div class = "namedescr expandable" > < span class = "name" >
undefbehavior.ObjLocChanges< / span > < span class = "lang" >
(C++)< / span > < div class = "descr" >
2012-10-06 13:09:43 +08:00
Undefined behavior: the program must ensure that an object occupies the same
2014-04-29 08:46:17 +08:00
storage location when the implicit or explicit destructor call takes place.
< p > Source: C++11 3.8p8.< / p > < / div > < / div > < / td >
< td > < div class = "exampleContainer expandable" >
< div class = "example" > < pre >
2012-10-06 13:09:43 +08:00
#include < new>
2014-04-29 08:46:17 +08:00
class A {};
class B {
public:
2012-10-06 13:09:43 +08:00
~B();
};
void test() {
2014-04-29 08:46:17 +08:00
B b;
new (& b) A;
2012-10-06 13:09:43 +08:00
} // warn
2014-04-29 08:46:17 +08:00
< / pre > < / div >
< div class = "example" > < pre >
#include < new>
class A {};
class B {
public:
~B();
};
void test() {
B *b = new B;
new (b) A;
delete b; // warn
}
< / pre > < / div > < / div > < / td >
< td class = "aligned" > < / td > < / tr >
2012-10-06 13:09:43 +08:00
2014-04-29 08:46:17 +08:00
< tr > < td > < div class = "namedescr expandable" > < span class = "name" >
undefbehavior.ExprEvalOrderUndef< / span > < span class = "lang" >
(C, C++03)< / span > < div class = "descr" >
2012-10-06 13:09:43 +08:00
Undefined behavior: a scalar object shall have its stored value modified at
2014-04-29 08:46:17 +08:00
most once by the evaluation of an expression.< br >
Note: most cases are currently handled by the Clang core (search for 'multiple
unsequenced modifications' warning in Clang tests).
< p > Source: C++03 5p4.< / p > < / div > < / div > < / td >
< td > < div class = "exampleContainer expandable" >
< div class = "example" > < pre >
int test () {
2012-10-06 13:09:43 +08:00
int i = 0;
i = ++i + 1; // warn
2014-04-29 08:46:17 +08:00
return i;
2012-10-06 13:09:43 +08:00
}
2014-04-29 08:46:17 +08:00
< / pre > < / div > < / div > < / td >
< td class = "aligned" > < / td > < / tr >
2012-10-06 13:09:43 +08:00
2014-04-29 08:46:17 +08:00
< tr > < td > < div class = "namedescr expandable" > < span class = "name" >
undefbehavior.StaticInitReentered< / span > < span class = "lang" >
(C++)< / span > < div class = "descr" >
2012-10-06 13:09:43 +08:00
Undefined behavior: static declaration is re-entered while the object is being
2014-04-29 08:46:17 +08:00
initialized.
< p > Source: C++11 6.7p4.< / p > < / div > < / div > < / td >
< td > < div class = "exampleContainer expandable" >
< div class = "example" > < pre >
2012-10-06 13:09:43 +08:00
int test(int i) {
2014-04-29 08:46:17 +08:00
static int s = test(2 * i); // warn
return i + 1;
2012-10-06 13:09:43 +08:00
}
2014-04-29 08:46:17 +08:00
< / pre > < / div > < / div > < / td >
< td class = "aligned" > < / td > < / tr >
2012-10-06 13:09:43 +08:00
2014-04-29 08:46:17 +08:00
< tr > < td > < div class = "namedescr expandable" > < span class = "name" >
undefbehavior.ConstModified< / span > < span class = "lang" >
(C, C++)< / span > < div class = "descr" >
Undefined behavior: const object is being modified.
< p > Source: C++03 7.1.5.1p4, C++11 7.1.6.1p4.< / p > < / div > < / div > < / td >
< td > < div class = "exampleContainer expandable" >
< div class = "example" > < pre >
void test() {
const int *cp = new const int (0);
int *p = const_cast< int *> (cp);
*p = 1; // warn
delete p;
}
< / pre > < / div >
< div class = "example" > < pre >
class C {
2012-10-06 13:09:43 +08:00
public :
2014-04-29 08:46:17 +08:00
int i;
C();
2012-10-06 13:09:43 +08:00
};
void test() {
2014-04-29 08:46:17 +08:00
const C cb;
2012-10-06 13:09:43 +08:00
2014-04-29 08:46:17 +08:00
C* cp = const_cast< C *> (&cb);
cp-> i = 1; // warn
2012-10-06 13:09:43 +08:00
}
2014-04-29 08:46:17 +08:00
< / pre > < / div > < / div > < / td >
< td class = "aligned" > < / td > < / tr >
2012-10-06 13:09:43 +08:00
2014-04-29 08:46:17 +08:00
< tr > < td > < div class = "namedescr expandable" > < span class = "name" >
undefbehavior.DeadDestructed< / span > < span class = "lang" >
(C++)< / span > < div class = "descr" >
2012-10-06 13:09:43 +08:00
Undefined behavior: the destructor is invoked for an object whose lifetime
2014-04-29 08:46:17 +08:00
has ended.
< p > Source: C++11 12.4p14.< / p > < / div > < / div > < / td >
< td > < div class = "exampleContainer expandable" >
< div class = "example" > < pre >
2012-10-06 13:09:43 +08:00
class A {
public:
2014-04-29 08:46:17 +08:00
void f();
A();
~A();
2012-10-06 13:09:43 +08:00
};
void test() {
A a;
a.~A();
} // warn
2014-04-29 08:46:17 +08:00
< / pre > < / div > < / div > < / td >
< td class = "aligned" > < / td > < / tr >
2012-10-06 13:09:43 +08:00
2014-04-29 08:46:17 +08:00
< tr > < td > < div class = "namedescr expandable" > < span class = "name" >
undefbehavior.MethodCallBeforeBaseInit< / span > < span class = "lang" >
(C++)< / span > < div class = "descr" >
Undefined behavior: calls member function but base not yet initialized.
< p > Source: C++03 12.6.2p8; C++11 12.6.2p13.< / p > < / div > < / div > < / td >
< td > < div class = "exampleContainer expandable" >
< div class = "example" > < pre >
2012-10-06 13:09:43 +08:00
class A {
public :
2014-04-29 08:46:17 +08:00
A(int);
2012-10-06 13:09:43 +08:00
};
2014-04-29 08:46:17 +08:00
2012-10-06 13:09:43 +08:00
class B : public A {
public :
int f();
B() : A(f()) {} // warn
};
2014-04-29 08:46:17 +08:00
< / pre > < / div > < / div > < / td >
< td class = "aligned" > < / td > < / tr >
2012-10-06 13:09:43 +08:00
2014-04-29 08:46:17 +08:00
< tr > < td > < div class = "namedescr expandable" > < span class = "name" >
undefbehavior.MemberOrBaseRefBeforeCtor< / span > < span class = "lang" >
(C++)< / span > < div class = "descr" >
2012-10-06 13:09:43 +08:00
C++ Undefined behavior: non-static member or base class of non-POD class type
2014-04-29 08:46:17 +08:00
is referred before constructor begins execution.< br >
2012-10-06 13:09:43 +08:00
C++11 Undefined behavior: non-static member or base class of a class with a
2014-04-29 08:46:17 +08:00
non-trivial constructor is referred before constructor begins execution.
< p > Source: C++03 12.7p1; C++11 12.7p1.< / p > < / div > < / div > < / td >
< td > < div class = "exampleContainer expandable" >
< div class = "example" > < pre >
struct non_POD {
int i;
non_POD();
};
extern non_POD non_pod;
int *p = & non_pod.i; // warn
< / pre > < / div >
< div class = "example" > < pre >
2012-10-06 13:09:43 +08:00
struct POD {
int i;
};
2014-04-29 08:46:17 +08:00
struct non_POD : public POD {
2012-10-06 13:09:43 +08:00
POD pod;
};
extern non_POD non_pod;
2014-04-29 08:46:17 +08:00
int *p = & non_pod.pod.i; // warn
< / pre > < / div >
< div class = "example" > < pre >
struct POD {
2012-10-06 13:09:43 +08:00
int i;
};
2014-04-29 08:46:17 +08:00
struct non_POD : public POD {};
2012-10-06 13:09:43 +08:00
2014-04-29 08:46:17 +08:00
extern non_POD non_pod;
2012-10-06 13:09:43 +08:00
2014-04-29 08:46:17 +08:00
POD *p = & non_pod; // warn
< / pre > < / div >
< div class = "example" > < pre >
struct non_POD {
int i;
non_POD();
};
2012-10-06 13:09:43 +08:00
struct S {
int *k;
2014-04-29 08:46:17 +08:00
non_POD non_pod;
S() : k(& non_pod.i) {} // warn
2012-10-06 13:09:43 +08:00
};
2014-04-29 08:46:17 +08:00
< / pre > < / div > < / div > < / td >
< td class = "aligned" > < / td > < / tr >
2012-10-06 13:09:43 +08:00
2014-04-29 08:46:17 +08:00
< tr > < td > < div class = "namedescr expandable" > < span class = "name" >
undefbehavior.MemberRefAfterDtor< / span > < span class = "lang" >
(C++)< / span > < div class = "descr" >
2012-10-06 13:09:43 +08:00
C++03: Undefined behavior: non-static member of non-POD class type is referred
2014-04-29 08:46:17 +08:00
after destructor ends execution.< br >
2012-10-06 13:09:43 +08:00
C++11: Undefined behavior: non-static member of a class with a non-trivial
2014-04-29 08:46:17 +08:00
destructor is referred after destructor ends execution.
< p > Source: C++03 12.7p1; C++11 12.7p1.< / p > < / div > < / div > < / td >
< td > < div class = "exampleContainer expandable" >
< div class = "example" > < pre >
class C {
public:
C();
void f();
2012-10-06 13:09:43 +08:00
};
void test() {
2014-04-29 08:46:17 +08:00
C *c = new C();
c-> ~C();
c-> f(); // warn
2012-10-06 13:09:43 +08:00
}
2014-04-29 08:46:17 +08:00
< / pre > < / div > < / div > < / td >
< td class = "aligned" > < / td > < / tr >
2012-10-06 13:09:43 +08:00
2014-04-29 08:46:17 +08:00
< tr > < td > < div class = "namedescr expandable" > < span class = "name" >
undefbehavior.CtorForeignCall< / span > < span class = "lang" >
(C++)< / span > < div class = "descr" >
2012-10-06 13:09:43 +08:00
Undefined behavior: call to virtual function of an object under construction
2014-04-29 08:46:17 +08:00
whose type is neither the constructors own class or one of its bases.
< p > Source: C++11 12.7p4.< / p > < / div > < / div > < / td >
< td > < div class = "exampleContainer expandable" >
< div class = "example" > < pre >
2012-10-06 13:09:43 +08:00
class A {
public:
virtual void f() {};
};
class B {
public:
B(A* a) { a-> f(); } // warn
};
class C : public A, B {
public:
C() : B((A*)this) {}
};
2014-04-29 08:46:17 +08:00
< / pre > < / div > < / div > < / td >
< td class = "aligned" > < / td > < / tr >
2012-10-06 13:09:43 +08:00
2014-04-29 08:46:17 +08:00
< tr > < td > < div class = "namedescr expandable" > < span class = "name" >
undefbehavior.CtorForeignTypeid< / span > < span class = "lang" >
(C++)< / span > < div class = "descr" >
Undefined behavior: the operand of < code > typeid< / code > is an object under
2012-10-06 13:09:43 +08:00
construction whose type is neither the constructors own class or one of its
2014-04-29 08:46:17 +08:00
bases.
< p > Source: C++11 12.7p5.< / p > < / div > < / div > < / td >
< td > < div class = "exampleContainer expandable" >
< div class = "example" > < pre >
#include < typeinfo>
class A {};
class B {
public:
B(A* a) {
(void)typeid(*a); // warn
}
};
class C : public A, B {
public:
C() : B((A*)this) {}
};
< / pre > < / div > < / div > < / td >
< td class = "aligned" > < / td > < / tr >
< tr > < td > < div class = "namedescr expandable" > < span class = "name" >
undefbehavior.CtorForeignCast< / span > < span class = "lang" >
(C++)< / span > < div class = "descr" >
Undefined behavior: the operand of < code > dynamic_cast< / code > is an object under
construction whose type is neither the constructors own class or one of its
bases.
< p > Source: C++11 12.7p6.< / p > < / div > < / div > < / td >
< td > < div class = "exampleContainer expandable" >
< div class = "example" > < pre >
2012-10-06 13:09:43 +08:00
#include < typeinfo>
class A {
public:
virtual void f() {};
};
class B {
public:
B(A* a) {
2014-04-29 08:46:17 +08:00
(void)dynamic_cast< B*> (a); //warn
2012-10-06 13:09:43 +08:00
}
};
class C : public A, B {
public:
C() : B((A*)this) {}
};
2014-04-29 08:46:17 +08:00
< / pre > < / div > < / div > < / td >
< td class = "aligned" > < / td > < / tr >
2012-10-06 13:09:43 +08:00
2014-04-29 08:46:17 +08:00
< tr > < td > < div class = "namedescr expandable" > < span class = "name" >
undefbehavior.MemberOrBaseRefInCatch< / span > < span class = "lang" >
(C++)< / span > < div class = "descr" >
2012-10-06 13:09:43 +08:00
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
2014-04-29 08:46:17 +08:00
for that object results in undefined behavior.
< p > Source: C++11 15.3p10.< / p > < / div > < / div > < / td >
< td > < div class = "exampleContainer expandable" >
< div class = "example" > < pre >
void f() { throw 1; }
2012-10-06 13:09:43 +08:00
class C {
int i;
public :
C()
2014-04-29 08:46:17 +08:00
try {
f();
}
catch (...) {
i=2; // warn
}
};
< / pre > < / div >
< div class = "example" > < pre >
void f() { throw 1; }
class Base {
public:
int i;
};
class C: public Base {
public :
~C() try {
f();
}
catch (...) {
2012-10-06 13:09:43 +08:00
i=2; // warn
}
};
2014-04-29 08:46:17 +08:00
< / pre > < / div > < / div > < / td >
< td class = "aligned" > < / td > < / tr >
2012-10-06 13:09:43 +08:00
2014-04-29 08:46:17 +08:00
< tr > < td > < div class = "namedescr expandable" > < span class = "name" >
undefbehavior.ReturnAtCatchEnd< / span > < span class = "lang" >
(C++)< / span > < div class = "descr" >
2012-10-06 13:09:43 +08:00
Undefined behavior: a function returns when control reaches the end of a
2014-04-29 08:46:17 +08:00
handler. This results in undefined behavior in a value-returning function.
< p > Source: C++11 15.3p10.< / p > < / div > < / div > < / td >
< td > < div class = "exampleContainer expandable" >
< div class = "example" > < pre >
void f() { throw 1; }
2012-10-06 13:09:43 +08:00
int test() try {
2014-04-29 08:46:17 +08:00
f();
return 1;
2012-10-06 13:09:43 +08:00
}
catch(int) {
} // warn
2014-04-29 08:46:17 +08:00
< / pre > < / div > < / div > < / td >
< td class = "aligned" > < / td > < / tr >
< tr > < td > < div class = "namedescr expandable" > < span class = "name" >
undefbehavior.AutoptrsOwnSameObj< / span > < span class = "lang" >
(C++03)< / span > < div class = "descr" >
Undefined behavior: if more than one < code > auto_ptr< / code > owns the same object
at the same time the behavior of the program is undefined.
< p > Source: C++03 20.4.5p3; C++11 < code > auto_ptr< / code > is deprecated
(D.10).< / p > < / div > < / div > < / td >
< td > < div class = "exampleContainer expandable" >
< div class = "example" > < pre >
2012-10-06 13:09:43 +08:00
#include < memory>
void test() {
int *data = new int;
std::auto_ptr< int> p(data);
std::auto_ptr< int> q(data); // warn
}
2014-04-29 08:46:17 +08:00
< / pre > < / div > < / div > < / td >
< td class = "aligned" > < / td > < / tr >
< tr > < td > < div class = "namedescr expandable" > < span class = "name" >
undefbehavior.BasicStringOutOfBound< / span > < span class = "lang" >
(C++03)< / span > < div class = "descr" >
Undefined behavior: out-of-bound < code > basic_string< / code > access/modification.
< br > Note: possibly an enhancement to < span class = "name" >
alpha.security.ArrayBoundV2< / span > .
< p > Source: C++03 21.3.4p1; C++11 behavior is defined
(21.4.5p2).< / p > < / div > < / div > < / td >
< td > < div class = "exampleContainer expandable" >
< div class = "example" > < pre >
#include < string>
2012-10-06 13:09:43 +08:00
void test() {
std::basic_string< char> s;
char c = s[10]; // warn
}
2014-04-29 08:46:17 +08:00
< / pre > < / div >
< div class = "example" > < pre >
#include < string>
2012-10-06 13:09:43 +08:00
void test() {
std::basic_string< char> s;
s[10] = 0; // warn
}
2014-04-29 08:46:17 +08:00
< / pre > < / div > < / div > < / td >
< td class = "aligned" > < / td > < / tr >
2012-10-06 13:09:43 +08:00
2014-04-29 08:46:17 +08:00
< tr > < td > < div class = "namedescr expandable" > < span class = "name" >
undefbehavior.EosDereference< / span > < span class = "lang" >
(C++)< / span > < div class = "descr" >
Undefined behavior: the result of < code > operator*()< / code > on an end of a
stream is undefined.
< p > Source: C++03 24.5.3p2; C++11 24.6.3p2.< / p > < / div > < / div > < / td >
< td > < div class = "exampleContainer expandable" >
< div class = "example" > < pre >
2012-10-06 13:09:43 +08:00
#include < vector>
2014-04-29 08:46:17 +08:00
int test() {
2012-10-06 13:09:43 +08:00
std::vector< int> v;
2014-04-29 08:46:17 +08:00
return *v.end(); // warn
2012-10-06 13:09:43 +08:00
}
2014-04-29 08:46:17 +08:00
< / pre > < / div > < / div > < / td >
< td class = "aligned" > < / td > < / tr >
2012-10-06 13:09:43 +08:00
2014-04-29 08:46:17 +08:00
< tr > < td > < div class = "namedescr expandable" > < span class = "name" >
undefbehavior.QsortNonPODNonTrivial< / span > < span class = "lang" >
(C++)< / span > < div class = "descr" >
2012-10-06 13:09:43 +08:00
C++03: Undefined behavior: the objects in the array passed to qsort are of
2014-04-29 08:46:17 +08:00
non-POD type.< br >
2012-10-06 13:09:43 +08:00
C++11: Undefined behavior: the objects in the array passed to qsort are of
2014-04-29 08:46:17 +08:00
non-trivial type.
< p > Source: C++03 25.4p4; C++11 25.5p4.< / p > < / div > < / div > < / td >
< td > < div class = "exampleContainer expandable" >
< div class = "example" > < pre >
2012-10-06 13:09:43 +08:00
// C++03
#include < cstdlib>
2014-04-29 08:46:17 +08:00
2012-10-06 13:09:43 +08:00
struct non_POD {
2014-04-29 08:46:17 +08:00
non_POD();
2012-10-06 13:09:43 +08:00
};
2014-04-29 08:46:17 +08:00
non_POD values[] = { non_POD(), non_POD() };
2012-10-06 13:09:43 +08:00
2014-04-29 08:46:17 +08:00
int compare(const void *a, const void *b);
2012-10-06 13:09:43 +08:00
void test() {
2014-04-29 08:46:17 +08:00
qsort(values, 2, sizeof(non_POD), compare); // warn
2012-10-06 13:09:43 +08:00
}
2014-04-29 08:46:17 +08:00
< / pre > < / div >
< div class = "example" > < pre >
2012-10-06 13:09:43 +08:00
// C++11
#include < cstdlib>
struct S {};
struct trivial_non_POD : public S {
int i;
};
struct non_trivial {
int i;
2014-04-29 08:46:17 +08:00
non_trivial();
2012-10-06 13:09:43 +08:00
};
trivial_non_POD tnp[2];
non_trivial nt[2];
2014-04-29 08:46:17 +08:00
int compare1(const void *a, const void *b);
2012-10-06 13:09:43 +08:00
2014-04-29 08:46:17 +08:00
int compare2(const void *a, const void *b);
2012-10-06 13:09:43 +08:00
void test() {
2014-04-29 08:46:17 +08:00
qsort(tnp, 2, sizeof(trivial_non_POD), compare1); // ok
qsort(nt, 2, sizeof(non_trivial), compare2); // warn
2012-10-06 13:09:43 +08:00
}
2014-04-29 08:46:17 +08:00
< / pre > < / div > < / div > < / td >
< td class = "aligned" > < / td > < / tr >
2012-10-06 13:09:43 +08:00
2014-04-29 08:46:17 +08:00
< tr > < td > < div class = "namedescr expandable" > < span class = "name" >
undefbehavior.ThrowWhileCopy< / span > < span class = "lang" >
(C++)< / span > < div class = "descr" >
2012-10-06 13:09:43 +08:00
Undefined behavior: copy constructor/assignment operator can throw an exception.
2014-04-29 08:46:17 +08:00
The effects are undefined if an exception is thrown.< / div > < / div > < / td >
< td > < div class = "exampleContainer expandable" >
< div class = "example" > < pre >
class C {
public:
2012-10-06 13:09:43 +08:00
int i, j;
2014-04-29 08:46:17 +08:00
C (const C & c) {
i = c.i;
2012-10-06 13:09:43 +08:00
throw 1; // warn
2014-04-29 08:46:17 +08:00
j = c.j;
2012-10-06 13:09:43 +08:00
};
2014-04-29 08:46:17 +08:00
};
< / pre > < / div >
< div class = "example" > < pre >
class C {
public:
int i, j;
C & operator=(const C & c) {
i = c.i;
2012-10-06 13:09:43 +08:00
throw 1; // warn
2014-04-29 08:46:17 +08:00
j = c.j;
};
2012-10-06 13:09:43 +08:00
};
2014-04-29 08:46:17 +08:00
< / pre > < / div > < / div > < / td >
< td class = "aligned" > < / td > < / tr >
< tr > < td > < div class = "namedescr expandable" > < span class = "name" >
undefbehavior.ValarrayArgBound< / span > < span class = "lang" >
(C++)< / span > < div class = "descr" >
Undefined behavior: the value of the < code > < i > n< / i > < / code > argument passed
to < code > valarray< / code > constructor is greater than the number of values
pointed to by the first argument (source).
< p > Source: C++03 26.3.2.1p4; C++11 26.6.2.2p4.< / p > < / div > < / div > < / td >
< td > < div class = "exampleContainer expandable" >
< div class = "example" > < pre >
2012-10-06 13:09:43 +08:00
#include < valarray>
struct S {
int i;
S(int ii) : i(ii) {};
};
void test(void) {
S s[] = { S(1), S(2) };
std::valarray< S> v(s,3); // warn
}
2014-04-29 08:46:17 +08:00
< / pre > < / div > < / div > < / td >
< td class = "aligned" > < / td > < / tr >
2012-10-06 13:09:43 +08:00
2014-04-29 08:46:17 +08:00
< tr > < td > < div class = "namedescr expandable" > < span class = "name" >
undefbehavior.ValarrayLengthDiffer< / span > < span class = "lang" >
(C++)< / span > < div class = "descr" >
Undefined behavior: < code > valarray< / code > operands are of different length.
< p > Source: C++03 26.3.2.2p1, 26.3.2.6p3, 26.3.3.1p3, 26.3.3.2p3;
C++11 defined (26.6.2.3p1), 26.6.2.7p3, 26.6.3.1p3,
26.6.3.2p3.< / p > < / div > < / div > < / td >
< td > < div class = "exampleContainer expandable" >
< div class = "example" > < pre >
2012-10-06 13:09:43 +08:00
// C++03
#include < valarray>
void test(void) {
std::valarray< int> a(0, 1), b(0, 2);
a = b; // warn
b.resize(1);
2014-04-29 08:46:17 +08:00
a = b; // ok
}
< / pre > < / div >
< div class = "example" > < pre >
// C++03, C++11
#include < valarray>
void test(void) {
std::valarray< int> a(0, 1), b(0, 2);
a *= b; // warn
2012-10-06 13:09:43 +08:00
}
2014-04-29 08:46:17 +08:00
< / pre > < / div >
< div class = "example" > < pre >
// C++03, C++11
#include < valarray>
2012-10-06 13:09:43 +08:00
2014-04-29 08:46:17 +08:00
void test(void) {
std::valarray< int> a(0, 1), b(0, 2);
a = a + b; // warn
}
< / pre > < / div >
< div class = "example" > < pre >
// C++03, C++11
2012-10-06 13:09:43 +08:00
#include < valarray>
void test(void) {
std::valarray< int> a(0, 1), b(0, 2);
std::valarray< bool> c(false, 1);
c = a == b; // warn
}
2014-04-29 08:46:17 +08:00
< / pre > < / div > < / div > < / td >
< td class = "aligned" > < / td > < / tr >
2012-10-06 13:09:43 +08:00
2014-04-29 08:46:17 +08:00
< tr > < td > < div class = "namedescr expandable" > < span class = "name" >
undefbehavior.ValarrayZeroLength< / span > < span class = "lang" >
(C++)< / span > < div class = "descr" >
Undefined behavior: calling < code > sum()< / code > /< code > min()< / code > /< code >
max()< / code > methods of a zero length < code > valarray< code > the behavior is
undefined.
< p > Source: C++03 26.3.2.7p2, p3, p4; C++11 26.6.2.8p5, p6,
p7.< / p > < / div > < / div > < / td >
< td > < div class = "exampleContainer expandable" >
< div class = "example" > < pre >
2012-10-06 13:09:43 +08:00
#include < valarray>
void test(void) {
std::valarray< int> v(0, 0);
v.sum(); // warn
}
2014-04-29 08:46:17 +08:00
< / pre > < / div > < / div > < / td >
< td class = "aligned" > < / td > < / tr >
2012-10-06 13:09:43 +08:00
2014-04-29 08:46:17 +08:00
< tr > < td > < div class = "namedescr expandable" > < span class = "name" >
undefbehavior.ValarrayBadIndirection< / span > < span class = "lang" >
(C++)< / span > < div class = "descr" >
Undefined behavior: element is specified more than once in an indirection.
< p > Source: C++03 26.3.9.2p2, 26.3.9.3p2; C++11 26.6.9.2p2,
26.6.9.3p2.< / p > < / div > < / div > < / td >
< td > < div class = "exampleContainer expandable" >
< div class = "example" > < pre >
2012-10-06 13:09:43 +08:00
#include < valarray>
void test() {
2014-04-29 08:46:17 +08:00
// '1' is specified more then once
size_t addr[] = {0, 1, 1};
2012-10-06 13:09:43 +08:00
std::valarray< size_t> indirect(addr, 3);
std::valarray< int> a(0, 5), b(1, 3);
a[indirect] = b; //warn
2014-04-29 08:46:17 +08:00
}
< / pre > < / div >
< div class = "example" > < pre >
#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);
2012-10-06 13:09:43 +08:00
a[indirect] *= b; //warn
}
2014-04-29 08:46:17 +08:00
< / pre > < / div > < / div > < / td >
< td class = "aligned" > < / td > < / tr >
2012-10-06 13:09:43 +08:00
2014-04-29 08:46:17 +08:00
< tr > < td > < div class = "namedescr expandable" > < span class = "name" >
undefbehavior.IosBaseDestroyedBeforeInit< / span > < span class = "lang" >
(C++)< / span > < div class = "descr" >
Undefined behavior: < code > ios_base< / code > object is destroyed before
initialization have taken place. < code > basic_ios::init< / code > should be call to
initialize < code > ios_base< / code > members.
< p > Source: C++03 27.4.2.7p1, 27.4.4.1p2; C++11 27.5.3.7p1,
27.5.5.2p2.< / p > < / div > < / div > < / td >
< td > < div class = "exampleContainer expandable" >
< div class = "example" > < pre >
2012-10-06 13:09:43 +08:00
#include < ios>
using namespace std;
2014-04-29 08:46:17 +08:00
template < class T, class Traits = std::char_traits< T> >
2012-10-06 13:09:43 +08:00
class my_stream1 : public std::basic_ios< T, Traits> {
};
2014-04-29 08:46:17 +08:00
template < class T, class Traits = std::char_traits< T> >
2012-10-06 13:09:43 +08:00
class my_stream2 : public std::basic_ios< T, Traits> {
2014-04-29 08:46:17 +08:00
class my_streambuf
: public std::basic_streambuf< T, Traits> {
2012-10-06 13:09:43 +08:00
};
public:
my_stream2() {
this->init(new my_streambuf);
}
};
void test() {
2014-04-29 08:46:17 +08:00
my_stream1< char> *p1 = new my_stream1< char> ;
my_stream2< char> *p2 = new my_stream2< char> ;
2012-10-06 13:09:43 +08:00
delete p1; // warn
delete p2; // ok
}
2014-04-29 08:46:17 +08:00
< / pre > < / div > < / div > < / td >
< td class = "aligned" > < / td > < / tr >
2012-10-06 13:09:43 +08:00
2014-04-29 08:46:17 +08:00
< tr > < td > < div class = "namedescr expandable" > < span class = "name" >
undefbehavior.IosBaseUsedBeforeInit< / span > < span class = "lang" >
(C++11)< / span > < div class = "descr" >
Undefined behavior: < code > ios_base< / code > object is used before initialization
have taken place. < code > basic_ios::init< / code > should be call to
initialize < code > ios_base< / code > members.
< p > Source: C++11 27.5.3.7p1, 27.5.5.2p2.< / p > < / div > < / div > < / td >
< td > < div class = "exampleContainer expandable" >
< div class = "example" > < pre >
2012-10-06 13:09:43 +08:00
#include < ios>
using namespace std;
2014-04-29 08:46:17 +08:00
template < class T, class Traits = std::char_traits< T> >
2012-10-06 13:09:43 +08:00
class my_stream1 : public std::basic_ios< T, Traits> {
};
2014-04-29 08:46:17 +08:00
template < class T, class Traits = std::char_traits< T> >
2012-10-06 13:09:43 +08:00
class my_stream2 : public std::basic_ios< T, Traits> {
2014-04-29 08:46:17 +08:00
class my_streambuf
: public std::basic_streambuf< T, Traits> {
2012-10-06 13:09:43 +08:00
};
public:
my_stream2() {
this->init(new my_streambuf);
}
};
void test() {
2014-04-29 08:46:17 +08:00
my_stream1< char> *p1 = new my_stream1< char> ;
my_stream2< char> *p2 = new my_stream2< char> ;
2012-10-06 13:09:43 +08:00
p1->narrow('a', 'b'); // warn
p2->narrow('a', 'b'); // ok
}
2014-04-29 08:46:17 +08:00
< / pre > < / div > < / div > < / td >
< td class = "aligned" > < / td > < / tr >
2012-10-06 13:09:43 +08:00
2014-04-29 08:46:17 +08:00
< tr > < td > < div class = "namedescr expandable" > < span class = "name" >
undefbehavior.MinusOnePosType< / span > < span class = "lang" >
(C++)< / span > < div class = "descr" >
Undefined behavior: passing -1 to any < code > streambuf< / code > /< code >
istream< / code > /< code > ostream< / code > member that accepts a value of
type < code > traits::pos_type< / code > result in undefined behavior.
< p > Source: C++03 27.4.3.2p3; C++11 27.5.4.2p3.< / p > < / div > < / div > < / td >
< td > < div class = "exampleContainer expandable" >
< div class = "example" > < pre >
2012-10-06 13:09:43 +08:00
#include < fstream>
class my_streambuf : public std::streambuf {
void f() {
seekpos(-1); // warn
}
};
2014-04-29 08:46:17 +08:00
< / pre > < / div >
< div class = "example" > < pre >
#include < fstream>
2012-10-06 13:09:43 +08:00
void test() {
std::filebuf fb;
2012-10-07 01:14:39 +08:00
std::istream in(& fb);
2012-10-06 13:09:43 +08:00
std::filebuf::off_type pos(-1);
in.seekg(pos); // warn
}
2014-04-29 08:46:17 +08:00
< / pre > < / div > < / div > < / td >
< td class = "aligned" > < / td > < / tr >
2012-10-06 13:09:43 +08:00
< / table >
2012-10-07 01:14:39 +08:00
<!-- ============================ different ================================ -->
2012-10-06 13:09:43 +08:00
< h3 > different< / h3 >
< table class = "checkers" >
< col class = "namedescr" > < col class = "example" > < col class = "progress" >
< thead > < tr > < td > Name, Description< / td > < td > Example< / td > < td > Progress< / td > < / tr >
< / thead >
2014-04-29 08:46:17 +08:00
< tr > < td > < div class = "namedescr expandable" > < span class = "name" >
different.SuccessiveAssign< / span > < span class = "lang" >
(C)< / span > < div class = "descr" >
Successive assign to a variable.< / div > < / div > < / td >
< td > < div class = "exampleContainer expandable" >
< div class = "example" > < pre >
int test() {
int i;
2012-10-06 13:09:43 +08:00
i=1;
i=2; // warn
2014-04-29 08:46:17 +08:00
return i;
2012-10-06 13:09:43 +08:00
}
2014-04-29 08:46:17 +08:00
< / pre > < / div > < / div > < / td >
< td class = "aligned" > < / td > < / tr >
2012-10-06 13:09:43 +08:00
2014-04-29 08:46:17 +08:00
< tr > < td > < div class = "namedescr expandable" > < span class = "name" >
different.NullDerefStmtOrder< / span > < span class = "lang" >
(C)< / span > < div class = "descr" >
2012-10-06 13:09:43 +08:00
Dereferencing of the null pointer might take place. Checking the pointer for
2014-04-29 08:46:17 +08:00
null should be performed first.
< br > Note: possibly an enhancement to < span class = "name" >
core.NullDereference< / span > .< / div > < / div > < / td >
< td > < div class = "exampleContainer expandable" >
< div class = "example" > < pre >
2012-10-06 13:09:43 +08:00
struct S {
int x;
};
2014-04-29 08:46:17 +08:00
struct S* f();
2012-10-06 13:09:43 +08:00
void test() {
2014-04-29 08:46:17 +08:00
struct S *p1 = f();
2012-10-06 13:09:43 +08:00
int x1 = p1-> x; // warn
if (p1) {};
2014-04-29 08:46:17 +08:00
struct S *p2 = f();
2012-10-06 13:09:43 +08:00
int x2 = p2-> x; // ok
}
2014-04-29 08:46:17 +08:00
< / pre > < / div > < / div > < / td >
< td class = "aligned" > < / td > < / tr >
2012-10-06 13:09:43 +08:00
2014-04-29 08:46:17 +08:00
< tr > < td > < div class = "namedescr expandable" > < span class = "name" >
different.NullDerefCondOrder< / span > < span class = "lang" >
(C)< / span > < div class = "descr" >
2012-10-06 13:09:43 +08:00
Dereferencing of the null pointer might take place. Checking the pointer for
2014-04-29 08:46:17 +08:00
null should be performed first.
< br > Note: possibly an enhancement to < span class = "name" >
core.NullDereference< / span > .< / div > < / div > < / td >
< td > < div class = "exampleContainer expandable" >
< div class = "example" > < pre >
struct S {int i;};
2012-10-06 13:09:43 +08:00
2014-04-29 08:46:17 +08:00
struct S* f();
2012-10-06 13:09:43 +08:00
void test() {
2014-04-29 08:46:17 +08:00
struct S *p = f();
if (p-> i & & p) {}; // warn
2012-10-06 13:09:43 +08:00
}
2014-04-29 08:46:17 +08:00
< / pre > < / div > < / div > < / td >
< td class = "aligned" > < / td > < / tr >
2012-10-06 13:09:43 +08:00
2014-04-29 08:46:17 +08:00
< tr > < td > < div class = "namedescr expandable" > < span class = "name" >
different.MultipleAccessors< / span > < span class = "lang" >
(C++)< / span > < div class = "descr" >
Identical accessor bodies. Possibly a misprint.< / div > < / div > < / td >
< td > < div class = "exampleContainer expandable" >
< div class = "example" > < pre >
2012-10-06 13:09:43 +08:00
class A {
int i;
int j;
public:
int getI() { return i; }
int getJ() { return i; } // warn
2014-04-29 08:46:17 +08:00
};
< / pre > < / div >
< div class = "example" > < pre >
class A {
int i;
int j;
public:
2012-10-06 13:09:43 +08:00
void setI(int& ii) { i = ii; }
void setJ(int& jj) { i = jj; } // warn
};
2014-04-29 08:46:17 +08:00
< / pre > < / div > < / div > < / td >
< td class = "aligned" > < / td > < / tr >
2012-10-06 13:09:43 +08:00
2014-04-29 08:46:17 +08:00
< tr > < td > < div class = "namedescr expandable" > < span class = "name" >
different.AccessorsForPublic< / span > < span class = "lang" >
(C++)< / span > < div class = "descr" >
Accessors exist for a public class field. Should this field really be
public?< / div > < / div > < / td >
< td > < div class = "exampleContainer expandable" >
< div class = "example" > < pre >
2012-10-06 13:09:43 +08:00
class A {
public:
int i; // warn
int getI() { return i; }
void setI(int& ii) { i = ii; }
};
2014-04-29 08:46:17 +08:00
< / pre > < / div > < / div > < / td >
< td class = "aligned" > < / td > < / tr >
2012-10-06 13:09:43 +08:00
2014-04-29 08:46:17 +08:00
< tr > < td > < div class = "namedescr expandable" > < span class = "name" >
different.LibFuncResultUnised< / span > < span class = "lang" >
(C, C++)< / span > < div class = "descr" >
Calling a function ignoring its return value is of no use (create the list of
known system/library/API functions falling into this category).< / div > < / div > < / td >
< td > < div class = "exampleContainer expandable" >
< div class = "example" > < pre >
2012-10-06 13:09:43 +08:00
#include < vector>
void test() {
std::vector< int> v;
v.empty(); // warn
}
2014-04-29 08:46:17 +08:00
< / pre > < / div > < / div > < / td >
< td class = "aligned" > < / td > < / tr >
2012-10-06 13:09:43 +08:00
2014-04-29 08:46:17 +08:00
< tr > < td > < div class = "namedescr expandable" > < span class = "name" >
different.WrongVarForStmt< / span > < span class = "lang" >
(C, C++)< / span > < div class = "descr" >
Wrong variable is possibly used in the loop/cond-expression of
the < code > for< / code > statement. Did you mean
'proper_variable_name'?< / div > < / div > < / td >
< td > < div class = "exampleContainer expandable" >
< div class = "example" > < pre >
2012-10-06 13:09:43 +08:00
void test() {
2014-04-29 08:46:17 +08:00
int i = 0;
int j = 0;
for (i = 0; i < 3 ; j + = 1 ) ; / / warn
}
< / pre > < / div >
< div class = "example" > < pre >
void test() {
int i = 0;
int j = 0;
for (int j = 0; i < 3 ; + + j ) ; / / warn
2012-10-06 13:09:43 +08:00
}
2014-04-29 08:46:17 +08:00
< / pre > < / div > < / div > < / td >
< td class = "aligned" > < / td > < / tr >
2012-10-06 13:09:43 +08:00
2014-04-29 08:46:17 +08:00
< tr > < td > < div class = "namedescr expandable" > < span class = "name" >
different.FloatingCompare< / span > < span class = "lang" >
(C)< / span > < div class = "descr" >
Comparing floating point numbers may be not precise.< / div > < / div > < / td >
< td > < div class = "exampleContainer expandable" >
< div class = "example" > < pre >
2012-10-06 13:09:43 +08:00
#include < math.h>
2014-04-29 08:46:17 +08:00
double test() {
2012-10-06 13:09:43 +08:00
double b = sin(M_PI / 6.0);
if (b == 0.5) // warn
b = 0;
2014-04-29 08:46:17 +08:00
return b;
2012-10-06 13:09:43 +08:00
}
2014-04-29 08:46:17 +08:00
< / pre > < / div > < / div > < / td >
< td class = "aligned" > < / td > < / tr >
2012-10-06 13:09:43 +08:00
2014-04-29 08:46:17 +08:00
< tr > < td > < div class = "namedescr expandable" > < span class = "name" >
different.BitwiseOpBoolArg< / span > < span class = "lang" >
(C, C++)< / span > < div class = "descr" >
Boolean value met at the left/right part of the bitwise < code > & < / code >
or < code > |< / code > operator.
Did you mean < code > & & < / code > (< code > ||< / code > ) ?< / div > < / div > < / td >
< td > < div class = "exampleContainer expandable" >
< div class = "example" > < pre >
2012-10-06 13:09:43 +08:00
int f();
void test() {
bool b = true;
2012-10-07 01:14:39 +08:00
if (b & f()) {} // warn
2012-10-06 13:09:43 +08:00
}
2014-04-29 08:46:17 +08:00
< / pre > < / div > < / div > < / td >
< td class = "aligned" > < / td > < / tr >
2012-10-06 13:09:43 +08:00
2014-04-29 08:46:17 +08:00
< tr > < td > < div class = "namedescr expandable" > < span class = "name" >
different.LabelInsideSwitch< / span > < span class = "lang" >
(C)< / span > < div class = "descr" >
Possibly a misprint: label found inside a < code > switch()< / code >
statement.< / div > < / div > < / td >
< td > < div class = "exampleContainer expandable" >
< div class = "example" > < pre >
void test(int c) {
2012-10-06 13:09:43 +08:00
switch(c){
case 1:
c += 1; break;
2014-04-29 08:46:17 +08:00
defalt: // warn (did you mean 'default'?)
2012-10-06 13:09:43 +08:00
c -= 1; break;
}
}
2014-04-29 08:46:17 +08:00
< / pre > < / div > < / div > < / td >
< td class = "aligned" > < / td > < / tr >
2012-10-06 13:09:43 +08:00
2014-04-29 08:46:17 +08:00
< tr > < td > < div class = "namedescr expandable" > < span class = "name" >
different.IdenticalCondIfIf< / span > < span class = "lang" >
(C)< / span > < div class = "descr" >
The conditions of two subsequent < code > if< / code > statements are
identical.< / div > < / div > < / td >
< td > < div class = "exampleContainer expandable" >
< div class = "example" > < pre >
int test(int c) {
if (c > 5)
2012-10-06 13:09:43 +08:00
c += 1;
if (c > 5) // warn
c -= 1;
2014-04-29 08:46:17 +08:00
return c;
2012-10-06 13:09:43 +08:00
}
2014-04-29 08:46:17 +08:00
< / pre > < / div > < / div > < / td >
< td class = "aligned" > < / td > < / tr >
2012-10-06 13:09:43 +08:00
2014-04-29 08:46:17 +08:00
< tr > < td > < div class = "namedescr expandable" > < span class = "name" >
different.LogicalOpUselessArg< / span > < span class = "lang" >
(C)< / span > < div class = "descr" >
The second operand of a < code > & & < / code > operator has no impact on
expression result.< / div > < / div > < / td >
< td > < div class = "exampleContainer expandable" >
< div class = "example" > < pre >
void test(unsigned a) {
2012-10-07 01:14:39 +08:00
if (a< 7 & & a< 10) {}; // warn
2012-10-06 13:09:43 +08:00
}
2014-04-29 08:46:17 +08:00
< / pre > < / div > < / div > < / td >
< td class = "aligned" > < / td > < / tr >
2012-10-06 13:09:43 +08:00
2014-04-29 08:46:17 +08:00
< tr > < td > < div class = "namedescr expandable" > < span class = "name" >
different.SameResLogicalExpr< / span > < span class = "lang" >
(C)< / span > < div class = "descr" >
An expression is always evaluated to true/false.< / div > < / div > < / td >
< td > < div class = "exampleContainer expandable" >
< div class = "example" > < pre >
2012-10-06 13:09:43 +08:00
void test() {
2014-04-29 08:46:17 +08:00
int i = 0;
if (i != 0) {}; // warn
}
< / pre > < / div >
< div class = "example" > < pre >
void test(int i) {
if (i == 0 & & i == 1) {}; // warn
}
< / pre > < / div >
< div class = "example" > < pre >
void test(int i) {
if (i < 0 | | i > = 0) {}; // warn
}
< / pre > < / div > < / div > < / td >
< td class = "aligned" > < / td > < / tr >
< tr > < td > < div class = "namedescr expandable" > < span class = "name" >
different.OpPrecedenceAssignCmp< / span > < span class = "lang" >
(C, C++)< / span > < div class = "descr" >
Comparison operation has higher precedence then assignment. Boolean value is
assigned to a variable of other type. Parenthesis may bee required around an
assignment.< / div > < / div > < / td >
< td > < div class = "exampleContainer expandable" >
< div class = "example" > < pre >
2012-10-06 13:09:43 +08:00
int f();
2014-04-29 08:46:17 +08:00
void test(int x, int y) {
2012-10-06 13:09:43 +08:00
bool b;
if((b = x != y)) {} // ok
if((x = f() != y)) {} // warn
}
2014-04-29 08:46:17 +08:00
< / pre > < / div > < / div > < / td >
< td class = "aligned" > < / td > < / tr >
2012-10-06 13:09:43 +08:00
2014-04-29 08:46:17 +08:00
< tr > < td > < div class = "namedescr expandable" > < span class = "name" >
different.OpPrecedenceIifShift< / span > < span class = "lang" >
(C, C++)< / span > < div class = "descr" >
< code > ?:< / code > has lower precedence then < code > < < < / code > .
< p > Source: Stephen C. Dewhurst "C++ Gotchas: Avoiding Common Problems in Coding
and Design", advise 15.< / p > < / div > < / div > < / td >
< td > < div class = "exampleContainer expandable" >
< div class = "example" > < pre >
2012-10-06 13:09:43 +08:00
#include < iostream>
2014-04-29 08:46:17 +08:00
void test(int a) {
2012-10-06 13:09:43 +08:00
std::cout < < a ? "a" : "b"; // warn
}
2014-04-29 08:46:17 +08:00
< / pre > < / div >
< div class = "example" > < pre >
void test(int a) {
a < < a > 7 ? 1 : 2; // warn
}
< / pre > < / div > < / div > < / td >
< td class = "aligned" > < / td > < / tr >
2012-10-06 13:09:43 +08:00
2014-04-29 08:46:17 +08:00
< tr > < td > < div class = "namedescr expandable" > < span class = "name" >
different.ObjectUnused< / span > < span class = "lang" >
(C++)< / span > < div class = "descr" >
The object was created but is not being used.< / div > < / div > < / td >
< td > < div class = "exampleContainer expandable" >
< div class = "example" > < pre >
2012-10-06 13:09:43 +08:00
struct S {
int x, y;
2014-04-29 08:46:17 +08:00
S(int xx, int yy) : x(xx), y(yy) {}
2012-10-06 13:09:43 +08:00
S(int xx) {
S(xx, 0); // warn
}
};
2014-04-29 08:46:17 +08:00
< / pre > < / div >
< div class = "example" > < pre >
#include < exception>
2012-10-06 13:09:43 +08:00
void test() {
2014-04-29 08:46:17 +08:00
std::exception();
// warn (did you mean 'throw std::exception()'?)
2012-10-06 13:09:43 +08:00
}
2014-04-29 08:46:17 +08:00
< / pre > < / div > < / div > < / td >
< td class = "aligned" > < / td > < / tr >
2012-10-06 13:09:43 +08:00
2014-04-29 08:46:17 +08:00
< tr > < td > < div class = "namedescr expandable" > < span class = "name" >
different.StaticArrayPtrCompare< / span > < span class = "lang" >
(C)< / span > < div class = "descr" >
Pointer to static array is being compared to NULL. May the subscripting is
missing.< / div > < / div > < / td >
< td > < div class = "exampleContainer expandable" >
< div class = "example" > < pre >
void test() {
int a[1][1];
if (a[0] == 0) {}; // warn
2012-10-06 13:09:43 +08:00
}
2014-04-29 08:46:17 +08:00
< / pre > < / div > < / div > < / td >
< td class = "aligned" > < / td > < / tr >
2012-10-06 13:09:43 +08:00
2014-04-29 08:46:17 +08:00
< tr > < td > < div class = "namedescr expandable" > < span class = "name" >
different.ConversionToBool< / span > < span class = "lang" >
(C, C++)< / span > < div class = "descr" >
Odd implicit conversion to boolean.
< br > Note: possibly merge with < span class = "name" >
alpha.core.BoolAssignment< / span > .< / div > < / div > < / td >
< td > < div class = "exampleContainer expandable" >
< div class = "example" > < pre >
2012-10-06 13:09:43 +08:00
bool test() {
return 1.; // warn
2014-04-29 08:46:17 +08:00
}
< / pre > < / div >
< div class = "example" > < pre >
bool test() {
2012-10-06 13:09:43 +08:00
return ""; // warn
}
2014-04-29 08:46:17 +08:00
< / pre > < / div > < / div > < / td >
< td class = "aligned" > < / td > < / tr >
2012-10-06 13:09:43 +08:00
2014-04-29 08:46:17 +08:00
< tr > < td > < div class = "namedescr expandable" > < span class = "name" >
different.ArrayBound< / span > < span class = "lang" >
(C++)< / span > < div class = "descr" >
Out-of-bound dynamic array access.
< br > Note: possibly an enhancement to < span class = "name" >
alpha.security.ArrayBoundV2< / span > .< / div > < / div > < / td >
< td > < div class = "exampleContainer expandable" >
< div class = "example" > < pre >
2012-10-06 13:09:43 +08:00
void test() {
2014-04-29 08:46:17 +08:00
int *p = new int[1];
2012-10-06 13:09:43 +08:00
int i = 1;
2014-04-29 08:46:17 +08:00
if(p[i]) {}; // warn
delete[] p;
2012-10-06 13:09:43 +08:00
}
2014-04-29 08:46:17 +08:00
< / pre > < / div > < / div > < / td >
< td class = "aligned" > < / td > < / tr >
2012-10-06 13:09:43 +08:00
2014-04-29 08:46:17 +08:00
< tr > < td > < div class = "namedescr expandable" > < span class = "name" >
different.StrcpyInputSize< / span > < span class = "lang" >
(C)< / span > < div class = "descr" >
Buffer copy without checking the size of input.
< br > Note: possibly an enhancement to < span class = "name" >
alpha.unix.cstring.OutOfBounds< / span > .< / div > < / div > < / td >
< td > < div class = "exampleContainer expandable" >
< div class = "example" > < pre >
2012-10-06 13:09:43 +08:00
void test(char* string) {
char buf[24];
strcpy(buf, string); // warn
}
2014-04-29 08:46:17 +08:00
< / pre > < / div > < / div > < / td >
< td class = "aligned" > < / td > < / tr >
2012-10-06 13:09:43 +08:00
2014-04-29 08:46:17 +08:00
< tr > < td > < div class = "namedescr expandable" > < span class = "name" >
different.IntegerOverflow< / span > < span class = "lang" >
(C)< / span > < div class = "descr" >
Integer overflow.
< br > Note: partially handled by Clang core
(search for 'overflow in expression' warning in Clang tests).
< p > Source: < a href = "http://cwe.mitre.org/data/definitions/190.html" >
CWE-190< / a > .< / p > < / div > < / div > < / td >
< td > < div class = "exampleContainer expandable" >
< div class = "example" > < pre >
2012-10-06 13:09:43 +08:00
#include < limits.h>
2014-04-29 08:46:17 +08:00
int f(int x);
2012-10-06 13:09:43 +08:00
void test() {
2014-04-29 08:46:17 +08:00
f(INT_MAX + 1); // warn
2012-10-06 13:09:43 +08:00
}
2014-04-29 08:46:17 +08:00
< / pre > < / div >
< div class = "example" > < pre >
#include < limits.h>
2012-10-06 13:09:43 +08:00
2014-04-29 08:46:17 +08:00
int test() {
int x = INT_MAX / 2 + 1;
return x * 2; // warn
}
< / pre > < / div > < / div > < / td >
< td class = "aligned" > < / td > < / tr >
< tr > < td > < div class = "namedescr expandable" > < span class = "name" >
different.SignExtension< / span > < span class = "lang" >
(C)< / span > < div class = "descr" >
Unexpected sign extension might take place.
< p > Source: < a href = "http://cwe.mitre.org/data/definitions/194.html" >
CWE-194< / a > .< / p > < / div > < / div > < / td >
< td > < div class = "exampleContainer expandable" >
< div class = "example" > < pre >
unsigned long long test(long long sll) {
unsigned long long ull = sll; // warn
return ull;
}
< / pre > < / div >
< div class = "example" > < pre >
2012-10-06 13:09:43 +08:00
void f(unsigned int i);
2014-04-29 08:46:17 +08:00
void test(int si) {
2012-10-06 13:09:43 +08:00
f(si); // warn
}
2014-04-29 08:46:17 +08:00
< / pre > < / div >
< div class = "example" > < pre >
unsigned int test(int i) {
return i;
}
< / pre > < / div > < / div > < / td >
< td class = "aligned" > < / td > < / tr >
2012-10-06 13:09:43 +08:00
2014-04-29 08:46:17 +08:00
< tr > < td > < div class = "namedescr expandable" > < span class = "name" >
different.NumericTruncation< / span > < span class = "lang" >
(C)< / span > < div class = "descr" >
Numeric truncation might take place.
< p > Source: < a href = "http://cwe.mitre.org/data/definitions/197.html" >
CWE-197< / a > .< / p > < / div > < / div > < / td >
< td > < div class = "exampleContainer expandable" >
< div class = "example" > < pre >
unsigned long test(unsigned long long ull) {
2012-10-06 13:09:43 +08:00
unsigned long ul = ull; // warn
2014-04-29 08:46:17 +08:00
return ul;
}
< / pre > < / div >
< div class = "example" > < pre >
void f(int i);
void test(long long sll) {
2012-10-06 13:09:43 +08:00
f(sll); // warn
2014-04-29 08:46:17 +08:00
}
< / pre > < / div >
< div class = "example" > < pre >
int f();
short test(long long sll) {
short ss = f();
return ss;
}
< / pre > < / div > < / div > < / td >
< td class = "aligned" > < / td > < / tr >
< tr > < td > < div class = "namedescr expandable" > < span class = "name" >
different.MissingCopyCtorAssignOp< / span > < span class = "lang" >
(C++)< / span > < div class = "descr" >
A class has dynamically allocated data members but do not define a copy
constructor/assignment operator.
< p > Source: Scott Meyers "Effective C++", item 11: Prevent exceptions from
leaving destructors.< / p > < / div > < / div > < / td >
< td > < div class = "exampleContainer expandable" >
< div class = "example" > < pre >
class C {
int *p; // warn
2012-10-06 13:09:43 +08:00
public:
C() { p = new int; }
~C() { delete p; }
};
2014-04-29 08:46:17 +08:00
< / pre > < / div > < / div > < / td >
< td class = "aligned" > < / td > < / tr >
2012-10-06 13:09:43 +08:00
< / table >
2012-10-07 01:14:39 +08:00
<!-- ============================ WinAPI =================================== -->
2012-10-06 13:09:43 +08:00
< h3 > WinAPI< / h3 >
< table class = "checkers" >
< col class = "namedescr" > < col class = "example" > < col class = "progress" >
< thead > < tr > < td > Name, Description< / td > < td > Example< / td > < td > Progress< / td > < / tr > < / thead >
2014-04-29 08:46:17 +08:00
< tr > < td > < div class = "namedescr expandable" > < span class = "name" >
WinAPI.CreateProcess< / span > < span class = "lang" >
(C)< / span > < div class = "descr" >
< code > CreateProcess()< / code > : if the first parameter < code > < i >
lpApplicationName< / i > < / code > is NULL then the executable name must be in the
white space-delimited string pointed to by < code > < i > lpCommandLine< / code > < / i > .
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.
< p > Source: < a href = "http://msdn.microsoft.com/en-us/library/windows/desktop/ms682425%28v=vs.85%29.aspx" >
MSDN: CreateProcess function, Security Remarks< / a > .< / p > < / div > < / div > < / td >
< td > < div class = "exampleContainer expandable" >
< div class = "example" > < pre >
2012-10-06 13:09:43 +08:00
#include < windows.h>
void test() {
STARTUPINFO si;
PROCESS_INFORMATION pi;
2014-04-29 08:46:17 +08:00
CreateProcess(NULL, TEXT("C:\\Program Files\\App -L -S"),
NULL, NULL, TRUE, 0, NULL, NULL, & si, &pi);
// warn
}
< / pre > < / div > < / div > < / td >
< td class = "aligned" > < / td > < / tr >
< tr > < td > < div class = "namedescr expandable" > < span class = "name" >
WinAPI.LoadLibrary< / span > < span class = "lang" >
(C)< / span > < div class = "descr" >
The < code > SearchPath()< / code > function is used to retrieve a path to a DLL for
a subsequent < code > LoadLibrary()< / code > call.
< p > Source: < a href = "http://msdn.microsoft.com/en-us/library/windows/desktop/ms684175%28v=vs.85%29.aspx" >
MSDN: LoadLibrary function, Security Remarks< / a > .< / p > < / div > < / div > < / td >
< td > < div class = "exampleContainer expandable" >
< div class = "example" > < pre >
2012-10-06 13:09:43 +08:00
#include < windows.h>
2014-04-29 08:46:17 +08:00
HINSTANCE test() {
char filePath[100];
SearchPath(NULL, "file.dll", NULL, 100, filePath, NULL);
return LoadLibrary(filePath); // warn
}
< / pre > < / div > < / div > < / td >
< td class = "aligned" > < / td > < / tr >
< tr > < td > < div class = "namedescr expandable" > < span class = "name" >
WinAPI.WideCharToMultiByte< / span > < span class = "lang" >
(C)< / span > < div class = "descr" >
Buffer overrun while calling < code > WideCharToMultiByte()< / code > . 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.
< p > Source: < a href = "http://msdn.microsoft.com/en-us/library/windows/desktop/dd374130%28v=vs.85%29.aspx" >
MSDN: WideCharToMultiByte function< / a > .< / p > < / div > < / div > < / td >
< td > < div class = "exampleContainer expandable" >
< div class = "example" > < pre >
2012-10-06 13:09:43 +08:00
#include < windows.h>
2014-04-29 08:46:17 +08:00
void test() {
2012-10-06 13:09:43 +08:00
wchar_t ws[] = L"abc";
char s[3];
2014-04-29 08:46:17 +08:00
WideCharToMultiByte(CP_UTF8, 0, ws, -1, s,
3, NULL, NULL); // warn
}
< / pre > < / div > < / div > < / td >
< td class = "aligned" > < / td > < / tr >
2012-10-06 13:09:43 +08:00
< / table >
2012-10-07 01:14:39 +08:00
<!-- =========================== optimization ============================== -->
2012-10-06 13:09:43 +08:00
< h3 > optimization< / h3 >
< table class = "checkers" >
< col class = "namedescr" > < col class = "example" > < col class = "progress" >
< thead > < tr > < td > Name, Description< / td > < td > Example< / td > < td > Progress< / td > < / tr > < / thead >
2014-04-29 08:46:17 +08:00
< tr > < td > < div class = "namedescr expandable" > < span class = "name" >
optimization.PassConstObjByValue< / span > < span class = "lang" >
(C, C++)< / span > < div class = "descr" >
Optimization: It is more effective to pass constant parameter by reference to
avoid unnecessary object copying.< / div > < / div > < / td >
< td > < div class = "exampleContainer expandable" >
< div class = "example" > < pre >
struct A {};
void f(const struct A a); // warn
< / pre > < / div > < / div > < / td >
< td class = "aligned" > < / td > < / tr >
< tr > < td > < div class = "namedescr expandable" > < span class = "name" >
optimization.PostfixIncIter< / span > < span class = "lang" >
(C++)< / span > < div class = "descr" >
Optimization: It is more effective to use prefix increment operator with
iterator.
< p > Source: Scott Meyers "More Effective C++", item 6:
Distinguish between prefix and postfix forms of increment and decrement
operators.< / p > < / div > < / div > < / td >
< td > < div class = "exampleContainer expandable" >
< div class = "example" > < pre >
2012-10-06 13:09:43 +08:00
#include < vector>
void test() {
std::vector< int> v;
std::vector< int> ::const_iterator it;
for(it = v.begin();
it != v.end(); it++) {}; // warn
}
2014-04-29 08:46:17 +08:00
< / pre > < / div > < / div > < / td >
< td class = "aligned" > < / td > < / tr >
2012-10-06 13:09:43 +08:00
2014-04-29 08:46:17 +08:00
< tr > < td > < div class = "namedescr expandable" > < span class = "name" >
optimization.MultipleCallsStrlen< / span > < span class = "lang" >
(C)< / span > < div class = "descr" >
Optimization: multiple calls to < code > strlen()< / code > for a string in an
expression. It is more effective to hold a value returned
from < code > strlen()< / code > in a temporary variable.< / div > < / div > < / td >
< td > < div class = "exampleContainer expandable" >
< div class = "example" > < pre >
2012-10-06 13:09:43 +08:00
#include < string.h>
2014-04-29 08:46:17 +08:00
void test(const char* s) {
2012-10-07 01:14:39 +08:00
if (strlen(s) > 0 & &
2012-10-06 13:09:43 +08:00
strlen(s) < 7) {}; // warn
}
2014-04-29 08:46:17 +08:00
< / pre > < / div > < / div > < / td >
< td class = "aligned" > < / td > < / tr >
2012-10-06 13:09:43 +08:00
2014-04-29 08:46:17 +08:00
< tr > < td > < div class = "namedescr expandable" > < span class = "name" >
optimization.StrLengthCalculation< / span > < span class = "lang" >
(C++)< / span > < div class = "descr" >
Optimization: it is more efficient to use < code > string::length()< / code > to
calculate the length of an < code > std::string< / code > .< / div > < / div > < / td >
< td > < div class = "exampleContainer expandable" >
< div class = "example" > < pre >
2012-10-06 13:09:43 +08:00
#include < string>
#include < string.h>
void test() {
std::string s;
if (strlen(s.c_str()) != 0) {}; // warn
}
2014-04-29 08:46:17 +08:00
< / pre > < / div > < / div > < / td >
< td class = "aligned" > < / td > < / tr >
2012-10-06 13:09:43 +08:00
2014-04-29 08:46:17 +08:00
< tr > < td > < div class = "namedescr expandable" > < span class = "name" >
optimization.EmptyContainerDetect< / span > < span class = "lang" >
(C++)< / span > < div class = "descr" >
Optimization: It is more efficient to use containers < code > empty()< / code >
method to identify an empty container.< / div > < / div > < / td >
< td > < div class = "exampleContainer expandable" >
< div class = "example" > < pre >
2012-10-06 13:09:43 +08:00
#include < list>
void test() {
std::list< int> l;
if (l.size() != 0) {}; // warn
}
2014-04-29 08:46:17 +08:00
< / pre > < / div > < / div > < / td >
< td class = "aligned" > < / td > < / tr >
2012-10-06 13:09:43 +08:00
< / table >
< br >
< / div > <!-- page -->
< / div > <!-- content -->
< / body >
< / html >