@ -116,66 +116,76 @@ let java_get_const_type_name (const: Const.t) : string =
let get_vararg_type_names tenv ( call_node : Procdesc . Node . t ) ( ivar : Pvar . t ) : string list =
let get_vararg_type_names tenv ( call_node : Procdesc . Node . t ) ( ivar : Pvar . t ) : string list =
(* Is this the node creating ivar? *)
(* Is this the node creating ivar? *)
let rec initializes_array instrs =
let initializes_array instrs =
match instrs with
instrs
| Sil . Call ( ( t1 , _ ) , Exp . Const ( Const . Cfun pn ) , _ , _ , _ )
| > List . find_map ~ f : ( function
:: Sil . Store ( Exp . Lvar iv , _ , Exp . Var t2 , _ ) :: is ->
| Sil . Store ( Exp . Lvar iv , _ , Exp . Var t2 , _ ) when Pvar . equal ivar iv ->
Pvar . equal ivar iv && Ident . equal t1 t2
Some t2
&& Typ . Procname . equal pn ( Typ . Procname . from_string_c_fun " __new_array " )
| _ ->
| | initializes_array is
None )
| _ :: is ->
| > Option . exists ~ f : ( fun t2 ->
initializes_array is
List . exists instrs ~ f : ( function
| _ ->
| Sil . Call ( ( t1 , _ ) , Exp . Const ( Const . Cfun pn ) , _ , _ , _ ) ->
false
Ident . equal t1 t2
&& Typ . Procname . equal pn ( Typ . Procname . from_string_c_fun " __new_array " )
| _ ->
false ) )
in
in
(* Get the type name added to ivar or None *)
(* Get the type name added to ivar or None *)
let added_type_name node =
let added_type_name instrs =
let rec nvar_type_name nvar instrs =
let nvar_type_name nvar =
match instrs with
instrs
| Sil . Load ( nv , Exp . Lfield ( _ , id , t ) , _ , _ ) :: _ when Ident . equal nv nvar ->
| > List . find_map ~ f : ( function
get_field_type_name tenv t id
| Sil . Load ( nv , e , t , _ ) when Ident . equal nv nvar ->
| Sil . Load ( nv , _ , t , _ ) :: _ when Ident . equal nv nvar ->
Some ( e , t )
Some ( get_type_name t )
| _ ->
| _ :: is ->
None )
nvar_type_name nvar is
| > Option . bind ~ f : ( function
| _ ->
| Exp . Lfield ( _ , id , t ) , _ ->
None
get_field_type_name tenv t id
| _ , t ->
Some ( get_type_name t ) )
in
in
let rec added_nvar array_nvar instrs =
let added_nvar array_nvar =
match instrs with
instrs
| Sil . Store ( Exp . Lindex ( Exp . Var iv , _ ) , _ , Exp . Var nvar , _ ) :: _
| > List . find_map ~ f : ( function
when Ident . equal iv array_nvar ->
| Sil . Store ( Exp . Lindex ( Exp . Var iv , _ ) , _ , Exp . Var nvar , _ )
nvar_type_name nvar ( Procdesc . Node . get_instrs node )
when Ident . equal iv array_nvar ->
| Sil . Store ( Exp . Lindex ( Exp . Var iv , _ ) , _ , Exp . Const c , _ ) :: _
Some ( nvar_type_name nvar )
when Ident . equal iv array_nvar ->
| Sil . Store ( Exp . Lindex ( Exp . Var iv , _ ) , _ , Exp . Const c , _ )
Some ( java_get_const_type_name c )
when Ident . equal iv array_nvar ->
| _ :: is ->
Some ( Some ( java_get_const_type_name c ) )
added_nvar array_nvar is
| _ ->
| _ ->
None )
None
| > Option . join
in
in
let rec array_nvar instrs =
let array_nvar =
match instrs with
instrs
| Sil . Load ( nv , Exp . Lvar iv , _ , _ ) :: _ when Pvar . equal iv ivar ->
| > List . find_map ~ f : ( function
added_nvar nv instrs
| Sil . Load ( nv , Exp . Lvar iv , _ , _ ) when Pvar . equal iv ivar ->
| _ :: is ->
Some nv
array_nvar is
| _ ->
| _ ->
None )
None
| > Option . bind ~ f : added_nvar
in
in
array_nvar ( Procdesc . Node . get_instrs node )
array_nvar
in
in
(* Walk nodes backward until definition of ivar, adding type names *)
(* Walk nodes backward until definition of ivar, adding type names *)
let rec type_names node =
let rec type_names acc node =
if initializes_array ( Procdesc . Node . get_instrs node ) then []
let instrs = Procdesc . Node . get_instrs node in
if initializes_array instrs then acc
else
else
match Procdesc . Node . get_preds node with
match Procdesc . Node . get_preds node with
| [ n ] -> (
| [ n ] -> (
match added_type_name node with Some name -> name :: type_names n | None -> type_names n )
match added_type_name instrs with
| Some name ->
type_names ( name :: acc ) n
| None ->
type_names acc n )
| _ ->
| _ ->
raise Caml . Not_found
raise Caml . Not_found
in
in
List . rev ( type_names call_node )
type_names [] call_node
let is_getter pname_java =
let is_getter pname_java =