tinycc-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Tinycc-devel] designated inits with duplicate fields


From: Guillaume Chéreau
Subject: [Tinycc-devel] designated inits with duplicate fields
Date: Thu, 30 Aug 2012 17:19:32 +0800

Hello,

I found an issue with tcc.
when trying to compile a code like this one:

    struct {
        int x;
    } var = {
        .x = 1,
        .x = 2,
    };

tcc would not generate any error or warning about the duplicated field.
Then at execution the value of var.x would be 3 (which happens to be
the result of the binary OR applied to the two values).

I think tcc should do like gcc in that case and consider that the last
specified value is the correct one.

The reason why this can be useful is because then we can use a macro
that defines the list of default values to put into a structure field.
 e.g:

    #define DEFAULT_VALUES .x = 10, .y = 20
    struct my_struct var = {DEFAULT_VALUES, .x = 5};

I am not familiar with the code of tcc, so maybe there are better ways
of fixing the issue, but I could get the behaviour I wanted by doing
this change to the code :

diff --git a/tccgen.c b/tccgen.c
index 71d0809..2edf984 100644
--- a/tccgen.c
+++ b/tccgen.c
@@ -4875,9 +4875,11 @@ static void init_putv(CType *type, Section
*sec, unsigned long c,
         case VT_BOOL:
             vtop->c.i = (vtop->c.i != 0);
         case VT_BYTE:
+            *(char *)ptr &= ~(bit_mask << bit_pos);
             *(char *)ptr |= (vtop->c.i & bit_mask) << bit_pos;
             break;
         case VT_SHORT:
+            *(short *)ptr &= ~(bit_mask << bit_pos);
             *(short *)ptr |= (vtop->c.i & bit_mask) << bit_pos;
             break;
         case VT_DOUBLE:
@@ -4887,12 +4889,14 @@ static void init_putv(CType *type, Section
*sec, unsigned long c,
             *(long double *)ptr = vtop->c.ld;
             break;
         case VT_LLONG:
+            *(long long *)ptr &= ~(bit_mask << bit_pos);
             *(long long *)ptr |= (vtop->c.ll & bit_mask) << bit_pos;
             break;
         default:
             if (vtop->r & VT_SYM) {
                 greloc(sec, vtop->sym, c, R_DATA_PTR);
             }
+            *(int *)ptr &= ~(bit_mask << bit_pos);
             *(int *)ptr |= (vtop->c.i & bit_mask) << bit_pos;
             break;
         }


Best regards,
Guillaume

-- 
Guillaume
address@hidden
+886 970422910



reply via email to

[Prev in Thread] Current Thread [Next in Thread]