Skip to content

C and CPP Analysis

kevin-hinz edited this page Aug 21, 2023 · 6 revisions

Information

The content on this page has moved: https://docs.sonarsource.com/sonarlint/vs-code/getting-started/running-an-analysis/#analyze-c-and-cpp-code

The SonarLint documentation has moved! Please visit https://docs.sonarsource.com/sonarlint/vs-code/ to have a look at the new documentation website. We’ve improved the documentation as a whole, integrated the four SonarLint IDE extension docs together, and moved everything under the sonarsource.com domain to share a home with the SonarQube docs (SonarCloud to come in Q3 of 2023).

These GitHub wikis will no longer be updated after September 1st, 2023 but no worries, we’ll keep them around a while for those running previous versions of SonarLint for VS Code.

Prerequisite

To analyze C and C++ code, you need to:

  1. Generate a compilation database
  2. Be on one of the supported enviroments

Generate a Compilation Database

Compilation Database is a JSON file format introduced by the LLVM project. It contains the compile commands used to build a project.

Generating Compilation Database Using the Build System

Many build systems support the automatic generation of compilation databases. For example:

  • CMake by simply setting this option CMAKE_EXPORT_COMPILE_COMMANDS
  • VS Code Makefile Tools extension
  • Ninja by setting the compdb flag
  • Xcode through Clang's -gen-cdb-fragment-path feature:
    # Add the following "OTHER_CFLAGS" option to the xcodebuild command
    xcodebuild clean build <additional args> OTHER_CFLAGS="\$(inherited) -gen-cdb-fragment-path \$(PROJECT_DIR)/CompilationDatabase"
    # After the build, aggregate the fragments into "compile_commands.json"
    cd CompilationDatabase && sed -e '1s/^/[\'$'\n''/' -e '$s/,$/\'$'\n'']/' *.json > ../compile_commands.json && cd ..
    
  • Clang using the -MJ option. Note that this will generate a compilation database entry by input. The merge of all entries can be done through something like sed -e '1s/^/[\'$'\n''/' -e '$s/,$/\'$'\n'']/' *.o.json > compile_commands.json

When different choices are available, generating a compilation database through the build system should be preferred.

Generating Compilation Database Using Open Source Wrappers

Many open-source projects can help in generating a compilation database. For example:

Generating Compilation Database Using a Custom Script

A compilation database is just a JSON file that describes how to compile a project. If none of the previous approaches is feasible, for example, in the case of an internal build system, writing a script that generates a compilation database that describes how source files are supposed to be compiled can be the last resort.

Best Practices

  • Make sure that the compilation database contains the actual compile commands. This can be checked by running the compilation commands inside the compile_commands.json and verifying that they succeed
  • Make sure that the compilation database is up to date. It should be refreshed as part of the development cycle
  • If the build system uses environment variables, make sure that they are set in the VS Code environment
  • The compilation database should not contain header files entries. We use internal heuristics to analyze header files

Supported Environments

Supported Compilers

  • Any version of Clang, GCC, and Microsoft C/C++ compilers
  • Any version of Intel compiler for Linux and macOS
  • ARM5 and ARM6 compilers
  • IAR compilers for ARM, Atmel AVR32, Atmel AVR, Renesas H8, Renesas RL78, Renesas RX, Renesas V850, Texas Instruments MSP430, and 8051
  • QNX compilers
  • Texas Instruments compilers on Windows and macOS for ARM, C2000, C6000, C7000, MSP430, and PRU
  • Wind River Diab and GCC compilers
  • Compilers based wholly on GCC, including, for instance, Linaro GCC, are also supported
Supported Language Standards

  • C standards: C89, C99, C11, C18
  • C++ standards: C++03, C++11, C++14, C++17, and C++20 standards
  • GNU extensions
Supported Runtime Environments

  • Microsoft Windows on x86-64
  • Linux on x86-64
  • macOS with version 10.14.3 and later on x86-64

Activating the Analysis

The analysis can be activated by simply pointing to a compilation database that describes the project to be analyzed. This can be done through a notification that pops up when a folder that contains a file named compile_commands.json is opened, or through the SonarLint embedded action that lists all compilation database files in the folder, or by manually assigning the sonarlint.pathToCompileCommands option in the settings to the full path of the compilation database.

Note that the SonarLint embedded action can be used to switch the active compilation database.

Troubleshooting

In case the analysis is not working or obvious false positives are raised, here are the recommended actions in order:

1. Investigate the Logs

First, enable SonarLint Analyzer Logs and look if there is any error or failures that indicate what went wrong. If there is no obvious sign in the logs, enable Verbose Logs and check again.

2. Make Sure that the Compilation Database is Credible

  • Make sure that the compilation database is up to date: It doesn't contain outdated commands or points to files that no longer exist.
  • Make sure that the compilation database contains the actual compilation commands. This can be done by running the commands inside the compile_commands.json and verifying that they succeed.
  • Make sure that the VS Code environment has the environment variables required to build the project
3. Enable the Rule `S2260`

In case of obvious false positives in the raised issues, Enable the cpp:S2260/c:S2260 rule and check if it raises issues on the culprit file. This rule indicates that the analyzer failed to parse part of the code and might give hints or indicate a configuration problem. Follow the description of the rule if it raises issues. If not move to the step in troubleshooting.

4. Generate the CFamily reproducer File and Report the Issue

When non of the previous suggestions help solve the issue, please report the faced problem on the Sonar Community to help.

In case of a false positive or an analysis failure, we need the CFamily reproducer file to investigate the issue. To generate the reproducer file, add the following analyzer option to the settings.json:

"sonarlint.analyzerProperties": {"sonar.cfamily.reproducer" : "C:\\replace\\by\\path\\to\\file.cpp"}

sonar.cfamily.reproducer should point to the source or header file on which you face the issue. After setting that option, trigger the analysis on the culprit file. You should see in the logs that a file name sonar-cfamily.reproducer is generated in a temporary directory. Upload that file in your community report or ask us to share it privately if it contains sensitive information.