re PR c++/19450 (__thread static class members)

PR c++/19450
	* decl.c (redeclaration_error_message): Issue diagnostics about
	olddecl and newdecl disagreement on __thread property.
	(grokdeclarator): Set DECL_TLS_MODEL on class static variables.

	* g++.dg/tls/diag-3.C: New test.
	* g++.dg/tls/diag-4.C: New test.
	* g++.dg/tls/static-1.C: New test.
	* g++.dg/tls/static-1a.cc: New file.

From-SVN: r106657
This commit is contained in:
Jakub Jelinek 2005-11-08 22:44:58 +01:00 committed by Jakub Jelinek
parent da11c5d226
commit 31a7923695
7 changed files with 103 additions and 0 deletions

View File

@ -1,3 +1,10 @@
2005-11-08 Jakub Jelinek <jakub@redhat.com>
PR c++/19450
* decl.c (redeclaration_error_message): Issue diagnostics about
olddecl and newdecl disagreement on __thread property.
(grokdeclarator): Set DECL_TLS_MODEL on class static variables.
2005-11-08 Jason Merrill <jason@redhat.com>
PR c++/21123

View File

@ -2014,6 +2014,18 @@ redeclaration_error_message (tree newdecl, tree olddecl)
return NULL;
}
else if (TREE_CODE (newdecl) == VAR_DECL
&& DECL_THREAD_LOCAL_P (newdecl) != DECL_THREAD_LOCAL_P (olddecl))
{
/* Only variables can be thread-local, and all declarations must
agree on this property. */
if (DECL_THREAD_LOCAL_P (newdecl))
return "thread-local declaration of %q#D follows "
"non-thread-local declaration";
else
return "non-thread-local declaration of %q#D follows "
"thread-local declaration";
}
else if (toplevel_bindings_p () || DECL_NAMESPACE_SCOPE_P (newdecl))
{
/* Objects declared at top level: */
@ -8216,6 +8228,17 @@ grokdeclarator (const cp_declarator *declarator,
is considered undefined until an out-of-class
definition is provided. */
DECL_EXTERNAL (decl) = 1;
if (thread_p)
{
if (targetm.have_tls)
DECL_TLS_MODEL (decl) = decl_default_tls_model (decl);
else
/* A mere warning is sure to result in improper
semantics at runtime. Don't bother to allow this to
compile. */
error ("thread-local storage not supported for this target");
}
}
else
{

View File

@ -1,3 +1,11 @@
2005-11-08 Jakub Jelinek <jakub@redhat.com>
PR c++/19450
* g++.dg/tls/diag-3.C: New test.
* g++.dg/tls/diag-4.C: New test.
* g++.dg/tls/static-1.C: New test.
* g++.dg/tls/static-1a.cc: New file.
2005-11-08 Diego Novillo <dnovillo@redhat.com>
PR 23046

View File

@ -0,0 +1,10 @@
// Report invalid extern and __thread combinations.
extern int j; // { dg-error "previously declared here" }
__thread int j; // { dg-error "follows non-thread-local" }
extern __thread int i; // { dg-error "previously declared here" }
int i; // { dg-error "follows thread-local" }
extern __thread int k; // This is fine.
__thread int k;

View File

@ -0,0 +1,9 @@
/* Invalid __thread specifiers. */
__thread typedef int g4; /* { dg-error "multiple storage classes" } */
void foo()
{
__thread auto int l2; /* { dg-error "multiple storage classes" } */
__thread register int l4; /* { dg-error "multiple storage classes" } */
}

View File

@ -0,0 +1,28 @@
// { dg-do run }
// { dg-options "-O2" }
// { dg-additional-sources "static-1a.cc" }
extern "C" void abort ();
extern int test ();
struct A
{
static __thread int i;
};
__thread int A::i = 8;
int
main ()
{
if (A::i != 8)
abort ();
if (test ())
abort ();
if (A::i != 17)
abort ();
return 0;
}

View File

@ -0,0 +1,18 @@
// { dg-do run }
// { dg-options "-O2" }
// { dg-additional-sources "static-1a.cc" }
struct A
{
static __thread int i;
};
int
test ()
{
if (A::i != 8)
return 1;
A::i = 17;
return 0;
}