Do not call null register_common in emutls
authorAlexandre Oliva <oliva@adacore.com>
Mon, 17 Feb 2020 20:08:11 +0000 (17:08 -0300)
committerAlexandre Oliva <oliva@gnu.org>
Mon, 17 Feb 2020 20:08:11 +0000 (17:08 -0300)
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.

gcc/ChangeLog
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/tls/emutls-3.c [new file with mode: 0644]
gcc/tree-emutls.c

index ef968492ee12be6e87a668cd21bf86723bec2cbe..a07e536789faa8d6ffe4b9a72bed10a2fac8b214 100644 (file)
@@ -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
index 1b6c566ac8426e192ce268af566b8aedca124699..2e8d92221dbf7fed51d4a97b7833eb1bab696ddc 100644 (file)
@@ -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 (file)
index 0000000..e062ba8
--- /dev/null
@@ -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;
+}
index e9241243f23a896ce80d90ae9fb539e8aa8f52d5..44755dd406aeeed114f047e9583b9ae737f4a9cc 100644 (file)
@@ -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;