[cleanup] restrict Java-specific utility functions to Typ.Procname.Java.t's

Reviewed By: jeremydubreil

Differential Revision: D6740465

fbshipit-source-id: 4ad717b
master
Sam Blackshear 7 years ago committed by Facebook Github Bot
parent 55ecd9b0a4
commit f7c415f7ae

@ -171,10 +171,10 @@ let inline_synthetic_method ret_id etl pdesc loc_call : Sil.instr option =
(** Find synthetic (access or bridge) Java methods in the procedure and inline them in the cfg. *) (** Find synthetic (access or bridge) Java methods in the procedure and inline them in the cfg. *)
let proc_inline_synthetic_methods cfg pdesc : unit = let proc_inline_synthetic_methods cfg pdesc : unit =
let instr_inline_synthetic_method = function let instr_inline_synthetic_method = function
| Sil.Call (ret_id, Exp.Const Const.Cfun pn, etl, loc, _) -> ( | Sil.Call (ret_id, Exp.Const Const.Cfun (Typ.Procname.Java java_pn as pn), etl, loc, _) -> (
match Typ.Procname.Hash.find cfg pn with match Typ.Procname.Hash.find cfg pn with
| pd -> | pd ->
let is_access = Typ.Procname.java_is_access_method pn in let is_access = Typ.Procname.Java.is_access_method java_pn in
let attributes = Procdesc.get_attributes pd in let attributes = Procdesc.get_attributes pd in
let is_synthetic = attributes.is_synthetic_method in let is_synthetic = attributes.is_synthetic_method in
let is_bridge = attributes.is_bridge_method in let is_bridge = attributes.is_bridge_method in

@ -506,45 +506,9 @@ let has_block_prefix s =
false false
(** Java types by name *)
let rec java_from_string : string -> t = function
| "" | "void" ->
mk Tvoid
| "int" ->
mk (Tint IInt)
| "byte" ->
mk (Tint IShort)
| "short" ->
mk (Tint IShort)
| "boolean" ->
mk (Tint IBool)
| "char" ->
mk (Tint IChar)
| "long" ->
mk (Tint ILong)
| "float" ->
mk (Tfloat FFloat)
| "double" ->
mk (Tfloat FDouble)
| typ_str when String.contains typ_str '[' ->
let stripped_typ = String.sub typ_str ~pos:0 ~len:(String.length typ_str - 2) in
mk (Tptr (mk (Tarray (java_from_string stripped_typ, None, None)), Pk_pointer))
| typ_str ->
mk (Tstruct (Name.Java.from_string typ_str))
type typ = t type typ = t
module Procname = struct module Procname = struct
type method_kind =
| Non_Static
(* in Java, procedures called with invokevirtual, invokespecial, and invokeinterface *)
| Static
(* in Java, procedures called with invokestatic *)
[@@deriving compare]
let equal_method_kind = [%compare.equal : method_kind]
(** Level of verbosity of some to_string functions. *) (** Level of verbosity of some to_string functions. *)
type detail_level = Verbose | Non_verbose | Simple [@@deriving compare] type detail_level = Verbose | Non_verbose | Simple [@@deriving compare]
@ -553,6 +517,13 @@ module Procname = struct
let is_verbose v = match v with Verbose -> true | _ -> false let is_verbose v = match v with Verbose -> true | _ -> false
module Java = struct module Java = struct
type kind =
| Non_Static
(* in Java, procedures called with invokevirtual, invokespecial, and invokeinterface *)
| Static
(* in Java, procedures called with invokestatic *)
[@@deriving compare]
(* TODO: use Mangled.t here *) (* TODO: use Mangled.t here *)
type java_type = string option * string type java_type = string option * string
@ -565,7 +536,7 @@ module Procname = struct
; parameters: java_type list ; parameters: java_type list
; class_name: Name.t ; class_name: Name.t
; return_type: java_type option (* option because constructors have no return type *) ; return_type: java_type option (* option because constructors have no return type *)
; kind: method_kind } ; kind: kind }
[@@deriving compare] [@@deriving compare]
let make class_name return_type method_name parameters kind = let make class_name return_type method_name parameters kind =
@ -655,6 +626,72 @@ module Procname = struct
else cls_prefix ^ j.method_name else cls_prefix ^ j.method_name
in in
method_name ^ "(" ^ params ^ ")" method_name ^ "(" ^ params ^ ")"
let get_return_typ pname_java =
let rec java_from_string = function
| "" | "void" ->
mk Tvoid
| "int" ->
mk (Tint IInt)
| "byte" ->
mk (Tint IShort)
| "short" ->
mk (Tint IShort)
| "boolean" ->
mk (Tint IBool)
| "char" ->
mk (Tint IChar)
| "long" ->
mk (Tint ILong)
| "float" ->
mk (Tfloat FFloat)
| "double" ->
mk (Tfloat FDouble)
| typ_str when String.contains typ_str '[' ->
let stripped_typ = String.sub typ_str ~pos:0 ~len:(String.length typ_str - 2) in
mk (Tptr (mk (Tarray (java_from_string stripped_typ, None, None)), Pk_pointer))
| typ_str ->
mk (Tstruct (Name.Java.from_string typ_str))
in
let typ = java_from_string (get_return_type pname_java) in
match typ.desc with Tstruct _ -> mk (Tptr (typ, Pk_pointer)) | _ -> typ
let is_close {method_name} = String.equal method_name "close"
let is_class_initializer {method_name} = String.equal method_name "<clinit>"
let is_anonymous_inner_class_constructor {class_name} =
Name.Java.is_anonymous_inner_class_name class_name
let is_static {kind} = match kind with Static -> true | _ -> false
let is_lambda {method_name} = String.is_prefix ~prefix:"lambda$" method_name
let is_generated {method_name} = String.is_prefix ~prefix:"$" method_name
let is_access_method {method_name} =
match String.rsplit2 method_name ~on:'$' with
| Some ("access", s) ->
let is_int =
try
ignore (int_of_string s) ;
true
with Failure _ -> false
in
is_int
| _ ->
false
let is_autogen_method {method_name} = String.contains method_name '$'
(** Check if the proc name has the type of a java vararg.
Note: currently only checks that the last argument has type Object[]. *)
let is_vararg {parameters} =
match List.last parameters with Some (_, "java.lang.Object[]") -> true | _ -> false
end end
(** Type of c procedure names. *) (** Type of c procedure names. *)
@ -758,67 +795,6 @@ module Procname = struct
t t
(** Check if the procedure name is an anonymous inner class constructor. *)
let java_is_anonymous_inner_class_constructor = function
| Java js ->
Name.Java.is_anonymous_inner_class_name js.class_name
| _ ->
false
(** Return true if the java procedure is static *)
let java_is_static = function Java j -> equal_method_kind j.kind Static | _ -> false
let java_is_lambda = function
| Java j ->
String.is_prefix ~prefix:"lambda$" j.method_name
| _ ->
false
let java_is_generated = function
| Java j ->
String.is_prefix ~prefix:"$" j.method_name
| _ ->
false
(** Check if the procedure name is an acess method (e.g. access$100 used to
access private members from a nested class. *)
let java_is_access_method = function
| Java js -> (
match String.rsplit2 js.method_name ~on:'$' with
| Some ("access", s) ->
let is_int =
try
ignore (int_of_string s) ;
true
with Failure _ -> false
in
is_int
| _ ->
false )
| _ ->
false
(** Check if the procedure name is of an auto-generated method containing '$'. *)
let java_is_autogen_method = function
| Java js ->
String.contains js.method_name '$'
| _ ->
false
(** Check if the proc name has the type of a java vararg.
Note: currently only checks that the last argument has type Object[]. *)
let java_is_vararg = function
| Java js -> (
match List.rev js.parameters with (_, "java.lang.Object[]") :: _ -> true | _ -> false )
| _ ->
false
let rec objc_cpp_replace_method_name t (new_method_name: string) = let rec objc_cpp_replace_method_name t (new_method_name: string) =
match t with match t with
| ObjC_Cpp osig -> | ObjC_Cpp osig ->
@ -909,16 +885,6 @@ module Procname = struct
false false
let java_is_close = function Java js -> String.equal js.method_name "close" | _ -> false
(** [is_class_initializer pname] returns true if [pname] is a class initializer *)
let is_class_initializer = function
| Java js ->
String.equal js.method_name "<clinit>"
| _ ->
false
(** [is_infer_undefined pn] returns true if [pn] is a special Infer undefined proc *) (** [is_infer_undefined pn] returns true if [pn] is a special Infer undefined proc *)
let is_infer_undefined pn = let is_infer_undefined pn =
match pn with match pn with
@ -1146,12 +1112,6 @@ module Procname = struct
end end
end end
(** Return the return type of [pname_java]. *)
let java_proc_return_typ pname_java : t =
let typ = java_from_string (Procname.Java.get_return_type pname_java) in
match typ.desc with Tstruct _ -> mk (Tptr (typ, Pk_pointer)) | _ -> typ
module Fieldname = struct module Fieldname = struct
type clang_field_info = {class_name: Name.t; field_name: string} [@@deriving compare] type clang_field_info = {class_name: Name.t; field_name: string} [@@deriving compare]

@ -258,19 +258,19 @@ type typ = t
module Procname : sig module Procname : sig
(** Module for Procedure Names. *) (** Module for Procedure Names. *)
type method_kind = (** Type of java procedure names. *)
module Java : sig
type kind =
| Non_Static | Non_Static
(** in Java, procedures called with invokevirtual, invokespecial, and invokeinterface *) (** in Java, procedures called with invokevirtual, invokespecial, and invokeinterface *)
| Static (** in Java, procedures called with invokestatic *) | Static (** in Java, procedures called with invokestatic *)
(** Type of java procedure names. *)
module Java : sig
type t [@@deriving compare] type t [@@deriving compare]
(** e.g. ("", "int") for primitive types or ("java.io", "PrintWriter") for objects *) (** e.g. ("", "int") for primitive types or ("java.io", "PrintWriter") for objects *)
type java_type = string option * string type java_type = string option * string
val make : Name.t -> java_type option -> string -> java_type list -> method_kind -> t val make : Name.t -> java_type option -> string -> java_type list -> kind -> t
(** Create a Java procedure name from its (** Create a Java procedure name from its
class_name method_name args_type_name return_type_name method_kind. *) class_name method_name args_type_name return_type_name method_kind. *)
@ -300,6 +300,38 @@ module Procname : sig
val replace_method : t -> string -> t val replace_method : t -> string -> t
(** Replace the method name of an existing java procname. *) (** Replace the method name of an existing java procname. *)
val get_return_typ : t -> typ
(** Return the return type of [pname_java]. return Tvoid if there's no return type *)
val is_access_method : t -> bool
(** Check if the procedure name is an acess method (e.g. access$100 used to
access private members from a nested class. *)
val is_autogen_method : t -> bool
(** Check if the procedure name is of an auto-generated method containing '$'. *)
val is_anonymous_inner_class_constructor : t -> bool
(** Check if the procedure name is an anonymous inner class constructor. *)
val is_close : t -> bool
(** Check if the method name is "close". *)
val is_static : t -> bool
(** Check if the java procedure is static. *)
val is_vararg : t -> bool
(** Check if the proc name has the type of a java vararg.
Note: currently only checks that the last argument has type Object[]. *)
val is_lambda : t -> bool
(** Check if the proc name comes from a lambda expression *)
val is_generated : t -> bool
(** Check if the proc name comes from generated code *)
val is_class_initializer : t -> bool
(** Check if this is a class initializer. *)
end end
(** Type of c procedure names. *) (** Type of c procedure names. *)
@ -435,35 +467,6 @@ module Procname : sig
val objc_method_kind_of_bool : bool -> objc_cpp_method_kind val objc_method_kind_of_bool : bool -> objc_cpp_method_kind
(** Create ObjC method type from a bool is_instance. *) (** Create ObjC method type from a bool is_instance. *)
val java_is_access_method : t -> bool
(** Check if the procedure name is an acess method (e.g. access$100 used to
access private members from a nested class. *)
val java_is_autogen_method : t -> bool
(** Check if the procedure name is of an auto-generated method containing '$'. *)
val java_is_anonymous_inner_class_constructor : t -> bool
(** Check if the procedure name is an anonymous inner class constructor. *)
val java_is_close : t -> bool
(** Check if the method name is "close". *)
val java_is_static : t -> bool
(** Check if the java procedure is static. *)
val java_is_vararg : t -> bool
(** Check if the proc name has the type of a java vararg.
Note: currently only checks that the last argument has type Object[]. *)
val java_is_lambda : t -> bool
(** Check if the proc name comes from a lambda expression *)
val java_is_generated : t -> bool
(** Check if the proc name comes from generated code *)
val is_class_initializer : t -> bool
(** Check if this is a class initializer. *)
val is_infer_undefined : t -> bool val is_infer_undefined : t -> bool
(** Check if this is a special Infer undefined procedure. *) (** Check if this is a special Infer undefined procedure. *)
@ -500,9 +503,6 @@ module Procname : sig
(** get qualifiers of a class owning objc/C++ method *) (** get qualifiers of a class owning objc/C++ method *)
end end
val java_proc_return_typ : Procname.Java.t -> t
(** Return the return type of [pname_java]. *)
module Fieldname : sig module Fieldname : sig
(** Names for fields of class/struct/union *) (** Names for fields of class/struct/union *)
type t [@@deriving compare] type t [@@deriving compare]

@ -1083,7 +1083,7 @@ let report_runtime_exceptions tenv pdesc summary =
&& &&
match pname with match pname with
| Typ.Procname.Java pname_java -> | Typ.Procname.Java pname_java ->
Typ.Procname.java_is_static pname Typ.Procname.Java.is_static pname_java
&& String.equal (Typ.Procname.Java.get_method pname_java) "main" && String.equal (Typ.Procname.Java.get_method pname_java) "main"
| _ -> | _ ->
false false

@ -904,7 +904,12 @@ let add_guarded_by_constraints tenv prop lexp pdesc =
in in
let is_synchronized_on_class guarded_by_str = let is_synchronized_on_class guarded_by_str =
guarded_by_str_is_current_class guarded_by_str pname && Procdesc.is_java_synchronized pdesc guarded_by_str_is_current_class guarded_by_str pname && Procdesc.is_java_synchronized pdesc
&& Typ.Procname.java_is_static pname &&
match pname with
| Typ.Procname.Java java_pname ->
Typ.Procname.Java.is_static java_pname
| _ ->
false
in in
let warn accessed_fld guarded_by_str = let warn accessed_fld guarded_by_str =
let loc = State.get_loc () in let loc = State.get_loc () in
@ -929,8 +934,14 @@ let add_guarded_by_constraints tenv prop lexp pdesc =
( guarded_by_str_is_current_class_this guarded_by_str pname ( guarded_by_str_is_current_class_this guarded_by_str pname
|| guarded_by_str_is_super_class_this guarded_by_str pname ) || guarded_by_str_is_super_class_this guarded_by_str pname )
&& Procdesc.is_java_synchronized pdesc && Procdesc.is_java_synchronized pdesc
|| guarded_by_str_is_current_class guarded_by_str pname || ( guarded_by_str_is_current_class guarded_by_str pname
&& Procdesc.is_java_synchronized pdesc && Typ.Procname.java_is_static pname && Procdesc.is_java_synchronized pdesc
&&
match pname with
| Typ.Procname.Java java_pname ->
Typ.Procname.Java.is_static java_pname
| _ ->
false )
|| (* or the prop says we already have the lock *) || (* or the prop says we already have the lock *)
List.exists List.exists
~f:(function Sil.Apred (Alocked, _) -> true | _ -> false) ~f:(function Sil.Apred (Alocked, _) -> true | _ -> false)
@ -972,7 +983,12 @@ let add_guarded_by_constraints tenv prop lexp pdesc =
in in
Procdesc.get_access pdesc <> PredSymb.Private Procdesc.get_access pdesc <> PredSymb.Private
&& not (Annotations.pdesc_return_annot_ends_with pdesc Annotations.visibleForTesting) && not (Annotations.pdesc_return_annot_ends_with pdesc Annotations.visibleForTesting)
&& not (Typ.Procname.java_is_access_method (Procdesc.get_proc_name pdesc)) && not
( match Procdesc.get_proc_name pdesc with
| Typ.Procname.Java java_pname ->
Typ.Procname.Java.is_access_method java_pname
| _ ->
false )
&& not (is_accessible_through_local_ref lexp) && not guardedby_is_self_referential && not (is_accessible_through_local_ref lexp) && not guardedby_is_self_referential
&& not (proc_has_suppress_guarded_by_annot pdesc) && not (proc_has_suppress_guarded_by_annot pdesc)
in in
@ -1761,10 +1777,15 @@ let rearrange ?(report_deref_errors= true) pdesc tenv lexp typ prop loc
if report_deref_errors then check_dereference_error tenv pdesc prop nlexp (State.get_loc ()) ; if report_deref_errors then check_dereference_error tenv pdesc prop nlexp (State.get_loc ()) ;
let pname = Procdesc.get_proc_name pdesc in let pname = Procdesc.get_proc_name pdesc in
let prop' = let prop' =
if Config.csl_analysis && !Config.footprint && Typ.Procname.is_java pname match pname with
&& not (Typ.Procname.is_constructor pname || Typ.Procname.is_class_initializer pname) | Typ.Procname.Java java_pname
then add_guarded_by_constraints tenv prop lexp pdesc when Config.csl_analysis && !Config.footprint
else prop && not
( Typ.Procname.is_constructor pname
|| Typ.Procname.Java.is_class_initializer java_pname ) ->
add_guarded_by_constraints tenv prop lexp pdesc
| _ ->
prop
in in
match Prop.prop_iter_create prop' with match Prop.prop_iter_create prop' with
| None -> | None ->

@ -38,13 +38,19 @@ let log_issue_from_errlog err_kind err_log ?loc ?node_id ?session ?ltr ?linters_
let log_issue_from_summary err_kind summary ?loc ?node_id ?session ?ltr ?linters_def_file ?doc_url let log_issue_from_summary err_kind summary ?loc ?node_id ?session ?ltr ?linters_def_file ?doc_url
?access exn = ?access exn =
let is_generated_method = Typ.Procname.java_is_generated (Specs.get_proc_name summary) in let is_java_generated_method =
match Specs.get_proc_name summary with
| Typ.Procname.Java java_pname ->
Typ.Procname.Java.is_generated java_pname
| _ ->
false
in
let should_suppress_lint = let should_suppress_lint =
Config.curr_language_is Config.Java Config.curr_language_is Config.Java
&& Annotations.ia_is_suppress_lint && Annotations.ia_is_suppress_lint
(fst (Specs.get_attributes summary).ProcAttributes.method_annotation) (fst (Specs.get_attributes summary).ProcAttributes.method_annotation)
in in
if should_suppress_lint || is_generated_method then () (* Skip the reporting *) if should_suppress_lint || is_java_generated_method then () (* Skip the reporting *)
else else
let err_log = Specs.get_err_log summary in let err_log = Specs.get_err_log summary in
log_issue_from_errlog err_kind err_log ?loc ?node_id ?session ?ltr ?linters_def_file ?doc_url log_issue_from_errlog err_kind err_log ?loc ?node_id ?session ?ltr ?linters_def_file ?doc_url

@ -723,7 +723,7 @@ let call_constructor_url_update_args pname actual_params =
Typ.Procname.Java Typ.Procname.Java
(Typ.Procname.Java.make (Typ.Procname.Java.make
(Typ.Name.Java.from_string "java.net.URL") (Typ.Name.Java.from_string "java.net.URL")
None "<init>" [(Some "java.lang", "String")] Typ.Procname.Non_Static) None "<init>" [(Some "java.lang", "String")] Typ.Procname.Java.Non_Static)
in in
if Typ.Procname.equal url_pname pname then if Typ.Procname.equal url_pname pname then
match actual_params with match actual_params with
@ -1186,7 +1186,7 @@ let rec sym_exec tenv current_pdesc instr_ (prop_: Prop.normal Prop.t) path
in in
match resolved_summary_opt with match resolved_summary_opt with
| None -> | None ->
let ret_typ = Typ.java_proc_return_typ callee_pname_java in let ret_typ = Typ.Procname.Java.get_return_typ callee_pname_java in
let ret_annots = load_ret_annots callee_pname in let ret_annots = load_ret_annots callee_pname in
exec_skip_call ~reason:"unknown method" resolved_pname ret_annots ret_typ exec_skip_call ~reason:"unknown method" resolved_pname ret_annots ret_typ
| Some resolved_summary -> | Some resolved_summary ->
@ -1211,7 +1211,7 @@ let rec sym_exec tenv current_pdesc instr_ (prop_: Prop.normal Prop.t) path
in in
match Ondemand.analyze_proc_name current_pdesc pname with match Ondemand.analyze_proc_name current_pdesc pname with
| None -> | None ->
let ret_typ = Typ.java_proc_return_typ callee_pname_java in let ret_typ = Typ.Procname.Java.get_return_typ callee_pname_java in
let ret_annots = load_ret_annots callee_pname in let ret_annots = load_ret_annots callee_pname in
exec_skip_call ~reason:"unknown method" ret_annots ret_typ exec_skip_call ~reason:"unknown method" ret_annots ret_typ
| Some callee_summary -> | Some callee_summary ->

@ -35,8 +35,10 @@ module TransferFunctions (CFG : ProcCfg.S) = struct
let is_non_objc_instance_method callee_pname = let is_non_objc_instance_method callee_pname =
if Typ.Procname.is_java callee_pname then not (Typ.Procname.java_is_static callee_pname) match callee_pname with
else | Typ.Procname.Java java_pname ->
not (Typ.Procname.Java.is_static java_pname)
| _ ->
Option.exists Option.exists
~f:(fun attributes -> attributes.ProcAttributes.is_cpp_instance_method) ~f:(fun attributes -> attributes.ProcAttributes.is_cpp_instance_method)
(Specs.proc_resolve_attributes callee_pname) (Specs.proc_resolve_attributes callee_pname)

@ -854,8 +854,14 @@ let pdesc_is_assumed_thread_safe pdesc tenv =
find more bugs. this is just a temporary measure to avoid obvious false positives *) find more bugs. this is just a temporary measure to avoid obvious false positives *)
let should_analyze_proc pdesc tenv = let should_analyze_proc pdesc tenv =
let pn = Procdesc.get_proc_name pdesc in let pn = Procdesc.get_proc_name pdesc in
not (Typ.Procname.is_class_initializer pn) && not (FbThreadSafety.is_logging_method pn) not
&& not (pdesc_is_assumed_thread_safe pdesc tenv) && not (RacerDConfig.Models.should_skip pn) ( match pn with
| Typ.Procname.Java java_pname ->
Typ.Procname.Java.is_class_initializer java_pname
| _ ->
false )
&& not (FbThreadSafety.is_logging_method pn) && not (pdesc_is_assumed_thread_safe pdesc tenv)
&& not (RacerDConfig.Models.should_skip pn)
let get_current_class_and_threadsafe_superclasses tenv pname = let get_current_class_and_threadsafe_superclasses tenv pname =
@ -1277,7 +1283,12 @@ let make_read_write_race_description ~read_is_sync (conflict: reported_access) p
let should_report_on_proc proc_desc tenv = let should_report_on_proc proc_desc tenv =
let proc_name = Procdesc.get_proc_name proc_desc in let proc_name = Procdesc.get_proc_name proc_desc in
is_thread_safe_method proc_name tenv is_thread_safe_method proc_name tenv
|| not (Typ.Procname.java_is_autogen_method proc_name) || not
( match proc_name with
| Typ.Procname.Java java_pname ->
Typ.Procname.Java.is_autogen_method java_pname
| _ ->
false )
&& Procdesc.get_access proc_desc <> PredSymb.Private && Procdesc.get_access proc_desc <> PredSymb.Private
&& not (Annotations.pdesc_return_annot_ends_with proc_desc Annotations.visibleForTesting) && not (Annotations.pdesc_return_annot_ends_with proc_desc Annotations.visibleForTesting)

@ -326,7 +326,11 @@ module MkCallback (Extension : ExtensionT) : CallBackT = struct
let proc_name = Procdesc.get_proc_name proc_desc in let proc_name = Procdesc.get_proc_name proc_desc in
let calls_this = ref false in let calls_this = ref false in
let filter_special_cases () = let filter_special_cases () =
if Typ.Procname.java_is_access_method proc_name if ( match proc_name with
| Typ.Procname.Java java_pname ->
Typ.Procname.Java.is_access_method java_pname
| _ ->
false )
|| (Specs.pdesc_resolve_attributes proc_desc).ProcAttributes.is_bridge_method || (Specs.pdesc_resolve_attributes proc_desc).ProcAttributes.is_bridge_method
then None then None
else else

@ -202,7 +202,12 @@ let check_field_assignment tenv find_canonical_duplicate curr_pdesc node instr_r
match t_ia_opt with Some (_, ia) -> Annotations.ia_is_mutable ia | _ -> false match t_ia_opt with Some (_, ia) -> Annotations.ia_is_mutable ia | _ -> false
in in
Config.eradicate_field_not_mutable && not (Typ.Procname.is_constructor curr_pname) Config.eradicate_field_not_mutable && not (Typ.Procname.is_constructor curr_pname)
&& not (Typ.Procname.is_class_initializer curr_pname) && not (field_is_mutable ()) && ( match curr_pname with
| Typ.Procname.Java java_pname ->
not (Typ.Procname.Java.is_class_initializer java_pname)
| _ ->
true )
&& not (field_is_mutable ())
in in
( if should_report_nullable || should_report_absent then ( if should_report_nullable || should_report_absent then
let ann = let ann =
@ -311,7 +316,11 @@ let check_return_annotation tenv find_canonical_duplicate curr_pdesc ret_range
match ret_range with match ret_range with
(* Disables the warnings since it is not clear how to annotate the return value of lambdas *) (* Disables the warnings since it is not clear how to annotate the return value of lambdas *)
| Some _ | Some _
when Typ.Procname.java_is_lambda curr_pname -> when match curr_pname with
| Typ.Procname.Java java_pname ->
Typ.Procname.Java.is_lambda java_pname
| _ ->
false ->
() ()
| Some (_, final_ta, _) -> | Some (_, final_ta, _) ->
let final_nullable = TypeAnnotation.get_value AnnotatedSignature.Nullable final_ta in let final_nullable = TypeAnnotation.get_value AnnotatedSignature.Nullable final_ta in

@ -546,13 +546,14 @@ let typecheck_instr tenv ext calls_this checks (node: Procdesc.Node.t) idenv get
List.mapi List.mapi
~f:(fun i (_, typ) -> ~f:(fun i (_, typ) ->
let arg = let arg =
if Int.equal i 0 && not (Typ.Procname.java_is_static callee_pname) then "this" if Int.equal i 0 && not (Typ.Procname.Java.is_static callee_pname_java) then
"this"
else Printf.sprintf "arg%d" i else Printf.sprintf "arg%d" i
in in
(Mangled.from_string arg, typ) ) (Mangled.from_string arg, typ) )
etl_ etl_
in in
let ret_type = Typ.java_proc_return_typ callee_pname_java in let ret_type = Typ.Procname.Java.get_return_typ callee_pname_java in
let proc_attributes = let proc_attributes =
{(ProcAttributes.default callee_pname) with ProcAttributes.formals; ret_type} {(ProcAttributes.default callee_pname) with ProcAttributes.formals; ret_type}
in in
@ -572,7 +573,7 @@ let typecheck_instr tenv ext calls_this checks (node: Procdesc.Node.t) idenv get
drop_unchecked_signature_params callee_attributes annotated_signature drop_unchecked_signature_params callee_attributes annotated_signature
in in
let is_anonymous_inner_class_constructor = let is_anonymous_inner_class_constructor =
Typ.Procname.java_is_anonymous_inner_class_constructor callee_pname Typ.Procname.Java.is_anonymous_inner_class_constructor callee_pname_java
in in
let do_return (ret_ta, ret_typ) loc' typestate' = let do_return (ret_ta, ret_typ) loc' typestate' =
let mk_return_range () = (ret_typ, ret_ta, [loc']) in let mk_return_range () = (ret_typ, ret_ta, [loc']) in
@ -858,7 +859,7 @@ let typecheck_instr tenv ext calls_this checks (node: Procdesc.Node.t) idenv get
(Models.get_check_not_null_parameter callee_pname) (Models.get_check_not_null_parameter callee_pname)
~is_vararg:false typestate2 ~is_vararg:false typestate2
else if has_method callee_pname "checkNotNull" else if has_method callee_pname "checkNotNull"
&& Typ.Procname.java_is_vararg callee_pname && Typ.Procname.Java.is_vararg callee_pname_java
then then
let last_parameter = List.length call_params in let last_parameter = List.length call_params in
do_preconditions_check_not_null last_parameter ~is_vararg:true typestate2 do_preconditions_check_not_null last_parameter ~is_vararg:true typestate2

@ -110,9 +110,9 @@ let formals_from_signature program tenv cn ms kind =
in in
let init_arg_list = let init_arg_list =
match kind with match kind with
| Typ.Procname.Static -> | Typ.Procname.Java.Static ->
[] []
| Typ.Procname.Non_Static -> | Typ.Procname.Java.Non_Static ->
[(JConfig.this, JTransType.get_class_type program tenv cn)] [(JConfig.this, JTransType.get_class_type program tenv cn)]
in in
List.rev (List.fold ~f:collect ~init:init_arg_list (JBasics.ms_args ms)) List.rev (List.fold ~f:collect ~init:init_arg_list (JBasics.ms_args ms))
@ -650,6 +650,12 @@ let method_invocation (context: JContext.t) loc pc var_opt cn ms sil_obj_opt exp
let sil_var = JContext.set_pvar context var return_type in let sil_var = JContext.set_pvar context var return_type in
call_ret_instrs sil_var call_ret_instrs sil_var
in in
let is_close = function
| Typ.Procname.Java java_pname ->
Typ.Procname.Java.is_close java_pname
| _ ->
false
in
let instrs = let instrs =
match call_args with match call_args with
(* modeling a class bypasses the treatment of Closeable *) (* modeling a class bypasses the treatment of Closeable *)
@ -668,7 +674,7 @@ let method_invocation (context: JContext.t) loc pc var_opt cn ms sil_obj_opt exp
call_instrs @ [set_file_attr] call_instrs @ [set_file_attr]
(* remove file attribute when calling the close method of a subtype of Closeable *) (* remove file attribute when calling the close method of a subtype of Closeable *)
| [exp] | [exp]
when Typ.Procname.java_is_close callee_procname -> when is_close callee_procname ->
let set_mem_attr = let set_mem_attr =
let set_builtin = Exp.Const (Const.Cfun BuiltinDecl.__set_mem_attribute) in let set_builtin = Exp.Const (Const.Cfun BuiltinDecl.__set_mem_attribute) in
Sil.Call (None, set_builtin, [exp], loc, CallFlags.default) Sil.Call (None, set_builtin, [exp], loc, CallFlags.default)
@ -891,7 +897,7 @@ let instruction (context: JContext.t) pc instr : translation =
let constr_procname, call_instrs = let constr_procname, call_instrs =
let ret_opt = Some (Exp.Var ret_id, class_type) in let ret_opt = Some (Exp.Var ret_id, class_type) in
method_invocation context loc pc None cn constr_ms ret_opt constr_arg_list I_Special method_invocation context loc pc None cn constr_ms ret_opt constr_arg_list I_Special
Typ.Procname.Non_Static Typ.Procname.Java.Non_Static
in in
let pvar = JContext.set_pvar context var class_type in let pvar = JContext.set_pvar context var class_type in
let set_instr = Sil.Store (Exp.Lvar pvar, class_type, Exp.Var ret_id, loc) in let set_instr = Sil.Store (Exp.Lvar pvar, class_type, Exp.Var ret_id, loc) in
@ -929,7 +935,7 @@ let instruction (context: JContext.t) pc instr : translation =
in in
let callee_procname, call_instrs = let callee_procname, call_instrs =
method_invocation context loc pc var_opt cn ms sil_obj_opt args I_Static method_invocation context loc pc var_opt cn ms sil_obj_opt args I_Static
Typ.Procname.Static Typ.Procname.Java.Static
in in
let node_kind = create_node_kind callee_procname in let node_kind = create_node_kind callee_procname in
let call_node = create_node node_kind (instrs @ call_instrs) in let call_node = create_node node_kind (instrs @ call_instrs) in
@ -944,7 +950,7 @@ let instruction (context: JContext.t) pc instr : translation =
let callee_procname, call_instrs = let callee_procname, call_instrs =
let ret_opt = Some (sil_obj_expr, sil_obj_type) in let ret_opt = Some (sil_obj_expr, sil_obj_type) in
method_invocation context loc pc var_opt cn ms ret_opt args invoke_kind method_invocation context loc pc var_opt cn ms ret_opt args invoke_kind
Typ.Procname.Non_Static Typ.Procname.Java.Non_Static
in in
let node_kind = create_node_kind callee_procname in let node_kind = create_node_kind callee_procname in
let call_node = create_node node_kind (instrs @ call_instrs) in let call_node = create_node node_kind (instrs @ call_instrs) in
@ -978,7 +984,7 @@ let instruction (context: JContext.t) pc instr : translation =
let instrs, sil_obj_expr, sil_obj_type = expression context pc obj in let instrs, sil_obj_expr, sil_obj_type = expression context pc obj in
let callee_procname, call_instrs = let callee_procname, call_instrs =
method_invocation context loc pc var_opt cn ms (Some (sil_obj_expr, sil_obj_type)) args method_invocation context loc pc var_opt cn ms (Some (sil_obj_expr, sil_obj_type)) args
I_Special Typ.Procname.Non_Static I_Special Typ.Procname.Java.Non_Static
in in
let node_kind = create_node_kind callee_procname in let node_kind = create_node_kind callee_procname in
let call_node = create_node node_kind (instrs @ call_instrs) in let call_node = create_node node_kind (instrs @ call_instrs) in
@ -1022,7 +1028,7 @@ let instruction (context: JContext.t) pc instr : translation =
let _, call_instrs = let _, call_instrs =
let ret_opt = Some (Exp.Var ret_id, class_type) in let ret_opt = Some (Exp.Var ret_id, class_type) in
method_invocation context loc pc None npe_cn constr_ms ret_opt [] I_Special method_invocation context loc pc None npe_cn constr_ms ret_opt [] I_Special
Typ.Procname.Static Typ.Procname.Java.Static
in in
let sil_exn = Exp.Exn (Exp.Var ret_id) in let sil_exn = Exp.Exn (Exp.Var ret_id) in
let set_instr = Sil.Store (Exp.Lvar ret_var, ret_type, sil_exn, loc) in let set_instr = Sil.Store (Exp.Lvar ret_var, ret_type, sil_exn, loc) in
@ -1079,7 +1085,7 @@ let instruction (context: JContext.t) pc instr : translation =
let constr_ms = JBasics.make_ms JConfig.constructor_name [] None in let constr_ms = JBasics.make_ms JConfig.constructor_name [] None in
let _, call_instrs = let _, call_instrs =
method_invocation context loc pc None out_of_bound_cn constr_ms method_invocation context loc pc None out_of_bound_cn constr_ms
(Some (Exp.Var ret_id, class_type)) [] I_Special Typ.Procname.Static (Some (Exp.Var ret_id, class_type)) [] I_Special Typ.Procname.Java.Static
in in
let sil_exn = Exp.Exn (Exp.Var ret_id) in let sil_exn = Exp.Exn (Exp.Var ret_id) in
let set_instr = Sil.Store (Exp.Lvar ret_var, ret_type, sil_exn, loc) in let set_instr = Sil.Store (Exp.Lvar ret_var, ret_type, sil_exn, loc) in
@ -1124,7 +1130,7 @@ let instruction (context: JContext.t) pc instr : translation =
let constr_ms = JBasics.make_ms JConfig.constructor_name [] None in let constr_ms = JBasics.make_ms JConfig.constructor_name [] None in
let _, call_instrs = let _, call_instrs =
method_invocation context loc pc None cce_cn constr_ms method_invocation context loc pc None cce_cn constr_ms
(Some (Exp.Var ret_id, class_type)) [] I_Special Typ.Procname.Static (Some (Exp.Var ret_id, class_type)) [] I_Special Typ.Procname.Java.Static
in in
let sil_exn = Exp.Exn (Exp.Var ret_id) in let sil_exn = Exp.Exn (Exp.Var ret_id) in
let set_instr = Sil.Store (Exp.Lvar ret_var, ret_type, sil_exn, loc) in let set_instr = Sil.Store (Exp.Lvar ret_var, ret_type, sil_exn, loc) in

@ -217,7 +217,7 @@ let method_signature_names ms =
let get_method_kind m = let get_method_kind m =
if Javalib.is_static_method m then Typ.Procname.Static else Typ.Procname.Non_Static if Javalib.is_static_method m then Typ.Procname.Java.Static else Typ.Procname.Java.Non_Static
let get_method_procname cn ms method_kind = let get_method_procname cn ms method_kind =

@ -12,10 +12,10 @@ open! IStd
open Javalib_pack open Javalib_pack
open Sawja_pack open Sawja_pack
val get_method_kind : JCode.jcode Javalib.jmethod -> Typ.Procname.method_kind val get_method_kind : JCode.jcode Javalib.jmethod -> Typ.Procname.Java.kind
val get_method_procname : val get_method_procname :
JBasics.class_name -> JBasics.method_signature -> Typ.Procname.method_kind -> Typ.Procname.t JBasics.class_name -> JBasics.method_signature -> Typ.Procname.Java.kind -> Typ.Procname.t
(** returns a procedure name based on the class name and the method's signature. *) (** returns a procedure name based on the class name and the method's signature. *)
val translate_method_name : JCode.jcode Javalib.jmethod -> Typ.Procname.t val translate_method_name : JCode.jcode Javalib.jmethod -> Typ.Procname.t

@ -41,9 +41,9 @@ include TaintAnalysis.Make (struct
false false
in in
match pname with match pname with
| Typ.Procname.Java java_pname as pname | Typ.Procname.Java java_pname
-> ( -> (
let is_static = Typ.Procname.java_is_static pname in let is_static = Typ.Procname.Java.is_static java_pname in
match match
( Typ.Procname.Java.get_class_name java_pname ( Typ.Procname.Java.get_class_name java_pname
, Typ.Procname.Java.get_method java_pname , Typ.Procname.Java.get_method java_pname

@ -278,11 +278,14 @@ module SinkKind = struct
let get pname actuals tenv = let get pname actuals tenv =
(* taint all the inputs of [pname]. for non-static procedures, taints the "this" parameter only match pname with
if [taint_this] is true. *) | Typ.Procname.Java java_pname
-> (
(* taint all the inputs of [pname]. for non-static procedures, taints the "this" parameter
only if [taint_this] is true. *)
let taint_all ?(taint_this= false) kind = let taint_all ?(taint_this= false) kind =
let actuals_to_taint, offset = let actuals_to_taint, offset =
if Typ.Procname.java_is_static pname || taint_this then (actuals, 0) if Typ.Procname.Java.is_static java_pname || taint_this then (actuals, 0)
else (List.tl_exn actuals, 1) else (List.tl_exn actuals, 1)
in in
let indexes = let indexes =
@ -292,11 +295,10 @@ module SinkKind = struct
in in
(* taint the nth non-"this" parameter (0-indexed) *) (* taint the nth non-"this" parameter (0-indexed) *)
let taint_nth n kind = let taint_nth n kind =
let first_index = if Typ.Procname.java_is_static pname then n else n + 1 in let first_index = if Typ.Procname.Java.is_static java_pname then n else n + 1 in
if first_index < List.length actuals then Some (kind, IntSet.singleton first_index) else None if first_index < List.length actuals then Some (kind, IntSet.singleton first_index)
else None
in in
match pname with
| Typ.Procname.Java java_pname -> (
match match
(Typ.Procname.Java.get_class_name java_pname, Typ.Procname.Java.get_method java_pname) (Typ.Procname.Java.get_class_name java_pname, Typ.Procname.Java.get_method java_pname)
with with

Loading…
Cancel
Save