Make is_cxx_method_overriding predicate take regex matching class/name

Reviewed By: jvillard

Differential Revision: D13419974

fbshipit-source-id: c63ad011e
master
David Lively 6 years ago committed by Facebook Github Bot
parent 61b51b09db
commit 5a531ac755

@ -1412,10 +1412,31 @@ let is_cxx_copy_constructor an =
false
let is_cxx_method_overriding an =
let is_cxx_method_overriding an qual_name_re =
let rec overrides_named (decl_refs : Clang_ast_t.decl_ref list) (qnre : ALVar.alexp) =
List.exists
~f:(fun (decl_ref : Clang_ast_t.decl_ref) ->
match CAst_utils.get_decl decl_ref.dr_decl_pointer with
| None ->
false
| Some decl -> (
match decl with
| Clang_ast_t.CXXMethodDecl (_, ndi, _, _, mdi) ->
ALVar.compare_str_with_alexp
(String.concat ~sep:"::" (List.rev ndi.ni_qual_name))
qnre
|| overrides_named mdi.xmdi_overriden_methods qnre
| _ ->
false ) )
decl_refs
in
match an with
| Ctl_parser_types.Decl (Clang_ast_t.CXXMethodDecl (_, _, _, _, mdi)) ->
not (List.is_empty mdi.xmdi_overriden_methods)
| Ctl_parser_types.Decl (Clang_ast_t.CXXMethodDecl (_, _, _, _, mdi)) -> (
match qual_name_re with
| None ->
not (List.is_empty mdi.xmdi_overriden_methods)
| Some qnre ->
overrides_named mdi.xmdi_overriden_methods qnre )
| _ ->
false

@ -487,10 +487,11 @@ val is_method_called_by_superclass : Ctl_parser_types.ast_node -> bool
val is_cxx_copy_constructor : Ctl_parser_types.ast_node -> bool
(** true if the current node is a C++ copy constructor *)
val is_cxx_method_overriding : Ctl_parser_types.ast_node -> bool
val is_cxx_method_overriding : Ctl_parser_types.ast_node -> ALVar.alexp option -> bool
(**
* Checks if the current node is a CXXMethodDecl node and is overriding a
* method in a superclass.
* True iff the current node is a CXXMethodDecl node and is overriding a
* method whose fully-qualified name (with class and namespace) matches
* the given regexp (if given, otherwise any overriding method satisfies).
*)
val is_init_expr_cxx11_constant : Ctl_parser_types.ast_node -> bool

@ -1154,7 +1154,9 @@ let rec eval_Atomic pred_name_ args an lcxt =
| "is_cxx_copy_constructor", [], an ->
CPredicates.is_cxx_copy_constructor an
| "is_cxx_method_overriding", [], an ->
CPredicates.is_cxx_method_overriding an
CPredicates.is_cxx_method_overriding an None
| "is_cxx_method_overriding", [qual_name_re], an ->
CPredicates.is_cxx_method_overriding an (Some qual_name_re)
| "is_init_expr_cxx11_constant", [], an ->
CPredicates.is_init_expr_cxx11_constant an
| "cxx_construct_expr_has_no_parameters", [], an ->

@ -2,3 +2,11 @@ codetoanalyze/cpp/linters-for-test-only/test_constructor.cpp, f, 12, FIND_STATIC
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_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, []
codetoanalyze/cpp/linters-for-test-only/test_overrides.cpp, Foo::Bar::SvIf_future_poke, 37, FIND_CXX_METHOD_OVERRIDES, no_bucket, WARNING, []
codetoanalyze/cpp/linters-for-test-only/test_overrides.cpp, Foo::Bar::SvIf_semifuture_poke, 38, FIND_CXX_METHOD_OVERRIDES, no_bucket, WARNING, []
codetoanalyze/cpp/linters-for-test-only/test_overrides.cpp, FooBarService_async_tm_poke, 50, FIND_CXX_METHOD_OVERRIDES, no_bucket, WARNING, []
codetoanalyze/cpp/linters-for-test-only/test_overrides.cpp, FooBarService_future_poke, 51, FIND_CXX_METHOD_OVERRIDES, no_bucket, WARNING, []
codetoanalyze/cpp/linters-for-test-only/test_overrides.cpp, FooBarService_future_poke, 51, FIND_CXX_METHOD_OVERRIDES_MATCHING, no_bucket, WARNING, []
codetoanalyze/cpp/linters-for-test-only/test_overrides.cpp, FooBarService_poke, 49, FIND_CXX_METHOD_OVERRIDES, no_bucket, WARNING, []
codetoanalyze/cpp/linters-for-test-only/test_overrides.cpp, FooBarService_semifuture_poke, 52, FIND_CXX_METHOD_OVERRIDES, no_bucket, WARNING, []

@ -31,3 +31,9 @@ DEFINE-CHECKER FIND_CXX_METHOD_OVERRIDES = {
SET report_when = is_cxx_method_overriding;
SET message = "%decl_name% overrides";
};
DEFINE-CHECKER FIND_CXX_METHOD_OVERRIDES_MATCHING = {
SET report_when = WHEN is_cxx_method_overriding(REGEXP("oo::.*::SvIf::future"))
HOLDS-IN-NODE CXXMethodDecl;
SET message = "%decl_name% overriding matching method";
};

@ -16,3 +16,38 @@ struct B : public A {
void bar() /* override */;
void bazoo();
};
namespace Foo {
class SvIf {
public:
virtual ~SvIf() {}
virtual void async_tm_poke() {}
virtual void future_poke() {}
virtual void semifuture_poke() {}
};
namespace Bar {
class SvIf : public Foo::SvIf {
public:
virtual ~SvIf() {}
virtual void poke() {}
virtual void async_tm_poke() override {}
virtual void future_poke() override {}
virtual void semifuture_poke() override {}
};
} // namespace Bar
} // namespace Foo
class ServiceBase {};
class FooBarService : public ServiceBase, public Foo::Bar::SvIf {
public:
explicit FooBarService() {}
virtual void poke() override {}
virtual void async_tm_poke() override {}
virtual void future_poke() override {}
virtual void semifuture_poke() override {}
};

Loading…
Cancel
Save