GaloisInc / saw-script

The SAW scripting language.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

MIR: Enum value panics when payload is a `repr(transparent)` struct with a type error

RyanGlScott opened this issue · comments

Given this Rust code:

// test.rs
#[repr(transparent)]
pub struct S(u32);

pub enum E {
    E1(S),
    E2,
}

pub fn f(e: E) -> E {
    e
}

I tried to write this SAW spec:

// test.saw
enable_experimental;

m <- mir_load_module "test.linked-mir.json";

let s_adt = mir_find_adt m "test::S" [];
let e_adt = mir_find_adt m "test::E" [];

let f_spec = do {
  x <- mir_fresh_var "f::x" mir_u64;
  let s = mir_struct_value s_adt [mir_term x];
  let e = mir_enum_value e_adt "E1" [s];

  mir_execute_func [e];

  mir_return e;
};

mir_verify m "test::f" [] false f_spec z3;

This spec contains an error: the payload of S should be a u32, but I have supplied a mir_u64, not a mir_u32, in the SAW spec. Surprisingly, SAW doesn't catch this mistake, and it instead produces a rather ugly panic:

$ saw-rustc test.rs
$ ~/Software/saw-1.1/bin/saw test.saw
[20:30:18.899] Loading file "/home/ryanscott/Documents/Hacking/SAW/test.saw"
[20:30:18.903] Verifying test/c8ab1cdc::f[0] ...
[20:30:18.903] You have encountered a bug in SAW's implementation.
*** Please create an issue at https://github.com/GaloisInc/saw-script/issues

%< --------------------------------------------------- 
  Revision:  5c16c876f35f0abdf0b412a5387e220b15b7f990
  Branch:    release-1.1 (uncommited files present)
  Location:  resolveSetupVal
  Message:   Enum field shape mismatch
             Expected: [ReqField (TransparentShape (TyAdt test/c8ab1cdc::S[0]::_adtb7803c2264daf0ec[0] test/c8ab1cdc::S[0] (Substs [])) (PrimShape (TyUint B32) (BaseBVRepr 32)))]
             Actual: [ReqField (TransparentShape (TyAdt test/c8ab1cdc::S[0]::_adtb7803c2264daf0ec[0] test/c8ab1cdc::S[0] (Substs [])) (PrimShape (TyUint B64) (BaseBVRepr 64)))]
CallStack (from HasCallStack):
  panic, called at src/SAWScript/Panic.hs:27:9 in saw-script-1.1-inplace:SAWScript.Panic
  panic, called at src/SAWScript/Crucible/MIR/ResolveSetupValue.hs:458:21 in saw-script-1.1-inplace:SAWScript.Crucible.MIR.ResolveSetupValue
%< --------------------------------------------------- 

The use of #[repr(transparent)] is important. If I comment out that line, SAW instead produces a much nicer type error:

$ saw-rustc test.rs
$ ~/Software/saw-1.1/bin/saw test.saw
[20:35:04.712] Loading file "/home/ryanscott/Documents/Hacking/SAW/test.saw"
[20:35:04.715] Verifying test/fb14f06a::f[0] ...
[20:35:04.715] Stack trace:
"mir_verify" (/home/ryanscott/Documents/Hacking/SAW/test.saw:19:1-19:11)
Struct field type mismatch
Field name: test/fb14f06a::S[0]::0[0]
Expected type: u32
Given type:    u64