pr 61548 - tree-emutls needs to resolve the aliases it creates
diff mbox

Message ID 1422661640-18867-1-git-send-email-tbsaunde+gcc@tbsaunde.org
State New
Headers show

Commit Message

tbsaunde+gcc@tbsaunde.org Jan. 30, 2015, 11:47 p.m. UTC
From: Trevor Saunders <tbsaunde+gcc@tbsaunde.org>

Hi,

tree-emutls wasn't resolvingthe aliases it created which meant that the
varpool node's ref_list  said it didn't refer to anything which caused
get_alias_target to crash.  Then varpool_node::remove called
varpool_node::ctor_useful_for_folding_p which expects it can get the alias
target through ref_list, but varpool_node::remove has already called
symtab_node::unregister which cleared ref_list causing a similar crash in
get_alias_target.  It seems safe to deal with removing the initializer before unregistering the varpool node so just do that.

bootstrapped + regtested x86_64-linux-gnu, and tested test case now passes on
aarch64-none-elf. ok?

Trev

gcc/

	* tree-emutls.c (new_emutls_decl): RResolve aliases as well as
	creating them.
	* varpool.c (varpool_node::remove): delay unregistering nodes
	until DECL_INITIALIZER has been delt with.

Patch
diff mbox

diff --git a/gcc/tree-emutls.c b/gcc/tree-emutls.c
index da03b2a..c37cb31 100644
--- a/gcc/tree-emutls.c
+++ b/gcc/tree-emutls.c
@@ -366,9 +366,12 @@  new_emutls_decl (tree decl, tree alias_of)
   else if (!alias_of)
     varpool_node::add (to);
   else 
-    varpool_node::create_alias (to,
-				varpool_node::get_for_asmname
-				  (DECL_ASSEMBLER_NAME (DECL_VALUE_EXPR (alias_of)))->decl);
+    {
+      tree target_name = DECL_ASSEMBLER_NAME (DECL_VALUE_EXPR (alias_of));
+      varpool_node *target = varpool_node::get_for_asmname (target_name);
+      varpool_node *alias = varpool_node::create_alias (to, target->decl);
+      alias->resolve_alias (target);
+    }
   return to;
 }
 
diff --git a/gcc/varpool.c b/gcc/varpool.c
index 9c8f1eb..fb60135 100644
--- a/gcc/varpool.c
+++ b/gcc/varpool.c
@@ -195,7 +195,6 @@  void
 varpool_node::remove (void)
 {
   symtab->call_varpool_removal_hooks (this);
-  unregister ();
 
   /* When streaming we can have multiple nodes associated with decl.  */
   if (symtab->state == LTO_STREAMING)
@@ -205,6 +204,8 @@  varpool_node::remove (void)
   else if (DECL_INITIAL (decl) && DECL_INITIAL (decl) != error_mark_node
 	   && !ctor_useable_for_folding_p ())
     remove_initializer ();
+
+  unregister ();
   ggc_free (this);
 }