Add information whether translated method has return parameter

Summary:
public
This information will be useful when returning values

Reviewed By: jberdine, jvillard

Differential Revision: D2864864

fb-gh-sync-id: 36da0bb
master
Andrzej Kotulski 9 years ago committed by facebook-github-bot-5
parent 2c8238849d
commit 61de633647

@ -30,17 +30,19 @@ type t =
procdesc : Cfg.Procdesc.t; procdesc : Cfg.Procdesc.t;
is_objc_method : bool; is_objc_method : bool;
curr_class: curr_class; curr_class: curr_class;
has_return_param : bool;
is_callee_expression : bool; is_callee_expression : bool;
outer_context : t option; (* in case of objc blocks, the context of the method containing the block *) outer_context : t option; (* in case of objc blocks, the context of the method containing the block *)
mutable blocks_static_vars : ((Sil.pvar * Sil.typ) list) Procname.Map.t; mutable blocks_static_vars : ((Sil.pvar * Sil.typ) list) Procname.Map.t;
} }
let create_context tenv cg cfg procdesc curr_class is_objc_method context_opt = let create_context tenv cg cfg procdesc curr_class ~has_return_param is_objc_method context_opt =
{ tenv = tenv; { tenv = tenv;
cg = cg; cg = cg;
cfg = cfg; cfg = cfg;
procdesc = procdesc; procdesc = procdesc;
curr_class = curr_class; curr_class = curr_class;
has_return_param = has_return_param;
is_callee_expression = false; is_callee_expression = false;
is_objc_method = is_objc_method; is_objc_method = is_objc_method;
outer_context = context_opt; outer_context = context_opt;

@ -25,6 +25,7 @@ type t =
procdesc : Cfg.Procdesc.t; procdesc : Cfg.Procdesc.t;
is_objc_method : bool; is_objc_method : bool;
curr_class: curr_class; curr_class: curr_class;
has_return_param : bool;
is_callee_expression : bool; is_callee_expression : bool;
outer_context : t option; (* in case of objc blocks, the context of the method containing the block *) outer_context : t option; (* in case of objc blocks, the context of the method containing the block *)
mutable blocks_static_vars : ((Sil.pvar * Sil.typ) list) Procname.Map.t; mutable blocks_static_vars : ((Sil.pvar * Sil.typ) list) Procname.Map.t;
@ -53,7 +54,7 @@ val is_objc_method : t -> bool
val get_tenv : t -> Sil.tenv val get_tenv : t -> Sil.tenv
val create_context : Sil.tenv -> Cg.t -> Cfg.cfg -> Cfg.Procdesc.t -> val create_context : Sil.tenv -> Cg.t -> Cfg.cfg -> Cfg.Procdesc.t ->
curr_class -> bool -> t option -> t curr_class -> has_return_param : bool -> bool -> t option -> t
val create_curr_class : Sil.tenv -> string -> curr_class val create_curr_class : Sil.tenv -> string -> curr_class

@ -30,7 +30,7 @@ struct
Specs.summary_exists_in_models procname && not !CFrontend_config.models_mode Specs.summary_exists_in_models procname && not !CFrontend_config.models_mode
(* Translates the method/function's body into nodes of the cfg. *) (* Translates the method/function's body into nodes of the cfg. *)
let add_method tenv cg cfg class_decl_opt procname instrs is_objc_method let add_method tenv cg cfg class_decl_opt procname instrs has_return_param is_objc_method
captured_vars outer_context_opt extra_instrs = captured_vars outer_context_opt extra_instrs =
Printing.log_out Printing.log_out
@ -41,7 +41,7 @@ struct
if (Cfg.Procdesc.is_defined procdesc && not (model_exists procname)) then if (Cfg.Procdesc.is_defined procdesc && not (model_exists procname)) then
(let context = (let context =
CContext.create_context tenv cg cfg procdesc class_decl_opt CContext.create_context tenv cg cfg procdesc class_decl_opt
is_objc_method outer_context_opt in has_return_param is_objc_method outer_context_opt in
let start_node = Cfg.Procdesc.get_start_node procdesc in let start_node = Cfg.Procdesc.get_start_node procdesc in
let exit_node = Cfg.Procdesc.get_exit_node procdesc in let exit_node = Cfg.Procdesc.get_exit_node procdesc in
Printing.log_out Printing.log_out
@ -75,8 +75,9 @@ struct
match body_opt with match body_opt with
| Some body -> (* Only in the case the function declaration has a defined body we create a procdesc *) | Some body -> (* Only in the case the function declaration has a defined body we create a procdesc *)
let procname = CMethod_signature.ms_get_name ms in let procname = CMethod_signature.ms_get_name ms in
let has_return_param = CMethod_signature.ms_has_return_param ms in
if CMethod_trans.create_local_procdesc cfg tenv ms [body] captured_vars false then if CMethod_trans.create_local_procdesc cfg tenv ms [body] captured_vars false then
add_method tenv cg cfg CContext.ContextNoCls procname [body] false add_method tenv cg cfg CContext.ContextNoCls procname [body] has_return_param false
captured_vars outer_context_opt extra_instrs captured_vars outer_context_opt extra_instrs
| None -> () | None -> ()
@ -88,8 +89,10 @@ struct
let is_instance = CMethod_signature.ms_is_instance ms in let is_instance = CMethod_signature.ms_is_instance ms in
let procname = CMethod_signature.ms_get_name ms in let procname = CMethod_signature.ms_get_name ms in
let is_objc_inst_method = is_instance && is_objc in let is_objc_inst_method = is_instance && is_objc in
let has_return_param = CMethod_signature.ms_has_return_param ms in
if CMethod_trans.create_local_procdesc cfg tenv ms [body] [] is_objc_inst_method then if CMethod_trans.create_local_procdesc cfg tenv ms [body] [] is_objc_inst_method then
add_method tenv cg cfg curr_class procname [body] is_objc [] None extra_instrs add_method tenv cg cfg curr_class procname [body] has_return_param is_objc []
None extra_instrs
| None -> () | None -> ()
let process_one_method_decl tenv cg cfg curr_class dec = let process_one_method_decl tenv cg cfg curr_class dec =

@ -20,6 +20,7 @@ type method_signature = {
_language : CFrontend_config.lang; _language : CFrontend_config.lang;
_pointer_to_parent : Clang_ast_t.pointer option; _pointer_to_parent : Clang_ast_t.pointer option;
_pointer_to_property_opt : Clang_ast_t.pointer option; (* If set then method is a getter/setter *) _pointer_to_property_opt : Clang_ast_t.pointer option; (* If set then method is a getter/setter *)
_has_return_param : bool;
} }
let ms_get_name ms = let ms_get_name ms =
@ -52,6 +53,9 @@ let ms_get_pointer_to_parent ms =
let ms_get_pointer_to_property_opt ms = let ms_get_pointer_to_property_opt ms =
ms._pointer_to_property_opt ms._pointer_to_property_opt
let ms_has_return_param ms =
ms._has_return_param
(* A method is a getter if it has a link to a property and *) (* A method is a getter if it has a link to a property and *)
(* it has 1 argument (this includes self) *) (* it has 1 argument (this includes self) *)
let ms_is_getter ms = let ms_is_getter ms =
@ -65,7 +69,7 @@ let ms_is_setter ms =
IList.length ms._args == 2 IList.length ms._args == 2
let make_ms procname args ret_type attributes loc is_instance lang pointer_to_parent let make_ms procname args ret_type attributes loc is_instance lang pointer_to_parent
pointer_to_property_opt = pointer_to_property_opt ~has_return_param =
let meth_signature = { let meth_signature = {
_name = procname; _name = procname;
_args = args; _args = args;
@ -76,6 +80,7 @@ let make_ms procname args ret_type attributes loc is_instance lang pointer_to_pa
_language = lang; _language = lang;
_pointer_to_parent = pointer_to_parent; _pointer_to_parent = pointer_to_parent;
_pointer_to_property_opt = pointer_to_property_opt; _pointer_to_property_opt = pointer_to_property_opt;
_has_return_param = has_return_param;
} in } in
meth_signature meth_signature

@ -33,13 +33,16 @@ val ms_get_pointer_to_parent : method_signature -> Clang_ast_t.pointer option
val ms_get_pointer_to_property_opt : method_signature -> Clang_ast_t.pointer option val ms_get_pointer_to_property_opt : method_signature -> Clang_ast_t.pointer option
val ms_has_return_param : method_signature -> bool
val ms_is_getter : method_signature -> bool val ms_is_getter : method_signature -> bool
val ms_is_setter : method_signature -> bool val ms_is_setter : method_signature -> bool
val make_ms : Procname.t -> (string * Clang_ast_t.type_ptr) list -> Clang_ast_t.type_ptr val make_ms : Procname.t -> (string * Clang_ast_t.type_ptr) list -> Clang_ast_t.type_ptr
-> Clang_ast_t.attribute list -> Clang_ast_t.source_range -> bool -> CFrontend_config.lang -> Clang_ast_t.attribute list -> Clang_ast_t.source_range -> bool -> CFrontend_config.lang
-> Clang_ast_t.pointer option -> Clang_ast_t.pointer option -> method_signature -> Clang_ast_t.pointer option -> Clang_ast_t.pointer option -> has_return_param : bool
-> method_signature
val replace_name_ms : method_signature -> Procname.t -> method_signature val replace_name_ms : method_signature -> Procname.t -> method_signature

@ -102,24 +102,25 @@ let get_parameters tenv function_method_decl_info =
let pars = IList.map par_to_ms_par (get_param_decls function_method_decl_info) in let pars = IList.map par_to_ms_par (get_param_decls function_method_decl_info) in
get_class_param function_method_decl_info @ pars @ get_return_param tenv function_method_decl_info get_class_param function_method_decl_info @ pars @ get_return_param tenv function_method_decl_info
(** get return type of the function and whether function has return parameter *)
let get_return_type tenv function_method_decl_info = let get_return_type tenv function_method_decl_info =
let return_type_ptr = get_original_return_type function_method_decl_info in let return_type_ptr = get_original_return_type function_method_decl_info in
let return_typ = CTypes_decl.type_ptr_to_sil_type tenv return_type_ptr in let return_typ = CTypes_decl.type_ptr_to_sil_type tenv return_type_ptr in
if should_add_return_param return_typ then if should_add_return_param return_typ then
Ast_expressions.create_void_type Ast_expressions.create_void_type, true
else return_type_ptr else return_type_ptr, false
let build_method_signature tenv decl_info procname function_method_decl_info is_anonym_block let build_method_signature tenv decl_info procname function_method_decl_info is_anonym_block
parent_pointer pointer_to_property_opt = parent_pointer pointer_to_property_opt =
let source_range = decl_info.Clang_ast_t.di_source_range in let source_range = decl_info.Clang_ast_t.di_source_range in
let tp = get_return_type tenv function_method_decl_info in let tp, has_return_param = get_return_type tenv function_method_decl_info in
let is_instance_method = is_instance_method function_method_decl_info in let is_instance_method = is_instance_method function_method_decl_info in
let parameters = get_parameters tenv function_method_decl_info in let parameters = get_parameters tenv function_method_decl_info in
let attributes = decl_info.Clang_ast_t.di_attributes in let attributes = decl_info.Clang_ast_t.di_attributes in
let lang = get_language function_method_decl_info in let lang = get_language function_method_decl_info in
CMethod_signature.make_ms CMethod_signature.make_ms
procname parameters tp attributes source_range is_instance_method lang parent_pointer procname parameters tp attributes source_range is_instance_method lang parent_pointer
pointer_to_property_opt pointer_to_property_opt ~has_return_param
let get_assume_not_null_calls param_decls = let get_assume_not_null_calls param_decls =
let do_one_param decl = match decl with let do_one_param decl = match decl with
@ -436,7 +437,7 @@ let get_method_for_frontend_checks cfg cg tenv class_name decl_info =
| None -> | None ->
let ms_type_ptr = Clang_ast_types.pointer_to_type_ptr (Ast_utils.get_invalid_pointer ()) in let ms_type_ptr = Clang_ast_types.pointer_to_type_ptr (Ast_utils.get_invalid_pointer ()) in
let ms = CMethod_signature.make_ms proc_name [] ms_type_ptr [] source_range false let ms = CMethod_signature.make_ms proc_name [] ms_type_ptr [] source_range false
CFrontend_config.OBJC None None in CFrontend_config.OBJC None None false in
let body = [Clang_ast_t.CompoundStmt (stmt_info, [])] in let body = [Clang_ast_t.CompoundStmt (stmt_info, [])] in
ignore (create_local_procdesc cfg tenv ms body [] false); ignore (create_local_procdesc cfg tenv ms body [] false);
let pdesc = Option.get (Cfg.Procdesc.find_from_name cfg proc_name) in let pdesc = Option.get (Cfg.Procdesc.find_from_name cfg proc_name) in

@ -127,7 +127,7 @@ let get_predefined_ms_method condition class_name method_name method_kind mk_pro
| Some procname -> procname | Some procname -> procname
| None -> mk_procname class_name method_name method_kind in | None -> mk_procname class_name method_name method_kind in
let ms = CMethod_signature.make_ms procname arguments return_type attributes let ms = CMethod_signature.make_ms procname arguments return_type attributes
(Ast_expressions.dummy_source_range ()) false lang None None in (Ast_expressions.dummy_source_range ()) false lang None None false in
Some ms Some ms
else None else None

Loading…
Cancel
Save