GaloisInc / saw-script

The SAW scripting language.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

`saw-core-what4`: Support SMT arrays with record/tuple elements

RyanGlScott opened this issue · comments

SAW currently crashes if you try to load this spec:

#include <stdint.h>

uint32_t f(uint16_t x) {
    return 0;
}

uint32_t g(int b) {
    if (b) {
        return f(27);
    } else {
        return f(42);
    }
}
enable_experimental;

import "Array.cry";

ghost <- llvm_declare_ghost_state "ghost";

let f_spec = do {
    arr <- llvm_fresh_cryptol_var "arr" {| Array [16] ([32], [64]) |};
    llvm_ghost_value ghost arr;
    x <- llvm_fresh_var "x" (llvm_int 16);

    llvm_execute_func [llvm_term x];

    llvm_return (llvm_term {{ (arrayLookup arr x).0 }});
};

let g_spec = do {
    arr <- llvm_fresh_cryptol_var "arr" {| Array [16] ([32], [64]) |};
    llvm_ghost_value ghost arr;
    b <- llvm_fresh_var "b" (llvm_int 32);

    llvm_execute_func [llvm_term b];

    llvm_return (llvm_term {{ if b != 0 then (arrayLookup arr 27).0 else (arrayLookup arr 42).0 }});
};

m <- llvm_load_module "test.bc";

f_ov <- llvm_unsafe_assume_spec m "f" f_spec;
llvm_verify m "g" [f_ov] false g_spec (w4_unint_z3 []);
$ ~/Software/saw-1.0/bin/saw test.saw



[18:48:59.215] Loading file "/home/ryanglscott/Documents/Hacking/Haskell/sandbox/saw-script/test.saw"
[18:48:59.337] Assume override f
[18:48:59.375] Verifying g ...
[18:48:59.375] Simulating g ...
[18:48:59.375] Registering overrides for `f`
[18:48:59.375]   variant `Symbol "f"`
[18:48:59.376] Matching 1 overrides of  f ...
[18:48:59.376] Branching on 1 override variants of f ...
[18:48:59.376] Applied override! f
[18:48:59.376] Matching 1 overrides of  f ...
[18:48:59.376] Branching on 1 override variants of f ...
[18:48:59.376] Applied override! f
[18:48:59.377] Checking proof obligations g ...
[18:48:59.378] You have encountered a bug in SAWCoreWhat4's implementation.
*** Please create an issue at https://github.com/GaloisInc/saw-core-what4/issues

%< --------------------------------------------------- 
  Revision:  f64fbe4c642530eca21c81ccd84e0e8c43e44135
  Branch:    release-1.0 (uncommited files present)
  Location:  Verifier.SAW.Simulator.What4.Panic.arrayLookup
  Message:   argument type mismatch
CallStack (from HasCallStack):
  panic, called at src/Verifier/SAW/Simulator/What4/Panic.hs:14:9 in saw-core-what4-0.2-inplace:Verifier.SAW.Simulator.What4.Panic
  panic, called at src/Verifier/SAW/Simulator/What4.hs:638:8 in saw-core-what4-0.2-inplace:Verifier.SAW.Simulator.What4
%< --------------------------------------------------- 

The root cause is this code:

symExprToValue ::
IsExpr (SymExpr sym) =>
W.BaseTypeRepr tp ->
W.SymExpr sym tp ->
Maybe (SValue sym)
symExprToValue tp expr = case tp of
BaseBoolRepr -> Just $ VBool expr
BaseIntegerRepr -> Just $ VInt expr
(BaseBVRepr w) -> Just $ withKnownNat w $ VWord $ DBV expr
(BaseArrayRepr (Ctx.Empty Ctx.:> _) _) -> Just $ VArray $ SArray expr
_ -> Nothing

This is missing a case for BaseStructRepr, which is what SAW desugars Cryptol's record/tuple types into. That being said, adding such a case is not entirely straightforward. I made an attempt at this in this commit, but this ended up generating the wrong SMT code! The problem is that this Cryptol type:

([32], [64])

Will desugar into this What4 type:

BaseStructRepr [BaseBVRepr 64, BaseBVRepr 32]

This is definitely not the order I expected it to be in, and I suspect that I may need to carefully reverse some things in my earlier commit in order to make the code correct. I haven't had time to investigate this more deeply than that, unfortunately.