Mercurial > hg > tinycc
changeset 432:01fb5d2a496e
Fix nonconstant double->bool conversion (grischka-2005-09-25 bugfix 6.2).
This patch was originally posted in grischka's 2005-09-25 email as a
"required fix" 6 (subfix 6.2) to compile gcc. It was tweaked by
David A. Wheeler to remove a code duplication, make the indenting
correct, and merge the test case into the standard tcc test suite.
author | Rob Landley <rob@landley.net> |
---|---|
date | Tue, 01 May 2007 17:18:57 -0400 |
parents | 8fa1af332910 |
children | 04d9a1c05f94 |
files | tcc.c tests/tcctest.c |
diffstat | 2 files changed, 43 insertions(+), 38 deletions(-) [+] |
line wrap: on
line diff
--- a/tcc.c Wed Apr 18 14:52:22 2007 -0400 +++ b/tcc.c Tue May 01 17:18:57 2007 -0400 @@ -5053,46 +5053,47 @@ } } else if (sf) { /* convert fp to int */ - /* we handle char/short/etc... with generic code */ - if (dbt != (VT_INT | VT_UNSIGNED) && - dbt != (VT_LLONG | VT_UNSIGNED) && - dbt != VT_BOOL && - dbt != VT_LLONG) - dbt = VT_INT; - if (c) { - switch(dbt) { - case VT_LLONG | VT_UNSIGNED: - case VT_LLONG: - /* XXX: add const cases for long long */ - goto do_ftoi; - case VT_INT | VT_UNSIGNED: - switch(sbt) { - case VT_FLOAT: vtop->c.ui = (unsigned int)vtop->c.d; break; - case VT_DOUBLE: vtop->c.ui = (unsigned int)vtop->c.d; break; - case VT_LDOUBLE: vtop->c.ui = (unsigned int)vtop->c.d; break; + if (dbt == VT_BOOL) { + vpushi(0); + gen_op(TOK_NE); + } else { + /* we handle char/short/etc... with generic code */ + if (dbt != (VT_INT | VT_UNSIGNED) && + dbt != (VT_LLONG | VT_UNSIGNED) && + dbt != VT_BOOL && + dbt != VT_LLONG) + dbt = VT_INT; + if (c) { + switch(dbt) { + case VT_LLONG | VT_UNSIGNED: + case VT_LLONG: + /* XXX: add const cases for long long */ + goto do_ftoi; + case VT_INT | VT_UNSIGNED: + switch(sbt) { + case VT_FLOAT: vtop->c.ui = (unsigned int)vtop->c.d; break; + case VT_DOUBLE: vtop->c.ui = (unsigned int)vtop->c.d; break; + case VT_LDOUBLE: vtop->c.ui = (unsigned int)vtop->c.d; break; + } + break; + default: + /* int case */ + switch(sbt) { + case VT_FLOAT: vtop->c.i = (int)vtop->c.d; break; + case VT_DOUBLE: vtop->c.i = (int)vtop->c.d; break; + case VT_LDOUBLE: vtop->c.i = (int)vtop->c.d; break; + } + break; } - break; - case VT_BOOL: - vpushi(0); - gen_op(TOK_NE); - break; - default: - /* int case */ - switch(sbt) { - case VT_FLOAT: vtop->c.i = (int)vtop->c.d; break; - case VT_DOUBLE: vtop->c.i = (int)vtop->c.d; break; - case VT_LDOUBLE: vtop->c.i = (int)vtop->c.d; break; - } - break; + } else { + do_ftoi: + gen_cvt_ftoi1(dbt); } - } else { - do_ftoi: - gen_cvt_ftoi1(dbt); - } - if (dbt == VT_INT && (type->t & (VT_BTYPE | VT_UNSIGNED)) != dbt) { - /* additional cast for char/short/bool... */ - vtop->type.t = dbt; - gen_cast(type); + if (dbt == VT_INT && (type->t & (VT_BTYPE | VT_UNSIGNED)) != dbt) { + /* additional cast for char/short... */ + vtop->type.t = dbt; + gen_cast(type); + } } } else if ((dbt & VT_BTYPE) == VT_LLONG) { if ((sbt & VT_BTYPE) != VT_LLONG) {
--- a/tests/tcctest.c Wed Apr 18 14:52:22 2007 -0400 +++ b/tests/tcctest.c Tue May 01 17:18:57 2007 -0400 @@ -919,6 +919,7 @@ if (toupper1 (i) != TOUPPER (i)) printf("error %d\n", i); } + } /* GCC accepts that */ @@ -1074,6 +1075,7 @@ char tab[10]; unsigned b,d; short s; + double g = 0.1; printf("cast_test:\n"); a = 0xfffff; @@ -1118,6 +1120,8 @@ /* Cast float to bool */ printf("%d\n", (_Bool) 0.1); + /* Cast non-constant double 0.1 to bool, should be 1, grischka case 6.2 */ + printf("1 -> %d\n", (_Bool) g); /* Cast with sign extension */ a = (short)0xf000;