diff --git a/infer/src/clang/cFrontend_config.ml b/infer/src/clang/cFrontend_config.ml index d851fcd21..b65883ccc 100644 --- a/infer/src/clang/cFrontend_config.ml +++ b/infer/src/clang/cFrontend_config.ml @@ -113,6 +113,16 @@ let fbAssertWithSignalAndLogFunctionHelper = "FBAssertWithSignalAndLogFunctionHe let google_LogMessageFatal = "google::LogMessageFatal_LogMessageFatal" +let google_MakeCheckOpString = "google::MakeCheckOpString" + +let google_whitelisting_functions = [ + "CheckNotNull"; + "GetReferenceableValue"; + "Check_NEImpl"; + "Check_LEImpl"; + "Check_GTImpl"; + "Check_EQImpl"] + let pseudo_object_type = "" let count = "count" diff --git a/infer/src/clang/cFrontend_config.mli b/infer/src/clang/cFrontend_config.mli index 3d4da1bd4..71762be58 100644 --- a/infer/src/clang/cFrontend_config.mli +++ b/infer/src/clang/cFrontend_config.mli @@ -115,6 +115,10 @@ val handleFailureInFunction : string val google_LogMessageFatal : string +val google_MakeCheckOpString : string + +val google_whitelisting_functions : string list + val pseudo_object_type : string val count : string diff --git a/infer/src/clang/cFrontend_decl.ml b/infer/src/clang/cFrontend_decl.ml index 2a03594fe..ae286b64b 100644 --- a/infer/src/clang/cFrontend_decl.ml +++ b/infer/src/clang/cFrontend_decl.ml @@ -147,14 +147,18 @@ struct let source_range = info.Clang_ast_t.di_source_range in let translate_location = CLocation.should_translate_lib source_range decl_trans_context in let always_translate_decl = match dec with - | Clang_ast_t.FunctionDecl (_, name_info, _, _) -> + | Clang_ast_t.FunctionDecl (_, name_info, _, _) + | Clang_ast_t.CXXMethodDecl (_, name_info, _, _, _) -> (* named_decl_info.ni_name has name without template parameters.*) (* It makes it possible to capture whole family of function instantiations*) (* to be named the same *) let fun_name = name_info.Clang_ast_t.ni_name in - let top_qual = IList.hd (IList.rev name_info.Clang_ast_t.ni_qual_name) in + let qual_name = name_info.Clang_ast_t.ni_qual_name in + let top_qual = IList.hd (IList.rev qual_name) in (* Always translate std::move so that it can be analyzed *) - top_qual="std" && fun_name = "move" + top_qual = "std" && fun_name = "move" || + top_qual = "google" && + IList.mem (=) fun_name CFrontend_config.google_whitelisting_functions | _ -> false in translate_location || always_translate_decl diff --git a/infer/src/clang/cTrans_models.ml b/infer/src/clang/cTrans_models.ml index 1b727d807..39c0a8ed2 100644 --- a/infer/src/clang/cTrans_models.ml +++ b/infer/src/clang/cTrans_models.ml @@ -76,7 +76,8 @@ let is_modeled_builtin funct = let is_assert_log_s funct = funct = CFrontend_config.assert_rtn || funct = CFrontend_config.assert_fail || - funct = CFrontend_config.fbAssertWithSignalAndLogFunctionHelper + funct = CFrontend_config.fbAssertWithSignalAndLogFunctionHelper || + Utils.string_contains CFrontend_config.google_MakeCheckOpString funct let is_assert_log_method m = m = CFrontend_config.google_LogMessageFatal diff --git a/infer/tests/codetoanalyze/cpp/errors/assertions/check_examples.cpp b/infer/tests/codetoanalyze/cpp/errors/assertions/check_examples.cpp index 45e907c3a..ee3ecb4a4 100644 --- a/infer/tests/codetoanalyze/cpp/errors/assertions/check_examples.cpp +++ b/infer/tests/codetoanalyze/cpp/errors/assertions/check_examples.cpp @@ -26,6 +26,11 @@ int check_example(int* a) { return *a; // no null deref flagged by Infer } +int check_not_null_example(int* p) { + CHECK_NOTNULL(p); + return *p; +} + int log_non_fatal_example() { int* a = nullptr; LOG_IF(INFO, a) << "well\n"; @@ -40,8 +45,6 @@ int log_if_fatal_example() { return *a; // no null deref } -// Still not modelled - int check_ne_example(int x) { CHECK_NE(x, 5); return x; @@ -52,7 +55,12 @@ int check_eq_example(int x, int y) { return x; } -int check_not_null_example(int* p) { - CHECK_NOTNULL(p); - return *p; +int check_le_example(int x) { + CHECK_LE(x, 5); + return x; +} + +int check_gt_example(int x) { + CHECK_GT(x, 5); + return x; }