Cppcheck is a simple tool for static analysis of C/C++ code.
When you write a checker you have access to:
- Token list - the tokenized code
- Syntax tree - Syntax tree of each expression
- SymbolDatabase - Information about all types/variables/functions/etc in the current translation unit
- Library - Configuration of functions/types
- Value flow analysis - Context sensitive analysis that determine possible values for each token
Use –debug on the command line to see debug output for the token list and the syntax tree. If both –debug and –verbose is used, the symbol database is also written.
The checks are written in C++. The checks are addons that can be easily added/removed.
Writing a check
Below is a simple example of a check that detect division with zero:
The function Token::Match is often used in the checks. Through it you can match tokens against patterns. It is currently not possible to write match expressions that uses the syntax tree, the symbol database, nor the library. Only the token list is used.
Creating a new check class from scratch
Check classes inherit from the Check class. The Check class specifies the interface that you must use. To integrate a check class into cppcheck all you need to do is:
- Add your source file(s) so they are compiled into the executable.
- Create an instance of the class (the Check::Check() constructor registers the class as an addon that Cppcheck then can use).
Cppcheck is designed to be easily embeddable into other programs.
The "cli/main.cpp" and "cli/cppcheckexecutor.*" files illustrate how cppcheck can be embedded into an application.
This happens when you execute cppcheck from the command line:
- CppCheckExecutor::check this function executes the Cppcheck
- CppCheck::parseFromArgs parse command line arguments
- The Settings class is used to maintain settings
- Use FileLister and command line arguments to get files to check
- ThreadExecutor create more instances of CppCheck if needed
- CppCheck::check is called for each file. It checks a single file
- Preprocess the file (through Preprocessor)
- Comments are removed
- Macros are expanded
- Tokenize the file (see Tokenizer)
- Run the runChecks of all check classes.
- Simplify the tokenlist (Tokenizer::simplifyTokenList2)
- Run the runSimplifiedChecks of all check classes
When errors are found, they are reported back to the CppCheckExecutor through the ErrorLogger interface