Add TLS checks to ObjC

* objc-obj-c++-shared/Object1.m: New.
	* objc.dg/torture: New directory.
	* objc.dg/torture/tls: Ditto.
	* objc.dg/tls: Ditto.
	* objc.dg/torture/tls/trivial.m: New test.
	* objc.dg/torture/tls/thr-init-2.m: New test.
	* objc.dg/torture/tls/thr-init-3.m: New test.
	* objc.dg/torture/tls/thr-init.m: New test.
	* objc.dg/torture/tls/diag-1.m: New test.
	* objc.dg/torture/tls/tls.exp: New.
	* objc.dg/torture/trivial.m: New test.
	* objc.dg/torture/dg-torture.exp: New.
	* objc.dg/tls/diag-3.m: New test.
	* objc.dg/tls/diag-4.m: New test.
	* objc.dg/tls/diag-5.m: New test.
	* objc.dg/tls/init-1.m: New test.
	* objc.dg/tls/init-2.m: New test.
	* objc.dg/tls/tls.exp: New.
	* objc.dg/tls/diag-2.m: New test.
	* lib/objc.exp: Respond to dg-additional-files.

From-SVN: r159311
This commit is contained in:
Iain Sandoe 2010-05-12 11:16:33 +00:00
parent 623a6941fa
commit 101422f049
18 changed files with 300 additions and 4 deletions

View File

@ -1,3 +1,26 @@
2010-05-12 Iain Sandoe <iains@gcc.gnu.org>
* objc-obj-c++-shared/Object1.m: New.
* objc.dg/torture: New directory.
* objc.dg/torture/tls: Ditto.
* objc.dg/tls: Ditto.
* objc.dg/torture/tls/trivial.m: New test.
* objc.dg/torture/tls/thr-init-2.m: New test.
* objc.dg/torture/tls/thr-init-3.m: New test.
* objc.dg/torture/tls/thr-init.m: New test.
* objc.dg/torture/tls/diag-1.m: New test.
* objc.dg/torture/tls/tls.exp: New.
* objc.dg/torture/trivial.m: New test.
* objc.dg/torture/dg-torture.exp: New.
* objc.dg/tls/diag-3.m: New test.
* objc.dg/tls/diag-4.m: New test.
* objc.dg/tls/diag-5.m: New test.
* objc.dg/tls/init-1.m: New test.
* objc.dg/tls/init-2.m: New test.
* objc.dg/tls/tls.exp: New.
* objc.dg/tls/diag-2.m: New test.
* lib/objc.exp: Respond to dg-additional-files.
2010-05-12 Maxim Kuvyrkov <maxim@codesourcery.com>
* gcc.target/m68k/20100512-1.c: New.

View File

@ -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"

View File

@ -27,14 +27,15 @@ if ![info exists DEFAULT_CFLAGS] then {
# Initialize `dg'.
dg-init
# Gather a list of all tests.
set tests [lsort [glob -nocomplain $srcdir/$subdir/*.m]]
# Main loop.
dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.\[m\]]] \
"-fgnu-runtime" $DEFAULT_CFLAGS
dg-runtest $tests "-fgnu-runtime" $DEFAULT_CFLAGS
# darwin targets can also run code with the NeXT runtime.
if [istarget "*-*-darwin*" ] {
dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.\[m\]]] \
"-fnext-runtime" $DEFAULT_CFLAGS
dg-runtest $tests "-fnext-runtime" $DEFAULT_CFLAGS
}
# All done.

View File

@ -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 " '__thread' used with 'typedef'" } */
void foo()
{
__thread int l1; /* { dg-error "implicitly auto and declared '__thread'" } */
auto __thread int l2; /* { dg-error "'__thread' used with 'auto'" } */
__thread extern int l3; /* { dg-error "'__thread' before 'extern'" } */
register __thread int l4; /* { dg-error "'__thread' used with 'register'" } */
}
__thread void f1 (); /* { dg-error "invalid storage class for function 'f1'" } */
extern __thread void f2 (); /* { dg-error "invalid storage class for function 'f2'" } */
static __thread void f3 (); /* { dg-error "invalid storage class for function 'f3'" } */
__thread void f4 () { } /* { dg-error "function definition declared '__thread'" } */
void bar(__thread int p1); /* { dg-error "(invalid in parameter)|(specified for parameter)" } */
struct A {
__thread int i; /* { dg-error "expected specifier-qualifier-list before '__thread'" } */
};

View File

@ -0,0 +1,11 @@
/* Report invalid extern and __thread combinations. */
/* { dg-require-effective-target tls } */
extern int j; /* { dg-message "previous declaration of 'j' was here" } */
__thread int j; /* { dg-error "follows non-thread-local" } */
extern __thread int i; /* { dg-message "previous declaration of 'i' was here" } */
int i; /* { dg-error "follows thread-local" } */
extern __thread int k; /* This is fine. */
__thread int k;

View File

@ -0,0 +1,10 @@
/* Invalid __thread specifiers. */
/* { dg-require-effective-target tls } */
__thread typedef int g4; /* { dg-error "'__thread' used with 'typedef'" } */
void foo()
{
__thread auto int l2; /* { dg-error "'__thread' used with 'auto'" } */
__thread register int l4; /* { dg-error "'__thread' used with 'register'" } */
}

View File

@ -0,0 +1,4 @@
/* __thread specifiers on empty declarations. */
/* { dg-require-effective-target tls } */
__thread struct foo; /* { dg-warning "useless '__thread' in empty declaration" } */

View File

@ -0,0 +1,5 @@
/* Invalid initializations. */
/* { dg-require-effective-target tls } */
extern __thread int i;
int *p = &i; /* { dg-error "initializer element is not constant" } */

View File

@ -0,0 +1,14 @@
/* Invalid initializations. */
/* { dg-require-effective-target tls } */
extern __thread int i;
__thread int *p = &i; /* { dg-error "initializer element is not constant" } */
extern int f();
__thread int j = f(); /* { dg-error "initializer element is not constant" } */
struct S
{
S(); /* { dg-error "expected specifier-qualifier-list before 'S'" } */
};
__thread S s; /* { dg-error "expected" } two errors here */

View File

@ -0,0 +1,26 @@
# Load support procs.
load_lib objc-dg.exp
# If a testcase doesn't have special options, use these.
global DEFAULT_CFLAGS
if ![info exists DEFAULT_CFLAGS] then {
set DEFAULT_CFLAGS ""
}
# Initialize `dg'.
dg-init
# Gather a list of all tests.
set tests [lsort [glob -nocomplain $srcdir/$subdir/*.m]]
# Main loop.
dg-runtest $tests "-fgnu-runtime" $DEFAULT_CFLAGS
# darwin targets can also run code with the NeXT runtime.
if [istarget "*-*-darwin*" ] {
dg-runtest $tests "-fnext-runtime" $DEFAULT_CFLAGS
}
# All done.
dg-finish

View File

@ -0,0 +1,17 @@
# This harness is for tests that should be run at all optimisation levels.
load_lib objc-dg.exp
dg-init
# Gather a list of all tests.
set tests [lsort [glob -nocomplain $srcdir/$subdir/*.m]]
objc-dg-runtest $tests "-fgnu-runtime"
# darwin targets can also run code with the NeXT runtime.
if [istarget "*-*-darwin*" ] {
objc-dg-runtest $tests "-fnext-runtime"
}
dg-finish

View File

@ -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;
}

View File

@ -0,0 +1,42 @@
// { dg-require-effective-target tls }
// { dg-do run }
extern void _exit(int);
__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 )
_exit (-(__LINE__)) ;
a = fa(glb);
if ( a != 6 )
_exit (-(__LINE__)) ;
a = fb(a);
if ( a != 10 || glb != 10 )
_exit (-(__LINE__)) ;
return 0;
}

View File

@ -0,0 +1,38 @@
/* { dg-require-effective-target tls } */
/* { dg-do run } */
/* { dg-xfail-run-if "Needs OBJC2 ABI" { *-*-darwin* && { lp64 && { ! objc2 } } } { "-fnext-runtime" } { "" } } */
/* { dg-additional-sources "../../../objc-obj-c++-shared/Object1.m" } */
#include "../../../objc-obj-c++-shared/Object1.h"
extern void _exit(int);
@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 )
_exit (-(__LINE__)) ;
return 0;
}

View File

@ -0,0 +1,25 @@
/* { dg-require-effective-target tls } */
/* { dg-do run } */
extern void _exit(int);
static __thread int fstat ;
static __thread int fstat = 1;
static __thread int fstat ;
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 ) _exit (-(__LINE__)) ;
return 0;
}

View File

@ -0,0 +1,17 @@
# This harness is for tests that should be run at all optimisation levels.
load_lib objc-dg.exp
dg-init
# Gather a list of all tests.
set tests [lsort [glob -nocomplain $srcdir/$subdir/*.m]]
objc-dg-runtest $tests "-fgnu-runtime"
# darwin targets can also run code with the NeXT runtime.
if [istarget "*-*-darwin*" ] {
objc-dg-runtest $tests "-fnext-runtime"
}
dg-finish

View File

@ -0,0 +1,3 @@
// { dg-require-effective-target tls }
__thread int i;

View File

@ -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.m" } */
#import "../../objc-obj-c++-shared/Object1.h"
int main(void)
{
[Object class];
return 0;
}