Skip to content

Commit 6dbd99d

Browse files
lyonel2017strub
authored andcommitted
Add check to prevent swapping of exception raises
1 parent c807474 commit 6dbd99d

4 files changed

Lines changed: 72 additions & 0 deletions

File tree

src/ecCoreModules.ml

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,26 @@ let is_while = _is_of_get get_while
161161
let is_match = _is_of_get get_match
162162
let is_raise = _is_of_get get_raise
163163

164+
(* -------------------------------------------------------------------- *)
165+
let i_iter (f : instr -> unit) =
166+
let rec i_iter (i : instr) =
167+
match i.i_node with
168+
| Sasgn _ | Srnd _ | Scall _ | Sraise _ | Sabstract _ -> ()
169+
170+
| Sif (_, s1, s2) ->
171+
List.iter fs [s1; s2]
172+
173+
| Swhile (_, s) ->
174+
fs s
175+
176+
| Smatch (_, bs) ->
177+
List.iter (fun (_, s) -> fs s) bs
178+
179+
and fs (s : stmt) =
180+
List.iter f s.s_node
181+
182+
in fun (i : instr) -> i_iter i
183+
164184
(* -------------------------------------------------------------------- *)
165185
module Uninit = struct (* FIXME: generalize this for use in ecPV *)
166186
let e_pv e =

src/ecCoreModules.mli

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,9 @@ val is_while : instr -> bool
7676
val is_match : instr -> bool
7777
val is_raise : instr -> bool
7878

79+
(* -------------------------------------------------------------------- *)
80+
val i_iter : (instr -> unit) -> instr -> unit
81+
7982
(* -------------------------------------------------------------------- *)
8083
val get_uninit_read : stmt -> Sx.t
8184

src/phl/ecPhlSwap.ml

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,23 @@ type swap_kind = {
1919
(* -------------------------------------------------------------------- *)
2020
module LowInternal = struct
2121
let check_swap (pf : proofenv) (env : EcEnv.env) (s1 : stmt) (s2 : stmt) =
22+
let is_contains_raise =
23+
let exception HasRaise in
24+
25+
let rec i_contains_raise (i : instr) =
26+
match i.i_node with
27+
| Sraise _ -> raise HasRaise
28+
| _ -> EcModules.i_iter i_contains_raise i in
29+
30+
fun (s : stmt) ->
31+
try
32+
List.iter i_contains_raise s.s_node;
33+
false
34+
with HasRaise -> true in
35+
36+
if List.exists is_contains_raise [s1; s2] then
37+
tc_error pf "cannot swap blocks that contain exceptions";
38+
2239
let m1,m2 = s_write env s1, s_write env s2 in
2340
let r1,r2 = s_read env s1, s_read env s2 in
2441
(* FIXME: this is not sufficient *)

tests/exception/exception_swap.ec

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
require import AllCore.
2+
3+
exception exn1.
4+
5+
module M = {
6+
var w : int
7+
var x : int
8+
var y : int
9+
var z : int
10+
11+
proc f() : unit = {
12+
w <- 42;
13+
x <- 42;
14+
raise exn1;
15+
y <- 42;
16+
z <- 42;
17+
}
18+
}.
19+
20+
lemma f_correct :
21+
hoare[M.f : true ==> false | exn1 => M.x = 42 /\ M.w = 42].
22+
proof. proc. wp. skip. smt(). qed.
23+
24+
lemma f_wrong :
25+
hoare[M.f : M.x = 0 ==> false | exn1 => M.x = 0].
26+
proof. proc.
27+
swap 1 1.
28+
swap 4 1.
29+
fail swap 1 2.
30+
fail swap 1 3.
31+
fail swap 3 1.
32+
abort.

0 commit comments

Comments
 (0)