--detect-vacuity doesn't work with the MIR backend
sauclovian-g opened this issue · comments
saw --detect-vacuity foo.saw doesn't detect unsatisfiable preconditions (such as a == 0 /\ b == 1 /\ a == b) when using the MIR (Rust) backend.
Here is a test case:
// test.c
void fun_c() {}
// test.rs
pub fn fun_rs() {}
// test.saw
enable_experimental;
let fun_c_spec = do {
x <- llvm_fresh_var "x" (llvm_int 32);
llvm_precond {{ x != x }};
llvm_execute_func [];
};
llvm_mod <- llvm_load_module "test.bc";
llvm_verify llvm_mod "fun_c" [] false fun_c_spec z3;
let fun_rs_spec = do {
x <- mir_fresh_var "x" mir_u32;
mir_precond {{ x != x }};
mir_execute_func [];
};
mir_mod <- mir_load_module "test.linked-mir.json";
mir_verify mir_mod "test::fun_rs" [] false fun_rs_spec z3;
$ clang -g -emit-llvm -c test.c
$ saw-rustc test.rs
$ ~/Software/saw-1.1/bin/saw test.saw --detect-vacuity
[00:07:29.925] Loading file "test.saw"
[00:07:29.963] Verifying fun_c ...
[00:07:29.982] Contradiction detected! Computing minimal core of contradictory assumptions:
[00:07:30.017] ConditionMetadata {conditionLoc = ProgramLoc {plFunction = llvm_precond, plSourceLoc = /home/ryanscott/Documents/Hacking/SAW/test.saw:6:3}, conditionTags = fromList [], conditionType = "specification assertion", conditionContext = ""}: precondition
[00:07:30.017] Because of the contradiction, the following proofs may be vacuous.
[00:07:30.017] Simulating fun_c ...
[00:07:30.017] Checking proof obligations fun_c ...
[00:07:30.017] Proof succeeded! fun_c
[00:07:30.057] Verifying test/569fd098::fun_rs[0] ...
[00:07:30.068] Simulating test/569fd098::fun_rs[0] ...
[00:07:30.068] Checking proof obligations test/569fd098::fun_rs[0] ...
[00:07:30.068] Proof succeeded! test/569fd098::fun_rs[0]
Note that SAW prints Contradiction detected!
for the llvm_verify
invocation, but not the mir_verify
one.
The reason this happens is because --detect-vacuity
only does anything in the LLVM backend:
saw-script/src/SAWScript/Crucible/LLVM/Builtins.hs
Lines 638 to 639 in 2a3ca89
The MIR backend (as well as the JVM backend) simply don't perform this check. Most of the code in the checkAssumptionsForContradictions
function is not LLVM-specific, and we could reasonably port it over to other backends:
saw-script/src/SAWScript/Crucible/LLVM/Builtins.hs
Lines 1030 to 1042 in 2a3ca89
We'd need to perform some mild refactoring to get rid of the LLVMCrucibleContext
argument, but I don't expect that to be difficult.