aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorIain Sandoe <iains@gcc.gnu.org>2010-05-24 14:36:32 +0000
committerIain Sandoe <iains@gcc.gnu.org>2010-05-24 14:36:32 +0000
commit1db0429a13b229a2a2ad43ca895786871f0b4834 (patch)
tree572e1afe3e6475f92e50a9110276f5d8b13583fa /gcc
parente72e2da4db2f88219961c6615f0d5a673be3aaa4 (diff)
downloadgcc-1db0429a13b229a2a2ad43ca895786871f0b4834.zip
gcc-1db0429a13b229a2a2ad43ca895786871f0b4834.tar.gz
gcc-1db0429a13b229a2a2ad43ca895786871f0b4834.tar.bz2
re PR target/44132 (emutls is broken under a range of circumstances.)
2010-05-24 Iain Sandoe <iains@gcc.gnu.org> PR target/44132 PR middle-end/43602 * varasm.c (get_emutls_init_templ_addr): Copy DECL_PRESERVE_P, DECL_VISIBILITY_SPECIFIED. (emutls_decl): Set DECL_PRESERVE_P and copy DECL_VISIBILITY_SPECIFIED, DECL_RESTRICTED_P. (emutls_finalize_control_var): New callback. (emutls_finish): Finalize emutls control variables. * toplev.c (compile_file): Move the call to emutls_finish () before varpool_assemble_pending_decls (). From-SVN: r159781
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog13
-rw-r--r--gcc/toplev.c9
-rw-r--r--gcc/varasm.c39
3 files changed, 53 insertions, 8 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 8313b2c..c82178c 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,16 @@
+2010-05-24 Iain Sandoe <iains@gcc.gnu.org>
+
+ PR target/44132
+ PR middle-end/43602
+ * varasm.c (get_emutls_init_templ_addr): Copy DECL_PRESERVE_P,
+ DECL_VISIBILITY_SPECIFIED.
+ (emutls_decl): Set DECL_PRESERVE_P and copy
+ DECL_VISIBILITY_SPECIFIED, DECL_RESTRICTED_P.
+ (emutls_finalize_control_var): New callback.
+ (emutls_finish): Finalize emutls control variables.
+ * toplev.c (compile_file): Move the call to emutls_finish ()
+ before varpool_assemble_pending_decls ().
+
2010-05-24 Daniel Gutson <dgutson@codesourcery.com>
* config/arm/lib1funcs.asm (__ARM_ARCH__): __ARM_ARCH_7EM__
diff --git a/gcc/toplev.c b/gcc/toplev.c
index 3cf65ba..fcd720d 100644
--- a/gcc/toplev.c
+++ b/gcc/toplev.c
@@ -1063,6 +1063,11 @@ compile_file (void)
if (errorcount || sorrycount)
return;
+ /* Ensure that emulated TLS control vars are finalized and build
+ a static constructor for them, when it is required. */
+ if (!targetm.have_tls)
+ emutls_finish ();
+
varpool_assemble_pending_decls ();
finish_aliases_2 ();
@@ -1070,10 +1075,6 @@ compile_file (void)
if (flag_mudflap)
mudflap_finish_file ();
- /* Likewise for emulated thread-local storage. */
- if (!targetm.have_tls)
- emutls_finish ();
-
output_shared_constant_pool ();
output_object_blocks ();
diff --git a/gcc/varasm.c b/gcc/varasm.c
index ef02994..3f8fd02 100644
--- a/gcc/varasm.c
+++ b/gcc/varasm.c
@@ -314,13 +314,14 @@ get_emutls_init_templ_addr (tree decl)
to = build_decl (DECL_SOURCE_LOCATION (decl),
VAR_DECL, name, TREE_TYPE (decl));
SET_DECL_ASSEMBLER_NAME (to, DECL_NAME (to));
- DECL_TLS_MODEL (to) = TLS_MODEL_EMULATED;
+
DECL_ARTIFICIAL (to) = 1;
TREE_USED (to) = TREE_USED (decl);
TREE_READONLY (to) = 1;
DECL_IGNORED_P (to) = 1;
DECL_CONTEXT (to) = DECL_CONTEXT (decl);
DECL_SECTION_NAME (to) = DECL_SECTION_NAME (decl);
+ DECL_PRESERVE_P (to) = DECL_PRESERVE_P (decl);
DECL_WEAK (to) = DECL_WEAK (decl);
if (DECL_ONE_ONLY (decl))
@@ -333,6 +334,7 @@ get_emutls_init_templ_addr (tree decl)
else
TREE_STATIC (to) = 1;
+ DECL_VISIBILITY_SPECIFIED (to) = DECL_VISIBILITY_SPECIFIED (decl);
DECL_INITIAL (to) = DECL_INITIAL (decl);
DECL_INITIAL (decl) = NULL;
@@ -385,6 +387,8 @@ emutls_decl (tree decl)
DECL_TLS_MODEL (to) = TLS_MODEL_EMULATED;
DECL_ARTIFICIAL (to) = 1;
DECL_IGNORED_P (to) = 1;
+ /* FIXME: work around PR44132. */
+ DECL_PRESERVE_P (to) = 1;
TREE_READONLY (to) = 0;
SET_DECL_ASSEMBLER_NAME (to, DECL_NAME (to));
if (DECL_ONE_ONLY (decl))
@@ -412,6 +416,10 @@ emutls_decl (tree decl)
DECL_COMMON (to) = DECL_COMMON (decl);
DECL_WEAK (to) = DECL_WEAK (decl);
DECL_VISIBILITY (to) = DECL_VISIBILITY (decl);
+ DECL_VISIBILITY_SPECIFIED (to) = DECL_VISIBILITY_SPECIFIED (decl);
+
+ /* Fortran might pass this to us. */
+ DECL_RESTRICTED_P (to) = DECL_RESTRICTED_P (decl);
return to;
}
@@ -450,16 +458,39 @@ emutls_common_1 (void **loc, void *xstmts)
return 1;
}
+/* Callback to finalize one emutls control variable. */
+
+static int
+emutls_finalize_control_var (void **loc,
+ void *unused ATTRIBUTE_UNUSED)
+{
+ struct tree_map *h = *(struct tree_map **) loc;
+ if (h != NULL)
+ {
+ struct varpool_node *node = varpool_node (h->to);
+ /* Because varpool_finalize_decl () has side-effects,
+ only apply to un-finalized vars. */
+ if (node && !node->finalized)
+ varpool_finalize_decl (h->to);
+ }
+ return 1;
+}
+
+/* Finalize emutls control vars and add a static constructor if
+ required. */
+
void
emutls_finish (void)
{
+ if (emutls_htab == NULL)
+ return;
+ htab_traverse_noresize (emutls_htab,
+ emutls_finalize_control_var, NULL);
+
if (targetm.emutls.register_common)
{
tree body = NULL_TREE;
- if (emutls_htab == NULL)
- return;
-
htab_traverse_noresize (emutls_htab, emutls_common_1, &body);
if (body == NULL_TREE)
return;