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 PR 51910, -frepo/linker demangling interaction


[Ooops, resending to include the attachment, this time....]

As discussed in PR c++/51910, my patch from last summer

http://gcc.gnu.org/ml/gcc-patches/2011-06/msg01368.html

to make HAVE_LD_DEMANGLE the default when using GNU ld exposed a bug in collect2's link-time -frepo handling -- it depends on the linker passing back mangled names of undefined symbols to collect2. This patch fixes that by explicitly adding --no-demangle to the options passed to the linker in the repository-processing loop. Then the original settings are restored for the final link, so that (for instance) if the user requested a map file or if there are messages for real link errors, they respect the user-specified demangling options. This patch therefore adds two extra link steps to the case where HAVE_LD_DEMANGLE is defined, there is repository information, and recompilation is necessary to resolve undefined symbols from the repository. In other cases it adds no overhead.

Bootstrapped and regression-tested on i636 linux. OK to check in?

-Sandra


2012-01-29 Sandra Loosemore <sandra@codesourcery.com> Jason Merrill <jason@redhat.com> Jakub Jelinek <jakub@redhat.com>

	PR c++/51910
	gcc/
	* tlink.c (do_tlink): Explicitly pass --no-demangle to linker
	for repo processing when HAVE_LD_DEMANGLE is defined.

	gcc/testsuite/
	* g++.dg/torture/pr51910.C: New testcase.


Index: gcc/tlink.c
===================================================================
--- gcc/tlink.c	(revision 183674)
+++ gcc/tlink.c	(working copy)
@@ -777,23 +777,53 @@ do_tlink (char **ld_argv, char **object_
       /* Until collect does a better job of figuring out which are object
 	 files, assume that everything on the command line could be.  */
       if (read_repo_files (ld_argv))
-	while (exit && i++ < MAX_ITERATIONS)
-	  {
-	    if (tlink_verbose >= 3)
-	      {
-		dump_file (ldout, stdout);
-		dump_file (lderrout, stderr);
-	      }
-	    demangle_new_symbols ();
-	    if (! scan_linker_output (ldout)
-		&& ! scan_linker_output (lderrout))
-	      break;
-	    if (! recompile_files ())
-	      break;
-	    if (tlink_verbose)
-	      fprintf (stderr, _("collect: relinking\n"));
-	    exit = tlink_execute ("ld", ld_argv, ldout, lderrout);
-	  }
+	{
+	  char **ld1_argv = ld_argv;
+
+#ifdef HAVE_LD_DEMANGLE
+	  /* We must explicitly tell the linker not to demangle names
+	     and re-do the initial link attempt, since repository processing
+	     requires demangled error output from the linker.  */
+	  int argc = 0;
+	  while (ld_argv[argc])
+	    ++argc;
+	  ld1_argv = XNEWVEC (char *, argc + 2);
+	  memcpy (ld1_argv, ld_argv, sizeof (ld_argv[0]) * argc);
+	  ld1_argv[argc] = CONST_CAST (char *, "--no-demangle");
+	  ld1_argv[argc + 1] = NULL;
+	  if (tlink_verbose)
+	    fprintf (stderr, _("collect: relinking\n"));
+	  exit = tlink_execute ("ld", ld1_argv, ldout, lderrout);
+#endif
+
+	  while (exit && i++ < MAX_ITERATIONS)
+	    {
+	      if (tlink_verbose >= 3)
+		{
+		  dump_file (ldout, stdout);
+		  dump_file (lderrout, stderr);
+		}
+	      demangle_new_symbols ();
+	      if (! scan_linker_output (ldout)
+		  && ! scan_linker_output (lderrout))
+		break;
+	      if (! recompile_files ())
+		break;
+	      if (tlink_verbose)
+		fprintf (stderr, _("collect: relinking\n"));
+	      exit = tlink_execute ("ld", ld1_argv, ldout, lderrout);
+	    }
+
+#ifdef HAVE_LD_DEMANGLE
+	  /* Now redo the final link with the original options so that
+	     any remaining errors, the link map, etc are presented to
+	     the user with the original mangling options.*/
+	  XDELETEVEC (ld1_argv);
+	  if (tlink_verbose)
+	    fprintf (stderr, _("collect: relinking\n"));
+	  exit = tlink_execute ("ld", ld_argv, ldout, lderrout);
+#endif
+	}
     }
 
   dump_file (ldout, stdout);
Index: gcc/testsuite/g++.dg/torture/pr51910.C
===================================================================
--- gcc/testsuite/g++.dg/torture/pr51910.C	(revision 0)
+++ gcc/testsuite/g++.dg/torture/pr51910.C	(revision 0)
@@ -0,0 +1,19 @@
+// PR c++/51910 
+// Check that -frepo works in the presence of linker symbol demangling.
+//
+// { dg-options "-frepo -Wl,--demangle" }
+// { dg-require-host-local "" }
+// { dg-skip-if "dkms are not final links" { vxworks_kernel } }
+
+template<typename T>
+struct Foo
+{
+  virtual ~Foo() { }
+};
+
+int main( int, char*[] )
+{
+  Foo<int> test;
+}
+
+// { dg-final { cleanup-repo-files } }

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