Translate builtin_expect as its first argument. Avoids weird symb. exec. problems

Reviewed By: akotulski

Differential Revision: D3348097

fbshipit-source-id: 8f19072
master
Dulma Churchill 9 years ago committed by Facebook Github Bot 2
parent e873a2c502
commit bf9d194e43

@ -84,8 +84,6 @@ clock_t __infer_nondet_clock_t() {
return t;
}
long infer__builtin_expect(long e, long x) { return e; }
void* infer__builtin___memset_chk(void* dest,
int val,
unsigned long len,

@ -212,6 +212,7 @@ let whitelisted_cpp_methods = [
["google"; "Check_NEImpl"];
["google"; "Check_LEImpl"];
["google"; "Check_GTImpl"];
["google"; "Check_GEImpl"];
["google"; "Check_EQImpl"]
]

@ -860,29 +860,34 @@ struct
CTrans_utils.builtin_trans trans_state_pri sil_loc si function_type callee_pname_opt with
| Some builtin -> builtin
| None ->
let res_trans_call =
match cast_trans context act_params sil_loc callee_pname_opt function_type with
| Some (instr, cast_exp) ->
{ empty_res_trans with
instrs = [instr];
exps = [(cast_exp, function_type)]; }
| None ->
let call_flags = { Sil.cf_default with Sil.cf_is_objc_block = is_call_to_block; } in
create_call_instr trans_state function_type sil_fe act_params sil_loc call_flags
~is_objc_method:false in
let nname = "Call "^(Sil.exp_to_string sil_fe) in
let all_res_trans = result_trans_subexprs @ [res_trans_call] in
let res_trans_to_parent =
PriorityNode.compute_results_to_parent trans_state_pri sil_loc nname si all_res_trans in
(match callee_pname_opt with
| Some callee_pname ->
let open CContext in
if not (Builtin.is_registered callee_pname) then
begin
Cg.add_edge context.cg procname callee_pname;
end
| None -> ());
{ res_trans_to_parent with exps = res_trans_call.exps }
(* Translate call to __builtin_expect as the first argument *)
(* for simpler symbolic execution *)
match callee_pname_opt, result_trans_subexprs with
| Some pname, [_; fst_arg_res; _]
when Procname.to_string pname = CFrontend_config.builtin_expect ->
fst_arg_res
| _ ->
let res_trans_call =
match cast_trans context act_params sil_loc callee_pname_opt function_type with
| Some (instr, cast_exp) ->
{ empty_res_trans with
instrs = [instr];
exps = [(cast_exp, function_type)]; }
| None ->
let call_flags =
{ Sil.cf_default with Sil.cf_is_objc_block = is_call_to_block; } in
create_call_instr trans_state function_type sil_fe act_params sil_loc
call_flags ~is_objc_method:false in
let nname = "Call "^(Sil.exp_to_string sil_fe) in
let all_res_trans = result_trans_subexprs @ [res_trans_call] in
let res_trans_to_parent = PriorityNode.compute_results_to_parent trans_state_pri
sil_loc nname si all_res_trans in
(match callee_pname_opt with
| Some callee_pname ->
if not (Builtin.is_registered callee_pname) then
Cg.add_edge context.CContext.cg procname callee_pname
| None -> ());
{ res_trans_to_parent with exps = res_trans_call.exps }
and cxx_method_construct_call_trans trans_state_pri result_trans_callee params_stmt
si function_type is_cpp_call_virtual =
@ -900,31 +905,31 @@ struct
CTrans_utils.trans_assertion sil_loc context trans_state_pri.succ_nodes
else
(* As we may have nodes coming from different parameters we need to *)
(* call instruction for each parameter and collect the results *)
(* afterwards. The 'instructions' function does not do that *)
let trans_state_param =
{ trans_state_pri with succ_nodes = []; var_exp_typ = None } in
let result_trans_subexprs =
let instruction' = exec_with_self_exception (exec_with_glvalue_as_reference instruction) in
let res_trans_p = IList.map (instruction' trans_state_param) params_stmt in
result_trans_callee :: res_trans_p in
(* first expr is method address, rest are params including 'this' parameter *)
let actual_params = IList.tl (collect_exprs result_trans_subexprs) in
let call_flags = {
Sil.cf_virtual = is_cpp_call_virtual;
Sil.cf_interface = false;
Sil.cf_noreturn = false;
Sil.cf_is_objc_block = false;
Sil.cf_targets = [];
} in
let res_trans_call = create_call_instr trans_state_pri function_type sil_method actual_params
sil_loc call_flags ~is_objc_method:false in
let nname = "Call " ^ (Sil.exp_to_string sil_method) in
let all_res_trans = result_trans_subexprs @ [res_trans_call] in
let result_trans_to_parent =
PriorityNode.compute_results_to_parent trans_state_pri sil_loc nname si all_res_trans in
Cg.add_edge context.CContext.cg procname callee_pname;
{ result_trans_to_parent with exps = res_trans_call.exps }
(* call instruction for each parameter and collect the results *)
(* afterwards. The 'instructions' function does not do that *)
let trans_state_param =
{ trans_state_pri with succ_nodes = []; var_exp_typ = None } in
let result_trans_subexprs =
let instruction' = exec_with_self_exception (exec_with_glvalue_as_reference instruction) in
let res_trans_p = IList.map (instruction' trans_state_param) params_stmt in
result_trans_callee :: res_trans_p in
(* first expr is method address, rest are params including 'this' parameter *)
let actual_params = IList.tl (collect_exprs result_trans_subexprs) in
let call_flags = {
Sil.cf_virtual = is_cpp_call_virtual;
Sil.cf_interface = false;
Sil.cf_noreturn = false;
Sil.cf_is_objc_block = false;
Sil.cf_targets = [];
} in
let res_trans_call = create_call_instr trans_state_pri function_type sil_method actual_params
sil_loc call_flags ~is_objc_method:false in
let nname = "Call " ^ (Sil.exp_to_string sil_method) in
let all_res_trans = result_trans_subexprs @ [res_trans_call] in
let result_trans_to_parent =
PriorityNode.compute_results_to_parent trans_state_pri sil_loc nname si all_res_trans in
Cg.add_edge context.CContext.cg procname callee_pname;
{ result_trans_to_parent with exps = res_trans_call.exps }
and cxxMemberCallExpr_trans trans_state si stmt_list expr_info =

@ -70,7 +70,6 @@ let get_builtinname method_name =
else None
let is_modeled_builtin funct =
funct = CFrontend_config.builtin_expect ||
funct = CFrontend_config.builtin_memset_chk
let is_assert_log_s funct =

@ -64,3 +64,8 @@ int check_gt_example(int x) {
CHECK_GT(x, 5);
return x;
}
int empty_check_ok(int index, std::vector<int> v) {
CHECK(index >= 1 && index < v.size());
return v[index]; // doesn't report empty vector
}

Loading…
Cancel
Save