From 310e3b428cfd181b51723276e6563b90d670da06 Mon Sep 17 00:00:00 2001 From: Kyryl Melekhin Date: Tue, 8 Sep 2020 22:12:01 +0000 Subject: [PATCH] (bug caused by tcc intristics) reproduce bug: $ ./configure --cc=gcc $ make $ make install (OK) run a test: extern int printf(const char *str, ...); int main() { int t2 = (int)(-1.847759065f * 4096); printf("%d\n", t2); } $ tcc test.c $ ./a.out $ -7568 (OK) (self compiled now) $ ./configure --cc=tcc $ make $ make install (OK) $ tcc test.c $ ./a.out $ 7568 (WRONG!!!) why: gcc does not have intristics for uint to long double conversion therefore it does cast implicitly, so the sign bit is preserved, but this does not happen when __fixunsxfdi is called because tcc was bootstrapped. solution: force cast to int64 and preserve the sign bit. side effects: not found. --- tccgen.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tccgen.c b/tccgen.c index dd6a497a..305a082b 100644 --- a/tccgen.c +++ b/tccgen.c @@ -3478,7 +3478,7 @@ again: vtop->c.i = (vtop->c.ld != 0); } else { if(sf) - vtop->c.i = vtop->c.ld; + vtop->c.i = (int64_t)vtop->c.ld; else if (sbt_bt == VT_LLONG || (PTR_SIZE == 8 && sbt == VT_PTR)) ; else if (sbt & VT_UNSIGNED) -- 2.11.4.GIT