aboutsummaryrefslogtreecommitdiff
path: root/gcc/lto/lto-symtab.c
diff options
context:
space:
mode:
authorJan Hubicka <hubicka@ucw.cz>2015-01-28 20:57:35 +0100
committerJan Hubicka <hubicka@gcc.gnu.org>2015-01-28 19:57:35 +0000
commit040968a88a1e9a8e4dd5f760e3fb4cabe5a63979 (patch)
treece1cc776ee6015b0d1ee8a88699584424616e54e /gcc/lto/lto-symtab.c
parentb1474d30f9ef6570beb3a9263ae520dc1ac1bb3a (diff)
downloadgcc-040968a88a1e9a8e4dd5f760e3fb4cabe5a63979.zip
gcc-040968a88a1e9a8e4dd5f760e3fb4cabe5a63979.tar.gz
gcc-040968a88a1e9a8e4dd5f760e3fb4cabe5a63979.tar.bz2
* lto-symtab.c (lto_varpool_replace_node): Merge TLS models.
From-SVN: r220214
Diffstat (limited to 'gcc/lto/lto-symtab.c')
-rw-r--r--gcc/lto/lto-symtab.c43
1 files changed, 38 insertions, 5 deletions
diff --git a/gcc/lto/lto-symtab.c b/gcc/lto/lto-symtab.c
index e3cc190..98edb88 100644
--- a/gcc/lto/lto-symtab.c
+++ b/gcc/lto/lto-symtab.c
@@ -158,11 +158,44 @@ lto_varpool_replace_node (varpool_node *vnode,
if (vnode->tls_model != prevailing_node->tls_model)
{
- error_at (DECL_SOURCE_LOCATION (vnode->decl),
- "%qD is defined as %s", vnode->decl, tls_model_names [vnode->tls_model]);
- inform (DECL_SOURCE_LOCATION (prevailing_node->decl),
- "previously defined here as %s",
- tls_model_names [prevailing_node->tls_model]);
+ bool error = false;
+
+ /* Non-TLS and TLS never mix together. Also emulated model is not
+ compatible with anything else. */
+ if (prevailing_node->tls_model == TLS_MODEL_NONE
+ || prevailing_node->tls_model == TLS_MODEL_EMULATED
+ || vnode->tls_model == TLS_MODEL_NONE
+ || vnode->tls_model == TLS_MODEL_EMULATED)
+ error = true;
+ /* Linked is silently supporting transitions
+ GD -> IE, GD -> LE, LD -> LE, IE -> LE, LD -> IE.
+ Do the same transitions and error out on others. */
+ else if ((prevailing_node->tls_model == TLS_MODEL_REAL
+ || prevailing_node->tls_model == TLS_MODEL_LOCAL_DYNAMIC)
+ && (vnode->tls_model == TLS_MODEL_INITIAL_EXEC
+ || vnode->tls_model == TLS_MODEL_LOCAL_EXEC))
+ prevailing_node->tls_model = vnode->tls_model;
+ else if ((vnode->tls_model == TLS_MODEL_REAL
+ || vnode->tls_model == TLS_MODEL_LOCAL_DYNAMIC)
+ && (prevailing_node->tls_model == TLS_MODEL_INITIAL_EXEC
+ || prevailing_node->tls_model == TLS_MODEL_LOCAL_EXEC))
+ ;
+ else if (prevailing_node->tls_model == TLS_MODEL_INITIAL_EXEC
+ && vnode->tls_model == TLS_MODEL_LOCAL_EXEC)
+ prevailing_node->tls_model = vnode->tls_model;
+ else if (vnode->tls_model == TLS_MODEL_INITIAL_EXEC
+ && prevailing_node->tls_model == TLS_MODEL_LOCAL_EXEC)
+ ;
+ else
+ error = true;
+ if (error)
+ {
+ error_at (DECL_SOURCE_LOCATION (vnode->decl),
+ "%qD is defined with tls model %s", vnode->decl, tls_model_names [vnode->tls_model]);
+ inform (DECL_SOURCE_LOCATION (prevailing_node->decl),
+ "previously defined here as %s",
+ tls_model_names [prevailing_node->tls_model]);
+ }
}
/* Finally remove the replaced node. */
vnode->remove ();