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.
This commit is contained in:
parent
bc0f8df124
commit
96bae436e0
@ -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
|
||||
|
@ -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.
|
||||
|
26
gcc/testsuite/gcc.dg/tls/emutls-3.c
Normal file
26
gcc/testsuite/gcc.dg/tls/emutls-3.c
Normal file
@ -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;
|
||||
}
|
@ -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;
|
||||
|
Loading…
x
Reference in New Issue
Block a user