summaryrefslogtreecommitdiff
path: root/cparser/Cutil.ml
diff options
context:
space:
mode:
authorGravatar xleroy <xleroy@fca1b0fc-160b-0410-b1d3-a4f43f01ea2e>2010-04-09 12:25:03 +0000
committerGravatar xleroy <xleroy@fca1b0fc-160b-0410-b1d3-a4f43f01ea2e>2010-04-09 12:25:03 +0000
commitd966e01ea011fa66d5a5a7f9ffce4344e415981a (patch)
tree487a86c759777b54a9e9dda72c602348c9270920 /cparser/Cutil.ml
parentb66aaf2d1b90ff51f54bcd2a344a6ab50ac6fe86 (diff)
Bug fix: infinite loop in cparser/ on bit field of size 32 bits.
Algorithmic efficiency: in cparser/, precompute sizeof and alignof of composites. Code cleanup: introduced Cutil.composite_info_{def,decl} git-svn-id: https://yquem.inria.fr/compcert/svn/compcert/trunk@1312 fca1b0fc-160b-0410-b1d3-a4f43f01ea2e
Diffstat (limited to 'cparser/Cutil.ml')
-rw-r--r--cparser/Cutil.ml65
1 files changed, 28 insertions, 37 deletions
diff --git a/cparser/Cutil.ml b/cparser/Cutil.ml
index c0c26e5..49b25a2 100644
--- a/cparser/Cutil.ml
+++ b/cparser/Cutil.ml
@@ -210,7 +210,7 @@ let pack_bitfields ml =
| Some n ->
if n = 0 then
(nbits, ms) (* bit width 0 means end of pack *)
- else if nbits + n >= 8 * !config.sizeof_int then
+ else if nbits + n > 8 * !config.sizeof_int then
(nbits, ml) (* doesn't fit in current word *)
else
pack (nbits + n) ms (* add to current word *)
@@ -249,24 +249,13 @@ let rec alignof env t =
| TFun(_, _, _, _) -> !config.alignof_fun
| TNamed(_, _) -> alignof env (unroll env t)
| TStruct(name, _) ->
- let ci = Env.find_struct env name in
- if ci.ci_incomplete
- then None
- else alignof_struct_union
- (Env.add_composite env name {ci with ci_incomplete = true})
- ci.ci_members
+ let ci = Env.find_struct env name in ci.ci_alignof
| TUnion(name, _) ->
- let ci = Env.find_union env name in
- if ci.ci_incomplete
- then None
- else alignof_struct_union
- (Env.add_composite env name {ci with ci_incomplete = true})
- ci.ci_members
+ let ci = Env.find_union env name in ci.ci_alignof
-(* We set ci_incomplete to true before recursing so that we stop and
- return None on ill-formed structs such as struct a { struct a x; }. *)
+(* Compute the natural alignment of a struct or union. *)
-and alignof_struct_union env members =
+let alignof_struct_union env members =
let rec align_rec al = function
| [] -> Some al
| m :: rem as ml ->
@@ -326,27 +315,15 @@ let rec sizeof env t =
| TFun(_, _, _, _) -> !config.sizeof_fun
| TNamed(_, _) -> sizeof env (unroll env t)
| TStruct(name, _) ->
- let ci = Env.find_struct env name in
- if ci.ci_incomplete
- then None
- else sizeof_struct
- (Env.add_composite env name {ci with ci_incomplete = true})
- ci.ci_members
+ let ci = Env.find_struct env name in ci.ci_sizeof
| TUnion(name, _) ->
- let ci = Env.find_union env name in
- if ci.ci_incomplete
- then None
- else sizeof_union
- (Env.add_composite env name {ci with ci_incomplete = true})
- ci.ci_members
+ let ci = Env.find_union env name in ci.ci_sizeof
-(* We set ci_incomplete to true before recursing so that we stop and
- return None on ill-formed structs such as struct a { struct a x; }. *)
+(* Compute the size of a union.
+ It is the size is the max of the sizes of fields, rounded up to the
+ natural alignment. *)
-(* For a union, the size is the max of the sizes of fields,
- rounded up to the natural alignment. *)
-
-and sizeof_union env members =
+let sizeof_union env members =
let rec sizeof_rec sz = function
| [] ->
begin match alignof_struct_union env members with
@@ -360,10 +337,11 @@ and sizeof_union env members =
end
in sizeof_rec 0 members
-(* For a struct, we lay out fields consecutively, inserting padding
- to preserve their natural alignment. *)
+(* Compute the size of a struct.
+ We lay out fields consecutively, inserting padding to preserve
+ their natural alignment. *)
-and sizeof_struct env members =
+let sizeof_struct env members =
let rec sizeof_rec ofs = function
| [] | [ { fld_typ = TArray(_, None, _) } ] ->
(* C99: ty[] allowed as last field *)
@@ -387,6 +365,19 @@ and sizeof_struct env members =
let incomplete_type env t =
match sizeof env t with None -> true | Some _ -> false
+(* Computing composite_info records *)
+
+let composite_info_decl env su =
+ { ci_kind = su; ci_members = []; ci_alignof = None; ci_sizeof = None }
+
+let composite_info_def env su m =
+ { ci_kind = su; ci_members = m;
+ ci_alignof = alignof_struct_union env m;
+ ci_sizeof =
+ match su with
+ | Struct -> sizeof_struct env m
+ | Union -> sizeof_union env m }
+
(* Type of a function definition *)
let fundef_typ fd =