Index: cgraphunit.c
===================================================================
--- cgraphunit.c	(revision 198926)
+++ cgraphunit.c	(working copy)
@@ -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: lto-symtab.c
===================================================================
--- lto-symtab.c	(revision 198926)
+++ lto-symtab.c	(working copy)
@@ -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;
Index: cgraph.c
===================================================================
--- cgraph.c	(revision 198926)
+++ cgraph.c	(working copy)
@@ -1558,7 +1558,7 @@ dump_cgraph_node (FILE *f, struct cgraph
 	       (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));
