let get_downcast_assertion
~simplify_constants:simplify_constants
~warning:warning
cast_typ expr =
let e_typ = Cil.typeOf expr
in
match e_typ with
| TInt (_,_) ->
let szTo = bitsSizeOf cast_typ
and szFrom = bitsSizeOf e_typ
in
if (szTo < szFrom) then
let (minType,maxType) = (get_signed_min szTo, get_signed_max szTo)
in let term = translate_C_expr_to_term ~cast:false expr in
let assertion_le () = assertion_le term maxType
and assertion_ge () = assertion_ge term minType
in
let ceval =
if simplify_constants then (
match get_expr_val expr with
| Some a64 ->
Some (Int64.compare a64 minType >= 0,
Int64.compare a64 maxType <= 0)
| None -> None
) else None
in match ceval with
| None ->
let full_assertion () =
Logic_const.pand (assertion_le (), assertion_ge ())
in [ (full_assertion (), None) ]
| Some (emin,emax) -> (
match (emin,emax) with
| (true,true) -> []
| (true,false) ->
let assertion = assertion_le () in
if warning then
rte_warn
"signed downcast assert broken: %a"
d_predicate_named assertion
;
[ (assertion, Some (make_check_false ())) ]
| (false,true) ->
let assertion = assertion_ge () in
if warning then
rte_warn
"signed downcast assert broken: %a"
d_predicate_named assertion
;
[ (assertion_le (), Some (make_check_false ())) ]
| (false,false) -> assert false
)
else []
| _ -> []