diff options
author | Xavier Leroy <xavier.leroy@inria.fr> | 2018-04-21 18:57:51 +0300 |
---|---|---|
committer | Xavier Leroy <xavierleroy@users.noreply.github.com> | 2018-04-25 14:27:31 +0200 |
commit | 92c8be3a36dff49f92e6cf94719a1750e4961538 (patch) | |
tree | 535a8dd1af2fad409abb00a6a356e3d5f0c02cef /cparser/Bitfields.ml | |
parent | 7be3e73fa8a46b6b813c1be98da54a1a471378b9 (diff) | |
download | compcert-92c8be3a36dff49f92e6cf94719a1750e4961538.tar.gz compcert-92c8be3a36dff49f92e6cf94719a1750e4961538.zip |
Initialization of anonymous bit-fields in structs
For anonymous bit-fields in structs, carrier fields may
be introduced which are not initialized since no default
initializer are generated earlier. This cause the translation in
C2C to throw an error since too few initializers are available.
Example:
struct s2 {
int : 10;
int a;
int : 10;
char b;
int : 10;
short c;
int : 10;
} s2 = { 42, 'a', 43 };
To work around this issue we need to generate a default inializer
for every new member that does not have a translated member.
Based on P#80, with more efficient algorithms.
Bug 23362
Diffstat (limited to 'cparser/Bitfields.ml')
-rw-r--r-- | cparser/Bitfields.ml | 21 |
1 files changed, 20 insertions, 1 deletions
diff --git a/cparser/Bitfields.ml b/cparser/Bitfields.ml index 71226ec6..696a9a8d 100644 --- a/cparser/Bitfields.ml +++ b/cparser/Bitfields.ml @@ -359,6 +359,20 @@ let rec transf_struct_init id fld_init_list = etyp = bf.bf_carrier_typ}) :: transf_struct_init id rem' +(* Add default initialization for carrier fields that are not listed in the output of + [transf_struct_init]. This happens with carrier fields that contain no named + bitfields, only anonymous bitfields. *) + +let rec completed_struct_init env actual expected = + match actual, expected with + | [], [] -> [] + | (f_a, i) :: actual', f_e :: expected' when f_a.fld_name = f_e.fld_name -> + (f_a, i) :: completed_struct_init env actual' expected' + | _, f_e :: expected' -> + (f_e, default_init env f_e.fld_typ) :: completed_struct_init env actual expected' + | _, [] -> + assert false + (* Check whether a field access (e.f or e->f) is a bitfield access. If so, return carrier expression (e and *e, respectively) and bitfield_info *) @@ -520,7 +534,12 @@ and transf_init env i = | Init_struct(id, fld_init_list) -> let fld_init_list' = List.map (fun (f, i) -> (f, transf_init env i)) fld_init_list in - Init_struct(id, transf_struct_init id fld_init_list') + begin match Hashtbl.find composite_transformed_members id with + | exception Not_found -> + Init_struct(id, fld_init_list') + | ml -> + Init_struct(id, completed_struct_init env (transf_struct_init id fld_init_list') ml) + end | Init_union(id, fld, i) -> let i' = transf_init env i in match is_bitfield id fld.fld_name with |