From 5591e5f9af6f09455a1f11d8e822785e34647186 Mon Sep 17 00:00:00 2001
From: Jakub Jelinek <jakub@redhat.com>
Date: Sun, 27 Feb 2005 18:13:28 +0100
Subject: [PATCH] re PR c++/20206 (COMDAT broken for C++ thunks)

	PR c++/20206
	* decl.c (cxx_comdat_group): Put thunks for
	TARGET_USE_LOCAL_THUNK_ALIAS_P (function) functions into the same
	comdat group as the thunk target.

	* g++.dg/opt/thunk2.C: New test.
	* g++.dg/opt/covariant1.C: New test.

From-SVN: r95619
---
 gcc/cp/ChangeLog                      |  7 ++++
 gcc/cp/decl.c                         | 17 +++++++++-
 gcc/testsuite/ChangeLog               |  6 ++++
 gcc/testsuite/g++.dg/opt/covariant1.C | 47 +++++++++++++++++++++++++++
 gcc/testsuite/g++.dg/opt/thunk2.C     | 44 +++++++++++++++++++++++++
 5 files changed, 120 insertions(+), 1 deletion(-)
 create mode 100644 gcc/testsuite/g++.dg/opt/covariant1.C
 create mode 100644 gcc/testsuite/g++.dg/opt/thunk2.C

diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index d11e3215997f..36e29ce306f1 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,10 @@
+2005-02-27  Jakub Jelinek  <jakub@redhat.com>
+
+	PR c++/20206
+	* decl.c (cxx_comdat_group): Put thunks for
+	TARGET_USE_LOCAL_THUNK_ALIAS_P (function) functions into the same
+	comdat group as the thunk target.
+
 2005-02-24  Volker Reichelt  <reichelt@igpm.rwth-aachen.de>
 
 	* call.c, class.c, cp-tree.h, decl2.c, error.c, init.c, mangle.c,
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index d767125ad10e..072519ca1ed4 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -11115,7 +11115,22 @@ cxx_comdat_group (tree decl)
   /* For all other DECLs, the COMDAT group is the mangled name of the
      declaration itself.  */
   else
-    name = DECL_ASSEMBLER_NAME (decl);
+    {
+      while (DECL_THUNK_P (decl))
+	{
+	  /* If TARGET_USE_LOCAL_THUNK_ALIAS_P, use_thunk puts the thunk
+	     into the same section as the target function.  In that case
+	     we must return target's name.  */
+	  tree target = THUNK_TARGET (decl);
+	  if (TARGET_USE_LOCAL_THUNK_ALIAS_P (target)
+	      && DECL_SECTION_NAME (target) != NULL
+	      && DECL_ONE_ONLY (target))
+	    decl = target;
+	  else
+	    break;
+	}
+      name = DECL_ASSEMBLER_NAME (decl);
+    }
 
   return IDENTIFIER_POINTER (name);
 }
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index ef1433f0b83f..aebf34b5f6ef 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,9 @@
+2005-02-27  Jakub Jelinek  <jakub@redhat.com>
+
+	PR c++/20206
+	* g++.dg/opt/thunk2.C: New test.
+	* g++.dg/opt/covariant1.C: New test.
+
 2005-02-27  Tobias Schl"uter  <tobias.schlueter@physik.uni-muenchen.de>
 
 	* gfortran.dg/e_d_fmt.f90: New test.
diff --git a/gcc/testsuite/g++.dg/opt/covariant1.C b/gcc/testsuite/g++.dg/opt/covariant1.C
new file mode 100644
index 000000000000..e57cf4c6be04
--- /dev/null
+++ b/gcc/testsuite/g++.dg/opt/covariant1.C
@@ -0,0 +1,47 @@
+// PR c++/20206
+// { dg-do run }
+// { dg-options "-O0" }
+
+void
+bar (int x)
+{
+  asm ("" : : "g" (x));
+}
+
+struct S { S () {}; virtual ~S () {}; };
+struct T { virtual T *foo (int) {}; };
+struct V : virtual S, virtual T {};
+struct V v;
+struct U : public S, public T
+{
+  bool a;
+  U () {}
+  virtual ~U () {}
+  virtual V *foo (int x)
+  {
+    switch (x)
+      {
+      case 12:
+	break;
+      case 9:
+	bar (7);
+	break;
+      case 10:
+	bar (12);
+	break;
+      case 4:
+	bar (18);
+	break;
+      case 2:
+	bar (26);
+	break;
+      }
+    return &v;
+  }
+};
+U u;
+
+int
+main ()
+{
+}
diff --git a/gcc/testsuite/g++.dg/opt/thunk2.C b/gcc/testsuite/g++.dg/opt/thunk2.C
new file mode 100644
index 000000000000..52fcd74bc11c
--- /dev/null
+++ b/gcc/testsuite/g++.dg/opt/thunk2.C
@@ -0,0 +1,44 @@
+// PR c++/20206
+// { dg-do run }
+// { dg-options "-O0" }
+
+void
+bar (int x)
+{
+  asm ("" : : "g" (x));
+}
+
+struct S { S () {}; virtual ~S () {}; };
+struct T { virtual void foo (int) = 0; };
+struct U : public S, public T
+{
+  bool a;
+  U () {}
+  virtual ~U () {}
+  virtual void foo (int x)
+  {
+    switch (x)
+      {
+      case 12:
+	break;
+      case 9:
+	bar (7);
+	break;
+      case 10:
+	bar (12);
+	break;
+      case 4:
+	bar (18);
+	break;
+      case 2:
+	bar (26);
+	break;
+      }
+  }
+};
+U u;
+
+int
+main ()
+{
+}
-- 
GitLab