summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Malcolm <dmalcolm@redhat.com>2020-01-26 18:40:43 -0500
committerDavid Malcolm <dmalcolm@redhat.com>2020-01-31 09:00:57 -0500
commit182ce042e7325a05a87fb34d2eaf6db3666fbd7f (patch)
treed9b9ba23a26d11ec85cf122c6d369c6c1b53c4e8
parent45eb3e4944ba93b1d4e9070c703068cfa7aaace4 (diff)
calls.c: refactor special_function_p for use by analyzer (v2)
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.
-rw-r--r--gcc/ChangeLog8
-rw-r--r--gcc/analyzer/ChangeLog8
-rw-r--r--gcc/analyzer/analyzer.cc10
-rw-r--r--gcc/analyzer/function-set.cc2
-rw-r--r--gcc/calls.c14
-rw-r--r--gcc/tree.h25
6 files changed, 46 insertions, 21 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 163afbae778..8b7ad4a9f38 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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 ...
diff --git a/gcc/analyzer/ChangeLog b/gcc/analyzer/ChangeLog
index 7ca6c2217e3..a46ee269f65 100644
--- a/gcc/analyzer/ChangeLog
+++ b/gcc/analyzer/ChangeLog
@@ -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
diff --git a/gcc/analyzer/analyzer.cc b/gcc/analyzer/analyzer.cc
index 1b5e4c9ecf8..5cf745ea632 100644
--- a/gcc/analyzer/analyzer.cc
+++ b/gcc/analyzer/analyzer.cc
@@ -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;
diff --git a/gcc/analyzer/function-set.cc b/gcc/analyzer/function-set.cc
index 6ed15ae95ad..1b6b5d9f9c1 100644
--- a/gcc/analyzer/function-set.cc
+++ b/gcc/analyzer/function-set.cc
@@ -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)));
}
diff --git a/gcc/calls.c b/gcc/calls.c
index 1336f49ea5e..d1c53171176 100644
--- a/gcc/calls.c
+++ b/gcc/calls.c
@@ -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;
diff --git a/gcc/tree.h b/gcc/tree.h
index 93422206b63..85ce6b3bd6a 100644
--- a/gcc/tree.h
+++ b/gcc/tree.h
@@ -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. */