From 95609d520e31f3f2262764b14b8016ca940af01d Mon Sep 17 00:00:00 2001 From: cinap_lenrek Date: Sun, 30 Oct 2016 23:30:13 +0100 Subject: [PATCH] 8c: fix double compiling FNX complex lvalue in cgen64() sugen() calls cgen64() speculatively so that when cgen64() returns zero, it will fall back and compile 64-bit copy. the bug was that cgen64() compiled the left hand side and then recursively called cgen64() again, which didnt handle the memory copy so it returned zero and sugen() would compile the left hand side again resulting in two function calls being emited. some code that reproduced the issue: #include #include typedef struct { char x[10]; vlong a; } X; X a; X *f(void) { return &a; } void main(int argc, char *argv[]) { f()->a = a.a; } producing: TEXT f+0(SB),0,$0 MOVL $a+0(SB),AX RET , RET , TEXT main+0(SB),0,$0 CALL ,f+0(SB) CALL ,f+0(SB) <- bug MOVL AX,CX LEAL a+12(SB),DX MOVL (DX),AX MOVL AX,12(CX) MOVL 4(DX),AX MOVL AX,16(CX) RET , GLOBL a+0(SB),$20 END , --- sys/src/cmd/8c/cgen64.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sys/src/cmd/8c/cgen64.c b/sys/src/cmd/8c/cgen64.c index 26afadaf0..04c1226e0 100644 --- a/sys/src/cmd/8c/cgen64.c +++ b/sys/src/cmd/8c/cgen64.c @@ -1577,9 +1577,9 @@ cgen64(Node *n, Node *nn) if(nn != Z && nn->complex >= FNX){ reglcgen(&nod1, nn, Z); - m = cgen64(n, &nod1); + cgen(n, &nod1); regfree(&nod1); - return m; + return 1; } switch(n->op) { -- 2.44.0