Home | History | Annotate | Download | only in analyzer
      1 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
      2           "http://www.w3.org/TR/html4/strict.dtd">
      3 <html>
      4 <head>
      5   <title>List of potential checkers</title>
      6   <link type="text/css" rel="stylesheet" href="content.css">
      7   <link type="text/css" rel="stylesheet" href="menu.css">
      8   <script type="text/javascript" src="scripts/menu.js"></script>
      9   <script type="text/javascript" src="scripts/dbtree.js"></script>
     10 </head>
     11 <body>
     12 
     13 <div id="page">
     14 
     15 <!-- menu -->
     16 <!--#include virtual="menu.html.incl"-->
     17 <!-- page content -->
     18 <div id="content">
     19 <h1>List of potential checkers</h1>
     20 
     21 <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>
     22 
     23 <!-- ========================= allocation/deallocation ======================= -->
     24 <h3>allocation/deallocation</h3>
     25 <table class="checkers">
     26 <col class="namedescr"><col class="example"><col class="progress">
     27 <thead><tr><td>Name, Description</td><td>Example</td><td>Progress</td></tr></thead>
     28 
     29 <tr><td><span class="name">memory.LeakNeverReleased<br>
     30 (C, C++)</span><br><br>
     31 Memory may be never released, potential leak of memory
     32 </td><td>
     33 <pre>
     34 #include &lt;stdlib.h&gt;
     35 
     36 int f() {};
     37 
     38 void test() { 
     39   int *p1 = (int*)malloc(sizeof(int)); // warn
     40   int *p2 = new int; // warn
     41   int x = f();
     42   if (x==1)
     43     return;
     44   delete p2;
     45 }
     46 </pre></td><td class="aligned"><a href="http://llvm.org/bugs/show_bug.cgi?id=15237">PR15237</a>
     47 </td></tr>
     48 
     49 <tr><td><span class="name">memory.MismatchedFree
     50 <br>enhancement to unix.Malloc<br>(C, C++)</span><br><br>
     51 Mismatched deallocation function is used
     52 </td><td><pre>
     53 #include &lt;stdlib.h&gt;
     54 
     55 void test() {
     56   int *p1 = new int;
     57   int *p2 = new int[1];
     58 
     59   free(p1); // warn
     60   free(p2); // warn
     61 }
     62 </pre></td><td class="aligned"><a href="http://llvm.org/bugs/show_bug.cgi?id=15238">PR15238</a>
     63 </td></tr>
     64 
     65 <tr><td><span class="name">memory.MismatchedDelete
     66 <br>(C, C++)</span><br><br>
     67 Mismatched deallocation function is used
     68 </td><td><pre>
     69 #include &lt;stdlib.h&gt;
     70 
     71 void test() {
     72   int *p1 = new int;
     73   int *p2 = new int[1];
     74   int *p3 = (int*)malloc(sizeof(int));
     75 
     76   delete[] p1; // warn
     77   delete p2; // warn
     78   delete p3; // warn
     79 }
     80 </pre></td><td class="aligned"><a href="http://llvm.org/bugs/show_bug.cgi?id=15238">PR15238</a>
     81 </td></tr>
     82 
     83 <tr><td><span class="name">memory.MultipleDelete
     84 <br>(C++)</span><br><br>
     85 Attempt to deallocate released memory
     86 </td><td><pre>
     87 #include &lt;new&gt;
     88 
     89 void test() {
     90   int *p1 = new int;
     91   int *p2 = new(p1) int;
     92   int *p3 = p1;
     93   delete p1;
     94   delete p1; // warn
     95   delete p2; // warn
     96   delete p3; // warn
     97 }
     98 </pre></td><td class="aligned"><a href="http://llvm.org/bugs/show_bug.cgi?id=15237">PR15237</a>
     99 </td></tr>
    100 
    101 
    102 <tr><td><span class="name">memory.LeakPtrValChanged
    103 <br>enhancement to unix.Malloc<br>(C, C++)</span><br><br>
    104 Potential memory leak: a pointer to newly allocated data loses its original 
    105 value
    106 </td><td><pre>
    107 #include &lt;stdlib.h&gt;
    108 
    109 void f(const int *);
    110 void g(int *);
    111 
    112 void test() {
    113   int *p1 = new int;
    114   p1++; // warn
    115   int *p2 = (int *)malloc(sizeof(int));
    116   p2 = p1; // warn
    117   int *p3 = new int;
    118   f(p3);
    119   p3++; // warn
    120   int *p4 = new int;
    121   f(p4);
    122   p4++; // ok
    123 }
    124 </pre></td><td class="aligned">done at r174678 (C case)
    125 </td></tr>
    126 
    127 
    128 <tr><td><span class="name">memory.DeallocateNonPtr
    129 <br>enhancement to unix.Malloc<br>(C, C++)</span><br><br>
    130 Deallocation function is applied to non-pointer
    131 </td><td><pre>
    132 #include &lt;stdlib.h&gt;
    133 
    134 class A {
    135   int *p;
    136 public:
    137   operator int *() { return p; }  
    138 };
    139 
    140 void test() {
    141   A a;
    142   delete a; // warn
    143   free(a); // warn
    144   const char *s = "text";
    145   delete s; // warn
    146   free(s); // warn
    147 }
    148 </pre></td><td class="aligned"><a href="http://llvm.org/bugs/show_bug.cgi?id=15237">PR15237</a>
    149 </td></tr>
    150 
    151 
    152 <tr><td><span class="name">memory.LeakEvalOrder<br>
    153 (C, C++)</span><br><br>
    154 Potential memory leak: argument evaluation order is undefined, g() may never be called
    155 </td><td><pre>
    156 #include &lt;stdlib.h&gt;
    157 
    158 void f1(int, int);
    159 void f2(int*, int*);
    160 int g(int *) { throw 1; };
    161 int h();
    162 
    163 void test() {
    164   f1(g(new int), h()); // warn
    165   f1(g((int *)malloc(sizeof(int))), h()); // warn
    166   f2(new int, new int);
    167 }
    168 </pre></td><td class="aligned"></td></tr>
    169 
    170 <tr><td><span class="name">memory.DstBufferTooSmall
    171 <br>(C, C++)</span><br><br>
    172 Destination buffer too small
    173 </td><td><pre>
    174 #include &lt;string.h&gt;
    175 
    176 void test() {
    177   const char* s1 = "abc";
    178   char *s2 = new char;
    179   strcpy(s2, s1); // warn
    180 
    181   int* p1 = new int[3];
    182   int* p2 = new int;
    183   memcpy(p2, p1, 3); // warn
    184 }
    185 </pre></td><td class="aligned"></td></tr>
    186 
    187 <tr><td><span class="name">memory.NegativeArraySize
    188 <br>enhancement to experimental.security.MallocOverflow<br>(C, C++)
    189 </span><br><br>
    190 'n' is used to specify the buffer size may be negative
    191 </td><td><pre>
    192 #include &lt;stdlib.h&gt;
    193 
    194 void test() {
    195   int *p;
    196   int n1 = -1;
    197   p = new int[n1]; // warn
    198 }
    199 </pre></td><td class="aligned"></td></tr>
    200 
    201 </table>
    202 
    203 <!-- ======================= constructors/destructors ====================== -->
    204 <h3>constructors/destructors</h3>
    205 <table class="checkers">
    206 <col class="namedescr"><col class="example"><col class="progress">
    207 <thead><tr><td>Name, Description</td><td>Example</td><td>Progress</td></tr></thead>
    208 
    209 <tr><td><span class="name">ctordtor.ExptInsideDtorExplicit<br>
    210 (C++)</span><br><br>
    211 It is dangerous to let an exception leave a destructor. Using try..catch will 
    212 solve the problem.
    213 </td><td><pre>
    214 void f();
    215 
    216 class A {
    217   A() {}
    218   ~A() { throw 1; } // warn
    219 };
    220 </pre></td><td class="aligned"></td></tr>
    221 
    222 <tr><td><span class="name">ctordtor.ExptInsideDtorImplicit<br>
    223 (C++)</span><br><br>
    224 Calls to functions inside a destructor that are known to throw exceptions is 
    225 dangerous. Using try..catch will solve the problem.
    226 </td><td><pre>
    227 void f() { throw 1; };
    228 
    229 class A {
    230   A() {}
    231   ~A() { f(); } // warn
    232 };
    233 </pre></td><td class="aligned"></td></tr>
    234 
    235 </table>
    236 
    237 <!-- ============================== exceptions ============================= -->
    238 <h3>exceptions</h3>
    239 <table class="checkers">
    240 <col class="namedescr"><col class="example"><col class="progress">
    241 <thead><tr><td>Name, Description</td><td>Example</td><td>Progress</td></tr></thead>
    242 
    243 <tr><td><span class="name">exceptions.ThrowSpecButNotThrow
    244 <br>(C++)</span><br><br>
    245 Function prototype has throw(T) specifier but the function do not throw
    246 </td><td><pre>
    247 void f() throw(int) { // warn
    248 }
    249 </pre></td><td class="aligned"></td></tr>
    250 
    251 <tr><td><span class="name">exceptions.NoThrowSpecButThrows
    252 <br>(C++)</span><br><br>
    253 An exception is throw from a function having the throw() specifier
    254 </td><td><pre>
    255 void f() throw() {
    256   throw(1); // warn
    257 }
    258 </pre></td><td class="aligned"></td></tr>
    259 
    260 <tr><td><span class="name">exceptions.ThrownTypeDiffersSpec
    261 <br>(C++)</span><br><br>
    262 The type of a thrown exception differs from those specified in the throw(T) 
    263 specifier
    264 </td><td><pre>
    265 struct S{};
    266 void f() throw(int) {
    267   S s;
    268   throw (s); // warn
    269 }
    270 </pre></td><td class="aligned"></td></tr>
    271 
    272 </table>
    273 
    274 <!-- ========================= smart pointers ============================== -->
    275 <h3>smart pointers</h3>
    276 <table class="checkers">
    277 <col class="namedescr"><col class="example"><col class="progress">
    278 <thead><tr><td>Name, Description</td><td>Example</td><td>Progress</td></tr></thead>
    279 
    280 <tr><td><span class="name">smartptr.SmartPtrInit<br>
    281 (C++)</span><br><br>
    282 C++03: auto_ptr should store a pointer to an object obtained via new as allocated
    283 memory will be cleaned using delete<br>
    284 C++11: one should use unique_ptr&lt;T[]&gt; to keep a pointer to memory
    285 allocated by new[]<br>
    286 C++11: to keep a pointer to memory allocated by new[] in a shared_ptr one
    287 should use a custom deleter that calls delete[]
    288 </td><td><pre>
    289 #include &lt;stdlib.h&gt;
    290 #include &lt;memory&gt;
    291 
    292 void test() {
    293   std::auto_ptr&lt;int&gt; p1(new int); // Ok
    294   std::auto_ptr&lt;int&gt; p2(new int[3]); // warn
    295   std::auto_ptr&lt;int&gt; 
    296          p3((int *)malloc(sizeof(int))); // warn
    297 }
    298 </pre></td><td class="aligned"></td></tr>
    299 
    300 </table>
    301 
    302 <!-- ========================= undefined behavior ========================== -->
    303 <h3>undefined behavior</h3>
    304 <table class="checkers">
    305 <col class="namedescr"><col class="example"><col class="progress">
    306 <thead><tr><td>Name, Description</td><td>Example</td><td>Progress</td></tr></thead>
    307 
    308 <tr><td><span class="name">undefbehavior.ExitInDtor
    309 <br>(C++)</span><br><br>
    310 Undefined behavior: std::exit is called to end the program during the 
    311 destruction of an object with static storage duration
    312 </td><td><pre>
    313 #include &lt;cstdlib&gt;
    314 
    315 class A {
    316 public:
    317   ~A() {
    318     std::exit(1); // warn
    319   }
    320 };
    321 
    322 A a;
    323 </pre></td><td class="aligned"></td></tr>
    324 
    325 <tr><td><span class="name">undefbehavior.LocalStaticDestroyed
    326 <br>(C++)</span><br><br>
    327 Undefined behavior: function containing a definition of static local object is 
    328 called during the destruction of an object with static storage duration so that 
    329 flow of control passes through the definition of the previously destroyed 
    330 static local object
    331 </td><td><pre>
    332 void f();
    333 
    334 class A {
    335 public:
    336   ~A() {
    337     f(); // warn
    338   }
    339 };
    340 
    341 class B {};
    342 
    343 A a;
    344 
    345 void f() {
    346   static B b; // &lt;-
    347 }
    348 </pre></td><td class="aligned"></td></tr>
    349 
    350 <tr><td><span class="name">undefbehavior.UseAfterRelease
    351 <br>enhancement to unix.Malloc<br>(C, C++)</span><br><br>
    352 Pointer to deleted object is referenced (The effect of using an invalid pointer 
    353 value is undefined)
    354 </td><td><pre>
    355 #include &lt;stdlib.h&gt;
    356 
    357 void test() {
    358   int *p = new int;
    359   delete p;
    360   int i = *p; // warn
    361 }
    362 
    363 </pre></td><td class="aligned"></td></tr>
    364 
    365 <tr><td><span class="name">undefbehavior.ZeroAllocDereference
    366 <br>enhancement to unix.Malloc<br>(C, C++)</span><br><br>
    367 The effect of dereferencing a pointer returned as a request for zero size is 
    368 undefined
    369 </td><td><pre>
    370 #include &lt;stdlib.h&gt;
    371 
    372 int *p = new int[0];
    373 int i = p[0]; // warn
    374 </pre></td><td class="aligned"></td></tr>
    375 
    376 <tr><td><span class="name">undefbehavior.DeadReferenced
    377 <br>(C++)</span><br><br>
    378 Undefined behavior: the following usage of the pointer to the object whose 
    379 lifetime has ended can result in undefined behavior
    380 </td><td><pre>
    381 // C++03
    382 #include &lt;new&gt;
    383 
    384 class A {
    385 public:
    386   int i;
    387   void f() {};
    388 };
    389 
    390 class B : public A {
    391 };
    392 
    393 void test() {
    394   B *b = new B;
    395   new(b) A;
    396   b->i; // warn
    397   b->f(); // warn
    398   static_cast&lt;A*&gt;(b); // warn
    399   dynamic_cast&lt;A*&gt;(b); // warn
    400   delete b; // warn
    401 }
    402 
    403 // C++11
    404 #include &lt;new&gt;
    405 
    406 class A {
    407 public:
    408   int i;
    409   void f() {};
    410 };
    411 
    412 class B : public A {
    413 public:
    414   ~B() {};
    415 };
    416 
    417 void test() {
    418   A *a = new A;
    419   new(a) B;
    420   a->i; // warn
    421   a->f(); // warn
    422   B *b = new B;
    423   new(b) A;
    424   b->i; // warn
    425   b->f(); // warn
    426   static_cast&lt;A*&gt;(b); // warn
    427   dynamic_cast&lt;A*&gt;(b); // warn
    428   delete b; // warn
    429 }
    430 </pre></td><td class="aligned"></td></tr>
    431 
    432 <tr><td><span class="name">undefbehavior.ObjLocChanges
    433 <br>(C++)</span><br><br>
    434 Undefined behavior: the program must ensure that an object occupies the same 
    435 storage location when the implicit or explicit destructor call takes place
    436 </td><td><pre>
    437 #include &lt;new&gt;
    438 
    439 class T { };
    440 struct B {
    441   ~B();
    442 };
    443 
    444 void test() {
    445   B *b1 = new B;
    446   B b2;
    447   new (b1) T;
    448   new (&amp;b2) T;
    449   delete b1; // warn
    450 } // warn
    451 </pre></td><td class="aligned"></td></tr>
    452 
    453 <tr><td><span class="name">undefbehavior.ExprEvalOrderUndef
    454 <br>(C, C++03)</span><br><br>
    455 Undefined behavior: a scalar object shall have its stored value modified at 
    456 most once by the evaluation of an expression
    457 </td><td><pre>
    458 void test () {
    459   int i = 0;
    460   int v[1] = {0};
    461   i = v[i++]; // warn
    462   i = ++i + 1; // warn
    463 }
    464 </pre></td><td class="aligned"></td></tr>
    465 
    466 <tr><td><span class="name">undefbehavior.StaticInitReentered
    467 <br>(C)</span><br><br>
    468 Undefined behavior: static declaration is re-entered while the object is being 
    469 initialized
    470 </td><td><pre>
    471 int test(int i) {
    472   static int s = test(2*i); // warn
    473   return i+1;
    474 }
    475 </pre></td><td class="aligned"></td></tr>
    476 
    477 <tr><td><span class="name">undefbehavior.ConstModified
    478 <br>(C, C++)</span><br><br>
    479 Undefined behavior: const object is being modified
    480 </td><td><pre>
    481 #include &lt;stdlib.h&gt;
    482 
    483 class X {
    484 public :
    485   mutable int i;
    486   int j;
    487 };
    488 class Y {
    489 public :
    490   X x;
    491   Y();
    492 };
    493 
    494 void test() {
    495   const int *ciq = 
    496     (int *)malloc(sizeof(int));
    497   int *iq = const_cast&lt;int *&gt;(ciq);
    498   *iq = 1; // warn
    499 
    500   const Y y;
    501   Y* p = const_cast&lt;Y*&gt;(&amp;y);
    502   p-&gt;x.i = 1; // ok
    503   p-&gt;x.j = 1; // warn
    504 }
    505 </pre></td><td class="aligned"></td></tr>
    506 
    507 <tr><td><span class="name">undefbehavior.DeadDestructed
    508 <br>(C++)</span><br><br>
    509 Undefined behavior: the destructor is invoked for an object whose lifetime 
    510 has ended
    511 </td><td><pre>
    512 class A {
    513 public:
    514   void f() {};
    515   A() {};
    516   ~A() {};
    517 };
    518 
    519 void test() {
    520   A a;
    521   a.~A();
    522 } // warn
    523 </pre></td><td class="aligned"></td></tr>
    524 
    525 <tr><td><span class="name">undefbehavior.MethodCallBeforeBaseInit
    526 <br>(C++)</span><br><br>
    527 Undefined behavior: calls member function but base not yet initialized
    528 </td><td><pre>
    529 class A {
    530 public :
    531   A(int );
    532 };
    533 class B : public A {
    534 public :
    535   int f();
    536   B() : A(f()) {} // warn
    537 };
    538 </pre></td><td class="aligned"></td></tr>
    539 
    540 <tr><td><span class="name">undefbehavior.MemberOrBaseRefBeforeCtor
    541 <br>(C++)</span><br><br>
    542 C++ Undefined behavior: non-static member or base class of non-POD class type 
    543 is referred before constructor begins execution<br>
    544 C++11 Undefined behavior: non-static member or base class of a class with a 
    545 non-trivial constructor is referred before constructor begins execution
    546 </td><td><pre>
    547 // C++03
    548 struct POD { 
    549   int i; 
    550 };
    551 
    552 struct non_POD : public POD { 
    553   int j; 
    554   POD pod;
    555 };
    556 
    557 extern POD pod;
    558 extern non_POD non_pod;
    559 
    560 int *p1 = &amp;non_pod.j; // warn
    561 int *p2 = &amp;non_pod.pod.i; // warn
    562 int *p3 = &amp;pod.i; // ok
    563 POD *p4 = &amp;non_pod; // warn
    564 
    565 POD a;
    566 non_POD b;
    567 
    568 struct S {
    569   int *k;
    570   non_POD non_pod;
    571   S() : k(&amp;non_pod.j) {} // warn
    572 };
    573 
    574 // C++11
    575 struct trivial { 
    576   int i; 
    577 };
    578 
    579 struct non_trivial: public trivial { 
    580   non_trivial() {};
    581   int j; 
    582   trivial pod;
    583 };
    584 
    585 extern trivial t;
    586 extern non_trivial nt;
    587 
    588 int *p1 = &amp;nt.j; // warn
    589 int *p2 = &amp;nt.i; // warn
    590 int *p3 = &amp;t.i; // ok
    591 trivial *p4 = &amp;nt;
    592 
    593 trivial t;
    594 non_trivial nt;
    595 
    596 struct S {
    597   int *k;
    598   non_trivial nt;
    599   S() : k(&amp;nt.j) {} // warn
    600 };
    601 </pre></td><td class="aligned"></td></tr>
    602 
    603 <tr><td><span class="name">undefbehavior.MemberRefAfterDtor
    604 <br>(C++)</span><br><br>
    605 C++03: Undefined behavior: non-static member of non-POD class type is referred 
    606 after destructor ends execution<br>
    607 C++11: Undefined behavior: non-static member of a class with a non-trivial 
    608 destructor is referred after destructor ends execution
    609 </td><td><pre>
    610 // C++03
    611 struct non_POD {
    612   virtual void f() {};
    613 };
    614 
    615 void test() {
    616   non_POD *non_pod = new non_POD();
    617   non_pod->~non_POD();  
    618   non_pod->f(); // warn
    619 }
    620 
    621 // C++11
    622 struct S {
    623   ~S() {};
    624   void f() {};
    625 };
    626 
    627 void test() {
    628   S *s = new S();
    629   s->~S();  
    630   s->f(); // warn
    631 }
    632 </pre></td><td class="aligned"></td></tr>
    633 
    634 <tr><td><span class="name">undefbehavior.CtorForeignCall
    635 <br>(C++)</span><br><br>
    636 Undefined behavior: call to virtual function of an object under construction 
    637 whose type is neither the constructors own class or one of its bases
    638 </td><td><pre>
    639 class A {
    640 public:
    641   virtual void f() {};
    642 };
    643 
    644 class B {
    645 public:
    646   B(A* a) { a-&gt;f(); } // warn
    647 };
    648 
    649 class C : public A, B {
    650 public:
    651   C() : B((A*)this) {}
    652 };
    653 </pre></td><td class="aligned"></td></tr>
    654 
    655 <tr><td><span class="name">undefbehavior.CtorForeignCast 
    656 undefbehavior.CtorForeignTypeid
    657 <br>(C++)</span><br><br>
    658 Undefined behavior: the operand of typeid/dynamic_cast is an object under 
    659 construction whose type is neither the constructors own class or one of its 
    660 bases
    661 </td><td><pre>
    662 #include &lt;typeinfo&gt;
    663 
    664 class A {
    665 public:
    666   virtual void f() {};
    667 };
    668 
    669 class B {
    670 public:
    671   B(A* a) { 
    672     typeid(*a); // warn
    673     dynamic_cast&lt;B*&gt;(a); //warn
    674   }
    675 };
    676 
    677 class C : public A, B {
    678 public:
    679   C() : B((A*)this) {}
    680 };
    681 </pre></td><td class="aligned"></td></tr>
    682 
    683 <tr><td><span class="name">undefbehavior.MemberRefInCatch 
    684 undefbehavior.BaseRefInCatch
    685 <br>(C++)</span><br><br>
    686 Undefined behavior: referring to any non-static member or base class of an 
    687 object in the handler for a function-try-block of a constructor or destructor 
    688 for that object results in undefined behavior
    689 </td><td><pre>
    690 class C {
    691   int i;
    692 public :
    693   C()
    694   try
    695   : i(1) {}
    696   catch (...)
    697   {
    698     i=2; // warn
    699   }
    700 };
    701 </pre></td><td class="aligned"></td></tr>
    702 
    703 <tr><td><span class="name">undefbehavior.ReturnAtCatchEnd
    704 <br>(C++)</span><br><br>
    705 Undefined behavior: a function returns when control reaches the end of a 
    706 handler. This results in undefined behavior in a value-returning 
    707 function
    708 </td><td><pre>
    709 int test() try {
    710 }
    711 catch(int) {
    712 } // warn
    713 </pre></td><td class="aligned"></td></tr>
    714 
    715 <tr><td><span class="name">undefbehavior.AutoptrsOwnSameObj
    716 <br>(C++03)</span><br><br>
    717 Undefined behavior: if more than one auto_ptr owns the same object at the same 
    718 time the behavior of the program is undefined.
    719 </td><td><pre>
    720 #include &lt;memory&gt;
    721 
    722 void test() {
    723   int *data = new int;
    724   std::auto_ptr&lt;int&gt; p(data);
    725   std::auto_ptr&lt;int&gt; q(data); // warn
    726 }
    727 </pre></td><td class="aligned"></td></tr>
    728 
    729 <tr><td><span class="name">undefbehavior.BasicStringBoundAccess
    730 <br>(C++03)</span><br><br>
    731 Undefined behavior: out-of-bound basic_string access
    732 </td><td><pre>
    733 void test() {
    734   std::basic_string&lt;char&gt; s;
    735   char c = s[10]; // warn
    736 }
    737 </pre></td><td class="aligned"></td></tr>
    738 
    739 <tr><td><span class="name">undefbehavior.BasicStringBoundModification
    740 <br>(C++)</span><br><br>
    741 Undefined behavior: out-of-bound basic_string modification
    742 </td><td><pre>
    743 void test() {
    744   std::basic_string&lt;char&gt; s;
    745   s[10] = 0; // warn
    746 }
    747 </pre></td><td class="aligned"></td></tr>
    748 
    749 <tr><td><span class="name">undefbehavior.EosDereference
    750 <br>(C++)</span><br><br>
    751 Undefined behavior: the result of operator*() on an end of stream is 
    752 undefined
    753 </td><td><pre>
    754 #include &lt;vector&gt;
    755 
    756 void test() {
    757   std::vector&lt;int&gt; v;
    758   int i = *v.end(); // warn
    759   *v.end() = 0; // warn
    760 }
    761 </pre></td><td class="aligned"></td></tr>
    762 
    763 <tr><td><span class="name">undefbehavior.QsortNonPOD 
    764 undefbehavior.QsortNonTrivial
    765 <br>C++</span><br><br>
    766 C++03: Undefined behavior: the objects in the array passed to qsort are of 
    767 non-POD type<br>
    768 C++11: Undefined behavior: the objects in the array passed to qsort are of 
    769 non-trivial type
    770 </td><td><pre>
    771 // C++03
    772 #include &lt;cstdlib&gt;
    773 
    774 struct non_POD {
    775   int i;
    776   non_POD(int ii) : i(ii) {}
    777 };
    778 
    779 non_POD values[] = { non_POD(2), non_POD(1) };
    780 
    781 int compare(const void *a, 
    782             const void *b) {
    783   return ( (*(non_POD*)a).i -
    784            (*(non_POD*)b).i );
    785 }
    786 
    787 void test() {
    788   qsort(values, 2, sizeof(non_POD), 
    789         compare); // warn
    790 }
    791 
    792 // C++11
    793 #include &lt;cstdlib&gt;
    794 
    795 struct S {};
    796 
    797 struct trivial_non_POD : public S {
    798   int i;
    799 };
    800 
    801 struct non_trivial {
    802   int i;
    803   non_trivial() {}
    804 };
    805 
    806 trivial_non_POD tnp[2];
    807 non_trivial nt[2];
    808 
    809 int compare1(const void *a, 
    810              const void *b) {
    811   return ( (*(trivial_non_POD *)a).i -
    812            (*(trivial_non_POD *)b).i );
    813 }
    814 
    815 int compare2(const void *a, 
    816              const void *b) {
    817   return ( (*(non_trivial *)a).i -
    818            (*(non_trivial *)b).i );
    819 }
    820 
    821 void test() {
    822   qsort(tnp, 2, sizeof(trivial_non_POD), 
    823         compare1); // ok
    824   qsort(nt, 2, sizeof(non_trivial), 
    825         compare2); // warn
    826 }
    827 </pre></td><td class="aligned"></td></tr>
    828 
    829 <tr><td><span class="name">undefbehavior.ThrowWhileCopy
    830 <br>C++</span><br><br>
    831 Undefined behavior: copy constructor/assignment operator can throw an exception.
    832 The effects are undefined if an exception is thrown.
    833 </td><td><pre>
    834 struct S {
    835   int i, j;
    836   S (const S &amp;s) {
    837     i = s.i;
    838     throw 1; // warn
    839     j = s.j;
    840   };
    841   S &amp;operator=(const S &amp;s) {
    842     i = s.i;
    843     throw 1; // warn
    844     j = s.j;
    845   }
    846 };
    847 </pre></td><td class="aligned"></td></tr>
    848 
    849 <tr><td><span class="name">undefbehavior.ValarrayArgBound
    850 <br>(C++)</span><br><br>
    851 Undefined behavior: the value of the second argument is greater than the number 
    852 of values pointed to by the first argument
    853 </td><td><pre>
    854 #include &lt;valarray&gt;
    855 
    856 struct S {
    857   int i;
    858   S(int ii) : i(ii) {};
    859 };
    860 
    861 void test(void) {
    862   S s[] = { S(1), S(2) };
    863   std::valarray&lt;S&gt; v(s,3); // warn
    864 }
    865 </pre></td><td class="aligned"></td></tr>
    866 
    867 <tr><td><span class="name">undefbehavior.ValarrayLengthDiffer
    868 <br>(C++)</span><br><br>
    869 Undefined behavior: valarray operands are of different length
    870 </td><td><pre>
    871 // C++03
    872 #include &lt;valarray&gt;
    873 
    874 void test(void) {
    875   std::valarray&lt;int&gt; a(0, 1), b(0, 2);
    876   std::valarray&lt;bool&gt; c(false, 1);
    877   a = b; // warn
    878   a *= b; // warn
    879   a = a * b; // warn
    880   c = a == b; // warn
    881   b.resize(1);
    882   a = b; // OK
    883 }
    884 
    885 // C++11
    886 #include &lt;valarray&gt;
    887 
    888 void test(void) {
    889   std::valarray&lt;int&gt; a(0, 1), b(0, 2);
    890   std::valarray&lt;bool&gt; c(false, 1);
    891   a = b; // ok
    892   a *= b; // ok
    893   a = a * b; // warn
    894   c = a == b; // warn
    895   b.resize(1);
    896   a = b; // OK
    897 }
    898 </pre></td><td class="aligned"></td></tr>
    899 
    900 <tr><td><span class="name">undefbehavior.ValarrayZeroLength
    901 <br>(C++)</span><br><br>
    902 Undefined behavior: calling sum()/min()/max() method of an array having zero 
    903 length, the behavior is undefined
    904 </td><td><pre>
    905 #include &lt;valarray&gt;
    906 
    907 void test(void) {
    908   std::valarray&lt;int&gt; v(0, 0);
    909   v.sum(); // warn
    910   v.min(); // warn
    911   v.max(); // warn
    912 }
    913 </pre></td><td class="aligned"></td></tr>
    914 
    915 <tr><td><span class="name">undefbehavior.ValarrayBadIndirection
    916 <br>(C++)</span><br><br>
    917 Undefined behavior: element N is specified more than once in the 
    918 indirection
    919 </td><td><pre>
    920 #include &lt;valarray&gt;
    921 
    922 void test() {
    923   size_t addr[] = {0, 1, 1}; // N is 1
    924   std::valarray&lt;size_t&gt;indirect(addr, 3);
    925   std::valarray&lt;int&gt; a(0, 5), b(1, 3);
    926   a[indirect] = b; //warn
    927   a[indirect] *= b; //warn
    928 }
    929 </pre></td><td class="aligned"></td></tr>
    930 
    931 <tr><td><span class="name">undefbehavior.IosBaseDestroyedBeforeInit
    932 <br>(C++)</span><br>
    933 <br>Undefined behavior: ios_base object is destroyed before initialization have 
    934 taken place. basic_ios::init should be call to initialize ios_base 
    935 members
    936 </td><td><pre>
    937 #include &lt;ios&gt;
    938 
    939 using namespace std;
    940 template &lt;class T, class Traits = std::char_traits&lt;T&gt;&gt;
    941 class my_stream1 : public std::basic_ios&lt;T, Traits&gt; {
    942 };
    943 
    944 template &lt;class T, class Traits = std::char_traits&lt;T&gt;&gt;
    945 class my_stream2 : public std::basic_ios&lt;T, Traits&gt; {
    946   class my_streambuf : public std::basic_streambuf&lt;T, Traits&gt; {
    947   };
    948 public:
    949   my_stream2() {
    950     this->init(new my_streambuf);
    951   }
    952 };
    953 
    954 void test() {
    955   my_stream1&lt;char&gt; *p1 = new my_stream1&lt;char&gt;
    956   my_stream2&lt;char&gt; *p2 = new my_stream2&lt;char&gt;
    957   delete p1; // warn
    958   delete p2; // ok
    959 }
    960 </pre></td><td class="aligned"></td></tr>
    961 
    962 <tr><td><span class="name">undefbehavior.IosBaseUsedBeforeInit
    963 <br>(C++11)</span><br><br>
    964 Undefined behavior: ios_base object is used before initialization have taken 
    965 place. basic_ios::init should be call to initialize ios_base members
    966 </td><td><pre>
    967 #include &lt;ios&gt;
    968 
    969 using namespace std;
    970 template &lt;class T, class Traits = std::char_traits&lt;T&gt;&gt;
    971 class my_stream1 : public std::basic_ios&lt;T, Traits&gt; {
    972 };
    973 
    974 template &lt;class T, class Traits = std::char_traits&lt;T&gt;&gt;
    975 class my_stream2 : public std::basic_ios&lt;T, Traits&gt; {
    976   class my_streambuf : public std::basic_streambuf&lt;T, Traits&gt; {
    977   };
    978 public:
    979   my_stream2() {
    980     this->init(new my_streambuf);
    981   }
    982 };
    983 
    984 void test() {
    985   my_stream1&lt;char&gt; *p1 = new my_stream1&lt;char&gt;
    986   my_stream2&lt;char&gt; *p2 = new my_stream2&lt;char&gt;
    987   p1->narrow('a', 'b'); // warn
    988   p2->narrow('a', 'b'); // ok
    989   delete p1; // warn
    990   delete p2; // ok
    991 }
    992 </pre></td><td class="aligned"></td></tr>
    993 
    994 <tr><td><span class="name">undefbehavior.MinusOnePosType
    995 <br>(C++)</span><br><br>
    996 Undefined behavior: passing -1 to any streambuf/istream/ostream member that 
    997 accepts a value of type traits::pos_type result in undefined behavior
    998 </td><td><pre>
    999 #include &lt;fstream&gt;
   1000 
   1001 class my_streambuf : public std::streambuf {
   1002   void f() {
   1003     seekpos(-1); // warn
   1004   }
   1005 };
   1006 
   1007 void test() {
   1008   std::filebuf fb;
   1009   std::istream in(&amp;fb);
   1010   std::ostream out(&amp;fb);
   1011   std::filebuf::off_type pos(-1);
   1012   in.seekg(pos); // warn
   1013   out.seekp(-1); // warn
   1014 }
   1015 </pre></td><td class="aligned"></td></tr>
   1016 </table>
   1017 
   1018 <!-- ============================ different ================================ -->
   1019 <h3>different</h3>
   1020 <table class="checkers">
   1021 <col class="namedescr"><col class="example"><col class="progress">
   1022 <thead><tr><td>Name, Description</td><td>Example</td><td>Progress</td></tr>
   1023 </thead>
   1024 
   1025 <tr><td><span class="name">different.ArgEvalOrderUndef
   1026 <br>(C)</span><br><br>
   1027 Errors because of the order of evaluation of function arguments is undefined
   1028 </td><td><pre>
   1029 void f(int, int);
   1030 
   1031 void test() {
   1032   int i = 0;
   1033   int v[1] = {0};
   1034   f(v[i], i++); // warn
   1035 }
   1036 </pre></td><td class="aligned"></td></tr>
   1037 
   1038 <tr><td><span class="name">different.IdenticalExprBinOp
   1039 <br>(C)</span><br><br>
   1040 There are identical sub-expressions to the left and to the right of the 
   1041 operator
   1042 </td><td><pre>
   1043 #define A 1
   1044 #define B 1
   1045 
   1046 bool isNan(double d) { 
   1047   return d != d; // ok
   1048 }
   1049 
   1050 int f();
   1051 
   1052 void test() {
   1053   int i = 0;
   1054   if (i != 0 && i != 0) {} // warn
   1055 
   1056   if(i == A || i == B) {} // ok
   1057 
   1058   if (++i != 0 && ++i != 0) {} // ok
   1059 
   1060   if (f() && f()) {} // ok
   1061 }
   1062 </pre></td><td class="aligned"></td></tr>
   1063 
   1064 <tr><td><span class="name">different.FuncPtrInsteadOfCall
   1065 <br>(C)</span><br><br>
   1066 Possibly a function call should be used instead of a pointer to function
   1067 </td><td><pre>
   1068 int f();
   1069 
   1070 void test() {
   1071   if (f == 0) {} // warn
   1072 }
   1073 </pre></td><td class="aligned"></td></tr>
   1074 
   1075 <tr><td><span class="name">different.IdenticalCondIfElseIf
   1076 <br>(C)</span><br><br>
   1077 The use of 'if (A) {...} else if (A) {...}' pattern was detected. There is a 
   1078 probability of logical error presence
   1079 </td><td><pre>
   1080 void test() { 
   1081   int i = 7;
   1082   if (i == 1) {}
   1083   else if (i == 1) {} // warn
   1084 }
   1085 </pre></td><td class="aligned"></td></tr>
   1086 
   1087 <tr><td><span class="name">SuccessiveAssign
   1088 <br>(C)</span><br><br>
   1089 Successive assign to a variable
   1090 </td><td><pre>
   1091 void test() { 
   1092   int i=0;
   1093   i=1;
   1094   i=2; // warn
   1095 }
   1096 </pre></td><td class="aligned"></td></tr>
   1097 
   1098 <tr><td><span class="name">different.NullDerefStmtOrder
   1099 <br>enhancement to core.NullDereference<br>(C)</span><br><br>
   1100 Dereferencing of the null pointer might take place. Checking the pointer for 
   1101 null should be performed first
   1102 </td><td><pre>
   1103 struct S {
   1104   int x;
   1105 };
   1106 
   1107 S* f();
   1108 
   1109 void test() {
   1110   S *p1 = f();
   1111   int x1 = p1-&gt;x; // warn
   1112   if (p1) {};
   1113 
   1114   S *p2 = f();
   1115   int x2 = p2-&gt;x; // ok
   1116 }
   1117 </pre></td><td class="aligned"></td></tr>
   1118 
   1119 <tr><td><span class="name">different.NullDerefCondOrder
   1120 <br>enhancement to core.NullDereference<br>(C)</span><br><br>
   1121 Dereferencing of the null pointer might take place. Checking the pointer for 
   1122 null should be performed first
   1123 </td><td><pre>
   1124 struct S{bool b;};
   1125 
   1126 S* f();
   1127 
   1128 void test() {
   1129   S *p = f();
   1130   if (p-&gt;b && p) {}; // warn
   1131 }
   1132 </pre></td><td class="aligned"></td></tr>
   1133 
   1134 <tr><td><span class="name">different.IdenticalStmtThenElse
   1135 <br>(C)</span><br><br>
   1136 The 'else' statement is equivalent to the 'then' statement
   1137 </td><td><pre>
   1138 void test() {
   1139   int i;
   1140   if (i==1) {
   1141     i++;
   1142   }
   1143   else { // warn
   1144     i++;
   1145   }
   1146 }
   1147 </pre></td><td class="aligned"></td></tr>
   1148 
   1149 <tr><td><span class="name">different.MultipleAccessors
   1150 <br>(C++)</span><br><br>
   1151 multiple accessors met for 'class::field'
   1152 </td><td><pre>
   1153 class A {
   1154   int i;
   1155   int j;
   1156 public:
   1157   int getI() { return i; }
   1158   int getJ() { return i; } // warn
   1159   void setI(int& ii) { i = ii; }
   1160   void setJ(int& jj) { i = jj; } // warn
   1161 };
   1162 </pre></td><td class="aligned"></td></tr>
   1163 
   1164 <tr><td><span class="name">different.AccessorsForPublic
   1165 <br>(C++)</span><br><br>
   1166 Accessors exist for 'class::field'. Should this field really be public?
   1167 </td><td><pre>
   1168 class A {
   1169 public:
   1170   int i; // warn
   1171   int getI() { return i; }
   1172   void setI(int& ii) { i = ii; }
   1173 };
   1174 </pre></td><td class="aligned"></td></tr>
   1175 
   1176 <tr><td><span class="name">different.LibFuncResultUnised
   1177 <br>(C, C++)</span><br><br>
   1178 Calling 'f' ignoring its return value is of no use (* create the list of known 
   1179 system/library/API functions falling into this category)
   1180 </td><td><pre>
   1181 #include &lt;vector&gt;
   1182 
   1183 void test() {
   1184   std::vector&lt;int&gt; v;
   1185   v.empty(); // warn
   1186 }
   1187 </pre></td><td class="aligned"></td></tr>
   1188 
   1189 <tr><td><span class="name">different.WrongVarForStmt
   1190 <br>(C, C++)</span><br><br>
   1191 Possibly wrong variable is used in the loop/cond-expression of the 'for'
   1192 statement. Did you mean 'proper_variable_name'?
   1193 </td><td><pre>
   1194 void test() {
   1195   int i;
   1196   int j;
   1197   for (j=0; j&lt;3; ++i); // warn
   1198   for (int j=0; i&lt;3; ++j); // warn
   1199 }
   1200 </pre></td><td class="aligned"></td></tr>
   1201 
   1202 <tr><td><span class="name">different.FloatingCompare
   1203 <br>(C)</span><br><br>
   1204 Comparing floating point numbers may be not precise
   1205 </td><td><pre>
   1206 #include &lt;math.h&gt;
   1207 
   1208 void test() {
   1209   double b = sin(M_PI / 6.0);
   1210   if (b == 0.5) // warn
   1211     b = 0;
   1212 }
   1213 </pre></td><td class="aligned"></td></tr>
   1214 
   1215 <tr><td><span class="name">different.BoolCompare
   1216 <br>maybe merge with experimental.core.BoolAssignment<br>(C, C++)</span><br><br>
   1217 Comparing boolean to a value other then 0 or 1
   1218 </td><td><pre>
   1219 void test() {
   1220   int i;
   1221   if (0 < i < 3) {}; // warn
   1222   bool b;
   1223   if (b == 3) {}; // warn
   1224 }
   1225 </pre></td><td class="aligned"></td></tr>
   1226 
   1227 <tr><td><span class="name">different.BitwiseOpBoolArg
   1228 <br>maybe join with experimental.core.BoolAssignment<br>(C, C++)</span><br><br>
   1229 bool value is used at the left/right part of the &amp; (|) operator. Did you mean 
   1230 &amp;&amp; (||) ?
   1231 </td><td><pre>
   1232 int f();
   1233 
   1234 void test() {
   1235   bool b = true;
   1236   if (b &amp; f()) {} // warn
   1237 }
   1238 </pre></td><td class="aligned"></td></tr>
   1239 
   1240 <tr><td><span class="name">different.LabelInsideSwitch
   1241 <br>(C)</span><br><br>
   1242 Possible misprint: label found inside the switch() statement. (* did you mean 
   1243 'default'?)
   1244 </td><td><pre>
   1245 void test() {
   1246   int c = 7;
   1247   switch(c){
   1248   case 1:
   1249     c += 1; break;
   1250   defalt: // warn
   1251     c -= 1; break;
   1252   }
   1253 }
   1254 </pre></td><td class="aligned"></td></tr>
   1255 
   1256 <tr><td><span class="name">different.IdenticalCondIfIf
   1257 <br>(C)</span><br><br>
   1258 The conditions of two subsequent 'if' statements are identical
   1259 </td><td><pre>
   1260 void test() {
   1261   int c = 7;
   1262   if (c &gt; 5) // &lt;-
   1263     c += 1;
   1264   if (c &gt; 5) // warn
   1265     c -= 1;
   1266 }
   1267 </pre></td><td class="aligned"></td></tr>
   1268 
   1269 <tr><td><span class="name">different.CondOpIdenticalReturn
   1270 <br>(C)</span><br><br>
   1271 The return expressions of the '?:' operator are identical
   1272 </td><td><pre>
   1273 void test() {
   1274   unsigned a;
   1275   a = a > 5 ? a : a; // warn
   1276 }
   1277 </pre></td><td class="aligned"></td></tr>
   1278 
   1279 <tr><td><span class="name">different.UnaryPlusWithUnsigned
   1280 <br>(C)</span><br><br>
   1281 Using 'unary +' with unsigned is meaningless
   1282 </td><td><pre>
   1283 void test() {
   1284   unsigned a;
   1285   a = +a; // warn
   1286 }
   1287 </pre></td><td class="aligned"></td></tr>
   1288 
   1289 <tr><td><span class="name">different.LogicalOpUselessArg
   1290 <br>(C)</span><br><br>
   1291 The second operand of the &amp;&amp; operator has no impact on expression result
   1292 </td><td><pre>
   1293 void test() {
   1294   unsigned a;
   1295   if (a&lt;7 &amp;&amp; a&lt;10) {}; // warn
   1296 }
   1297 </pre></td><td class="aligned"></td></tr>
   1298 
   1299 <tr><td><span class="name">different.SameResLogicalExpr
   1300 <br>(C)</span><br><br>
   1301 The expression always evaluates to true/false
   1302 </td><td><pre>
   1303 void test() {
   1304   int i=0;
   1305   if (i!=0) {}; // warn
   1306   if (i==0 &amp;&amp; i==1) {}; // warn
   1307   if (i<0 || i>=0) {}; // warn
   1308 }
   1309 </pre></td><td class="aligned"></td></tr>
   1310 
   1311 <tr><td><span class="name">different.SameResUnsignedCmp
   1312 <br>(C)</span><br><br>
   1313 Comparison of unsigned expression 'op expr' is always true/false
   1314 </td><td><pre>
   1315 void test() {
   1316   unsigned u;
   1317   if (u &lt; -1) {}; // warn
   1318   if (u &gt;= 0) {}; // warn
   1319 }
   1320 </pre></td><td class="aligned"></td></tr>
   1321 
   1322 <tr><td><span class="name">different.OpPrecedenceAssignCmp
   1323 <br>(C)</span><br><br>
   1324 Comparison operation has higher precedence then assignment. Bool value is 
   1325 assigned to variable of type 'type'. Parenthesis may bee required around an 
   1326 assignment
   1327 </td><td><pre>
   1328 int f();
   1329 
   1330 void test() {
   1331   bool b;
   1332   int x, y;
   1333   if((b = x != y)) {} // ok
   1334   if((x = f() != y)) {} // warn
   1335 }
   1336 </pre></td><td class="aligned"></td></tr>
   1337 
   1338 <tr><td><span class="name">different.OpPrecedenceIifShift
   1339 <br>(C)</span><br><br>
   1340 ?: has lower precedence then &lt;&lt;
   1341 </td><td><pre>
   1342 #include &lt;iostream&gt;
   1343 
   1344 void test() {
   1345   int a;
   1346   std::cout &lt;&lt; a ? "a" : "b"; // warn
   1347   a &lt;&lt; a&gt;7 ? 1 : 2; // warn
   1348 }
   1349 </pre></td><td class="aligned"></td></tr>
   1350 
   1351 <tr><td><span class="name">different.ObjectUnused
   1352 <br>(C++)</span><br><br>
   1353 The object was created but is not being used<br><br>
   1354 The exception object was created but is not being used. Did you mean 
   1355 'throw std::exception();'?
   1356 </td><td><pre>
   1357 #include &lt;exception&gt;
   1358 
   1359 struct S {
   1360   int x, y;
   1361   S(int xx, int yy) : x(xx), y(yy) {
   1362   }
   1363   S(int xx) {
   1364     S(xx, 0); // warn
   1365   }
   1366 };
   1367 
   1368 void test() {
   1369   S(0, 0); // warn
   1370   std::exception(); // warn
   1371 }
   1372 </pre></td><td class="aligned"></td></tr>
   1373 
   1374 <tr><td><span class="name">different.StaticArrayPtrCompare
   1375 <br>(C)</span><br><br>
   1376 Pointer to static array is being compared to NULL. May the subscripting is 
   1377 missing
   1378 </td><td><pre>
   1379 void test() {
   1380   int a1[1];
   1381   if (a1 == 0) {}; // warn
   1382 
   1383   int a2[1][1];
   1384   if (a2[0]) {}; // warn
   1385 }
   1386 </pre></td><td class="aligned"></td></tr>
   1387 
   1388 <tr><td><span class="name">different.ConversionToBool
   1389 <br>maybe join with experimental.core.BoolAssignment<br>(C, C++)</span><br><br>
   1390 Odd implicit conversion from 'type' to 'bool'
   1391 </td><td><pre>
   1392 bool test() {
   1393   return 1.; // warn
   1394   return ""; // warn
   1395 }
   1396 </pre></td><td class="aligned"></td></tr>
   1397 
   1398 <tr><td><span class="name">different.ArrayBound
   1399 <br>enhancement to experimental.security.ArrayBound[v2]<br>(C, C++)</span><br><br>
   1400 Out-of-bound dynamic array access
   1401 </td><td><pre>
   1402 #include &lt;stdlib.h&gt;
   1403 
   1404 void test() {
   1405   int *p2 = new int[1];
   1406   if(p2[1]) {}; // warn
   1407   int i = 1;
   1408   if(p2[i]) {}; // warn
   1409 }
   1410 </pre></td><td class="aligned"></td></tr>
   1411 
   1412 <tr><td><span class="name">different.StrcpyInputSize
   1413 <BR>enhancement to experimental.unix.cstring.OutOfBounds<br>(C)</span><br><br>
   1414 Buffer copy without checking size of input
   1415 </td><td><pre>
   1416 void test(char* string) {
   1417   char buf[24];
   1418   strcpy(buf, string); // warn
   1419 }
   1420 </pre></td><td class="aligned"></td></tr>
   1421 
   1422 <tr><td><span class="name">different.IntegerOverflow
   1423 <br>(C)</span><br><br>
   1424 Integer overflow
   1425 </td><td><pre>
   1426 #include &lt;limits.h&gt;
   1427 
   1428 int f(int x) {
   1429   return INT_MAX+1; // warn
   1430 }
   1431 
   1432 void test() {
   1433   int x = INT_MAX+1; // warn
   1434   f(INT_MAX+1); // warn
   1435 
   1436   int y = INT_MAX/2+1; // warn
   1437   x = y*2; // warn
   1438 }
   1439 </pre></td><td class="aligned"></td></tr>
   1440 
   1441 <tr><td><span class="name">different.SignExtension
   1442 <br>(C)</span><br><br>
   1443 Unexpected sign extension might take place
   1444 </td><td><pre>
   1445 void f(unsigned int i);
   1446 int g();
   1447 
   1448 unsigned int test() {
   1449   long long sll;
   1450   unsigned long long ull = sll; // warn
   1451   long sl;
   1452   unsigned long ul = sl; // warn
   1453   int si;
   1454   unsigned int ui = si; // warn
   1455   short ss;
   1456   unsigned short us = ss; // warn
   1457   signed char sc;
   1458   unsigned char uc = sc; // warn
   1459   f(si); // warn
   1460   ui = g(); // warn
   1461   return si; // warn
   1462 }
   1463 </pre></td><td class="aligned"></td></tr>
   1464 
   1465 <tr><td><span class="name">different.NumericTruncation
   1466 <br>(C)</span><br><br>
   1467 Numeric truncation might take place
   1468 </td><td><pre>
   1469 void f(int i);
   1470 int g();
   1471 
   1472 int test() {
   1473   unsigned long long ull;
   1474   long long sll;
   1475   unsigned long ul = ull; // warn
   1476   long sl = sll; // warn
   1477   unsigned int ui = ul; // warn
   1478   int si = sl; // warn
   1479   unsigned short us = ui; // warn
   1480   short ss = si; // warn
   1481   unsigned char uc = us; // warn
   1482   signed char sc = uc; // warn
   1483   f(sll); // warn
   1484   ss = g(); // warn
   1485   return sll; // warn
   1486 }
   1487 </pre></td><td class="aligned"></td></tr>
   1488 
   1489 <tr><td><span class="name">different.MissingCopyCtorAssignOp
   1490 <br>(C, C++)</span><br><br>
   1491 The class has dynamically allocated data members but do not define a copy 
   1492 constructor/assignment operator
   1493 </td><td><pre>
   1494 class C { // warn
   1495   int *p; // &lt;-
   1496 public:
   1497   C() { p = new int; }
   1498   ~C() { delete p; }
   1499 };
   1500 </pre></td><td class="aligned"></td></tr>
   1501 
   1502 </table>
   1503 
   1504 <!-- ============================ WinAPI =================================== -->
   1505 <h3>WinAPI</h3>
   1506 <table class="checkers">
   1507 <col class="namedescr"><col class="example"><col class="progress">
   1508 <thead><tr><td>Name, Description</td><td>Example</td><td>Progress</td></tr></thead>
   1509 
   1510 <tr><td><span class="name">WinAPI.CreateProcess
   1511 <br>(C)</span><br><br>
   1512 After calling CreateProcess(), ensure that process and thread handles get closed
   1513 (* for the given example: examine data flow from pi, pi.hProcess and pi.hThread)
   1514 </td><td><pre>
   1515 #include &lt;windows.h&gt;
   1516 
   1517 void test() {
   1518   STARTUPINFO si;
   1519   PROCESS_INFORMATION pi;
   1520   BOOL fSuccess;
   1521   fSuccess = CreateProcess(
   1522     NULL, TEXT("MyProgram.exe"), NULL, NULL, 
   1523     TRUE, 0, NULL, NULL, &amp;si, &amp;pi);
   1524 } // warn
   1525 </pre></td><td class="aligned"></td></tr>
   1526 
   1527 <tr><td><span class="name">WinAPI.LoadLibrary
   1528 <br>(C)</span><br><br>
   1529 Calling LoadLibrary without a fully qualified path may allow to load a DLL from 
   1530 arbitrary location
   1531 </td><td><pre>
   1532 #include &lt;windows.h&gt;
   1533 
   1534 void test() {
   1535   HINSTANCE h = LoadLibrary("X.dll"); // warn
   1536 }
   1537 </pre></td><td class="aligned"></td></tr>
   1538 
   1539 <tr><td><span class="name">WinAPI.WideCharToMultiByte
   1540 <br>(C)</span><br><br>
   1541 Buffer overrun while calling WideCharToMultiByte
   1542 </td><td><pre>
   1543 #include &lt;windows.h&gt;
   1544 
   1545 void test() 
   1546 {
   1547   wchar_t ws[] = L"abc";
   1548   char s[3];
   1549   int res1 = WideCharToMultiByte(
   1550                CP_UTF8, 0, ws, -1, s, 
   1551                3, NULL, NULL); // warn
   1552   int res2 = WideCharToMultiByte(
   1553                CP_UTF8, 0, ws, -1, s, 
   1554                3, NULL, NULL); // ok
   1555   if (res2 == sizeof(s))
   1556     s[res2-1] = 0;
   1557   else
   1558    s[res2] = 0;
   1559 }
   1560 </pre></td><td class="aligned"></td></tr>
   1561 
   1562 </table>
   1563 
   1564 <!-- =========================== optimization ============================== -->
   1565 <h3>optimization</h3>
   1566 <table class="checkers">
   1567 <col class="namedescr"><col class="example"><col class="progress">
   1568 <thead><tr><td>Name, Description</td><td>Example</td><td>Progress</td></tr></thead>
   1569 
   1570 <tr><td><span class="name">optimization.PassConstObjByValue
   1571 <br>(C, C++)</span><br><br>
   1572 Optimization: It is more effective to pass const n-th parameter by reference to 
   1573 avoid unnecessary object copying
   1574 </td><td><pre>
   1575 struct A {
   1576   int a[20];
   1577   int b;
   1578 };
   1579 
   1580 bool FirstIsZero(const struct A a) { // warn
   1581   return a.a[0] == 0;
   1582 }
   1583 </pre></td><td class="aligned"></td></tr>
   1584 
   1585 <tr><td><span class="name">optimization.PostfixIncIter
   1586 <br>(C++)</span><br><br>
   1587 Optimization: It is more effective to use prefix ++ with iterator here
   1588 </td><td><pre>
   1589 #include &lt;vector&gt;
   1590 
   1591 void test() {
   1592   std::vector&lt;int&gt; v;
   1593   std::vector&lt;int&gt;::const_iterator it;
   1594   for(it = v.begin(); 
   1595       it != v.end(); it++) {}; // warn
   1596 }
   1597 </pre></td><td class="aligned"></td></tr>
   1598 
   1599 <tr><td><span class="name">optimization.MultipleCallsStrlen
   1600 <br>(C)</span><br><br>
   1601 Optimization: multiple calls to strlen for a given string in the given 
   1602 expression. It is more effective to hold strlen result in a temporary 
   1603 variable
   1604 </td><td><pre>
   1605 #include &lt;string.h&gt;
   1606 
   1607 void test() {
   1608   const char* s = "abc";
   1609   if (strlen(s) &gt; 0 &amp;&amp;
   1610       strlen(s) &lt; 7) {}; // warn
   1611 }
   1612 </pre></td><td class="aligned"></td></tr>
   1613 
   1614 <tr><td><span class="name">optimization.EmptyCstrDetect
   1615 <br>(C)</span><br><br>
   1616 Optimization: it is more efficient to use "str[0] != '\0'" to identify an empty 
   1617 string
   1618 </td><td><pre>
   1619 #include &lt;string.h&gt;
   1620 
   1621 void test() {
   1622   const char* s = "abc";
   1623   if (strlen(s) &gt; 0) {}; // warn
   1624 }
   1625 </pre></td><td class="aligned"></td></tr>
   1626 
   1627 <tr><td><span class="name">optimization.StrLengthCalculation
   1628 <br>(C, C++)</span><br><br>
   1629 Optimization: it is more efficient to use string::length() method to calculate 
   1630 string length
   1631 </td><td><pre>
   1632 #include &lt;string&gt;
   1633 #include &lt;string.h&gt;
   1634 
   1635 void test() {
   1636   std::string s;
   1637   if (strlen(s.c_str()) != 0) {}; // warn
   1638 }
   1639 </pre></td><td class="aligned"></td></tr>
   1640 
   1641 <tr><td><span class="name">optimization.EmptyContainerDetect
   1642 <br>(C, C++)</span><br><br>
   1643 Optimization: It is more efficient to use container.empty() to identify an 
   1644 empty container
   1645 </td><td><pre>
   1646 #include &lt;list&gt;
   1647 
   1648 void test() {
   1649   std::list&lt;int&gt; l;
   1650   if (l.size() != 0) {}; // warn
   1651 }
   1652 </pre></td><td class="aligned"></td></tr>
   1653 
   1654 </table>
   1655 
   1656 <br>
   1657 </div> <!-- page -->
   1658 </div> <!-- content -->
   1659 </body>
   1660 </html>
   1661