Re: [PATCH v2 1/2] analyzer: add helper methods for dynamic_cast support
David Malcolm <[email protected]>
| Newsgroups | gmane.comp.gcc.patches |
|---|---|
| Message-ID | <[email protected]> |
On Sun, 2026-08-16 at 20:24 +0100, Egas Ribeiro wrote: > 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]> Thanks; this patch looks OK for trunk. Dave > --- > 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))