Section extensions.
Context {CS: compspecs} {Espec: OracleKind}.
(*genv_cenv ge = cenv_cs*) cenv_sub cenv_cs (genv_cenv ge) -> exists jm', exists te', exists rho', rho' = mkEnviron (ge_of rho) (ve_of rho) (make_tenv te') /\ level jm = S (level jm') /\ guard_environ Delta' f rho'  /\ jstep (cl_core_sem ge) (State f c k ve te) jm (State f Sskip k ve te') jm' /\ ((F rho' * Q rho') && funassert Delta' rho) (m_phi jm')) -> semax Espec Delta (fun rho => B rho && |> P rho) c (normal_ret_assert Q).  Definition force_valid_pointers m v1 v2 := match v1, v2 with | Vptr b1 ofs1, Vptr b2 ofs2 => (Mem.valid_pointer m b1 (Ptrofs.unsigned ofs1) && Mem.valid_pointer m b2 (Ptrofs.unsigned ofs2))%bool | _, _ => false end.  Definition blocks_match op v1 v2 := match op with Cop.Olt | Cop.Ogt | Cop.Ole | Cop.Oge => match v1, v2 with Vptr b _, Vptr b2 _ => b=b2 | _, _ => False end | _ => True end.  Lemma later_sepcon2  {A} {JA: Join A}{PA: Perm_alg A}{SA: Sep_alg A}{AG: ageable A}{XA: Age_alg A}: forall P Q,  P * |> Q |-- |> (P * Q).   Lemma perm_order''_trans: forall x y z, perm_order'' x y -> perm_order'' y z -> perm_order'' x z.  Lemma mapsto_valid_pointer : forall b o sh t jm, nonidentity sh -> (mapsto_ sh (t) (Vptr b o) * TT)%pred (m_phi jm) -> Mem.valid_pointer (m_dry jm) b (Ptrofs.unsigned o) = true. intros. rename H into N.  destruct H0. destruct H. destruct H. destruct H0. unfold mapsto_,mapsto in H0.  unfold mapsto in *. destruct (readable_share_dec sh) as [H2 | H2]. * (* readable_share sh *)
destruct (access_mode t); try solve [ inv H0].
destruct (type_is_volatile t) eqn:VOL; try contradiction.
assert (exists v,  address_mapsto m v sh (b, Ptrofs.unsigned o) x).
destruct H0.
econstructor; apply H0. destruct H0 as [_ [v2' H0]]; exists v2'; apply H0.
clear H0; destruct H2 as [x1 H0].
pose proof mapsto_core_load m x1 sh (b, Ptrofs.unsigned o) (m_phi jm).
destruct H2. simpl; eauto.
simpl in H2.
destruct H2.
specialize (H3 (b, Ptrofs.unsigned o)).
if_tac in H3.
destruct H3.  destruct H3.
rewrite valid_pointer_nonempty_perm.
unfold perm.
assert (JMA := juicy_mem_access jm (b, Ptrofs.unsigned o)).
unfold access_at in *. simpl in JMA.
unfold perm_of_res in *.
rewrite H3 in JMA. simpl in JMA.
unfold perm_of_sh in *.
rewrite JMA.
repeat if_tac; try constructor. subst.
simpl in H3.
contradiction.
destruct H4.  repeat split. omega.
destruct m; simpl; omega.
* (* ~ readable_share sh *)
destruct (access_mode t) eqn:?; try contradiction.
destruct (type_is_volatile t); [inversion H0 |].
destruct H0 as [_ [? _]].
specialize (H0 (b, Ptrofs.unsigned o)).
simpl in H0.
rewrite if_true in H0
by (split; auto; pose proof (size_chunk_pos m); omega).
clear H1.
pose proof (resource_at_join _ _ _ (b, Ptrofs.unsigned o) H).
unfold resource_share in H0.
rewrite <- (Z.add_0_r (Ptrofs.unsigned o)).
apply (valid_pointer_dry b o 0 jm).
hnf.
rewrite Z.add_0_r.
destruct H0.
destruct  (x @ (b, Ptrofs.unsigned o)); inv H0; inv H1; simpl; auto.
intro.
apply split_identity in RJ; auto.
Qed.

Lemma pointer_cmp_no_mem_bool_type:
forall (Delta : tycontext) cmp (e1 e2 : expr) sh1 sh2 x1 x b1 o1 b2 o2 i3 s3,
is_comparison cmp = true->
eqb_type (typeof e1) int_or_ptr_type = false ->
eqb_type (typeof e2) int_or_ptr_type = false ->
forall (rho : environ) phi,
eval_expr e1 rho = Vptr b1 o1 ->
eval_expr e2 rho = Vptr b2 o2 ->
blocks_match cmp (eval_expr e1 rho) (eval_expr e2 rho) ->
denote_tc_assert (typecheck_expr Delta e1) rho phi ->
denote_tc_assert (typecheck_expr Delta e2) rho phi ->
(mapsto_ sh1 (typeof e1)
(eval_expr e1 rho)) x ->
(mapsto_ sh2 (typeof e2)
(eval_expr e2 rho)) x1 ->
typecheck_environ Delta rho ->
is_int i3 s3
(force_val
(sem_binary_operation' cmp (typeof e1) (typeof e2)
(eval_expr e1 rho)
(eval_expr e2 rho))).