OSDN Git Service

PR c++/19450
authorjakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 8 Nov 2005 21:44:58 +0000 (21:44 +0000)
committerjakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 8 Nov 2005 21:44:58 +0000 (21:44 +0000)
* 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

gcc/cp/ChangeLog
gcc/cp/decl.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/tls/diag-3.C [new file with mode: 0644]
gcc/testsuite/g++.dg/tls/diag-4.C [new file with mode: 0644]
gcc/testsuite/g++.dg/tls/static-1.C [new file with mode: 0644]
gcc/testsuite/g++.dg/tls/static-1a.cc [new file with mode: 0644]

index 1b2d166..bcbddc7 100644 (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
index c5fe658..7263b32 100644 (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
              {
index 6444335..8058bb8 100644 (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
diff --git a/gcc/testsuite/g++.dg/tls/diag-3.C b/gcc/testsuite/g++.dg/tls/diag-3.C
new file mode 100644 (file)
index 0000000..ae2b6ce
--- /dev/null
@@ -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 (file)
index 0000000..3b840f1
--- /dev/null
@@ -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 (file)
index 0000000..3cbcbec
--- /dev/null
@@ -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 (file)
index 0000000..c87efdb
--- /dev/null
@@ -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;
+}