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:
parent
623a6941fa
commit
101422f049
|
@ -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.
|
||||
|
|
|
@ -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"
|
|
@ -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.
|
||||
|
|
|
@ -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'" } */
|
||||
};
|
|
@ -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;
|
|
@ -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'" } */
|
||||
}
|
|
@ -0,0 +1,4 @@
|
|||
/* __thread specifiers on empty declarations. */
|
||||
/* { dg-require-effective-target tls } */
|
||||
|
||||
__thread struct foo; /* { dg-warning "useless '__thread' in empty declaration" } */
|
|
@ -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" } */
|
|
@ -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 */
|
|
@ -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
|
|
@ -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
|
|
@ -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;
|
||||
}
|
|
@ -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;
|
||||
}
|
|
@ -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;
|
||||
}
|
|
@ -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;
|
||||
}
|
|
@ -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
|
|
@ -0,0 +1,3 @@
|
|||
// { dg-require-effective-target tls }
|
||||
|
||||
__thread int i;
|
|
@ -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;
|
||||
}
|
Loading…
Reference in New Issue