From a8c946f1d93e5b15c893df740e89fb4bfb078894 Mon Sep 17 00:00:00 2001 From: David Lively Date: Thu, 24 Jan 2019 08:45:40 -0800 Subject: [PATCH] new predicate is_in_source_file and placeholders %source_file% and %kind% Reviewed By: ddino Differential Revision: D13745562 fbshipit-source-id: b3e646001 --- infer/src/clang/cFrontend_errors.ml | 8 ++++++++ infer/src/clang/cPredicates.ml | 5 +++++ infer/src/clang/cPredicates.mli | 5 +++++ infer/src/clang/cTL.ml | 2 ++ infer/src/clang/ctl_parser_types.ml | 20 +++++++++++++++++++ infer/src/clang/ctl_parser_types.mli | 2 ++ .../cpp/linters-for-test-only/issues.exp | 1 + .../linters-for-test-only/linters_example.al | 6 ++++++ .../cpp/linters-for-test-only/test_included.h | 12 +++++++++++ .../linters-for-test-only/test_includer.cpp | 12 +++++++++++ 10 files changed, 73 insertions(+) create mode 100644 infer/tests/codetoanalyze/cpp/linters-for-test-only/test_included.h create mode 100644 infer/tests/codetoanalyze/cpp/linters-for-test-only/test_includer.cpp diff --git a/infer/src/clang/cFrontend_errors.ml b/infer/src/clang/cFrontend_errors.ml index 4a7e9e489..228249302 100644 --- a/infer/src/clang/cFrontend_errors.ml +++ b/infer/src/clang/cFrontend_errors.ml @@ -129,6 +129,14 @@ let evaluate_place_holder context ph an = MF.monospaced_to_string (Ctl_parser_types.ast_node_name an) | "%cxx_fully_qualified_name%" -> MF.monospaced_to_string (Ctl_parser_types.ast_node_cxx_fully_qualified_name an) + | "%kind%" -> + MF.monospaced_to_string (Ctl_parser_types.ast_node_kind an) + | "%source_file%" -> + (* N.B.: This is the source_file in which the AST node occurs, which is not + * necessarily the same as the translation unit's source file. + *) + MF.monospaced_to_string + (SourceFile.to_rel_path (SourceFile.create (Ctl_parser_types.get_source_file an))) | _ -> L.die InternalError "helper function %s is unknown" ph diff --git a/infer/src/clang/cPredicates.ml b/infer/src/clang/cPredicates.ml index 5df8e50d2..50df28592 100644 --- a/infer/src/clang/cPredicates.ml +++ b/infer/src/clang/cPredicates.ml @@ -1456,3 +1456,8 @@ let is_init_expr_cxx11_constant an = vdi.vdi_is_init_expr_cxx11_constant | _ -> false + + +let is_in_source_file an path_re = + let src_file = Ctl_parser_types.get_source_file an in + ALVar.compare_str_with_alexp (SourceFile.to_rel_path (SourceFile.create src_file)) path_re diff --git a/infer/src/clang/cPredicates.mli b/infer/src/clang/cPredicates.mli index 96444ee96..c5cd93aec 100644 --- a/infer/src/clang/cPredicates.mli +++ b/infer/src/clang/cPredicates.mli @@ -492,6 +492,11 @@ val has_cxx_fully_qualified_name : Ctl_parser_types.ast_node -> ALVar.alexp -> b * matching the given regexp *) +val is_in_source_file : Ctl_parser_types.ast_node -> ALVar.alexp -> bool +(** + * True iff the source file path of the given node matches the given regexp or string. + *) + val is_cxx_method_overriding : Ctl_parser_types.ast_node -> ALVar.alexp option -> bool (** * True iff the current node is a CXXMethodDecl node and is overriding a diff --git a/infer/src/clang/cTL.ml b/infer/src/clang/cTL.ml index 7ea54b77e..a93c44d8b 100644 --- a/infer/src/clang/cTL.ml +++ b/infer/src/clang/cTL.ml @@ -1163,6 +1163,8 @@ let rec eval_Atomic pred_name_ args an lcxt = CPredicates.is_init_expr_cxx11_constant an | "cxx_construct_expr_has_no_parameters", [], an -> CPredicates.cxx_construct_expr_has_no_parameters an + | "is_in_source_file", [path_re], an -> + CPredicates.is_in_source_file an path_re | _ -> L.(die ExternalError) "Undefined Predicate or wrong set of arguments: '%s'" pred_name diff --git a/infer/src/clang/ctl_parser_types.ml b/infer/src/clang/ctl_parser_types.ml index ef293a98d..6be18caa9 100644 --- a/infer/src/clang/ctl_parser_types.ml +++ b/infer/src/clang/ctl_parser_types.ml @@ -598,3 +598,23 @@ let stmt_node_child_type an = match stmts with [stmt] -> ast_node_type (Stmt stmt) | _ -> "" ) | _ -> "" + + +let get_source_range an = + match an with + | Stmt stmt -> + let stmt_info, _ = Clang_ast_proj.get_stmt_tuple stmt in + stmt_info.si_source_range + | Decl decl -> + let decl_info = Clang_ast_proj.get_decl_tuple decl in + decl_info.di_source_range + + +let get_source_file an = + match get_source_range an with + | {sl_file= Some sf}, _ -> + sf + | _, {sl_file= Some sf} -> + sf + | _ -> + assert false diff --git a/infer/src/clang/ctl_parser_types.mli b/infer/src/clang/ctl_parser_types.mli index 416a61f98..51318a351 100644 --- a/infer/src/clang/ctl_parser_types.mli +++ b/infer/src/clang/ctl_parser_types.mli @@ -83,3 +83,5 @@ type abs_ctype = val c_type_equal : Clang_ast_t.c_type -> abs_ctype -> bool val abs_ctype_to_string : abs_ctype -> string + +val get_source_file : ast_node -> Clang_ast_t.source_file diff --git a/infer/tests/codetoanalyze/cpp/linters-for-test-only/issues.exp b/infer/tests/codetoanalyze/cpp/linters-for-test-only/issues.exp index 3fcdedecf..46e357ca3 100644 --- a/infer/tests/codetoanalyze/cpp/linters-for-test-only/issues.exp +++ b/infer/tests/codetoanalyze/cpp/linters-for-test-only/issues.exp @@ -1,5 +1,6 @@ codetoanalyze/cpp/linters-for-test-only/test_constructor.cpp, f, 12, FIND_STATIC_LOCAL_VAR, no_bucket, WARNING, [] codetoanalyze/cpp/linters-for-test-only/test_constructor.cpp, g, 17, FIND_CXX_COPY_CONSTRUCTOR, no_bucket, WARNING, [] +codetoanalyze/cpp/linters-for-test-only/test_included.h, Bazoo_fibble, 11, FIND_CXX_METHODS_FROM_HEADER_FILE, no_bucket, WARNING, [] codetoanalyze/cpp/linters-for-test-only/test_overrides.cpp, B_bar, 16, FIND_CXX_METHOD_OVERRIDES, no_bucket, WARNING, [] codetoanalyze/cpp/linters-for-test-only/test_overrides.cpp, B_foo, 14, FIND_CXX_METHOD_OVERRIDES, no_bucket, WARNING, [] codetoanalyze/cpp/linters-for-test-only/test_overrides.cpp, Foo::Bar::SvIf_async_tm_poke, 36, FIND_CXX_METHOD_OVERRIDES, no_bucket, WARNING, [] diff --git a/infer/tests/codetoanalyze/cpp/linters-for-test-only/linters_example.al b/infer/tests/codetoanalyze/cpp/linters-for-test-only/linters_example.al index 4044990a4..d2aaea2ef 100644 --- a/infer/tests/codetoanalyze/cpp/linters-for-test-only/linters_example.al +++ b/infer/tests/codetoanalyze/cpp/linters-for-test-only/linters_example.al @@ -42,3 +42,9 @@ DEFINE-CHECKER FIND_NODES_WITH_CXX_FULL_NAME = { SET report_when = has_cxx_fully_qualified_name(REGEXP("::Foo::.*")); SET message = "%cxx_fully_qualified_name% matches"; }; + +DEFINE-CHECKER FIND_CXX_METHODS_FROM_HEADER_FILE = { + SET report_when = WHEN is_in_source_file(REGEXP("/test_included.h$")) + HOLDS-IN-NODE CXXMethodDecl; + SET message = "found C++ method %name% in %source_file%"; +}; diff --git a/infer/tests/codetoanalyze/cpp/linters-for-test-only/test_included.h b/infer/tests/codetoanalyze/cpp/linters-for-test-only/test_included.h new file mode 100644 index 000000000..5b6716c70 --- /dev/null +++ b/infer/tests/codetoanalyze/cpp/linters-for-test-only/test_included.h @@ -0,0 +1,12 @@ +/* + * Copyright (c) 2019-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +#pragma once + +struct Bazoo { + void fibble(); +}; diff --git a/infer/tests/codetoanalyze/cpp/linters-for-test-only/test_includer.cpp b/infer/tests/codetoanalyze/cpp/linters-for-test-only/test_includer.cpp new file mode 100644 index 000000000..c28c8e12b --- /dev/null +++ b/infer/tests/codetoanalyze/cpp/linters-for-test-only/test_includer.cpp @@ -0,0 +1,12 @@ +/* + * Copyright (c) 2019-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +#include "test_included.h" + +struct Bazowey { + void frazzle(); +};