tinycc-devel
[Top][All Lists]
Advanced

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

Re: [Tinycc-devel] designated inits with duplicate fields


From: grischka
Subject: Re: [Tinycc-devel] designated inits with duplicate fields
Date: Mon, 03 Sep 2012 13:43:41 +0200
User-agent: Thunderbird 2.0.0.24 (Windows/20100228)

If you think it's okay and don't get responses, you might just give
it a try and push on mob.  Read more at
    http://repo.or.cz/w/tinycc.git

Thanks,

--- grischka

Guillaume Chéreau wrote:
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;
         }



reply via email to

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