Menu

Missing nameTokenId and scopeId when running misra.py

noisymime
2019-01-22
2019-06-26
  • noisymime

    noisymime - 2019-01-22

    I've been using the Misra validator for a while now, but had frozen my project against v1.79 in order to have a consistant target. With the supression feature now in place though, I'm now looking at moving up to the latest release (1.86), but ran into a bunch of errors when running the misra.py script. Long story short, a number of elements were reaching Variable.setId() in cppcheckdata.py with values of 0x0, which caused the script to crash out. Specifically these were the nameTokenId and scopeId variables, though only a handful (out of thousands) of them come through with the 0x0 value.

    I added the following 2 if statement checks into that function in cppcheckdata.py (https://github.com/danmar/cppcheck/blob/1.86/addons/cppcheckdata.py#L421):

    def setId(self, IdMap):
            if(self.nameTokenId != "0x0"):
                self.nameToken = IdMap[self.nameTokenId]
            self.typeStartToken = IdMap[self.typeStartTokenId]
            self.typeEndToken = IdMap[self.typeEndTokenId]
            if(self.scopeId != "0x0"):
                self.scope = IdMap[self.scopeId]
    

    And this seems to work, at least everything runs without crashing and I get the results I'm after. But I'm wondering if there's something I'm doing wrong to cause this in the first place?

    The commands I'm running are:

    cppcheck --dump --inline-suppr --suppress=syntaxError:src/PID_v1/PID_v1.h --suppressions-list=../misra/suppressions.txt --include=./*.h -DCORE_AVR=1 -D__AVR_ATmega2560__ ./*.c
    

    To get the dump, followed by:

    python cppcheck/addons/misra.py --rule-texts=misra/misra_2012_text.txt *.dump
    

    Is there anything I'm missing that I should be checking or does this look like a bug?

     

    Last edit: noisymime 2019-01-22
  • noisymime

    noisymime - 2019-01-22

    Not sure if this helps at all, but it looks like the elements that it's failing on are all function arguments. If I get the script to print out the ID when it hits one with a 0x0 scopeId, they're all function arguments that show in the dump file like:

    <var id="0x7fcbb48e1890" nameToken="0x0" typeStartToken="0x7fcbb2f0c5a0" typeEndToken="0x7fcbb2f0c5a0" access="Argument" scope="0x0" constness="0" isArgument="true" isArray="false" isClass="false" isConst="false" isExtern="false" isLocal="false" isPointer="false" isReference="false" isStatic="false"/>
    

    These functions appear to be declared correctly. The one matching the above var is declared:

    void receiveCalibration(byte);
    
     
  • noisymime

    noisymime - 2019-01-22

    Here's a little minimum test from one or the files I'm using. It produces a bunch of scopeId = 0x0 results causing the script to crash out.

    Not sure if related, but it also produces a bunch of false-positives on misra 5.4 in globals.h. The only reason I wonder if it's related is because the false-positive is a result of the scope of the macro definitions not being taken into account (ie the macro is declared in multiple places, but all within a series of exclusive #if #elif statements). This same test passes all checks on 1.79.

     
  • noisymime

    noisymime - 2019-06-25

    It took me a while to track this down, but I finally figured out why nameTokenId and scopeId were occassionally having their value come through as "0x0".

    It turns out that if you're running cppcheck over a file that #includes a header file, and that header file in turn has an #include to another header file, then arguements of any function defined in that final header file will come through as having nameTokenId and scopeId set to 0x0.

    Eg:
    someFile.c
    global.h
    someOtherFile.h

    someFile.c has:
    #include "global.h

    And global.h has:
    #inclde "someOtherFile.h"

    And finally someOtherFile.h has a function prototype of:
    uint16_t someFunction(int16_t variable1, int16_t variable2);

    When you run cppcheck with --dump on someFile.c, you will get entries for variable1 and variable2 that have nameId and scopeId equal to "0x0". This in turn will cause cppcheckdata.py to fail on line 439 with a KeyError

    I know it's not common to have further #includes in a header file, but in my case it is required in order to get a struct definition. It seems like a bug either in the cppcheck that results in the 0x0 values or in cppcheckdata.py that doesn't check for this, but I'm not sure what the best way to raise this is.
    Per my original post, adding a check for "0x0" in cppcheckdata.py solves the problem, but it seems like these should be getting proper values assigned in the first place?

     

    Last edit: noisymime 2019-06-25
  • versat

    versat - 2019-06-26

    Thanks for digging into this.
    I have tried to reproduce it with the latest development code and also with Cppcheck 1.87.
    It looks like i do not get exactly the same results.
    I attach a zip with the source code and dump file that i get when running "cppcheck --dump two_level_include.c".
    Maybe you can compare the dump file with what you get.
    For the var entry, scope really is 0, but i am not sure if that is a problem. And it does not change if the second include file is directly included into the .c file. So that could be intended that way for a function declaration.

    Have you tried Cppcheck 1.87? You mentioned version 1.86 in the first post, maybe something has been fixed in 1.87.

     

    Last edit: versat 2019-06-26

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.