Local Open Scope logic.
Section SEMAX_SC.
Context {cs: compspecs}.

(* Specifications: *)
Lemma semax_SC_set:
forall {Espec: OracleKind},
forall Delta id P Q R (e2: expr) t v,
typeof_temp Delta id = Some t ->
is_neutral_cast (implicit_deref (typeof e2)) t = true ->
ENTAIL Delta, PROPx P (LOCALx Q (SEPx R)) |-- local (`(eq v) (eval_expr e2)) ->
ENTAIL Delta, PROPx P (LOCALx Q (SEPx R)) |--
(tc_expr Delta e2) ->
semax Delta (|>PROPx P (LOCALx Q (SEPx R)))
(Sset id e2)
(normal_ret_assert
(PROPx P
(LOCALx (temp id v :: remove_localdef_temp id Q)
(SEPx R)))).
Lemma semax_SC_field_load:
forall {Espec: OracleKind} n (Delta: tycontext) sh id P Q R e1
t_id t_root gfs0 gfs1 gfs (p v_val: val) (v_reptype: reptype (nested_field_type t_root gfs0)),
typeof e1 = nested_field_type t_root gfs ->
typeof_temp Delta id = Some t_id ->
is_neutral_cast (nested_field_type t_root gfs) t_id = true ->
type_is_volatile (nested_field_type t_root gfs) = false ->
ENTAIL Delta, PROPx P (LOCALx Q (SEPx R)) |--
local (`(eq (field_address t_root gfs p)) (eval_lvalue e1)) ->
nth_error R n = Some (field_at sh t_root gfs0 v_reptype p) ->
gfs = gfs1 ++ gfs0 ->
readable_share sh ->
JMeq (proj_reptype (nested_field_type t_root gfs0) gfs1 v_reptype) v_val ->
ENTAIL Delta, PROPx P (LOCALx Q (SEPx R)) |--
(tc_lvalue Delta e1) && local (`(tc_val (nested_field_type t_root gfs) v_val)) ->
@semax cs Espec Delta (|> PROPx P (LOCALx Q (SEPx R)))
(Sset id e1)
(normal_ret_assert
(PROPx P
(LOCALx (temp id v_val :: remove_localdef_temp id Q)
(SEPx R)))).
Lemma nth_error_SEP_sepcon_TT': forall D P Q R n Rn S,
ENTAIL D, PROPx P (LOCALx Q (SEPx (Rn :: nil))) |-- S ->
nth_error R n = Some Rn ->
ENTAIL D, (PROPx P (LOCALx Q (SEPx R))) |-- S * TT.
Lemma semax_SC_field_cast_load:
forall {Espec: OracleKind} n (Delta: tycontext) sh id P Q R e1 t
t_root gfs0 gfs1 gfs (p v_val: val) (v_reptype: reptype (nested_field_type t_root gfs0)),
typeof e1 = nested_field_type t_root gfs ->
typeof_temp Delta id = Some t ->
type_is_by_value (nested_field_type t_root gfs) = true ->
cast_pointer_to_bool (nested_field_type t_root gfs) t = false ->
type_is_volatile (nested_field_type t_root gfs) = false ->
ENTAIL Delta, PROPx P (LOCALx Q (SEPx R)) |--
local (`(eq (field_address t_root gfs p)) (eval_lvalue e1)) ->
nth_error R n = Some (field_at sh t_root gfs0 v_reptype p) ->
gfs = gfs1 ++ gfs0 ->
readable_share sh ->
JMeq (proj_reptype (nested_field_type t_root gfs0) gfs1 v_reptype) v_val ->
ENTAIL Delta, PROPx P (LOCALx Q (SEPx R)) |--
(tc_lvalue Delta e1) && local (`(tc_val t (eval_cast (nested_field_type t_root gfs) t v_val))) ->
@semax cs Espec Delta (|> PROPx P (LOCALx Q (SEPx R)))
(Sset id (Ecast e1 t))
(normal_ret_assert
(PROPx P
(LOCALx (temp id (eval_cast (nested_field_type t_root gfs) t v_val) :: remove_localdef_temp id Q)
(SEPx R)))).
Lemma semax_SC_field_store:
forall {Espec: OracleKind},
forall Delta sh n (p: val) P Q R (e1 e2 : expr)
(t_root: type) (gfs0 gfs1 gfs: list gfield)
(v0: reptype (nested_field_type (nested_field_type t_root gfs0) gfs1))
(v0_val: val) (v v_new: reptype (nested_field_type t_root gfs0)),
typeof e1 = nested_field_type t_root gfs ->
type_is_by_value (nested_field_type t_root gfs) = true ->
type_is_volatile (nested_field_type t_root gfs) = false ->
gfs = gfs1 ++ gfs0 ->
nth_error R n = Some (field_at sh t_root gfs0 v p) ->
ENTAIL Delta, PROPx P (LOCALx Q (SEPx R)) |--
local (`(eq (field_address t_root gfs p)) (eval_lvalue e1)) ->
ENTAIL Delta, PROPx P (LOCALx Q (SEPx R)) |--
local (`(eq v0_val) (eval_expr (Ecast e2 (nested_field_type t_root gfs)))) ->
writable_share sh ->
JMeq v0 v0_val ->
data_equal (upd_reptype (nested_field_type t_root gfs0) gfs1 v v0) v_new ->
ENTAIL Delta, PROPx P (LOCALx Q (SEPx R)) |--
(tc_lvalue Delta e1) &&
(tc_expr Delta (Ecast e2 (nested_field_type t_root gfs))) ->
semax Delta (|>PROPx P (LOCALx Q (SEPx R)))
(Sassign e1 e2)
(normal_ret_assert
(PROPx P
(LOCALx Q
(SEPx
(replace_nth n R
(field_at sh t_root gfs0 v_new p)))))).