calls.c: refactor special_function_p for use by analyzer (v2)
authorDavid Malcolm <dmalcolm@redhat.com>
Sun, 26 Jan 2020 23:40:43 +0000 (18:40 -0500)
committerDavid Malcolm <dmalcolm@redhat.com>
Fri, 31 Jan 2020 14:00:57 +0000 (09:00 -0500)
This patch refactors some code in special_function_p that checks for
the function being sane to match by name, splitting it out into a new
maybe_special_function_p, and using it it two places in the analyzer.

gcc/analyzer/ChangeLog:
* analyzer.cc (is_named_call_p): Replace tests for fndecl being
extern at file scope and having a non-NULL DECL_NAME with a call
to maybe_special_function_p.
* function-set.cc (function_set::contains_decl_p): Add call to
maybe_special_function_p.

gcc/ChangeLog:
* calls.c (special_function_p): Split out the check for DECL_NAME
being non-NULL and fndecl being extern at file scope into a
new maybe_special_function_p and call it.  Drop check for fndecl
being non-NULL that was after a usage of DECL_NAME (fndecl).
* tree.h (maybe_special_function_p): New inline function.

gcc/ChangeLog
gcc/analyzer/ChangeLog
gcc/analyzer/analyzer.cc
gcc/analyzer/function-set.cc
gcc/calls.c
gcc/tree.h

index 163afba..8b7ad4a 100644 (file)
@@ -1,3 +1,11 @@
+2020-01-31  David Malcolm  <dmalcolm@redhat.com>
+
+       * calls.c (special_function_p): Split out the check for DECL_NAME
+       being non-NULL and fndecl being extern at file scope into a
+       new maybe_special_function_p and call it.  Drop check for fndecl
+       being non-NULL that was after a usage of DECL_NAME (fndecl).
+       * tree.h (maybe_special_function_p): New inline function.
+
 2020-01-30  Andrew Stubbs  <ams@codesourcery.com>
 
        * config/gcn/gcn-valu.md (gather<mode>_exec): Move contents ...
index 7ca6c22..a46ee26 100644 (file)
@@ -1,5 +1,13 @@
 2020-01-31  David Malcolm  <dmalcolm@redhat.com>
 
+       * analyzer.cc (is_named_call_p): Replace tests for fndecl being
+       extern at file scope and having a non-NULL DECL_NAME with a call
+       to maybe_special_function_p.
+       * function-set.cc (function_set::contains_decl_p): Add call to
+       maybe_special_function_p.
+
+2020-01-31  David Malcolm  <dmalcolm@redhat.com>
+
        PR analyzer/93450
        * constraint-manager.cc
        (constraint_manager::get_or_add_equiv_class): Only compare constants
index 1b5e4c9..5cf745e 100644 (file)
@@ -65,18 +65,10 @@ is_named_call_p (tree fndecl, const char *funcname)
   gcc_assert (fndecl);
   gcc_assert (funcname);
 
-  /* Exclude functions not at the file scope, or not `extern',
-     since they are not the magic functions we would otherwise
-     think they are.  */
-  if (!((DECL_CONTEXT (fndecl) == NULL_TREE
-        || TREE_CODE (DECL_CONTEXT (fndecl)) == TRANSLATION_UNIT_DECL)
-       && TREE_PUBLIC (fndecl)))
+  if (!maybe_special_function_p (fndecl))
     return false;
 
   tree identifier = DECL_NAME (fndecl);
-  if (identifier == NULL)
-    return false;
-
   const char *name = IDENTIFIER_POINTER (identifier);
   const char *tname = name;
 
index 6ed15ae..1b6b5d9 100644 (file)
@@ -59,6 +59,8 @@ bool
 function_set::contains_decl_p (tree fndecl) const
 {
   gcc_assert (fndecl && DECL_P (fndecl));
+  if (!maybe_special_function_p (fndecl))
+    return false;
   return contains_name_p (IDENTIFIER_POINTER (DECL_NAME (fndecl)));
 }
 
index 1336f49..d1c5317 100644 (file)
@@ -586,18 +586,8 @@ special_function_p (const_tree fndecl, int flags)
 {
   tree name_decl = DECL_NAME (fndecl);
 
-  if (fndecl && name_decl
-      && IDENTIFIER_LENGTH (name_decl) <= 11
-      /* Exclude functions not at the file scope, or not `extern',
-        since they are not the magic functions we would otherwise
-        think they are.
-        FIXME: this should be handled with attributes, not with this
-        hacky imitation of DECL_ASSEMBLER_NAME.  It's (also) wrong
-        because you can declare fork() inside a function if you
-        wish.  */
-      && (DECL_CONTEXT (fndecl) == NULL_TREE
-         || TREE_CODE (DECL_CONTEXT (fndecl)) == TRANSLATION_UNIT_DECL)
-      && TREE_PUBLIC (fndecl))
+  if (maybe_special_function_p (fndecl)
+      && IDENTIFIER_LENGTH (name_decl) <= 11)
     {
       const char *name = IDENTIFIER_POINTER (name_decl);
       const char *tname = name;
index 9342220..85ce6b3 100644 (file)
@@ -5611,6 +5611,31 @@ builtin_decl_declared_p (enum built_in_function fncode)
          && builtin_info[uns_fncode].declared_p);
 }
 
+/* Determine if the function identified by FNDECL is one that
+   makes sense to match by name, for those places where we detect
+   "magic" functions by name.
+
+   Return true if FNDECL has a name and is an extern fndecl at file scope.
+   FNDECL must be a non-NULL decl.
+
+   Avoid using this, as it's generally better to use attributes rather
+   than to check for functions by name.  */
+
+static inline bool
+maybe_special_function_p (const_tree fndecl)
+{
+  tree name_decl = DECL_NAME (fndecl);
+  if (name_decl
+      /* Exclude functions not at the file scope, or not `extern',
+        since they are not the magic functions we would otherwise
+        think they are.  */
+      && (DECL_CONTEXT (fndecl) == NULL_TREE
+         || TREE_CODE (DECL_CONTEXT (fndecl)) == TRANSLATION_UNIT_DECL)
+      && TREE_PUBLIC (fndecl))
+    return true;
+  return false;
+}
+
 /* Return true if T (assumed to be a DECL) is a global variable.
    A variable is considered global if its storage is not automatic.  */