let initialize_var_using_type varinfo state =
CurrentLoc.set varinfo.vdecl;
let rec add_offsetmap depth v name_desc name typ offset_orig typ_orig state =
let typ = Cil.unrollType typ in
let loc = loc_of_typoffset v typ_orig offset_orig in
let must_initialize =
(not (hasAttribute "const" (typeAttrs typ))) ||
(Cvalue_type.V.equal
(Relations_type.Model.find ~with_alarms:CilE.warn_none_mode state loc)
Cvalue_type.V.top)
in
if not must_initialize
then state else
match typ with
| TInt _ | TEnum (_, _)->
Relations_type.Model.add_binding
~with_alarms:CilE.warn_none_mode
~exact:true
state
loc
Cvalue_type.V.top_int
| TFloat _ ->
Relations_type.Model.add_binding
~with_alarms:CilE.warn_none_mode
~exact:true
state
loc
Cvalue_type.V.top_float
| TFun _ ->
Relations_type.Model.add_binding
~with_alarms:CilE.warn_none_mode
~exact:true
state
loc
(Cvalue_type.V.top_leaf_origin ())
| TPtr (typ, _) as full_typ
when depth <= Value_parameters.AutomaticContextMaxDepth.get () ->
let attr = typeAttr full_typ in
if not (isVoidType typ) && not (isFunctionType typ) then
let i = match findAttribute "arraylen" attr with
| [AInt i] -> i
| _ -> Value_parameters.AutomaticContextMaxWidth.get ()
in
let pointed_typ = TArray(typ,Some (integer i),empty_size_cache (), [])
in
let hidden_var_name =
Cabs2cil.fresh_global ("star_" ^ name)
in
let name_desc = "*"^name_desc in
let hidden_var =
makeGlobalVar ~logic:true hidden_var_name pointed_typ
in
hidden_var.vdescr <- Some name_desc;
let hidden_base = Base.create_logic
hidden_var
(match Base.validity_from_type hidden_var with
| Base.Known (a,b)
when not (Value_parameters.AllocatedContextValid.get ()) ->
Base.Unknown (a,b)
| (Base.All | Base.Unknown _ | Base.Known _) as s -> s)
in
let state = add_offsetmap
(depth + 1)
hidden_base
name_desc
hidden_var_name
pointed_typ
NoOffset
pointed_typ
state
in
let value = Cvalue_type.V.inject hidden_base (Ival.zero)
in
let value =
if Value_parameters.AllocatedContextValid.get ()
then value
else Cvalue_type.V.join Cvalue_type.V.singleton_zero value
in
Relations_type.Model.add_binding
~with_alarms:CilE.warn_none_mode
~exact:true
state
loc
value
else
let hidden_var_name =
Cabs2cil.fresh_global ("star_" ^ name)
in
let name_desc = "*"^name_desc in
let hidden_var =
makeGlobalVar ~logic:true hidden_var_name typ
in
hidden_var.vdescr <- Some name_desc;
let hidden_base =
Base.create_logic
hidden_var
(if Value_parameters.AllocatedContextValid.get () then
Base.Known (Int.zero,Bit_utils.max_bit_address ())
else
Base.Unknown (Int.zero,Bit_utils.max_bit_address ()))
in
make_well (Bit_utils.max_bit_size ()) hidden_base state loc
| TArray (typ, len, _, _) ->
begin try
let size = lenOfArray len in
let state = ref state in
let treat_index (i : int) =
let offset =
addOffset
(Index (integer i, NoOffset))
offset_orig
in
let name = name ^ "_" ^ (string_of_int i) ^ "nth" in
let name_desc = name_desc ^ "[" ^ (string_of_int i) ^ "]" in
state := (add_offsetmap depth v
name_desc name typ
offset typ_orig !state)
in
for i = 0 to pred size do
treat_index i
done;
!state
with LenOfArray ->
Value_parameters.result ~once:true ~current:true "could not find a size for array";
state
end
| TComp ({cstruct=true;} as compinfo, _, _) ->
let treat_field (next_offset,state) field =
let new_offset = Field (field, NoOffset) in
let offset =
addOffset
new_offset
offset_orig
in
let field_offset,field_width = bitsOffset typ_orig offset in
let state =
if field_offset>next_offset then
let loc = make_loc
(Location_Bits.inject v (Ival.of_int next_offset))
(Int_Base.inject (Int.of_int (field_offset-next_offset)))
in
Relations_type.Model.add_binding_unspecified
state
loc
else state
in
field_offset+field_width,
add_offsetmap
depth
v
(name_desc ^ "." ^ field.fname)
(name^"__"^field.fname)
field.ftype
offset
typ_orig
state
in
begin try
let boff,bwidth = bitsOffset typ_orig offset_orig in
let last_offset,state= List.fold_left
treat_field
(boff,state)
compinfo.cfields
in
if last_offset<(boff+bwidth) then
let loc = make_loc
(Location_Bits.inject v (Ival.of_int last_offset))
(Int_Base.inject (Int.of_int (boff+bwidth-last_offset)))
in
Relations_type.Model.add_binding_unspecified
state
loc
else state
with Cil.SizeOfError _ -> state
end
| TComp ({cstruct=false}, _, _) when
is_fully_arithmetic typ
->
Relations_type.Model.add_binding
~with_alarms:CilE.warn_none_mode
~exact:true
state
loc
Cvalue_type.V.top_int
| TPtr _ when Value_parameters.AllocatedContextValid.get () ->
Relations_type.Model.add_binding
~with_alarms:CilE.warn_none_mode
~exact:true
state
loc
Cvalue_type.V.singleton_zero
| TBuiltin_va_list _ | TComp _ | TVoid _ | TPtr _ ->
let hidden_var_name =
Cabs2cil.fresh_global (name^"_WELL")
in
let hidden_var =
makeGlobalVar ~logic:true hidden_var_name charType
in
hidden_var.vdescr <- Some (name_desc^"_WELL");
let size = Bit_utils.max_bit_size () in
let hidden_base =
Base.create_logic
hidden_var
(Base.Known (Int.zero,Bit_utils.max_bit_address ()))
in
make_well size hidden_base state loc
| TNamed (_, _) -> assert false
in
add_offsetmap
0
(Base.create_varinfo varinfo)
varinfo.vname varinfo.vname varinfo.vtype NoOffset varinfo.vtype state