diff options
author | Iain Sandoe <iains@gcc.gnu.org> | 2010-05-24 14:36:32 +0000 |
---|---|---|
committer | Iain Sandoe <iains@gcc.gnu.org> | 2010-05-24 14:36:32 +0000 |
commit | 1db0429a13b229a2a2ad43ca895786871f0b4834 (patch) | |
tree | 572e1afe3e6475f92e50a9110276f5d8b13583fa /gcc | |
parent | e72e2da4db2f88219961c6615f0d5a673be3aaa4 (diff) | |
download | gcc-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/ChangeLog | 13 | ||||
-rw-r--r-- | gcc/toplev.c | 9 | ||||
-rw-r--r-- | gcc/varasm.c | 39 |
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; |