let returned_value kf return_type state =
let return_type = unrollType return_type in
match return_type with
| TComp _ when is_fully_arithmetic return_type ->
Cvalue.V.top_int, state
| TPtr(typ,_) | (TComp _ as typ) -> begin
let new_base =
Returned_Val.memo
(fun kf ->
let new_varinfo =
makeGlobalVar
~logic:true
(Cabs2cil.fresh_global
("alloced_return_" ^ Kernel_function.get_name kf))
typ
in
let new_offsetmap =
Cvalue.V_Offsetmap.sized_zero (memory_size ())
in
Cvalue.Default_offsetmap.create_initialized_var
new_varinfo
(Base.Known (Int.zero, max_bit_address ()))
new_offsetmap)
kf
in
let initial_value =
if isIntegralType typ
then Cvalue.V.top_int
else if isFloatingType typ
then Cvalue.V.top_float
else
Cvalue.V.inject_top_origin
(Origin.Leaf (LocationSetLattice.currentloc_singleton()))
(Cvalue.V.Top_Param.O.singleton new_base)
in
let modu = try
if isVoidType typ then Int.one else Int_Base.project (osizeof typ)
with Int_Base.Error_Top ->
assert (Cvalue.V.is_isotropic initial_value);
Int.one
in
let returned_loc =
try
Location_Bytes.inject
new_base
(Ival.filter_ge_int (Some Int.zero)
(Ival.create_all_values
~signed:true
~modu
~size:(sizeofpointer ())))
with Int_Base.Error_Top ->
Location_Bytes.inject
new_base
Ival.top
in
let state =
Cvalue.Model.create_initial
~base:new_base
~v:initial_value ~modu:(Int.mul Int.eight modu) ~state
in
returned_loc, state
end
| TInt _ | TEnum _ -> Cvalue.V.top_int, state
| TFloat _ -> Cvalue.V.top_float, state
| TBuiltin_va_list _ ->
Cvalue.V.top_leaf_origin()
,
state
| TVoid _ -> Cvalue.V.top , state
| TFun _ | TNamed _ | TArray _ -> assert false