Fix LTO wrt aliases

Jan Hubicka hubicka@ucw.cz
Tue Dec 14 22:13:00 GMT 2010


Hi,
This problem kept me wondering for a while, but in fact it is rather easy.
When the prevailing symbol is an alias that is unused in the original source we
have no cgraph/varpool node associated with it and ICE trying to merge the
nodes as the code assumes that prevailing decl is always having node attached.
Since there is absolutely no info on the alias, it is OK to just create a new
node.  We probably could better sanity check that it is an alias and not
missing node for some internal corruption, but I know of no cheap way testing
that DECL is an alias?

can_prevail predicates are probably also wrong here for non-plugin directed
linking, since the alias can prevail even if it is not analyzed.  Will look
into this incrementally.

Bootstrapped/regtested x86_64-linux and tested on mozilla build.  Will commit
it later today.

Honza

	PR lto/46940
	PR lto/44463
	* lto-symtab.c (lto_symtab_merge_cgraph_nodes_1): Construct nodes
	for aliases when they are used.

	* gcc.dg/lto/pr46940_0.c: New testcase.
	* gcc.dg/lto/pr46940_1.c: New testcase.
	* gcc.dg/lto/pr44463_0.c: New testcase.
	* gcc.dg/lto/pr44463_1.c: New testcase.
	* gcc.dg/lto/pr44463_12c: New testcase.
Index: lto-symtab.c
===================================================================
*** lto-symtab.c	(revision 167805)
--- lto-symtab.c	(working copy)
*************** lto_symtab_merge_cgraph_nodes_1 (void **
*** 795,803 ****
    for (e = prevailing->next; e; e = e->next)
      {
        if (e->node != NULL)
! 	lto_cgraph_replace_node (e->node, prevailing->node);
        if (e->vnode != NULL)
! 	lto_varpool_replace_node (e->vnode, prevailing->vnode);
      }
  
    /* Drop all but the prevailing decl from the symtab.  */
--- 795,820 ----
    for (e = prevailing->next; e; e = e->next)
      {
        if (e->node != NULL)
! 	{
! 	  /* In case we prevail funcion by an alias, we can run into case
! 	     that the alias has no cgraph node attached, since it was
! 	     previously unused.  Create the node.  */
! 	  if (!prevailing->node)
! 	    {
! 	      prevailing->node = cgraph_node (prevailing->decl);
! 	      prevailing->node->alias = true;
! 	    }
! 	  lto_cgraph_replace_node (e->node, prevailing->node);
! 	}
        if (e->vnode != NULL)
! 	{
! 	  if (!prevailing->vnode)
! 	    {
! 	      prevailing->vnode = varpool_node (prevailing->decl);
! 	      prevailing->vnode->alias = true;
! 	    }
! 	  lto_varpool_replace_node (e->vnode, prevailing->vnode);
! 	}
      }
  
    /* Drop all but the prevailing decl from the symtab.  */
Index: testsuite/gcc.dg/lto/pr46940_0.c
===================================================================
*** testsuite/gcc.dg/lto/pr46940_0.c	(revision 0)
--- testsuite/gcc.dg/lto/pr46940_0.c	(revision 0)
***************
*** 0 ****
--- 1,10 ----
+ * { dg-require-linker-plugin "" } */
+ * { dg-extra-ld-options "-fuse-linker-plugin" } */
+ 
+ extern __attribute__((visibility("hidden"))) void _moz_foo (void);
+ extern __typeof (_moz_foo) _moz_foo __asm__ ("" "INT__foo") __attribute__((__visibility__("hidden"))) ;
+ void _moz_foo(void)
+ {
+   printf ("blah\n");
+ }
+ extern __typeof (_moz_foo) EXT__foo __asm__("" "_moz_foo") __attribute__((__alias__("" "INT__foo")));
Index: testsuite/gcc.dg/lto/pr44463_0.c
===================================================================
*** testsuite/gcc.dg/lto/pr44463_0.c	(revision 0)
--- testsuite/gcc.dg/lto/pr44463_0.c	(revision 0)
***************
*** 0 ****
--- 1,5 ----
+ /* { dg-lto-do link } */
+ #include <stdio.h>
+ 
+ void y(void) { printf("y\n"); } 
+ void x(void) __attribute__((weak, alias("y")));
Index: testsuite/gcc.dg/lto/pr46940_1.c
===================================================================
*** testsuite/gcc.dg/lto/pr46940_1.c	(revision 0)
--- testsuite/gcc.dg/lto/pr46940_1.c	(revision 0)
***************
*** 0 ****
--- 1,5 ----
+ extern void _moz_foo (void);
+ main()
+ {
+   _moz_foo ();
+ }
Index: testsuite/gcc.dg/lto/pr44463_1.c
===================================================================
*** testsuite/gcc.dg/lto/pr44463_1.c	(revision 0)
--- testsuite/gcc.dg/lto/pr44463_1.c	(revision 0)
***************
*** 0 ****
--- 1,2 ----
+ #include <stdio.h>
+ void x(void) { printf("strong\n"); }
Index: testsuite/gcc.dg/lto/pr44463_2.c
===================================================================
*** testsuite/gcc.dg/lto/pr44463_2.c	(revision 0)
--- testsuite/gcc.dg/lto/pr44463_2.c	(revision 0)
***************
*** 0 ****
--- 1,3 ----
+ extern void x(void);
+ 
+ int main(void) { x(); return 0; }



More information about the Gcc-patches mailing list