Definition int_or_ptr_type : type :=
Tpointer Tvoid {| attr_volatile := false; attr_alignas := Some log2_sizeof_pointer |}.
(** The following describes types that can be interpreted as a boolean: integers, floats, pointers.  It is used for the semantics of the [!] and [?] operators, as well as the [if], [while], [for] statements. *)
(** Interpretation of values as truth values. Non-zero integers, non-zero floats and non-null pointers are considered as true.  The integer zero (which also represents the null pointer) and the float 0.0 are false. *)
Definition bool_val_i (v : val) : option bool :=
match v with
| Vint n => Some (negb (Int.eq n Int.zero))
| _ => None
end.
Definition bool_val_p (v : val) : option bool :=
match v with
| Vint n => if Archi.ptr64 then None else Some (negb (Int.eq n Int.zero))
| Vlong n => if Archi.ptr64 then Some (negb (Int64.eq n Int64.zero)) else None
| Vptr b ofs => Some true
| _ => None
end.
Definition bool_val_s (v : val) : option bool :=
match v with
| Vsingle f => Some (negb (Float32.cmp Ceq f Float32.zero))
| _ => None
end.
Definition bool_val_f (v : val) : option bool :=
match v with
| Vfloat f => Some (negb (Float.cmp Ceq f Float.zero))
| _ => None
end.
Definition bool_val_l (v : val) : option bool :=
match v with
| Vlong n => Some (negb (Int64.eq n Int64.zero))
| Vptr b ofs =>
if negb Archi.ptr64 then None else Some true
| _ => None
end.
Definition bool_val (t: type) : val -> option bool :=
match t with
| Tint _ _ _ => bool_val_i
| Tpointer _ _ => if  eqb_type t int_or_ptr_type then (fun _ => None) else bool_val_p
| Tfloat F64 _ => bool_val_f
| Tfloat F32 _ => bool_val_s
| Tlong _ _ => bool_val_l
| _ => fun v => None
end.
(*************** from veric.expr.v   **********************)
Definition size_t := if Archi.ptr64 then Tlong Unsigned noattr else Tint I32 Unsigned noattr.
Definition is_int (sz: intsize) (sg: signedness) (v: val) :=
match v with
| Vint i =>
match sz, sg with
| I8, Signed => Byte.min_signed <= Int.signed i <= Byte.max_signed
| I8, Unsigned => Int.unsigned i <= Byte.max_unsigned
| I16, Signed => -two_p (16-1) <= Int.signed i <= two_p (16-1) -1
| I16, Unsigned => Int.unsigned i <= two_p 16 - 1
| I32, _ => True
| IBool, _ => i = Int.zero \/ i = Int.one
end
| _ => False
end.
Definition tc_val (ty: type) : val -> Prop :=
match ty with
| Tint sz sg _ => is_int sz sg
| Tlong _ _ => is_long
| Tfloat F64 _ => is_float
| Tfloat F32 _ => is_single
| Tpointer _ _ => if eqb_type ty int_or_ptr_type then is_pointer_or_integer else is_pointer_or_null
| Tarray _ _ _ | Tfunction _ _ _ => is_pointer_or_null
| Tstruct _ _ => isptr
| Tunion _ _ => isptr
| _ => fun _ => False
end.
Definition tc_val' t v := v <> Vundef -> tc_val t v.
Fixpoint tc_vals (ty: list type) (v: list val) : Prop :=
match v, ty with
| v1::vs , t1::ts => tc_val t1 v1 /\ tc_vals ts vs
| nil, nil => True
| _, _ => False
end.

(* Specifications: *)
Lemma tc_val_Vundef:
forall t, ~tc_val t Vundef.
Lemma tc_val'_Vundef:
forall t, tc_val' t Vundef.
Lemma tc_val_tc_val':
forall t v, tc_val t v -> tc_val' t v.
Lemma tc_val_has_type (ty : type) (v : val) :
tc_val ty v ->
Val.has_type v (typ_of_type ty).