From be891e8413c78c6260caa1a1355454893f85890b Mon Sep 17 00:00:00 2001 From: Andrzej Kotulski Date: Fri, 2 Sep 2016 07:01:34 -0700 Subject: [PATCH] Simplify builtin function detection during translation Summary: Given that mangling now respects `extern "C" {}` declarations, pnames of C function will have no mangling and we don't need to discard mangled part from procname. Move `malloc` detection to `get_builtin_pname_opt` function (together with all others) Reviewed By: dulmarod Differential Revision: D3804402 fbshipit-source-id: 9ae9991 --- infer/models/c/src/infer_builtins.h | 10 ++++++++++ infer/src/clang/ComponentKit.ml | 2 +- infer/src/clang/cFrontend_checkers.ml | 2 +- infer/src/clang/cFrontend_utils.ml | 2 +- infer/src/clang/cFrontend_utils.mli | 2 +- infer/src/clang/cTrans.ml | 21 ++++++--------------- 6 files changed, 20 insertions(+), 19 deletions(-) diff --git a/infer/models/c/src/infer_builtins.h b/infer/models/c/src/infer_builtins.h index ce0a1bcfe..2a978ae17 100644 --- a/infer/models/c/src/infer_builtins.h +++ b/infer/models/c/src/infer_builtins.h @@ -14,6 +14,12 @@ #include #include +#ifdef __cplusplus +// specify C linkage to avoid mangling of names of infer builtins +// they need to have plain C name so backend can recognise it +extern "C" { +#endif + // model returning an arbitrary (nondeterministic) short short __infer_nondet_short(); @@ -72,3 +78,7 @@ extern void __set_array_length(void* ptr, size_t size); // builtin: set the flag to the given value for the procedure where this call // appears extern void __infer_set_flag(char* flag, char* value); + +#ifdef __cplusplus +} // extern "C" +#endif diff --git a/infer/src/clang/ComponentKit.ml b/infer/src/clang/ComponentKit.ml index 81266f98c..05ac2d16e 100644 --- a/infer/src/clang/ComponentKit.ml +++ b/infer/src/clang/ComponentKit.ml @@ -83,7 +83,7 @@ let mutable_local_vars_advice context decl = let is_const = qual_type.qt_is_const || is_const_ref in let condition = context.CLintersContext.is_ck_translation_unit && Ast_utils.is_in_main_file decl - && General_utils.is_objc_extention + && General_utils.is_objc_extension && (not (Ast_utils.is_syntactically_global_var decl)) && (not is_const) in if condition then diff --git a/infer/src/clang/cFrontend_checkers.ml b/infer/src/clang/cFrontend_checkers.ml index fcdc571ac..f0d949490 100644 --- a/infer/src/clang/cFrontend_checkers.ml +++ b/infer/src/clang/cFrontend_checkers.ml @@ -200,7 +200,7 @@ let global_var_init_with_calls_warning _ decl = match Clang_ast_proj.get_named_decl_tuple decl with | Some (di, ndi) -> di, ndi.ni_name | None -> assert false (* we cannot be here *) in - let condition = General_utils.is_objc_extention + let condition = General_utils.is_objc_extension && Ast_utils.is_syntactically_global_var decl && (not (Ast_utils.is_const_expr_var decl)) && is_initialized_with_expensive_call decl in diff --git a/infer/src/clang/cFrontend_utils.ml b/infer/src/clang/cFrontend_utils.ml index 6d92a6db5..75f24aa02 100644 --- a/infer/src/clang/cFrontend_utils.ml +++ b/infer/src/clang/cFrontend_utils.ml @@ -589,7 +589,7 @@ struct let is_cpp_translation = Config.clang_lang = Config.CPP || Config.clang_lang = Config.OBJCPP - let is_objc_extention = + let is_objc_extension = Config.clang_lang = Config.OBJC || Config.clang_lang = Config.OBJCPP let rec get_mangled_method_name function_decl_info method_decl_info = diff --git a/infer/src/clang/cFrontend_utils.mli b/infer/src/clang/cFrontend_utils.mli index b3494edf3..7b457ce17 100644 --- a/infer/src/clang/cFrontend_utils.mli +++ b/infer/src/clang/cFrontend_utils.mli @@ -231,6 +231,6 @@ sig val is_cpp_translation : bool (** true if Config.clang_lang is ObjC or ObjC++ *) - val is_objc_extention : bool + val is_objc_extension : bool end diff --git a/infer/src/clang/cTrans.ml b/infer/src/clang/cTrans.ml index 0f73cdee0..a455a9dfc 100644 --- a/infer/src/clang/cTrans.ml +++ b/infer/src/clang/cTrans.ml @@ -466,6 +466,9 @@ struct Some ModelBuiltins.__objc_release_cf | _ when CTrans_models.is_retain_builtin name type_ptr -> Some ModelBuiltins.__objc_retain_cf + | _ when name = CFrontend_config.malloc && + General_utils.is_objc_extension -> + Some ModelBuiltins.malloc_no_fail | _ -> None @@ -484,21 +487,9 @@ struct (* If we are not translating a callee expression, *) (* then the address of the function is being taken.*) (* As e.g. in fun_ptr = foo; *) - let name = Procname.to_string pname in - let non_mangled_func_name = - if name = CFrontend_config.malloc && - (Config.clang_lang = Config.OBJC || - Config.clang_lang = Config.OBJCPP) then - ModelBuiltins.malloc_no_fail - else Procname.from_string_c_fun name in - let is_builtin = Builtin.is_registered non_mangled_func_name in - if is_builtin then (* malloc, free, exit, scanf, ... *) - { empty_res_trans with exps = [(Exp.Const (Const.Cfun non_mangled_func_name), typ)] } - else - begin - if address_of_function then Cfg.set_procname_priority context.cfg pname; - { empty_res_trans with exps = [(Exp.Const (Const.Cfun pname), typ)] } - end + let is_builtin = Builtin.is_registered pname in + if address_of_function && not is_builtin then Cfg.set_procname_priority context.cfg pname; + { empty_res_trans with exps = [(Exp.Const (Const.Cfun pname), typ)] } let field_deref_trans trans_state stmt_info pre_trans_result decl_ref ~is_constructor_init = let open CContext in