static-analysiscppcheck

using cppcheck with an explicit set of macro combinations


cppcheck produces a set of combinations of all macros that affect conditional compilation of all headers or sources by default, then filters them down to a set of some 12 combinations unless --force is used.

I have a large codebase with a lot of portability macros. I'm only interested in targeting a relatively small subset of these for what I'm testing, so I've used --config-exclude=include/port/ to filter out all the port headers in my project.

The trouble is that cppcheck then appears to test no combinations at all - to the point where it fails to complain of obviously bogus code like

    int *foo = NULL;

    *foo = 1;

In any case, I'd actually like to test some combinations of macros, just not the whole unmanageable list.

Is there any sane way to get cppcheck to accept a list of macros to try combinations of? Or am I going to be stuck with generating explicit -U and -D lists to pass to it in multiple invocations myself?

I've noticed that it likes to try things like running with -DMSC_VER and without it. If I explicitly set -DMSC_VER then it finds a planted issue that's outside any #ifdef MSC_VER guard; but if I set -UMSC_VER then it fails to find the issue and appears to test zero combinations.

It's as if an explicit -Umacro doesn't execute the same path as the path cppcheck takes if it's allowed to try both the defined and not-defined paths itself...


Solution

  • --project=compilation_commands.json would allow for this nowadays.

    A project configuration can specify checks for the same source file many times with different macros.

    Other solution is to force-include a dummy header containing combinatory macro structure that represents your build. Arguments needed are: --include=$DIR/cppcheck_macro_config.h

    --suppress=unknownMacro may be also needed, because first combination contains alsways no macros, and it may trigger errors.

    And example:

    #ifdef STM32H7
      #ifdef STM32H725xx
      #elif STM32H723
      #else
      #endif
    #elif defined(STM32F4)
      #ifdef STM32F413xx
        #ifdef ENABLE_SPI
        #endif
      #endif
    #else
    #endif
    

    Note, that this is would become very messy if there was more than two levels of combinations.

    The only advantage to the first method is that it works with misra plugin better. Specifically with System level checks (e.g. rule 2.5) that require .ctu-info files interpretation. Which, as of now (v2.14.1), is not supported with --project argument.