aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorAlexandre Oliva <oliva@adacore.com>2020-02-17 17:08:11 -0300
committerAlexandre Oliva <oliva@gnu.org>2020-02-17 17:08:11 -0300
commit96bae436e0cb2b3e14ea7f16854e1b535a72ca66 (patch)
treeadd8279bb9b95dc60a2acd439ae488277b67df5e /gcc
parentbc0f8df124f6ee12c82c5a6c1335868a15bcaecb (diff)
downloadgcc-96bae436e0cb2b3e14ea7f16854e1b535a72ca66.zip
gcc-96bae436e0cb2b3e14ea7f16854e1b535a72ca66.tar.gz
gcc-96bae436e0cb2b3e14ea7f16854e1b535a72ca66.tar.bz2
Do not call null register_common in emutls
Thread-local variables with DECL_COMMON trigger an internal compiler error on targets that use emulated TLS without register_common, when we attempt to expand a call to the NULL register_common, with testcases as simple as gcc.dg/tls/emutls-2.c. The documentation states that, on such targets, common variables would fall back to explicitly initialized. This patch rearranges the code that deals with initialization of common and non-common variables, complementing code that is already in place to detect register_common-less targets. for gcc/ChangeLog * tree-emutls.c (new_emutls_decl, emutls_common_1): Complete handling of register_common-less targets. for gcc/testsuite/ChangeLog * gcc.dg/tls/emutls-3.c: New, combining emutls-2.c and thr-init-2.c into an execution test with explicitly common variables.
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog5
-rw-r--r--gcc/testsuite/ChangeLog6
-rw-r--r--gcc/testsuite/gcc.dg/tls/emutls-3.c26
-rw-r--r--gcc/tree-emutls.c4
4 files changed, 39 insertions, 2 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index ef96849..a07e536 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,8 @@
+2020-02-17 Alexandre Oliva <oliva@adacore.com>
+
+ * tree-emutls.c (new_emutls_decl, emutls_common_1): Complete
+ handling of register_common-less targets.
+
2020-02-17 Martin Liska <mliska@suse.cz>
PR ipa/93760
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 1b6c566..2e8d922 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,9 @@
+2020-02-17 Alexandre Oliva <oliva@adacore.com>
+
+ * gcc.dg/tls/emutls-3.c: New, combining emutls-2.c and
+ thr-init-2.c into an execution test with explicitly common
+ variables.
+
2020-02-17 Wilco Dijkstra <wdijkstr@arm.com>
* gcc.target/aarch64/pr93565.c: Fix test for ilp32.
diff --git a/gcc/testsuite/gcc.dg/tls/emutls-3.c b/gcc/testsuite/gcc.dg/tls/emutls-3.c
new file mode 100644
index 0000000..e062ba8
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tls/emutls-3.c
@@ -0,0 +1,26 @@
+/* { dg-do run } */
+/* { dg-require-effective-target tls } */
+/* { dg-require-effective-target global_constructor } */
+/* { dg-options "-O2" } */
+/* { dg-require-effective-target tls_runtime } */
+/* { dg-add-options tls } */
+
+__thread int i __attribute__((common));
+
+extern void abort (void);
+
+int test_code(int b)
+{
+ i += b ;
+ return i;
+}
+
+int main (int ac, char *av[])
+{
+ int a = test_code(test_code(1));
+
+ if ((a != 2) || (i != 2))
+ abort () ;
+
+ return 0;
+}
diff --git a/gcc/tree-emutls.c b/gcc/tree-emutls.c
index e924124..44755dd 100644
--- a/gcc/tree-emutls.c
+++ b/gcc/tree-emutls.c
@@ -322,7 +322,7 @@ new_emutls_decl (tree decl, tree alias_of)
control structure with size and alignment information. Initialization
of COMMON block variables happens elsewhere via a constructor. */
if (!DECL_EXTERNAL (to)
- && (!DECL_COMMON (to)
+ && (!DECL_COMMON (to) || !targetm.emutls.register_common
|| (DECL_INITIAL (decl)
&& DECL_INITIAL (decl) != error_mark_node)))
{
@@ -360,7 +360,7 @@ emutls_common_1 (tree tls_decl, tree control_decl, tree *pstmts)
tree x;
tree word_type_node;
- if (! DECL_COMMON (tls_decl)
+ if (!DECL_COMMON (tls_decl) || !targetm.emutls.register_common
|| (DECL_INITIAL (tls_decl)
&& DECL_INITIAL (tls_decl) != error_mark_node))
return;