diff --git a/man/cppcheck-design-overview.docbook b/man/cppcheck-design-overview.docbook new file mode 100644 index 000000000..d5daf3781 --- /dev/null +++ b/man/cppcheck-design-overview.docbook @@ -0,0 +1,204 @@ + +
+ + Cppcheck Design Overview + + + DanielMarjamäki + + + Cppcheck + + + + 2010 + + +
+ Introduction + + This article is an overview of the design of Cppcheck. + + The design of Cppcheck are based on: + + + + Cppcheck will never be perfectly clever + + + + No false warnings are allowed + + +
+ +
+ Limitations of static analysis + + It is not very reasonable to think that a static analysis tool will + detect all bugs in your code. + + There are many bugs in programs that is really hard to detect for + tools. + + Many bugs are caused by wrong calculations. Here is an + example: + + // calculate number of days +int days(int hours) +{ + return hours / 23; +} + + A human programmer can see the error in that code because he knows + that there are 24 hours in a day. + + Tools will probably not know that there are 24 hours in a + day. + + A tool that tries to guarantee that all bugs are found could write a + warning message for every calculation in the program. In my humble opinion + it wouldn't be usable to do that. + + Cppcheck will only write a warning message if it can determine that + the calculation is wrong. This approach means that many bugs will not be + detected. +
+ +
+ Buffer overflows + + This is a simple description of the buffer overflows checking in + Cppcheck. + + For simple cases, no sophisticated control flow analysis is used. If + an array is accessed out of bounds somewhere in its scope then an error + message will be written. + + An example code: + + void f() +{ + char a[10]; + if (x + y == 2) { + a[20] = 0; + } +} + + Cppcheck will report this message: + + Array 'a[10]' index 20 out of bounds + + Cppcheck will not try to determine how execution can reach the + "a[20] = 0;" statement. It is assumed that all statements are reachable. + Cppcheck will detect the error even if it is really impossible that "x + y + == 2" is true. I still claim that this is a correct warning because the + statement is there and it has the error. + + Cppcheck will also investigate function calls. But then control flow + is needed to avoid false warnings. Here is an example that logically is + the same as the previous example: + + void f1(char *s) +{ + s[20] = 0; +} + +void f2() +{ + char a[10]; + if (x + y == 2) { + f1(a); + } +}Cppcheck will report this message: + + Array 'a[10]' index 20 out of bounds + + If the execution reaches the function call then there will be an + error. + + But if the condition is moved into "f1" then it will be necessary to + prove that "x+y==2" can be true when the function is called from + "f2". + + No error message is reported for this code: + + void f1(char *s) +{ + if (x + y == 2) { + s[20] = 0; + } +} + +void f2() +{ + char a[10]; + f1(); +} +
+ +
+ Memory leaks + + Simple control-flow analysis is made. The assumtion is that all + conditions can always be either true or false. + + It is assumed that all statements are reachable. + + Here is an example: + + void f() +{ + char *a = malloc(10); + if (x + y == 2) { + return; + } + free(a); +} + + Cppcheck will determine that there is a leak at the "return;" + statement: + + Memory leak: a + + Cppcheck doesn't try to determine how the execution reaches the + "return;" statement. It will only see that if the execution reaches the + "return;" then there will be a memory leak. + + This lack of advanced control-flow analysis means that many bugs are + not detected: + + void f(int x) +{ + char *a = 0; + + if (x == 10) + a = malloc(10); + + if (x == 20) + free(a); +} + + Many other static analysis tools will probably detect that. + + Many memory leaks are caused by: + + + + Completely forgetting to deallocate + + + + Forgetting to deallocate in a bailout path + + + + These types of leaks should be detected by Cppcheck. +
+