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] Fix COMDAT group of thunks


Hi!

The testcase below fails to assemble on targets that use COMDAT and
local thunk aliases.
g++4 -o thunk2{,.C}
/tmp/ccWXeK5j.s: Assembler messages:
/tmp/ccWXeK5j.s:647: Error: can't resolve `.gnu.linkonce.t._ZN1U3fooEi' {.gnu.linkonce.t._ZN1U3fooEi section} - `.LFB20' {.gnu.linkonce.t._ZN1U3fooEi section}

The problem is that use_thunk puts the thunk into the same section as
its THUNK_TARGET, but as COMDAT group for it g++ uses DECL_ASSEMBLER_NAME
of the thunk.

  if (TARGET_USE_LOCAL_THUNK_ALIAS_P (function)
      && targetm.have_named_sections)
    {
      resolve_unique_section (function, 0, flag_function_sections);

      if (DECL_SECTION_NAME (function) != NULL && DECL_ONE_ONLY (function))
        {
          resolve_unique_section (thunk_fndecl, 0, flag_function_sections);

          /* Output the thunk into the same section as function.  */
          DECL_SECTION_NAME (thunk_fndecl) = DECL_SECTION_NAME (function);
        }
    }

This leads to
        .section .gnu.linkonce.t._ZN1U3fooEi,"axG",@progbits,_ZThn8_N1U3fooEi,comdat
...
_ZThn8_N1U3fooEi:
...
_ZN1U3fooEi:
all in the same section, which in itself is wrong, linker might kill needed
functions etc., but that itself doesn't lead to assemble failure.
The problem at -O0 is that the switch table is emitted in the middle of the
_ZN1U3fooEi function, which means switching to
.section .gnu.linkonce.r._ZN1U3fooEi,"aG",@progbits,_ZN1U3fooEi,comdat
section and then switching back to .gnu.linkonce.t._ZN1U3fooEi.
But at this point current function decl is _ZN1U3fooEi, not the thunk, so
we return to:
.section .gnu.linkonce.t._ZN1U3fooEi,"axG",@progbits,_ZN1U3fooEi,comdat
i.e. have start of the _ZN1U3fooEi function in a different section from the
end, and thus .LFE20 - .LFB20 is not computable at assembly time.

The patch below repeats the tests from use_thunk and uses THUNK_TARGET's
DECL_ASSEMBLER_NAME in cxx_comdat_group in that case.

Ok to commit for 4.0/HEAD?

2005-02-25  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.

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

--- gcc/cp/decl.c.jj	2005-02-24 22:20:24.000000000 +0100
+++ gcc/cp/decl.c	2005-02-25 11:36:53.729017752 +0100
@@ -11117,6 +11117,17 @@ cxx_comdat_group (tree decl)
   else
     name = DECL_ASSEMBLER_NAME (decl);
 
+  if (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))
+	name = DECL_ASSEMBLER_NAME (target);
+    }
   return IDENTIFIER_POINTER (name);
 }
 
--- gcc/testsuite/g++.dg/opt/thunk2.C.jj	2005-02-25 11:59:32.080830651 +0100
+++ gcc/testsuite/g++.dg/opt/thunk2.C	2005-02-25 11:59:56.218544991 +0100
@@ -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 ()
+{
+}

	Jakub


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