A Look at Static Analysis Tools
By Jeff Tranter | Tuesday, November 14, 2017
Static Analysis (1), or more correctly, Static Program Analysis, is a method of analysis of computer software that is performed by examining source code without actually executing it. It is typically performed by automated tools.
Static analysis is increasingly used in the development of safety-critical software, such as medical, nuclear and aviation systems. In this installment of our series on software development tools, today we look at some options for static analysis, focusing on those that support C++.
Cppcheck (2) is a static code analysis tool for the C and C++ programming languages. It runs on most platforms and is free software released under the GNU GPL.
It checks for a number of issues, including automatic variable checking, bounds checking for array overruns, correct use of C++ classes, use of deprecated or superseded functions, exception safety checking, usage of memory allocation and destructors, and certain types of memory and resource leaks.
I tried it on a very simple code example that had some intentional errors in it, and it immediately reported the problems:
[demo.cpp:11]: (error) Array 'x' accessed at index 10, which is out of bounds. [demo.cpp:20]: (error) Array 'y' accessed at index 4, which is out of bounds. [demo.cpp:24]: (error) Memory leak: x [demo.cpp:24]: (error) Memory leak: y [demo.cpp:22]: (error) Invalid memory address freed.
Clang/Clang Analyzer/Clang Tooling
Clang is a compiler front end for a number of programming languages, including C++. It is open source, and much of the development is done by Apple, who use it as the Objective-C compiler for Mac OS. It is highly compatible with gcc. As well as a compiler, Clang is used as a front end for a number of analysis tools including the Clang Static Analyzer (3).
On Linux systems, you can invoke the Clang Static Analyzer using a Perl script called scan-build. You can read the documentation for details. It generates output as text or as nicely formatting HTML that you can view in a web browser.
Here is an example for a small program that contains an error:
% scan-build g++ demo.cpp scan-build: Using '/usr/lib/llvm-4.0/bin/clang' for static analysis demo.cpp:17:23: warning: Division by zero result = left / right; ~~~~~^~~~~~~ 1 warning generated. scan-build: 1 bug found. scan-build: Run 'scan-view /tmp/scan-build-2017-09-26-150842-24144-1' to examine bug reports.
The HTML reports looks like the screen shots below:
An easy way to run the Clang static analyzer is from the Qt Creator IDE. If Clang is installed on your system, and a Qt project loaded, you can select Analyze / Clang Static Analyzer from the menu and it will analyze your current project.
OCLint (4) is a static code analysis tool for improving quality and reducing defects by inspecting C, C++ and Objective-C code and looking for potential problems like empty conditional statements, unused code, code with high cyclomatic complexity, and incorrect use of parameters.
Here is an example of the output for a small test program:
Compiler Warnings: demo.cpp:21:1: control may reach end of non-void function OCLint Report Summary: TotalFiles=1 FilesWithViolations=1 P1=0 P2=0 P3=9 demo.cpp:29:5: unused local variable [unused|P3] The local variable 'c' is unused. demo.cpp:30:5: unused local variable [unused|P3] The local variable 'i' is unused. demo.cpp:30:5: unused local variable [unused|P3] The local variable 'j' is unused. demo.cpp:4:16: short variable name [naming|P3] Length of variable name `op` is 2, which is shorter than the threshold of 3 demo.cpp:29:5: short variable name [naming|P3] Length of variable name `c` is 1, which is shorter than the threshold of 3 demo.cpp:30:5: short variable name [naming|P3] Length of variable name `i` is 1, which is shorter than the threshold of 3 demo.cpp:30:5: short variable name [naming|P3] Length of variable name `j` is 1, which is shorter than the threshold of 3 demo.cpp:33:5: short variable name [naming|P3] Length of variable name `x` is 1, which is shorter than the threshold of 3 demo.cpp:44:5: short variable name [naming|P3] Length of variable name `y` is 1, which is shorter than the threshold of 3 [OCLint (http://oclint.org) v0.12]
To obtain OCLint you'll probably need to download a package from the project web site or build it from source.
There are a number of commercial status analysis tools. I have only limited experience with a few of them. They can be very expensive to purchase, but can pay for themselves by finding serious bugs in your code.
Some of these tools have free or less expensive licenses for checking open source software. The Qt project, for example, is regularly scanned using Coverity and the results presented to the developers.
Here are some commercial static analysis tools that you might want to investigate: PC-lint (5), Klocwork (6), Veracode (7), Coverity (8), and Black Duck (9).
The qmllint program, part of Qt since the 5.4 release, checks QML files for correct syntax. In my experience, it doesn't typically catch hidden errors in code but can be useful as part of a Continuous Integration (CI) system to detect errors at build time or on code check-in to verify that QML code doesn't contain syntax errors.
Clazy (10)(11) is a compiler plugin that allows Clang to understand Qt semantics. It can check code for common errors and the use of best practices for using Qt. Examples include use of the new style connect() syntax, incorrect use of connect() or emit(), and incorrect or inefficient use of Qt containers.
Bjarne Stroustrup, the creator of C++, has released a set of C++ Core Guidelines (12) that cover C++ best practices. A number of tools, including Clang and Microsoft's C++ compiler, can now check for enforcement of many of these guidelines. I expect we will see more tools supporting this in the future.
I encourage you to explore static analysis tools and make them part of your software development process. It is best to use them early in your project, to catch errors sooner and avoid having to wade through many warnings in existing code after it has been developed.