Menu

Suppression not working reliable when using --cppcheck-build-dir

2021-06-10
2023-06-15
  • Tobias Mark

    Tobias Mark - 2021-06-10

    Code:

    int main(int argc, char *argv[])
    {
        // cppcheck-suppress unreadVariable
        int i = 0;
    }  
    

    On first run no output as expected:

    $ cppcheck --cppcheck-build-dir=/tmp/cpp --enable=all --inline-suppr test.c
    Checking test.c ...
    

    However if called again immediately without any change:

    $ cppcheck --cppcheck-build-dir=/tmp/cpp --enable=all --inline-suppr test.c
    Checking test.c ...
    test.c:4:0: information: Unmatched suppression: unreadVariable [unmatchedSuppression]
        int i = 0;
    

    I have to add another --suppress=unmatchedSuppression:test.c to make this work.

    This feels like a Bug to me.
    a) its a chore to add a --supress for every file that has a 'real' suppression. Because --suppress=unmatchedSuppression:* is not enough.
    b) should the 'real' suppression become no longer needed i will never see it. This basically rendering the whole unmatchedSuppression check useless.

    Or am I doing something wrong?

    Version is 2.4.1 build with MATCHCOMPILER=yes HAVE_RULES=yes on ubuntu 18.04

    [edit] The problem also disappears when using -j 2 or more.

     

    Last edit: Tobias Mark 2021-06-10
  • Daniel Marjamäki

    Yes that is a bug

     
  • Adam Rosenfield

    Adam Rosenfield - 2021-09-16

    I'm still experiencing this issue in Cppcheck 2.5, which has the fix above. The example that Tobias posted doesn't reproduce the issue any more, but this slightly different example still triggers it.

    Code:

    #include "missing-header.h" // cppcheck-suppress missingInclude
    
    int main(int argc, char **argv)
    {
      return 0;
    }
    

    When run without --cppcheck-build-dir, it succeeds (the warning is correctly suppressed), but when run twice with --cppcheck-build-dir, it produces a false positive:

    # First execution succeeds:
    $ cppcheck --enable=all --cppcheck-build-dir=/tmp/cpp --inline-suppr /tmp/test.c
    Checking /tmp/test.c ...
    
    # Second execution fails:
    $ cppcheck --enable=all --cppcheck-build-dir=/tmp/cpp --inline-suppr /tmp/test.c
    Checking /tmp/test.c ...
    /tmp/test.c:1:0: information: Unmatched suppression: missingInclude [unmatchedSuppression]
    #include "missing-header.h" // cppcheck-suppress missingInclude
    ^
    
     
    • Daniel Marjamäki

      I can reproduce that. I have created https://trac.cppcheck.net/ticket/10489

       
  • Joel Wirz

    Joel Wirz - 2023-05-25

    We'd like to use the build directory as well because we currently suffer from a long build time. But since we use inline suppressions we also experience this problem.

    Will this issue be fixed anytime soon?
    Is there a workaround to still use a build directory and specifying suppressions (e.g. passing a list via xml)?

     
  • Daniel Marjamäki

    ouch.. I am not sure if there is some workaround directly. It feels bad it has been open for so long.

     
    • Joel Wirz

      Joel Wirz - 2023-05-26

      I definitely can understand you. And I imagine that using both features combined is not uncommon.
      So I currently see no other option but to wait using the build directory until the bug is fixed...

       
  • Daniel Marjamäki

    Can you help me to reproduce it? As I understand from comments in #10489 I need to run in windows and I need to use -j2.

    Testing:

    C:\Users\Administrator\source\repos\cppcheck>bin\debug\cppcheck.exe -j2 --cppcheck-build-dir=b --enable=missingInclude --platform=win64 --inline-suppr test\cli\proj-inline-suppress\missing-include.cpp
    Checking test\cli\proj-inline-suppress\missing-include.cpp ...
    
    C:\Users\Administrator\source\repos\cppcheck>bin\debug\cppcheck.exe -j2 --cppcheck-build-dir=b --enable=missingInclude --platform=win64 --inline-suppr test\cli\proj-inline-suppress\missing-include.cpp
    Checking test\cli\proj-inline-suppress\missing-include.cpp ...
    
    C:\Users\Administrator\source\repos\cppcheck>
    

    The file test\cli\proj-inline-suppress\missing-include.cpp:

    C:\Users\Administrator\source\repos\cppcheck>type test\cli\proj-inline-suppress\missing-include.cpp
    #include "missing-include.h" // cppcheck-suppress missingInclude
    x=12;
    
     
    • Daniel Marjamäki

      Without the --inline-suppr I get the expected warning:

      C:\Users\Administrator\source\repos\cppcheck>bin\debug\cppcheck.exe -j2 --cppcheck-build-dir=b --enable=missingInclude --platform=win64 test\cli\proj-inline-suppress\missing-include.cpp
      Checking test\cli\proj-inline-suppress\missing-include.cpp ...
      test\cli\proj-inline-suppress\missing-include.cpp:1:0: information: Include file: "missing-include.h" not found. [missingInclude]
      #include "missing-include.h" // cppcheck-suppress missingInclude
      ^
      
       
  • Joel Wirz

    Joel Wirz - 2023-05-30

    We don't run cppCheck with the -j2 setting. Instead we use the following settings:
    - j12 --enable=all --inline-suppr --cppcheck-build-dir=C:\cppCheck --xml-version=2

    Additionally we specify multiple directories to check and to ignore with the -I respectively -i flag as well as defines (-D).

    I will run our build with the -j2 option and report back if the problem still occurs.

     

    Last edit: Joel Wirz 2023-05-30
  • Joel Wirz

    Joel Wirz - 2023-06-05

    I've tried to reproduce the problem with an unused function since these are the errors which are reported even though we suppressed them. I've tried the following configurations:

    // #1 This commend will ignore the suppressions and therefore error will be reported (falsely)
    "C:\Program Files\Cppcheck\cppcheck.exe" -j2 --enable=all --inline-suppr --xml-version=2 --cppcheck-build-dir=C:\cppCheckBuild %cd%\src\unused-func-1
    
    // #2 This commend will process the suppressions and therefore error won't be reported
    "C:\Program Files\Cppcheck\cppcheck.exe" -j1 --enable=all --inline-suppr --xml-version=2 --cppcheck-build-dir=C:\cppCheckBuild %cd%\src\unused-func-1
    
    // #3 This commend will process the suppressions and therefore error won't be reported
    "C:\Program Files\Cppcheck\cppcheck.exe" -j2 --enable=all --inline-suppr --xml-version=2 %cd%\src\unused-func-1
    

    What I found interesting is that using the -j option automatically disables the unusued function check:

    C:\Users\joel.wirz\Documents\CppCheck\reproductionProject>"C:\Program Files\Cppcheck\cppcheck.exe" -j2 --enable=all --inline-suppr --xml-version=2 C:\Users\joel.wirz\Documents\CppCheck\reproductionProject\src\unused-func-1
    cppcheck: unusedFunction check can't be used with '-j' option. Disabling unusedFunction check.
    

    Now to wrap things up:
    - Using -j2 with build directory ignores the suppression and reports the error. Eventough this check is "disabled" according to the output directory.
    - Using -j1 option with build directory processes the suppression.
    - Using -j2 option without build directory seems to process (or properly disable the unused function check?) the suppressions.

    What I found interesting is the discrepancy between case #1 and case #2. These should behave identically in my opinion.

    I've attached you the batch file and source file. Can you reproduce the issue?

     

    Last edit: Joel Wirz 2023-06-14
  • Daniel Marjamäki

    Sorry for late reply.

    But .. if you use -j2 and don't have a cppcheck build dir then the checker is disabled.

    if you use -j1 the checker is enabled.
    if you use cppcheck build dir the checker is enable.

    if the checker is disabled and a suppression is provided then I assume that unmatchedSuppression is reasonable.

    if the checker is enabled .. then the suppression works right?

     
  • Joel Wirz

    Joel Wirz - 2023-06-14

    If the checker is enabled (-j1 is used) the suppressions works right. This behaves as it should

    If the checker is disabled (-j2 used):
    - If a build directory is provided, it's reporting an error. And this error does not say unmatched
    suppression, it says the function is unused even though it should be suppressed.
    - If no build directory is provided, same behavior as when using -j1

    I would not make the output result dependent on the number of cpu cores used. In all 3 cases, I would expect the checker to accept the suppression and do not report an error. Even tough the checker might be disabled...

     
  • Daniel Marjamäki

    If the checker is disabled (-j2 used):

    That is not 100% correct. -j2 doesn't disable the checker if you have a build dir.

    I would not make the output result dependent on the number of cpu cores used

    The reason is that the checker is not thread safe.

    If you use a build dir or -j1 then there is no need for thread handling in the check.

    If somebody wants to make the checker thread safe I think that would be good. I am not sure but I have the feeling that no CTU checking is threadsafe..

    Different threading mechanisms are used. If I'm not mistaken we currently use:
    * Qt threads
    * Posix processes.
    * Windows threads.
    I believe that makes shared data in the checker not super trivial. I am not sure but I assume that standard C++11 mutexes works both for Qt threads and Windows threads at least.

     

    Last edit: Daniel Marjamäki 2023-06-14
  • Joel Wirz

    Joel Wirz - 2023-06-15

    Ok I see, configuring the build directory enables the check which is normally disabled in our case (since we currently don't use a build directory) and therefore we don't get the errors.

    Maybe a workaround would be to manually disable the unused function check. Is there a way to do that via cli?

     
    • Daniel Marjamäki

      Avoid using --enable=all and --enable=unusedFunction. You can use --enable=style,information,missingInclude to enable everything except unusedFunction.

       

Log in to post a comment.

Want the latest updates on software, tech news, and AI?
Get latest updates about software, tech news, and AI from SourceForge directly in your inbox once a month.