diff --git a/infer/src/backend/sil.ml b/infer/src/backend/sil.ml index fba5eef30..4d71f9fbe 100644 --- a/infer/src/backend/sil.ml +++ b/infer/src/backend/sil.ml @@ -571,11 +571,17 @@ end (** Flags for a procedure call *) type call_flags = { cf_virtual : bool; + cf_interface : bool; cf_noreturn : bool; cf_is_objc_block : bool; } -let cf_default = { cf_virtual = false; cf_noreturn = false; cf_is_objc_block = false; } +let cf_default = + { cf_virtual = false; + cf_interface = false; + cf_noreturn = false; + cf_is_objc_block = false; + } (** expression representing the result of decompilation *) type dexp = @@ -3449,8 +3455,10 @@ let instr_sub (subst: subst) instr = Goto_node (exp_s e, loc) let call_flags_compare cflag1 cflag2 = - let n = bool_compare cflag1.cf_virtual cflag2.cf_virtual in - if n <> 0 then n else bool_compare cflag1.cf_noreturn cflag2.cf_noreturn + bool_compare cflag1.cf_virtual cflag2.cf_virtual + |> next bool_compare cflag1.cf_interface cflag2.cf_interface + |> next bool_compare cflag1.cf_noreturn cflag2.cf_noreturn + |> next bool_compare cflag1.cf_is_objc_block cflag2.cf_is_objc_block let exp_typ_compare (exp1, typ1) (exp2, typ2) = let n = exp_compare exp1 exp2 in diff --git a/infer/src/backend/sil.mli b/infer/src/backend/sil.mli index 1868460dd..9e1dec6e6 100644 --- a/infer/src/backend/sil.mli +++ b/infer/src/backend/sil.mli @@ -209,7 +209,8 @@ end (** Flags for a procedure call *) type call_flags = { - cf_virtual: bool; + cf_virtual : bool; + cf_interface : bool; cf_noreturn : bool; cf_is_objc_block : bool; } diff --git a/infer/src/clang/cTrans.ml b/infer/src/clang/cTrans.ml index c440c69cb..a018e7250 100644 --- a/infer/src/clang/cTrans.ml +++ b/infer/src/clang/cTrans.ml @@ -691,7 +691,7 @@ struct | None -> let ret_id = if (Sil.typ_equal function_type Sil.Tvoid) then [] else [Ident.create_fresh Ident.knormal] in - let call_flags = { Sil.cf_virtual = false; Sil.cf_noreturn = false; Sil.cf_is_objc_block = is_call_to_block; } in + let call_flags = { Sil.cf_default with Sil.cf_is_objc_block = is_call_to_block; } in let call_instr = Sil.Call(ret_id, sil_fe, act_params, sil_loc, call_flags) in ret_id, call_instr in @@ -743,6 +743,7 @@ struct else [Ident.create_fresh Ident.knormal] in let call_flags = { Sil.cf_virtual = false (* TODO t7725350 *); + Sil.cf_interface = false; Sil.cf_noreturn = false; Sil.cf_is_objc_block = false; } in @@ -870,10 +871,7 @@ struct let ret_id = if Sil.typ_equal method_type Sil.Tvoid then [] else [Ident.create_fresh Ident.knormal] in - let call_flags = { - Sil.cf_virtual = is_virtual; - Sil.cf_noreturn = false; - Sil.cf_is_objc_block = false; } in + let call_flags = { Sil.cf_default with Sil.cf_virtual = is_virtual; } in let stmt_call = Sil.Call (ret_id, (Sil.Const (Sil.Cfun callee_name)), param_exps, sil_loc, call_flags) in let selector = obj_c_message_expr_info.Clang_ast_t.omei_selector in diff --git a/infer/src/clang/cTrans_utils.ml b/infer/src/clang/cTrans_utils.ml index 31c427927..fbc9c51ac 100644 --- a/infer/src/clang/cTrans_utils.ml +++ b/infer/src/clang/cTrans_utils.ml @@ -303,7 +303,7 @@ let objc_new_trans trans_state loc stmt_info cls_name function_type = create_alloc_instrs trans_state.context loc function_type fname in let init_ret_id = Ident.create_fresh Ident.knormal in let is_instance = true in - let call_flags = { Sil.cf_virtual = is_instance; Sil.cf_noreturn = false; Sil.cf_is_objc_block = false; } in + let call_flags = { Sil.cf_default with Sil.cf_virtual = is_instance; } in let pname = General_utils.mk_procname_from_objc_method cls_name CFrontend_config.init Procname.Instance_objc_method in CMethod_trans.create_external_procdesc trans_state.context.CContext.cfg pname is_instance None; let args = [(Sil.Var alloc_ret_id, alloc_ret_type)] in diff --git a/infer/src/harness/inhabit.ml b/infer/src/harness/inhabit.ml index 666222adb..9f5bc46ee 100644 --- a/infer/src/harness/inhabit.ml +++ b/infer/src/harness/inhabit.ml @@ -178,9 +178,7 @@ let inhabit_call_with_args procname procdesc args env = if is_void then [] else [Ident.create_fresh Ident.knormal] in let call_instr = let fun_exp = fun_exp_from_name procname in - let flags = - let cf_virtual = not (Procname.java_is_static procname) in - { Sil.cf_virtual = cf_virtual; Sil.cf_noreturn = false; Sil.cf_is_objc_block = false; } in + let flags = { Sil.cf_default with Sil.cf_virtual = not (Procname.java_is_static procname); } in Sil.Call (retval, fun_exp, args, env.pc, flags) in env_add_instr call_instr retval env diff --git a/infer/src/java/jTrans.ml b/infer/src/java/jTrans.ml index 9265b8ff6..660ee05e0 100644 --- a/infer/src/java/jTrans.ml +++ b/infer/src/java/jTrans.ml @@ -558,11 +558,12 @@ let method_invocation context loc pc var_opt cn ms sil_obj_opt expr_list invoke_ let program = JContext.get_program context in if JConfig.create_callee_procdesc then ignore (get_method_procdesc program cfg tenv cn ms method_kind); - let cf_virtual = match invoke_code with - | I_Virtual -> true - | _ -> false in + let cf_virtual, cf_interface = match invoke_code with + | I_Virtual -> (true, false) + | I_Interface -> (true, true) + | _ -> (false, false) in let call_flags = - { Sil.cf_virtual = cf_virtual; Sil.cf_noreturn = false; Sil.cf_is_objc_block = false; } in + { Sil.cf_default with Sil.cf_virtual = cf_virtual; Sil.cf_interface = cf_interface; } in let init = match sil_obj_opt with | None -> ([], [], []) @@ -788,7 +789,7 @@ let assume_not_null loc sil_expr = let builtin_infer_assume = Sil.Const (Sil.Cfun SymExec.ModelBuiltins.__infer_assume) in let not_null_expr = Sil.BinOp (Sil.Ne, sil_expr, Sil.exp_null) in - let assume_call_flag = { Sil.cf_virtual = false; Sil.cf_noreturn = true; Sil.cf_is_objc_block = false; } in + let assume_call_flag = { Sil.cf_default with Sil.cf_noreturn = true; } in let call_args = [(not_null_expr, Sil.Tint Sil.IBool)] in Sil.Call ([], builtin_infer_assume, call_args, loc, assume_call_flag) @@ -996,7 +997,8 @@ let rec instruction context pc instr : translation = let instr = instruction_array_call ms obj_type obj args var_opt vt in instruction context pc instr end - | JBir.InterfaceCall cn -> trans_virtual_call cn + | JBir.InterfaceCall cn -> + trans_virtual_call cn end | JBir.InvokeNonVirtual (var_opt, obj, cn, ms, args) -> let cn = (resolve_method context cn ms) in