This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] Revert behavior to r251316.


Hello.

The refactoring in r251316 changed the logic when cgraph_node::record_function_versions
function is called. Suggested patch reverts the logic prior to the revision.

Patch can bootstrap on ppc64le-redhat-linux and survives regression tests.
And make check RUNTESTFLAGS="i386.exp" on x86_64 works.

Ready to be installed?
Martin

gcc/cp/ChangeLog:

2018-01-26  Martin Liska  <mliska@suse.cz>

	PR c++/84059.
	* class.c (add_method): Append argument value.
	* cp-tree.h (maybe_version_functions): Add new argument.
	* decl.c (decls_match): Call it if a declaration does not
	have DECL_FUNCTION_VERSIONED.
	(maybe_version_functions): record argument is added.

gcc/testsuite/ChangeLog:

2018-01-26  Martin Liska  <mliska@suse.cz>

	PR c++/84059.
	* g++.dg/ext/mv26.C: New test.
---
 gcc/cp/class.c                  |  2 +-
 gcc/cp/cp-tree.h                |  2 +-
 gcc/cp/decl.c                   | 14 ++++++--------
 gcc/testsuite/g++.dg/ext/mv26.C | 15 +++++++++++++++
 4 files changed, 23 insertions(+), 10 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/ext/mv26.C


diff --git a/gcc/cp/class.c b/gcc/cp/class.c
index a4098ac872e..57a2e69ada6 100644
--- a/gcc/cp/class.c
+++ b/gcc/cp/class.c
@@ -1099,7 +1099,7 @@ add_method (tree type, tree method, bool via_using)
 	  /* If these are versions of the same function, process and
 	     move on.  */
 	  if (TREE_CODE (fn) == FUNCTION_DECL
-	      && maybe_version_functions (method, fn))
+	      && maybe_version_functions (method, fn, true))
 	    continue;
 
 	  if (DECL_INHERITED_CTOR (method))
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index a53f4fd9c03..b636333b93f 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -6136,7 +6136,7 @@ extern bool note_iteration_stmt_body_start	(void);
 extern void note_iteration_stmt_body_end	(bool);
 extern tree make_lambda_name			(void);
 extern int decls_match				(tree, tree, bool = true);
-extern bool maybe_version_functions		(tree, tree);
+extern bool maybe_version_functions		(tree, tree, bool);
 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 01ce9fb6d69..3ccea9e6a45 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -1087,7 +1087,9 @@ decls_match (tree newdecl, tree olddecl, bool record_versions /* = true */)
 	  && !DECL_EXTERN_C_P (newdecl)
 	  && !DECL_EXTERN_C_P (olddecl)
 	  && record_versions
-	  && maybe_version_functions (newdecl, olddecl))
+	  && maybe_version_functions (newdecl, olddecl,
+				      (!DECL_FUNCTION_VERSIONED (newdecl)
+				       || !DECL_FUNCTION_VERSIONED (olddecl))))
 	return 0;
     }
   else if (TREE_CODE (newdecl) == TEMPLATE_DECL)
@@ -1145,19 +1147,17 @@ decls_match (tree newdecl, tree olddecl, bool record_versions /* = true */)
 }
 
 /* NEWDECL and OLDDECL have identical signatures.  If they are
-   different versions adjust them and return true.  */
+   different versions adjust them and return true.
+   If RECORD is set to true, record function versions.  */
 
 bool
-maybe_version_functions (tree newdecl, tree olddecl)
+maybe_version_functions (tree newdecl, tree olddecl, bool record)
 {
   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);
@@ -1165,13 +1165,11 @@ maybe_version_functions (tree newdecl, tree 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);
 
diff --git a/gcc/testsuite/g++.dg/ext/mv26.C b/gcc/testsuite/g++.dg/ext/mv26.C
new file mode 100644
index 00000000000..1b455130e46
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ext/mv26.C
@@ -0,0 +1,15 @@
+// PR c++/84059
+// { dg-do compile { target i?86-*-* x86_64-*-* } }
+// { dg-require-ifunc "" }
+
+template <typename> struct a
+{
+  int __attribute__ ((target ("arch=ivybridge"))) c (int) {return 1;}
+  int __attribute__ ((target ("default"))) c (int) { return 2; }
+};
+void
+d ()
+{
+  a<double> b;
+  b.c (2);
+}


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]