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