let rec status_of_deps values state =
if S.use_ctrl_dependencies && !last_stmt != dummyStmt then begin
let stmt = !last_stmt in
let _, kf = Kernel_function.find_from_sid stmt.sid in
let pdg = !Pdg.get kf in
let nodes = !Pdg.find_simple_stmt_nodes pdg stmt in
let deps =
match nodes with
| [] -> []
| n :: _ -> !Pdg.direct_ctrl_dpds pdg n
in
let status_of_dep dep =
match dep.skind with
| If(e, _, _, _) | Switch(e, _, _, _) ->
find_exp_status ~with_deps:false values state e
| Block _ | UnspecifiedSequence _
| Instr (Asm _) ->
S.bottom
| _ ->
assert false
in
List.fold_left
(fun acc n ->
let s =
match !Pdg.node_key n with
| PdgIndex.Key.Stmt s -> s
| PdgIndex.Key.SigCallKey (_id,
(PdgIndex.Signature.In PdgIndex.Signature.InCtrl)) ->
dummyStmt
| PdgIndex.Key.SigKey _k -> dummyStmt
| _ ->
Options.fatal "unknown PDG key: %a"
PdgIndex.Key.pretty (!Pdg.node_key n)
in
S.join acc (status_of_dep s))
(try (Stack.top call_stack).deps with Stack.Empty -> S.bottom)
deps
end else
S.bottom
and join_deps values state = S.join (status_of_deps values state)
and find_loc_or_status ?(with_deps=true) values state e =
let status s =
Status
(if with_deps then S.join s (status_of_deps values state) else s)
in
match (stripInfo e).enode with
| Info _ -> assert false
| Const _ | SizeOf _ | SizeOfStr _ | AlignOf _ ->
status S.constant
| Lval lv ->
let e, subst_occured = Subst.lval ~trans:true lv state.subst in
if subst_occured then
find_loc_or_status ~with_deps values state e
else
Location (lval_to_loc values lv)
| AddrOf _lv | StartOf _lv ->
Options.warning ~once:true ~current:true
"address expression detected: suboptimical case in this version";
Status S.top
| CastE(ty, e) ->
let s = L.type_attributes2state S.bottom ty in
let ls = find_loc_or_status ~with_deps values state e in
if S.equal s S.bottom then
ls
else
(match ls with
| Status _ ->
status s
| Location l ->
status (S.join s (L.snd (find_loc_status state l))))
| SizeOfE e | AlignOfE e | UnOp(_, e, _) ->
find_loc_or_status ~with_deps values state e
| BinOp((PlusPI | IndexPI | MinusPI | MinusPP), _e1, _e2, TPtr _) ->
Options.warning ~once:true ~current:true
"arithmetic pointer expression detected: suboptimital case in this version";
Status S.top
| BinOp((PlusPI | IndexPI | MinusPI | MinusPP), _e1, _e2, _) ->
assert false
| BinOp(_, e1, e2, _) ->
let s1 = find_exp_status ~with_deps values state e1 in
let s2 = find_exp_status ~with_deps values state e2 in
status (S.join s1 s2)
and find_exp_status ?(with_deps=true) values state e =
match find_loc_or_status ~with_deps values state e with
| Status s -> s
| Location l -> find_loc_status_with_deps ~with_deps state l