aboutsummaryrefslogtreecommitdiff
path: root/gcc/cp
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/cp')
-rw-r--r--gcc/cp/ChangeLog6
-rw-r--r--gcc/cp/class.c30
-rw-r--r--gcc/cp/cp-tree.h1
-rw-r--r--gcc/cp/decl.c58
4 files changed, 47 insertions, 48 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 7b82a61..3bc7de0 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,5 +1,11 @@
2017-08-23 Nathan Sidwell <nathan@acm.org>
+ * cp-tree.h (maybe_version_functions): Declare.
+ * decl.c (decls_match): Break function versioning check to
+ separate function. Call it.
+ (maybe_version_functions): Broken out of decls_match.
+ * class.c (add_method): Use maybe_version_functions.
+
* cp-tree.h (print_search_statistics,
reinit_search_statistics): Don't declare.
* search.c (n_fields_searched, n_calls_lookup_field,
diff --git a/gcc/cp/class.c b/gcc/cp/class.c
index 94738bd..78a9b5f 100644
--- a/gcc/cp/class.c
+++ b/gcc/cp/class.c
@@ -1154,33 +1154,11 @@ add_method (tree type, tree method, bool via_using)
TREE_TYPE (method_type)))
&& equivalently_constrained (fn, method))
{
- /* For function versions, their parms and types match
- but they are not duplicates. Record function versions
- as and when they are found. extern "C" functions are
- not treated as versions. */
+ /* If these are versions of the same function, process and
+ move on. */
if (TREE_CODE (fn) == FUNCTION_DECL
- && TREE_CODE (method) == FUNCTION_DECL
- && !DECL_EXTERN_C_P (fn)
- && !DECL_EXTERN_C_P (method)
- && targetm.target_option.function_versions (fn, method))
- {
- /* Mark functions as versions if necessary. Modify the mangled
- decl name if necessary. */
- if (!DECL_FUNCTION_VERSIONED (fn))
- {
- DECL_FUNCTION_VERSIONED (fn) = 1;
- if (DECL_ASSEMBLER_NAME_SET_P (fn))
- mangle_decl (fn);
- }
- if (!DECL_FUNCTION_VERSIONED (method))
- {
- DECL_FUNCTION_VERSIONED (method) = 1;
- if (DECL_ASSEMBLER_NAME_SET_P (method))
- mangle_decl (method);
- }
- cgraph_node::record_function_versions (fn, method);
- continue;
- }
+ && maybe_version_functions (method, fn))
+ continue;
if (DECL_INHERITED_CTOR (method))
{
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index fb9dade..d80cd29 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -6071,6 +6071,7 @@ extern void push_switch (tree);
extern void pop_switch (void);
extern tree make_lambda_name (void);
extern int decls_match (tree, tree);
+extern bool maybe_version_functions (tree, tree);
extern tree duplicate_decls (tree, tree, bool);
extern tree declare_local_label (tree);
extern tree define_label (location_t, tree);
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index 5307e11..a9d72c0 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -1088,28 +1088,8 @@ decls_match (tree newdecl, tree olddecl)
if (types_match
&& !DECL_EXTERN_C_P (newdecl)
&& !DECL_EXTERN_C_P (olddecl)
- && targetm.target_option.function_versions (newdecl, olddecl))
- {
- /* Mark functions as versions if necessary. Modify the mangled decl
- name if necessary. */
- if (DECL_FUNCTION_VERSIONED (newdecl)
- && DECL_FUNCTION_VERSIONED (olddecl))
- return 0;
- if (!DECL_FUNCTION_VERSIONED (newdecl))
- {
- DECL_FUNCTION_VERSIONED (newdecl) = 1;
- if (DECL_ASSEMBLER_NAME_SET_P (newdecl))
- mangle_decl (newdecl);
- }
- if (!DECL_FUNCTION_VERSIONED (olddecl))
- {
- DECL_FUNCTION_VERSIONED (olddecl) = 1;
- if (DECL_ASSEMBLER_NAME_SET_P (olddecl))
- mangle_decl (olddecl);
- }
- cgraph_node::record_function_versions (olddecl, newdecl);
- return 0;
- }
+ && maybe_version_functions (newdecl, olddecl))
+ return 0;
}
else if (TREE_CODE (newdecl) == TEMPLATE_DECL)
{
@@ -1165,6 +1145,40 @@ decls_match (tree newdecl, tree olddecl)
return types_match;
}
+/* NEWDECL and OLDDECL have identical signatures. If they are
+ different versions adjust them and return true. */
+
+bool
+maybe_version_functions (tree newdecl, tree olddecl)
+{
+ if (!targetm.target_option.function_versions (newdecl, olddecl))
+ return false;
+
+ bool record = false;
+
+ if (!DECL_FUNCTION_VERSIONED (olddecl))
+ {
+ record = true;
+ DECL_FUNCTION_VERSIONED (olddecl) = 1;
+ if (DECL_ASSEMBLER_NAME_SET_P (olddecl))
+ mangle_decl (olddecl);
+ }
+
+ if (!DECL_FUNCTION_VERSIONED (newdecl))
+ {
+ record = true;
+ DECL_FUNCTION_VERSIONED (newdecl) = 1;
+ if (DECL_ASSEMBLER_NAME_SET_P (newdecl))
+ mangle_decl (newdecl);
+ }
+
+ /* Only record if at least one was not already versions. */
+ if (record)
+ cgraph_node::record_function_versions (olddecl, newdecl);
+
+ return true;
+}
+
/* If NEWDECL is `static' and an `extern' was seen previously,
warn about it. OLDDECL is the previous declaration.