Pass return parameter type in context

Summary:
public
Add type of return parameter to the context. It allows for better translation
of returnStmt and will be necessary for easy implementation of constructor init lists

Reviewed By: cristianoc

Differential Revision: D2890838

fb-gh-sync-id: e791c3d
master
Andrzej Kotulski 9 years ago committed by facebook-github-bot-7
parent 028ac24d46
commit 7cabc86f77

@ -30,19 +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; return_param_typ : Sil.typ option;
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 ~has_return_param is_objc_method context_opt = let create_context tenv cg cfg procdesc curr_class return_param_typ 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; return_param_typ = return_param_typ;
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,7 +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; return_param_typ : Sil.typ option;
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;
@ -54,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 -> has_return_param : bool -> bool -> t option -> t curr_class -> Sil.typ option -> bool -> t option -> t
val create_curr_class : Sil.tenv -> string -> Csu.class_kind -> curr_class val create_curr_class : Sil.tenv -> string -> Csu.class_kind -> curr_class

@ -75,9 +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 let return_param_typ_opt = CMethod_signature.ms_get_return_param_typ 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 has_return_param false add_method tenv cg cfg CContext.ContextNoCls procname body return_param_typ_opt false
captured_vars outer_context_opt extra_instrs captured_vars outer_context_opt extra_instrs
| None -> () | None -> ()
@ -89,9 +89,9 @@ 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 let return_param_typ_opt = CMethod_signature.ms_get_return_param_typ 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 has_return_param is_objc [] add_method tenv cg cfg curr_class procname body return_param_typ_opt is_objc []
None extra_instrs None extra_instrs
| None -> () | None -> ()

@ -20,7 +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; return_param_typ : Sil.typ option;
} }
let ms_get_name { name } = let ms_get_name { name } =
@ -53,8 +53,8 @@ let ms_get_pointer_to_parent { pointer_to_parent } =
let ms_get_pointer_to_property_opt { pointer_to_property_opt } = let ms_get_pointer_to_property_opt { pointer_to_property_opt } =
pointer_to_property_opt pointer_to_property_opt
let ms_has_return_param { has_return_param } = let ms_get_return_param_typ { return_param_typ } =
has_return_param return_param_typ
(* 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) *)
@ -69,7 +69,7 @@ let ms_is_setter { pointer_to_property_opt; args } =
IList.length args == 2 IList.length args == 2
let make_ms name args ret_type attributes loc is_instance language pointer_to_parent let make_ms name args ret_type attributes loc is_instance language pointer_to_parent
pointer_to_property_opt ~has_return_param = pointer_to_property_opt return_param_typ =
{ {
name; name;
args; args;
@ -80,7 +80,7 @@ let make_ms name args ret_type attributes loc is_instance language pointer_to_pa
language; language;
pointer_to_parent; pointer_to_parent;
pointer_to_property_opt; pointer_to_property_opt;
has_return_param; return_param_typ;
} }
let replace_name_ms ms name = let replace_name_ms ms name =

@ -33,7 +33,7 @@ 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_get_return_param_typ : method_signature -> Sil.typ option
val ms_is_getter : method_signature -> bool val ms_is_getter : method_signature -> bool
@ -41,7 +41,7 @@ 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 -> has_return_param : bool -> Clang_ast_t.pointer option -> Clang_ast_t.pointer option -> Sil.typ option
-> method_signature -> method_signature
val replace_name_ms : method_signature -> Procname.t -> method_signature val replace_name_ms : method_signature -> Procname.t -> method_signature

@ -109,26 +109,26 @@ 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 *) (** get return type of the function and optionally type of function's 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
let is_objc_method = is_objc_method function_method_decl_info in let is_objc_method = is_objc_method function_method_decl_info in
if should_add_return_param return_typ is_objc_method then if should_add_return_param return_typ is_objc_method then
Ast_expressions.create_void_type, true Ast_expressions.create_void_type, Some (Sil.Tptr (return_typ, Sil.Pk_pointer))
else return_type_ptr, false else return_type_ptr, None
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, has_return_param = get_return_type tenv function_method_decl_info in let tp, return_param_type_opt = 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 ~has_return_param pointer_to_property_opt return_param_type_opt
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
@ -446,7 +446,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 false in CFrontend_config.OBJC None None None 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

@ -1750,16 +1750,16 @@ struct
let trans_result = (match stmt_list with let trans_result = (match stmt_list with
| [stmt] -> (* return exp; *) | [stmt] -> (* return exp; *)
let procdesc = context.CContext.procdesc in let procdesc = context.CContext.procdesc in
let ret_exp, var_instrs, var_ids = if context.CContext.has_return_param then let ret_exp, var_instrs, var_ids = match context.CContext.return_param_typ with
let name = CFrontend_config.return_param in | Some ret_param_typ ->
let procname = Cfg.Procdesc.get_proc_name procdesc in let name = CFrontend_config.return_param in
let pvar = Sil.mk_pvar (Mangled.from_string name) procname in let procname = Cfg.Procdesc.get_proc_name procdesc in
let id = Ident.create_fresh Ident.knormal in let pvar = Sil.mk_pvar (Mangled.from_string name) procname in
let ret_type_ptr = Sil.Tptr (Sil.Tvoid, Sil.Pk_pointer) in let id = Ident.create_fresh Ident.knormal in
let instr = Sil.Letderef (id, Sil.Lvar pvar, ret_type_ptr, sil_loc) in let instr = Sil.Letderef (id, Sil.Lvar pvar, ret_param_typ, sil_loc) in
Sil.Var id, [instr], [id] Sil.Var id, [instr], [id]
else | None ->
Sil.Lvar (Cfg.Procdesc.get_ret_var procdesc), [], [] in Sil.Lvar (Cfg.Procdesc.get_ret_var procdesc), [], [] in
let ret_type = Cfg.Procdesc.get_ret_type procdesc in let ret_type = Cfg.Procdesc.get_ret_type procdesc in
let trans_state' = { trans_state_pri with succ_nodes = []; var_exp = Some ret_exp} in let trans_state' = { trans_state_pri with succ_nodes = []; var_exp = Some ret_exp} in
let res_trans_stmt = exec_with_self_exception instruction trans_state' stmt in let res_trans_stmt = exec_with_self_exception instruction trans_state' stmt 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 false in (Ast_expressions.dummy_source_range ()) false lang None None None in
Some ms Some ms
else None else None

@ -91,7 +91,7 @@ digraph iCFG {
19 -> 22 ; 19 -> 22 ;
18 [label="18: Return Stmt \n n$0=*&__return_param:void * [line 24]\n n$2=*&a:int [line 24]\n n$3=*&b:int [line 24]\n _fun_X_X(&SIL_materialize_temp__n$1:class X *,n$2:int ,n$3:int ) [line 24]\n _fun_X_X(n$0:class X *,&SIL_materialize_temp__n$1:class X &) [line 24]\n REMOVE_TEMPS(n$0,n$2,n$3); [line 24]\n NULLIFY(&__return_param,false); [line 24]\n NULLIFY(&a,false); [line 24]\n NULLIFY(&b,false); [line 24]\n NULLIFY(&SIL_materialize_temp__n$1,false); [line 24]\n APPLY_ABSTRACTION; [line 24]\n " shape="box"] 18 [label="18: Return Stmt \n n$0=*&__return_param:class X * [line 24]\n n$2=*&a:int [line 24]\n n$3=*&b:int [line 24]\n _fun_X_X(&SIL_materialize_temp__n$1:class X *,n$2:int ,n$3:int ) [line 24]\n _fun_X_X(n$0:class X *,&SIL_materialize_temp__n$1:class X &) [line 24]\n REMOVE_TEMPS(n$0,n$2,n$3); [line 24]\n NULLIFY(&__return_param,false); [line 24]\n NULLIFY(&a,false); [line 24]\n NULLIFY(&b,false); [line 24]\n NULLIFY(&SIL_materialize_temp__n$1,false); [line 24]\n APPLY_ABSTRACTION; [line 24]\n " shape="box"]
18 -> 17 ; 18 -> 17 ;

@ -174,7 +174,7 @@ digraph iCFG {
18 -> 19 ; 18 -> 19 ;
17 [label="17: Return Stmt \n n$0=*&__return_param:void * [line 21]\n n$2=*&this:class Y * [line 21]\n n$3=*n$2.f:int [line 21]\n n$4=*&this:class Y * [line 21]\n n$5=*n$4.b:int [line 21]\n _fun_X_X(&SIL_materialize_temp__n$1:class X *,n$3:int ,n$5:_Bool ) [line 21]\n _fun_X_X(n$0:class X *,&SIL_materialize_temp__n$1:class X &) [line 21]\n REMOVE_TEMPS(n$0,n$2,n$3,n$4,n$5); [line 21]\n NULLIFY(&__return_param,false); [line 21]\n NULLIFY(&this,false); [line 21]\n NULLIFY(&SIL_materialize_temp__n$1,false); [line 21]\n APPLY_ABSTRACTION; [line 21]\n " shape="box"] 17 [label="17: Return Stmt \n n$0=*&__return_param:class X * [line 21]\n n$2=*&this:class Y * [line 21]\n n$3=*n$2.f:int [line 21]\n n$4=*&this:class Y * [line 21]\n n$5=*n$4.b:int [line 21]\n _fun_X_X(&SIL_materialize_temp__n$1:class X *,n$3:int ,n$5:_Bool ) [line 21]\n _fun_X_X(n$0:class X *,&SIL_materialize_temp__n$1:class X &) [line 21]\n REMOVE_TEMPS(n$0,n$2,n$3,n$4,n$5); [line 21]\n NULLIFY(&__return_param,false); [line 21]\n NULLIFY(&this,false); [line 21]\n NULLIFY(&SIL_materialize_temp__n$1,false); [line 21]\n APPLY_ABSTRACTION; [line 21]\n " shape="box"]
17 -> 16 ; 17 -> 16 ;

@ -18,7 +18,7 @@ digraph iCFG {
8 -> 7 ; 8 -> 7 ;
7 [label="7: Return Stmt \n n$0=*&__return_param:void * [line 17]\n _fun_X_X(n$0:class X *,&x:class X &) [line 17]\n REMOVE_TEMPS(n$0); [line 17]\n NULLIFY(&__return_param,false); [line 17]\n NULLIFY(&x,false); [line 17]\n APPLY_ABSTRACTION; [line 17]\n " shape="box"] 7 [label="7: Return Stmt \n n$0=*&__return_param:class X * [line 17]\n _fun_X_X(n$0:class X *,&x:class X &) [line 17]\n REMOVE_TEMPS(n$0); [line 17]\n NULLIFY(&__return_param,false); [line 17]\n NULLIFY(&x,false); [line 17]\n APPLY_ABSTRACTION; [line 17]\n " shape="box"]
7 -> 6 ; 7 -> 6 ;

@ -85,7 +85,7 @@ digraph iCFG {
13 -> 12 ; 13 -> 12 ;
12 [label="12: Return Stmt \n n$0=*&__return_param:void * [line 23]\n _fun_X_X(n$0:class X *,&x:class X &) [line 23]\n REMOVE_TEMPS(n$0); [line 23]\n NULLIFY(&__return_param,false); [line 23]\n NULLIFY(&x,false); [line 23]\n APPLY_ABSTRACTION; [line 23]\n " shape="box"] 12 [label="12: Return Stmt \n n$0=*&__return_param:class X * [line 23]\n _fun_X_X(n$0:class X *,&x:class X &) [line 23]\n REMOVE_TEMPS(n$0); [line 23]\n NULLIFY(&__return_param,false); [line 23]\n NULLIFY(&x,false); [line 23]\n APPLY_ABSTRACTION; [line 23]\n " shape="box"]
12 -> 11 ; 12 -> 11 ;

Loading…
Cancel
Save