Menu

#2539 expression with bool result assigned to bitfield generates wrong code

closed-fixed
None
Front-end
7
2017-04-10
2016-08-15
No

Code generated in following example only tests for bit #0

struct sBITS {
   unsigned  b0 : 1;
   unsigned  b1 : 1;
   unsigned  b2 : 1;
   unsigned  b3 : 1;
   unsigned  b4 : 1;
   unsigned  b5 : 1;
   unsigned  b6 : 1;
   unsigned  b7 : 1;
};
struct sBITS vb;
__bit  not_0;

void SetIf(uint8_t x) {
   vb.b3 = (x != 0); // only bit 0 of 'x' testet
   not_0 = (x != 0);  // works
}   

void main() {
   SetIf(13);
}

Resulting Code (from rst-file)

_SetIf:
    mov r7,dpl
;   sd1.c:17: vb.b3 = (x != 0); // only bit 0 of 'x' testet
    mov r0,#_vb
    mov a,r7
    rrc a           ; <-- BUG: only bit 0 tested
    mov a,@r0
    mov acc.3,c
    mov @r0,a
;   sd1.c:18: not_0 = (x != 0);  // works
    mov a,r7
    add a,#0xff
    mov _not_0,c
    ret

Compiler Version:
SDCC : mcs51/z80/z180/r2k/r3ka/gbz80/tlcs90/ds390/pic16/pic14/TININative/ds400/hc08/s08/stm8 3.6.0 #9615 (MINGW32)

command to compile:
sdcc.exe -mmcs51 --std-sdcc99 sample.c

  • Heinz

Discussion

  • Philipp Klaus Krause

    I can reproduce the issue in sdcc 3.6.1 #9667. And it really is mcs51-specific: The code for stm8 and z80 looks okay.

    Philipp

     
  • Ben Shi

    Ben Shi - 2016-08-19

    I am afraid this is a bug will affect all ports.

    The following test case fails.

    /* bug-2539.c
      */
    
    #include <testfwk.h>
    #include <stdlib.h>
    
    struct sBITS {
       unsigned  b0 : 1;
       unsigned  b1 : 1;
       unsigned  b2 : 1;
       unsigned  b3 : 1;
       unsigned  b4 : 1;
       unsigned  b5 : 1;
       unsigned  b6 : 1;
       unsigned  b7 : 1;
    };
    struct sBITS vb;
    
    void SetIf(char x) {
       vb.b3 = (x != 0); // only bit 0 of 'x' testet
    }
    
    void
    testBug(void)
    {
            vb.b3 = 0;
            SetIf(0x60);
            ASSERT(vb.b3 == 1);
    
            vb.b3 = 0;
    
           SetIf(0x02);
            ASSERT(vb.b3 == 1);
    }
    

    Here is the wrong AST

    Ben@Ben-PC /cygdrive/d/sdcc/qwe
    $ sdcc a.c -c --dump-ast
    FUNCTION (_SetIf=0x60016a140) type (void fixed) args (unsigned-char fixed)
    tree (0x60016a0a0) not decorated
    (null):0:{ L1 B0
    (null):0:  DECLARE SYMBOL (L1 B1 x=0x6001695a0) type (unsigned-char fixed)
    a.c:14:  ASSIGN(=) (0x600169460) type (unsigned-bitfield {3,1} data)
    a.c:14:    PTR_ACCESS (0x600168d00) type (unsigned-bitfield {3,1} data)
    a.c:14:      ADDRESS_OF (0x600168c60) type (struct sBITS near* fixed)
    a.c:14:        SYMBOL (L0 B0 vb=0x600168580 @ 0x600166f30) type (struct sBITS fixed)
    a.c:14:      SYMBOL (L1 B2 b3=0x600168bc0 @ 0x600168870)
    a.c:14:    SYMBOL (L1 B1 x=0x6001690f0 @ 0x600167990) type (unsigned-char fixed)
    (null):0:}
    
    Ben@Ben-PC /cygdrive/d/sdcc/qwe
    $ cat a.c
    struct sBITS {
       unsigned  b0 : 1;
       unsigned  b1 : 1;
       unsigned  b2 : 1;
       unsigned  b3 : 1;
       unsigned  b4 : 1;
       unsigned  b5 : 1;
       unsigned  b6 : 1;
       unsigned  b7 : 1;
    };
    struct sBITS vb;
    
    void SetIf(char x) {
       vb.b3 = (x != 0); // only bit 0 of 'x' testet
    }
    
     
  • Ben Shi

    Ben Shi - 2016-08-24
    • Category: MCS51 --> Front-end
     
  • Philipp Klaus Krause

    • Priority: 5 --> 7
     
  • Philipp Klaus Krause

    • status: open --> closed-fixed
    • assigned_to: Philipp Klaus Krause
     
  • Philipp Klaus Krause

    Seems this got fixed with the double negation stuff a while ago. To be sure it doesn't come back I added a test in rev. #9873.

    Philipp

     

Log in to post a comment.

MongoDB Logo MongoDB