diff options
author | Jakub Jelinek <jakub@redhat.com> | 2005-11-08 22:44:58 +0100 |
---|---|---|
committer | Jakub Jelinek <jakub@gcc.gnu.org> | 2005-11-08 22:44:58 +0100 |
commit | 31a7923695f5540aa1b721f35ab21e471320bda6 (patch) | |
tree | c3d8a4d48d1074926a1e30b5347d5e5bdfc1a4b8 | |
parent | da11c5d2261283280dade0b9a7942ed56c4e67de (diff) | |
download | gcc-31a7923695f5540aa1b721f35ab21e471320bda6.zip gcc-31a7923695f5540aa1b721f35ab21e471320bda6.tar.gz gcc-31a7923695f5540aa1b721f35ab21e471320bda6.tar.bz2 |
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
-rw-r--r-- | gcc/cp/ChangeLog | 7 | ||||
-rw-r--r-- | gcc/cp/decl.c | 23 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 8 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/tls/diag-3.C | 10 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/tls/diag-4.C | 9 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/tls/static-1.C | 28 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/tls/static-1a.cc | 18 |
7 files changed, 103 insertions, 0 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 1b2d166..bcbddc7 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -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 diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index c5fe658..7263b32 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -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 { diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 6444335..8058bb8 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -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 diff --git a/gcc/testsuite/g++.dg/tls/diag-3.C b/gcc/testsuite/g++.dg/tls/diag-3.C new file mode 100644 index 0000000..ae2b6ce --- /dev/null +++ b/gcc/testsuite/g++.dg/tls/diag-3.C @@ -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; diff --git a/gcc/testsuite/g++.dg/tls/diag-4.C b/gcc/testsuite/g++.dg/tls/diag-4.C new file mode 100644 index 0000000..3b840f1 --- /dev/null +++ b/gcc/testsuite/g++.dg/tls/diag-4.C @@ -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" } */ +} diff --git a/gcc/testsuite/g++.dg/tls/static-1.C b/gcc/testsuite/g++.dg/tls/static-1.C new file mode 100644 index 0000000..3cbcbec --- /dev/null +++ b/gcc/testsuite/g++.dg/tls/static-1.C @@ -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; +} diff --git a/gcc/testsuite/g++.dg/tls/static-1a.cc b/gcc/testsuite/g++.dg/tls/static-1a.cc new file mode 100644 index 0000000..c87efdb --- /dev/null +++ b/gcc/testsuite/g++.dg/tls/static-1a.cc @@ -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; +} |