1.2. Cppcheck Application Note

Cppcheck is an open source static analysis tool for C/C++. In addition to various static analysis, it also has an addon to verify compliance with MISRA C 2012. Please refer to Cppcheck Project Page for details on Cppcheck.

Cppcheck can be run standalone or along with MISRA addon from within the RMM build system. TF-RMM aims to have 0 outstanding errors with the recommended Cppcheck version mentioned in Tool & Dependency overview.

1.2.1. Installing Cppcheck

Cppcheck can be installed directly from various package managers or built from source. However installing from package manager can get you an outdated version.

For building from source, please refer to Cppcheck GitHub for downloading recommended version and build guidelines. Once Cppcheck is built, add both Cppcheck binary folder and Cppcheck-htmlreport folder to PATH. The latter is used to convert Cppcheck XML output into user friendly html report. Asssuming that build is the output folder for Cppcheck build:

export PATH=$cppcheck_root/build/bin:$cppcheck_root/htmlreport:$PATH
cppcheck --version

The Cppcheck version should report the recommended version.

1.2.2. Invoking Cppcheck rule within TF-RMM build system

If you own a valid copy of a MISRA rules file, copy the file to the below location as it will give a more descriptive error message on detecting MISRA errors.

cp -a <path to the misra rules file>/<file name> ${RMM_SOURCE_DIR}/tools/cppcheck/misra.rules

To invoke the standard Cppcheck static analysis build rule on TF-RMM, run the cppcheck build target after TF-RMM configuration :

cd $rmm_root
cmake -DRMM_CONFIG=fvp_defcfg -S . -B build  -DCMAKE_EXPORT_COMPILE_COMMANDS=ON
cmake --build build -- cppcheck

The -DCMAKE_EXPORT_COMPILE_COMMANDS=ON generates a compile_commands.json file containing the exact compiler calls for all translation units of the project in machine-readable form.

The successful execution of the build target will generate cppcheck.xml in build/tools/cppcheck folder.

To invoke the Cppcheck static analysis with MISRA addon, run the cppcheck-misra build target:

cd $rmm_root
cmake -DRMM_CONFIG=fvp_defcfg -S . -B build  -DCMAKE_EXPORT_COMPILE_COMMANDS=ON
cmake --build build -- cppcheck-misra

This will generate cppcheck_misra.xml in build/tools/cppcheck folder.

If the above generated xml contains error tags detected by Cppcheck and if the installed version of Cppcheck matches or exceeds the recommended version mentioned in Tool & Dependency overview, the build fails and prints the error count. However, if the installed version is less than the recommended version, a warning is generated and the output is not parsed for errors.

1.2.3. Generating the Cppcheck HTML report

To generate html report in current directory after the Cppcheck build target has executed, run cppcheck-htmlreport tool with the genenerated xml file as input. For example, after the cppcheck-misra build target has completed, use the below cmd line to generate the html report :

cppcheck-htmlreport --file=./build/tools/cppcheck/cppcheck_misra.xml --report-dir=test --source-dir=.

The output will be generated in the specified report-dir and, for the above command, the html report can be found at ./test/index.html.

1.2.4. Cppcheck Error Suppression

TF-RMM as a project has decided to suppress some rules because either the rule is not found to be useful for the project or there are too many false positives generated by the rule. The global suppression rules are specified via suppressions.txt file present in tools/cppcheck directory.

If more suppressions need to be added for Cppcheck, it can be done by adding it to the suppression rules file. For example, to skip ext folder from Cppcheck analysis, add the following line to the file :

*:*/ext/*

Suppression can be added inline to code as a comment. For example, to suppress the uninitvar rule on a particular line, add the following comment above the line :

/* cppcheck-suppress uninitvar */

Multiple rules can be disabled via this method, as shown in example below :

/* cppcheck-suppress [arrayIndexOutOfBounds, uninitvar] */

If a certain rule needs to be suppressed for a block of code, the block suppression format can be used as shown in example below:

/* cppcheck-suppress-begin uninitvar */
block_of_code;
/* cppcheck-suppress-end uninitvar */