This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

Integer promotion bug

I think there is a bug in the C51 and CX51 compilers
regarding integer promotion. I have not deselected
integer promotion and thus expect proper C semantics
without adding casts. The bug seems to be appearing
in different cases but working in others, like with
the "?" operator versus the if-statement.

Se code below with comments on actual and expected results.

typedef unsigned char uint8_t;
typedef   signed char int8_t;
typedef   signed int  int16_t;

volatile int x;

void foo(void)
{
    int8_t b1 = -128, b2 = 0;

    x = -b1; // OK: x = 128
    x = b1 > 0 ?
          0 :
          -b1;   // ERR: x = -128

    if (b1 > 0)
       x = 0;
    else
       x = -b1;     // OK: x = +128

    x = -(b1-b2);   // OK: x = 128
    x = (b1-b2) > 0 ?
          0 :
          -(b1-b2);    //ERR: x = -128

    if ((b1-b2) > 0)
       x = 0;
    else
       x = -(b1-b2);     // OK: x = +128
}

void fie(void)
{
    uint8_t b1 = 10, b2 = 20;

    x = (b1-b2) > 0 ?
          0 : // ERR: This branch is executed -> x = 0
          -(b1-b2);

    if ((b1-b2) > 0)
       x = 0;  // ERR: This branch is executed -> x = 0
    else
       x = -(b1-b2);
}

#define ABS(a) ((a) > 0 ? (a) : (-(a)))
#define ABS_FIX(a) ((int16_t)(a) > 0 ? (a) : ((int16_t)-(a)))

void fum(void)
{
   int8_t b1 = -128;
   uint8_t b2 = 10, b3 = 20;

   x = ABS(b1); // ERR: x = -128
   x = ABS_FIX(b1); // OK: x = +128

   x = ABS(b2-b3); // ERR: x = 246
   x = ABS_FIX(b2-b3); // OK: x = 10
}

int main(void)
{
   foo();
   fie();
   fum();
   return 0;
}