aboutsummaryrefslogtreecommitdiffstats
path: root/cparser/Cutil.ml
diff options
context:
space:
mode:
authorBernhard Schommer <bernhardschommer@gmail.com>2017-01-20 14:44:59 +0100
committerBernhard Schommer <bernhardschommer@gmail.com>2017-01-20 14:44:59 +0100
commit47e818992372c1480b1052b64728a33d758637cf (patch)
treee6351d1028516561f2bb56879d4b3174850c7198 /cparser/Cutil.ml
parentac2e4bb9bc63e0ea8b5cf67274bddb9ec74b771e (diff)
downloadcompcert-kvx-47e818992372c1480b1052b64728a33d758637cf.tar.gz
compcert-kvx-47e818992372c1480b1052b64728a33d758637cf.zip
Simplified version.
The problem was that sub structs are were not correctly aligned. The new version is much simpler and uses the sizeof_struct to calculate the individual offsets and add them up to get correct offest. Bug 20765
Diffstat (limited to 'cparser/Cutil.ml')
-rw-r--r--cparser/Cutil.ml51
1 files changed, 18 insertions, 33 deletions
diff --git a/cparser/Cutil.ml b/cparser/Cutil.ml
index 66ea19e4..30f7294b 100644
--- a/cparser/Cutil.ml
+++ b/cparser/Cutil.ml
@@ -535,40 +535,25 @@ let sizeof_struct env members =
(* Compute the offset of a struct member *)
let offsetof env ty fields =
- let align_field ofs ty =
- let a = match alignof env ty with
- | Some a -> a
- | None -> assert false in
- align ofs a in
- let rec offsetof_rec ofs field rest = function
- | [] -> ofs
- | m :: rem as ml ->
- if m.fld_name = field.fld_name then begin
- match rest with
- | [] -> align_field ofs field.fld_typ
- | _ -> lookup_field ofs field.fld_typ rest
- end else if m.fld_bitfield = None then begin
- match alignof env m.fld_typ, sizeof env m.fld_typ with
- | Some a, Some s -> offsetof_rec (align ofs a + s) field rest rem
- | _, _ -> assert false (* should never happen *)
- end else begin
- let (s, a, ml') = pack_bitfields ml in
- let ofs = align ofs a + s in
- offsetof_rec ofs field rest ml'
- end
- and lookup_field ofs ty = function
- | [] -> align_field ofs ty
- | fld::rest ->
- begin match unroll env ty with
- | TStruct (id,_) ->
- let str = Env.find_struct env id in
- offsetof_rec ofs fld rest str.ci_members
- | TUnion (id,_) ->
- lookup_field ofs fld.fld_typ rest
- | _ -> assert false
- end
+ let rec sub acc name = function
+ | [] -> List.rev acc
+ | m::rem -> if m.fld_name = name then
+ List.rev acc
+ else
+ sub (m::acc) name rem in
+ let offset (ofs,ty) field =
+ match unroll env ty with
+ | TStruct (id,_) ->
+ let str = Env.find_struct env id in
+ let pre = sub [] field.fld_name str.ci_members in
+ begin match sizeof_struct env pre ,alignof env field.fld_typ with
+ | Some s, Some a ->
+ (ofs + align s a),field.fld_typ
+ | _ -> assert false end
+ | _ -> ofs,field.fld_typ
in
- lookup_field 0 ty (List.rev fields)
+ let fields = List.rev fields in
+ fst (List.fold_left offset (0,ty) fields)
(* Simplified version to compute offsets on structs without bitfields *)
let struct_layout env members =