method vexpr exp =
debug "considering exp %a\n" Cil.d_exp exp ;
match exp.enode with
| BinOp((Div|Mod) as op,dividend,divisor,TInt(kind,_)) ->
if self#is_DoDivMod () then
self#queue_assertion
(get_divmod_assertion
~simplify_constants:(self#is_ConstFold ())
~warning:(self#is_Warning ())
divisor)
;
if (self#is_DoSignedOverflow ()) && (op = Div) && (isSigned kind) then
begin
self#queue_assertion
(get_signed_div_assertion
~simplify_constants:(self#is_ConstFold ())
~warning:(self#is_Warning ())
dividend divisor)
end
;
DoChildren
| BinOp((Shiftlt|Shiftrt) as shiftop,loperand,roperand,TInt(kind,_)) ->
if self#is_DoSignedOverflow () || self#is_DoUnsignedOverflow () then (
let (a, isOk) =
get_bitwise_shift_right_operand_assertion
~simplify_constants:(self#is_ConstFold ())
~warning:(self#is_Warning ())
exp roperand
in
self#queue_assertion a ;
if isOk
then
(
if (self#is_DoSignedOverflow ()) && (isSigned kind) then (
self#queue_assertion
(get_bitwise_shift_assertion
~simplify_constants:(self#is_ConstFold ())
~warning:(self#is_Warning ())
exp shiftop loperand roperand)
)
;
if self#is_DoUnsignedOverflow () &&
(shiftop = Shiftlt) && not(isSigned kind) then (
self#queue_assertion
(get_bitwise_lshift_unsigned_assertion
~simplify_constants:(self#is_ConstFold ())
~warning:(self#is_Warning ())
exp loperand roperand)
)
)
)
;
DoChildren
| BinOp((PlusA|MinusA|Mult)
as op,loperand,roperand,TInt(kind,_)) when (isSigned kind) ->
if (self#is_DoSignedOverflow ()) &&
not(self#is_in_skip_set exp.eid SkipBounding) then
self#queue_assertion
(get_multsubadd_assertion
~simplify_constants:(self#is_ConstFold ())
~warning:(self#is_Warning ())
exp op loperand roperand)
;
DoChildren
| BinOp((PlusA|MinusA|Mult)
as op,loperand,roperand,TInt(kind,_)) when not(isSigned kind) ->
if self#is_DoUnsignedOverflow () then
self#queue_assertion
(get_multsubadd_unsigned_assertion
~simplify_constants:(self#is_ConstFold ())
~warning:(self#is_Warning ())
exp op loperand roperand)
;
DoChildren
| UnOp(Neg,operand,TInt(kind,_)) when (isSigned kind) ->
if self#is_DoSignedOverflow () then
self#queue_assertion
(get_uminus_assertion
~simplify_constants:(self#is_ConstFold ())
~warning:(self#is_Warning ())
operand)
;
DoChildren
| Lval lval ->
if self#is_DoMemAccess () then (
debug "exp %a is an lval: validity of potential mem access checked\n"
Cil.d_exp exp ;
self#queue_assertion (get_lval_assertion lval)
)
;
DoChildren
| CastE (TInt (kind,_) as typ, e) when (isSigned kind) ->
if self#is_DoDownCast () then (
let downcast_asserts =
get_downcast_assertion
~simplify_constants:(self#is_ConstFold ())
~warning:(self#is_Warning ())
typ e
in match downcast_asserts with
| [] -> ()
| _ ->
self#queue_assertion downcast_asserts
;
self#add_to_skip_set e.eid SkipBounding
)
;
DoChildren
| StartOf _
| AddrOf _
| Info _
| UnOp _
| Const _
| CastE _
| BinOp _ -> DoChildren
| SizeOf _
| SizeOfE _
| SizeOfStr _
| AlignOf _
| AlignOfE _ -> SkipChildren