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))

Reply via email to