cc65: cc65: Returning structs by value generates invalid code
The following code:
struct x { int a; char b; };
struct x f(void)
{
struct x x = { 1, 2 };
return x; /* Returned in eax with high byte = junk */
}
int main(void)
{
struct x x;
x = f(); /* Overwrites x with 4 bytes */
return 0;
}
Looks like this after translation with â-Oirs -Tâ:
; ---------------------------------------------------------------
; struct x __near__ f (void)
; ---------------------------------------------------------------
.segment "CODE"
.proc _f: near
.segment "CODE"
;
; struct x x = { 1, 2 };
;
jsr decsp3
ldy #$02
L0002: lda M0001,y
sta (sp),y
dey
bpl L0002
;
; return x; /* Returned in eax with high byte = junk */
;
jsr ldeax0sp
;
; }
;
jmp incsp3
.segment "RODATA"
M0001:
.word $0001
.byte $02
.endproc
; ---------------------------------------------------------------
; int __near__ main (void)
; ---------------------------------------------------------------
.segment "CODE"
.proc _main: near
.segment "CODE"
;
; x = f(); /* Overwrites x with 4 bytes */
;
jsr decsp3
jsr _f
jsr steax0sp
;
; return 0;
;
ldx #$00
txa
;
; }
;
jmp incsp3
.endproc
As you can see, the struct is 3 bytes in size but is handled by eax which causes one additional byte to be read/written. The write might cause erratic behavior or program crashes.
About this issue
- Original URL
- State: closed
- Created a year ago
- Comments: 15 (12 by maintainers)
Commits related to this issue
- Disallow pass/return of 3-byte struct (#2022), document capability added in #1102. — committed to bbbradsmith/cc65 by bbbradsmith a year ago
- Disallow pass/return of 3-byte struct (#2022), document capability added in #1102. — committed to acqn/cc65 by bbbradsmith a year ago
I created PR #2072 which simply disables the problematic 3-byte case. I also documented the feature, and added a simple test case for it.