From cca95c35a944a994de1daee2462c1b3663b3efd2 Mon Sep 17 00:00:00 2001 From: xleroy Date: Fri, 24 Sep 2010 09:04:51 +0000 Subject: Inconsistent treatment of "lone" zero-width bit fields (i.e. not preceded by another bit field). git-svn-id: https://yquem.inria.fr/compcert/svn/compcert/trunk@1516 fca1b0fc-160b-0410-b1d3-a4f43f01ea2e --- cparser/Bitfields.ml | 32 +++++++++++++++++++------------- cparser/Cutil.ml | 22 ++++++++++++---------- 2 files changed, 31 insertions(+), 23 deletions(-) (limited to 'cparser') diff --git a/cparser/Bitfields.ml b/cparser/Bitfields.ml index a345d97..9452a4f 100644 --- a/cparser/Bitfields.ml +++ b/cparser/Bitfields.ml @@ -88,19 +88,25 @@ let rec transf_members env id count = function m :: transf_members env id count ms else begin let (nbits, bitfields, ml') = pack_bitfields env id ml in - let carrier = sprintf "__bf%d" count in - let carrier_typ = TInt(unsigned_ikind_for_carrier nbits, []) in - List.iter - (fun (name, pos, sz, signed, signed2) -> - if name <> "" then - Hashtbl.add bitfield_table - (id, name) - {bf_carrier = carrier; bf_carrier_typ = carrier_typ; - bf_pos = pos; bf_size = sz; - bf_signed = signed; bf_signed_res = signed2}) - bitfields; - { fld_name = carrier; fld_typ = carrier_typ; fld_bitfield = None} - :: transf_members env id (count + 1) ml' + if nbits = 0 then + (* Lone zero-size bitfield: just ignore *) + transf_members env id count ml' + else begin + (* Create integer field of sufficient size for this bitfield group *) + let carrier = sprintf "__bf%d" count in + let carrier_typ = TInt(unsigned_ikind_for_carrier nbits, []) in + List.iter + (fun (name, pos, sz, signed, signed2) -> + if name <> "" then + Hashtbl.add bitfield_table + (id, name) + {bf_carrier = carrier; bf_carrier_typ = carrier_typ; + bf_pos = pos; bf_size = sz; + bf_signed = signed; bf_signed_res = signed2}) + bitfields; + { fld_name = carrier; fld_typ = carrier_typ; fld_bitfield = None} + :: transf_members env id (count + 1) ml' + end end let transf_composite env su id ml = diff --git a/cparser/Cutil.ml b/cparser/Cutil.ml index cb241e5..bb540c7 100644 --- a/cparser/Cutil.ml +++ b/cparser/Cutil.ml @@ -216,12 +216,14 @@ let pack_bitfields ml = pack (nbits + n) ms (* add to current word *) in let (nbits, ml') = pack 0 ml in - let sz = - if nbits <= 8 then 1 else - if nbits <= 16 then 2 else - if nbits <= 32 then 4 else - if nbits <= 64 then 8 else assert false in - (sz, ml') + let (sz, al) = + (* A lone bitfield of width 0 consumes no space and aligns to 1 *) + if nbits = 0 then (0, 1) else + if nbits <= 8 then (1, 1) else + if nbits <= 16 then (2, 2) else + if nbits <= 32 then (4, 4) else + if nbits <= 64 then (8, 8) else assert false in + (sz, al, ml') (* Natural alignment, in bytes *) @@ -264,8 +266,8 @@ let alignof_struct_union env members = | None -> None | Some a -> align_rec (max a al) rem end else begin - let (sz, ml') = pack_bitfields ml in - align_rec (max sz al) ml' + let (s, a, ml') = pack_bitfields ml in + align_rec (max a al) ml' end in align_rec 1 members @@ -355,8 +357,8 @@ let sizeof_struct env members = | Some a, Some s -> sizeof_rec (align ofs a + s) rem | _, _ -> None end else begin - let (sz, ml') = pack_bitfields ml in - sizeof_rec (align ofs sz + sz) ml' + let (s, a, ml') = pack_bitfields ml in + sizeof_rec (align ofs a + s) ml' end in sizeof_rec 0 members -- cgit v1.2.3