let find_prm_in_env env ?tr counter f x =
let kf =
try Globals.Functions.find_by_name f
with Not_found -> Aorai_option.abort "Unknown function %s" f
in
if Datatype.String.equal x "return" ||
Datatype.String.equal x "\\result" then begin
let rt = Kernel_function.get_return_type kf in
if Cil.isVoidType rt then
Aorai_option.abort
"%a returns void. %s().%s is meaningless in this context"
Kernel_function.pretty kf f x;
let env,cond = add_current_event (EReturn kf) env (TReturn kf) in
env,
Logic_const.term (TLval (TResult rt,TNoOffset)) (Ctype rt),
cond
end else begin
let rec treat_env top =
function
| ECall(kf',_,_) as event :: _
when Kernel_function.equal kf kf'->
(match check_one top event counter x with
Some lv ->
env, lv, TTrue
| None ->
Aorai_option.abort "Function %s has no parameter %s" f x)
| (ENone | EReturn _ | EMulti | ECOR _ | ECall _ )
:: tl ->
treat_env false tl
| [] ->
let env, cond =
match tr with
None ->
Aorai_option.abort
"Function %s is not in the call stack. Cannot use its parameter %s here" f x
| Some tr ->
add_current_event
(ECall (kf, Cil_datatype.Varinfo.Hashtbl.create 3, tr))
env
(TCall (kf,None))
in
let vi =
try Globals.Vars.find_from_astinfo x (VFormal kf)
with Not_found ->
Aorai_option.abort "Function %s has no parameter %s" f x
in
env, Logic_const.tvar (Cil.cvar_to_lvar vi), cond
in treat_env true env
end