EtchedPixels / Fuzix-Compiler-Kit

Fuzix C Compiler Project
Other
49 stars 13 forks source link

6800 bug: pass a single argument to a varargs function, the call will fail because the stack is not adjusted. #139

Closed zu2 closed 3 weeks ago

zu2 commented 3 weeks ago

The problem occurs in wtest/input071.c

$ cat test/wtests/input071.c
void cprintf(char *fmt, ...);

int main() {
  int x;
  x = 0;
  while (x < 100) {
    if (x == 5) { x = x + 2; continue; }
    cprintf("%d\n", x);
    if (x == 14) { break; }
    x = x + 1;
  }
  cprintf("Done\n");
  return (0);
}

cprintf is called in two places. The stack is adjusted correctly when there are two arguments, but not when there is one.

2 argments.

;make local ptr off 0, rlim 254 noff 0
        pshb
        psha
        jsr _cprintf+0
        ins
        ins
        ins
        ins

1 arg.

        ldb #<T8+0
        lda #>T8+0
        pshb
        psha
        jsr _cprintf+0
;
        clra
        clrb

The problem seems to be due to gen_direct in be-codegen-6800.c, but I can't figure out how to fix it.

    case T_CLEANUP:
        sp -= r->value;
        printf("; T_CLEANUP: r->value=%d, n->val2=%d, sp=%u\n",r->value, n->val2,sp);
        if (cpu_has_d || n->val2) /* Varargs */
            adjust_s(r->value, (func_flags & F_VOIDRET) ? 0 : 1);
        return 1; 

When there is one argument, n->val2=0 so the stack is not adjusted.

2 args. ; T_CLEANUP: r->value=4, n->val2=1, sp=0 1 arg. ; T_CLEANUP: r->value=2, n->val2=0, sp=0

EtchedPixels commented 3 weeks ago

Bug in the compiler front end