Menu

#3523 void function changes stack usage in another function

closed-fixed
None
other
5
2023-01-21
2022-11-29
Under4Mhz
No

The following code produces the incorrect output of 3,4 instead of 1,2:

/// GPL 2.0 or later
#include <stdio.h>
#include <stdint.h>
#include <stdbool.h>

typedef struct {

    int x;
    int y;

} maths_point;

void PlayerGridNextGet( maths_point *next ) {

    next->x = 1;
    next->y = 2;
}

void PlayerGridGet( maths_point *current ) {

    current->x = 3;
    current->y = 4;
}

int MapGet( int x, int y ) { return 0; }

int StateDoorHiddenOpenSet( int x, int y ) { printf( "%d,%d", x, y ); }

bool ObjectIsHiddenDoor( char ch ) { return true; }

void SoundDoorOpen() {}

void Action() {

    maths_point next;
    PlayerGridNextGet( &next );
    char ch = MapGet( next.x, next.y );

    maths_point current;
    PlayerGridGet( &current );
    char chCurrent = MapGet( current.x, current.y );

    // Hidden door open
    StateDoorHiddenOpenSet( next.x, next.y );
}

int main() {

    printf("Start\n");
    Action();
    printf("\nEnd\n");

    return 0;
}

#ifdef __SDCC
__sfr __at 0xff sif;
int putchar( int c ) {

    sif = 'p';
    sif = c;

    return c;
}
#endif

// sdcc -mz80 --fverbose-asm ./get2.c  -o get2.ihx && ucsim_z80 -I if=outputs[0xff] get2.ihx
$ sdcc -mz80 --fverbose-asm ./get2.c  -o get2.ihx && ucsim_z80 -I if=outputs[0xff] get2.ihx
./get2.c:25: warning 85: in function MapGet unreferenced function argument : 'x'
./get2.c:25: warning 85: in function MapGet unreferenced function argument : 'y'
./get2.c:27: warning 59: function 'StateDoorHiddenOpenSet' must return value
./get2.c:29: warning 85: in function ObjectIsHiddenDoor unreferenced function argument : 'ch'
./get2.c:31: warning 283: function declarator with no prototype
./get2.c:33: warning 283: function declarator with no prototype
./get2.c:47: warning 283: function declarator with no prototype
uCsim 0.7.6, Copyright (C) 1997 Daniel Drotos.
0> Loading from get2.ihx
3221 words read from get2.ihx
r
Simulation started, PC=0x000000
Start
3,4
End
gcc ./get2.c && ./a.out 
Start
1,2
End

Removing the empty function SoundDoorOpen seems to make the difference. In my actual code, SoundDoorOpen contains code and is compiled in a separate source file. Being called makes no difference.

With SoundDoorOpen, sdcc seems to decide to use 4 bytes for the stack instead of 8:

$ diff get2-*.asm
13d12
<   .globl _SoundDoorOpen
189,201d187
< ;./get2.c:35: void SoundDoorOpen() {}
< ; genLabel
< ; genFunction
< ; ---------------------------------
< ; Function SoundDoorOpen
< ; ---------------------------------
< ; Register assignment is optimal.
< ; Stack space usage: 0 bytes.
< _SoundDoorOpen::
< ; genLabel
< ; common peephole 158 removed unused label 00101$.
< ; genEndFunction
<   ret
209c195
< ; Stack space usage: 4 bytes.
---
> ; Stack space usage: 8 bytes.
214,216c200,203
< ; adjustStack by -4
<   push    af
<   push    af
---
> ; adjustStack by -8
>   ld  hl, #-8
>   add hl, sp
>   ld  sp, hl
251c238
<   ld  hl, #0
---
>   ld  hl, #4
260,262c247,248
<   pop hl
<   pop de
<   push    de
---
>   ld  e, -2 (ix)
>   ld  d, -1 (ix)
266,267c252,257
< ; common peephole 50b eleminated dead push/pop pair.
<   push    hl
---
>   ld  l, -4 (ix)
> ; spillPairReg hl
> ; spillPairReg hl
>   ld  h, -3 (ix)
> ; spillPairReg hl
> ; spillPairReg hl
sdcc -v
SDCC : mcs51/z80/z180/r2k/r2ka/r3ka/sm83/tlcs90/ez80_z80/z80n/ds390/pic16/pic14/TININative/ds400/hc08/s08/stm8/pdk13/pdk14/pdk15/mos6502 4.2.9 #13755 (Linux)
2 Attachments

Related

Wiki: NGI0-Entrust-SDCC

Discussion

  • Philipp Klaus Krause

    I sometimes can reproduce this (on Debian GNU/Linux on amd64 using sdcc from current trunk). But not always; looks like it even makes a difference from which directory I call SDCC. But valgrind doesn't show reads of uninitialized memory. Maybe this is affected by [bugs:3505]?

    P.S.: The difference is already visible in the conflict graph for stack allocation, as can be seen using --dump-graphs. From the code supplied by Under4Mhz I've created a regression test case for this (attached).

     

    Last edit: Philipp Klaus Krause 2023-01-21
  • Philipp Klaus Krause

    • assigned_to: Philipp Klaus Krause
     
  • Philipp Klaus Krause

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

    Fixed in [r13807].

     

    Related

    Commit: [r13807]


Log in to post a comment.

MongoDB Logo MongoDB