Open feldrim opened 8 years ago
This is something I'd definitely be interested in trying but I guess I've never really found the right tool. Do you have any recommendations? Something cross platform and powerful would be nice.
Clang-analyzer is a good start. I also use coverity which is free (of charge) for opensource projects
On 21 Apr 2016, at 19:10, Daniel Holden notifications@github.com wrote:
This is something I'd definitely be interested in trying but I guess I've never really found the right tool. Do you have any recommendations? Something cross platform and powerful would be nice.
— You are receiving this because you are subscribed to this thread. Reply to this email directly or view it on GitHub
I've used Coverity Scan for now. I've tried Cppcheck too. But it's a different one since it doesn't do syntax checks, yet very helpful. Clang-analyzer seems like the most common one, which @radare mentioned.
I've heard about Klocwork, Frama-C, splint and ECLAIR but haven't use any. A simple Google search effort would be more helpful than the information I've provided. But static code analysis is required for non-hobby projects, that's for sure.
I tried analyzing with CppCheck tool, which is not a syntax checking but error checking tool. Here are the results of the repository:
[benchmarks\Dict\dict_cello.c:27]: (error) Memory leak: buf
[benchmarks\Dict\dict_cpp.cpp:49]: (error) Common realloc mistake: 'mem' nulled but not freed upon failure
[benchmarks\GC\gc_c.c:6]: (style) Variable 'i00' is allocated memory that is never used.
[benchmarks\GC\gc_c.c:6]: (style) Variable 'i01' is allocated memory that is never used.
[benchmarks\GC\gc_c.c:6]: (style) Variable 'i02' is allocated memory that is never used.
[benchmarks\GC\gc_c.c:6]: (style) Variable 'i03' is allocated memory that is never used.
[benchmarks\GC\gc_c.c:6]: (style) Variable 'i04' is allocated memory that is never used.
[benchmarks\GC\gc_c.c:7]: (style) Variable 'i05' is allocated memory that is never used.
[benchmarks\GC\gc_c.c:7]: (style) Variable 'i06' is allocated memory that is never used.
[benchmarks\GC\gc_c.c:7]: (style) Variable 'i07' is allocated memory that is never used.
[benchmarks\GC\gc_c.c:7]: (style) Variable 'i08' is allocated memory that is never used.
[benchmarks\GC\gc_c.c:7]: (style) Variable 'i09' is allocated memory that is never used.
[benchmarks\GC\gc_c.c:8]: (style) Variable 'i10' is allocated memory that is never used.
[benchmarks\GC\gc_c.c:8]: (style) Variable 'i11' is allocated memory that is never used.
[benchmarks\GC\gc_c.c:8]: (style) Variable 'i12' is allocated memory that is never used.
[benchmarks\GC\gc_c.c:8]: (style) Variable 'i13' is allocated memory that is never used.
[benchmarks\GC\gc_c.c:8]: (style) Variable 'i14' is allocated memory that is never used.
[benchmarks\GC\gc_c.c:9]: (style) Variable 'i15' is allocated memory that is never used.
[benchmarks\GC\gc_c.c:9]: (style) Variable 'i16' is allocated memory that is never used.
[benchmarks\GC\gc_c.c:9]: (style) Variable 'i17' is allocated memory that is never used.
[benchmarks\GC\gc_c.c:9]: (style) Variable 'i18' is allocated memory that is never used.
[benchmarks\GC\gc_c.c:9]: (style) Variable 'i19' is allocated memory that is never used.
[benchmarks\GC\gc_c.c:10]: (style) Variable 'i20' is allocated memory that is never used.
[benchmarks\GC\gc_c.c:10]: (style) Variable 'i21' is allocated memory that is never used.
[benchmarks\GC\gc_c.c:10]: (style) Variable 'i22' is allocated memory that is never used.
[benchmarks\GC\gc_c.c:10]: (style) Variable 'i23' is allocated memory that is never used.
[benchmarks\GC\gc_c.c:10]: (style) Variable 'i24' is allocated memory that is never used.
[benchmarks\GC\gc_c.c:11]: (style) Variable 'i25' is allocated memory that is never used.
[benchmarks\GC\gc_c.c:11]: (style) Variable 'i26' is allocated memory that is never used.
[benchmarks\GC\gc_c.c:11]: (style) Variable 'i27' is allocated memory that is never used.
[benchmarks\GC\gc_c.c:11]: (style) Variable 'i28' is allocated memory that is never used.
[benchmarks\GC\gc_c.c:11]: (style) Variable 'i29' is allocated memory that is never used.
[benchmarks\GC\gc_c.c:12]: (style) Variable 'i30' is allocated memory that is never used.
[benchmarks\GC\gc_c.c:12]: (style) Variable 'i31' is allocated memory that is never used.
[benchmarks\GC\gc_c.c:12]: (style) Variable 'i32' is allocated memory that is never used.
[benchmarks\GC\gc_c.c:12]: (style) Variable 'i33' is allocated memory that is never used.
[benchmarks\GC\gc_c.c:12]: (style) Variable 'i34' is allocated memory that is never used.
[benchmarks\GC\gc_c.c:15]: (error) Memory leak: i00
[benchmarks\GC\gc_c.c:15]: (error) Memory leak: i01
[benchmarks\GC\gc_c.c:15]: (error) Memory leak: i02
[benchmarks\GC\gc_c.c:15]: (error) Memory leak: i03
[benchmarks\GC\gc_c.c:15]: (error) Memory leak: i04
[benchmarks\GC\gc_c.c:15]: (error) Memory leak: i05
[benchmarks\GC\gc_c.c:15]: (error) Memory leak: i06
[benchmarks\GC\gc_c.c:15]: (error) Memory leak: i07
[benchmarks\GC\gc_c.c:15]: (error) Memory leak: i08
[benchmarks\GC\gc_c.c:15]: (error) Memory leak: i09
[benchmarks\GC\gc_c.c:15]: (error) Memory leak: i10
[benchmarks\GC\gc_c.c:15]: (error) Memory leak: i11
[benchmarks\GC\gc_c.c:15]: (error) Memory leak: i12
[benchmarks\GC\gc_c.c:15]: (error) Memory leak: i13
[benchmarks\GC\gc_c.c:15]: (error) Memory leak: i14
[benchmarks\GC\gc_c.c:15]: (error) Memory leak: i15
[benchmarks\GC\gc_c.c:15]: (error) Memory leak: i16
[benchmarks\GC\gc_c.c:15]: (error) Memory leak: i17
[benchmarks\GC\gc_c.c:15]: (error) Memory leak: i18
[benchmarks\GC\gc_c.c:15]: (error) Memory leak: i19
[benchmarks\GC\gc_c.c:15]: (error) Memory leak: i20
[benchmarks\GC\gc_c.c:15]: (error) Memory leak: i21
[benchmarks\GC\gc_c.c:15]: (error) Memory leak: i22
[benchmarks\GC\gc_c.c:15]: (error) Memory leak: i23
[benchmarks\GC\gc_c.c:15]: (error) Memory leak: i24
[benchmarks\GC\gc_c.c:15]: (error) Memory leak: i25
[benchmarks\GC\gc_c.c:15]: (error) Memory leak: i26
[benchmarks\GC\gc_c.c:15]: (error) Memory leak: i27
[benchmarks\GC\gc_c.c:15]: (error) Memory leak: i28
[benchmarks\GC\gc_c.c:15]: (error) Memory leak: i29
[benchmarks\GC\gc_c.c:15]: (error) Memory leak: i30
[benchmarks\GC\gc_c.c:15]: (error) Memory leak: i31
[benchmarks\GC\gc_c.c:15]: (error) Memory leak: i32
[benchmarks\GC\gc_c.c:15]: (error) Memory leak: i33
[benchmarks\GC\gc_c.c:15]: (error) Memory leak: i34
[benchmarks\GC\gc_cello.c:12]: (style) Variable 'i33' is assigned a value that is never used.
[benchmarks\GC\gc_cpp.cpp:18]: (style) Variable 'i33' is assigned a value that is never used.
[benchmarks\Map\map_c.c:34]: (error) Common realloc mistake: 'mem' nulled but not freed upon failure
[benchmarks\Map\map_cello.c:26]: (error) Memory leak: buf
[benchmarks\Map\map_cpp.cpp:23]: (style) Unused variable: ret
[benchmarks\Map\map_cpp.cpp:37]: (error) Common realloc mistake: 'mem' nulled but not freed upon failure
[benchmarks\Matmul\matmul_cello.c:29]: (error) Uninitialized struct member: m.n
[benchmarks\Matmul\matmul_cello.c:42]: (error) Uninitialized struct member: m.n
[benchmarks\Matmul\matmul_cpp.cpp:15]: (warning) Redundant assignment of 'n' to itself.
[benchmarks\Matmul\matmul_cpp.cpp:14]: (warning) Member variable 'Matrix::n' is not initialized in the constructor.
[benchmarks\Matmul\matmul_cpp.cpp:3]: (style) 'class Matrix' does not have a copy constructor which is recommended since the class contains a pointer to allocated memory.
[benchmarks\Matmul\matmul_cpp.cpp:9]: (style) Class 'Matrix' has a constructor with 1 argument that is not explicit.
[benchmarks\Sudoku\sudoku_c.c:112]: (style) The scope of the variable 'cc2' can be reduced.
[benchmarks\Sudoku\sudoku_c.c:110]: (error) Shifting a negative value is undefined behaviour
[benchmarks\Sudoku\sudoku_c.c:89]: (style) Unused variable: r2
[benchmarks\Sudoku\sudoku_cello.c:36]: (style) The scope of the variable 'cc2' can be reduced.
[benchmarks\Sudoku\sudoku_cello.c:34]: (error) Shifting a negative value is undefined behaviour
[benchmarks\Sudoku\sudoku_cpp.cpp:114]: (style) The scope of the variable 'cc2' can be reduced.
[benchmarks\Sudoku\sudoku_cpp.cpp:112]: (error) Shifting a negative value is undefined behaviour
[benchmarks\Sudoku\sudoku_cpp.cpp:93]: (style) Unused variable: r2
[benchmarks\ext\regexp9.c:1104] -> [benchmarks\ext\regexp9.c:1104]: (warning) Either the condition 'mp!=0' is redundant or there is possible null pointer dereference: mp.
[benchmarks\ext\regexp9.c:1124] -> [benchmarks\ext\regexp9.c:1124]: (warning) Either the condition 'mp!=0' is redundant or there is possible null pointer dereference: mp.
[benchmarks\ext\regexp9.c:1398] -> [benchmarks\ext\regexp9.c:1398]: (warning) Either the condition 'mp!=0' is redundant or there is possible null pointer dereference: mp.
[benchmarks\ext\regexp9.c:1418] -> [benchmarks\ext\regexp9.c:1418]: (warning) Either the condition 'mp!=0' is redundant or there is possible null pointer dereference: mp.
[benchmarks\ext\regexp9.c:151]: (style) The scope of the variable 'c1' can be reduced.
[benchmarks\ext\regexp9.c:185]: (style) The scope of the variable 'i' can be reduced.
[benchmarks\ext\regexp9.c:430]: (style) The scope of the variable 'inst' can be reduced.
[benchmarks\ext\regexp9.c:864]: (style) The scope of the variable 'i' can be reduced.
[benchmarks\ext\regexp9.c:868]: (style) The scope of the variable 'nl' can be reduced.
[benchmarks\ext\regexp9.c:869]: (style) The scope of the variable 'tle' can be reduced.
[benchmarks\ext\regexp9.c:870]: (style) The scope of the variable 'nle' can be reduced.
[benchmarks\ext\regexp9.c:1175]: (style) The scope of the variable 'i' can be reduced.
[benchmarks\ext\regexp9.c:1178]: (style) The scope of the variable 'nl' can be reduced.
[benchmarks\ext\regexp9.c:1179]: (style) The scope of the variable 'tle' can be reduced.
[benchmarks\ext\regexp9.c:1180]: (style) The scope of the variable 'nle' can be reduced.
[benchmarks\ext\regexp9.c:1016]: (error) Memory leak: relist0
[benchmarks\ext\regexp9.c:1152]: (warning) Conversion of string literal "regerr" to bool always evaluates to true.
[benchmarks\ext\regexp9.c:1]: (information) Skipping configuration 'AUTOLIB' since the value of 'AUTOLIB' is unknown. Use -D if you want to check it. You can use -U to skip it explicitly.
[examples\iteration.c:11]: (style) Variable 'items' is assigned a value that is never used.
[examples\newtype.c:0]: (information) The configuration '' was not checked because its code equals another one.
[examples\newtype.c:41]: (error) Syntax Error: AST broken, ternary operator lacks ':'.
[examples\object.c:5]: (style) struct member 'Point::x' is never used.
[examples\object.c:5]: (style) struct member 'Point::y' is never used.
[examples\threads.c:17]: (style) Variable 'threads' is assigned a value that is never used.
[src\Array.c:246] -> [src\Array.c:246]: (style) Same expression on both sides of '&&'.
[src\Array.c:302]: (style) Consecutive return, break, continue, goto or throw statements are unnecessary.
[src\Array.c:347]: (style) Consecutive return, break, continue, goto or throw statements are unnecessary.
[src\Array.c:366]: (style) Consecutive return, break, continue, goto or throw statements are unnecessary.
[src\Array.c:402]: (style) Consecutive return, break, continue, goto or throw statements are unnecessary.
[src\Exception.c:265]: (style) Variable 'buffer' is not assigned a value.
[src\File.c:188]: (style) Variable 'f' is assigned a value that is never used.
[src\GC.c:162]: (style) Consecutive return, break, continue, goto or throw statements are unnecessary.
[src\Iter.c:350]: (style) Variable 'r' is assigned a value that is never used.
[src\Iter.c:652]: (style) Variable 's' is assigned a value that is never used.
[src\List.c:207] -> [src\List.c:207]: (style) Same expression on both sides of '&&'.
[src\List.c:173]: (style) Variable 'l' is assigned a value that is never used.
[src\List.c:97]: (error) Memory leak: item
[src\List.c:335]: (style) Consecutive return, break, continue, goto or throw statements are unnecessary.
[src\Show.c:402]: (style) Expression is always false because 'else if' condition matches previous condition at line 400.
[src\Show.c:409]: (style) Expression is always false because 'else if' condition matches previous condition at line 400.
[src\Show.c:439]: (style) Expression is always false because 'else if' condition matches previous condition at line 400.
[src\Show.c:447]: (style) Expression is always false because 'else if' condition matches previous condition at line 400.
[src\Show.c:409]: (style) Expression is always false because 'else if' condition matches previous condition at line 402.
[src\Show.c:439]: (style) Expression is always false because 'else if' condition matches previous condition at line 402.
[src\Show.c:447]: (style) Expression is always false because 'else if' condition matches previous condition at line 402.
[src\Show.c:439]: (style) Expression is always false because 'else if' condition matches previous condition at line 409.
[src\Show.c:447]: (style) Expression is always false because 'else if' condition matches previous condition at line 409.
[src\Show.c:447]: (style) Expression is always false because 'else if' condition matches previous condition at line 439.
[src\Table.c:277] -> [src\Table.c:277]: (style) Same expression on both sides of '&&'.
[src\Table.c:272]: (style) The scope of the variable 'c' can be reduced.
[src\Thread.c:404]: (style) Variable 't' is assigned a value that is never used.
[src\Thread.c:419]: (style) Variable 't' is assigned a value that is never used.
[src\Thread.c:606]: (style) Variable 'm' is assigned a value that is never used.
[src\Thread.c:615]: (style) Variable 'm' is assigned a value that is never used.
[src\Thread.c:624]: (style) Variable 'm' is assigned a value that is never used.
[src\Thread.c:642]: (style) Variable 'm' is assigned a value that is never used.
[src\Thread.c:659]: (style) Variable 'm' is assigned a value that is never used.
[src\Tree.c:237] -> [src\Tree.c:237]: (style) Same expression on both sides of '&&'.
[src\Tree.c:588]: (style) Consecutive return, break, continue, goto or throw statements are unnecessary.
[src\Tree.c:232]: (style) The scope of the variable 'c' can be reduced.
[src\Tree.c:151]: (style) Variable 'key' is assigned a value that is never used.
[src\Tree.c:153]: (style) Variable 'val' is assigned a value that is never used.
[src\Tree.c:208]: (style) Variable 'm' is assigned a value that is never used.
[src\Tuple.c:476] -> [src\Tuple.c:476]: (style) Same expression on both sides of '&&'.
[src\Tuple.c:214]: (style) Consecutive return, break, continue, goto or throw statements are unnecessary.
[src\Tuple.c:287]: (style) Consecutive return, break, continue, goto or throw statements are unnecessary.
[tests\test.c:445]: (style) Variable 'testoutput2' is assigned a value that is never used.
[tests\test.c:2015]: (style) Variable 'cid' is assigned a value that is never used.
[tests\test.c:2796]: (style) Variable 'r3' is assigned a value that is never used.
[tests\test.c:2802]: (style) Variable 'r3' is assigned a value that is never used.
[tests\test.c:2808]: (style) Variable 'r3' is assigned a value that is never used.
Interesting. I checked a few but most seem like false positives. In particular anything intended to be cleaned up by the GC is reported. I should look through all the reports a bit more closely at a later date.
Yes, memory errors are expected because of GC's existence. Though there are a few more things mentioned in the report, some of which are about styling. If you are sure about false positives, you may give a feedback to the CppCheck community.
There are many statical analysis systems for C language. Mostly specified on some standards. Have you tried any for Cello? Some of them may give some errors which a developer may never see because it's not on an embedded platform etc. But it'd be good to see the limitations since it has some hacks as you've mentioned and those hacks may cause some issues under some conditions.