This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

Device constants in MSP430xxxxx.h signed, SFRs defined as unsigned: Static analysis complaining like mad

I'm running Parasoft C/C++ check on my code and getting a lot of signed/unsigned mismatch complaints.  The mismatch is that the SFRs are unsigned, but the constants don't all have the U suffix to make them unsigned.

#define SFR_8BIT(address)   extern volatile unsigned char address
#define SFR_16BIT(address)  extern volatile unsigned int address
//#define SFR_20BIT(address)  extern volatile unsigned int address
typedef void (* __SFR_FARPTR)();
#define SFR_20BIT(address) extern __SFR_FARPTR address
#define SFR_32BIT(address)  extern volatile unsigned long address

// snip...

#define DMADSTINCR1            (0x0800)       /* DMA destination increment bit 1 */
#define DMADT0                 (0x1000)       /* DMA transfer mode bit 0 */
#define DMADT1                 (0x2000)       /* DMA transfer mode bit 1 */
#define DMADT2                 (0x4000)       /* DMA transfer mode bit 2 */

#define DMASWDW                (0*0x0040u)    /* DMA transfer: source word to destination word */
#define DMASBDW                (1*0x0040u)    /* DMA transfer: source byte to destination word */
#define DMASWDB                (2*0x0040u)    /* DMA transfer: source word to destination byte */
#define DMASBDB                (3*0x0040u)    /* DMA transfer: source byte to destination byte */

It seems only the defines that involve a multiplier are unsigned, (as to avoid multiplier overflow into the signed msb?).

As a quick fix I can add edit and add the unsigned suffix myself, but will need to redo it for every compiler update.  Would TI consider fixing this?

  • The C standard says that a hexadecimal constant which can fit into both int and unsigned int has type int.

    C99 §6.3.1.3 says that for such SFRs, the conversion from int to unsigned int does not change the value. So if your checker complains that the conversion might change the value, it is wrong.

    (Not even MISRA requires a "u" in this situation. What exactly is the checker complaining about?)

  • I agree with your statement that regardless of the "U", the hex value is assigned as the coder expects.  The rule is about clarity.  About the only way one could run into trouble is a right shift or a divide, but that's beside the point.  I don't want to digress on the value behind the rule (I also find it annoying and would rather not try to convince anyone of their value in order to address an issue I'm having).

    So yes, it's the MISRA2004-10_1_a-3 rule.  Here's a definition I found:

    Rule 10.1 (required): The value of an expression of integer type shall not be implicitly
    converted to a different underlying type if:

    • (a) it is not a conversion to a wider integer type of the same signedness, or
    • (b) the expression is complex, or
    • (c) the expression is not constant and is a function argument, or
    • (d) the expression is not constant and is a return expression

    (a) is the issue, and the conversion is indeed not to the same signedness.   MISRA 2004 does indeed require a "U"  (except for hex values >=  0x8000, which you correctly point out should already be taken as unsigned, for a 16 bit int).

    Again, we don't need to argue.  I can bring this up on the MISRA forum and they will let me know. (I'm still waiting for my account approval before I can post).

    In the short term, here's a Q/A about this very issue. 
    http://stackoverflow.com/questions/31847640/does-size-t-foo-0-need-a-cast

    It seems MISRA 2012 might have rectified this silly issue.  Nevertheless, I'm talking about MISRA2004 rules that many of us are stuck with (I know, the old standard from 12 years ago).

    Regards.

**Attention** This is a public forum