[PATCH v2 1/2] analyzer: add helper methods for dynamic_cast support
Egas Ribeiro <[email protected]>
| Newsgroups | gmane.comp.gcc.patches |
|---|---|
| Message-ID | <[email protected]> |
Add helper methods needed for adding a new known_function for __dynamic_cast and recognize functions in the __cxxabiv1 namespace. gcc/analyzer/ChangeLog: * analyzer.cc (is_fndecl_in_toplevel_namespace_p): New function, factored out of... (is_std_function_p): ...here. Call it. (is_cxxabi_function_p): New function. * common.h (is_cxxabi_function_p): New decl. * known-function-manager.cc (known_function_manager::get_match): Also match functions declared in namespace __cxxabiv1. Signed-off-by: Egas Ribeiro <[email protected]> --- gcc/analyzer/analyzer.cc | 26 +++++++++++++++++++++++--- gcc/analyzer/common.h | 1 + gcc/analyzer/known-function-manager.cc | 10 +++++++--- 3 files changed, 31 insertions(+), 6 deletions(-) diff --git a/gcc/analyzer/analyzer.cc b/gcc/analyzer/analyzer.cc index f58cfc93fc7..1425e913379 100644 --- a/gcc/analyzer/analyzer.cc +++ b/gcc/analyzer/analyzer.cc @@ -349,27 +349,47 @@ is_named_call_p (const_tree fndecl, const char *funcname) return 0 == strcmp (tname, funcname); } -/* Return true if FNDECL is within the namespace "std". +/* Return true if FNDECL is declared directly within a top-level + namespace named NS_NAME (e.g. "std" or "__cxxabiv1"). Compare with cp/typeck.cc: decl_in_std_namespace_p, but this doesn't rely on being the C++ FE (or handle inline namespaces inside of std). */ bool -is_std_function_p (const_tree fndecl) +is_fndecl_in_toplevel_namespace_p (const_tree fndecl, const char *ns_name) { tree name_decl = DECL_NAME (fndecl); if (!name_decl) return false; + if (!DECL_CONTEXT (fndecl)) return false; if (TREE_CODE (DECL_CONTEXT (fndecl)) != NAMESPACE_DECL) return false; tree ns = DECL_CONTEXT (fndecl); + /* Require the namespace itself to be at top level. */ if (!(DECL_CONTEXT (ns) == NULL_TREE || TREE_CODE (DECL_CONTEXT (ns)) == TRANSLATION_UNIT_DECL)) return false; if (!DECL_NAME (ns)) return false; - return id_equal ("std", DECL_NAME (ns)); + + return id_equal (ns_name, DECL_NAME (ns)); +} + +/* Return true if FNDECL is within the namespace "std". */ + +bool +is_std_function_p (const_tree fndecl) +{ + return is_fndecl_in_toplevel_namespace_p (fndecl, "std"); +} + +/* Return true if FNDECL is within the namespace "__cxxabiv1". */ + +bool +is_cxxabi_function_p (const_tree fndecl) +{ + return is_fndecl_in_toplevel_namespace_p (fndecl, "__cxxabiv1"); } /* Like is_named_call_p, but look for std::FUNCNAME. */ diff --git a/gcc/analyzer/common.h b/gcc/analyzer/common.h index 8ce1475bc5e..05452ef02ed 100644 --- a/gcc/analyzer/common.h +++ b/gcc/analyzer/common.h @@ -544,6 +544,7 @@ extern bool is_named_call_p (const_tree fndecl, const char *funcname); extern bool is_named_call_p (const_tree fndecl, const char *funcname, const gcall &call, unsigned int num_args); extern bool is_std_function_p (const_tree fndecl); +extern bool is_cxxabi_function_p (const_tree fndecl); extern bool is_std_named_call_p (const_tree fndecl, const char *funcname); extern bool is_std_named_call_p (const_tree fndecl, const char *funcname, const gcall &call, unsigned int num_args); diff --git a/gcc/analyzer/known-function-manager.cc b/gcc/analyzer/known-function-manager.cc index fcc9a618d15..679fe1a7015 100644 --- a/gcc/analyzer/known-function-manager.cc +++ b/gcc/analyzer/known-function-manager.cc @@ -120,9 +120,13 @@ known_function_manager::get_match (tree fndecl, const call_details &cd) const return nullptr; } - if (DECL_CONTEXT (fndecl) - && TREE_CODE (DECL_CONTEXT (fndecl)) != TRANSLATION_UNIT_DECL) - return nullptr; + /* Only match functions declared at global scope, or within namespace + __cxxabiv1 (e.g. __dynamic_cast). */ + if (!is_cxxabi_function_p (fndecl)) + if (DECL_CONTEXT (fndecl) + && TREE_CODE (DECL_CONTEXT (fndecl)) != TRANSLATION_UNIT_DECL) + return nullptr; + if (tree identifier = DECL_NAME (fndecl)) if (const known_function *candidate = get_by_identifier (identifier)) if (candidate->matches_call_types_p (cd)) -- 2.54.0