aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorgrischka <grischka>2009-06-17 02:09:07 +0200
committergrischka <grischka>2009-06-17 02:09:07 +0200
commit69fdb57eddd00c592828605819f0678522d346c6 (patch)
treedcca669d72e59ee4168fbf15f5651538c77071ae
parentbba515afe5496ee59fc10c3307577a87c94fb87f (diff)
downloadtinycc-69fdb57eddd00c592828605819f0678522d346c6.tar.gz
tinycc-69fdb57eddd00c592828605819f0678522d346c6.tar.bz2
unions: initzialize only one field
struct { union { int a,b; }; int c; } sss = { 1,2 }; This had previously assigned 1,2 to a,b and 0 to c which is wrong.
-rw-r--r--tccgen.c18
1 files changed, 18 insertions, 0 deletions
diff --git a/tccgen.c b/tccgen.c
index fcfaa7e..05eb646 100644
--- a/tccgen.c
+++ b/tccgen.c
@@ -4530,6 +4530,24 @@ static void decl_initializer(CType *type, Section *sec, unsigned long c,
index = index + type_size(&f->type, &align1);
if (index > array_length)
array_length = index;
+
+ /* gr: skip fields from same union - ugly. */
+ while (f->next) {
+ ///printf("index: %2d %08x -- %2d %08x\n", f->c, f->type.t, f->next->c, f->next->type.t);
+ /* test for same offset */
+ if (f->next->c != f->c)
+ break;
+ /* if yes, test for bitfield shift */
+ if ((f->type.t & VT_BITFIELD) && (f->next->type.t & VT_BITFIELD)) {
+ int bit_pos_1 = (f->type.t >> VT_STRUCT_SHIFT) & 0x3f;
+ int bit_pos_2 = (f->next->type.t >> VT_STRUCT_SHIFT) & 0x3f;
+ //printf("bitfield %d %d\n", bit_pos_1, bit_pos_2);
+ if (bit_pos_1 != bit_pos_2)
+ break;
+ }
+ f = f->next;
+ }
+
f = f->next;
if (no_oblock && f == NULL)
break;