OSDN Git Service

add TLS checks to ObjC++
authoriains <iains@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 25 May 2010 08:28:44 +0000 (08:28 +0000)
committeriains <iains@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 25 May 2010 08:28:44 +0000 (08:28 +0000)
* obj-c++.dg/torture/tls/trivial.mm: New.
* obj-c++.dg/torture/tls/thr-init-1.mm: New.
* obj-c++.dg/torture/tls/thr-init-2.mm: New.
* obj-c++.dg/torture/tls/thr-init-3.mm: New.
* obj-c++.dg/torture/tls/diag-1.mm: New.
* obj-c++.dg/torture/tls/tls.exp: New.
* obj-c++.dg/torture/trivial.mm: New.
* obj-c++.dg/torture/dg-torture.exp: New.
* obj-c++.dg/dg.exp: Gather tests explicitly from the source dir.
* obj-c++.dg/tls/trivial.m: New.
* obj-c++.dg/tls/init-1.mm: New.
* obj-c++.dg/tls/diag-1.mm: New.
* obj-c++.dg/tls/init-2.mm: New.
* obj-c++.dg/tls/diag-2.mm: New.
* obj-c++.dg/tls/diag-3.mm: New.
* obj-c++.dg/tls/diag-4.mm: New.
* obj-c++.dg/tls/static-1.mm: New.
* obj-c++.dg/tls/tls.exp: New.
* obj-c++.dg/tls/diag-5.mm: New.
* obj-c++.dg/tls/static-1a.mm: New.
* objc-obj-c++-shared/Object1.mm: New.
* lib/obj-c++-dg.exp (obj-c++-dg-runtest): New proc.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@159810 138bc75d-0d04-0410-961f-82ee72b054a4

23 files changed:
gcc/testsuite/ChangeLog
gcc/testsuite/lib/obj-c++-dg.exp
gcc/testsuite/obj-c++.dg/dg.exp
gcc/testsuite/obj-c++.dg/tls/diag-1.mm [new file with mode: 0644]
gcc/testsuite/obj-c++.dg/tls/diag-2.mm [new file with mode: 0644]
gcc/testsuite/obj-c++.dg/tls/diag-3.mm [new file with mode: 0644]
gcc/testsuite/obj-c++.dg/tls/diag-4.mm [new file with mode: 0644]
gcc/testsuite/obj-c++.dg/tls/diag-5.mm [new file with mode: 0644]
gcc/testsuite/obj-c++.dg/tls/init-1.mm [new file with mode: 0644]
gcc/testsuite/obj-c++.dg/tls/init-2.mm [new file with mode: 0644]
gcc/testsuite/obj-c++.dg/tls/static-1.mm [new file with mode: 0644]
gcc/testsuite/obj-c++.dg/tls/static-1a.mm [new file with mode: 0644]
gcc/testsuite/obj-c++.dg/tls/tls.exp [new file with mode: 0644]
gcc/testsuite/obj-c++.dg/tls/trivial.m [new file with mode: 0644]
gcc/testsuite/obj-c++.dg/torture/dg-torture.exp [new file with mode: 0644]
gcc/testsuite/obj-c++.dg/torture/tls/diag-1.mm [new file with mode: 0644]
gcc/testsuite/obj-c++.dg/torture/tls/thr-init-1.mm [new file with mode: 0644]
gcc/testsuite/obj-c++.dg/torture/tls/thr-init-2.mm [new file with mode: 0644]
gcc/testsuite/obj-c++.dg/torture/tls/thr-init-3.mm [new file with mode: 0644]
gcc/testsuite/obj-c++.dg/torture/tls/tls.exp [new file with mode: 0644]
gcc/testsuite/obj-c++.dg/torture/tls/trivial.mm [new file with mode: 0644]
gcc/testsuite/obj-c++.dg/torture/trivial.mm [new file with mode: 0644]
gcc/testsuite/objc-obj-c++-shared/Object1.mm [new file with mode: 0644]

index 146fa02..b0db389 100644 (file)
@@ -1,3 +1,28 @@
+2010-05-25  Iain Sandoe  <iains@gcc.gnu.org>
+
+       * obj-c++.dg/torture/tls/trivial.mm: New.
+       * obj-c++.dg/torture/tls/thr-init-1.mm: New.
+       * obj-c++.dg/torture/tls/thr-init-2.mm: New.
+       * obj-c++.dg/torture/tls/thr-init-3.mm: New.
+       * obj-c++.dg/torture/tls/diag-1.mm: New.
+       * obj-c++.dg/torture/tls/tls.exp: New.
+       * obj-c++.dg/torture/trivial.mm: New.
+       * obj-c++.dg/torture/dg-torture.exp: New.
+       * obj-c++.dg/dg.exp: Gather tests explicitly from the source dir.
+       * obj-c++.dg/tls/trivial.m: New.
+       * obj-c++.dg/tls/init-1.mm: New.
+       * obj-c++.dg/tls/diag-1.mm: New.
+       * obj-c++.dg/tls/init-2.mm: New.
+       * obj-c++.dg/tls/diag-2.mm: New.
+       * obj-c++.dg/tls/diag-3.mm: New.
+       * obj-c++.dg/tls/diag-4.mm: New.
+       * obj-c++.dg/tls/static-1.mm: New.
+       * obj-c++.dg/tls/tls.exp: New.
+       * obj-c++.dg/tls/diag-5.mm: New.
+       * obj-c++.dg/tls/static-1a.mm: New.
+       * objc-obj-c++-shared/Object1.mm: New.
+       * lib/obj-c++-dg.exp (obj-c++-dg-runtest): New proc.
+
 2010-05-24  Iain Sandoe  <iains@gcc.gnu.org>
 
        PR ObjC++/43689
index dc8c560..dbdeaa2 100644 (file)
@@ -26,3 +26,9 @@ proc obj-c++-dg-test { prog do_what extra_tool_flags } {
 proc obj-c++-dg-prune { system text } {
     return [gcc-dg-prune $system $text]
 }
+
+# Modified dg-runtest that can cycle through a list of optimization options
+# as c-torture does.
+proc obj-c++-dg-runtest { testcases default-extra-flags } {
+    return [gcc-dg-runtest $testcases ${default-extra-flags}]
+}
index 1097464..bff972b 100644 (file)
@@ -28,7 +28,7 @@ if ![info exists DEFAULT_OBJCXXFLAGS] then {
 dg-init
 
 # Gather a list of all tests.
-set tests [lsort [find $srcdir/$subdir *.mm]]
+set tests [lsort [glob -nocomplain $srcdir/$subdir/*.mm]]
 
 # Main loop.
 dg-runtest $tests "-fgnu-runtime" $DEFAULT_OBJCXXFLAGS
diff --git a/gcc/testsuite/obj-c++.dg/tls/diag-1.mm b/gcc/testsuite/obj-c++.dg/tls/diag-1.mm
new file mode 100644 (file)
index 0000000..7c3245d
--- /dev/null
@@ -0,0 +1,12 @@
+// Valid __thread specifiers.
+// { dg-require-effective-target tls }
+
+__thread int g1;
+extern __thread int g2;
+static __thread int g3;
+
+void foo()
+{
+  extern __thread int l1;
+  static __thread int l2;
+}
diff --git a/gcc/testsuite/obj-c++.dg/tls/diag-2.mm b/gcc/testsuite/obj-c++.dg/tls/diag-2.mm
new file mode 100644 (file)
index 0000000..de88eb1
--- /dev/null
@@ -0,0 +1,26 @@
+/* Invalid __thread specifiers.  */
+/* { dg-require-effective-target tls } */
+
+__thread extern int g1;                /* { dg-error "'__thread' before 'extern'" } */
+__thread static int g2;                /* { dg-error "'__thread' before 'static'" } */
+__thread __thread int g3;      /* { dg-error "duplicate '__thread'" } */
+typedef __thread int g4;       /* { dg-error "multiple storage classes" } */
+
+void foo()
+{
+  __thread int l1;             /* { dg-error "implicitly auto and declared '__thread'" } */
+  auto __thread int l2;                /* { dg-error "multiple storage classes" } */
+  __thread extern int l3;      /* { dg-error "'__thread' before 'extern'" } */
+  register __thread int l4;    /* { dg-error "multiple storage classes" } */
+}
+
+__thread void f1 ();           /* { dg-error "storage class '__thread' invalid for function 'f1'" } */
+extern __thread void f2 ();    /* { dg-error "storage class '__thread' invalid for function 'f2'" } */
+static __thread void f3 ();    /* { dg-error "storage class '__thread' invalid for function 'f3'" } */
+__thread void f4 () { }                /* { dg-error "storage class '__thread' invalid for function 'f4'" } */
+
+void bar(__thread int p1);     /* { dg-error "(invalid in parameter)|(specified for parameter)" } */
+
+struct A {
+  __thread int i;              /* { dg-error "storage class specified for 'i'" } */
+};
diff --git a/gcc/testsuite/obj-c++.dg/tls/diag-3.mm b/gcc/testsuite/obj-c++.dg/tls/diag-3.mm
new file mode 100644 (file)
index 0000000..0a597b2
--- /dev/null
@@ -0,0 +1,11 @@
+/* Report invalid extern and __thread combinations. */
+/* { dg-require-effective-target tls } */
+
+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/obj-c++.dg/tls/diag-4.mm b/gcc/testsuite/obj-c++.dg/tls/diag-4.mm
new file mode 100644 (file)
index 0000000..10ac2aa
--- /dev/null
@@ -0,0 +1,10 @@
+/* Invalid __thread specifiers.  */
+/* { dg-require-effective-target tls } */
+
+__thread typedef int g4;       /* { dg-error "multiple storage classes in declaration of" } */
+
+void foo()
+{
+  __thread auto int l2;                /* { dg-error "multiple storage classes in declaration of" } */
+  __thread register int l4;    /* { dg-error "multiple storage classes in declaration of" } */
+}
diff --git a/gcc/testsuite/obj-c++.dg/tls/diag-5.mm b/gcc/testsuite/obj-c++.dg/tls/diag-5.mm
new file mode 100644 (file)
index 0000000..07ecd3f
--- /dev/null
@@ -0,0 +1,4 @@
+/* __thread specifiers on empty declarations.  */
+/* { dg-require-effective-target tls } */
+
+__thread struct foo; /* { dg-warning "qualifiers can only be specified for objects and functions" } */
diff --git a/gcc/testsuite/obj-c++.dg/tls/init-1.mm b/gcc/testsuite/obj-c++.dg/tls/init-1.mm
new file mode 100644 (file)
index 0000000..9430887
--- /dev/null
@@ -0,0 +1,14 @@
+/* Invalid initializations.  */
+/* { dg-require-effective-target tls } */
+
+__thread int i = 42;
+
+static int j;
+__thread int *p = &j;
+
+/* Note that this is valid in C++ (unlike C) as a run-time initialization.  */
+int *q = &i;
+
+/* Valid because "const int k" is an integral constant expression in C++.  */
+__thread const int k = 42;
+__thread const int l = k;
\ No newline at end of file
diff --git a/gcc/testsuite/obj-c++.dg/tls/init-2.mm b/gcc/testsuite/obj-c++.dg/tls/init-2.mm
new file mode 100644 (file)
index 0000000..dc886ba
--- /dev/null
@@ -0,0 +1,14 @@
+/* Invalid initializations.  */
+/* { dg-require-effective-target tls } */
+
+extern __thread int i;
+__thread int *p = &i;   /* { dg-error "dynamically initialized" } */
+
+extern int f();
+__thread int j = f();   /* { dg-error "dynamically initialized" } */
+
+struct S
+{
+  S();
+};
+__thread S s;           /* { dg-error "" } two errors here */
diff --git a/gcc/testsuite/obj-c++.dg/tls/static-1.mm b/gcc/testsuite/obj-c++.dg/tls/static-1.mm
new file mode 100644 (file)
index 0000000..2d20b88
--- /dev/null
@@ -0,0 +1,30 @@
+// { dg-do run }
+// { dg-require-effective-target tls }
+// { dg-additional-sources "static-1a.mm" }
+
+extern "C" {
+extern 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/obj-c++.dg/tls/static-1a.mm b/gcc/testsuite/obj-c++.dg/tls/static-1a.mm
new file mode 100644 (file)
index 0000000..4097420
--- /dev/null
@@ -0,0 +1,17 @@
+// { dg-skip-if "Additional Source File"  *-*-* "*" ""  }
+// This is the additional source file for test static-1.mm
+
+struct A
+{
+  static __thread int i;
+};
+
+int
+test ()
+{
+  if (A::i != 8)
+    return 1;
+
+  A::i = 17;
+  return 0;
+}
diff --git a/gcc/testsuite/obj-c++.dg/tls/tls.exp b/gcc/testsuite/obj-c++.dg/tls/tls.exp
new file mode 100644 (file)
index 0000000..a4ba639
--- /dev/null
@@ -0,0 +1,25 @@
+# Load support procs.
+load_lib obj-c++-dg.exp
+
+# If a testcase doesn't have special options, use these.
+global DEFAULT_OBJCXXFLAGS
+if ![info exists DEFAULT_OBJCXXFLAGS] then {
+    set DEFAULT_OBJCXXFLAGS " -ansi -pedantic-errors -Wno-long-long"
+}
+
+# Initialize `dg'.
+dg-init
+
+# Gather a list of all tests.
+set tests [lsort [glob -nocomplain $srcdir/$subdir/*.mm]]
+
+# Main loop.
+dg-runtest $tests "-fgnu-runtime" $DEFAULT_OBJCXXFLAGS
+
+# darwin targets can also run code with the NeXT runtime.
+if [istarget "*-*-darwin*" ] {
+dg-runtest $tests "-fnext-runtime" $DEFAULT_OBJCXXFLAGS
+}
+
+# All done.
+dg-finish
diff --git a/gcc/testsuite/obj-c++.dg/tls/trivial.m b/gcc/testsuite/obj-c++.dg/tls/trivial.m
new file mode 100644 (file)
index 0000000..e2b8f45
--- /dev/null
@@ -0,0 +1,3 @@
+// { dg-require-effective-target tls }
+
+__thread int i;
diff --git a/gcc/testsuite/obj-c++.dg/torture/dg-torture.exp b/gcc/testsuite/obj-c++.dg/torture/dg-torture.exp
new file mode 100644 (file)
index 0000000..9ef34e9
--- /dev/null
@@ -0,0 +1,17 @@
+# This harness is for tests that should be run at all optimisation levels.
+
+load_lib obj-c++-dg.exp
+
+dg-init
+
+# Gather a list of all tests.
+set tests [lsort [glob -nocomplain $srcdir/$subdir/*.mm]]
+obj-c++-dg-runtest $tests "-fgnu-runtime"
+
+# darwin targets can also run code with the NeXT runtime.
+if [istarget "*-*-darwin*" ] {
+  obj-c++-dg-runtest $tests "-fnext-runtime"
+}
+
+dg-finish
diff --git a/gcc/testsuite/obj-c++.dg/torture/tls/diag-1.mm b/gcc/testsuite/obj-c++.dg/torture/tls/diag-1.mm
new file mode 100644 (file)
index 0000000..7c3245d
--- /dev/null
@@ -0,0 +1,12 @@
+// Valid __thread specifiers.
+// { dg-require-effective-target tls }
+
+__thread int g1;
+extern __thread int g2;
+static __thread int g3;
+
+void foo()
+{
+  extern __thread int l1;
+  static __thread int l2;
+}
diff --git a/gcc/testsuite/obj-c++.dg/torture/tls/thr-init-1.mm b/gcc/testsuite/obj-c++.dg/torture/tls/thr-init-1.mm
new file mode 100644 (file)
index 0000000..45d67f4
--- /dev/null
@@ -0,0 +1,23 @@
+// { dg-require-effective-target tls }
+// { dg-do run }
+extern "C" {
+extern void abort ();
+}
+
+static __thread int fstat = 1;
+
+int test_code(int b)
+{
+  fstat += b ;
+  return fstat;
+}
+
+int main (int ac, char *av[])
+{
+  int a = test_code(1);
+  
+  if ( a != 2 || fstat != 2 ) 
+    abort ();
+  
+  return 0;
+}
diff --git a/gcc/testsuite/obj-c++.dg/torture/tls/thr-init-2.mm b/gcc/testsuite/obj-c++.dg/torture/tls/thr-init-2.mm
new file mode 100644 (file)
index 0000000..a96ae94
--- /dev/null
@@ -0,0 +1,44 @@
+// { dg-require-effective-target tls }
+// { dg-do run }
+
+extern "C" {
+extern void abort ();
+}
+
+__thread int glb =1 ;
+
+static __thread int fstat = 2;
+
+int fa(int a)
+{
+static __thread int as = 3;
+  as += a ;
+  return as;
+}
+
+int fb(int b)
+{
+static __thread int bs = 4;
+  bs += b ;
+  glb = bs;
+  return bs;
+}
+
+int main (int ac, char *av[])
+{
+  int a = 1;
+  
+  a = fa(fstat);
+  if ( a != 5 ) 
+    abort () ;
+
+  a = fa(glb);
+  if ( a != 6 ) 
+    abort () ;
+
+  a = fb(a);  
+  if ( a != 10 || glb != 10 ) 
+    abort () ;
+  
+  return 0;
+}
\ No newline at end of file
diff --git a/gcc/testsuite/obj-c++.dg/torture/tls/thr-init-3.mm b/gcc/testsuite/obj-c++.dg/torture/tls/thr-init-3.mm
new file mode 100644 (file)
index 0000000..98d1ba4
--- /dev/null
@@ -0,0 +1,41 @@
+/* { dg-require-effective-target tls } */
+/* { dg-do run } */
+/* { dg-xfail-if "PR44140" { *-*-* } { "-flto" "-fwhopr" } { "" } } */
+/* { dg-xfail-run-if "Needs OBJC2 ABI" { *-*-darwin* && { lp64 && { ! objc2 } } } { "-fnext-runtime" } { "" } } */
+/* { dg-additional-sources "../../../objc-obj-c++-shared/Object1.mm" } */
+
+#include "../../../objc-obj-c++-shared/Object1.h"
+extern "C" {
+extern void abort ();
+}
+
+@interface tsObj: Object {
+  int ai ;
+}
+
+- (int) fa:(int) n;
+
+@end
+
+@implementation tsObj
+
+- (int) fa:(int) n
+{
+static __thread int as = 3;
+  as += n ;
+  return as ;
+}
+
+@end
+
+int main (int ac, char *av[])
+{
+  int a ;
+  tsObj *to = [tsObj new];
+  
+  a = [to fa:5];
+  if ( a != 8 ) 
+    abort () ;
+  
+  return 0;
+}
diff --git a/gcc/testsuite/obj-c++.dg/torture/tls/tls.exp b/gcc/testsuite/obj-c++.dg/torture/tls/tls.exp
new file mode 100644 (file)
index 0000000..6d06680
--- /dev/null
@@ -0,0 +1,16 @@
+# This harness is for tests that should be run at all optimisation levels.
+
+load_lib obj-c++-dg.exp
+
+dg-init
+# Gather a list of all tests.
+set tests [lsort [glob -nocomplain $srcdir/$subdir/*.mm]]
+
+obj-c++-dg-runtest $tests "-fgnu-runtime"
+
+# darwin targets can also run code with the NeXT runtime.
+if [istarget "*-*-darwin*" ] {
+  obj-c++-dg-runtest $tests "-fnext-runtime"
+}
+
+dg-finish
diff --git a/gcc/testsuite/obj-c++.dg/torture/tls/trivial.mm b/gcc/testsuite/obj-c++.dg/torture/tls/trivial.mm
new file mode 100644 (file)
index 0000000..e2b8f45
--- /dev/null
@@ -0,0 +1,3 @@
+// { dg-require-effective-target tls }
+
+__thread int i;
diff --git a/gcc/testsuite/obj-c++.dg/torture/trivial.mm b/gcc/testsuite/obj-c++.dg/torture/trivial.mm
new file mode 100644 (file)
index 0000000..8d776b7
--- /dev/null
@@ -0,0 +1,11 @@
+// { dg-do run }
+// { dg-xfail-run-if "Needs OBJC2 ABI" { *-*-darwin* && { lp64 && { ! objc2 } } } { "-fnext-runtime" } { "" } }
+// { dg-additional-sources "../../objc-obj-c++-shared/Object1.mm" }
+
+#import "../../objc-obj-c++-shared/Object1.h"
+
+int main(void)
+{
+  [Object class];
+  return 0;
+}
diff --git a/gcc/testsuite/objc-obj-c++-shared/Object1.mm b/gcc/testsuite/objc-obj-c++-shared/Object1.mm
new file mode 100644 (file)
index 0000000..f435a75
--- /dev/null
@@ -0,0 +1,11 @@
+#import "Object1.h"
+/* This will generate the code if required - as determined by
+   the headr above.  It is kept like this to keep one code file
+   shared between dg-xxxx tests that can ask for an extra source
+   and the objc/{compile,execute}/xxx tests that have to include
+   the implementation explicitly.
+   
+   For cases/targets that don't require the generation of the
+   Object implementation, this should result in an empty object.
+*/
+#import "Object1-implementation.h"