[gcc r17-3358] analyzer: add helper methods for dynamic_cast support

Egas Ribeiro via Gcc-cvs <[email protected]>
Newsgroups gmane.comp.gcc.cvs
Message-ID <[email protected]>
https://gcc.gnu.org/g:98d58f11d19ee3a25c5b9f7e34cac02cbb4a3c34

commit r17-3358-g98d58f11d19ee3a25c5b9f7e34cac02cbb4a3c34
Author: Egas Ribeiro <[email protected]>
Date:   Sun Aug 16 13:43:32 2026 +0100

    analyzer: add helper methods for dynamic_cast support
    
    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]>

Diff:
---
 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 f58cfc93fc7d..1425e913379a 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 8ce1475bc5eb..05452ef02ede 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 fcc9a618d15c..679fe1a70158 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))
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.