aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--www/analyzer/content.css32
-rw-r--r--www/analyzer/potential_checkers.html1645
2 files changed, 1677 insertions, 0 deletions
diff --git a/www/analyzer/content.css b/www/analyzer/content.css
index ea75fbabd1..c2fa294d79 100644
--- a/www/analyzer/content.css
+++ b/www/analyzer/content.css
@@ -63,6 +63,38 @@ table.options td { border-bottom: 1px #cccccc dotted }
table.options td { padding:5px; padding-left:8px; padding-right:8px }
table.options td { text-align:left; font-size:9pt }
+table.checkers {
+ border: 1px #cccccc solid;
+ border-collapse: collapse;
+ margin:0px; margin-top:20px; margin-bottom:20px;
+ text-align:left;
+ table-layout: fixed;
+ width: 100%;
+ word-wrap :break-word;
+ font-size: 100%;
+}
+
+table.checkers thead {
+ background-color:#eee; color:#666666;
+ border-top: 2px solid #cccccc;
+ border-bottom: 2px solid #cccccc;
+ font-weight: bold; font-family: Verdana;
+}
+
+table.checkers td {
+ padding:5px; padding-left:8px; padding-right:8px;
+ border-right: 1px #cccccc dotted;
+ border-bottom: 1px #cccccc dotted;
+}
+
+table.checkers col.namedescr { width: 45% }
+table.checkers col.example { width: 55% }
+table.checkers col.progress { width: 84px }
+table.checkers pre { margin:1px; font-size: 100%; word-wrap :break-word; }
+table.checkers .name { font-weight:bold; }
+table.checkers .checked { background-color:#81F781; }
+table.checkers .commented { color:#909090; }
+
/* Collapsing Trees: http://dbtree.megalingo.com/web/demo/simple-collapsible-tree.cfm */
#collapsetree, #collapsetree a:link, #collapsetree li a:link, #collapsetree a:visited, #collapsetree li a:visited{color:#000;text-decoration:none}
#collapsetree,#collapsetree ul{list-style-type:none; width:auto; margin:0; padding:0}
diff --git a/www/analyzer/potential_checkers.html b/www/analyzer/potential_checkers.html
new file mode 100644
index 0000000000..3da3c66f52
--- /dev/null
+++ b/www/analyzer/potential_checkers.html
@@ -0,0 +1,1645 @@
+<!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">
+ <script type="text/javascript" src="scripts/menu.js"></script>
+ <script type="text/javascript" src="scripts/dbtree.js"></script>
+</head>
+<body>
+
+<div id="page">
+
+<!-- menu -->
+<!--#include virtual="menu.html.incl"-->
+<!-- page content -->
+<div id="content">
+<h1>List of potential checkers</h1>
+
+<!---------------------------- allocation/deallocation -------------------------->
+<h3>allocation/deallocation</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>
+
+<tr><td><span class="name">memory.LeakNeverReleased<br>
+(C, C++)</span><br><br>
+Memory may be never released, potential leak of memory
+</td><td>
+<pre>
+#include &lt;stdlib.h&gt;
+
+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;
+}
+</pre></td><td></td></tr>
+
+<tr><td><span class="name">memory.MismatchedFree
+<br>enhancement to unix.Malloc<br>(C, C++)</span><br><br>
+Mismatched deallocation function is used
+</td><td><pre>
+#include &lt;stdlib.h&gt;
+
+void test() {
+ int *p1 = new int;
+ int *p2 = new int[1];
+
+ free(p1); // warn
+ free(p2); // warn
+}
+</pre></td><td></td></tr>
+
+<tr><td><span class="name">memory.MismatchedDelete
+<br>(C, C++)</span><br><br>
+Mismatched deallocation function is used
+</td><td><pre>
+#include &lt;stdlib.h&gt;
+
+void test() {
+ int *p1 = new int;
+ int *p2 = new int[1];
+ int *p3 = (int*)malloc(sizeof(int));
+
+ delete[] p1; // warn
+ delete p2; // warn
+ delete p3; // warn
+}
+</pre></td><td></td></tr>
+
+<tr><td><span class="name">memory.MultipleDelete
+<br>(C++)</span><br><br>
+Attempt to deallocate released memory
+</td><td><pre>
+#include &lt;new&gt;
+
+void test() {
+ int *p1 = new int;
+ int *p2 = new(p1) int;
+ int *p3 = p1;
+ delete p1;
+ delete p1; // warn
+ delete p2; // warn
+ delete p3; // warn
+}
+</pre></td><td></td></tr>
+
+<tr><td><span class="name">memory.LeakPtrValChanged
+<br>enhancement to unix.Malloc<br>(C, C++)</span><br><br>
+Potential memory leak: a pointer to newly allocated data loses its original
+value
+</td><td><pre>
+#include &lt;stdlib.h&gt;
+
+void f(const int *);
+void g(int *);
+
+void test() {
+ int *p1 = new int;
+ p1++; // warn
+ int *p2 = (int *)malloc(sizeof(int));
+ p2 = p1; // warn
+ int *p3 = new int;
+ f(p3);
+ p3++; // warn
+ int *p4 = new int;
+ f(p4);
+ p4++; // ok
+}
+</pre></td><td></td></tr>
+
+<tr><td><span class="name">memory.DeallocateNonPtr
+<br>enhancement to unix.Malloc<br>(C, C++)</span><br><br>
+Deallocation function is applied to non-pointer
+</td><td><pre>
+#include &lt;stdlib.h&gt;
+
+class A {
+ int *p;
+public:
+ operator int *() { return p; }
+};
+
+void test() {
+ A a;
+ delete a; // warn
+ free(a); // warn
+ const char *s = "text";
+ delete s; // warn
+ free(s); // warn
+}
+</pre></td><td></td></tr>
+
+<tr><td><span class="name">memory.LeakEvalOrder<br>
+(C, C++)</span><br><br>
+Potential memory leak: argument evaluation order is undefined, g() may never be called
+</td><td><pre>
+#include &lt;stdlib.h&gt;
+
+void f1(int, int);
+void f2(int*, int*);
+int g(int *) { throw 1; };
+int h();
+
+void test() {
+ f1(g(new int), h()); // warn
+ f1(g((int *)malloc(sizeof(int))), h()); // warn
+ f2(new int, new int);
+}
+</pre></td><td></td></tr>
+
+<tr><td><span class="name">memory.DstBufferTooSmall
+<br>(C, C++)</span><br><br>
+Destination buffer too small
+</td><td><pre>
+#include &lt;string.h&gt;
+
+void test() {
+ const char* s1 = "abc";
+ char *s2 = new char;
+ strcpy(s2, s1); // warn
+
+ int* p1 = new int[3];
+ int* p2 = new int;
+ memcpy(p2, p1, 3); // warn
+}
+</pre></td><td></td></tr>
+
+<tr><td><span class="name">memory.NegativeArraySize
+<br>enhancement to experimental.security.MallocOverflow<br>(C, C++)
+</span><br><br>
+‘n’ is used to specify the buffer size may be negative
+</td><td><pre>
+#include &lt;stdlib.h&gt;
+
+void test() {
+ int *p;
+ int n1 = -1;
+ p = new int[n1]; // warn
+}
+</pre></td><td></td></tr>
+
+</table>
+
+<!-------------------------- constructors/destructors ------------------------->
+<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>
+
+<tr><td><span class="name">ctordtor.ExptInsideDtorExplicit<br>
+(C++)</span><br><br>
+It is dangerous to let an exception leave a destructor. Using try..catch will
+solve the problem.
+</td><td><pre>
+void f();
+
+class A {
+ A() {}
+ ~A() { throw 1; } // warn
+};
+</pre></td><td></td></tr>
+
+<tr><td><span class="name">ctordtor.ExptInsideDtorImplicit<br>
+(C++)</span><br><br>
+Calls to functions inside a destructor that are known to throw exceptions is
+dangerous. Using try..catch will solve the problem.
+</td><td><pre>
+void f() { throw 1; };
+
+class A {
+ A() {}
+ ~A() { f(); } // warn
+};
+</pre></td><td></td></tr>
+
+</table>
+
+<!--------------------------------- exceptions -------------------------------->
+<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>
+
+<tr><td><span class="name">exceptions.ThrowSpecButNotThrow
+<br>(C++)</span><br><br>
+Function prototype has throw(T) specifier but the function do not throw
+</td><td><pre>
+void f() throw(int) { // warn
+}
+</pre></td><td></td></tr>
+
+<tr><td><span class="name">exceptions.NoThrowSpecButThrows
+<br>(C++)</span><br><br>
+An exception is throw from a function having the throw() specifier
+</td><td><pre>
+void f() throw() {
+ throw(1); // warn
+}
+</pre></td><td></td></tr>
+
+<tr><td><span class="name">exceptions.ThrownTypeDiffersSpec
+<br>(C++)</span><br><br>
+The type of a thrown exception differs from those specified in the throw(T)
+specifier
+</td><td><pre>
+struct S{};
+void f() throw(int) {
+ S s;
+ throw (s); // warn
+}
+</pre></td><td></td></tr>
+
+</table>
+
+<!---------------------------- smart pointers --------------------------------->
+<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>
+
+<tr><td><span class="name">smartptr.AutoPtrInit<br>
+(C++03)</span><br><br>
+auto_ptr should store a pointer to an object obtained via new as allocated
+memory will be cleaned using delete
+</td><td><pre>
+#include &lt;stdlib.h&gt;
+#include &lt;memory&gt;
+
+void test() {
+ std::auto_ptr&lt;int&gt; p1(new int); // Ok
+ std::auto_ptr&lt;int&gt; p2(new int[3]); // warn
+ std::auto_ptr&lt;int&gt;
+ p3((int *)malloc(sizeof(int))); // warn
+}
+</pre></td><td></td></tr>
+
+</table>
+
+<!---------------------------- undefined behavior ----------------------------->
+<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>
+
+<tr><td><span class="name">undefbehavior.ExitInDtor
+<br>(C++)</span><br><br>
+Undefined behavior: std::exit is called to end the program during the
+destruction of an object with static storage duration
+</td><td><pre>
+#include &lt;cstdlib&gt;
+
+class A {
+public:
+ ~A() {
+ std::exit(1); // warn
+ }
+};
+
+A a;
+</pre></td><td></td></tr>
+
+<tr><td><span class="name">undefbehavior.LocalStaticDestroyed
+<br>(C++)</span><br><br>
+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
+</td><td><pre>
+void f();
+
+class A {
+public:
+ ~A() {
+ f(); // warn
+ }
+};
+
+class B {};
+
+A a;
+
+void f() {
+ static B b; // &lt;-
+}
+</pre></td><td></td></tr>
+
+<tr><td><span class="name">undefbehavior.UseAfterRelease
+<br>enhancement to unix.Malloc<br>(C, C++)</span><br><br>
+Pointer to deleted object is referenced (The effect of using an invalid pointer
+value is undefined)
+</td><td><pre>
+#include &lt;stdlib.h&gt;
+
+void test() {
+ int *p = new int;
+ delete p;
+ int i = *p; // warn
+}
+
+</pre></td><td></td></tr>
+
+<tr><td><span class="name">undefbehavior.ZeroAllocDereference
+<br>enhancement to unix.Malloc<br>(C, C++)</span><br><br>
+The effect of dereferencing a pointer returned as a request for zero size is
+undefined
+</td><td><pre>
+#include &lt;stdlib.h&gt;
+
+int *p = new int[0];
+int i = p[0]; // warn
+</pre></td><td></td></tr>
+
+<tr><td><span class="name">undefbehavior.DeadReferenced
+<br>(C++)</span><br><br>
+Undefined behavior: the following usage of the pointer to the object whose
+lifetime has ended can result in undefined behavior
+</td><td><pre>
+// C++03
+#include &lt;new&gt;
+
+class A {
+public:
+ int i;
+ void f() {};
+};
+
+class B : public A {
+};
+
+void test() {
+ B *b = new B;
+ new(b) A;
+ b->i; // warn
+ b->f(); // warn
+ static_cast&lt;A*&gt;(b); // warn
+ dynamic_cast&lt;A*&gt;(b); // warn
+ delete b; // warn
+}
+
+// C++11
+#include &lt;new&gt;
+
+class A {
+public:
+ int i;
+ void f() {};
+};
+
+class B : public A {
+public:
+ ~B() {};
+};
+
+void 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&lt;A*&gt;(b); // warn
+ dynamic_cast&lt;A*&gt;(b); // warn
+ delete b; // warn
+}
+</pre></td><td></td></tr>
+
+<tr><td><span class="name">undefbehavior.ObjLocChanges
+<br>(C++)</span><br><br>
+Undefined behavior: the program must ensure that an object occupies the same
+storage location when the implicit or explicit destructor call takes place
+</td><td><pre>
+#include &lt;new&gt;
+
+class T { };
+struct B {
+ ~B();
+};
+
+void test() {
+ B *b1 = new B;
+ B b2;
+ new (b1) T;
+ new (&b2) T;
+ delete b1; // warn
+} // warn
+</pre></td><td></td></tr>
+
+<tr><td><span class="name">undefbehavior.ExprEvalOrderUndef
+<br>(C, C++03)</span><br><br>
+Undefined behavior: a scalar object shall have its stored value modified at
+most once by the evaluation of an expression
+</td><td><pre>
+void test () {
+ int i = 0;
+ int v[1] = {0};
+ i = v[i++]; // warn
+ i = ++i + 1; // warn
+}
+</pre></td><td></td></tr>
+
+<tr><td><span class="name">undefbehavior.StaticInitReentered
+<br>(C)</span><br><br>
+Undefined behavior: static declaration is re-entered while the object is being
+initialized
+</td><td><pre>
+int test(int i) {
+ static int s = test(2*i); // warn
+ return i+1;
+}
+</pre></td><td></td></tr>
+
+<tr><td><span class="name">undefbehavior.ConstModified
+<br>(C, C++)</span><br><br>
+Undefined behavior: const object is being modified
+</td><td><pre>
+#include &lt;stdlib.h&gt;
+
+class X {
+public :
+ mutable int i;
+ int j;
+};
+class Y {
+public :
+ X x;
+ Y();
+};
+
+void test() {
+ const int *ciq =
+ (int *)malloc(sizeof(int));
+ int *iq = const_cast&lt;int *&gt;(ciq);
+ *iq = 1; // warn
+
+ const Y y;
+ Y* p = const_cast&lt;Y*&gt;(&y);
+ p-&gt;x.i = 1; // ok
+ p-&gt;x.j = 1; // warn
+}
+</pre></td><td></td></tr>
+
+<tr><td><span class="name">undefbehavior.DeadDestructed
+<br>(C++)</span><br><br>
+Undefined behavior: the destructor is invoked for an object whose lifetime
+has ended
+</td><td><pre>
+class A {
+public:
+ void f() {};
+ A() {};
+ ~A() {};
+};
+
+void test() {
+ A a;
+ a.~A();
+} // warn
+</pre></td><td></td></tr>
+
+<tr><td><span class="name">undefbehavior.MethodCallBeforeBaseInit
+<br>(C++)</span><br><br>
+Undefined behavior: calls member function but base not yet initialized
+</td><td><pre>
+class A {
+public :
+ A(int );
+};
+class B : public A {
+public :
+ int f();
+ B() : A(f()) {} // warn
+};
+</pre></td><td></td></tr>
+
+<tr><td><span class="name">undefbehavior.MemberOrBaseRefBeforeCtor
+<br>(C++)</span><br><br>
+C++ Undefined behavior: non-static member or base class of non-POD class type
+is referred before constructor begins execution<br>
+C++11 Undefined behavior: non-static member or base class of a class with a
+non-trivial constructor is referred before constructor begins execution
+</td><td><pre>
+// C++03
+struct POD {
+ int i;
+};
+
+struct non_POD : public POD {
+ int j;
+ POD pod;
+};
+
+extern POD pod;
+extern non_POD non_pod;
+
+int *p1 = &non_pod.j; // warn
+int *p2 = &non_pod.pod.i; // warn
+int *p3 = &pod.i; // ok
+POD *p4 = & non_pod; // warn
+
+POD a;
+non_POD b;
+
+struct S {
+ int *k;
+ non_POD non_pod;
+ S() : k(&non_pod.j) {} // warn
+};
+
+// C++11
+struct trivial {
+ int i;
+};
+
+struct non_trivial: public trivial {
+ non_trivial() {};
+ int j;
+ trivial pod;
+};
+
+extern trivial t;
+extern non_trivial nt;
+
+int *p1 = &nt.j; // warn
+int *p2 = &nt.i; // warn
+int *p3 = &t.i; // ok
+trivial *p4 = &nt;
+
+trivial t;
+non_trivial nt;
+
+struct S {
+ int *k;
+ non_trivial nt;
+ S() : k(&nt.j) {} // warn
+};
+</pre></td><td></td></tr>
+
+<tr><td><span class="name">undefbehavior.MemberRefAfterDtor
+<br>(C++)</span><br><br>
+C++03: Undefined behavior: non-static member of non-POD class type is referred
+after destructor ends execution<br>
+C++11: Undefined behavior: non-static member of a class with a non-trivial
+destructor is referred after destructor ends execution
+</td><td><pre>
+// C++03
+struct non_POD {
+ virtual void f() {};
+};
+
+void test() {
+ non_POD *non_pod = new non_POD();
+ non_pod->~non_POD();
+ non_pod->f(); // warn
+}
+
+// C++11
+struct S {
+ ~S() {};
+ void f() {};
+};
+
+void test() {
+ S *s = new S();
+ s->~S();
+ s->f(); // warn
+}
+</pre></td><td></td></tr>
+
+<tr><td><span class="name">undefbehavior.CtorForeignCall
+<br>(C++)</span><br><br>
+Undefined behavior: call to virtual function of an object under construction
+whose type is neither the constructors own class or one of its bases
+</td><td><pre>
+class A {
+public:
+ virtual void f() {};
+};
+
+class B {
+public:
+ B(A* a) { a-&gt;f(); } // warn
+};
+
+class C : public A, B {
+public:
+ C() : B((A*)this) {}
+};
+</pre></td><td></td></tr>
+
+<tr><td><span class="name">undefbehavior.CtorForeignCast
+undefbehavior.CtorForeignTypeid
+<br>(C++)</span><br><br>
+Undefined behavior: the operand of typeid/dynamic_cast is an object under
+construction whose type is neither the constructors own class or one of its
+bases
+</td><td><pre>
+#include &lt;typeinfo&gt;
+
+class A {
+public:
+ virtual void f() {};
+};
+
+class B {
+public:
+ B(A* a) {
+ typeid(*a); // warn
+ dynamic_cast&lt;B*&gt;(a); //warn
+ }
+};
+
+class C : public A, B {
+public:
+ C() : B((A*)this) {}
+};
+</pre></td><td></td></tr>
+
+<tr><td><span class="name">undefbehavior.MemberRefInCatch
+undefbehavior.BaseRefInCatch
+<br>(C++)</span><br><br>
+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
+</td><td><pre>
+class C {
+ int i;
+public :
+ C()
+ try
+ : i(1) {}
+ catch (...)
+ {
+ i=2; // warn
+ }
+};
+</pre></td><td></td></tr>
+
+<tr><td><span class="name">undefbehavior.ReturnAtCatchEnd
+<br>(C++)</span><br><br>
+Undefined behavior: a function returns when control reaches the end of a
+handler. This results in undefined behavior in a value-returning
+function
+</td><td><pre>
+int test() try {
+}
+catch(int) {
+} // warn
+</pre></td><td></td></tr>
+
+<tr><td><span class="name">undefbehavior.AutoptrsOwnSameObj
+<br>(C++03)</span><br><br>
+Undefined behavior: if more than one auto_ptr owns the same object at the same
+time the behavior of the program is undefined.
+</td><td><pre>
+#include &lt;memory&gt;
+
+void test() {
+ int *data = new int;
+ std::auto_ptr&lt;int&gt; p(data);
+ std::auto_ptr&lt;int&gt; q(data); // warn
+}
+</pre></td><td></td></tr>
+
+<tr><td><span class="name">undefbehavior.BasicStringBoundAccess
+<br>(C++03)</span><br><br>
+Undefined behavior: out-of-bound basic_string access
+</td><td><pre>
+void test() {
+ std::basic_string&lt;char&gt; s;
+ char c = s[10]; // warn
+}
+</pre></td><td></td></tr>
+
+<tr><td><span class="name">undefbehavior.BasicStringBoundModification
+<br>(C++)</span><br><br>
+Undefined behavior: out-of-bound basic_string modification
+</td><td><pre>
+void test() {
+ std::basic_string&lt;char&gt; s;
+ s[10] = 0; // warn
+}
+</pre></td><td></td></tr>
+
+<tr><td><span class="name">undefbehavior.EosDereference
+<br>(C++)</span><br><br>
+Undefined behavior: the result of operator*() on an end of stream is
+undefined
+</td><td><pre>
+#include &lt;vector&gt;
+
+void test() {
+ std::vector&lt;int&gt; v;
+ int i = *v.end(); // warn
+ *v.end() = 0; // warn
+}
+</pre></td><td></td></tr>
+
+<tr><td><span class="name">undefbehavior.QsortNonPOD
+undefbehavior.QsortNonTrivial
+<br>C++</span><br><br>
+C++03: Undefined behavior: the objects in the array passed to qsort are of
+non-POD type<br>
+C++11: Undefined behavior: the objects in the array passed to qsort are of
+non-trivial type
+</td><td><pre>
+// C++03
+#include &lt;cstdlib&gt;
+
+struct non_POD {
+ int i;
+ non_POD(int ii) : i(ii) {}
+};
+
+non_POD values[] = { non_POD(2), non_POD(1) };
+
+int compare(const void *a,
+ const void *b) {
+ return ( (*(non_POD*)a).i -
+ (*(non_POD*)b).i );
+}
+
+void test() {
+ qsort(values, 2, sizeof(non_POD),
+ compare); // warn
+}
+
+// C++11
+#include &lt;cstdlib&gt;
+
+struct S {};
+
+struct trivial_non_POD : public S {
+ int i;
+};
+
+struct non_trivial {
+ int i;
+ non_trivial() {}
+};
+
+trivial_non_POD tnp[2];
+non_trivial nt[2];
+
+int compare1(const void *a,
+ const void *b) {
+ return ( (*(trivial_non_POD *)a).i -
+ (*(trivial_non_POD *)b).i );
+}
+
+int compare2(const void *a,
+ const void *b) {
+ return ( (*(non_trivial *)a).i -
+ (*(non_trivial *)b).i );
+}
+
+void test() {
+ qsort(tnp, 2, sizeof(trivial_non_POD),
+ compare1); // ok
+ qsort(nt, 2, sizeof(non_trivial),
+ compare2); // warn
+}
+</pre></td><td></td></tr>
+
+<tr><td><span class="name">undefbehavior.ThrowWhileCopy
+<br>C++</span><br><br>
+Undefined behavior: copy constructor/assignment operator can throw an exception.
+The effects are undefined if an exception is thrown.
+</td><td><pre>
+struct S {
+ int i, j;
+ S (const S &s) {
+ i = s.i;
+ throw 1; // warn
+ j = s.j;
+ };
+ S& operator=(const S &s) {
+ i = s.i;
+ throw 1; // warn
+ j = s.j;
+ }
+};
+</pre></td><td></td></tr>
+
+<tr><td><span class="name">undefbehavior.ValarrayArgBound
+<br>(C++)</span><br><br>
+Undefined behavior: the value of the second argument is greater than the number
+of values pointed to by the first argument
+</td><td><pre>
+#include &lt;valarray&gt;
+
+struct S {
+ int i;
+ S(int ii) : i(ii) {};
+};
+
+void test(void) {
+ S s[] = { S(1), S(2) };
+ std::valarray&lt;S&gt; v(s,3); // warn
+}
+</pre></td><td></td></tr>
+
+<tr><td><span class="name">undefbehavior.ValarrayLengthDiffer
+<br>(C++)</span><br><br>
+Undefined behavior: valarray operands are of different length
+</td><td><pre>
+// C++03
+#include &lt;valarray&gt;
+
+void test(void) {
+ std::valarray&lt;int&gt; a(0, 1), b(0, 2);
+ std::valarray&lt;bool&gt; c(false, 1);
+ a = b; // warn
+ a *= b; // warn
+ a = a * b; // warn
+ c = a == b; // warn
+ b.resize(1);
+ a = b; // OK
+}
+
+// C++11
+#include &lt;valarray&gt;
+
+void test(void) {
+ std::valarray&lt;int&gt; a(0, 1), b(0, 2);
+ std::valarray&lt;bool&gt; c(false, 1);
+ a = b; // ok
+ a *= b; // ok
+ a = a * b; // warn
+ c = a == b; // warn
+ b.resize(1);
+ a = b; // OK
+}
+</pre></td><td></td></tr>
+
+<tr><td><span class="name">undefbehavior.ValarrayZeroLength
+<br>(C++)</span><br><br>
+Undefined behavior: calling sum()/min()/max() method of an array having zero
+length, the behavior is undefined
+</td><td><pre>
+#include &lt;valarray&gt;
+
+void test(void) {
+ std::valarray&lt;int&gt; v(0, 0);
+ v.sum(); // warn
+ v.min(); // warn
+ v.max(); // warn
+}
+</pre></td><td></td></tr>
+
+<tr><td><span class="name">undefbehavior.ValarrayBadIndirection
+<br>(C++)</span><br><br>
+Undefined behavior: element N is specified more than once in the
+indirection
+</td><td><pre>
+#include &lt;valarray&gt;
+
+void test() {
+ size_t addr[] = {0, 1, 1}; // N is 1
+ std::valarray&lt;size_t&gt;indirect(addr, 3);
+ std::valarray&lt;int&gt; a(0, 5), b(1, 3);
+ a[indirect] = b; //warn
+ a[indirect] *= b; //warn
+}
+</pre></td><td></td></tr>
+
+<tr><td><span class="name">undefbehavior.IosBaseDestroyedBeforeInit
+<br>(C++)</span><br>
+<br>Undefined behavior: ios_base object is destroyed before initialization have
+taken place. basic_ios::init should be call to initialize ios_base
+members
+</td><td><pre>
+#include &lt;ios&gt;
+
+using namespace std;
+template &lt;class T, class Traits = std::char_traits&lt;T&gt;&gt;
+class my_stream1 : public std::basic_ios&lt;T, Traits&gt; {
+};
+
+template &lt;class T, class Traits = std::char_traits&lt;T&gt;&gt;
+class my_stream2 : public std::basic_ios&lt;T, Traits&gt; {
+ class my_streambuf : public std::basic_streambuf&lt;T, Traits&gt; {
+ };
+public:
+ my_stream2() {
+ this->init(new my_streambuf);
+ }
+};
+
+void test() {
+ my_stream1&lt;char&gt; *p1 = new my_stream1&lt;char&gt;
+ my_stream2&lt;char&gt; *p2 = new my_stream2&lt;char&gt;
+ delete p1; // warn
+ delete p2; // ok
+}
+</pre></td><td></td></tr>
+
+<tr><td><span class="name">undefbehavior.IosBaseUsedBeforeInit
+<br>(C++11)</span><br><br>
+Undefined behavior: ios_base object is used before initialization have taken
+place. basic_ios::init should be call to initialize ios_base members
+</td><td><pre>
+#include &lt;ios&gt;
+
+using namespace std;
+template &lt;class T, class Traits = std::char_traits&lt;T&gt;&gt;
+class my_stream1 : public std::basic_ios&lt;T, Traits&gt; {
+};
+
+template &lt;class T, class Traits = std::char_traits&lt;T&gt;&gt;
+class my_stream2 : public std::basic_ios&lt;T, Traits&gt; {
+ class my_streambuf : public std::basic_streambuf&lt;T, Traits&gt; {
+ };
+public:
+ my_stream2() {
+ this->init(new my_streambuf);
+ }
+};
+
+void test() {
+ my_stream1&lt;char&gt; *p1 = new my_stream1&lt;char&gt;
+ my_stream2&lt;char&gt; *p2 = new my_stream2&lt;char&gt;
+ p1->narrow('a', 'b'); // warn
+ p2->narrow('a', 'b'); // ok
+ delete p1; // warn
+ delete p2; // ok
+}
+</pre></td><td></td></tr>
+
+<tr><td><span class="name">undefbehavior.MinusOnePosType
+<br>(C++)</span><br><br>
+Undefined behavior: passing -1 to any streambuf/istream/ostream member that
+accepts a value of type traits::pos_type result in undefined behavior
+</td><td><pre>
+#include &lt;fstream&gt;
+
+class my_streambuf : public std::streambuf {
+ void f() {
+ seekpos(-1); // warn
+ }
+};
+
+void test() {
+ std::filebuf fb;
+ std::istream in(&fb);
+ std::ostream out(&fb);
+ std::filebuf::off_type pos(-1);
+ in.seekg(pos); // warn
+ out.seekp(-1); // warn
+}
+</pre></td><td></td></tr>
+</table>
+
+<!------------------------------- different ----------------------------------->
+<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>
+
+<tr><td><span class="name">different.ArgEvalOrderUndef
+<br>(C)</span><br><br>
+Errors because of the order of evaluation of function arguments is undefined
+</td><td><pre>
+void f(int, int);
+
+void test() {
+ int i = 0;
+ int v[1] = {0};
+ f(v[i], i++); // warn
+}
+</pre></td><td></td></tr>
+
+<tr><td><span class="name">different.IdenticalExprBinOp
+<br>(C)</span><br><br>
+There are identical sub-expressions to the left and to the right of the
+operator
+</td><td><pre>
+#define A 1
+#define B 1
+
+bool isNan(double d) {
+ return d != d; // ok
+}
+
+int f();
+
+void test() {
+ int i = 0;
+ if (i != 0 && i != 0) {} // warn
+
+ if(i == A || i == B) {} // ok
+
+ if (++i != 0 && ++i != 0) {} // ok
+
+ if (f() && f()) {} // ok
+}
+</pre></td><td></td></tr>
+
+<tr><td><span class="name">different.FuncPtrInsteadOfCall
+<br>(C)</span><br><br>
+Possibly a function call should be used instead of a pointer to function
+</td><td><pre>
+int f();
+
+void test() {
+ if (f == 0) {} // warn
+}
+</pre></td><td></td></tr>
+
+<tr><td><span class="name">different.IdenticalCondIfElseIf
+<br>(C)</span><br><br>
+The use of 'if (A) {...} else if (A) {...}' pattern was detected. There is a
+probability of logical error presence
+</td><td><pre>
+void test() {
+ int i = 7;
+ if (i == 1) {}
+ else if (i == 1) {} // warn
+}
+</pre></td><td></td></tr>
+
+<tr><td><span class="name">SuccessiveAssign
+<br>(C)</span><br><br>
+Successive assign to a variable
+</td><td><pre>
+void test() {
+ int i=0;
+ i=1;
+ i=2; // warn
+}
+</pre></td><td></td></tr>
+
+<tr><td><span class="name">different.NullDerefStmtOrder
+<br>enhancement to core.NullDereference<br>(C)</span><br><br>
+Dereferencing of the null pointer might take place. Checking the pointer for
+null should be performed first
+</td><td><pre>
+struct S {
+ int x;
+};
+
+S* f();
+
+void test() {
+ S *p1 = f();
+ int x1 = p1-&gt;x; // warn
+ if (p1) {};
+
+ S *p2 = f();
+ int x2 = p2-&gt;x; // ok
+}
+</pre></td><td></td></tr>
+
+<tr><td><span class="name">different.NullDerefCondOrder
+<br>enhancement to core.NullDereference<br>(C)</span><br><br>
+Dereferencing of the null pointer might take place. Checking the pointer for
+null should be performed first
+</td><td><pre>
+struct S{bool b;};
+
+S* f();
+
+void test() {
+ S *p = f();
+ if (p-&gt;b && p) {}; // warn
+}
+</pre></td><td&