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) =
(min_signed_number szTo, max_signed_number szTo)
in
let term = translate_C_expr_to_term ~cast:false expr in
let assertion_le () = assertion_le term maxType in
let assertion_ge () = assertion_ge term minType in
let ceval =
if simplify_constants then (
match get_expr_val expr with
| Some a64 ->
Some (My_bigint.ge a64 minType,
My_bigint.le a64 maxType)
| 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
fmt_warn_signed_downcast_assert
d_predicate_named assertion ;
[ assertion, Some Property_status.False_if_reachable ]
| (false,true) ->
let assertion = assertion_ge () in
if warning then
rte_warn
fmt_warn_signed_downcast_assert
d_predicate_named assertion ;
[ assertion_le (), Some Property_status.False_if_reachable ]
| (false,false) -> assert false )
else []
| _ -> []