Definition offset_in_range ofs p :=
  match p with
  | Vptr b iofs => 0 <= Ptrofs.unsigned iofs + ofs <= Ptrofs.modulus
  | _ => True
  end.Definition offset_strict_in_range ofs p :=
  match p with
  | Vptr b iofs => 0 <= Ptrofs.unsigned iofs + ofs < Ptrofs.modulus
  | _ => True
  end.Definition data_at_rec: forall t, reptype t -> val -> mpred :=
  type_func (fun t => reptype t -> val -> mpred)
    (fun t v p =>
       if type_is_volatile t
       then memory_block sh (sizeof t) p
       else mapsto sh t p (repinject t v))
    (fun t n a P v => array_pred 0 (Z.max 0 n) (fun i v => at_offset (P v) (sizeof t * i)) (unfold_reptype v))
    (fun id a P v => struct_data_at_rec_aux sh (co_members (get_co id)) (co_members (get_co id)) (co_sizeof (get_co id)) P (unfold_reptype v))
    (fun id a P v => union_data_at_rec_aux sh (co_members (get_co id)) (co_members (get_co id)) (co_sizeof (get_co id)) P (unfold_reptype v)).

Lemma data_at_rec_eq: forall t v, data_at_rec t v = match t return REPTYPE t -> val -> mpred with | Tvoid | Tfunction _ _ _ => fun _ _ => FF | Tint _ _ _ | Tfloat _ _ | Tlong _ _ | Tpointer _ _ => fun v p => if type_is_volatile t then memory_block sh (sizeof t) p else mapsto sh t p v | Tarray t0 n a => array_pred 0 (Z.max 0 n) (fun i v => at_offset (data_at_rec t0 v) (sizeof t0 * i)) | Tstruct id a => struct_pred (co_members (get_co id)) (fun it v => withspacer sh (field_offset cenv_cs (fst it) (co_members (get_co id)) + sizeof (field_type (fst it) (co_members (get_co id)))) (field_offset_next cenv_cs (fst it) (co_members (get_co id)) (co_sizeof (get_co id))) (at_offset (data_at_rec (field_type (fst it) (co_members (get_co id))) v) (field_offset cenv_cs (fst it) (co_members (get_co id))))) | Tunion id a => union_pred (co_members (get_co id)) (fun it v => withspacer sh (sizeof (field_type (fst it) (co_members (get_co id)))) (co_sizeof (get_co id)) (data_at_rec (field_type (fst it) (co_members (get_co id))) v)) end (unfold_reptype v).