tinycc-devel
[Top][All Lists]
Advanced

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

Re: [Tinycc-devel] Weird bitfield size handling, discrepancy with gcc


From: David Mertens
Subject: Re: [Tinycc-devel] Weird bitfield size handling, discrepancy with gcc
Date: Tue, 18 Oct 2016 10:17:52 -0400

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 <address@hidden> 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 <address@hidden> - 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
address@hidden
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

reply via email to

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