#389 Fix for OP_ASSIGN bug

closed-fixed
5
2013-05-25
2002-09-13
Wim Lewis
No

SDCC generates incorrect code for some statements of
the form foo += bar. The current implementation of
those operators transforms the statement to foo = foo +
bar, and then strips out any increment/decrement
operators found in the second instance of foo. However
this does not work in more complex cases, e.g.
getitem()->flags |= 42;
(the getitem() call will be invoked twice).

This patch makes SDCC create temporary variables if
needed in order to store side-effect-ful values. The
above statement now gets transformed to
tmp = getitem(); tmp->flags = tmp->flags | 42;

The generated code could use some more attention from
the peephole optimizer, but at least it is correct.

Discussion

  • Wim Lewis

    Wim Lewis - 2002-09-13

    the patch

     
  • Maarten Brock

    Maarten Brock - 2005-12-13
    • assigned_to: nobody --> maartenbrock
     
  • Frieder Ferlemann

    Logged In: YES
    user_id=589052

    The bug still persists. I'm appending a file which
    reproduces the bug.

    Changed from a patch submission to a bug report.

    //--------8<-----------------------------------
    typedef struct
    {
    char a;
    char n;
    } item_type;

    item_type t;

    char more_items_in_list(void)
    {
    return 1;
    }

    near item_type* get_next_item(void)
    {
    /* have a side effect */
    t.n++;

    /* keep things easy, not implementing a list.
    Using a true list would break things
    even more pointedly:
    a) reading beyond end of the list and
    b) intermixing list members */
    return &t;
    }

    void main(void)
    {
    t.a = 0;
    t.n = 0;

    if( more_items_in_list() )
    {
    /* get_item() is called twice */
    get_next_item()->a |= 42;
    }

    /*
    * Now t.n is 2 instead of 1.
    * Also the or'ed value of 42 and the 2nd list item
    * would be written to the 1st list item
    */

    }

    //-------->8-----------------------------------

    // compiles to:

    //--------8<-----------------------------------
    #if 0

    _main:
    ;bug-608752.c:32: t.a = 0;
    mov _t,#0x00
    ;bug-608752.c:33: t.n = 0;
    mov (_t + 0x0001),#0x00
    ;bug-608752.c:35: if( more_items_in_list() )
    lcall _more_items_in_list
    mov a,dpl
    jz 00103$
    ;bug-608752.c:38: get_next_item()->a |= 42;
    lcall _get_next_item ; ------------#1
    mov r0,dpl
    push ar0
    lcall _get_next_item ; ------------#2
    mov r1,dpl
    pop ar0
    mov ar2,@r1 ; read from @r1
    mov a,#0x2A
    orl a,r2
    mov @r0,acc ; written to @r0
    00103$:
    ret

    #endif

     
  • Frieder Ferlemann

    shows the bug

     
  • Maarten Brock

    Maarten Brock - 2006-06-10

    Logged In: YES
    user_id=888171

    And finally after almost 4 years this bug is fixed in SDCC
    2.5.6 #4212.

     
  • Maarten Brock

    Maarten Brock - 2006-06-10
    • labels: --> C-Front End
    • milestone: --> fixed
    • status: open --> closed-fixed
     

Log in to post a comment.

Get latest updates about Open Source Projects, Conferences and News.

Sign up for the SourceForge newsletter:

JavaScript is required for this form.





No, thanks