From 8cb3e5368ff7c6bf8c58c391acffaff0553e9177 Mon Sep 17 00:00:00 2001
From: grischka <grischka>
Date: Fri, 18 Sep 2020 22:53:41 +0200
Subject: [PATCH] bitfields init : tiny solution

This replaces commit 5c6356ff8e8ad57c8d5ad8220d665dfba02290cf,
except the tests.
---
 tccgen.c | 36 +++++++++---------------------------
 1 file changed, 9 insertions(+), 27 deletions(-)

diff --git a/tccgen.c b/tccgen.c
index c46adfd1..52f2462c 100644
--- a/tccgen.c
+++ b/tccgen.c
@@ -7423,10 +7423,17 @@ static int decl_designator(CType *type, Section *sec, unsigned long c,
             c += f->c;
         }
     }
+
     /* must put zero in holes (note that doing it that way
        ensures that it even works with designators) */
-    if (!(flags & DIF_SIZE_ONLY) && c - corig > al)
-	init_putz(sec, corig + al, c - corig - al);
+    if (!(flags & DIF_SIZE_ONLY)) {
+        int zlen = c - (corig + al);
+        if (type->t & VT_BITFIELD) /* must include current field too */
+            zlen += type_size(type, &align);
+        if (zlen > 0)
+	    init_putz(sec, corig + al, zlen);
+    }
+
     decl_initializer(type, sec, c, flags & ~DIF_FIRST);
 
     /* XXX: make it more general */
@@ -7651,23 +7658,6 @@ static void init_putv(CType *type, Section *sec, unsigned long c)
     }
 }
 
-/* Check for bitfield in struct/union recursive */
-static int check_bf(Sym *f)
-{
-   while (f->next) {
-       f = f->next;
-       if ((f->type.t & VT_BITFIELD) ||
-           ((f->type.t & VT_BTYPE) == VT_STRUCT && check_bf(f->type.ref)))
-           return 1;
-       if (f->type.t & VT_ARRAY) {
-           Sym *r = f->type.ref;
-           if (((r->type.t & VT_BTYPE) == VT_STRUCT && check_bf(r->type.ref)))
-               return 1;
-       }
-    }
-    return 0;
-}
-
 /* 't' contains the type and storage info. 'c' is the offset of the
    object in section 'sec'. If 'sec' is NULL, it means stack based
    allocation. 'flags & DIF_FIRST' is true if array '{' must be read (multi
@@ -7705,11 +7695,6 @@ static void decl_initializer(CType *type, Section *sec, unsigned long c,
         t1 = pointed_type(type);
         size1 = type_size(t1, &align1);
 
-        if (!(flags & DIF_SIZE_ONLY) &&
-            (s->type.t & VT_BTYPE) == VT_STRUCT && check_bf (s->type.ref))
-            /* If there is a bitfield in array clear it */
-            init_putz(sec, c, size1 * n);
-
         no_oblock = 1;
         if (((flags & DIF_FIRST) && tok != TOK_LSTR && tok != TOK_STR) ||
             tok == '{') {
@@ -7839,9 +7824,6 @@ static void decl_initializer(CType *type, Section *sec, unsigned long c,
         s = type->ref;
         f = s->next;
         n = s->c;
-        if (!(flags & DIF_SIZE_ONLY) && check_bf (s))
-            /* If there is a bitfield in struct/union clear it */
-            init_putz(sec, c, n);
 	goto do_init_list;
     } else if (tok == '{') {
         if (flags & DIF_HAVE_ELEM)