According to Christian, we have at least one major compiler (VC++) whose
behavior matches tcc's current behavior and another (GCC) whose behavior
differs. While it would be nice to just pick one implementation and go with
it, I am personally much more concerned with binary compatibility with
one's major compiler of choice. In that case, the logic for how to handle
this would depend upon a bit being set in the TCCState struct.

Here is a patch that makes the bit field size logic match gcc. I can
confirm that the original alignment bug is gone (though other alignment
bugs may yet be around). I am not 100% sure if this is correct, but I throw
it out there for folks to mull over. Note that indentation may not be
consistent; the indentation pattern in the existing code was weird.
Finally, it might be more efficient to use (bit_size & 7) rather than
(bit_size % 8), or optimizing compilers might do that for us anyway; I
leave that to the gurus.

If this looks good, I propose adding a bit to TCCState to pick this vs the
old behavior, then throwing in a couple of if statements to the below patch
to switch based on said bit.

David

diff --git a/tccgen.c b/tccgen.c
index ad70de6..97b37a4 100644
--- a/tccgen.c
+++ b/tccgen.c
@@ -3109,13 +3109,27 @@ static void struct_decl(CType *type, AttributeDef
*ad, int u)
                             /* zero size: means to pad */
                             bit_pos = 0;
                         } else {
+                           size = bit_size / 8;
+                            if (bit_size % 8) size++; /* round up */
+                            lbit_pos = bit_pos;
                             /* we do not have enough room ?
                                did the type change?
                                is it a union? */
                             if ((bit_pos + bit_size) > bsize ||
-                                bt != prevbt || a == TOK_UNION)
-                                bit_pos = 0;
-                            lbit_pos = bit_pos;
+                                bt != prevbt || a == TOK_UNION) {
+                                lbit_pos = bit_pos = 0;
+                            }
+                            /* only allocate large-type int bitfields
+                             * one byte at a time */
+                            else {
+                               int overage;
+                               overage = bit_pos % 8 + bit_size;
+                               if (overage > 8) {
+                                   lbit_pos = 0;
+                                   size = overage / 8;
+                                   if (overage % 8 == 0) size--;
+                               }
+                           }
                             /* XXX: handle LSB first */
                             type1.t |= VT_BITFIELD |
                                 (bit_pos << VT_STRUCT_SHIFT) |



On Tue, Oct 18, 2016 at 4:35 AM, Vincent Lefevre <vinc...@vinc17.net> wrote:

> On 2016-10-18 09:59:36 +0200, Daniel Glöckner wrote:
> > On Tue, Oct 18, 2016 at 09:41:49AM +0200, Vincent Lefevre wrote:
> > > AFAIK, both are correct.
> >
> > It depends on the ABI. The ARM EABI defines those details in
> > http://infocenter.arm.com/help/topic/com.arm.doc.
> ihi0042f/IHI0042F_aapcs.pdf
> > section 7.1.7. But I don't know if we adhere to those rules when
> > compiling for ARM.
>
> "For the purposes of calculating the alignment of the aggregate the
> type of the member shall be the Fundamental Data Type upon which the
> bit-field is based.[1]
>
> [1] The intent is to permit the C construct struct {int a:8; char b[7];}
> to have size 8 and alignment 4."
>
> Assuming that there are similar requirements for other architectures,
> the behavior of GCC now makes sense to me.
>
> --
> Vincent Lefèvre <vinc...@vinc17.net> - Web: <https://www.vinc17.net/>
> 100% accessible validated (X)HTML - Blog: <https://www.vinc17.net/blog/>
> Work: CR INRIA - computer arithmetic / AriC project (LIP, ENS-Lyon)
>
> _______________________________________________
> Tinycc-devel mailing list
> Tinycc-devel@nongnu.org
> https://lists.nongnu.org/mailman/listinfo/tinycc-devel
>



-- 
 "Debugging is twice as hard as writing the code in the first place.
  Therefore, if you write the code as cleverly as possible, you are,
  by definition, not smart enough to debug it." -- Brian Kernighan
_______________________________________________
Tinycc-devel mailing list
Tinycc-devel@nongnu.org
https://lists.nongnu.org/mailman/listinfo/tinycc-devel

Reply via email to