* 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.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@106657
138bc75d-0d04-0410-961f-
82ee72b054a4
+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
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: */
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
{
+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
--- /dev/null
+// 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;
--- /dev/null
+/* 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" } */
+}
--- /dev/null
+// { 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;
+}
--- /dev/null
+// { 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;
+}