[inferbo] Address __return_param on function calls

Summary: In SIL, sometimes a return value is assigned to `__return_param`.

Reviewed By: ezgicicek, mbouaziz

Differential Revision: D14538590

fbshipit-source-id: dfbb74dc2
master
Sungkeun Cho 6 years ago committed by Facebook Github Bot
parent ce7850a8d0
commit a46130655e

@ -156,6 +156,9 @@ end
(** Name used for the return variable *)
let name_return = Mangled.from_string "return"
(** Name used for the return param variable *)
let name_return_param = Mangled.from_string "__return_param"
(** Return the standard name for the given kind *)
let standard_name kind =
if equal_kind kind KNormal || equal_kind kind KNone then Name.Normal

@ -67,6 +67,9 @@ val name_spec : name
val name_return : Mangled.t
(** Name used for the return variable *)
val name_return_param : Mangled.t
(** Name used for the return param variable *)
val string_to_name : string -> name
(** Convert a string to a name. *)

@ -213,6 +213,8 @@ let mk (name : Mangled.t) (proc_name : Typ.Procname.t) : t =
let get_ret_pvar pname = mk Ident.name_return pname
let get_ret_param_pvar pname = mk Ident.name_return_param pname
(** [mk_callee name proc_name] creates a program var
for a callee function with the given function name *)
let mk_callee (name : Mangled.t) (proc_name : Typ.Procname.t) : t =

@ -39,6 +39,9 @@ val get_name : t -> Mangled.t
val get_ret_pvar : Typ.Procname.t -> t
(** [get_ret_pvar proc_name] retuns the return pvar associated with the procedure name *)
val get_ret_param_pvar : Typ.Procname.t -> t
(** [get_ret_param_pvar proc_name] retuns the return_param pvar associated with the procedure name *)
val get_simplified_name : t -> string
(** Get a simplified version of the name component of a program variable. *)

@ -94,7 +94,13 @@ module TransferFunctions = struct
Option.value_map ret_alias ~default:mem ~f:(fun l -> Dom.Mem.load_alias ret_id l mem)
in
let ret_var = Loc.of_var (Var.of_id ret_id) in
let ret_val = Dom.Mem.find (Loc.of_pvar (Pvar.get_ret_pvar callee_pname)) callee_exit_mem in
let ret_val =
let val_of_return_var =
Dom.Mem.find_opt (Loc.of_pvar (Pvar.get_ret_pvar callee_pname)) callee_exit_mem
in
IOption.value_default_f val_of_return_var ~f:(fun () ->
Dom.Val.of_loc (Loc.of_pvar (Pvar.get_ret_param_pvar callee_pname)) )
in
Dom.Mem.add_stack ret_var (Dom.Val.subst ret_val eval_sym_trace location) mem
|> instantiate_ret_alias
|> copy_reachable_locs_from (PowLoc.join formal_locs (Dom.Val.get_all_locs ret_val))

@ -26,3 +26,27 @@ void call_by_ref_bad() {
ref_set_to_zero(i);
arr[i - 1] = 123;
}
struct S init_S(int x) {
struct S s = {x};
return s;
}
int loop_with_init_S(int length) {
int i = 0;
while (i < length) {
struct S s = init_S(i + 1);
i = s.field;
}
return i;
}
void call_loop_with_init_S_Good() {
int a[10];
a[loop_with_init_S(5)] = 0;
}
void call_loop_with_init_S_Bad() {
int a[10];
a[loop_with_init_S(10)] = 0;
}

@ -51,6 +51,7 @@ codetoanalyze/cpp/bufferoverrun/folly_split.cpp, folly_split::do_not_ignore_empt
codetoanalyze/cpp/bufferoverrun/folly_split.cpp, folly_split::do_not_ignore_empty_Bad, 3, INTEGER_OVERFLOW_L5, no_bucket, ERROR, [Call,Call,Assignment,Through,Call,Parameter `this->infer_size`,Call,<RHS trace>,Parameter `this->infer_size`,Binary operation: (4 × [0, +oo]):unsigned64]
codetoanalyze/cpp/bufferoverrun/folly_split.cpp, folly_split::do_not_ignore_empty_Good, 3, INTEGER_OVERFLOW_L5, no_bucket, ERROR, [Call,Call,Assignment,Through,Call,Parameter `this->infer_size`,Call,<RHS trace>,Parameter `this->infer_size`,Binary operation: (4 × [1, +oo]):unsigned64]
codetoanalyze/cpp/bufferoverrun/function_call.cpp, call_by_ref_bad, 4, BUFFER_OVERRUN_L1, no_bucket, ERROR, [<Offset trace>,Call,Assignment,<Length trace>,Array declaration,Array access: Offset: -1 Size: 10]
codetoanalyze/cpp/bufferoverrun/function_call.cpp, call_loop_with_init_S_Bad, 2, BUFFER_OVERRUN_L1, no_bucket, ERROR, [<Offset trace>,Call,Parameter `length`,Assignment,<Length trace>,Array declaration,Array access: Offset: 10 Size: 10]
codetoanalyze/cpp/bufferoverrun/realloc.cpp, realloc_Bad, 4, BUFFER_OVERRUN_L1, no_bucket, ERROR, [<Offset trace>,Assignment,<Length trace>,Array declaration,Assignment,Array access: Offset: 5 Size: 5]
codetoanalyze/cpp/bufferoverrun/realloc.cpp, realloc_flexible_array_Bad, 4, BUFFER_OVERRUN_L1, no_bucket, ERROR, [<Length trace>,Array declaration,Array access: Offset: 7 Size: 5]
codetoanalyze/cpp/bufferoverrun/realloc.cpp, realloc_struct1_Bad, 4, BUFFER_OVERRUN_L1, no_bucket, ERROR, [<Offset trace>,Assignment,<Length trace>,Array declaration,Assignment,Array access: Offset: 5 Size: 5]

Loading…
Cancel
Save