Commit cca95c35 authored by xleroy's avatar xleroy
Browse files

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
parent 280f0024
......@@ -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 =
......
......@@ -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
......
......@@ -9,7 +9,7 @@ LIBS=$(LIBMATH)
# Can run and have reference output in Results
TESTS=bitfields1 bitfields2 bitfields3 bitfields4 \
bitfields5 bitfields6 \
bitfields5 bitfields6 bitfields7 \
expr1 initializers volatile2 \
funct3 expr5 struct7 struct8 casts1 casts2
......
#include <stdio.h>
struct S0 {
signed f0 : 12;
unsigned f1 : 28;
};
struct S5 {
struct S0 f1;
unsigned : 0;
signed f2 : 26;
};
struct S5 g_22 = {{0,0},1};
int main(int argc, char* argv[])
{
printf("g_22.f2 = %d\n", g_22.f2);
return 0;
}
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment