Menu

cppcheck -I parameter (continued)

2016-11-29
2020-12-31
  • Alexander Nikitin

    Things getting worse :(

    While playing around with -I parameter the following weird bug appeared:
    1. OS Windows 7 x86
    2. cppcheck x86 (1.75 and 1.76.1)

    source code :

    #include <stdio.h>
    #include <string>
    
    int main(int , char **) {
        int i = 1 / 0; // <<<<<<<<<<<< division by zero
        return 0;
    }
    

    command line (for 1.75) :
    cppcheck.exe ./src -I"C:\Program Files\Microsoft Visual Studio 10.0\VC\INCLUDE" --quiet --force --inline-suppr --enable=all --verbose --xml-version=2

    output (for 1.75) :
    <?xml version="1.0" encoding="UTF-8"?>
    <results version="2">
    <cppcheck version="1.76.1"/>
    <errors>
    </errors>
    </results>

    command line (for 1.76.1) :
    cppcheck.exe ./src --suppress=purgedConfiguration -I"C:\Program Files\Microsoft Visual Studio 10.0\VC\INCLUDE" --quiet --force --inline-suppr --enable=all --verbose --xml-version=2

    output (for 1.76.1) :
    <?xml version="1.0" encoding="UTF-8"?>
    <results version="2">
    <cppcheck version="1.76.1"/>
    <errors>
    </errors>
    </results>

    But, if we comment the first line of code:
    source code :

    //#include <stdio.h>
    #include <string>
    
    int main(int , char **) {
        int i = 1 / 0; // <<<<<<<<<<<< division by zero
        return 0;
    }
    

    we can finally get valid "zerodiv" error:
    <error id="zerodiv" severity="error" msg="Division by zero." verbose="Division by zero." cwe="369">
    <location file0="src\\main.cxx" file="src\\main.cxx" line="5"/>
    </error>

     
  • Daniel Marjamäki

    I recommend that you don't include the normal standard C/C++ headers. We have the std.cfg that has better information.

    Imagine what will happen if there is macros in those headers.. for instance:

    #define strcpy(dest,src)    __builtin_strcpy(dest,src)
    

    If there is such macro then cppcheck will not detect any bugs when you use strcpy(). And the normal C/C++ headers are full of macros and tweaks to make compilation as efficient as possible.

     
  • Daniel Marjamäki

    If you want to include stdio.h etc then it would be better to include headers that are meant to be used for static analysis. no macro obfuscations etc. we dont distribute such headers but for instance frama-c has it.

     
    • Alexander Nikitin

      Hi Daniel!

      I think that I found the root of this problem. It seems that cppcheck incorrectly processes #error directive.

      #ifndef SOME_UNDEFINED_MACRO
      #error "Ooops"
      #endif //SOME_UNDEFINED_MACRO
      
      //
      int main (int, char **) {
          int i = 1 / 0; <<<<<<<<<<<<<<<<<< division by zero
          return 0;
      }
      

      if we comment #error "Ooops" cppcheck successfully finds zerodiv error

      As for including standard C/C++ headers (or third party library C/C++ headers) in my previous tests...
      Recently I found the following "bug/enhancement" in third party libraries that I use to build my applications:

      in "version 1.0" of third party library there was the following declaration:

      #define NAME_SIZE 128
      void get_group_name ( char name [NAME_SIZE] );
      

      so I wrote the following code:

      int main (int, char **) {
          char name [NAME_SIZE] = {0};
          get_group_name(name);
          return 0;
      }
      

      lately "version 2.0" of third party library appeared and there were the following changes:

      #define NAME_SIZE 128
      #define GROUP_NAME_SIZE 256
      void get_group_name ( char name [GROUP_NAME_SIZE] );
      

      But neither compiler nor cppcheck (I think because of #error directive bug in cppcheck) didn't warn me about these changes (size mismatch in my code) - and it resulted in buffer overflow and my application crashed :)

      So actually I need to add third party libraries in -I parameter to detect errors like this.

       
  • Daniel Marjamäki

    Feel free to include 3rd party library headers. get_group_name is not a standard C/C++ function. So Cppcheck knows nothing about it unless you include the header.

     

    Last edit: Daniel Marjamäki 2016-12-01
  • Daniel Marjamäki

    Yes I agree.. the #error in your example is not handled correctly. I will make sure that is fixed.

    ticket created: http://trac.cppcheck.net/ticket/7842

     

    Last edit: Daniel Marjamäki 2016-12-01
  • Alexander Nikitin

    Hi Daniel!
    I've tested new cppcheck build (1.77) - previous bug is gone, but new one appeared :( :

    #ifndef X
    #error "Ooops X"
    #endif //X
    
    #ifndef Y
    #error "Ooops Y"
    #endif //Y
    
    //
    int main (int, char **) {
        //
        int i = 1 / 0; <<<<<<<<<<<<<<<<<< division by zero
        return 0;
    }
    

    tests were performed with the following parameters:
    cppcheck.exe ./src --suppress=purgedConfiguration --quiet --force --inline-suppr --enable=all --verbose --xml-version=2

     
    • David V. Corbin

      David V. Corbin - 2020-12-31

      Just curious - were X and Y defined at time of analysis of that module? If either was no, then my expectation would be more of "unreachable" code...

      Validating combinatorial's of of preprocessor is a major challenge. I don't think there is a tool that can really do it. For example this file should detect "If X is not defined then the definition (or not) of Y is immaterial to the compilation of this unit - the compilation of anything after the #error will not be be processed.

       
  • Daniel Marjamäki

    I just tried that example and latest cppcheck finds that error:

    $ ./cppcheck 1.c
    Checking 1.c ...
    Checking 1.c: X;Y...
    1.c:12:15: error: Division by zero. [zerodiv]
        int i = 1 / 0; //<<<<<<<<<<<<<<<<<< division by zero
                  ^
    
     

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.