|
|
@ -14,6 +14,13 @@ module Payload = SummaryPayload.Make (struct
|
|
|
|
let of_payloads (payloads : Payloads.t) = payloads.class_loads
|
|
|
|
let of_payloads (payloads : Payloads.t) = payloads.class_loads
|
|
|
|
end)
|
|
|
|
end)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
let get_java_class = function
|
|
|
|
|
|
|
|
| Typ.Procname.Java java_pname ->
|
|
|
|
|
|
|
|
Some (Typ.Procname.Java.get_class_name java_pname)
|
|
|
|
|
|
|
|
| _ ->
|
|
|
|
|
|
|
|
None
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
let exec_instr pdesc astate _ (instr : Sil.instr) =
|
|
|
|
let exec_instr pdesc astate _ (instr : Sil.instr) =
|
|
|
|
match instr with
|
|
|
|
match instr with
|
|
|
|
| Call (_, Const (Cfun callee), _, loc, _) ->
|
|
|
|
| Call (_, Const (Cfun callee), _, loc, _) ->
|
|
|
@ -24,22 +31,48 @@ let exec_instr pdesc astate _ (instr : Sil.instr) =
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
let report_loads proc_desc summary astate =
|
|
|
|
let report_loads proc_desc summary astate =
|
|
|
|
let report_load ({ClassLoadsDomain.Event.loc} as event) =
|
|
|
|
let report_load ({ClassLoadsDomain.Event.loc; elem} as event) =
|
|
|
|
let ltr = ClassLoadsDomain.Event.make_loc_trace event in
|
|
|
|
let ltr = ClassLoadsDomain.Event.make_loc_trace event in
|
|
|
|
Reporting.log_warning summary ~loc ~ltr IssueType.class_load "Class load"
|
|
|
|
let msg = Format.asprintf "Class %s loaded" elem in
|
|
|
|
|
|
|
|
Reporting.log_warning summary ~loc ~ltr IssueType.class_load msg
|
|
|
|
in
|
|
|
|
in
|
|
|
|
let pname = Procdesc.get_proc_name proc_desc in
|
|
|
|
let pname = Procdesc.get_proc_name proc_desc in
|
|
|
|
ClassLoadsDomain.get_java_class pname
|
|
|
|
get_java_class pname
|
|
|
|
|> Option.iter ~f:(fun clazz ->
|
|
|
|
|> Option.iter ~f:(fun clazz ->
|
|
|
|
let method_strname = Typ.Procname.get_method pname in
|
|
|
|
let method_strname = Typ.Procname.get_method pname in
|
|
|
|
let fullname = clazz ^ "." ^ method_strname in
|
|
|
|
let fullname = clazz ^ "." ^ method_strname in
|
|
|
|
(* Logging.debug_dev "Pname = %s" method_strname ; *)
|
|
|
|
|
|
|
|
if String.Set.mem Config.class_loads_roots fullname then
|
|
|
|
if String.Set.mem Config.class_loads_roots fullname then
|
|
|
|
ClassLoadsDomain.iter report_load astate )
|
|
|
|
ClassLoadsDomain.iter report_load astate )
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
(* if [pdesc] is *not* a class initializer (to avoid infinite recursion), return the
|
|
|
|
|
|
|
|
class initializer of [pdesc]'s class *)
|
|
|
|
|
|
|
|
let class_initializer_of_method pdesc =
|
|
|
|
|
|
|
|
let open Typ.Procname in
|
|
|
|
|
|
|
|
match Procdesc.get_proc_name pdesc with
|
|
|
|
|
|
|
|
| Java java_pname when Java.is_class_initializer java_pname ->
|
|
|
|
|
|
|
|
None
|
|
|
|
|
|
|
|
| Java java_pname ->
|
|
|
|
|
|
|
|
Some (Java Java.(replace_method_name class_initializer_method_name java_pname))
|
|
|
|
|
|
|
|
| _ ->
|
|
|
|
|
|
|
|
assert false
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
let analyze_procedure {Callbacks.proc_desc; summary} =
|
|
|
|
let analyze_procedure {Callbacks.proc_desc; summary} =
|
|
|
|
let init = ClassLoadsDomain.empty in
|
|
|
|
let proc_name = Procdesc.get_proc_name proc_desc in
|
|
|
|
let post = Procdesc.fold_instrs proc_desc ~init ~f:(exec_instr proc_desc) in
|
|
|
|
let loc = Procdesc.get_loc proc_desc in
|
|
|
|
|
|
|
|
(* add a load for the method's class *)
|
|
|
|
|
|
|
|
let init =
|
|
|
|
|
|
|
|
get_java_class proc_name
|
|
|
|
|
|
|
|
|> Option.fold ~init:ClassLoadsDomain.empty ~f:(ClassLoadsDomain.add_load loc)
|
|
|
|
|
|
|
|
in
|
|
|
|
|
|
|
|
(* add loads done by the static initialization of this method's class *)
|
|
|
|
|
|
|
|
let after_class_init =
|
|
|
|
|
|
|
|
class_initializer_of_method proc_desc
|
|
|
|
|
|
|
|
|> Option.bind ~f:(Payload.read proc_desc)
|
|
|
|
|
|
|
|
(* pretend there is a call to class initializer before the method body *)
|
|
|
|
|
|
|
|
|> Option.fold ~init ~f:(ClassLoadsDomain.integrate_summary proc_name loc)
|
|
|
|
|
|
|
|
in
|
|
|
|
|
|
|
|
let post = Procdesc.fold_instrs proc_desc ~init:after_class_init ~f:(exec_instr proc_desc) in
|
|
|
|
report_loads proc_desc summary post ;
|
|
|
|
report_loads proc_desc summary post ;
|
|
|
|
Payload.update_summary post summary
|
|
|
|
Payload.update_summary post summary
|
|
|
|