changeset 406:204dee5c5152

Patch from Marcelo Jimenez <marcelo.jimenez@gmail.com> fixing the following bug reported in the Debian BTS: Tcc doesn't correctly implement casts from floating point types to _Bool. According to C99, such casts must return true for all numbers except 0: When any scalar value is converted to _Bool, the result is 0 if the value compares equal to 0; otherwise, the result is 1. This means that (_Bool) 0.1 must be 1; with tcc it's 0. The following trivial program can be used to test this: #include <stdio.h> int main (void) { printf ("%d\n", (_Bool) 0.1); return 0; } The program prints 1 under Gcc (and other C99-compliant compilers I tested it with, such as Sun's cc) and 0 under Tcc. I know that Tcc doesn't aim for C99 conformance, but it's confusing that it implements the _Bool type which comes from C99, but not the associated semantics. http://bugs.debian.org/322913
author landley@driftwood
date Sun, 08 Oct 2006 22:54:25 -0400
parents e0e5d588f606
children 8221c0d15dee
files tcc.c tests/tcctest.c
diffstat 2 files changed, 8 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- a/tcc.c	Sun Oct 08 22:46:00 2006 -0400
+++ b/tcc.c	Sun Oct 08 22:54:25 2006 -0400
@@ -5846,6 +5846,7 @@
             /* 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) {
@@ -5861,6 +5862,10 @@
                     case VT_LDOUBLE: vtop->c.ui = (unsigned int)vtop->c.d; break;
                     }
                     break;
+                case VT_BOOL:
+                    vpushi(0);
+                    gen_op(TOK_NE);
+                    break;
                 default:
                     /* int case */
                     switch(sbt) {
--- a/tests/tcctest.c	Sun Oct 08 22:46:00 2006 -0400
+++ b/tests/tcctest.c	Sun Oct 08 22:54:25 2006 -0400
@@ -1109,6 +1109,9 @@
     printf("sizeof(+(char)'a') = %d\n", sizeof(+(char)'a'));
     printf("sizeof(-(char)'a') = %d\n", sizeof(-(char)'a'));
     printf("sizeof(~(char)'a') = %d\n", sizeof(-(char)'a'));
+
+    /* Cast float to bool */
+    printf("%d\n", (_Bool) 0.1);
 }
 
 /* initializers tests */