|
| 1 | +// This is a regression test for saw-script issue #900; it tests whether |
| 2 | +// `jvm_verify` will successfully verify a spec that does not specify a |
| 3 | +// new value for a field, when the method actually does modify that |
| 4 | +// field. For soundness of compositional verification, it is required |
| 5 | +// that such a verification will fail. |
| 6 | +// https://github.com/GaloisInc/saw-script/issues/900 |
| 7 | + |
| 8 | +enable_experimental; |
| 9 | +c <- java_load_class "Test"; |
| 10 | + |
| 11 | +let set_spec_1 = |
| 12 | + do { |
| 13 | + this <- jvm_alloc_object "Test"; |
| 14 | + x <- jvm_fresh_var "x" java_int; |
| 15 | + jvm_execute_func [this, jvm_term x]; |
| 16 | + jvm_field_is this "b" (jvm_term x); |
| 17 | + }; |
| 18 | + |
| 19 | +let set_spec_2 = |
| 20 | + do { |
| 21 | + this <- jvm_alloc_object "Test"; |
| 22 | + x <- jvm_fresh_var "x" java_int; |
| 23 | + jvm_execute_func [this, jvm_term x]; |
| 24 | + jvm_static_field_is "a" (jvm_term x); |
| 25 | + }; |
| 26 | + |
| 27 | +set_ov_1 <- jvm_unsafe_assume_spec c "set" set_spec_1; |
| 28 | +set_ov_2 <- jvm_unsafe_assume_spec c "set" set_spec_2; |
| 29 | + |
| 30 | +let one = jvm_term {{ 1:[32] }}; |
| 31 | +let two = jvm_term {{ 2:[32] }}; |
| 32 | + |
| 33 | +// A correct spec for test_a. |
| 34 | +jvm_verify c "test_a" [] false |
| 35 | + do { |
| 36 | + this <- jvm_alloc_object "Test"; |
| 37 | + jvm_static_field_is "a" one; |
| 38 | + jvm_execute_func [this, two]; |
| 39 | + jvm_static_field_is "a" two; |
| 40 | + jvm_field_is this "b" two; |
| 41 | + jvm_return two; |
| 42 | + } |
| 43 | + z3; |
| 44 | + |
| 45 | +// An incorrect spec for test_a, which can be proven using the bogus |
| 46 | +// spec set_ov_1. |
| 47 | +jvm_verify c "test_a" [set_ov_1] false |
| 48 | + do { |
| 49 | + this <- jvm_alloc_object "Test"; |
| 50 | + jvm_static_field_is "a" one; |
| 51 | + jvm_execute_func [this, two]; |
| 52 | + jvm_static_field_is "a" one; |
| 53 | + jvm_field_is this "b" two; |
| 54 | + jvm_return one; |
| 55 | + } |
| 56 | + z3; |
| 57 | + |
| 58 | +// A correct spec for test_b. |
| 59 | +jvm_verify c "test_b" [] false |
| 60 | + do { |
| 61 | + this <- jvm_alloc_object "Test"; |
| 62 | + jvm_static_field_is "a" one; |
| 63 | + jvm_field_is this "b" one; |
| 64 | + jvm_execute_func [this, two]; |
| 65 | + jvm_static_field_is "a" two; |
| 66 | + jvm_field_is this "b" two; |
| 67 | + jvm_return two; |
| 68 | + } |
| 69 | + z3; |
| 70 | + |
| 71 | +// An incorrect spec for test_b, which can be proven using the bogus |
| 72 | +// spec set_ov_2. |
| 73 | +jvm_verify c "test_b" [set_ov_2] false |
| 74 | + do { |
| 75 | + this <- jvm_alloc_object "Test"; |
| 76 | + jvm_static_field_is "a" one; |
| 77 | + jvm_field_is this "b" one; |
| 78 | + jvm_execute_func [this, two]; |
| 79 | + jvm_static_field_is "a" two; |
| 80 | + jvm_field_is this "b" one; |
| 81 | + jvm_return one; |
| 82 | + } |
| 83 | + z3; |
| 84 | + |
| 85 | +// It should be impossible to verify the bogus set_spec_1. |
| 86 | +// FIXME: this should fail |
| 87 | +jvm_verify c "set" [] false set_spec_1 z3; |
| 88 | + |
| 89 | +// It should be impossible to verify the bogus set_spec_2. |
| 90 | +// FIXME: this should fail |
| 91 | +jvm_verify c "set" [] false set_spec_2 z3; |
0 commit comments