============ initial translation from Move ================ [variant baseline] public fun A::mutate_at($t0|addr: address) { var $t1|s: &mut A::S var $t2: address var $t3: &mut A::S var $t4: u64 var $t5: &mut A::S var $t6: &mut u64 0: $t2 := move($t0) 1: $t3 := borrow_global($t2) 2: $t1 := $t3 3: $t4 := 2 4: $t5 := move($t1) 5: $t6 := borrow_field.x($t5) 6: write_ref($t6, $t4) 7: return () } [variant baseline] public fun A::read_at($t0|addr: address): u64 { var $t1|s: &A::S var $t2: address var $t3: &A::S var $t4: &A::S var $t5: &u64 var $t6: u64 0: $t2 := move($t0) 1: $t3 := borrow_global($t2) 2: $t1 := $t3 3: $t4 := move($t1) 4: $t5 := borrow_field.x($t4) 5: $t6 := read_ref($t5) 6: return $t6 } [variant baseline] public fun B::move_from_test_incorrect($t0|addr1: address, $t1|addr2: address): B::T { var $t2|v: B::T var $t3|x0: u64 var $t4|x1: u64 var $t5: address var $t6: u64 var $t7: address var $t8: B::T var $t9: address var $t10: u64 var $t11: B::T 0: $t5 := copy($t1) 1: $t6 := A::read_at($t5) 2: $t3 := $t6 3: $t7 := move($t0) 4: $t8 := move_from($t7) 5: $t2 := $t8 6: $t9 := move($t1) 7: $t10 := A::read_at($t9) 8: $t4 := $t10 9: assert Eq($t3, $t4) 10: $t11 := move($t2) 11: return $t11 } [variant baseline] public fun B::move_to_test_incorrect($t0|account: &signer, $t1|addr2: address) { var $t2|x0: u64 var $t3|x1: u64 var $t4: address var $t5: u64 var $t6: &signer var $t7: u64 var $t8: B::T var $t9: address var $t10: u64 0: $t4 := copy($t1) 1: $t5 := A::read_at($t4) 2: $t2 := $t5 3: $t6 := move($t0) 4: $t7 := 2 5: $t8 := pack B::T($t7) 6: move_to($t8, $t6) 7: $t9 := move($t1) 8: $t10 := A::read_at($t9) 9: $t3 := $t10 10: assert Eq($t2, $t3) 11: return () } [variant baseline] public fun B::mutate_S_test1_incorrect($t0|addr1: address, $t1|addr2: address) { var $t2|x0: u64 var $t3|x1: u64 var $t4: address var $t5: u64 var $t6: address var $t7: address var $t8: u64 0: $t4 := copy($t1) 1: $t5 := A::read_at($t4) 2: $t2 := $t5 3: $t6 := move($t0) 4: A::mutate_at($t6) 5: $t7 := move($t1) 6: $t8 := A::read_at($t7) 7: $t3 := $t8 8: assert Eq($t2, $t3) 9: return () } [variant baseline] public fun B::mutate_S_test2_incorrect($t0|addr: address) { var $t1|x0: u64 var $t2|x1: u64 var $t3: address var $t4: u64 var $t5: address var $t6: address var $t7: u64 0: $t3 := copy($t0) 1: $t4 := A::read_at($t3) 2: $t1 := $t4 3: $t5 := copy($t0) 4: A::mutate_at($t5) 5: $t6 := move($t0) 6: $t7 := A::read_at($t6) 7: $t2 := $t7 8: assert Eq($t1, $t2) 9: return () } [variant baseline] public fun B::mutate_at_test_incorrect($t0|addr1: address, $t1|addr2: address) { var $t2|t: &mut B::T var $t3|x0: u64 var $t4|x1: u64 var $t5: address var $t6: u64 var $t7: address var $t8: &mut B::T var $t9: u64 var $t10: &mut B::T var $t11: &mut u64 var $t12: address var $t13: u64 0: $t5 := copy($t1) 1: $t6 := A::read_at($t5) 2: $t3 := $t6 3: $t7 := move($t0) 4: $t8 := borrow_global($t7) 5: $t2 := $t8 6: $t9 := 2 7: $t10 := move($t2) 8: $t11 := borrow_field.x($t10) 9: write_ref($t11, $t9) 10: $t12 := move($t1) 11: $t13 := A::read_at($t12) 12: $t4 := $t13 13: assert Eq($t3, $t4) 14: return () } ============ after pipeline `spec_instrumentation` ================ [variant verification] public fun A::mutate_at($t0|addr: address) { var $t1|s: &mut A::S var $t2: &mut A::S var $t3: num var $t4: u64 var $t5: &mut u64 0: assume CanModify($t0) 1: @1 := save_mem(A::S) # VC: caller does not have permission to modify `A::S` at given address at tests/spec_instrumentation/modifies.move:18:17+17 2: assert CanModify($t0) 3: $t2 := borrow_global($t0) on_abort goto 13 with $t3 4: $t4 := 2 5: $t5 := borrow_field.x($t2) 6: write_ref($t5, $t4) 7: write_back[Reference($t2).x (u64)]($t5) 8: write_back[A::S@]($t2) 9: label L1 # VC: function does not abort under this condition at tests/spec_instrumentation/modifies.move:24:9+27 10: assert Not(Not(exists[@1]($t0))) # VC: post-condition does not hold at tests/spec_instrumentation/modifies.move:23:9+31 11: assert Eq(select A::S.x(global($t0)), 2) 12: return () 13: label L2 # VC: abort not covered by any of the `aborts_if` clauses at tests/spec_instrumentation/modifies.move:21:5+162 14: assert Not(exists[@1]($t0)) 15: abort($t3) } [variant verification] public fun A::read_at($t0|addr: address): u64 { var $t1|s: A::S var $t2: A::S var $t3: num var $t4: u64 0: @0 := save_mem(A::S) 1: $t2 := get_global($t0) on_abort goto 7 with $t3 2: $t4 := get_field.x($t2) 3: label L1 # VC: function does not abort under this condition at tests/spec_instrumentation/modifies.move:13:9+27 4: assert Not(Not(exists[@0]($t0))) # VC: post-condition does not hold at tests/spec_instrumentation/modifies.move:14:9+36 5: assert Eq($t4, select A::S.x(global($t0))) 6: return $t4 7: label L2 # VC: abort not covered by any of the `aborts_if` clauses at tests/spec_instrumentation/modifies.move:11:5+131 8: assert Not(exists[@0]($t0)) 9: abort($t3) } [variant verification] public fun B::move_from_test_incorrect($t0|addr1: address, $t1|addr2: address): B::T { var $t2|v: B::T var $t3|x0: u64 var $t4|x1: u64 var $t5: u64 var $t6: bool var $t7: num var $t8: B::T var $t9: u64 var $t10: bool 0: assume CanModify($t1) 1: $t5 := opaque begin: A::read_at($t1) 2: assume Identical($t6, Not(exists($t1))) 3: if ($t6) goto 4 else goto 7 4: label L4 5: trace_abort($t7) 6: goto 26 7: label L3 8: assume WellFormed($t5) 9: assume Eq($t5, select A::S.x(global($t1))) 10: $t5 := opaque end: A::read_at($t1) # VC: caller does not have permission to modify `B::T` at given address at tests/spec_instrumentation/modifies.move:65:17+9 11: assert CanModify($t0) 12: $t8 := move_from($t0) on_abort goto 26 with $t7 13: $t9 := opaque begin: A::read_at($t1) 14: assume Identical($t10, Not(exists($t1))) 15: if ($t10) goto 16 else goto 19 16: label L6 17: trace_abort($t7) 18: goto 26 19: label L5 20: assume WellFormed($t9) 21: assume Eq($t9, select A::S.x(global($t1))) 22: $t9 := opaque end: A::read_at($t1) 23: assert Eq($t5, $t9) 24: label L1 25: return $t8 26: label L2 27: abort($t7) } [variant verification] public fun B::move_to_test_incorrect($t0|account: signer, $t1|addr2: address) { var $t2|x0: u64 var $t3|x1: u64 var $t4: u64 var $t5: bool var $t6: num var $t7: u64 var $t8: B::T var $t9: u64 var $t10: bool 0: assume CanModify($t1) 1: $t4 := opaque begin: A::read_at($t1) 2: assume Identical($t5, Not(exists($t1))) 3: if ($t5) goto 4 else goto 7 4: label L4 5: trace_abort($t6) 6: goto 28 7: label L3 8: assume WellFormed($t4) 9: assume Eq($t4, select A::S.x(global($t1))) 10: $t4 := opaque end: A::read_at($t1) 11: $t7 := 2 12: $t8 := pack B::T($t7) # VC: caller does not have permission to modify `B::T` at given address at tests/spec_instrumentation/modifies.move:52:9+7 13: assert CanModify($t0) 14: move_to($t8, $t0) on_abort goto 28 with $t6 15: $t9 := opaque begin: A::read_at($t1) 16: assume Identical($t10, Not(exists($t1))) 17: if ($t10) goto 18 else goto 21 18: label L6 19: trace_abort($t6) 20: goto 28 21: label L5 22: assume WellFormed($t9) 23: assume Eq($t9, select A::S.x(global($t1))) 24: $t9 := opaque end: A::read_at($t1) 25: assert Eq($t4, $t9) 26: label L1 27: return () 28: label L2 29: abort($t6) } [variant verification] public fun B::mutate_S_test1_incorrect($t0|addr1: address, $t1|addr2: address) { var $t2|x0: u64 var $t3|x1: u64 var $t4: u64 var $t5: bool var $t6: num var $t7: bool var $t8: u64 var $t9: bool 0: assume Neq
($t0, $t1) 1: assume CanModify($t1) 2: $t4 := opaque begin: A::read_at($t1) 3: assume Identical($t5, Not(exists($t1))) 4: if ($t5) goto 5 else goto 8 5: label L4 6: trace_abort($t6) 7: goto 36 8: label L3 9: assume WellFormed($t4) 10: assume Eq($t4, select A::S.x(global($t1))) 11: $t4 := opaque end: A::read_at($t1) # VC: caller does not have permission to modify `A::S` at given address at tests/spec_instrumentation/modifies.move:79:9+19 12: assert CanModify($t0) 13: opaque begin: A::mutate_at($t0) 14: assume Identical($t7, Not(exists($t0))) 15: if ($t7) goto 16 else goto 19 16: label L6 17: trace_abort($t6) 18: goto 36 19: label L5 20: modifies global($t0) 21: assume Eq(select A::S.x(global($t0)), 2) 22: opaque end: A::mutate_at($t0) 23: $t8 := opaque begin: A::read_at($t1) 24: assume Identical($t9, Not(exists($t1))) 25: if ($t9) goto 26 else goto 29 26: label L8 27: trace_abort($t6) 28: goto 36 29: label L7 30: assume WellFormed($t8) 31: assume Eq($t8, select A::S.x(global($t1))) 32: $t8 := opaque end: A::read_at($t1) 33: assert Eq($t4, $t8) 34: label L1 35: return () 36: label L2 37: abort($t6) } [variant verification] public fun B::mutate_S_test2_incorrect($t0|addr: address) { var $t1|x0: u64 var $t2|x1: u64 var $t3: u64 var $t4: bool var $t5: num var $t6: bool var $t7: u64 var $t8: bool 0: assume CanModify($t0) 1: $t3 := opaque begin: A::read_at($t0) 2: assume Identical($t4, Not(exists($t0))) 3: if ($t4) goto 4 else goto 7 4: label L4 5: trace_abort($t5) 6: goto 35 7: label L3 8: assume WellFormed($t3) 9: assume Eq($t3, select A::S.x(global($t0))) 10: $t3 := opaque end: A::read_at($t0) # VC: caller does not have permission to modify `A::S` at given address at tests/spec_instrumentation/modifies.move:92:9+18 11: assert CanModify($t0) 12: opaque begin: A::mutate_at($t0) 13: assume Identical($t6, Not(exists($t0))) 14: if ($t6) goto 15 else goto 18 15: label L6 16: trace_abort($t5) 17: goto 35 18: label L5 19: modifies global($t0) 20: assume Eq(select A::S.x(global($t0)), 2) 21: opaque end: A::mutate_at($t0) 22: $t7 := opaque begin: A::read_at($t0) 23: assume Identical($t8, Not(exists($t0))) 24: if ($t8) goto 25 else goto 28 25: label L8 26: trace_abort($t5) 27: goto 35 28: label L7 29: assume WellFormed($t7) 30: assume Eq($t7, select A::S.x(global($t0))) 31: $t7 := opaque end: A::read_at($t0) 32: assert Eq($t3, $t7) 33: label L1 34: return () 35: label L2 36: abort($t5) } [variant verification] public fun B::mutate_at_test_incorrect($t0|addr1: address, $t1|addr2: address) { var $t2|t: &mut B::T var $t3|x0: u64 var $t4|x1: u64 var $t5: u64 var $t6: bool var $t7: num var $t8: &mut B::T var $t9: u64 var $t10: &mut u64 var $t11: u64 var $t12: bool 0: assume CanModify($t1) 1: $t5 := opaque begin: A::read_at($t1) 2: assume Identical($t6, Not(exists($t1))) 3: if ($t6) goto 4 else goto 7 4: label L4 5: trace_abort($t7) 6: goto 31 7: label L3 8: assume WellFormed($t5) 9: assume Eq($t5, select A::S.x(global($t1))) 10: $t5 := opaque end: A::read_at($t1) # VC: caller does not have permission to modify `B::T` at given address at tests/spec_instrumentation/modifies.move:38:17+17 11: assert CanModify($t0) 12: $t8 := borrow_global($t0) on_abort goto 31 with $t7 13: $t9 := 2 14: $t10 := borrow_field.x($t8) 15: write_ref($t10, $t9) 16: write_back[Reference($t8).x (u64)]($t10) 17: write_back[B::T@]($t8) 18: $t11 := opaque begin: A::read_at($t1) 19: assume Identical($t12, Not(exists($t1))) 20: if ($t12) goto 21 else goto 24 21: label L6 22: trace_abort($t7) 23: goto 31 24: label L5 25: assume WellFormed($t11) 26: assume Eq($t11, select A::S.x(global($t1))) 27: $t11 := opaque end: A::read_at($t1) 28: assert Eq($t5, $t11) 29: label L1 30: return () 31: label L2 32: abort($t7) } ==== spec-instrumenter input specs ==== fun A::mutate_at[baseline] spec { ensures Eq(select A::S.x(global($t0)), 2); aborts_if Not(exists($t0)); modifies global($t0); } fun A::mutate_at[verification] spec { ensures Eq(select A::S.x(global($t0)), 2); aborts_if Not(exists($t0)); modifies global($t0); } fun A::read_at[baseline] spec { aborts_if Not(exists($t0)); ensures Eq(result0(), select A::S.x(global($t0))); } fun A::read_at[verification] spec { aborts_if Not(exists($t0)); ensures Eq(result0(), select A::S.x(global($t0))); } fun B::move_from_test_incorrect[baseline] spec { modifies global($t1); } fun B::move_from_test_incorrect[verification] spec { modifies global($t1); } fun B::move_to_test_incorrect[baseline] spec { modifies global($t1); } fun B::move_to_test_incorrect[verification] spec { modifies global($t1); } fun B::mutate_S_test1_incorrect[baseline] spec { requires Neq
($t0, $t1); modifies global($t1); } fun B::mutate_S_test1_incorrect[verification] spec { requires Neq
($t0, $t1); modifies global($t1); } fun B::mutate_S_test2_incorrect[baseline] spec { modifies global($t0); } fun B::mutate_S_test2_incorrect[verification] spec { modifies global($t0); } fun B::mutate_at_test_incorrect[baseline] spec { modifies global($t1); } fun B::mutate_at_test_incorrect[verification] spec { modifies global($t1); }