]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
lto-symtab.c (lto_symtab_merge_cgraph_nodes): Resolve cross module weakrefs.
authorJan Hubicka <jh@suse.cz>
Fri, 17 May 2013 22:20:58 +0000 (00:20 +0200)
committerJan Hubicka <hubicka@gcc.gnu.org>
Fri, 17 May 2013 22:20:58 +0000 (22:20 +0000)
* lto-symtab.c (lto_symtab_merge_cgraph_nodes): Resolve cross module
weakrefs.
* cgraph.c (dump_cgraph_node): Do not ice on unresolved alias.
* cgraphunit.c (handle_alias_pairs): Store target of unresolved weakrefs.
(output_weakrefs): Update.

From-SVN: r199041

gcc/ChangeLog
gcc/cgraph.c
gcc/cgraphunit.c
gcc/lto-symtab.c

index 7fce202e6fc504ecbe83ac0682ed6f618e5e2279..5cc09ae4dddcbfe73a81d9f95175df3adb63d5ef 100644 (file)
@@ -1,3 +1,11 @@
+2013-05-17  Jan Hubicka  <jh@suse.cz>
+
+       * lto-symtab.c (lto_symtab_merge_cgraph_nodes): Resolve cross module
+       weakrefs.
+       * cgraph.c (dump_cgraph_node): Do not ice on unresolved alias.
+       * cgraphunit.c (handle_alias_pairs): Store target of unresolved weakrefs.
+       (output_weakrefs): Update.
+
 2013-05-17  Po-Chun Chang  <pchang9@cs.wisc.edu>
            Martin Jambor  <mjambor@suse.cz>
 
index dff391638da458c17c607c4762d800d42429f58f..899f65cb979cd5be741e76c1ac9e1958775669d9 100644 (file)
@@ -1558,7 +1558,7 @@ dump_cgraph_node (FILE *f, struct cgraph_node *node)
               (int)node->thunk.virtual_value,
               (int)node->thunk.virtual_offset_p);
     }
-  if (node->alias && node->thunk.alias)
+  if (node->alias && node->thunk.alias && DECL_P (node->thunk.alias))
     {
       fprintf (f, "  Alias of %s",
               lang_hooks.decl_printable_name (node->thunk.alias, 2));
index 7fa8055878c8588bbbda1109d8d17cf284339b30..6ebf8d4aa062793ad5dbf072b91f42493b07951a 100644 (file)
@@ -1069,9 +1069,17 @@ handle_alias_pairs (void)
       if (!target_node && lookup_attribute ("weakref", DECL_ATTRIBUTES (p->decl)) != NULL)
        {
          if (TREE_CODE (p->decl) == FUNCTION_DECL)
-           cgraph_get_create_node (p->decl)->alias = true;
+           {
+             struct cgraph_node *anode = cgraph_get_create_node (p->decl);
+             anode->alias = true;
+             anode->thunk.alias = p->target;
+           }
          else
-           varpool_get_node (p->decl)->alias = true;
+           {
+             struct varpool_node *anode = varpool_get_node (p->decl);
+             anode->alias = true;
+             anode->alias_of = p->target;
+           }
          DECL_EXTERNAL (p->decl) = 1;
          alias_pairs->unordered_remove (i);
          continue;
@@ -1939,14 +1947,14 @@ output_weakrefs (void)
         && !TREE_ASM_WRITTEN (node->symbol.decl)
        && lookup_attribute ("weakref", DECL_ATTRIBUTES (node->symbol.decl)))
       do_assemble_alias (node->symbol.decl,
-                        node->thunk.alias ? DECL_ASSEMBLER_NAME (node->thunk.alias)
+                        node->thunk.alias && DECL_P (node->thunk.alias) ? DECL_ASSEMBLER_NAME (node->thunk.alias)
                         : get_alias_symbol (node->symbol.decl));
   FOR_EACH_VARIABLE (vnode)
     if (vnode->alias && DECL_EXTERNAL (vnode->symbol.decl)
         && !TREE_ASM_WRITTEN (vnode->symbol.decl)
        && lookup_attribute ("weakref", DECL_ATTRIBUTES (vnode->symbol.decl)))
       do_assemble_alias (vnode->symbol.decl,
-                        vnode->alias_of ? DECL_ASSEMBLER_NAME (vnode->alias_of)
+                        vnode->alias_of && DECL_P (vnode->alias_of) ? DECL_ASSEMBLER_NAME (vnode->alias_of)
                         : get_alias_symbol (vnode->symbol.decl));
 }
 
index a004eea24fdcdac78d57c154fb37efa06acff56a..8091d36193e015dcff8c047972b547ee913dd95b 100644 (file)
@@ -593,13 +593,67 @@ lto_symtab_merge_cgraph_nodes (void)
 
   FOR_EACH_FUNCTION (cnode)
     {
+      /* Resolve weakrefs to symbol defined in other unit.  */
+      if (!cnode->analyzed && cnode->thunk.alias && !DECL_P (cnode->thunk.alias))
+       {
+         symtab_node node = symtab_node_for_asm (cnode->thunk.alias);
+         if (node && is_a <cgraph_node> (node))
+           {
+             struct cgraph_node *n;
+
+             for (n = cgraph (node); n && n->alias;
+                  n = n->analyzed ? cgraph_alias_aliased_node (n) : NULL)
+               if (n == cnode)
+                 {
+                   error ("function %q+D part of alias cycle", cnode->symbol.decl);
+                   cnode->alias = false;
+                   break;
+                 }
+             if (cnode->alias)
+               {
+                 cgraph_create_function_alias (cnode->symbol.decl, node->symbol.decl);
+                 ipa_record_reference ((symtab_node)cnode, (symtab_node)node,
+                                       IPA_REF_ALIAS, NULL);
+                 cnode->analyzed = true;
+               }
+           }
+         else if (node)
+           error ("%q+D alias in between function and variable is not supported", cnode->symbol.decl);
+       }
       if ((cnode->thunk.thunk_p || cnode->alias)
-         && cnode->thunk.alias)
+         && cnode->thunk.alias && DECL_P (cnode->thunk.alias))
         cnode->thunk.alias = lto_symtab_prevailing_decl (cnode->thunk.alias);
       cnode->symbol.aux = NULL;
     }
   FOR_EACH_VARIABLE (vnode)
     {
+      /* Resolve weakrefs to symbol defined in other unit.  */
+      if (!vnode->analyzed && vnode->alias_of && !DECL_P (vnode->alias_of))
+       {
+         symtab_node node = symtab_node_for_asm (vnode->alias_of);
+         if (node && is_a <cgraph_node> (node))
+           {
+             struct varpool_node *n;
+
+             for (n = varpool (node); n && n->alias;
+                  n = n->analyzed ? varpool_alias_aliased_node (n) : NULL)
+               if (n == vnode)
+                 {
+                   error ("function %q+D part of alias cycle", vnode->symbol.decl);
+                   vnode->alias = false;
+                   break;
+                 }
+             if (vnode->alias)
+               {
+                 varpool_create_variable_alias (vnode->symbol.decl, node->symbol.decl);
+                 ipa_record_reference ((symtab_node)vnode, (symtab_node)node,
+                                       IPA_REF_ALIAS, NULL);
+                 vnode->analyzed = true;
+               }
+           }
+         else if (node)
+           error ("%q+D alias in between function and variable is not supported", vnode->symbol.decl);
+       }
       if (vnode->alias_of)
         vnode->alias_of = lto_symtab_prevailing_decl (vnode->alias_of);
       vnode->symbol.aux = NULL;