diff options
author | Ted Kremenek <kremenek@apple.com> | 2012-10-06 05:09:43 +0000 |
---|---|---|
committer | Ted Kremenek <kremenek@apple.com> | 2012-10-06 05:09:43 +0000 |
commit | 41c1c717cf7de6f8f54f6504fe2f6556e9184d0b (patch) | |
tree | f627d56fd65a8176a61a0bcd1681048fa58583aa | |
parent | b1368c8089b707616cd76612d4f207e5dc0be22a (diff) |
Add list of potential checkers. Provided by Anton Yartsev!
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@165359 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | www/analyzer/content.css | 32 | ||||
-rw-r--r-- | www/analyzer/potential_checkers.html | 1645 |
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 <stdlib.h> + +int f() {}; + +void test() { + int *p1 = (int*)malloc(sizeof(int)); // warn + int *p2 = new int; // warn + int x = f(); + if (x==1) + return; + delete p2; +} +</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 <stdlib.h> + +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 <stdlib.h> + +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 <new> + +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 <stdlib.h> + +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 <stdlib.h> + +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 <stdlib.h> + +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 <string.h> + +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 <stdlib.h> + +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 <stdlib.h> +#include <memory> + +void test() { + std::auto_ptr<int> p1(new int); // Ok + std::auto_ptr<int> p2(new int[3]); // warn + std::auto_ptr<int> + 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 <cstdlib> + +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; // <- +} +</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 <stdlib.h> + +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 <stdlib.h> + +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 <new> + +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<A*>(b); // warn + dynamic_cast<A*>(b); // warn + delete b; // warn +} + +// C++11 +#include <new> + +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<A*>(b); // warn + dynamic_cast<A*>(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 <new> + +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 <stdlib.h> + +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<int *>(ciq); + *iq = 1; // warn + + const Y y; + Y* p = const_cast<Y*>(&y); + p->x.i = 1; // ok + p->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->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 <typeinfo> + +class A { +public: + virtual void f() {}; +}; + +class B { +public: + B(A* a) { + typeid(*a); // warn + dynamic_cast<B*>(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 <memory> + +void test() { + int *data = new int; + std::auto_ptr<int> p(data); + std::auto_ptr<int> 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<char> 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<char> 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 <vector> + +void test() { + std::vector<int> 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 <cstdlib> + +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 <cstdlib> + +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 <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 +} +</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 <valarray> + +void test(void) { + std::valarray<int> a(0, 1), b(0, 2); + std::valarray<bool> 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 <valarray> + +void test(void) { + std::valarray<int> a(0, 1), b(0, 2); + std::valarray<bool> 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 <valarray> + +void test(void) { + std::valarray<int> 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 <valarray> + +void test() { + size_t addr[] = {0, 1, 1}; // N is 1 + std::valarray<size_t>indirect(addr, 3); + std::valarray<int> 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 <ios> + +using namespace std; +template <class T, class Traits = std::char_traits<T>> +class my_stream1 : public std::basic_ios<T, Traits> { +}; + +template <class T, class Traits = std::char_traits<T>> +class my_stream2 : public std::basic_ios<T, Traits> { + class my_streambuf : public std::basic_streambuf<T, Traits> { + }; +public: + my_stream2() { + this->init(new my_streambuf); + } +}; + +void test() { + my_stream1<char> *p1 = new my_stream1<char> + my_stream2<char> *p2 = new my_stream2<char> + 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 <ios> + +using namespace std; +template <class T, class Traits = std::char_traits<T>> +class my_stream1 : public std::basic_ios<T, Traits> { +}; + +template <class T, class Traits = std::char_traits<T>> +class my_stream2 : public std::basic_ios<T, Traits> { + class my_streambuf : public std::basic_streambuf<T, Traits> { + }; +public: + my_stream2() { + this->init(new my_streambuf); + } +}; + +void test() { + my_stream1<char> *p1 = new my_stream1<char> + my_stream2<char> *p2 = new my_stream2<char> + p1->narrow('a', 'b'); // warn + p2->narrow('a', 'b'); // ok + delete p1; // warn + delete p2; // ok +} +</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 <fstream> + +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 < |