Work at SourceForge, help us to make it a better place! We have an immediate need for a Support Technician in our San Francisco or Denver office.

Close

#1398 Bad code for a bitfield in triple operator

closed-fixed
Maarten Brock
5
2013-05-25
2007-11-25
Anonymous
No

SDCC 2.7.0 produces erroneous code for a statement like

*bp++ = sp->b ? 'A' : 'B';

The compiled code will crash when executed. More details in the enclosed file.

Submitted by: j (dot) kangas (at) luukku (dot) com

Discussion

  • Logged In: NO

    System sis not accept the enclosed file, I'll enclose it here:

    /* Demonstrates a problem in SDCC 2.7.0

    This program will crash when run in an 8051. The error is
    on the line marked below. The compiler produces PUSH AR0,
    but the corresponding POP AR0 is misplaced and is not
    executed when s.b is 0. This leaves stack corrupted and
    executing RET in the end of func() crashes the program.

    The assembly for the marked statement:

    ; triple.c:33: *bp++ = sp->b ? 'A' : 'B';
    mov ar1,r0
    inc r0
    push ar0
    mov r0,#_s
    movx a,@r0
    jnb acc.0,00103$
    pop ar0
    mov r2,#0x41
    sjmp 00104$
    00103$:
    mov r2,#0x42
    00104$:
    mov @r1,ar2

    Compiler command line:
    sdcc --xram-size 256 triple.c

    Compiler version:
    SDCC : mcs51/gbz80/z80/avr/ds390/pic16/pic14/TININative/xa51/ds400/hc08 2.7.0 #4818 (May 31 2007) (MINGW32)

    Submitted by:
    j dot kangas at luukku dot com

    */

    typedef struct st
    {
    unsigned char b:1;
    } ST;

    __pdata ST s;
    __idata unsigned char buf[5];

    void func( void )
    {
    __pdata ST *sp;
    __idata unsigned char *bp;

    sp = &s;
    bp = buf;

    *bp++ = sp->b ? 'A' : 'B'; // statement producing bad code
    *bp++ = 'C';
    }

    void main( void )
    {
    s.b = 0;

    func();

    while (1);
    }

     
  • Robert Larice
    Robert Larice
    2008-02-26

    Logged In: YES
    user_id=1840151
    Originator: NO

    for debugging purpose the offending code can be reduced to:

    struct { char b:1; } data * glbl;

    void func(char data *p) {
    *p++ = glbl->b ? 'A' : 'B';
    *p = 'C';
    }

    Robert Larice

     
  • Robert Larice
    Robert Larice
    2008-02-26

    Logged In: YES
    user_id=1840151
    Originator: NO

    Problem Analysis:

    within genPointerGet ()
    sometimes a getFreePtr() is called (and emits a push) to free a register
    then sometimes genUnpackBits()/genIfxJump() is called
    and emits a conditional jump
    and after that freeAsmop() is called and emits a pop

    this results in something like:
    push ..
    ...
    conditional jump to label
    pop

    next-icode
    ...

    label:
    ...

    -------------------------------

    call trace:

    gen51Code()

    processing the icode:
    bug-20-a.c(l13:s7:k8:d0:s0) iTemp5 [k10 lr7:8 so:0]{ ia0 a2p0 re0 rm0 nos0 ru0 dp0}{unsigned-bitfield {0,1}} = @[iTemp4 [k9 lr6:7 so:0]{ ia1 a2p0 re0 rm0 nos0 ru0 dp0}{unsigned-bitfield {0,1} near* }[r2 ]]

    calls:

    genPointerGet () calls
    genNearPointerGet() calls
    getFreePtr()
    emits a "push ..."

    then

    genPointerGet () calls
    genUnpackBits (operand * result, char *rname, int ptype, iCode *ifx) calls
    genIfxJump (iCode * ic, char *jval, operand *left, operand *right, operand *result)
    emits a conditional jump

    then

    genNearPointerGet()

    /* now some housekeeping stuff */
    if (aop) /* we had to allocate for this iCode */
    {
    ...
    freeAsmop (NULL, aop, ic, RESULTONSTACK (ic) ? FALSE : TRUE);

    and freeAsmop() emits a "pop"

    this results in "emit"-age of

    # Breakpoint 13, emitcode (inst=0x81249d9 "push", fmt=0x81249e2 "%s") at gen.c:158
    # Breakpoint 13, emitcode (inst=0x81249d0 "mov", fmt=0x8124a96 "%s,%s") at gen.c:158
    # Breakpoint 13, emitcode (inst=0x81249d0 "mov", fmt=0x8124bb0 "a,@%s") at gen.c:158
    # Breakpoint 13, emitcode (inst=0x81255bd "jb", fmt=0x812532d "%s,%05d$") at gen.c:158
    # Breakpoint 13, emitcode (inst=0x8125289 "ljmp", fmt=0x81252ce "%05d$") at gen.c:158
    # Breakpoint 13, emitcode (inst=0x81249bf "", fmt=0x81249b8 "%05d$:") at gen.c:158
    # Breakpoint 4, freeAsmop (op=0x0, aaop=0x81e6600, ic=0x81dac10, pop=1) at gen.c:1076
    # Breakpoint 13, emitcode (inst=0x81249de "pop", fmt=0x8124b1a "ar0") at gen.c:158

    --------------------------------

    Robert Larice

     
  • Maarten Brock
    Maarten Brock
    2008-02-27

    • assigned_to: nobody --> maartenbrock
     
  • Maarten Brock
    Maarten Brock
    2008-02-27

    • milestone: --> fixed
    • status: open --> closed-fixed
     
  • Maarten Brock
    Maarten Brock
    2008-02-27

    Logged In: YES
    user_id=888171
    Originator: NO

    Fixed in SDCC 2.7.5 #5054.
    Thanks to Robert Larice for the extensive pre-work.