mirror of
https://gcc.gnu.org/git/gcc.git
synced 2025-01-16 08:43:48 +08:00
next_mapping.h: Update for C++.
* objc/execute/next_mapping.h: Update for C++. * obj-c++.dg/selector-1.mm: Move to... * obj-c++.dg/selector-4.mm: here... * obj-c++.dg/comp-types-1.mm: New. * obj-c++.dg/cxx-class-1.mm: New. * obj-c++.dg/cxx-ivars-1.mm: New. * obj-c++.dg/cxx-ivars-2.mm: New. * obj-c++.dg/cxx-ivars-3.mm: New. * obj-c++.dg/cxx-scope-1.mm: New. * obj-c++.dg/cxx-scope-2.mm: New. * obj-c++.dg/defs.mm: New. * obj-c++.dg/empty-private-1.mm: New. * obj-c++.dg/encode-1.mm: New. * obj-c++.dg/encode-2.mm: New. * obj-c++.dg/encode-3.mm: New. * obj-c++.dg/extern-c-1.mm: New. * obj-c++.dg/extra-semi.mm: New. * obj-c++.dg/fix-and-continue-2.mm: New. * obj-c++.dg/isa-field-1.mm: New. * obj-c++.dg/ivar-list-semi.mm: New. * obj-c++.dg/local-decl-1.mm: New. * obj-c++.dg/lookup-1.mm: New. * obj-c++.dg/lookup-2.mm: New. * obj-c++.dg/method-1.mm: New. * obj-c++.dg/method-2.mm: New. * obj-c++.dg/method-3.mm: New. * obj-c++.dg/method-4.mm: New. * obj-c++.dg/method-5.mm: New. * obj-c++.dg/method-6.mm: New. * obj-c++.dg/method-7.mm: New. * obj-c++.dg/no-extra-load.mm: New. * obj-c++.dg/overload-1.mm: New. * obj-c++.dg/pragma-1.mm: New. * obj-c++.dg/pragma-2.mm: New. * obj-c++.dg/private-1.mm: New. * obj-c++.dg/private-2.mm: New. * obj-c++.dg/proto-qual-1.mm: New. * obj-c++.dg/qual-types-1.mm: New. * obj-c++.dg/stubify-1.mm: New. * obj-c++.dg/stubify-2.mm: New. * obj-c++.dg/super-class-1.mm: New. * obj-c++.dg/super-class-2.mm: New. * obj-c++.dg/super-dealloc-1.mm: New. * obj-c++.dg/super-dealloc-2.mm: New. * obj-c++.dg/template-1.mm: New. * obj-c++.dg/template-2.mm: New. * obj-c++.dg/template-3.mm: New. * obj-c++.dg/template-4.mm: New. * obj-c++.dg/template-5.mm: New. * obj-c++.dg/template-6.mm: New. * obj-c++.dg/try-catch-1.mm: New. * obj-c++.dg/try-catch-2.mm: New. * obj-c++.dg/try-catch-3.mm: New. * obj-c++.dg/try-catch-4.mm: New. * obj-c++.dg/try-catch-5.mm: New. * obj-c++.dg/try-catch-6.mm: New. * obj-c++.dg/try-catch-7.mm: New. * obj-c++.dg/try-catch-8.mm: New. * obj-c++.dg/try-catch-9.mm: New. * obj-c++.dg/va-meth-1.mm: New. Co-Authored-By: Mike Stump <mrs@apple.com> From-SVN: r100181
This commit is contained in:
parent
047c276597
commit
7cb56e5cd4
@ -1,8 +1,69 @@
|
||||
2005-05-25 Mike Stump <mrs@apple.com>
|
||||
2005-05-25 Ziemowit Laski <zlaski@apple.com>
|
||||
Mike Stump <mrs@apple.com>
|
||||
|
||||
* objc/execute/next_mapping.h: Update for C++.
|
||||
|
||||
* obj-c++.dg/selector-1.mm: Move to...
|
||||
* obj-c++.dg/selector-4.mm: here...
|
||||
|
||||
* obj-c++.dg/comp-types-1.mm: New.
|
||||
* obj-c++.dg/cxx-class-1.mm: New.
|
||||
* obj-c++.dg/cxx-ivars-1.mm: New.
|
||||
* obj-c++.dg/cxx-ivars-2.mm: New.
|
||||
* obj-c++.dg/cxx-ivars-3.mm: New.
|
||||
* obj-c++.dg/cxx-scope-1.mm: New.
|
||||
* obj-c++.dg/cxx-scope-2.mm: New.
|
||||
* obj-c++.dg/defs.mm: New.
|
||||
* obj-c++.dg/empty-private-1.mm: New.
|
||||
* obj-c++.dg/encode-1.mm: New.
|
||||
* obj-c++.dg/encode-2.mm: New.
|
||||
* obj-c++.dg/encode-3.mm: New.
|
||||
* obj-c++.dg/extern-c-1.mm: New.
|
||||
* obj-c++.dg/extra-semi.mm: New.
|
||||
* obj-c++.dg/fix-and-continue-2.mm: New.
|
||||
* obj-c++.dg/isa-field-1.mm: New.
|
||||
* obj-c++.dg/ivar-list-semi.mm: New.
|
||||
* obj-c++.dg/local-decl-1.mm: New.
|
||||
* obj-c++.dg/lookup-1.mm: New.
|
||||
* obj-c++.dg/lookup-2.mm: New.
|
||||
* obj-c++.dg/method-1.mm: New.
|
||||
* obj-c++.dg/method-2.mm: New.
|
||||
* obj-c++.dg/method-3.mm: New.
|
||||
* obj-c++.dg/method-4.mm: New.
|
||||
* obj-c++.dg/method-5.mm: New.
|
||||
* obj-c++.dg/method-6.mm: New.
|
||||
* obj-c++.dg/method-7.mm: New.
|
||||
* obj-c++.dg/no-extra-load.mm: New.
|
||||
* obj-c++.dg/overload-1.mm: New.
|
||||
* obj-c++.dg/pragma-1.mm: New.
|
||||
* obj-c++.dg/pragma-2.mm: New.
|
||||
* obj-c++.dg/private-1.mm: New.
|
||||
* obj-c++.dg/private-2.mm: New.
|
||||
* obj-c++.dg/proto-qual-1.mm: New.
|
||||
* obj-c++.dg/qual-types-1.mm: New.
|
||||
* obj-c++.dg/stubify-1.mm: New.
|
||||
* obj-c++.dg/stubify-2.mm: New.
|
||||
* obj-c++.dg/super-class-1.mm: New.
|
||||
* obj-c++.dg/super-class-2.mm: New.
|
||||
* obj-c++.dg/super-dealloc-1.mm: New.
|
||||
* obj-c++.dg/super-dealloc-2.mm: New.
|
||||
* obj-c++.dg/template-1.mm: New.
|
||||
* obj-c++.dg/template-2.mm: New.
|
||||
* obj-c++.dg/template-3.mm: New.
|
||||
* obj-c++.dg/template-4.mm: New.
|
||||
* obj-c++.dg/template-5.mm: New.
|
||||
* obj-c++.dg/template-6.mm: New.
|
||||
* obj-c++.dg/try-catch-1.mm: New.
|
||||
* obj-c++.dg/try-catch-2.mm: New.
|
||||
* obj-c++.dg/try-catch-3.mm: New.
|
||||
* obj-c++.dg/try-catch-4.mm: New.
|
||||
* obj-c++.dg/try-catch-5.mm: New.
|
||||
* obj-c++.dg/try-catch-6.mm: New.
|
||||
* obj-c++.dg/try-catch-7.mm: New.
|
||||
* obj-c++.dg/try-catch-8.mm: New.
|
||||
* obj-c++.dg/try-catch-9.mm: New.
|
||||
* obj-c++.dg/va-meth-1.mm: New.
|
||||
|
||||
2005-05-25 Ziemowit Laski <zlaski@apple.com>
|
||||
|
||||
* obj-c++.dg/selector-1.mm: New.
|
||||
|
16
gcc/testsuite/obj-c++.dg/comp-types-1.mm
Normal file
16
gcc/testsuite/obj-c++.dg/comp-types-1.mm
Normal file
@ -0,0 +1,16 @@
|
||||
/* { dg-do compile } */
|
||||
|
||||
@interface A
|
||||
+ new;
|
||||
@end
|
||||
|
||||
@interface B : A
|
||||
@end
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
B *b = [B new];
|
||||
A *a = b;
|
||||
|
||||
return (b == a);
|
||||
}
|
||||
|
18
gcc/testsuite/obj-c++.dg/cxx-class-1.mm
Normal file
18
gcc/testsuite/obj-c++.dg/cxx-class-1.mm
Normal file
@ -0,0 +1,18 @@
|
||||
/* Test that Objective-C++ is able to chew through a simple C++ class hierarchy.
|
||||
This was broken in earlier ObjC++ incarnations. */
|
||||
|
||||
struct foo
|
||||
{
|
||||
foo(void *a) {};
|
||||
};
|
||||
|
||||
struct bar : foo
|
||||
{
|
||||
bar() : foo((char*)0) {};
|
||||
};
|
||||
|
||||
class apple : foo
|
||||
{
|
||||
public:
|
||||
apple() : foo(0) { };
|
||||
};
|
42
gcc/testsuite/obj-c++.dg/cxx-ivars-1.mm
Normal file
42
gcc/testsuite/obj-c++.dg/cxx-ivars-1.mm
Normal file
@ -0,0 +1,42 @@
|
||||
// Check if ivars may be accessed via the C++ dot notation.
|
||||
|
||||
// { dg-do run }
|
||||
// { dg-options "-fno-objc-call-cxx-cdtors" }
|
||||
|
||||
#include <objc/Object.h>
|
||||
#include <stdlib.h>
|
||||
#define CHECK_IF(expr) if(!(expr)) abort()
|
||||
|
||||
struct cxx_struct {
|
||||
int a, b;
|
||||
void set_values (int _a, int _b = 3) {
|
||||
a = _a; b = _b;
|
||||
}
|
||||
~cxx_struct (void) {
|
||||
a = b = 99;
|
||||
}
|
||||
};
|
||||
|
||||
@interface Manip : Object {
|
||||
int c;
|
||||
cxx_struct s; // { dg-warning "user-defined destructor" }
|
||||
// { dg-warning "constructors and destructors will not be invoked" "" { target *-*-* } 22 }
|
||||
}
|
||||
- (void) manipulate_ivars;
|
||||
@end
|
||||
|
||||
@implementation Manip
|
||||
- (void) manipulate_ivars {
|
||||
s.set_values (7);
|
||||
CHECK_IF (s.a == 7 && s.b == 3);
|
||||
s.~cxx_struct();
|
||||
CHECK_IF (s.a == 99 && s.b == 99);
|
||||
}
|
||||
@end
|
||||
|
||||
int main (void)
|
||||
{
|
||||
Manip *obj = [Manip new];
|
||||
[obj manipulate_ivars];
|
||||
[obj free];
|
||||
}
|
76
gcc/testsuite/obj-c++.dg/cxx-ivars-2.mm
Normal file
76
gcc/testsuite/obj-c++.dg/cxx-ivars-2.mm
Normal file
@ -0,0 +1,76 @@
|
||||
// Check if the '- .cxx_construct' and '-.cxx_destruct' methods get called
|
||||
// and if they perform their desired function.
|
||||
|
||||
// { dg-do run }
|
||||
// { dg-options "-fobjc-call-cxx-cdtors" }
|
||||
|
||||
#include <objc/Object.h>
|
||||
#include <stdlib.h>
|
||||
#define CHECK_IF(expr) if(!(expr)) abort()
|
||||
|
||||
static int ctor1_called, ctor2_called, dtor1_called;
|
||||
|
||||
struct bar {
|
||||
int a, b;
|
||||
bar(void) {
|
||||
a = 5; b = 6;
|
||||
ctor1_called++;
|
||||
}
|
||||
~bar(void) {
|
||||
a = b = 99;
|
||||
dtor1_called++;
|
||||
}
|
||||
};
|
||||
|
||||
struct boo: bar {
|
||||
int c;
|
||||
boo(int _c = 9): c(_c) {
|
||||
ctor2_called++;
|
||||
}
|
||||
};
|
||||
|
||||
@interface Baz: Object {
|
||||
@public
|
||||
bar aa;
|
||||
}
|
||||
@end
|
||||
|
||||
@implementation Baz
|
||||
@end
|
||||
|
||||
@interface Foo: Baz {
|
||||
@public
|
||||
int a;
|
||||
boo bb;
|
||||
bar b;
|
||||
float c;
|
||||
bar d;
|
||||
}
|
||||
@end
|
||||
|
||||
@implementation Foo
|
||||
@end
|
||||
|
||||
int main (void)
|
||||
{
|
||||
CHECK_IF(!ctor1_called && !ctor2_called && !dtor1_called); /* are we sane? */
|
||||
|
||||
Baz *baz = [Baz new];
|
||||
CHECK_IF(ctor1_called && !ctor2_called && !dtor1_called);
|
||||
CHECK_IF(baz->aa.a == 5 && baz->aa.b == 6);
|
||||
ctor1_called = 0; /* reset */
|
||||
|
||||
[baz free];
|
||||
CHECK_IF(!ctor1_called && !ctor2_called && dtor1_called);
|
||||
dtor1_called = 0; /* reset */
|
||||
|
||||
Foo *foo = [Foo new];
|
||||
CHECK_IF(ctor1_called && ctor2_called && !dtor1_called);
|
||||
CHECK_IF(foo->bb.a == 5 && foo->bb.b == 6 && foo->bb.c == 9);
|
||||
CHECK_IF(foo->b.a == 5 && foo->b.b == 6);
|
||||
CHECK_IF(foo->d.a == 5 && foo->d.b == 6);
|
||||
ctor1_called = ctor2_called = 0; /* reset */
|
||||
|
||||
[foo free];
|
||||
CHECK_IF(!ctor1_called && !ctor2_called && dtor1_called);
|
||||
}
|
46
gcc/testsuite/obj-c++.dg/cxx-ivars-3.mm
Normal file
46
gcc/testsuite/obj-c++.dg/cxx-ivars-3.mm
Normal file
@ -0,0 +1,46 @@
|
||||
// Check if ObjC classes with non-POD C++ ivars are specially marked in the metadata.
|
||||
|
||||
// { dg-do run { target *-*-darwin* } }
|
||||
// { dg-options "-fobjc-call-cxx-cdtors -fnext-runtime" }
|
||||
|
||||
#include <objc/objc-runtime.h>
|
||||
#include <stdlib.h>
|
||||
#define CHECK_IF(expr) if(!(expr)) abort()
|
||||
|
||||
#ifndef CLS_HAS_CXX_STRUCTORS
|
||||
#define CLS_HAS_CXX_STRUCTORS 0x2000L
|
||||
#endif
|
||||
|
||||
struct cxx_struct {
|
||||
int a, b;
|
||||
cxx_struct (void) { a = b = 55; }
|
||||
};
|
||||
|
||||
@interface Foo {
|
||||
int c;
|
||||
cxx_struct s;
|
||||
}
|
||||
@end
|
||||
|
||||
@interface Bar: Foo {
|
||||
float f;
|
||||
}
|
||||
@end
|
||||
|
||||
@implementation Foo
|
||||
@end
|
||||
|
||||
@implementation Bar
|
||||
@end
|
||||
|
||||
int main (void)
|
||||
{
|
||||
Class cls;
|
||||
|
||||
cls = objc_getClass("Foo");
|
||||
CHECK_IF(cls->info & CLS_HAS_CXX_STRUCTORS);
|
||||
cls = objc_getClass("Bar");
|
||||
CHECK_IF(!(cls->info & CLS_HAS_CXX_STRUCTORS));
|
||||
|
||||
return 0;
|
||||
}
|
53
gcc/testsuite/obj-c++.dg/cxx-scope-1.mm
Normal file
53
gcc/testsuite/obj-c++.dg/cxx-scope-1.mm
Normal file
@ -0,0 +1,53 @@
|
||||
/* Handle C++ scoping ('::') operators in ObjC message receivers gracefully. */
|
||||
/* Author: Ziemowit Laski <zlaski@apple.com> */
|
||||
|
||||
/* { dg-do run } */
|
||||
|
||||
#include <objc/Object.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
@class Derived;
|
||||
|
||||
Derived *inst[3];
|
||||
|
||||
struct CxxClass {
|
||||
static Derived *get_instance(int);
|
||||
};
|
||||
|
||||
Derived *CxxClass::get_instance(int offs) {
|
||||
return inst[offs];
|
||||
}
|
||||
|
||||
@interface Derived: Object {
|
||||
int value;
|
||||
}
|
||||
-(id)initWithValue:(int)val;
|
||||
-(int)derived_meth;
|
||||
@end
|
||||
|
||||
@implementation Derived
|
||||
-(id)initWithValue:(int)val {
|
||||
[super init];
|
||||
value = val;
|
||||
return self;
|
||||
}
|
||||
- (int)derived_meth {
|
||||
return value;
|
||||
}
|
||||
@end
|
||||
|
||||
int main(void) {
|
||||
int r;
|
||||
inst[1] = [[::Derived alloc] initWithValue:7];
|
||||
inst[2] = [[Derived alloc] initWithValue:77];
|
||||
|
||||
r = [CxxClass::get_instance(2) derived_meth];
|
||||
if (r != 77)
|
||||
abort();
|
||||
|
||||
r = [CxxClass::get_instance(1) derived_meth];
|
||||
if (r != 7)
|
||||
abort();
|
||||
|
||||
return 0;
|
||||
}
|
19
gcc/testsuite/obj-c++.dg/cxx-scope-2.mm
Normal file
19
gcc/testsuite/obj-c++.dg/cxx-scope-2.mm
Normal file
@ -0,0 +1,19 @@
|
||||
/* Make sure Objective-C++ can distinguish ObjC classes from C++ classes. */
|
||||
/* Author: Ziemowit Laski <zlaski@apple.com> */
|
||||
|
||||
/* { dg-do compile } */
|
||||
|
||||
#include <objc/Object.h>
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
|
||||
@interface iostream: Object
|
||||
@end
|
||||
|
||||
int main(void) {
|
||||
id i = [std::iostream new]; /* { dg-warning "not an Objective\\-C class name or alias" } */
|
||||
i = [iostream new];
|
||||
i = [std::basic_string<char> new]; /* { dg-warning "not an Objective\\-C class name or alias" } */
|
||||
|
||||
return 0;
|
||||
}
|
43
gcc/testsuite/obj-c++.dg/defs.mm
Normal file
43
gcc/testsuite/obj-c++.dg/defs.mm
Normal file
@ -0,0 +1,43 @@
|
||||
/* Check @defs() in Objective-C++ */
|
||||
/* Contributed by Devang Patel <dpatel@apple.com> */
|
||||
|
||||
/* { dg-options "-lobjc" } */
|
||||
/* { dg-do run } */
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <objc/objc.h>
|
||||
#include <objc/Object.h>
|
||||
|
||||
extern void abort(void);
|
||||
|
||||
@interface A : Object
|
||||
{
|
||||
@public
|
||||
int a;
|
||||
}
|
||||
@end
|
||||
|
||||
struct A_defs
|
||||
{
|
||||
@defs(A);
|
||||
};
|
||||
|
||||
@implementation A
|
||||
- init
|
||||
{
|
||||
a = 42;
|
||||
return self;
|
||||
}
|
||||
@end
|
||||
|
||||
|
||||
int main()
|
||||
{
|
||||
A *a = [A init];
|
||||
struct A_defs *a_defs = (struct A_defs *)a;
|
||||
|
||||
if (a->a != a_defs->a)
|
||||
abort ();
|
||||
|
||||
return 0;
|
||||
}
|
9
gcc/testsuite/obj-c++.dg/empty-private-1.mm
Normal file
9
gcc/testsuite/obj-c++.dg/empty-private-1.mm
Normal file
@ -0,0 +1,9 @@
|
||||
/* Test for no entry after @private token. */
|
||||
|
||||
/* { do-do compile } */
|
||||
|
||||
@interface foo
|
||||
{
|
||||
@private
|
||||
}
|
||||
@end
|
23
gcc/testsuite/obj-c++.dg/encode-1.mm
Normal file
23
gcc/testsuite/obj-c++.dg/encode-1.mm
Normal file
@ -0,0 +1,23 @@
|
||||
/* Test for graceful encoding of const-qualified fields and parameters. */
|
||||
/* Author: Ziemowit Laski <zlaski@apple.com> */
|
||||
|
||||
/* { dg-do compile } */
|
||||
|
||||
struct Cxx {
|
||||
const struct Cxx *next;
|
||||
};
|
||||
|
||||
@interface ObjC {
|
||||
const struct Cxx *obj;
|
||||
}
|
||||
- (ObjC *)initWithCxx: (struct Cxx *const)c and: (const struct Cxx *)d;
|
||||
@end
|
||||
|
||||
@implementation ObjC
|
||||
- (ObjC *)initWithCxx: (struct Cxx *const)c and: (const struct Cxx *)d {
|
||||
obj = d;
|
||||
return self;
|
||||
}
|
||||
@end
|
||||
|
||||
/* { dg-final { scan-assembler "@\[0-9\]+@0:\[0-9\]+r\\^{Cxx=\\^r{Cxx}}\[0-9\]+\\^r{Cxx}" } } */
|
14
gcc/testsuite/obj-c++.dg/encode-2.mm
Normal file
14
gcc/testsuite/obj-c++.dg/encode-2.mm
Normal file
@ -0,0 +1,14 @@
|
||||
/* { dg-do compile } */
|
||||
|
||||
template <class T>
|
||||
struct Vec {
|
||||
T x, y;
|
||||
int z;
|
||||
};
|
||||
|
||||
Vec<double> dd;
|
||||
const char *enc = @encode(Vec<float>);
|
||||
const char *enc2 = @encode(Vec<double>);
|
||||
|
||||
/* { dg-final { scan-assembler "{Vec<float>=ffi}" } } */
|
||||
/* { dg-final { scan-assembler "{Vec<double>=ddi}" } } */
|
30
gcc/testsuite/obj-c++.dg/encode-3.mm
Normal file
30
gcc/testsuite/obj-c++.dg/encode-3.mm
Normal file
@ -0,0 +1,30 @@
|
||||
/* { dg-do run } */
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
template <class T>
|
||||
struct Vec {
|
||||
T x, y;
|
||||
long z;
|
||||
long long zz;
|
||||
};
|
||||
|
||||
Vec<double> dd;
|
||||
const char *enc = @encode(Vec<float>);
|
||||
const char *enc2 = @encode(Vec<double>);
|
||||
|
||||
int main(void) {
|
||||
char *encode = @encode(long);
|
||||
|
||||
if (strcmp (encode, "l"))
|
||||
abort();
|
||||
|
||||
if (strcmp (enc, "{Vec<float>=fflq}"))
|
||||
abort();
|
||||
|
||||
if (strcmp (enc2, "{Vec<double>=ddlq}"))
|
||||
abort();
|
||||
|
||||
return 0;
|
||||
}
|
18
gcc/testsuite/obj-c++.dg/extern-c-1.mm
Normal file
18
gcc/testsuite/obj-c++.dg/extern-c-1.mm
Normal file
@ -0,0 +1,18 @@
|
||||
/* Test extern c support inside @implementation */
|
||||
/* Devang Patel <dpatel@apple.com>. */
|
||||
|
||||
#include <objc/objc.h>
|
||||
|
||||
@interface Extern
|
||||
@end
|
||||
|
||||
@implementation Extern
|
||||
|
||||
extern "C" void NSRegisterElement(id element);
|
||||
|
||||
- init {
|
||||
NSRegisterElement(self);
|
||||
return self;
|
||||
}
|
||||
|
||||
@end
|
10
gcc/testsuite/obj-c++.dg/extra-semi.mm
Normal file
10
gcc/testsuite/obj-c++.dg/extra-semi.mm
Normal file
@ -0,0 +1,10 @@
|
||||
/* Allow extra semicolons in between method declarations,
|
||||
for old times' sake. */
|
||||
|
||||
/* { dg-do compile } */
|
||||
|
||||
@interface Foo
|
||||
-(Foo *) expiration;
|
||||
-(void) setExpiration:(Foo *) date;;
|
||||
-(int) getVersion;
|
||||
@end
|
24
gcc/testsuite/obj-c++.dg/fix-and-continue-2.mm
Normal file
24
gcc/testsuite/obj-c++.dg/fix-and-continue-2.mm
Normal file
@ -0,0 +1,24 @@
|
||||
/* Static variables, even if local, require indirect access through a stub
|
||||
if -mfix-and-continue is enabled. */
|
||||
|
||||
/* Author: Ziemowit Laski <zlaski@apple.com> */
|
||||
|
||||
/* { dg-do assemble { target *-*-darwin* } } */
|
||||
/* { dg-options "-mfix-and-continue" } */
|
||||
|
||||
#include <objc/Object.h>
|
||||
|
||||
@interface Foo: Object
|
||||
+ (Object *)indexableFileTypes;
|
||||
@end
|
||||
|
||||
@implementation Foo
|
||||
+ (Object *)indexableFileTypes
|
||||
{
|
||||
static Object *fileTypes = 0;
|
||||
if(!fileTypes) {
|
||||
fileTypes = [Object new];
|
||||
}
|
||||
return fileTypes;
|
||||
}
|
||||
@end
|
43
gcc/testsuite/obj-c++.dg/isa-field-1.mm
Normal file
43
gcc/testsuite/obj-c++.dg/isa-field-1.mm
Normal file
@ -0,0 +1,43 @@
|
||||
/* Ensure there are no bizarre difficulties with accessing the 'isa' field of objects. */
|
||||
/* { dg-do compile } */
|
||||
|
||||
#include <objc/Object.h>
|
||||
|
||||
@interface Object (Test)
|
||||
- (Class) test1: (id)object;
|
||||
@end
|
||||
|
||||
@interface Derived: Object
|
||||
- (Class) test2: (id)object;
|
||||
@end
|
||||
|
||||
@implementation Object (Test)
|
||||
|
||||
Class test1(id object) {
|
||||
Class cls = object->isa;
|
||||
return cls;
|
||||
}
|
||||
- (Class) test1: (id)object {
|
||||
Class cls = object->isa;
|
||||
return cls;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@implementation Derived
|
||||
|
||||
Class test2(id object) {
|
||||
Class cls = object->isa;
|
||||
return cls;
|
||||
}
|
||||
- (Class) test2: (id)object {
|
||||
Class cls = object->isa;
|
||||
return cls;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
Class test3(id object) {
|
||||
Class cls = object->isa;
|
||||
return cls;
|
||||
}
|
12
gcc/testsuite/obj-c++.dg/ivar-list-semi.mm
Normal file
12
gcc/testsuite/obj-c++.dg/ivar-list-semi.mm
Normal file
@ -0,0 +1,12 @@
|
||||
/* Allow for an optional semicolon following the ivar block. */
|
||||
/* Contributed by: Ziemowit Laski <zlaski@apple.com>. */
|
||||
|
||||
#include <objc/Object.h>
|
||||
|
||||
@interface Tink : Object {
|
||||
@private
|
||||
unsigned long mCode[4];
|
||||
};
|
||||
- (id)initWithProc:(void *)inProc;
|
||||
- (void *)getUniqueProc;
|
||||
@end
|
44
gcc/testsuite/obj-c++.dg/local-decl-1.mm
Normal file
44
gcc/testsuite/obj-c++.dg/local-decl-1.mm
Normal file
@ -0,0 +1,44 @@
|
||||
/* Test for ivar access inside of class methods. It should be allowed
|
||||
(with a warning), but only if no other declarations with the same
|
||||
name are seen. */
|
||||
/* Author: Ziemowit Laski <zlaski@apple.com>. */
|
||||
|
||||
/* { dg-do compile } */
|
||||
|
||||
#include <objc/Object.h>
|
||||
|
||||
@interface Sprite: Object {
|
||||
int sprite, spree;
|
||||
}
|
||||
+ (void)setFoo:(int)foo;
|
||||
+ (void)setSprite:(int)sprite;
|
||||
- (void)setFoo:(int)foo;
|
||||
- (void)setSprite:(int)sprite;
|
||||
@end
|
||||
|
||||
int spree = 23;
|
||||
|
||||
@implementation Sprite
|
||||
+ (void)setFoo:(int)foo {
|
||||
sprite = foo; /* { dg-warning "instance variable .sprite. accessed in class method" } */
|
||||
spree = foo;
|
||||
}
|
||||
+ (void)setSprite:(int)sprite {
|
||||
int spree;
|
||||
sprite = 15;
|
||||
spree = 17;
|
||||
((Sprite *)self)->sprite = 16; /* NB: This is how one _should_ access */
|
||||
((Sprite *)self)->spree = 18; /* ivars from within class methods! */
|
||||
}
|
||||
- (void)setFoo:(int)foo {
|
||||
sprite = foo;
|
||||
spree = foo;
|
||||
}
|
||||
- (void)setSprite:(int)sprite {
|
||||
int spree;
|
||||
sprite = 15; /* { dg-warning "local declaration of .sprite. hides instance variable" } */
|
||||
self->sprite = 16;
|
||||
spree = 17; /* { dg-warning "local declaration of .spree. hides instance variable" } */
|
||||
self->spree = 18;
|
||||
}
|
||||
@end
|
8
gcc/testsuite/obj-c++.dg/lookup-1.mm
Normal file
8
gcc/testsuite/obj-c++.dg/lookup-1.mm
Normal file
@ -0,0 +1,8 @@
|
||||
/* Simple test to check Objectivec-C++ qualified type lookup. */
|
||||
/* Devang Patel <dpatel@apple.com>. */
|
||||
|
||||
@interface A
|
||||
{
|
||||
A *ap;
|
||||
}
|
||||
@end
|
56
gcc/testsuite/obj-c++.dg/lookup-2.mm
Normal file
56
gcc/testsuite/obj-c++.dg/lookup-2.mm
Normal file
@ -0,0 +1,56 @@
|
||||
/* { dg-do run } */
|
||||
|
||||
#include <objc/Object.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
class MyWidget {
|
||||
public:
|
||||
int a;
|
||||
MyWidget(void) { a = 17; }
|
||||
};
|
||||
|
||||
MyWidget gWidget;
|
||||
|
||||
@protocol MyProto
|
||||
- (MyWidget *)widget;
|
||||
@end
|
||||
|
||||
@interface Foo: Object
|
||||
@end
|
||||
|
||||
@interface Bar: Foo <MyProto>
|
||||
@end
|
||||
|
||||
@interface Container: Object
|
||||
+ (MyWidget *)elementForView:(Foo *)view;
|
||||
@end
|
||||
|
||||
@implementation Foo
|
||||
@end
|
||||
|
||||
@implementation Bar
|
||||
- (MyWidget *)widget {
|
||||
return &gWidget;
|
||||
}
|
||||
@end
|
||||
|
||||
@implementation Container
|
||||
+ (MyWidget *)elementForView:(Foo *)view
|
||||
{
|
||||
MyWidget *widget = nil;
|
||||
if ([view conformsTo:@protocol(MyProto)]) {
|
||||
widget = [(Foo <MyProto> *)view widget];
|
||||
}
|
||||
return widget;
|
||||
}
|
||||
@end
|
||||
|
||||
int main(void) {
|
||||
id view = [Bar new];
|
||||
MyWidget *w = [Container elementForView: view];
|
||||
|
||||
if (!w || w->a != 17)
|
||||
abort ();
|
||||
|
||||
return 0;
|
||||
}
|
30
gcc/testsuite/obj-c++.dg/method-1.mm
Normal file
30
gcc/testsuite/obj-c++.dg/method-1.mm
Normal file
@ -0,0 +1,30 @@
|
||||
/* Test whether casting 'id' to a specific class removes method lookup
|
||||
ambiguity. */
|
||||
/* Author: Ziemowit Laski <zlaski@apple.com>. */
|
||||
|
||||
/* { dg-do compile } */
|
||||
|
||||
#include <objc/objc.h>
|
||||
|
||||
@class Int1, Int2;
|
||||
|
||||
@interface Int1
|
||||
+ (Int1 *)classMethod1;
|
||||
+ (id)classMethod2;
|
||||
- (Int1 *)instanceMethod:(Int2 *)arg; /* { dg-bogus "using" } */
|
||||
@end
|
||||
|
||||
@interface Int2: Int1
|
||||
+ (Int1 *)classMethod1;
|
||||
+ (id)classMethod2;
|
||||
- (id)int2Method;
|
||||
- (int)instanceMethod:(int)arg; /* { dg-bogus "also found" } */
|
||||
@end
|
||||
|
||||
int main(void) {
|
||||
id i = [(Int2 *)[Int1 classMethod1] int2Method]; /* { dg-bogus "may not respond to" } */
|
||||
int j = [(Int2 *)[Int2 classMethod2] instanceMethod: 45]; /* { dg-bogus "multiple methods" } */
|
||||
/* { dg-bogus "invalid conversion" "" { target *-*-* } 25 } */
|
||||
/* { dg-bogus "invalid conversion" "" { target *-*-* } 25 } */
|
||||
return j;
|
||||
}
|
56
gcc/testsuite/obj-c++.dg/method-2.mm
Normal file
56
gcc/testsuite/obj-c++.dg/method-2.mm
Normal file
@ -0,0 +1,56 @@
|
||||
/* Test if prior method lookup at method @implementation time is not
|
||||
overly aggressive, leading to methods being found in other classes. */
|
||||
/* Author: Ziemowit Laski <zlaski@apple.com>. */
|
||||
|
||||
/* { dg-do compile } */
|
||||
|
||||
#include <objc/Object.h>
|
||||
|
||||
@class NSString;
|
||||
|
||||
@protocol NSMenuItem
|
||||
+ (void)setUsesUserKeyEquivalents:(BOOL)flag;
|
||||
+ (BOOL)usesUserKeyEquivalents;
|
||||
@end
|
||||
|
||||
@interface NSMenuItem : Object <NSMenuItem> {
|
||||
@private
|
||||
id _menu;
|
||||
}
|
||||
@end
|
||||
|
||||
@interface NSResponder : Object <NSMenuItem>
|
||||
{
|
||||
id _nextResponder;
|
||||
}
|
||||
@end
|
||||
|
||||
@interface Object(NSMenuValidation)
|
||||
- (BOOL)validateMenuItem:(id <NSMenuItem>)menuItem;
|
||||
@end
|
||||
|
||||
@interface NSResponder (NSStandardKeyBindingMethods)
|
||||
- (void)insertText:(id)insertString;
|
||||
- (void)doCommandBySelector:(SEL)aSelector;
|
||||
@end
|
||||
|
||||
@interface NSView : NSResponder
|
||||
{
|
||||
id _superview;
|
||||
id _subviews;
|
||||
}
|
||||
@end
|
||||
|
||||
@interface SKTGraphicView : NSView {
|
||||
@private
|
||||
float _gridSpacing;
|
||||
}
|
||||
@end
|
||||
|
||||
@implementation SKTGraphicView
|
||||
- (BOOL)validateMenuItem:(NSMenuItem *)item {
|
||||
return (BOOL)1;
|
||||
}
|
||||
- (void)insertText:(NSString *)str {
|
||||
}
|
||||
@end
|
24
gcc/testsuite/obj-c++.dg/method-3.mm
Normal file
24
gcc/testsuite/obj-c++.dg/method-3.mm
Normal file
@ -0,0 +1,24 @@
|
||||
/* Do not warn about "slightly" mismatched method signatures if
|
||||
-Wstrict-selector-match is off. */
|
||||
|
||||
/* { dg-do compile } */
|
||||
/* { dg-options "-Wno-strict-selector-match" } */
|
||||
|
||||
#include <objc/objc.h>
|
||||
|
||||
@interface Base
|
||||
- (id) meth1: (Base *)arg1;
|
||||
- (id) window;
|
||||
@end
|
||||
|
||||
@interface Derived: Base
|
||||
- (id) meth1: (Derived *)arg1;
|
||||
- (Base *) window;
|
||||
@end
|
||||
|
||||
void foo(void) {
|
||||
id r;
|
||||
|
||||
[r meth1:r];
|
||||
[r window];
|
||||
}
|
24
gcc/testsuite/obj-c++.dg/method-4.mm
Normal file
24
gcc/testsuite/obj-c++.dg/method-4.mm
Normal file
@ -0,0 +1,24 @@
|
||||
/* Warn about "slightly" mismatched method signatures if
|
||||
-Wstrict-selector-match is on. */
|
||||
|
||||
/* { dg-do compile } */
|
||||
/* { dg-options "-Wstrict-selector-match" } */
|
||||
|
||||
#include <objc/objc.h>
|
||||
|
||||
@interface Base
|
||||
- (id) meth1: (Base *)arg1; /* { dg-warning "using .\\-\\(id\\)meth1:\\(Base \\*\\)arg1." } */
|
||||
- (id) window; /* { dg-warning "using .\\-\\(id\\)window" } */
|
||||
@end
|
||||
|
||||
@interface Derived: Base
|
||||
- (id) meth1: (Derived *)arg1; /* { dg-warning "also found .\\-\\(id\\)meth1:\\(Derived \\*\\)arg1." } */
|
||||
- (Base *) window; /* { dg-warning "also found .\\-\\(Base \\*\\)window." } */
|
||||
@end
|
||||
|
||||
void foo(void) {
|
||||
id r;
|
||||
|
||||
[r meth1:r]; /* { dg-warning "multiple methods named .\\-meth1:. found" } */
|
||||
[r window]; /* { dg-warning "multiple methods named .\\-window. found" } */
|
||||
}
|
30
gcc/testsuite/obj-c++.dg/method-5.mm
Normal file
30
gcc/testsuite/obj-c++.dg/method-5.mm
Normal file
@ -0,0 +1,30 @@
|
||||
/* Do not warn about "slightly" mismatched method signatures if
|
||||
-Wstrict-selector-match is off. */
|
||||
|
||||
/* { dg-do compile } */
|
||||
/* { dg-options "-Wno-strict-selector-match" } */
|
||||
|
||||
#include <objc/objc.h>
|
||||
|
||||
typedef enum { en1_1, en1_2 } En1;
|
||||
typedef enum { en2_1, en2_2 } En2;
|
||||
typedef struct { int a, b; } St1;
|
||||
typedef struct { unsigned a, b; } St2;
|
||||
|
||||
@interface Base
|
||||
- (id) meth1: (En1)arg1;
|
||||
- (St1) window;
|
||||
@end
|
||||
|
||||
@interface Derived: Base
|
||||
- (id) meth1: (En2)arg1;
|
||||
- (St2)window;
|
||||
@end
|
||||
|
||||
void foo(void) {
|
||||
id r;
|
||||
En1 en;
|
||||
|
||||
[r meth1:en];
|
||||
[r window];
|
||||
}
|
19
gcc/testsuite/obj-c++.dg/method-6.mm
Normal file
19
gcc/testsuite/obj-c++.dg/method-6.mm
Normal file
@ -0,0 +1,19 @@
|
||||
/* The following should NOT generate "may not respond to" warnings,
|
||||
since a forward-declared @class (instance) should be treated like a
|
||||
'Class') ('id'). */
|
||||
|
||||
/* { dg-do compile } */
|
||||
|
||||
#include <objc/Object.h>
|
||||
|
||||
@class NotKnown;
|
||||
|
||||
void foo(NotKnown *n) {
|
||||
[NotKnown new];
|
||||
[n nonexistent_method]; /* { dg-warning "no .\\-nonexistent_method. method found" } */
|
||||
}
|
||||
|
||||
/* { dg-warning "Messages without a matching method signature" "" { target *-*-* } 0 } */
|
||||
/* { dg-warning "will be assumed to return .id. and accept" "" { target *-*-* } 0 } */
|
||||
/* { dg-warning ".\.\.\.. as arguments" "" { target *-*-* } 0 } */
|
||||
|
21
gcc/testsuite/obj-c++.dg/method-7.mm
Normal file
21
gcc/testsuite/obj-c++.dg/method-7.mm
Normal file
@ -0,0 +1,21 @@
|
||||
/* Check if sending messages to "underspecified" objects is handled gracefully. */
|
||||
/* Author: Ziemowit Laski <zlaski@apple.com>. */
|
||||
|
||||
/* { dg-do compile } */
|
||||
|
||||
@class UnderSpecified;
|
||||
typedef struct NotAClass {
|
||||
int a, b;
|
||||
} NotAClass;
|
||||
|
||||
void foo(UnderSpecified *u, NotAClass *n) {
|
||||
[n nonexistent_method]; /* { dg-warning "invalid receiver type" } */
|
||||
/* { dg-warning "no .\\-nonexistent_method. method found" "" { target *-*-* } 12 } */
|
||||
[NotAClass nonexistent_method]; /* { dg-error ".NotAClass. is not an Objective\\-C class name or alias" } */
|
||||
[u nonexistent_method]; /* { dg-warning "no .\\-nonexistent_method. method found" } */
|
||||
[UnderSpecified nonexistent_method]; /* { dg-warning "no .\\+nonexistent_method. method found" } */
|
||||
}
|
||||
|
||||
/* { dg-warning "Messages without a matching method signature" "" { target *-*-* } 0 } */
|
||||
/* { dg-warning "will be assumed to return .id. and accept" "" { target *-*-* } 0 } */
|
||||
/* { dg-warning ".\.\.\.. as arguments" "" { target *-*-* } 0 } */
|
24
gcc/testsuite/obj-c++.dg/no-extra-load.mm
Normal file
24
gcc/testsuite/obj-c++.dg/no-extra-load.mm
Normal file
@ -0,0 +1,24 @@
|
||||
// Radar 3926484
|
||||
|
||||
// { dg-do compile }
|
||||
|
||||
#include <objc/Object.h>
|
||||
#include <iostream>
|
||||
|
||||
@interface Greeter : Object
|
||||
- (void) greet: (const char *)msg;
|
||||
@end
|
||||
|
||||
@implementation Greeter
|
||||
- (void) greet: (const char *)msg { std::cout << msg; }
|
||||
@end
|
||||
|
||||
int
|
||||
main ()
|
||||
{
|
||||
std::cout << "Hello from C++\n";
|
||||
Greeter *obj = [Greeter new];
|
||||
[obj greet: "Hello from Objective-C\n"];
|
||||
}
|
||||
|
||||
/* { dg-final { scan-assembler-not "L_objc_msgSend\\\$non_lazy_ptr" } } */
|
11
gcc/testsuite/obj-c++.dg/overload-1.mm
Normal file
11
gcc/testsuite/obj-c++.dg/overload-1.mm
Normal file
@ -0,0 +1,11 @@
|
||||
// Make sure we can overload on ObjC classes
|
||||
// Radar 3960754
|
||||
|
||||
// { dg-do compile }
|
||||
|
||||
@class A, B;
|
||||
|
||||
struct X {
|
||||
void call(A*);
|
||||
void call(B*);
|
||||
};
|
11
gcc/testsuite/obj-c++.dg/pragma-1.mm
Normal file
11
gcc/testsuite/obj-c++.dg/pragma-1.mm
Normal file
@ -0,0 +1,11 @@
|
||||
/* It is OK to use #pragma inside @interface body. This test checks that. */
|
||||
/* Devang Patel <dpatel@apple.com>. */
|
||||
|
||||
@interface A
|
||||
{
|
||||
int p;
|
||||
}
|
||||
+(int) foo;
|
||||
#pragma Mark foobar
|
||||
-(int) bar;
|
||||
@end
|
23
gcc/testsuite/obj-c++.dg/pragma-2.mm
Normal file
23
gcc/testsuite/obj-c++.dg/pragma-2.mm
Normal file
@ -0,0 +1,23 @@
|
||||
/* It is OK to use #pragma inside @implementation body. This test checks that. */
|
||||
/* Ziemowit Laski <zlaski@apple.com>. */
|
||||
|
||||
@interface A
|
||||
{
|
||||
int p;
|
||||
}
|
||||
+(int) foo;
|
||||
-(int) bar;
|
||||
@end
|
||||
|
||||
@implementation A
|
||||
#pragma mark -
|
||||
#pragma mark init / dealloc
|
||||
+ (int)foo {
|
||||
return 1;
|
||||
}
|
||||
#pragma mark -
|
||||
#pragma mark Private Functions
|
||||
- (int)bar {
|
||||
return 2;
|
||||
}
|
||||
@end
|
60
gcc/testsuite/obj-c++.dg/private-1.mm
Normal file
60
gcc/testsuite/obj-c++.dg/private-1.mm
Normal file
@ -0,0 +1,60 @@
|
||||
/* Test errors for accessing @private and @protected variables. */
|
||||
/* Based on work by: Nicola Pero <nicola@brainstorm.co.uk>. */
|
||||
|
||||
/* { dg-do compile } */
|
||||
|
||||
#include <objc/objc.h>
|
||||
|
||||
@interface MySuperClass
|
||||
{
|
||||
@private
|
||||
int _private;
|
||||
|
||||
@protected
|
||||
int _protected;
|
||||
|
||||
@public
|
||||
int _public;
|
||||
}
|
||||
- (void) test;
|
||||
@end
|
||||
|
||||
@implementation MySuperClass
|
||||
- (void) test
|
||||
{
|
||||
_private = 12; /* Ok */
|
||||
_protected = 12; /* Ok */
|
||||
_public = 12; /* Ok */
|
||||
}
|
||||
@end
|
||||
|
||||
|
||||
@interface MyClass : MySuperClass
|
||||
@end
|
||||
|
||||
@implementation MyClass
|
||||
- (void) test
|
||||
{
|
||||
/* Private variables simply don't exist in the subclass. */
|
||||
_private = 12; /* { dg-error "._private. was not declared in this scope" } */
|
||||
|
||||
_protected = 12; /* Ok */
|
||||
_public = 12; /* Ok */
|
||||
}
|
||||
@end
|
||||
|
||||
int main (void)
|
||||
{
|
||||
MyClass *m = nil;
|
||||
|
||||
if (m != nil)
|
||||
{
|
||||
int access;
|
||||
|
||||
access = m->_private; /* { dg-error "is @private" } */
|
||||
access = m->_protected; /* { dg-error "is @protected" } */
|
||||
access = m->_public; /* Ok */
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
56
gcc/testsuite/obj-c++.dg/private-2.mm
Normal file
56
gcc/testsuite/obj-c++.dg/private-2.mm
Normal file
@ -0,0 +1,56 @@
|
||||
/* Test warnings for shadowing instance variables. */
|
||||
/* Based on work by: Nicola Pero <nicola@brainstorm.co.uk>. */
|
||||
|
||||
/* { dg-do compile } */
|
||||
|
||||
#include <objc/objc.h>
|
||||
|
||||
@interface MySuperClass
|
||||
{
|
||||
@private
|
||||
int _private;
|
||||
|
||||
@protected
|
||||
int _protected;
|
||||
|
||||
@public
|
||||
int _public;
|
||||
}
|
||||
- (void) test;
|
||||
@end
|
||||
|
||||
@implementation MySuperClass
|
||||
- (void) test
|
||||
{
|
||||
/* FIXME: I wonder if the warnings shouldn't be better generated
|
||||
when the variable is declared, rather than used! */
|
||||
int _private = 12;
|
||||
int _protected = 12;
|
||||
int _public = 12;
|
||||
int a;
|
||||
|
||||
a = _private; /* { dg-warning "hides instance variable" } */
|
||||
a = _protected; /* { dg-warning "hides instance variable" } */
|
||||
a = _public; /* { dg-warning "hides instance variable" } */
|
||||
}
|
||||
@end
|
||||
|
||||
|
||||
@interface MyClass : MySuperClass
|
||||
@end
|
||||
|
||||
@implementation MyClass
|
||||
- (void) test
|
||||
{
|
||||
int _private = 12;
|
||||
int _protected = 12;
|
||||
int _public = 12;
|
||||
int a;
|
||||
|
||||
/* The private variable can be shadowed without warnings, because
|
||||
* it's invisible, and not accessible, to the subclass! */
|
||||
a = _private; /* Ok */
|
||||
a = _protected; /* { dg-warning "hides instance variable" } */
|
||||
a = _public; /* { dg-warning "hides instance variable" } */
|
||||
}
|
||||
@end
|
52
gcc/testsuite/obj-c++.dg/proto-qual-1.mm
Normal file
52
gcc/testsuite/obj-c++.dg/proto-qual-1.mm
Normal file
@ -0,0 +1,52 @@
|
||||
/* Check that protocol qualifiers are compiled and encoded properly. */
|
||||
/* Author: Ziemowit Laski <zlaski@apple.com> */
|
||||
|
||||
/* { dg-do run } */
|
||||
|
||||
#include <objc/Protocol.h>
|
||||
#ifndef __NEXT_RUNTIME__
|
||||
#include <objc/objc-api.h>
|
||||
#endif
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
/* The encoded parameter sizes will be rounded up to match pointer alignment. */
|
||||
#define ROUND(s,a) (a * ((s + a - 1) / a))
|
||||
#define aligned_sizeof(T) ROUND(sizeof(T),__alignof(void *))
|
||||
|
||||
#define CHECK_IF(expr) if(!(expr)) abort()
|
||||
|
||||
@protocol Retain
|
||||
+ (oneway void)retainArgument:(out bycopy id)arg1 with:(in signed char **)arg2;
|
||||
- (bycopy) address:(byref inout id)location with:(out short unsigned **)arg2;
|
||||
@end
|
||||
|
||||
@interface Foo <Retain>
|
||||
+ (oneway void)retainArgument:(out bycopy id)arg with:(in signed char **)arg2;
|
||||
@end
|
||||
|
||||
@implementation Foo
|
||||
+ (oneway void)retainArgument:(out bycopy id)arg1 with:(in signed char **)arg2 { }
|
||||
- (bycopy) address:(byref inout id)location with:(out short unsigned **)arg2 { return nil; }
|
||||
@end
|
||||
|
||||
Protocol *proto = @protocol(Retain);
|
||||
struct objc_method_description *meth;
|
||||
unsigned totsize, offs0, offs1, offs2, offs3, offs4, offs5, offs6, offs7;
|
||||
|
||||
static void scan_initial(const char *pattern) {
|
||||
totsize = offs0 = offs1 = offs2 = offs3 = offs4 = offs5 = offs6 = offs7 = (unsigned)-1;
|
||||
sscanf(meth->types, pattern, &totsize, &offs0, &offs1, &offs2, &offs3,
|
||||
&offs4, &offs5, &offs6, &offs7);
|
||||
CHECK_IF(!offs0 && offs1 == aligned_sizeof(id) && offs2 == offs1 + aligned_sizeof(SEL) && totsize >= offs2);
|
||||
}
|
||||
|
||||
int main(void) {
|
||||
meth = [proto descriptionForInstanceMethod: @selector(address:with:)];
|
||||
scan_initial("O@%u@%u:%uNR@%uo^^S%u");
|
||||
CHECK_IF(offs3 == offs2 + aligned_sizeof(id) && totsize == offs3 + aligned_sizeof(unsigned));
|
||||
meth = [proto descriptionForClassMethod: @selector(retainArgument:with:)];
|
||||
scan_initial("Vv%u@%u:%uOo@%un^*%u");
|
||||
CHECK_IF(offs3 == offs2 + aligned_sizeof(id) && totsize == offs3 + aligned_sizeof(char **));
|
||||
return 0;
|
||||
}
|
68
gcc/testsuite/obj-c++.dg/qual-types-1.mm
Normal file
68
gcc/testsuite/obj-c++.dg/qual-types-1.mm
Normal file
@ -0,0 +1,68 @@
|
||||
/* Test if ObjC++ can distinguish protocol qualifiers from
|
||||
template arguments. */
|
||||
/* Author: Ziemowit Laski <zlaski@apple.com>. */
|
||||
|
||||
/* { dg-do run } */
|
||||
|
||||
#include <objc/Object.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#define CHECK_IF(expr) if(!(expr)) abort()
|
||||
|
||||
@protocol Zone
|
||||
+ allocFromZone:(void *)zone;
|
||||
- copyFromZone:(void *)zone;
|
||||
@end
|
||||
|
||||
@protocol Init <Zone>
|
||||
+ initialize;
|
||||
- init;
|
||||
@end
|
||||
|
||||
@interface Foo: Object
|
||||
{ @public int val; }
|
||||
- init;
|
||||
@end
|
||||
|
||||
template <class T, class U> struct X {
|
||||
T x; U y;
|
||||
};
|
||||
|
||||
X<int, float> xx;
|
||||
|
||||
template <typename T> struct Holder
|
||||
{
|
||||
T *obj;
|
||||
static int counter;
|
||||
Holder(void) { obj = [[T alloc] init]; }
|
||||
~Holder(void) { [obj free]; --counter; }
|
||||
id <Init, Zone> getObjId(void) { return obj; }
|
||||
Object <Zone, Init> *getObj(void) { return obj; }
|
||||
};
|
||||
|
||||
typedef Holder <Foo <Init, Zone> > FooHolder;
|
||||
|
||||
@implementation Foo
|
||||
-(id) init {
|
||||
[super init];
|
||||
val = ++FooHolder::counter;
|
||||
return self;
|
||||
}
|
||||
@end
|
||||
|
||||
template <typename T>
|
||||
int Holder<T>::counter = 0;
|
||||
|
||||
int main (void) {
|
||||
CHECK_IF(FooHolder::counter == 0);
|
||||
{
|
||||
FooHolder holder;
|
||||
CHECK_IF(holder.obj->val == 1);
|
||||
CHECK_IF(FooHolder::counter == 1);
|
||||
FooHolder holder2;
|
||||
CHECK_IF(holder2.obj->val == 2);
|
||||
CHECK_IF(FooHolder::counter == 2);
|
||||
}
|
||||
CHECK_IF(FooHolder::counter == 0);
|
||||
return 0;
|
||||
}
|
@ -1,26 +1,30 @@
|
||||
/* Test warning for non existing selectors. */
|
||||
/* Contributed by Devang Patel <dpatel@apple.com>. */
|
||||
/* { dg-options "-Wselector -fnext-runtime" } */
|
||||
/* Test whether including C++ keywords such as 'and', 'or',
|
||||
'not', etc., is allowed inside ObjC selectors (as it must be). */
|
||||
/* Author: Ziemowit Laski <zlaski@apple.com>. */
|
||||
|
||||
/* { dg-do compile } */
|
||||
|
||||
typedef struct objc_object { struct objc_class *class_pointer; } *id;
|
||||
typedef struct objc_selector *SEL;
|
||||
|
||||
@interface Foo
|
||||
- (void) foo;
|
||||
- (void) bar;
|
||||
@interface Int1
|
||||
+ (int)and_eq:(int)arg1 and:(int)arg2;
|
||||
- (int)or_eq:(int)arg1 or:(int)arg3;
|
||||
- (int)not:(int)arg1 xor:(int)arg2;
|
||||
- (void)bitand:(char)c1 bitor:(char)c2;
|
||||
- (void)compl:(float)f1 xor_eq:(double)d1;
|
||||
- (void)not_eq;
|
||||
@end
|
||||
|
||||
@implementation Foo
|
||||
- (void) bar
|
||||
{
|
||||
}
|
||||
|
||||
- (void) foo
|
||||
{
|
||||
SEL a,b,c;
|
||||
a = @selector(b1ar); /* { dg-warning "creating selector for nonexistent method .b1ar." } */
|
||||
b = @selector(bar);
|
||||
}
|
||||
@implementation Int1
|
||||
+ (int)and_eq:(int)arg1 and:(int)arg2 { return arg1 + arg2; }
|
||||
- (int)or_eq:(int)arg1 or:(int)arg3 { return arg1 + arg3; }
|
||||
- (int)not:(int)arg1 xor:(int)arg2 { return arg1 + arg2; }
|
||||
- (void)bitand:(char)c1 bitor:(char)c2 { }
|
||||
- (void)compl:(float)f1 xor_eq:(double)d1 { }
|
||||
- (void)not_eq { }
|
||||
@end
|
||||
|
||||
/* { dg-final { scan-assembler "\\+\\\[Int1 and_eq:and:\\]|c_Int1__and_eq_and" } } */
|
||||
/* { dg-final { scan-assembler "\\-\\\[Int1 or_eq:or:\\]|i_Int1__or_eq_or" } } */
|
||||
/* { dg-final { scan-assembler "\\-\\\[Int1 not:xor:\\]|i_Int1__not_xor" } } */
|
||||
/* { dg-final { scan-assembler "\\-\\\[Int1 bitand:bitor:\\]|i_Int1__bitand_bitor" } } */
|
||||
/* { dg-final { scan-assembler "\\-\\\[Int1 compl:xor_eq:\\]|i_Int1__compl_xor_eq" } } */
|
||||
/* { dg-final { scan-assembler "\\-\\\[Int1 not_eq\\]|i_Int1__not_eq" } } */
|
||||
|
37
gcc/testsuite/obj-c++.dg/stubify-1.mm
Normal file
37
gcc/testsuite/obj-c++.dg/stubify-1.mm
Normal file
@ -0,0 +1,37 @@
|
||||
/* All calls must be properly stubified. Complain about any "call
|
||||
_objc_msgSend<end-of-line>" without the $stub suffix. */
|
||||
|
||||
/* { dg-do compile { target *-*-darwin* } } */
|
||||
/* { dg-options "-Os -mdynamic-no-pic -fno-exceptions" } */
|
||||
|
||||
typedef struct objc_object { } *id ;
|
||||
int x = 41 ;
|
||||
|
||||
extern "C" {
|
||||
extern id objc_msgSend(id self, char * op, ...);
|
||||
extern int bogonic (int, int, int);
|
||||
}
|
||||
|
||||
@interface Document {}
|
||||
- (Document *) window;
|
||||
- (Document *) class;
|
||||
- (Document *) close;
|
||||
@end
|
||||
@implementation Document
|
||||
- (Document *) class { }
|
||||
- (Document *) close { }
|
||||
- (Document *) window { }
|
||||
- (void)willEndCloseSheet:(void *)sheet returnCode:(int)returnCode contextInfo:(void *)contextInfo {
|
||||
[[self window] close];
|
||||
((void (*)(id, char *, int))objc_msgSend)([self class], (char *)contextInfo, 1);
|
||||
((void (*)(id, char *, int))bogonic)([self class], (char *)contextInfo, 1);
|
||||
bogonic (3, 4, 5);
|
||||
x++;
|
||||
}
|
||||
@end
|
||||
|
||||
/* { dg-final { scan-assembler-not "\(bl|call\)\[ \t\]+_objc_msgSend\n" } } */
|
||||
/* { dg-final { scan-assembler "\(bl|call\)\[ \t\]+L_objc_msgSend\\\$stub\n" } } */
|
||||
/* { dg-final { scan-assembler-not "\(bl|call\)\[ \t\]+_bogonic\n" } } */
|
||||
/* { dg-final { scan-assembler "\(bl|call\)\[ \t\]+L_bogonic\\\$stub\n" } } */
|
||||
/* { dg-final { scan-assembler-not "\\\$non_lazy_ptr" } } */
|
31
gcc/testsuite/obj-c++.dg/stubify-2.mm
Normal file
31
gcc/testsuite/obj-c++.dg/stubify-2.mm
Normal file
@ -0,0 +1,31 @@
|
||||
/* All calls must be properly stubified. */
|
||||
/* Testcase extracted from TextEdit:Document.m. */
|
||||
|
||||
/* { dg-do compile { target *-*-darwin* } } */
|
||||
/* { dg-options "-mdynamic-no-pic -fdump-rtl-jump" } */
|
||||
|
||||
typedef struct objc_object { } *id ;
|
||||
int x = 41 ;
|
||||
extern id objc_msgSend(id self, char * op, ...);
|
||||
extern int bogonic (int, int, int) ;
|
||||
@interface Document {}
|
||||
- (Document *) window;
|
||||
- (Document *) class;
|
||||
- (Document *) close;
|
||||
@end
|
||||
@implementation Document
|
||||
- (Document *) class { }
|
||||
- (Document *) close { }
|
||||
- (Document *) window { }
|
||||
- (void)willEndCloseSheet:(void *)sheet returnCode:(int)returnCode contextInfo:(void *)contextInfo {
|
||||
[[self window] close];
|
||||
((void (*)(id, char *, int))objc_msgSend)([self class], (char *)contextInfo, 1);
|
||||
((void (*)(id, char *, int))bogonic)([self class], (char *)contextInfo, 1);
|
||||
bogonic (3, 4, 5);
|
||||
x++;
|
||||
}
|
||||
@end
|
||||
|
||||
/* Any symbol_ref of an un-stubified objc_msgSend is an error; look
|
||||
for "objc_msgSend" in quotes, without the $stub suffix. */
|
||||
/* { dg-final { scan-file-not stubify-2.mm.03.jump "symbol_ref.*\"objc_msgSend\"" } } */
|
30
gcc/testsuite/obj-c++.dg/super-class-1.mm
Normal file
30
gcc/testsuite/obj-c++.dg/super-class-1.mm
Normal file
@ -0,0 +1,30 @@
|
||||
/* Test calling super from within a category method. */
|
||||
|
||||
/* { dg-do compile } */
|
||||
|
||||
#include <objc/objc.h>
|
||||
|
||||
@interface NSObject
|
||||
@end
|
||||
@interface NSMenuItem: NSObject
|
||||
@end
|
||||
|
||||
@interface NSObject (Test)
|
||||
+ (int) test_func;
|
||||
@end
|
||||
|
||||
@implementation NSObject (Test)
|
||||
+ (int) test_func
|
||||
{}
|
||||
@end
|
||||
|
||||
@interface NSMenuItem (Test)
|
||||
+ (int) test_func;
|
||||
@end
|
||||
|
||||
@implementation NSMenuItem (Test)
|
||||
+ (int) test_func
|
||||
{
|
||||
return [super test_func]; /* { dg-bogus "invalid use of undefined type" } */
|
||||
} /* { dg-bogus "forward declaration of" "" { target *-*-* } 28 } */
|
||||
@end
|
35
gcc/testsuite/obj-c++.dg/super-class-2.mm
Normal file
35
gcc/testsuite/obj-c++.dg/super-class-2.mm
Normal file
@ -0,0 +1,35 @@
|
||||
/* Bail out gracefully if attempting to derive from a class that has only been
|
||||
forward-declared (via @class). Conversely, @compatibility_alias declarations
|
||||
should be traversed to find the @interface. */
|
||||
|
||||
/* { dg-do compile } */
|
||||
|
||||
#include <objc/Object.h>
|
||||
|
||||
@class MyWpModule;
|
||||
|
||||
@compatibility_alias MyObject Object;
|
||||
@compatibility_alias FictitiousModule MyWpModule;
|
||||
|
||||
@protocol MySelTarget
|
||||
- (id) meth1;
|
||||
@end
|
||||
|
||||
@protocol Img
|
||||
- (id) meth2;
|
||||
@end
|
||||
|
||||
@interface FunnyModule: FictitiousModule <Img> /* { dg-error ".MyWpModule., superclass of .FunnyModule." } */
|
||||
- (id) meth2;
|
||||
@end
|
||||
|
||||
@interface MyProjWpModule : MyWpModule <MySelTarget, Img> /* { dg-error ".MyWpModule., superclass of .MyProjWpModule." } */ {
|
||||
id i1, i2;
|
||||
}
|
||||
- (id) meth1;
|
||||
- (id) meth2;
|
||||
@end
|
||||
|
||||
@interface AnotherModule: MyObject <MySelTarget>
|
||||
- (id) meth1;
|
||||
@end
|
46
gcc/testsuite/obj-c++.dg/super-dealloc-1.mm
Normal file
46
gcc/testsuite/obj-c++.dg/super-dealloc-1.mm
Normal file
@ -0,0 +1,46 @@
|
||||
/* Check for warnings about missing [super dealloc] calls. */
|
||||
/* Author: Ziemowit Laski <zlaski@apple.com> */
|
||||
|
||||
/* { dg-do compile } */
|
||||
|
||||
@interface Foo {
|
||||
void *isa;
|
||||
}
|
||||
- (void) dealloc;
|
||||
- (void) some_other;
|
||||
@end
|
||||
|
||||
@interface Bar: Foo {
|
||||
void *casa;
|
||||
}
|
||||
- (void) dealloc;
|
||||
@end
|
||||
|
||||
@interface Baz: Bar {
|
||||
void *usa;
|
||||
}
|
||||
- (void) dealloc;
|
||||
@end
|
||||
|
||||
@implementation Foo
|
||||
- (void) dealloc {
|
||||
isa = 0; /* Should not warn here. */
|
||||
}
|
||||
- (void) some_other {
|
||||
isa = (void *)-1;
|
||||
}
|
||||
@end
|
||||
|
||||
@implementation Bar
|
||||
- (void) dealloc {
|
||||
casa = 0;
|
||||
[super some_other];
|
||||
} /* { dg-warning "method possibly missing a .super dealloc. call" } */
|
||||
@end
|
||||
|
||||
@implementation Baz
|
||||
- (void) dealloc {
|
||||
usa = 0;
|
||||
[super dealloc]; /* Should not warn here. */
|
||||
}
|
||||
@end
|
46
gcc/testsuite/obj-c++.dg/super-dealloc-2.mm
Normal file
46
gcc/testsuite/obj-c++.dg/super-dealloc-2.mm
Normal file
@ -0,0 +1,46 @@
|
||||
/* Check for warnings about missing [super dealloc] calls. */
|
||||
/* Author: Ziemowit Laski <zlaski@apple.com> */
|
||||
|
||||
/* { dg-do compile } */
|
||||
|
||||
@interface Foo {
|
||||
void *isa;
|
||||
}
|
||||
- (void) dealloc;
|
||||
- (void) some_other;
|
||||
@end
|
||||
|
||||
@interface Bar: Foo {
|
||||
void *casa;
|
||||
}
|
||||
- (void) dealloc0;
|
||||
@end
|
||||
|
||||
@interface Baz: Bar {
|
||||
void *usa;
|
||||
}
|
||||
- (void) dealloc;
|
||||
@end
|
||||
|
||||
@implementation Foo
|
||||
- (void) dealloc {
|
||||
isa = 0; /* Should not warn here. */
|
||||
}
|
||||
- (void) some_other {
|
||||
isa = (void *)-1;
|
||||
}
|
||||
@end
|
||||
|
||||
@implementation Bar
|
||||
- (void) dealloc0 {
|
||||
casa = 0;
|
||||
[super some_other]; /* Should not warn here. */
|
||||
}
|
||||
@end
|
||||
|
||||
@implementation Baz
|
||||
- (void) dealloc {
|
||||
usa = 0;
|
||||
[super dealloc0];
|
||||
} /* { dg-warning "method possibly missing a .super dealloc. call" } */
|
||||
@end
|
49
gcc/testsuite/obj-c++.dg/template-1.mm
Normal file
49
gcc/testsuite/obj-c++.dg/template-1.mm
Normal file
@ -0,0 +1,49 @@
|
||||
/* Test for using ObjC classes as C++ template parameters. */
|
||||
/* Author: Ziemowit Laski <zlaski@apple.com>. */
|
||||
|
||||
/* { dg-do run } */
|
||||
|
||||
#include <objc/Object.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#define CHECK_IF(expr) if(!(expr)) abort()
|
||||
|
||||
@interface Base: Object
|
||||
- (int) meth;
|
||||
@end
|
||||
|
||||
@interface Derived: Base
|
||||
- (int) meth;
|
||||
@end
|
||||
|
||||
static int count = 0;
|
||||
|
||||
template <class T> struct Templ
|
||||
{
|
||||
T *m;
|
||||
int i;
|
||||
Templ(): i(55), m([[T alloc] init]) { count++; }
|
||||
~Templ() { [m free]; count--; }
|
||||
};
|
||||
|
||||
@implementation Base
|
||||
- (int) meth { return 333; }
|
||||
@end
|
||||
|
||||
@implementation Derived
|
||||
- (int) meth { return 666; }
|
||||
@end
|
||||
|
||||
int main (void) {
|
||||
CHECK_IF(count == 0);
|
||||
{
|
||||
Templ<Derived> derived;
|
||||
CHECK_IF(derived.i == 55 && count == 1);
|
||||
Templ<Base> base;
|
||||
CHECK_IF(base.i == 55 && count == 2);
|
||||
CHECK_IF([base.m meth] == 333);
|
||||
CHECK_IF([derived.m meth] == 666);
|
||||
}
|
||||
CHECK_IF(count == 0);
|
||||
return 0;
|
||||
}
|
29
gcc/testsuite/obj-c++.dg/template-2.mm
Normal file
29
gcc/testsuite/obj-c++.dg/template-2.mm
Normal file
@ -0,0 +1,29 @@
|
||||
/* Test if ObjC classes (and pointers thereto) can participate
|
||||
in C++ overloading. Correct handling of cv-qualifiers is
|
||||
key here. */
|
||||
/* Author: Ziemowit Laski <zlaski@apple.com>. */
|
||||
|
||||
/* { dg-do compile } */
|
||||
|
||||
@interface foo {
|
||||
int a, b;
|
||||
}
|
||||
@end
|
||||
|
||||
struct bar {
|
||||
int c, d;
|
||||
};
|
||||
|
||||
template <class _Tp>
|
||||
struct allocator {
|
||||
typedef _Tp* pointer;
|
||||
typedef const _Tp* const_pointer;
|
||||
typedef _Tp& reference;
|
||||
typedef const _Tp& const_reference;
|
||||
|
||||
pointer address(reference __x) const { return &__x; }
|
||||
const_pointer address(const_reference __x) const { return &__x; }
|
||||
};
|
||||
|
||||
allocator<bar *> b;
|
||||
allocator<foo *> d;
|
80
gcc/testsuite/obj-c++.dg/template-3.mm
Normal file
80
gcc/testsuite/obj-c++.dg/template-3.mm
Normal file
@ -0,0 +1,80 @@
|
||||
/* Test for passing arguments to ObjC methods in the context of template
|
||||
expansion. */
|
||||
/* Contributed by Ziemowit Laski <zlaski@apple.com>. */
|
||||
|
||||
/* { dg-do run } */
|
||||
|
||||
#include <objc/Object.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#define CHECK_IF(expr) if(!(expr)) abort()
|
||||
|
||||
@interface ObjCClass : Object
|
||||
{
|
||||
@public
|
||||
int info;
|
||||
}
|
||||
-(id) init;
|
||||
-(id) initWithInformation: (int) whatInfo;
|
||||
-(id) initWithInformation: (int) whatInfo andInfo: (int) info2;
|
||||
@end
|
||||
|
||||
void foo(int info) {
|
||||
ObjCClass *mObj1 = [[ObjCClass alloc] init];
|
||||
ObjCClass *mObj2 = [[ObjCClass alloc] initWithInformation: info];
|
||||
ObjCClass *mObj3 = [[ObjCClass alloc] initWithInformation: info andInfo: 39];
|
||||
|
||||
CHECK_IF(mObj1->info == 666);
|
||||
CHECK_IF(mObj2->info == info);
|
||||
CHECK_IF(mObj3->info == info + 39);
|
||||
}
|
||||
|
||||
template <class WrappedObjCClass>
|
||||
class ObjCObjectWrapper
|
||||
{
|
||||
public:
|
||||
ObjCObjectWrapper(int info);
|
||||
WrappedObjCClass *mObj1, *mObj2, *mObj3;
|
||||
};
|
||||
|
||||
template <class WrappedObjCClass>
|
||||
ObjCObjectWrapper<WrappedObjCClass>::ObjCObjectWrapper(int info)
|
||||
{
|
||||
mObj1 = [[WrappedObjCClass alloc] init];
|
||||
mObj2 = [[WrappedObjCClass alloc] initWithInformation: info];
|
||||
mObj3 = [[WrappedObjCClass alloc] initWithInformation: info andInfo: 67];
|
||||
}
|
||||
|
||||
@implementation ObjCClass
|
||||
-(id) init {
|
||||
return [self initWithInformation:666];
|
||||
}
|
||||
-(id) initWithInformation: (int) whatInfo {
|
||||
[super init];
|
||||
info = whatInfo;
|
||||
return self;
|
||||
}
|
||||
-(id) initWithInformation: (int) whatInfo andInfo: (int) info2 {
|
||||
[super init];
|
||||
info = whatInfo + info2;
|
||||
return self;
|
||||
}
|
||||
@end
|
||||
|
||||
ObjCObjectWrapper<ObjCClass> staticInstance(42);
|
||||
|
||||
int main(void) {
|
||||
ObjCObjectWrapper<ObjCClass> stackInstance(47);
|
||||
|
||||
foo(89);
|
||||
|
||||
CHECK_IF(staticInstance.mObj1->info == 666);
|
||||
CHECK_IF(staticInstance.mObj2->info == 42);
|
||||
CHECK_IF(staticInstance.mObj3->info == 42 + 67);
|
||||
|
||||
CHECK_IF(stackInstance.mObj1->info == 666);
|
||||
CHECK_IF(stackInstance.mObj2->info == 47);
|
||||
CHECK_IF(stackInstance.mObj3->info == 47 + 67);
|
||||
|
||||
return 0;
|
||||
}
|
81
gcc/testsuite/obj-c++.dg/template-4.mm
Normal file
81
gcc/testsuite/obj-c++.dg/template-4.mm
Normal file
@ -0,0 +1,81 @@
|
||||
/* Author: Ziemowit Laski <zlaski@apple.com>. */
|
||||
|
||||
/* { dg-do run } */
|
||||
|
||||
#include <objc/Object.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#ifdef __NEXT_RUNTIME__
|
||||
/* The following ain't pretty, but does allow us to have just one copy
|
||||
of next_mapping.h. */
|
||||
#include "../objc/execute/next_mapping.h"
|
||||
#else
|
||||
#include <objc/NXConstStr.h>
|
||||
#endif
|
||||
|
||||
#define CHECK_IF(expr) if(!(expr)) abort()
|
||||
|
||||
template <class ARR, class TYPE> class TestT
|
||||
{
|
||||
public:
|
||||
TYPE k;
|
||||
int abc(ARR *array) {
|
||||
return [array count] * k;
|
||||
}
|
||||
TestT(TYPE _k): k(_k) { }
|
||||
};
|
||||
|
||||
template <class TYPE>
|
||||
const char *getDesc(void) {
|
||||
return [TYPE name];
|
||||
}
|
||||
|
||||
@class Array;
|
||||
|
||||
template <class TYPE>
|
||||
int abc(TYPE *xyz, Array *array) {
|
||||
return [xyz count] + [array count];
|
||||
}
|
||||
|
||||
@interface Array: Object {
|
||||
id *arr;
|
||||
int count;
|
||||
}
|
||||
+ (id)arrayWithObjects:(id)first, ... ;
|
||||
- (int)count;
|
||||
@end
|
||||
|
||||
@implementation Array
|
||||
+ (id)arrayWithObjects:(id)first, ... {
|
||||
Array *a = [Array new];
|
||||
a->count = 0;
|
||||
a->arr = (id *) calloc(8, sizeof(id));
|
||||
|
||||
va_list args;
|
||||
va_start (args, first);
|
||||
|
||||
a->arr[a->count++] = first;
|
||||
|
||||
for (id el; el = va_arg(args, id); a->count++)
|
||||
a->arr[a->count] = el;
|
||||
|
||||
return a;
|
||||
}
|
||||
- (int)count {
|
||||
return count;
|
||||
}
|
||||
@end
|
||||
|
||||
int main(void) {
|
||||
CHECK_IF(!strcmp ([@"Object" cString], getDesc<Object>()));
|
||||
CHECK_IF(!strcmp ([@"Array" cString], getDesc<Array>()));
|
||||
|
||||
Array* a1 = [Array arrayWithObjects:@"One", @"Two", @"Three", nil];
|
||||
Array* a2 = [Array arrayWithObjects:@"Four", @"Five", nil];
|
||||
|
||||
TestT<Array, int> t(7);
|
||||
CHECK_IF(t.abc(a1) + t.abc(a2) == 35);
|
||||
CHECK_IF(abc(a1, a2) * t.k == 35);
|
||||
return 0;
|
||||
}
|
17
gcc/testsuite/obj-c++.dg/template-5.mm
Normal file
17
gcc/testsuite/obj-c++.dg/template-5.mm
Normal file
@ -0,0 +1,17 @@
|
||||
// Test that extern template does not get emitted.
|
||||
// Author: Matt Austern <austern@apple.com>
|
||||
|
||||
// { dg-do compile }
|
||||
// { dg-options "" }
|
||||
// { dg-final { scan-assembler-not ".globl __ZN3FooIiE5identEi" } }
|
||||
|
||||
template <typename X>
|
||||
struct Foo {
|
||||
X ident(X x) { return x; }
|
||||
};
|
||||
|
||||
extern template struct Foo<int>;
|
||||
|
||||
int abcde(Foo<int>& foo, int n) {
|
||||
return foo.ident(n);
|
||||
}
|
16
gcc/testsuite/obj-c++.dg/template-6.mm
Normal file
16
gcc/testsuite/obj-c++.dg/template-6.mm
Normal file
@ -0,0 +1,16 @@
|
||||
// Test that extern template does not get emitted.
|
||||
// Author: Matt Austern <austern@apple.com>
|
||||
|
||||
// { dg-do compile }
|
||||
// { dg-options "" }
|
||||
// { dg-final { scan-assembler-not ".globl __ZN3FooIiE5identEi" } }
|
||||
|
||||
template <typename X>
|
||||
struct Foo { X ident(X x); };
|
||||
|
||||
template <typename X>
|
||||
X Foo<X>::ident(X x) { return x; }
|
||||
|
||||
extern template struct Foo<int>;
|
||||
|
||||
int abcde(Foo<int>& foo, int n) { return foo.ident(n); }
|
42
gcc/testsuite/obj-c++.dg/try-catch-1.mm
Normal file
42
gcc/testsuite/obj-c++.dg/try-catch-1.mm
Normal file
@ -0,0 +1,42 @@
|
||||
/* Test if the compiler accepts @throw / @try..@catch..@finally syntax. */
|
||||
/* Developed by Ziemowit Laski <zlaski@apple.com>. */
|
||||
|
||||
/* { dg-options "-fobjc-exceptions" } */
|
||||
/* { dg-do compile } */
|
||||
|
||||
#include <objc/Object.h>
|
||||
#include <stdio.h>
|
||||
#include <setjmp.h>
|
||||
|
||||
@interface Frob: Object
|
||||
@end
|
||||
|
||||
@implementation Frob: Object
|
||||
@end
|
||||
|
||||
static int exc_control = 0;
|
||||
|
||||
int proc() {
|
||||
if(exc_control) {
|
||||
printf ("Throwing (%d)... ", exc_control);
|
||||
@throw [Frob new];
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
int foo()
|
||||
{
|
||||
@try {
|
||||
return proc();
|
||||
}
|
||||
@catch (Frob* ex) {
|
||||
if(exc_control > 1) {
|
||||
printf("Rethrowing (%d)... ", exc_control);
|
||||
@throw;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@finally {
|
||||
printf("In @finally block (%d)... ", exc_control);
|
||||
}
|
||||
}
|
78
gcc/testsuite/obj-c++.dg/try-catch-2.mm
Normal file
78
gcc/testsuite/obj-c++.dg/try-catch-2.mm
Normal file
@ -0,0 +1,78 @@
|
||||
/* Test out '@catch(id foo) {...}', which should catch
|
||||
all uncaught exceptions. */
|
||||
/* Developed by Ziemowit Laski <zlaski@apple.com>. */
|
||||
|
||||
/* { dg-options "-fobjc-exceptions" } */
|
||||
/* { dg-do run } */
|
||||
|
||||
#include <objc/Object.h>
|
||||
#include <stdio.h>
|
||||
|
||||
/* The following is not required in actual user code; we include it
|
||||
here to check that the compiler generates an internal definition of
|
||||
_setjmp that is consistent with what <setjmp.h> provides. */
|
||||
#include <setjmp.h>
|
||||
|
||||
extern "C" void abort(void);
|
||||
#define CHECK_IF(expr) if(!(expr)) abort()
|
||||
|
||||
@interface Frob: Object
|
||||
@end
|
||||
|
||||
@implementation Frob: Object
|
||||
@end
|
||||
|
||||
static Frob* _connection = nil;
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
|
||||
|
||||
void test (Object* sendPort)
|
||||
{
|
||||
int cleanupPorts = 1;
|
||||
Frob* receivePort = nil;
|
||||
|
||||
@try {
|
||||
printf ("receivePort = %p\n", receivePort);
|
||||
printf ("sendPort = %p\n", sendPort);
|
||||
printf ("cleanupPorts = %d\n", cleanupPorts);
|
||||
printf ("---\n");
|
||||
|
||||
receivePort = (Frob *) -1;
|
||||
_connection = (Frob *) -1;
|
||||
printf ("receivePort = %p\n", receivePort);
|
||||
printf ("sendPort = %p\n", sendPort);
|
||||
printf ("cleanupPorts = %d\n", cleanupPorts);
|
||||
printf ("---\n");
|
||||
|
||||
receivePort = nil;
|
||||
sendPort = nil;
|
||||
cleanupPorts = 0;
|
||||
|
||||
printf ("receivePort = %p\n", receivePort);
|
||||
printf ("sendPort = %p\n", sendPort);
|
||||
printf ("cleanupPorts = %d\n", cleanupPorts);
|
||||
printf ("---\n");
|
||||
|
||||
@throw [Object new];
|
||||
}
|
||||
@catch(Frob *obj) {
|
||||
printf ("Exception caught by incorrect handler!\n");
|
||||
CHECK_IF(0);
|
||||
}
|
||||
@catch(id exc) {
|
||||
printf ("Exception caught by correct handler.\n");
|
||||
printf ("receivePort = %p (expected 0x0)\n", receivePort);
|
||||
printf ("sendPort = %p (expected 0x0)\n", sendPort);
|
||||
printf ("cleanupPorts = %d (expected 0)\n", cleanupPorts);
|
||||
printf ("---");
|
||||
CHECK_IF(!receivePort);
|
||||
CHECK_IF(!sendPort);
|
||||
CHECK_IF(!cleanupPorts);
|
||||
}
|
||||
}
|
||||
|
||||
int main (void) {
|
||||
test((Object *)-1);
|
||||
return 0;
|
||||
}
|
18
gcc/testsuite/obj-c++.dg/try-catch-3.mm
Normal file
18
gcc/testsuite/obj-c++.dg/try-catch-3.mm
Normal file
@ -0,0 +1,18 @@
|
||||
/* Test if caught exception objects are accessible inside the
|
||||
@catch block. (Yes, I managed to break this.) */
|
||||
/* Author: Ziemowit Laski <zlaski@apple.com> */
|
||||
|
||||
/* { dg-do compile } */
|
||||
/* { dg-options "-fobjc-exceptions" } */
|
||||
|
||||
#include <objc/Object.h>
|
||||
|
||||
const char *foo(void)
|
||||
{
|
||||
@try {
|
||||
return "foo";
|
||||
}
|
||||
@catch (Object* theException) {
|
||||
return [theException name];
|
||||
}
|
||||
}
|
25
gcc/testsuite/obj-c++.dg/try-catch-4.mm
Normal file
25
gcc/testsuite/obj-c++.dg/try-catch-4.mm
Normal file
@ -0,0 +1,25 @@
|
||||
/* Check that the compiler does not incorrectly complain about
|
||||
exceptions being caught by previous @catch blocks. */
|
||||
/* Author: Ziemowit Laski <zlaski@apple.com> */
|
||||
|
||||
/* { dg-do compile } */
|
||||
/* { dg-options "-Wall -fobjc-exceptions" } */
|
||||
|
||||
@interface Exception
|
||||
@end
|
||||
|
||||
@interface FooException : Exception
|
||||
@end
|
||||
|
||||
extern void foo();
|
||||
|
||||
void test()
|
||||
{
|
||||
@try {
|
||||
foo();
|
||||
}
|
||||
@catch (FooException* fe) {
|
||||
}
|
||||
@catch (Exception* e) {
|
||||
}
|
||||
}
|
26
gcc/testsuite/obj-c++.dg/try-catch-5.mm
Normal file
26
gcc/testsuite/obj-c++.dg/try-catch-5.mm
Normal file
@ -0,0 +1,26 @@
|
||||
/* Check that the compiler does correctly complain about
|
||||
exceptions being caught by previous @catch blocks. */
|
||||
/* Force the use of NeXT runtime to see that we don't ICE after
|
||||
generating the warning message. */
|
||||
|
||||
/* { dg-do compile } */
|
||||
/* { dg-options "-Wall -fnext-runtime -fobjc-exceptions" } */
|
||||
|
||||
@interface Exception
|
||||
@end
|
||||
|
||||
@interface FooException : Exception
|
||||
@end
|
||||
|
||||
extern void foo();
|
||||
|
||||
void test()
|
||||
{
|
||||
@try {
|
||||
foo();
|
||||
}
|
||||
@catch (Exception* e) { /* { dg-warning "earlier handler" } */
|
||||
}
|
||||
@catch (FooException* fe) { /* { dg-warning "will be caught" } */
|
||||
}
|
||||
}
|
14
gcc/testsuite/obj-c++.dg/try-catch-6.mm
Normal file
14
gcc/testsuite/obj-c++.dg/try-catch-6.mm
Normal file
@ -0,0 +1,14 @@
|
||||
/* A very simple @try-@catch example. */
|
||||
|
||||
/* { dg-do compile } */
|
||||
/* { dg-options "-fobjc-exceptions" } */
|
||||
|
||||
int foo(void) {
|
||||
@try {
|
||||
return 2;
|
||||
}
|
||||
@catch (id foo) {
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
24
gcc/testsuite/obj-c++.dg/try-catch-7.mm
Normal file
24
gcc/testsuite/obj-c++.dg/try-catch-7.mm
Normal file
@ -0,0 +1,24 @@
|
||||
/* { dg-do compile } */
|
||||
/* { dg-options "-fobjc-exceptions" } */
|
||||
|
||||
#include <objc/Object.h>
|
||||
|
||||
int main (int argc, const char * argv[]) {
|
||||
Object * pool = [Object new];
|
||||
int a;
|
||||
|
||||
if ( 1 ) {
|
||||
@try {
|
||||
a = 1;
|
||||
}
|
||||
@catch (Object *e) {
|
||||
a = 2;
|
||||
}
|
||||
@finally {
|
||||
a = 3;
|
||||
}
|
||||
}
|
||||
|
||||
[pool free];
|
||||
return 0;
|
||||
}
|
27
gcc/testsuite/obj-c++.dg/try-catch-8.mm
Normal file
27
gcc/testsuite/obj-c++.dg/try-catch-8.mm
Normal file
@ -0,0 +1,27 @@
|
||||
/* Test for graceful compilation of @synchronized statements. */
|
||||
|
||||
/* { dg-do compile } */
|
||||
/* { dg-options "-fobjc-exceptions" } */
|
||||
|
||||
#include <objc/Object.h>
|
||||
|
||||
@interface Derived: Object
|
||||
- (id) meth;
|
||||
@end
|
||||
|
||||
@implementation Derived
|
||||
- (id) meth {
|
||||
return self;
|
||||
}
|
||||
|
||||
static Derived* rewriteDict(void) {
|
||||
static Derived *sDict = 0;
|
||||
if (sDict == 0) {
|
||||
@synchronized ([Derived class]) {
|
||||
if (sDict == 0)
|
||||
sDict = [Derived new];
|
||||
}
|
||||
}
|
||||
return sDict;
|
||||
}
|
||||
@end
|
65
gcc/testsuite/obj-c++.dg/try-catch-9.mm
Normal file
65
gcc/testsuite/obj-c++.dg/try-catch-9.mm
Normal file
@ -0,0 +1,65 @@
|
||||
/* Check that local variables that get modified inside the @try
|
||||
block survive until the @catch block is reached. */
|
||||
/* Developed by Ziemowit Laski <zlaski@apple.com>. */
|
||||
|
||||
/* { dg-options "-fobjc-exceptions -O2" } */
|
||||
/* { dg-do run } */
|
||||
|
||||
#include <objc/Object.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
int gi1 = 9, gi2 = 19;
|
||||
float gf1 = 9.0, gf2 = 19.0;
|
||||
id obj2 = nil;
|
||||
|
||||
void foo (int arg1, float *arg2)
|
||||
{
|
||||
int *pi = &gi1;
|
||||
float *pf = &gf1;
|
||||
id obj1 = nil;
|
||||
int local1 = 45, local2 = 47;
|
||||
float local3 = 3.0, local4 = 4.0;
|
||||
register int local5 = 15;
|
||||
static float local6 = 16.0;
|
||||
|
||||
@try {
|
||||
local1 = 123;
|
||||
local2 = 345;
|
||||
local3 = 5.0;
|
||||
local4 = 6.0;
|
||||
local5 = 17;
|
||||
local6 = 18.0;
|
||||
pi = &gi2;
|
||||
pf = &gf2;
|
||||
obj2 = obj1 = [Object new];
|
||||
arg1 = 17;
|
||||
arg2 = &gf2;
|
||||
|
||||
@throw [Object new];
|
||||
}
|
||||
@catch (Object *obj) {
|
||||
if (local1 != 123 || local2 != 345 || local3 != 5.0
|
||||
|| local4 != 6.0 || local5 != 17 || local6 != 18.0) {
|
||||
printf("Abort 1\n");
|
||||
abort();
|
||||
}
|
||||
if (pi != &gi2 || pf != &gf2) {
|
||||
printf("Abort 2\n");
|
||||
abort();
|
||||
}
|
||||
if (!obj1 || obj1 != obj2) {
|
||||
printf("Abort 3\n");
|
||||
abort();
|
||||
}
|
||||
if (arg1 != 17 || arg2 != &gf2) {
|
||||
printf("Abort 4\n");
|
||||
abort();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int main(void) {
|
||||
foo(15, &gf1);
|
||||
return 0;
|
||||
}
|
74
gcc/testsuite/obj-c++.dg/va-meth-1.mm
Normal file
74
gcc/testsuite/obj-c++.dg/va-meth-1.mm
Normal file
@ -0,0 +1,74 @@
|
||||
/* Based on objc/execute/va_method.m, by Nicola Pero */
|
||||
|
||||
/* { dg-do run } */
|
||||
|
||||
#include <objc/Object.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
/* Test methods with "C-style" trailing arguments, with or without ellipsis. */
|
||||
|
||||
@interface MathClass: Object
|
||||
/* sum positive numbers; -1 ends the list */
|
||||
+ (int) sum: (int) firstNumber, int secondNumber, ...;
|
||||
+ (int) prod: (int) firstNumber, int secondNumber, int thirdNumber;
|
||||
+ (int) minimum: (int) firstNumber, ...;
|
||||
@end
|
||||
|
||||
extern "C" int some_func(id self, SEL _cmd, int firstN, int secondN, int thirdN, ...) {
|
||||
return firstN + secondN + thirdN;
|
||||
}
|
||||
|
||||
@implementation MathClass
|
||||
+ (int) sum: (int) firstNumber, int secondNumber, ...
|
||||
{
|
||||
va_list ap;
|
||||
int sum = 0, number = 0;
|
||||
|
||||
va_start (ap, secondNumber);
|
||||
number = firstNumber + secondNumber;
|
||||
|
||||
while (number >= 0)
|
||||
{
|
||||
sum += number;
|
||||
number = va_arg (ap, int);
|
||||
}
|
||||
|
||||
va_end (ap);
|
||||
|
||||
return sum;
|
||||
}
|
||||
+ (int) prod: (int) firstNumber, int secondNumber, int thirdNumber {
|
||||
return firstNumber * secondNumber * thirdNumber;
|
||||
}
|
||||
+ (int) minimum: (int) firstNumber, ...
|
||||
{
|
||||
va_list ap;
|
||||
int minimum = 999, number = 0;
|
||||
|
||||
va_start (ap, firstNumber);
|
||||
number = firstNumber;
|
||||
|
||||
while (number >= 0)
|
||||
{
|
||||
minimum = (minimum < number ? minimum: number);
|
||||
number = va_arg (ap, int);
|
||||
}
|
||||
|
||||
va_end (ap);
|
||||
|
||||
return minimum;
|
||||
}
|
||||
@end
|
||||
|
||||
int main (void)
|
||||
{
|
||||
if ([MathClass sum: 1, 2, 3, 4, 5, -1] != 15)
|
||||
abort ();
|
||||
if ([MathClass prod: 4, 5, 6] != 120)
|
||||
abort ();
|
||||
if ([MathClass minimum: 17, 9, 133, 84, 35, -1] != 9)
|
||||
abort ();
|
||||
|
||||
return 0;
|
||||
}
|
@ -8,6 +8,8 @@
|
||||
#include <objc/objc-class.h>
|
||||
#include <objc/Object.h>
|
||||
#include <ctype.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#define objc_get_class(C) objc_getClass(C)
|
||||
#define objc_get_meta_class(C) objc_getMetaClass(C)
|
||||
@ -45,22 +47,28 @@
|
||||
/* The following is necessary to "cover" the bf*.m test cases on NeXT. */
|
||||
|
||||
#undef MAX
|
||||
#undef MIN
|
||||
#undef ROUND
|
||||
|
||||
#ifdef __cplusplus
|
||||
#define MAX(X, Y) ((X > Y) ? X : Y)
|
||||
#define MIN(X, Y) ((X < Y) ? X : Y)
|
||||
#define ROUND(V, A) (A * ((V + A - 1) / A))
|
||||
#else
|
||||
#define MAX(X, Y) \
|
||||
({ typeof (X) __x = (X), __y = (Y); \
|
||||
(__x > __y ? __x : __y); })
|
||||
|
||||
#undef MIN
|
||||
#define MIN(X, Y) \
|
||||
({ typeof (X) __x = (X), __y = (Y); \
|
||||
(__x < __y ? __x : __y); })
|
||||
|
||||
#undef ROUND
|
||||
#define ROUND(V, A) \
|
||||
({ typeof (V) __v = (V); typeof (A) __a = (A); \
|
||||
__a * ((__v+__a - 1)/__a); })
|
||||
#endif
|
||||
|
||||
#define BITS_PER_UNIT __CHAR_BIT__
|
||||
#define STRUCTURE_SIZE_BOUNDARY (BITS_PER_UNIT * sizeof (struct{char a;}))
|
||||
typedef struct{ char a; } __small_struct;
|
||||
#define STRUCTURE_SIZE_BOUNDARY (BITS_PER_UNIT * sizeof (__small_struct))
|
||||
|
||||
/* Not sure why the following are missing from NeXT objc headers... */
|
||||
|
||||
@ -104,7 +112,7 @@ struct objc_struct_layout
|
||||
unsigned int record_align;
|
||||
};
|
||||
|
||||
typedef union {
|
||||
typedef union arglist {
|
||||
char *arg_ptr;
|
||||
char arg_regs[sizeof (char*)];
|
||||
} *arglist_t; /* argument frame */
|
||||
@ -117,6 +125,7 @@ void objc_layout_structure (const char *type,
|
||||
BOOL objc_layout_structure_next_member (struct objc_struct_layout *layout);
|
||||
void objc_layout_finish_structure (struct objc_struct_layout *layout,
|
||||
unsigned int *size, unsigned int *align);
|
||||
int objc_aligned_size (const char *type);
|
||||
|
||||
/*
|
||||
return the size of an object specified by type
|
||||
@ -193,10 +202,6 @@ objc_sizeof_type (const char *type)
|
||||
return sizeof (double);
|
||||
break;
|
||||
|
||||
case _C_VOID:
|
||||
return sizeof (void);
|
||||
break;
|
||||
|
||||
case _C_PTR:
|
||||
case _C_ATOM:
|
||||
case _C_CHARPTR:
|
||||
|
Loading…
Reference in New Issue
Block a user