let get_internal =
Internals.memo
(fun kf ->
!Value.compute ();
let result_with_spurious_locals =
match kf.fundec with
| Definition (f,_) ->
(try
Stack.iter
(fun g -> if kf == g then begin
Cil.warn
"recursive call detected during out analysis of %a. Ignoring it is safe if the value analysis suceeded without problem."
Kernel_function.pretty_name kf;
raise Ignore
end
)
call_stack;
Stack.push kf call_stack;
let computer = new do_it in
ignore (visitFramacFunction (computer:>frama_c_visitor) f);
let _ = Stack.pop call_stack in
computer#result
with Ignore -> Zone.bottom)
| Declaration (_,_,_,_) ->
let behaviors =
!Value.valid_behaviors kf (Value.get_initial_state kf)
in
let assigns = Ast_info.merge_assigns behaviors in
(match assigns with
WritesAny ->
Zone.bottom
| Writes assigns ->
(try
let state = Value.get_initial_state kf in
List.fold_left
(fun acc (loc,_) ->
let c = loc.it_content in
if (Logic_utils.is_result c)
then acc
else
let loc =
!Properties.Interp.loc_to_loc ~result:None state c
in
Zone.join acc (Locations.valid_enumerate_bits loc))
Zone.bottom
assigns
with Invalid_argument "not an lvalue" ->
Cil.warn
"unsupported assigns clause for function %a; Ignoring it."
Kernel_function.pretty_name kf;
Zone.bottom))
in
Zone.filter_base (Db.accept_base_internal kf) result_with_spurious_locals
)