From fb22e0c12dbbf8907253a9e05a4433542d3c82d1 Mon Sep 17 00:00:00 2001 From: Michael Matz Date: Tue, 10 Dec 2019 17:49:04 +0100 Subject: [PATCH] Fix type/r/r2 confusion differently on i386 111_conversion.c breaks when save_reg_upstack isn't careful about r2 and type mismatches. The bcheck patches fixed this by enlarging the stack slot beyond the natural type, this variant simply avoids saving the second register is the type indicates that it isn't needed. Adds also a comment how this should ideally work, namely that type and r/r2 entries in the vstack are consistent. In the 111_conversion testcase it's specifically gen_cast via gen_cvt_ftoi that breaks this, but there more general code broken as well, so that would deserve a careful fixup based on some additional asserts. --- tccgen.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/tccgen.c b/tccgen.c index b41dd82c..73a44948 100644 --- a/tccgen.c +++ b/tccgen.c @@ -1193,10 +1193,6 @@ ST_FUNC void save_reg_upstack(int r, int n) type = &int_type; #endif size = type_size(type, &align); - if ((p->r2 & VT_VALMASK) < VT_CONST) { - size *= 2; - align *= 2; - } l=get_temp_local_var(size,align); sv.type.t = type->t; sv.r = VT_LOCAL | VT_LVAL; @@ -1208,8 +1204,11 @@ ST_FUNC void save_reg_upstack(int r, int n) o(0xd8dd); /* fstp %st(0) */ } #endif - /* special long long case */ - if ((p->r2 & VT_VALMASK) < VT_CONST) { + /* special long long case. Ideally r2 would always + be VT_CONST is the type is smaller than a double-word + type. Not all routines (e.g. gen_cast with _ftoi) are + careful to clear r2, though. */ + if ((p->r2 & VT_VALMASK) < VT_CONST && size > PTR_SIZE) { sv.c.i += PTR_SIZE; store(p->r2, &sv); } -- 2.11.4.GIT