spitz
spitz

Reputation: 31

Using splint for static code analysis on windowms with MPLAB how to avoid system file parse errors

I'm using MPLAB X (3.26) with a PIC32 on windows (XC32 v1.40 compiler). I'm trying to use splint to do static code analysis on someones code as part of a review. I've got most of the compiler defines and search paths sorted, but are a bit stumped when it comes to avoiding the parse errors in the PIC32 std include files.

The command I am using to run splint is

splint ^
-D"__32MX370F512L__" ^
-D"__PIC32_FEATURE_SET__"=370 ^
-D"__LANGUAGE_C__" ^
+I"C:/Program Files (x86)/Microchip/xc32/v1.40/pic32mx/include/" ^
main.c

The output then gives

< Location unknown >: Field name reused:
Code cannot be parsed.  For help on parse errors, see splint -help
parseerrors. (Use -syntax to inhibit warning)
< Location unknown >: Previous use of
< Location unknown >: Previous use of

.... approx 100 times then...

C:\Program Files (x86)\Microchip\xc32\v1.40\pic32mx\include\\stddef.h(4,18):
Datatype ptrdiff_t declared with inconsistent type: long int
A function, variable or constant is redefined with a different type. (Use
-incondefs to inhibit warning)
load file standard.lcd: Specification of ptrdiff_t: arbitrary integral type
C:\Program Files (x86)\Microchip\xc32\v1.40\pic32mx\include\\stddef.h(5,27):
Datatype size_t declared with inconsistent type: unsigned long int
load file standard.lcd: Specification of size_t:
arbitrary unsigned integral type
C:\Program Files (x86)\Microchip\xc32\v1.40\pic32mx\include\\stddef.h(6,13):
Datatype wchar_t declared with inconsistent type: int
load file standard.lcd: Specification of wchar_t: arbitrary integral type
C:\Program Files (x86)\Microchip\xc32\v1.40\pic32mx\include\\stdarg.h(75,36):
No type before declaration name (implicit int type): __builtin_va_list :
int
A variable declaration has no explicit type.  The type is implicitly int.
(Use -imptype to inhibit warning)
C:\Program Files (x86)\Microchip\xc32\v1.40\pic32mx\include\\stdarg.h(75,36):
Parse Error: Suspect missing struct or union keyword: __builtin_va_list :
int. (For help on parse errors, see splint -help parseerrors.)
*** Cannot continue.

The last one causes things to stop. I've tried things like -skip-iso-headers with no luck. It seems it is seeing issues with its standard.lcd file and the xc32 std files

Can anyone tell me

So far only way to solve the header file issue is to define the types, e.g.

-D"__builtin_va_list"=int ^

Upvotes: 3

Views: 1017

Answers (2)

Dainius
Dainius

Reputation: 61

I am working with a different processor, compiler, and static analysis tool (PRQA / Helix QAC), but I think we are facing the same problem regarding the parse issue of the standard header files. It took me some time to figure out what is going on.

For one thing, I can say that your workaround is good enough and apparently you should not worry about it too much. I used a slightly different workaround described here: Pycparser not working on preprocessed code

-D __builtin_va_list = struct __builtin_va_list {}

I guess another way would be to use stub standard headers instead of the real ones. My tool manual claims, for example, that there should be such header files supplied with the tool, although I haven't found/obtained them yet.

Upvotes: 1

EchoLynx
EchoLynx

Reputation: 510

I think your code (or some code that you #include) is using anonymous bitfields or/and structs. Anonymous structs and anonymous unions are provided by a GNU extension for versions of C earlier than C11. Since Splint doesn't know about C11 (I only found mentions of C99 in the manual, and google agrees) and only partial support for the GNU extensions (search for gnu-extensions), it has a hard time parsing them.

I had a similar problem with some code written for a PIC18f46k22, though I was using sdcc instead of XC8.

The issue was with pic18f46k22.h, which had anonymous structs (bitfields, specifically) inside a typedef union.

This code...

typedef union
  {
  struct
    {
    unsigned name0              : 1;
    unsigned name1              : 1;
    unsigned name2              : 1;
    unsigned name3              : 1;
    unsigned name4              : 1;
    unsigned                    : 1;
    unsigned                    : 1;
    unsigned                    : 1;
    };

  struct
    {
    unsigned name               : 6;
    unsigned                    : 2;
    };
  } __NAMEbits_t;

...would produce these errors...

< Location unknown >: Field name reused:
Code cannot be parsed.  For help on parse errors, see splint -help
parseerrors. (Use -syntax to inhibit warning)
< Location unknown >: Previous use of

...but this code wouldn't.

  struct indv
    {
    unsigned name0              : 1;
    unsigned name1              : 1;
    unsigned name2              : 1;
    unsigned name3              : 1;
    unsigned name4              : 1;
    unsigned                    : 1;
    unsigned                    : 1;
    unsigned                    : 1;
    };
  struct all
    {
    unsigned name               : 6;
    unsigned                    : 2;
    };

  typedef union
    {
    struct indv individualbits;
    struct all  allbits;
    } __NAMEbits_t;

Upvotes: 0

Related Questions