1 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
2 "http://www.w3.org/TR/html4/strict.dtd">
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>
16 <!--#include virtual="menu.html.incl"-->
19 <h1>List of potential checkers</h1>
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>
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>
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
34 #include <stdlib.h>
39 int *p1 = (int*)malloc(sizeof(int)); // warn
40 int *p2 = new int; // warn
46 </pre></td><td class="aligned"><a href="http://llvm.org/bugs/show_bug.cgi?id=15237">PR15237</a>
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
53 #include <stdlib.h>
62 </pre></td><td class="aligned"><a href="http://llvm.org/bugs/show_bug.cgi?id=15238">PR15238</a>
65 <tr><td><span class="name">memory.LeakPtrValChanged
66 <br>enhancement to unix.Malloc<br>(C, C++)</span><br><br>
67 Potential memory leak: a pointer to newly allocated data loses its original
70 #include <stdlib.h>
78 int *p2 = (int *)malloc(sizeof(int));
87 </pre></td><td class="aligned">done at r174678 (C case)
90 <tr><td><span class="name">memory.LeakEvalOrder<br>
91 (C, C++)</span><br><br>
92 Potential memory leak: argument evaluation order is undefined, g() may never be called
94 #include <stdlib.h>
98 int g(int *) { throw 1; };
102 f1(g(new int), h()); // warn
103 f1(g((int *)malloc(sizeof(int))), h()); // warn
104 f2(new int, new int);
106 </pre></td><td class="aligned"></td></tr>
108 <tr><td><span class="name">memory.DstBufferTooSmall
109 <br>(C, C++)</span><br><br>
110 Destination buffer too small
112 #include <string.h>
115 const char* s1 = "abc";
117 strcpy(s2, s1); // warn
119 int* p1 = new int[3];
121 memcpy(p2, p1, 3); // warn
123 </pre></td><td class="aligned"></td></tr>
125 <tr><td><span class="name">memory.NegativeArraySize
126 <br>enhancement to experimental.security.MallocOverflow<br>(C, C++)
128 'n' is used to specify the buffer size may be negative
130 #include <stdlib.h>
135 p = new int[n1]; // warn
137 </pre></td><td class="aligned"></td></tr>
141 <!-- ======================= constructors/destructors ====================== -->
142 <h3>constructors/destructors</h3>
143 <table class="checkers">
144 <col class="namedescr"><col class="example"><col class="progress">
145 <thead><tr><td>Name, Description</td><td>Example</td><td>Progress</td></tr></thead>
147 <tr><td><span class="name">ctordtor.ExptInsideDtorExplicit<br>
149 It is dangerous to let an exception leave a destructor. Using try..catch will
156 ~A() { throw 1; } // warn
158 </pre></td><td class="aligned"></td></tr>
160 <tr><td><span class="name">ctordtor.ExptInsideDtorImplicit<br>
162 Calls to functions inside a destructor that are known to throw exceptions is
163 dangerous. Using try..catch will solve the problem.
165 void f() { throw 1; };
169 ~A() { f(); } // warn
171 </pre></td><td class="aligned"></td></tr>
173 <tr><td><span class="name">ctordtor.PlacementSelfCopy<br>
174 (C++11)</span><br><br>
175 For a placement copy or move, it is almost certainly an error if the constructed object is also the object being copied from.
179 void test(A *dst, A *src) {
180 ::new (dst) A(*dst); // warn (should be 'src')
182 </pre></td><td class="aligned"><!--rdar://problem/13688366--></td></tr>
186 <!-- ============================== exceptions ============================= -->
188 <table class="checkers">
189 <col class="namedescr"><col class="example"><col class="progress">
190 <thead><tr><td>Name, Description</td><td>Example</td><td>Progress</td></tr></thead>
192 <tr><td><span class="name">exceptions.ThrowSpecButNotThrow
193 <br>(C++)</span><br><br>
194 Function prototype has throw(T) specifier but the function do not throw
196 void f() throw(int) { // warn
198 </pre></td><td class="aligned"></td></tr>
200 <tr><td><span class="name">exceptions.NoThrowSpecButThrows
201 <br>(C++)</span><br><br>
202 An exception is throw from a function having the throw() specifier
207 </pre></td><td class="aligned"></td></tr>
209 <tr><td><span class="name">exceptions.ThrownTypeDiffersSpec
210 <br>(C++)</span><br><br>
211 The type of a thrown exception differs from those specified in the throw(T)
215 void f() throw(int) {
219 </pre></td><td class="aligned"></td></tr>
223 <!-- ========================= smart pointers ============================== -->
224 <h3>smart pointers</h3>
225 <table class="checkers">
226 <col class="namedescr"><col class="example"><col class="progress">
227 <thead><tr><td>Name, Description</td><td>Example</td><td>Progress</td></tr></thead>
229 <tr><td><span class="name">smartptr.SmartPtrInit<br>
231 C++03: auto_ptr should store a pointer to an object obtained via new as allocated
232 memory will be cleaned using delete<br>
233 C++11: one should use unique_ptr<T[]> to keep a pointer to memory
234 allocated by new[]<br>
235 C++11: to keep a pointer to memory allocated by new[] in a shared_ptr one
236 should use a custom deleter that calls delete[]
238 #include <stdlib.h>
239 #include <memory>
242 std::auto_ptr<int> p1(new int); // Ok
243 std::auto_ptr<int> p2(new int[3]); // warn
244 std::auto_ptr<int>
245 p3((int *)malloc(sizeof(int))); // warn
247 </pre></td><td class="aligned"></td></tr>
251 <!-- ========================= undefined behavior ========================== -->
252 <h3>undefined behavior</h3>
253 <table class="checkers">
254 <col class="namedescr"><col class="example"><col class="progress">
255 <thead><tr><td>Name, Description</td><td>Example</td><td>Progress</td></tr></thead>
257 <tr><td><span class="name">undefbehavior.ExitInDtor
258 <br>(C++)</span><br><br>
259 Undefined behavior: std::exit is called to end the program during the
260 destruction of an object with static storage duration
262 #include <cstdlib>
267 std::exit(1); // warn
272 </pre></td><td class="aligned"></td></tr>
274 <tr><td><span class="name">undefbehavior.LocalStaticDestroyed
275 <br>(C++)</span><br><br>
276 Undefined behavior: function containing a definition of static local object is
277 called during the destruction of an object with static storage duration so that
278 flow of control passes through the definition of the previously destroyed
297 </pre></td><td class="aligned"></td></tr>
299 <tr><td><span class="name">undefbehavior.UseAfterRelease
300 <br>enhancement to unix.Malloc<br>(C, C++)</span><br><br>
301 Pointer to deleted object is referenced (The effect of using an invalid pointer
304 #include <stdlib.h>
312 </pre></td><td class="aligned"></td></tr>
314 <tr><td><span class="name">undefbehavior.ZeroAllocDereference
315 <br>enhancement to unix.Malloc<br>(C, C++)</span><br><br>
316 The effect of dereferencing a pointer returned as a request for zero size is
319 #include <stdlib.h>
322 int i = p[0]; // warn
323 </pre></td><td class="aligned"></td></tr>
325 <tr><td><span class="name">undefbehavior.DeadReferenced
326 <br>(C++)</span><br><br>
327 Undefined behavior: the following usage of the pointer to the object whose
328 lifetime has ended can result in undefined behavior
347 static_cast<A*>(b); // warn
348 dynamic_cast<A*>(b); // warn
375 static_cast<A*>(b); // warn
376 dynamic_cast<A*>(b); // warn
379 </pre></td><td class="aligned"></td></tr>
381 <tr><td><span class="name">undefbehavior.ObjLocChanges
382 <br>(C++)</span><br><br>
383 Undefined behavior: the program must ensure that an object occupies the same
384 storage location when the implicit or explicit destructor call takes place
400 </pre></td><td class="aligned"></td></tr>
402 <tr><td><span class="name">undefbehavior.ExprEvalOrderUndef
403 <br>(C, C++03)</span><br><br>
404 Undefined behavior: a scalar object shall have its stored value modified at
405 most once by the evaluation of an expression
413 </pre></td><td class="aligned"></td></tr>
415 <tr><td><span class="name">undefbehavior.StaticInitReentered
416 <br>(C)</span><br><br>
417 Undefined behavior: static declaration is re-entered while the object is being
421 static int s = test(2*i); // warn
424 </pre></td><td class="aligned"></td></tr>
426 <tr><td><span class="name">undefbehavior.ConstModified
427 <br>(C, C++)</span><br><br>
428 Undefined behavior: const object is being modified
430 #include <stdlib.h>
445 (int *)malloc(sizeof(int));
446 int *iq = const_cast<int *>(ciq);
450 Y* p = const_cast<Y*>(&y);
452 p->x.j = 1; // warn
454 </pre></td><td class="aligned"></td></tr>
456 <tr><td><span class="name">undefbehavior.DeadDestructed
457 <br>(C++)</span><br><br>
458 Undefined behavior: the destructor is invoked for an object whose lifetime
472 </pre></td><td class="aligned"></td></tr>
474 <tr><td><span class="name">undefbehavior.MethodCallBeforeBaseInit
475 <br>(C++)</span><br><br>
476 Undefined behavior: calls member function but base not yet initialized
485 B() : A(f()) {} // warn
487 </pre></td><td class="aligned"></td></tr>
489 <tr><td><span class="name">undefbehavior.MemberOrBaseRefBeforeCtor
490 <br>(C++)</span><br><br>
491 C++ Undefined behavior: non-static member or base class of non-POD class type
492 is referred before constructor begins execution<br>
493 C++11 Undefined behavior: non-static member or base class of a class with a
494 non-trivial constructor is referred before constructor begins execution
501 struct non_POD : public POD {
507 extern non_POD non_pod;
509 int *p1 = &non_pod.j; // warn
510 int *p2 = &non_pod.pod.i; // warn
511 int *p3 = &pod.i; // ok
512 POD *p4 = &non_pod; // warn
520 S() : k(&non_pod.j) {} // warn
528 struct non_trivial: public trivial {
535 extern non_trivial nt;
537 int *p1 = &nt.j; // warn
538 int *p2 = &nt.i; // warn
539 int *p3 = &t.i; // ok
540 trivial *p4 = &nt;
548 S() : k(&nt.j) {} // warn
550 </pre></td><td class="aligned"></td></tr>
552 <tr><td><span class="name">undefbehavior.MemberRefAfterDtor
553 <br>(C++)</span><br><br>
554 C++03: Undefined behavior: non-static member of non-POD class type is referred
555 after destructor ends execution<br>
556 C++11: Undefined behavior: non-static member of a class with a non-trivial
557 destructor is referred after destructor ends execution
565 non_POD *non_pod = new non_POD();
567 non_pod->f(); // warn
581 </pre></td><td class="aligned"></td></tr>
583 <tr><td><span class="name">undefbehavior.CtorForeignCall
584 <br>(C++)</span><br><br>
585 Undefined behavior: call to virtual function of an object under construction
586 whose type is neither the constructors own class or one of its bases
595 B(A* a) { a->f(); } // warn
598 class C : public A, B {
602 </pre></td><td class="aligned"></td></tr>
604 <tr><td><span class="name">undefbehavior.CtorForeignCast
605 undefbehavior.CtorForeignTypeid
606 <br>(C++)</span><br><br>
607 Undefined behavior: the operand of typeid/dynamic_cast is an object under
608 construction whose type is neither the constructors own class or one of its
611 #include <typeinfo>
622 dynamic_cast<B*>(a); //warn
626 class C : public A, B {
630 </pre></td><td class="aligned"></td></tr>
632 <tr><td><span class="name">undefbehavior.MemberRefInCatch
633 undefbehavior.BaseRefInCatch
634 <br>(C++)</span><br><br>
635 Undefined behavior: referring to any non-static member or base class of an
636 object in the handler for a function-try-block of a constructor or destructor
637 for that object results in undefined behavior
650 </pre></td><td class="aligned"></td></tr>
652 <tr><td><span class="name">undefbehavior.ReturnAtCatchEnd
653 <br>(C++)</span><br><br>
654 Undefined behavior: a function returns when control reaches the end of a
655 handler. This results in undefined behavior in a value-returning
662 </pre></td><td class="aligned"></td></tr>
664 <tr><td><span class="name">undefbehavior.AutoptrsOwnSameObj
665 <br>(C++03)</span><br><br>
666 Undefined behavior: if more than one auto_ptr owns the same object at the same
667 time the behavior of the program is undefined.
669 #include <memory>
673 std::auto_ptr<int> p(data);
674 std::auto_ptr<int> q(data); // warn
676 </pre></td><td class="aligned"></td></tr>
678 <tr><td><span class="name">undefbehavior.BasicStringBoundAccess
679 <br>(C++03)</span><br><br>
680 Undefined behavior: out-of-bound basic_string access
683 std::basic_string<char> s;
684 char c = s[10]; // warn
686 </pre></td><td class="aligned"></td></tr>
688 <tr><td><span class="name">undefbehavior.BasicStringBoundModification
689 <br>(C++)</span><br><br>
690 Undefined behavior: out-of-bound basic_string modification
693 std::basic_string<char> s;
696 </pre></td><td class="aligned"></td></tr>
698 <tr><td><span class="name">undefbehavior.EosDereference
699 <br>(C++)</span><br><br>
700 Undefined behavior: the result of operator*() on an end of stream is
703 #include <vector>
706 std::vector<int> v;
707 int i = *v.end(); // warn
708 *v.end() = 0; // warn
710 </pre></td><td class="aligned"></td></tr>
712 <tr><td><span class="name">undefbehavior.QsortNonPOD
713 undefbehavior.QsortNonTrivial
714 <br>C++</span><br><br>
715 C++03: Undefined behavior: the objects in the array passed to qsort are of
717 C++11: Undefined behavior: the objects in the array passed to qsort are of
721 #include <cstdlib>
725 non_POD(int ii) : i(ii) {}
728 non_POD values[] = { non_POD(2), non_POD(1) };
730 int compare(const void *a,
732 return ( (*(non_POD*)a).i -
737 qsort(values, 2, sizeof(non_POD),
742 #include <cstdlib>
746 struct trivial_non_POD : public S {
755 trivial_non_POD tnp[2];
758 int compare1(const void *a,
760 return ( (*(trivial_non_POD *)a).i -
761 (*(trivial_non_POD *)b).i );
764 int compare2(const void *a,
766 return ( (*(non_trivial *)a).i -
767 (*(non_trivial *)b).i );
771 qsort(tnp, 2, sizeof(trivial_non_POD),
773 qsort(nt, 2, sizeof(non_trivial),
776 </pre></td><td class="aligned"></td></tr>
778 <tr><td><span class="name">undefbehavior.ThrowWhileCopy
779 <br>C++</span><br><br>
780 Undefined behavior: copy constructor/assignment operator can throw an exception.
781 The effects are undefined if an exception is thrown.
790 S &operator=(const S &s) {
796 </pre></td><td class="aligned"></td></tr>
798 <tr><td><span class="name">undefbehavior.ValarrayArgBound
799 <br>(C++)</span><br><br>
800 Undefined behavior: the value of the second argument is greater than the number
801 of values pointed to by the first argument
803 #include <valarray>
807 S(int ii) : i(ii) {};
811 S s[] = { S(1), S(2) };
812 std::valarray<S> v(s,3); // warn
814 </pre></td><td class="aligned"></td></tr>
816 <tr><td><span class="name">undefbehavior.ValarrayLengthDiffer
817 <br>(C++)</span><br><br>
818 Undefined behavior: valarray operands are of different length
821 #include <valarray>
824 std::valarray<int> a(0, 1), b(0, 2);
825 std::valarray<bool> c(false, 1);
835 #include <valarray>
838 std::valarray<int> a(0, 1), b(0, 2);
839 std::valarray<bool> c(false, 1);
847 </pre></td><td class="aligned"></td></tr>
849 <tr><td><span class="name">undefbehavior.ValarrayZeroLength
850 <br>(C++)</span><br><br>
851 Undefined behavior: calling sum()/min()/max() method of an array having zero
852 length, the behavior is undefined
854 #include <valarray>
857 std::valarray<int> v(0, 0);
862 </pre></td><td class="aligned"></td></tr>
864 <tr><td><span class="name">undefbehavior.ValarrayBadIndirection
865 <br>(C++)</span><br><br>
866 Undefined behavior: element N is specified more than once in the
869 #include <valarray>
872 size_t addr[] = {0, 1, 1}; // N is 1
873 std::valarray<size_t>indirect(addr, 3);
874 std::valarray<int> a(0, 5), b(1, 3);
875 a[indirect] = b; //warn
876 a[indirect] *= b; //warn
878 </pre></td><td class="aligned"></td></tr>
880 <tr><td><span class="name">undefbehavior.IosBaseDestroyedBeforeInit
882 <br>Undefined behavior: ios_base object is destroyed before initialization have
883 taken place. basic_ios::init should be call to initialize ios_base
889 template <class T, class Traits = std::char_traits<T>>
890 class my_stream1 : public std::basic_ios<T, Traits> {
893 template <class T, class Traits = std::char_traits<T>>
894 class my_stream2 : public std::basic_ios<T, Traits> {
895 class my_streambuf : public std::basic_streambuf<T, Traits> {
899 this->init(new my_streambuf);
904 my_stream1<char> *p1 = new my_stream1<char>
905 my_stream2<char> *p2 = new my_stream2<char>
909 </pre></td><td class="aligned"></td></tr>
911 <tr><td><span class="name">undefbehavior.IosBaseUsedBeforeInit
912 <br>(C++11)</span><br><br>
913 Undefined behavior: ios_base object is used before initialization have taken
914 place. basic_ios::init should be call to initialize ios_base members
919 template <class T, class Traits = std::char_traits<T>>
920 class my_stream1 : public std::basic_ios<T, Traits> {
923 template <class T, class Traits = std::char_traits<T>>
924 class my_stream2 : public std::basic_ios<T, Traits> {
925 class my_streambuf : public std::basic_streambuf<T, Traits> {
929 this->init(new my_streambuf);
934 my_stream1<char> *p1 = new my_stream1<char>
935 my_stream2<char> *p2 = new my_stream2<char>
936 p1->narrow('a', 'b'); // warn
937 p2->narrow('a', 'b'); // ok
941 </pre></td><td class="aligned"></td></tr>
943 <tr><td><span class="name">undefbehavior.MinusOnePosType
944 <br>(C++)</span><br><br>
945 Undefined behavior: passing -1 to any streambuf/istream/ostream member that
946 accepts a value of type traits::pos_type result in undefined behavior
948 #include <fstream>
950 class my_streambuf : public std::streambuf {
958 std::istream in(&fb);
959 std::ostream out(&fb);
960 std::filebuf::off_type pos(-1);
961 in.seekg(pos); // warn
962 out.seekp(-1); // warn
964 </pre></td><td class="aligned"></td></tr>
967 <!-- ============================ different ================================ -->
969 <table class="checkers">
970 <col class="namedescr"><col class="example"><col class="progress">
971 <thead><tr><td>Name, Description</td><td>Example</td><td>Progress</td></tr>
974 <tr><td><span class="name">different.ArgEvalOrderUndef
975 <br>(C)</span><br><br>
976 Errors because of the order of evaluation of function arguments is undefined
983 f(v[i], i++); // warn
985 </pre></td><td class="aligned"></td></tr>
987 <tr><td><span class="name">different.IdenticalExprBinOp
988 <br>(C)</span><br><br>
989 There are identical sub-expressions to the left and to the right of the
995 bool isNan(double d) {
1003 if (i != 0 && i != 0) {} // warn
1005 if(i == A || i == B) {} // ok
1007 if (++i != 0 && ++i != 0) {} // ok
1009 if (f() && f()) {} // ok
1011 </pre></td><td class="aligned"></td></tr>
1013 <tr><td><span class="name">different.FuncPtrInsteadOfCall
1014 <br>(C)</span><br><br>
1015 Possibly a function call should be used instead of a pointer to function
1020 if (f == 0) {} // warn
1022 </pre></td><td class="aligned"></td></tr>
1024 <tr><td><span class="name">different.IdenticalCondIfElseIf
1025 <br>(C)</span><br><br>
1026 The use of 'if (A) {...} else if (A) {...}' pattern was detected. There is a
1027 probability of logical error presence
1032 else if (i == 1) {} // warn
1034 </pre></td><td class="aligned"></td></tr>
1036 <tr><td><span class="name">SuccessiveAssign
1037 <br>(C)</span><br><br>
1038 Successive assign to a variable
1045 </pre></td><td class="aligned"></td></tr>
1047 <tr><td><span class="name">different.NullDerefStmtOrder
1048 <br>enhancement to core.NullDereference<br>(C)</span><br><br>
1049 Dereferencing of the null pointer might take place. Checking the pointer for
1050 null should be performed first
1060 int x1 = p1->x; // warn
1064 int x2 = p2->x; // ok
1066 </pre></td><td class="aligned"></td></tr>
1068 <tr><td><span class="name">different.NullDerefCondOrder
1069 <br>enhancement to core.NullDereference<br>(C)</span><br><br>
1070 Dereferencing of the null pointer might take place. Checking the pointer for
1071 null should be performed first
1079 if (p->b && p) {}; // warn
1081 </pre></td><td class="aligned"></td></tr>
1083 <tr><td><span class="name">different.IdenticalStmtThenElse
1084 <br>(C)</span><br><br>
1085 The 'else' statement is equivalent to the 'then' statement
1096 </pre></td><td class="aligned"></td></tr>
1098 <tr><td><span class="name">different.MultipleAccessors
1099 <br>(C++)</span><br><br>
1100 multiple accessors met for 'class::field'
1106 int getI() { return i; }
1107 int getJ() { return i; } // warn
1108 void setI(int& ii) { i = ii; }
1109 void setJ(int& jj) { i = jj; } // warn
1111 </pre></td><td class="aligned"></td></tr>
1113 <tr><td><span class="name">different.AccessorsForPublic
1114 <br>(C++)</span><br><br>
1115 Accessors exist for 'class::field'. Should this field really be public?
1120 int getI() { return i; }
1121 void setI(int& ii) { i = ii; }
1123 </pre></td><td class="aligned"></td></tr>
1125 <tr><td><span class="name">different.LibFuncResultUnised
1126 <br>(C, C++)</span><br><br>
1127 Calling 'f' ignoring its return value is of no use (* create the list of known
1128 system/library/API functions falling into this category)
1130 #include <vector>
1133 std::vector<int> v;
1136 </pre></td><td class="aligned"></td></tr>
1138 <tr><td><span class="name">different.WrongVarForStmt
1139 <br>(C, C++)</span><br><br>
1140 Possibly wrong variable is used in the loop/cond-expression of the 'for'
1141 statement. Did you mean 'proper_variable_name'?
1146 for (j=0; j<3; ++i); // warn
1147 for (int j=0; i<3; ++j); // warn
1149 </pre></td><td class="aligned"></td></tr>
1151 <tr><td><span class="name">different.FloatingCompare
1152 <br>(C)</span><br><br>
1153 Comparing floating point numbers may be not precise
1155 #include <math.h>
1158 double b = sin(M_PI / 6.0);
1159 if (b == 0.5) // warn
1162 </pre></td><td class="aligned"></td></tr>
1164 <tr><td><span class="name">different.BoolCompare
1165 <br>maybe merge with experimental.core.BoolAssignment<br>(C, C++)</span><br><br>
1166 Comparing boolean to a value other then 0 or 1
1170 if (0 < i < 3) {}; // warn
1172 if (b == 3) {}; // warn
1174 </pre></td><td class="aligned"></td></tr>
1176 <tr><td><span class="name">different.BitwiseOpBoolArg
1177 <br>maybe join with experimental.core.BoolAssignment<br>(C, C++)</span><br><br>
1178 bool value is used at the left/right part of the & (|) operator. Did you mean
1185 if (b & f()) {} // warn
1187 </pre></td><td class="aligned"></td></tr>
1189 <tr><td><span class="name">different.LabelInsideSwitch
1190 <br>(C)</span><br><br>
1191 Possible misprint: label found inside the switch() statement. (* did you mean
1203 </pre></td><td class="aligned"></td></tr>
1205 <tr><td><span class="name">different.IdenticalCondIfIf
1206 <br>(C)</span><br><br>
1207 The conditions of two subsequent 'if' statements are identical
1211 if (c > 5) // <-
1213 if (c > 5) // warn
1216 </pre></td><td class="aligned"></td></tr>
1218 <tr><td><span class="name">different.CondOpIdenticalReturn
1219 <br>(C)</span><br><br>
1220 The return expressions of the '?:' operator are identical
1224 a = a > 5 ? a : a; // warn
1226 </pre></td><td class="aligned"></td></tr>
1228 <tr><td><span class="name">different.LogicalOpUselessArg
1229 <br>(C)</span><br><br>
1230 The second operand of the && operator has no impact on expression result
1234 if (a<7 && a<10) {}; // warn
1236 </pre></td><td class="aligned"></td></tr>
1238 <tr><td><span class="name">different.SameResLogicalExpr
1239 <br>(C)</span><br><br>
1240 The expression always evaluates to true/false
1244 if (i!=0) {}; // warn
1245 if (i==0 && i==1) {}; // warn
1246 if (i<0 || i>=0) {}; // warn
1248 </pre></td><td class="aligned"></td></tr>
1250 <tr><td><span class="name">different.SameResUnsignedCmp
1251 <br>(C)</span><br><br>
1252 Comparison of unsigned expression 'op expr' is always true/false
1256 if (u < -1) {}; // warn
1257 if (u >= 0) {}; // warn
1259 </pre></td><td class="aligned"></td></tr>
1261 <tr><td><span class="name">different.OpPrecedenceAssignCmp
1262 <br>(C)</span><br><br>
1263 Comparison operation has higher precedence then assignment. Bool value is
1264 assigned to variable of type 'type'. Parenthesis may bee required around an
1272 if((b = x != y)) {} // ok
1273 if((x = f() != y)) {} // warn
1275 </pre></td><td class="aligned"></td></tr>
1277 <tr><td><span class="name">different.OpPrecedenceIifShift
1278 <br>(C)</span><br><br>
1279 ?: has lower precedence then <<
1281 #include <iostream>
1285 std::cout << a ? "a" : "b"; // warn
1286 a << a>7 ? 1 : 2; // warn
1288 </pre></td><td class="aligned"></td></tr>
1290 <tr><td><span class="name">different.ObjectUnused
1291 <br>(C++)</span><br><br>
1292 The object was created but is not being used<br><br>
1293 The exception object was created but is not being used. Did you mean
1294 'throw std::exception();'?
1296 #include <exception>
1300 S(int xx, int yy) : x(xx), y(yy) {
1309 std::exception(); // warn
1311 </pre></td><td class="aligned"></td></tr>
1313 <tr><td><span class="name">different.StaticArrayPtrCompare
1314 <br>(C)</span><br><br>
1315 Pointer to static array is being compared to NULL. May the subscripting is
1320 if (a1 == 0) {}; // warn
1323 if (a2[0]) {}; // warn
1325 </pre></td><td class="aligned"></td></tr>
1327 <tr><td><span class="name">different.ConversionToBool
1328 <br>maybe join with experimental.core.BoolAssignment<br>(C, C++)</span><br><br>
1329 Odd implicit conversion from 'type' to 'bool'
1335 </pre></td><td class="aligned"></td></tr>
1337 <tr><td><span class="name">different.ArrayBound
1338 <br>enhancement to experimental.security.ArrayBound[v2]<br>(C, C++)</span><br><br>
1339 Out-of-bound dynamic array access
1341 #include <stdlib.h>
1344 int *p2 = new int[1];
1345 if(p2[1]) {}; // warn
1347 if(p2[i]) {}; // warn
1349 </pre></td><td class="aligned"></td></tr>
1351 <tr><td><span class="name">different.StrcpyInputSize
1352 <BR>enhancement to experimental.unix.cstring.OutOfBounds<br>(C)</span><br><br>
1353 Buffer copy without checking size of input
1355 void test(char* string) {
1357 strcpy(buf, string); // warn
1359 </pre></td><td class="aligned"></td></tr>
1361 <tr><td><span class="name">different.IntegerOverflow
1362 <br>(C)</span><br><br>
1365 #include <limits.h>
1368 return INT_MAX+1; // warn
1372 int x = INT_MAX+1; // warn
1373 f(INT_MAX+1); // warn
1375 int y = INT_MAX/2+1; // warn
1378 </pre></td><td class="aligned"></td></tr>
1380 <tr><td><span class="name">different.SignExtension
1381 <br>(C)</span><br><br>
1382 Unexpected sign extension might take place
1384 void f(unsigned int i);
1387 unsigned int test() {
1389 unsigned long long ull = sll; // warn
1391 unsigned long ul = sl; // warn
1393 unsigned int ui = si; // warn
1395 unsigned short us = ss; // warn
1397 unsigned char uc = sc; // warn
1402 </pre></td><td class="aligned"></td></tr>
1404 <tr><td><span class="name">different.NumericTruncation
1405 <br>(C)</span><br><br>
1406 Numeric truncation might take place
1412 unsigned long long ull;
1414 unsigned long ul = ull; // warn
1415 long sl = sll; // warn
1416 unsigned int ui = ul; // warn
1417 int si = sl; // warn
1418 unsigned short us = ui; // warn
1419 short ss = si; // warn
1420 unsigned char uc = us; // warn
1421 signed char sc = uc; // warn
1426 </pre></td><td class="aligned"></td></tr>
1428 <tr><td><span class="name">different.MissingCopyCtorAssignOp
1429 <br>(C, C++)</span><br><br>
1430 The class has dynamically allocated data members but do not define a copy
1431 constructor/assignment operator
1436 C() { p = new int; }
1439 </pre></td><td class="aligned"></td></tr>
1443 <!-- ============================ WinAPI =================================== -->
1445 <table class="checkers">
1446 <col class="namedescr"><col class="example"><col class="progress">
1447 <thead><tr><td>Name, Description</td><td>Example</td><td>Progress</td></tr></thead>
1449 <tr><td><span class="name">WinAPI.CreateProcess
1450 <br>(C)</span><br><br>
1451 After calling CreateProcess(), ensure that process and thread handles get closed
1452 (* for the given example: examine data flow from pi, pi.hProcess and pi.hThread)
1454 #include <windows.h>
1458 PROCESS_INFORMATION pi;
1460 fSuccess = CreateProcess(
1461 NULL, TEXT("MyProgram.exe"), NULL, NULL,
1462 TRUE, 0, NULL, NULL, &si, &pi);
1464 </pre></td><td class="aligned"></td></tr>
1466 <tr><td><span class="name">WinAPI.LoadLibrary
1467 <br>(C)</span><br><br>
1468 Calling LoadLibrary without a fully qualified path may allow to load a DLL from
1471 #include <windows.h>
1474 HINSTANCE h = LoadLibrary("X.dll"); // warn
1476 </pre></td><td class="aligned"></td></tr>
1478 <tr><td><span class="name">WinAPI.WideCharToMultiByte
1479 <br>(C)</span><br><br>
1480 Buffer overrun while calling WideCharToMultiByte
1482 #include <windows.h>
1486 wchar_t ws[] = L"abc";
1488 int res1 = WideCharToMultiByte(
1489 CP_UTF8, 0, ws, -1, s,
1490 3, NULL, NULL); // warn
1491 int res2 = WideCharToMultiByte(
1492 CP_UTF8, 0, ws, -1, s,
1493 3, NULL, NULL); // ok
1494 if (res2 == sizeof(s))
1499 </pre></td><td class="aligned"></td></tr>
1503 <!-- =========================== optimization ============================== -->
1504 <h3>optimization</h3>
1505 <table class="checkers">
1506 <col class="namedescr"><col class="example"><col class="progress">
1507 <thead><tr><td>Name, Description</td><td>Example</td><td>Progress</td></tr></thead>
1509 <tr><td><span class="name">optimization.PassConstObjByValue
1510 <br>(C, C++)</span><br><br>
1511 Optimization: It is more effective to pass const n-th parameter by reference to
1512 avoid unnecessary object copying
1519 bool FirstIsZero(const struct A a) { // warn
1522 </pre></td><td class="aligned"></td></tr>
1524 <tr><td><span class="name">optimization.PostfixIncIter
1525 <br>(C++)</span><br><br>
1526 Optimization: It is more effective to use prefix ++ with iterator here
1528 #include <vector>
1531 std::vector<int> v;
1532 std::vector<int>::const_iterator it;
1534 it != v.end(); it++) {}; // warn
1536 </pre></td><td class="aligned"></td></tr>
1538 <tr><td><span class="name">optimization.MultipleCallsStrlen
1539 <br>(C)</span><br><br>
1540 Optimization: multiple calls to strlen for a given string in the given
1541 expression. It is more effective to hold strlen result in a temporary
1544 #include <string.h>
1547 const char* s = "abc";
1548 if (strlen(s) > 0 &&
1549 strlen(s) < 7) {}; // warn
1551 </pre></td><td class="aligned"></td></tr>
1553 <tr><td><span class="name">optimization.EmptyCstrDetect
1554 <br>(C)</span><br><br>
1555 Optimization: it is more efficient to use "str[0] != '\0'" to identify an empty
1558 #include <string.h>
1561 const char* s = "abc";
1562 if (strlen(s) > 0) {}; // warn
1564 </pre></td><td class="aligned"></td></tr>
1566 <tr><td><span class="name">optimization.StrLengthCalculation
1567 <br>(C, C++)</span><br><br>
1568 Optimization: it is more efficient to use string::length() method to calculate
1571 #include <string>
1572 #include <string.h>
1576 if (strlen(s.c_str()) != 0) {}; // warn
1578 </pre></td><td class="aligned"></td></tr>
1580 <tr><td><span class="name">optimization.EmptyContainerDetect
1581 <br>(C, C++)</span><br><br>
1582 Optimization: It is more efficient to use container.empty() to identify an
1585 #include <list>
1588 std::list<int> l;
1589 if (l.size() != 0) {}; // warn
1591 </pre></td><td class="aligned"></td></tr>
1596 </div> <!-- page -->
1597 </div> <!-- content -->