summaryrefslogtreecommitdiff
path: root/cparser
diff options
context:
space:
mode:
authorGravatar xleroy <xleroy@fca1b0fc-160b-0410-b1d3-a4f43f01ea2e>2010-09-24 09:04:51 +0000
committerGravatar xleroy <xleroy@fca1b0fc-160b-0410-b1d3-a4f43f01ea2e>2010-09-24 09:04:51 +0000
commitcca95c35a944a994de1daee2462c1b3663b3efd2 (patch)
treee329e63fcd9bdd182e5a8e967c8bfd8fdb9b6668 /cparser
parent280f002460e9b7df7f48517ada79d06252c1629c (diff)
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
Diffstat (limited to 'cparser')
-rw-r--r--cparser/Bitfields.ml32
-rw-r--r--cparser/Cutil.ml22
2 files changed, 31 insertions, 23 deletions
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