Skip to content

Commit e65e067

Browse files
author
Eddy Westbrook
authored
Fix Rust to Heapster type translation for functions with no return value (#1445)
* fixed the IRT description generation to match the recent change that made the translation of bitvector permissions to just be bitvectors * updated xor_swap_rust example to use the Rust type in the SAW script * added a case to the Rust to Heapster translator to handle function types with no return value * whoops, forgot to update the bitcode file for xor_swap_rust * bugfix in the Rust to Heapster translator: empty return types need to be converted to unit, not to the empty struct * tweaked the error message for when Rust types do not translate correctly to the expected LLVM type
1 parent 2436cec commit e65e067

File tree

3 files changed

+21
-10
lines changed

3 files changed

+21
-10
lines changed
-3.2 KB
Binary file not shown.
+4-3
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
// This script expects to be run from the saw-script root directory
22
enable_experimental;
3-
43
env <- heapster_init_env "xor_swap_rust" "xor_swap_rust.bc";
54

6-
xor_swap_sym <- heapster_find_symbol env "13xor_swap_rust13xor_swap_rust";
5+
heapster_define_llvmshape env "i64" 64 "" "fieldsh(exists x:bv 64.eq(llvmword(x)))";
76

8-
heapster_typecheck_fun_rename env xor_swap_sym "xor_swap_rust" "(x:bv 64, y:bv 64). arg0: ptr((W,0) |-> eq(llvmword(x))), arg1: ptr((W,0) |-> eq(llvmword(y))) -o arg0: ptr((W,0) |-> exists z:bv 64.eq(llvmword(z))), arg1: ptr((W,0) |-> exists z:bv 64.eq(llvmword(z))), ret:true";
7+
xor_swap_sym <- heapster_find_symbol env "13xor_swap_rust13xor_swap_rust";
8+
heapster_typecheck_fun_rename env xor_swap_sym "xor_swap_rust" "<'a,'b> fn (x:&'a mut i64, y:&'b mut i64)";
9+
//heapster_typecheck_fun_rename env xor_swap_sym "xor_swap_rust" "(x:bv 64, y:bv 64). arg0: ptr((W,0) |-> eq(llvmword(x))), arg1: ptr((W,0) |-> eq(llvmword(y))) -o arg0: ptr((W,0) |-> exists z:bv 64.eq(llvmword(z))), arg1: ptr((W,0) |-> exists z:bv 64.eq(llvmword(z))), ret:true";
910

1011
heapster_export_coq env "xor_swap_rust_gen.v";

heapster-saw/src/Verifier/SAW/Heapster/RustTypes.hs

+17-7
Original file line numberDiff line numberDiff line change
@@ -673,12 +673,12 @@ un3SomeFunPerm args ret (Some3FunPerm fun_perm)
673673
return $ SomeFunPerm fun_perm
674674
un3SomeFunPerm args ret (Some3FunPerm fun_perm) =
675675
fail $ renderDoc $ vsep
676-
[ pretty "Incorrect LLVM type for function permission:"
676+
[ pretty "Unexpected LLVM type for function permission:"
677677
, permPretty emptyPPInfo fun_perm
678-
, pretty "Expected type:"
678+
, pretty "Actual LLVM type of function:"
679679
<+> PP.group (permPretty emptyPPInfo args) <+> pretty "=>"
680680
<+> PP.group (permPretty emptyPPInfo ret)
681-
, pretty "Actual type:"
681+
, pretty "Expected LLVM type of function:"
682682
<+> PP.group (permPretty emptyPPInfo (funPermArgs fun_perm))
683683
<+> pretty "=>"
684684
<+> PP.group (permPretty emptyPPInfo (funPermRet fun_perm)) ]
@@ -931,14 +931,24 @@ layoutFun abi arg_shs ret_sh =
931931
foldr appendArgLayout argLayout0 <$> mapM (layoutArgShape abi) arg_shs
932932
ret_layout_eith <- layoutArgShapeOrBlock abi ret_sh
933933
case ret_layout_eith of
934+
935+
-- Special case: if the return type is empty, use the unit type as the
936+
-- return type
937+
Right (ArgLayout Ctx.Empty _) ->
938+
funPerm3FromArgLayoutNoArgs args_layout UnitRepr ValPerm_True
939+
940+
-- Special case: if the return type is a single field, remove the struct
941+
-- type and just use the type of that single field
934942
Right (ArgLayout (Ctx.Empty Ctx.:> ret_tp)
935943
(argLayoutPerm1ToPerm -> ret_p)) ->
936-
-- Special case: if the return type is a single field, remove the
937-
-- struct type and just use the type of that single field
938944
funPerm3FromArgLayoutNoArgs args_layout ret_tp ret_p
945+
946+
-- If the return type can be laid out as a struct type, then do so
939947
Right (ArgLayout ret_ctx ret_p) ->
940948
funPerm3FromArgLayoutNoArgs args_layout (StructRepr ret_ctx)
941949
(argLayoutPermToPerm ret_p)
950+
951+
-- Otherwise add an extra pointer argument used as an out variable
942952
Left bp ->
943953
funPerm3FromArgLayout args_layout
944954
(extend Ctx.empty knownRepr)
@@ -1088,13 +1098,13 @@ rsConvertMonoFun w span abi ls fn_tp =
10881098
rsConvertFun :: (1 <= w, KnownNat w) => prx w ->
10891099
Abi -> Generics Span -> FnDecl Span -> RustConvM Some3FunPerm
10901100
rsConvertFun w abi (Generics ldefs _tparams@[]
1091-
(WhereClause [] _) _) (FnDecl args (Just ret_tp) False _) =
1101+
(WhereClause [] _) _) (FnDecl args maybe_ret_tp False _) =
10921102
fmap (\ret ->
10931103
tracePretty (pretty "rsConvertFun returning:" <+>
10941104
permPretty emptyPPInfo ret) ret) $
10951105
withLifetimes ldefs $
10961106
do arg_shapes <- mapM (rsConvert w) args
1097-
ret_shape <- rsConvert w ret_tp
1107+
ret_shape <- maybe (return PExpr_EmptyShape) (rsConvert w) maybe_ret_tp
10981108
layoutFun abi arg_shapes ret_shape
10991109
rsConvertFun _ _ _ _ = fail "rsConvertFun: unsupported Rust function type"
11001110

0 commit comments

Comments
 (0)