(** A semantics for general initializers *)
Definition dummy_function := mkfunction Tvoid cc_default nil nil Sskip.
Fixpoint fields_of_struct (fl: members) (pos: Z) : list (Z * type) :=
match fl with
| nil => nil
| (id1, ty1) :: fl' =>
(align pos (alignof ge ty1), ty1) :: fields_of_struct fl' (align pos (alignof ge ty1) + sizeof ge ty1)
end.
Inductive exec_init: mem -> block -> Z -> type -> initializer -> mem -> Prop :=
| exec_init_single: forall m b ofs ty a v1 ty1 chunk m' v m'',
star step ge (ExprState dummy_function a Kstop empty_env m)
E0 (ExprState dummy_function (Eval v1 ty1) Kstop empty_env m') ->
sem_cast v1 ty1 ty m' = Some v ->
access_mode ty = By_value chunk ->
Mem.store chunk m' b ofs v = Some m'' ->
exec_init m b ofs ty (Init_single a) m''
| exec_init_array_: forall m b ofs ty sz a il m',
exec_init_array m b ofs ty sz il m' ->
exec_init m b ofs (Tarray ty sz a) (Init_array il) m'
| exec_init_struct: forall m b ofs id a il co m',
ge.(genv_cenv)!id = Some co -> co_su co = Struct ->
exec_init_list m b ofs (fields_of_struct (co_members co) 0) il m' ->
exec_init m b ofs (Tstruct id a) (Init_struct il) m'
| exec_init_union: forall m b ofs id a f i ty co m',
ge.(genv_cenv)!id = Some co -> co_su co = Union ->
field_type f (co_members co) = OK ty ->
exec_init m b ofs ty i m' ->
exec_init m b ofs (Tunion id a) (Init_union f i) m'
with exec_init_array: mem -> block -> Z -> type -> Z -> initializer_list -> mem -> Prop :=
| exec_init_array_nil: forall m b ofs ty sz,
sz >= 0 ->
exec_init_array m b ofs ty sz Init_nil m
| exec_init_array_cons: forall m b ofs ty sz i1 il m' m'',
exec_init m b ofs ty i1 m' ->
exec_init_array m' b (ofs + sizeof ge ty) ty (sz - 1) il m'' ->
exec_init_array m b ofs ty sz (Init_cons i1 il) m''
with exec_init_list: mem -> block -> Z -> list (Z * type) -> initializer_list -> mem -> Prop :=
| exec_init_list_nil: forall m b ofs,
exec_init_list m b ofs nil Init_nil m
| exec_init_list_cons: forall m b ofs pos ty l i1 il m' m'',
exec_init m b (ofs + pos) ty i1 m' ->
exec_init_list m' b ofs l il m'' ->
exec_init_list m b ofs ((pos, ty) :: l) (Init_cons i1 il) m''.
Scheme exec_init_ind3 := Minimality for exec_init Sort Prop
with exec_init_array_ind3 := Minimality for exec_init_array Sort Prop
with exec_init_list_ind3 := Minimality for exec_init_list Sort Prop.
Combined Scheme exec_init_scheme from exec_init_ind3, exec_init_array_ind3, exec_init_list_ind3.
Remark exec_init_array_length:
forall m b ofs ty sz il m',
exec_init_array m b ofs ty sz il m' -> sz >= 0.

(* Specifications: *)
Lemma store_init_data_list_app:
forall data1 m b ofs m' data2 m'',
Genv.store_init_data_list ge m b ofs data1 = Some m' ->
Genv.store_init_data_list ge m' b (ofs + idlsize data1) data2 = Some m'' ->
Genv.store_init_data_list ge m b ofs (data1 ++ data2) = Some m''.