let isCrossableAtInit tr func =
let rec isCross = function
| POr (c1, c2) ->
(isCross c1) || (isCross c2)
| PAnd (c1, c2) ->
(isCross c1) && (isCross c2)
| PNot (c1) ->
not (isCross c1)
| PCall (s) ->
(func=s)
| PReturn (_) ->
false
| PCallOrReturn (s) ->
func=s
| PTrue ->
true
| PFalse ->
false
| PIndexedExp e ->
(evalExpAtInit (Data_for_aorai.get_exp_from_tmpident e))<>0
| PFuncReturn (_, _) -> false
| PFuncParam (e, f, _) -> if func=f then (evalExpAtInit (Data_for_aorai.get_exp_from_tmpident e))<>0 else false
and error_msg msg =
Aorai_option.fatal "Aorai plugin internal error. Status : %s. \n" msg;
and evalExpAtInit:Cil_types.exp -> int = fun e ->
match e.enode with
| Cil_types.Const (c) ->
begin
match c with
| Cil_types.CInt64(int64,_,_) -> Int64.to_int int64
| Cil_types.CStr (_)
| Cil_types.CWStr(_) -> error_msg "String values not supported into LTL expressions"
| Cil_types.CChr(c) -> Char.code c
| Cil_types.CReal (_,_,_) -> error_msg "Real values not supported into LTL expressions"
| Cil_types.CEnum {eival = exp} -> evalExpAtInit exp
end
| Cil_types.Lval (Cil_types.Var(vi),Cil_types.NoOffset) -> get_val_from_vi vi
| Cil_types.Lval (_) -> raise LazyInit
| Cil_types.UnOp (unop,exp,typ) ->
if not (Cil.isIntegralType typ) then
error_msg "Such operator not yet supported in LTL expressions"
else
begin
match unop with
| Cil_types.Neg -> (-(evalExpAtInit exp))
| Cil_types.BNot -> error_msg "Bitwise complement not supported in LTL expressions"
| Cil_types.LNot -> if (evalExpAtInit exp)=0 then 1 else 0
end
| Cil_types.BinOp (binop,exp1,exp2,typ) ->
if not (Cil.isIntegralType typ) then
error_msg "Such operator not yet supported in LTL expressions"
else
begin
match binop with
| Cil_types.PlusA -> (evalExpAtInit exp1) + (evalExpAtInit exp2)
| Cil_types.MinusA -> (evalExpAtInit exp1) - (evalExpAtInit exp2)
| Cil_types.Mult -> (evalExpAtInit exp1) * (evalExpAtInit exp2)
| Cil_types.Div -> (evalExpAtInit exp1) / (evalExpAtInit exp2)
| Cil_types.Mod -> error_msg "Modulo not yet supported in LTL expressions"
| Cil_types.PlusPI
| Cil_types.IndexPI
| Cil_types.MinusPI
| Cil_types.MinusPP -> error_msg "Pointer and array not yet supported in LTL expressions"
| Cil_types.Shiftlt
| Cil_types.Shiftrt -> error_msg "Shifts not yet supported in LTL expressions"
| Cil_types.Lt -> ( try
if (evalExpAtInit exp1) < (evalExpAtInit exp2) then 1 else 0
with
| LazyInit -> 1
| _ as e -> raise e )
| Cil_types.Gt ->( try
if (evalExpAtInit exp1) > (evalExpAtInit exp2) then 1 else 0
with
| LazyInit -> 1
| _ as e -> raise e)
| Cil_types.Le ->(try
if (evalExpAtInit exp1) <= (evalExpAtInit exp2) then 1 else 0
with
| LazyInit -> 1
| _ as e -> raise e)
| Cil_types.Ge ->(try
if (evalExpAtInit exp1) >= (evalExpAtInit exp2) then 1 else 0
with
| LazyInit -> 1
| _ as e -> raise e)
| Cil_types.Eq ->(try
if (evalExpAtInit exp1) = (evalExpAtInit exp2) then 1 else 0
with
| LazyInit -> 1
| _ as e -> raise e)
| Cil_types.Ne ->(try
if (evalExpAtInit exp1) <> (evalExpAtInit exp2) then 1 else 0
with
| LazyInit -> 1
| _ as e -> raise e)
| Cil_types.BAnd
| Cil_types.BXor
| Cil_types.BOr -> error_msg "Bitwise operations not supported in LTL expressions"
| Cil_types.LAnd ->(try
if (evalExpAtInit exp1)<>0 && (evalExpAtInit exp2)<>0 then 1 else 0
with
| LazyInit -> 1
| _ as e -> raise e )
| Cil_types.LOr ->(try
if (evalExpAtInit exp1)<>0 or (evalExpAtInit exp2)<>0 then 1 else 0
with
| LazyInit -> 1
| _ as e -> raise e )
end
| Cil_types.Info (exp,_) ->
evalExpAtInit exp
| Cil_types.CastE (_,exp) ->
Aorai_option.warning "Warning (Aorai plugin) CastE is not yet fully supported as a valid LTL expression. " ;
evalExpAtInit exp
| Cil_types.SizeOf (_)
| Cil_types.SizeOfE (_)
| Cil_types.SizeOfStr (_) ->
error_msg "Sizeof is not supported as a valid LTL expression"
| Cil_types.AlignOf (_)
| Cil_types.AlignOfE (_) ->
error_msg "AlignOf is not supported as a valid LTL expression"
| Cil_types.AddrOf (_) ->
error_msg "AddrOf is not yet supported as a valid LTL expression"
| Cil_types.StartOf(_) ->
error_msg "StartOf is not yet supported as a valid LTL expression"
and get_val_from_vi vi =
try
let ini=Globals.Vars.find vi in
match ini.Cil_types.init with
| None -> error_msg ("'"^(vi.Cil_types.vname)^"'Seems to not be initialized" )
| Some (Cil_types.SingleInit(exp)) -> evalExpAtInit exp
| Some (Cil_types.CompoundInit(_,_)) -> error_msg "Compound values not yet supported into LTL expressions"
with
| _ ->
error_msg ("initialisation of '"^(vi.Cil_types.vname)^"' not found")
in
isCross tr.cross