URL
https://opencores.org/ocsvn/openrisc/openrisc/trunk
Subversion Repositories openrisc
Compare Revisions
- This comparison shows the changes necessary to convert path
/openrisc/trunk/gnu-dev/or1k-gcc/gcc/testsuite/obj-c++.dg
- from Rev 685 to Rev 703
- ↔ Reverse comparison
Rev 685 → Rev 703
/method-19.mm
0,0 → 1,72
/* Test if instance methods of root classes are used as class methods, if no |
"real" methods are found. For receivers of type 'id' and 'Class', all |
root classes must be considered. */ |
/* Author: Ziemowit Laski <zlaski@apple.com>. */ |
/* { dg-do run } */ |
/* { dg-xfail-run-if "Needs OBJC2 ABI" { *-*-darwin* && { lp64 && { ! objc2 } } } { "-fnext-runtime" } { "" } } */ |
#include <objc/objc.h> |
#include "../objc-obj-c++-shared/runtime.h" |
|
#include <stdlib.h> |
#include <string.h> |
|
#define CHECK_IF(expr) if(!(expr)) abort() |
|
@protocol Proto |
- (const char *) method4; |
@end |
|
@interface Root |
{ Class isa; } |
+ (const char *) method2; |
@end |
|
@interface Derived: Root |
- (const char *) method1; |
- (const char *) method2; |
- (const char *) method3; |
@end |
|
@interface Root (Categ) |
- (const char *) method3; |
@end |
|
@implementation Root (Categ) |
- (const char *) method3 { return "Root(Categ)::-method3"; } |
- (const char *) method4 { return "Root(Categ)::-method4"; } |
@end |
|
@implementation Derived |
- (const char *) method1 { return "Derived::-method1"; } |
- (const char *) method2 { return "Derived::-method2"; } |
- (const char *) method3 { return "Derived::-method3"; } |
@end |
|
@implementation Root |
+ initialize { return self; } |
- (const char *) method1 { return "Root::-method1"; } |
+ (const char *) method2 { return "Root::+method2"; } |
@end |
|
int main(void) |
{ |
Class obj = objc_getClass("Derived"); |
|
/* None of the following should elicit compiler-time warnings. */ |
|
CHECK_IF(!strcmp([Root method1], "Root::-method1")); |
CHECK_IF(!strcmp([Root method2], "Root::+method2")); |
CHECK_IF(!strcmp([Root method3], "Root(Categ)::-method3")); |
CHECK_IF(!strcmp([Root method4], "Root(Categ)::-method4")); |
CHECK_IF(!strcmp([Derived method1], "Root::-method1")); |
CHECK_IF(!strcmp([Derived method2], "Root::+method2")); |
CHECK_IF(!strcmp([Derived method3], "Root(Categ)::-method3")); |
CHECK_IF(!strcmp([Derived method4], "Root(Categ)::-method4")); |
CHECK_IF(!strcmp([obj method1], "Root::-method1")); |
CHECK_IF(!strcmp([obj method2], "Root::+method2")); |
CHECK_IF(!strcmp([obj method3], "Root(Categ)::-method3")); |
CHECK_IF(!strcmp([obj method4], "Root(Categ)::-method4")); |
|
return 0; |
} |
|
/encode-1-next.mm
0,0 → 1,26
/* This file tests that things are encoded using the gcc-3.3 ABI which is only |
used by the NeXT runtime. */ |
/* Test for graceful encoding of const-qualified fields and parameters. */ |
/* Author: Ziemowit Laski <zlaski@apple.com> */ |
|
/* { dg-do compile } */ |
/* { dg-skip-if "" { *-*-* } { "-fgnu-runtime" } { "" } } */ |
|
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\]+\\^{Cxx=\\^{Cxx}}\[0-9\]+r\\^{Cxx=\\^{Cxx}}" } } */ |
/private-1.mm
0,0 → 1,58
/* 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 "instance variable \\'_private\\' is declared private" } */ |
|
_protected = 12; /* Ok */ |
_public = 12; /* Ok */ |
} |
@end |
|
int main (void) |
{ |
MyClass *m = nil; |
|
if (m != nil) |
{ |
int access; |
|
access = m->_private; /* { dg-warning "is @private" } */ |
access = m->_protected; /* { dg-warning "is @protected" } */ |
access = m->_public; /* Ok */ |
} |
|
return 0; |
} |
/gnu-runtime-2.mm
0,0 → 1,30
/* Sanity check for GNU-runtime version of constant strings, |
regardless of runtime used on target system. */ |
|
/* { dg-do compile } */ |
/* { dg-skip-if "" { *-*-* } { "-fnext-runtime" } { "" } } */ |
|
#include <objc/Object.h> |
#include <string.h> |
#include <stdlib.h> |
|
@interface NXConstantString: Object |
{ |
char *c_string; |
unsigned int len; |
} |
-(const char *) cString; |
-(unsigned int) length; |
@end |
|
@implementation NXConstantString |
-(const char *) cString { return c_string; } |
-(unsigned int) length { return len; } |
@end |
|
int main(int argc, const char **args) |
{ |
if (strcmp ([@"this is a string" cString], "this is a string")) |
abort (); |
return 0; |
} |
/naming-3.mm
0,0 → 1,15
/* Testing for detecting duplicate ivars. */ |
/* { dg-do compile } */ |
|
@interface A |
{ |
char x; /* { dg-message "previous declaration" } */ |
char x; |
} /* { dg-error "redeclaration" } */ |
@end |
|
@interface B : A |
{ |
char y; |
} |
@end |
/template-4.mm
0,0 → 1,85
/* Author: Ziemowit Laski <zlaski@apple.com>. */ |
|
/* { dg-do run } */ |
/* { dg-xfail-run-if "Needs OBJC2 ABI" { *-*-darwin* && { lp64 && { ! objc2 } } } { "-fnext-runtime" } { "" } } */ |
/* { dg-options "-mno-constant-cfstrings" { target *-*-darwin* } } */ |
/* { dg-additional-sources "../objc-obj-c++-shared/nsconstantstring-class-impl.mm" } */ |
|
#include <stdarg.h> |
#include <stdlib.h> |
#include <string.h> |
|
#ifndef __NEXT_RUNTIME__ |
#include <objc/NXConstStr.h> |
#else |
#include "../objc-obj-c++-shared/nsconstantstring-class.h" |
#endif |
|
#include "../objc-obj-c++-shared/TestsuiteObject.m" |
#include "../objc-obj-c++-shared/runtime.h" |
|
#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: TestsuiteObject { |
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 ([@"TestsuiteObject" cString], getDesc<TestsuiteObject>())); |
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; |
} |
/try-catch-10.mm
0,0 → 1,25
/* Check that taking the address of a local variable marked 'volatile' |
by the compiler does not generate untoward errors. */ |
/* Developed by Ziemowit Laski <zlaski@apple.com>. */ |
|
/* { dg-options "-fobjc-exceptions" } */ |
/* { dg-do compile } */ |
|
|
void foo (int *arg1, int *arg2) |
{ |
*arg1 = *arg2; |
} |
|
void bar (int arg) { |
int rcvr; |
|
@try { |
rcvr = arg; |
} |
@finally { |
int *rcvr0 = &rcvr; |
foo (rcvr0, &arg); |
} |
} |
|
/class-extension-2.mm
0,0 → 1,56
/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, December 2010. */ |
/* { dg-do compile } */ |
|
/* This test tests class extensions and protocols. */ |
|
#include <objc/objc.h> |
|
/* First, a simple test where a plain class has a protocol attached to |
it in a class extension. */ |
@interface MyObject |
{ |
Class isa; |
} |
@end |
|
@protocol MyProtocol |
- (void) test; |
@end |
|
@interface MyObject () <MyProtocol> |
@end |
|
@implementation MyObject |
@end /* { dg-warning "incomplete implementation of class .MyObject." } */ |
/* { dg-warning "method definition for .-test. not found" "" { target *-*-* } 24 } */ |
/* { dg-warning "class .MyObject. does not fully implement the .MyProtocol. protocol" "" { target *-*-* } 24 } */ |
|
|
|
/* Second, a more interesting test where protocols are added from the |
main class and from two different class extensions. */ |
@interface MyObject2 : MyObject <MyProtocol> |
@end |
|
@protocol MyProtocol2 |
- (void) test2; |
@end |
|
@protocol MyProtocol3 |
- (void) test3; |
@end |
|
@interface MyObject2 () <MyProtocol2> |
@end |
|
@interface MyObject2 () <MyProtocol3> |
@end |
|
@implementation MyObject2 |
@end /* { dg-warning "incomplete implementation of class .MyObject2." } */ |
/* { dg-warning "method definition for .-test. not found" "" { target *-*-* } 50 } */ |
/* { dg-warning "class .MyObject2. does not fully implement the .MyProtocol. protocol" "" { target *-*-* } 50 } */ |
/* { dg-warning "method definition for .-test2. not found" "" { target *-*-* } 50 } */ |
/* { dg-warning "class .MyObject2. does not fully implement the .MyProtocol2. protocol" "" { target *-*-* } 50 } */ |
/* { dg-warning "method definition for .-test3. not found" "" { target *-*-* } 50 } */ |
/* { dg-warning "class .MyObject2. does not fully implement the .MyProtocol3. protocol" "" { target *-*-* } 50 } */ |
/comp-types-10.mm
0,0 → 1,20
/* Yet another mysterious gimplifier crasher. */ |
/* { dg-do compile } */ |
/* { dg-prune-output ".*internal compiler error.*" } */ |
/* { dg-options "-O3" } */ |
|
@class NSString; |
@protocol NSObject |
@end |
@interface NSObject <NSObject> { |
} |
@end |
void __setRetained(id *ivar, id value) { |
*ivar = value; |
} |
static NSString *_logProcessPrefix = 0; |
@implementation NSObject (ScopeAdditions) |
+ (void)setObjectLogProcessPrefix:(NSString *)processPrefix { |
__setRetained(&_logProcessPrefix, processPrefix); |
} |
@end |
/syntax-error-4.mm
0,0 → 1,15
/* Yet another stray infinite loop... */ |
/* { dg-do compile } */ |
|
@interface t |
{ |
} |
- (void)go; |
@end |
@implementation t |
- (void)go |
{ |
} |
} /* { dg-error "stray .\}. between Objective\\-C\\+\\+ methods" } */ |
@end |
|
/method-conflict-3.mm
0,0 → 1,63
/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, December 2010. */ |
/* { dg-do compile } */ |
|
#include <objc/objc.h> |
|
/* Test that the compiler can correctly compare protocols in types of |
method signatures. */ |
|
@protocol A, B, C; |
|
@interface MyClass |
- (void) method1: (id)x; |
- (void) method1: (id)x; /* Ok */ |
|
- (void) method2: (id <A>)x; |
- (void) method2: (id <A>)x; /* Ok */ |
|
- (void) method3: (id <A, B>)x; |
- (void) method3: (id <A, B>)x; /* Ok */ |
|
- (void) method4: (id <A, B>)x; |
- (void) method4: (id <A, B, B>)x; /* Ok */ |
|
- (void) method5: (id <A, A, B>)x; |
- (void) method5: (id <A, B, B>)x; /* Ok */ |
|
- (void) method6: (id <A, A, B, B, C, C>)x; |
- (void) method6: (id <C, A, B>)x; /* Ok */ |
|
- (void) method7: (id)x; /* { dg-message "previous declaration" } */ |
- (void) method7: (id <A>)x; /* { dg-error "duplicate declaration" } */ |
|
- (void) method8: (id <A>)x; /* { dg-message "previous declaration" } */ |
- (void) method8: (id)x; /* { dg-error "duplicate declaration" } */ |
|
- (void) method9: (id <A>)x; /* { dg-message "previous declaration" } */ |
- (void) method9: (id <B>)x; /* { dg-error "duplicate declaration" } */ |
|
- (void) methodA: (id <A>)x; /* { dg-message "previous declaration" } */ |
- (void) methodA: (id <A, B>)x; /* { dg-error "duplicate declaration" } */ |
|
- (void) methodB: (id <A, B>)x; /* { dg-message "previous declaration" } */ |
- (void) methodB: (id <A>)x; /* { dg-error "duplicate declaration" } */ |
|
- (void) methodC: (id <A, B, C>)x; /* { dg-message "previous declaration" } */ |
- (void) methodC: (id <A, B>)x; /* { dg-error "duplicate declaration" } */ |
|
- (void) methodD: (id <A, B, C>)x; /* { dg-message "previous declaration" } */ |
- (void) methodD: (id <A, B, A>)x; /* { dg-error "duplicate declaration" } */ |
|
- (void) methodE: (MyClass <A, B, C> *)x; /* { dg-message "previous declaration" } */ |
- (void) methodE: (MyClass <A, B, A> *)x; /* { dg-error "duplicate declaration" } */ |
|
- (void) methodF: (MyClass <A, B, A> *)x; |
- (void) methodF: (MyClass <A, B, A> *)x; /* Ok */ |
|
- (void) methodG: (MyClass *)x; /* { dg-message "previous declaration" } */ |
- (void) methodG: (MyClass <A, B, C> *)x; /* { dg-error "duplicate declaration" } */ |
|
- (void) methodH: (MyClass <A, C>*)x; /* { dg-message "previous declaration" } */ |
- (void) methodH: (MyClass *)x; /* { dg-error "duplicate declaration" } */ |
|
@end |
/bitfield-2.mm
0,0 → 1,80
/* Check if bitfield ivars are inherited correctly (i.e., without |
being "promoted" to ints). */ |
/* Contributed by Ziemowit Laski <zlaski@apple.com>. */ |
/* { dg-do run } */ |
/* { dg-xfail-run-if "Needs OBJC2 ABI" { *-*-darwin* && { lp64 && { ! objc2 } } } { "-fnext-runtime" } { "" } } */ |
|
#include "../objc-obj-c++-shared/TestsuiteObject.m" |
#include <stdlib.h> |
|
#define CHECK_IF(expr) if(!(expr)) abort(); |
|
@interface Base: TestsuiteObject |
{ |
int full; |
int full2: 32; |
int _refs: 8; |
int field2: 3; |
unsigned f3: 8; |
short cc; |
unsigned g: 16; |
int r2: 8; |
int r3: 8; |
int r4: 2; |
int r5: 8; |
char c; |
} |
- (void)setValues; |
@end |
|
@interface Derived: Base |
{ |
char d; |
int _field3: 6; |
} |
- (void)checkValues; |
@end |
|
@implementation Base |
-(void)setValues { |
full = 1; |
full2 = 2; |
_refs = 3; |
field2 = 1; |
f3 = 6; |
cc = 7; |
g = 8; |
r2 = 9; |
r3 = 10; |
r4 = 1; |
r5 = 12; |
c = 13; |
} |
@end |
|
@implementation Derived |
-(void)checkValues { |
CHECK_IF(full == 1); |
CHECK_IF(full2 == 2); |
CHECK_IF(_refs == 3); |
CHECK_IF(field2 == 1); |
CHECK_IF(f3 == 6); |
CHECK_IF(cc == 7); |
CHECK_IF(g == 8); |
CHECK_IF(r2 == 9); |
CHECK_IF(r3 == 10); |
CHECK_IF(r4 == 1); |
CHECK_IF(r5 == 12); |
CHECK_IF(c == 13); |
} |
@end |
|
int main(void) { |
Derived *obj = [[Derived alloc] init]; |
|
[obj setValues]; |
[obj checkValues]; |
|
return 0; |
} |
|
/defs.mm
0,0 → 1,43
/* Check @defs() in Objective-C++ */ |
/* Contributed by Devang Patel <dpatel@apple.com> */ |
/* { dg-options "" } */ |
/* { dg-do run } */ |
/* { dg-xfail-run-if "Needs OBJC2 ABI" { *-*-darwin* && { lp64 && { ! objc2 } } } { "-fnext-runtime" } { "" } } */ |
#include "../objc-obj-c++-shared/TestsuiteObject.m" |
#include <stdlib.h> |
#include <objc/objc.h> |
|
extern "C" void abort(void); |
|
@interface A : TestsuiteObject |
{ |
@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; |
} |
|
/method-5.mm
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]; |
} |
/selector-warn-1.mm
0,0 → 1,16
/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, January 2011. */ |
/* { dg-options "-Wselector" } */ |
/* { dg-do compile } */ |
|
#include <objc/objc.h> |
|
@interface RootObject |
@end |
|
@interface MyObject : RootObject |
- (void) method; /* { dg-message "found" } */ |
@end |
|
@interface MyObject2 : RootObject |
- (int) method; /* { dg-message "also found" } */ |
@end /* { dg-warning "multiple selectors named .-method. found" } */ |
/exceptions-7.mm
0,0 → 1,18
/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, December 2010. */ |
/* { dg-options "-fobjc-exceptions" } */ |
/* { dg-do compile } */ |
|
/* Test warnings when the argument of @throw is invalid. */ |
|
#include <objc/objc.h> |
|
void test (id object) |
{ |
struct x { int i; } invalid_1, *invalid_2; |
|
@throw object; /* Ok */ |
@throw 1; /* { dg-error ".@throw. argument is not an object" } */ |
@throw "string"; /* { dg-error ".@throw. argument is not an object" } */ |
@throw invalid_1; /* { dg-error ".@throw. argument is not an object" } */ |
@throw invalid_2; /* { dg-error ".@throw. argument is not an object" } */ |
} |
/except-1.mm
0,0 → 1,66
/* { dg-do run } */ |
/* { dg-xfail-run-if "Needs OBJC2 ABI" { *-*-darwin* && { lp64 && { ! objc2 } } } { "-fnext-runtime" } { "" } } */ |
|
/* This tests that exceptions work. It used to fail because |
objc_msgSend was marked with DECL_NOTHROW. |
If you include objc/Object.h, the problem goes away, because |
that file includes objc/objc-runtime.h which explicitly prototypes |
objc_msgSend without 'nothrow'. */ |
|
#include <stdio.h> |
#include <stdlib.h> |
#include "../objc-obj-c++-shared/TestsuiteObject.m" |
|
// ObjectiveC class header |
@interface ObjCclass : TestsuiteObject { |
} |
-(void)method1; |
-(void)method2; |
@end |
|
// C++ class header |
class CPPclass { |
public: |
void function1(); |
}; |
|
|
// Main |
int main(int argc, char *argv[]) |
{ |
ObjCclass * foo = [[ObjCclass alloc] init]; |
[foo method1]; |
exit (0); |
} |
|
|
// ObjectiveC implementation |
@implementation ObjCclass |
|
-(void) method1 |
{ |
try { |
[self method2]; |
} |
catch(...) { |
return; |
} |
} |
|
-(void) method2 |
{ |
CPPclass foo; |
foo.function1(); |
} |
|
@end |
|
|
// C++ implementation |
void CPPclass::function1() |
{ |
throw (1); |
/* Shouldn't be here because we threw. */ |
abort (); |
} |
|
/pr45735.mm
0,0 → 1,4
/* { dg-do compile } */ |
@interface Fraction |
-(void) setNumerator: (int) :(int) ; /* { dg-error "expected identifier" } */ |
@end |
/encode-1.mm
0,0 → 1,24
/* Test for graceful encoding of const-qualified fields and parameters. */ |
/* Author: Ziemowit Laski <zlaski@apple.com> */ |
|
/* { dg-do compile } */ |
/* { dg-skip-if "" { *-*-* } { "-fnext-runtime" } { "" } } */ |
|
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}" } } */ |
/warn5.mm
0,0 → 1,25
/* Check to make sure that a c++ program compiled in objective-c++ mode |
has no trace of meta-data specific diagnosis coming out of compiling it. |
This is replicate of warn5.C. |
*/ |
// { dg-do assemble } |
// { dg-options "-Wpointer-arith" } |
|
double X(const double x) { return x; } |
double Y() { return 1.0; } |
double Z() { return 2.0; } |
|
struct A { |
void bar() { } |
void foo() { } |
}; |
|
typedef void (A::*pmf)(); |
|
static int mememe = &A::foo - &A::bar; // { dg-error "" } |
pmf b = &A::foo-1; // { dg-error "" } |
|
int main() { |
double y; |
y=X(Y-Z); // { dg-error "" } |
} |
/gnu-api-2-protocol.mm
0,0 → 1,163
/* Test the Modern GNU Objective-C Runtime API. |
|
This is test 'protocol', covering all functions starting with 'protocol'. */ |
|
/* { dg-do run } */ |
/* { dg-skip-if "No API#2 pre-Darwin9" { *-*-darwin[5-8]* } { "-fnext-runtime" } { "" } } */ |
/* { dg-xfail-run-if "Needs OBJC2 ABI" { *-*-darwin* && { lp64 && { ! objc2 } } } { "-fnext-runtime" } { "" } } */ |
|
/* To get the modern GNU Objective-C Runtime API, you include |
objc/runtime.h. */ |
#include <objc/runtime.h> |
#include <stdlib.h> |
#include <iostream> |
#include <cstring> |
|
@interface MyRootClass |
{ Class isa; } |
+ alloc; |
- init; |
+ initialize; |
@end |
|
@implementation MyRootClass |
+ alloc { return class_createInstance (self, 0); } |
- init { return self; } |
+ initialize { return self; } |
@end |
|
@protocol MyProtocol |
- (id) variable; |
@end |
|
@protocol MySecondProtocol |
- (id) setVariable: (id)value; |
@end |
|
@protocol MyThirdProtocol <MySecondProtocol> |
- (id) setAnotherVariable: (id)value; |
@end |
|
@interface MySubClass : MyRootClass <MyProtocol> |
{ id variable_ivar; } |
- (void) setVariable: (id)value; |
- (id) variable; |
@end |
|
@implementation MySubClass |
- (void) setVariable: (id)value { variable_ivar = value; } |
- (id) variable { return variable_ivar; } |
@end |
|
|
int main () |
{ |
/* Functions are tested in alphabetical order. */ |
|
std::cout << "Testing protocol_conformsToProtocol ()...\n"; |
{ |
if (!protocol_conformsToProtocol (@protocol (MyProtocol), |
@protocol (MyProtocol))) |
abort (); |
|
if (!protocol_conformsToProtocol (@protocol (MyThirdProtocol), |
@protocol (MySecondProtocol))) |
abort (); |
|
if (protocol_conformsToProtocol (@protocol (MyProtocol), |
@protocol (MySecondProtocol))) |
abort (); |
} |
|
std::cout << "Testing protocol_copyMethodDescriptionList ()...\n"; |
{ |
unsigned int count; |
struct objc_method_description *list; |
|
list = protocol_copyMethodDescriptionList (@protocol (MyThirdProtocol), |
YES, YES, &count); |
|
if (count != 1) |
abort (); |
|
if (std::strcmp (sel_getName (list[0].name), "setAnotherVariable:") != 0) |
abort (); |
|
if (list[1].name != NULL && list[1].types != NULL) |
abort (); |
} |
|
/* TODO: Test new ABI (when available). */ |
std::cout << "Testing protocol_copyPropertyList ()...\n"; |
{ |
unsigned int count; |
objc_property_t *list; |
|
list = protocol_copyPropertyList (@protocol (MyProtocol), &count); |
|
if (count != 0 || list != NULL) |
abort (); |
} |
|
std::cout << "Testing protocol_copyProtocolList ()...\n"; |
{ |
unsigned int count; |
Protocol **list; |
|
list = protocol_copyProtocolList (@protocol (MyThirdProtocol), &count); |
|
if (count != 1) |
abort (); |
|
if (std::strcmp (protocol_getName (list[0]), "MySecondProtocol") != 0) |
abort (); |
|
if (list[1] != NULL) |
abort (); |
} |
|
std::cout << "Testing protocol_getMethodDescription ()...\n"; |
{ |
struct objc_method_description description; |
|
description = protocol_getMethodDescription (@protocol (MySecondProtocol), |
@selector (setVariable:), |
YES, YES); |
if (description.name == NULL && description.types == NULL) |
abort (); |
|
if (std::strcmp (sel_getName (description.name), "setVariable:") != 0) |
abort (); |
} |
|
std::cout << "Testing protocol_getName ()...\n"; |
{ |
if (std::strcmp (protocol_getName (@protocol (MyProtocol)), "MyProtocol") != 0) |
abort (); |
} |
|
/* TODO: Test new ABI (when available). */ |
std::cout << "Testing protocol_getProperty ()...\n"; |
{ |
objc_property_t property; |
|
property = protocol_getProperty (objc_getProtocol ("MyProtocol"), "someProperty", |
YES, YES); |
|
if (property != NULL) |
abort (); |
} |
|
std::cout << "Testing protocol_isEqual ()...\n"; |
{ |
if (!protocol_isEqual (@protocol (MyProtocol), |
@protocol (MyProtocol))) |
abort (); |
|
if (!protocol_isEqual (@protocol (MyProtocol), |
objc_getProtocol ("MyProtocol"))) |
abort (); |
} |
|
return (0); |
} |
/method-20.mm
0,0 → 1,17
/* Test if context-sensitive "in", "out", "byref", etc., qualifiers can be |
used as method selectors. */ |
/* Author: Ziemowit Laski <zlaski@apple.com>. */ |
/* { dg-do compile } */ |
|
@interface Foo |
- (void)insertNewButtonImage:(Foo *)newButtonImage in:(Foo *)buttonCell; |
+ (oneway void)oneway:(int)i2 byref:(int)i3 out:(float)f4 bycopy:(float)f5; |
@end |
|
@implementation Foo |
- (void)insertNewButtonImage:(Foo *)newButtonImage in:(Foo *)buttonCell { } |
+ (oneway void)oneway:(int)i2 byref:(int)i3 out:(float)f4 bycopy:(float)f5 { } |
@end |
|
/* { dg-final { scan-assembler "insertNewButtonImage:in:" } } */ |
/* { dg-final { scan-assembler "oneway:byref:out:bycopy:" } } */ |
/super-class-1.mm
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 |
/proto-lossage-5.mm
0,0 → 1,22
/* Do not lose references to forward-declared protocols. */ |
/* { dg-do compile } */ |
@class MyBaseClass; |
@class MyClassThatFails; |
@protocol _MyProtocol; |
|
@interface MyClassThatFails |
- (MyBaseClass<_MyProtocol> *) aMethod; |
@end |
|
@interface MyBaseClass |
@end |
|
@protocol _MyProtocol |
@end |
|
@implementation MyClassThatFails |
- (MyBaseClass<_MyProtocol> *) aMethod |
{ |
return 0; |
} |
@end |
/fobjc-exceptions-2.mm
0,0 → 1,29
/* Test that Objective-C exceptions cause an error with -fobjc-exceptions. */ |
/* { dg-do compile } */ |
|
@class Object; |
|
int dummy (int number, Object *o) |
{ |
@synchronized (o) /* { dg-error ".-fobjc-exceptions. is required to enable Objective-C exception syntax" } */ |
{ |
number++; |
} |
|
@try { /* Nothing, error has already been produced. */ |
number++; |
@throw o; /* Nothing, error has already been produced. */ |
} |
@catch (id object) |
{ |
number++; |
@throw; /* Nothing, error has already been produced. */ |
} |
@finally |
{ |
number++; |
} |
|
|
return number; |
} |
/try-catch-6.mm
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; |
} |
/comp-types-4.mm
0,0 → 1,64
/* Test assignments and comparisons between protocols (obscure case). */ |
/* Author: Nicola Pero <nicola@brainstorm.co.uk>. */ |
/* { dg-do compile } */ |
|
#include <objc/objc.h> |
|
@protocol MyProtocolA |
- (void) methodA; |
@end |
|
@protocol MyProtocolB |
- (void) methodB; |
@end |
|
@protocol MyProtocolAB <MyProtocolA, MyProtocolB> |
@end |
|
@protocol MyProtocolAC <MyProtocolA> |
- (void) methodC; |
@end |
|
int main() |
{ |
id<MyProtocolA> obj_a = nil; |
id<MyProtocolB> obj_b = nil; |
id<MyProtocolAB> obj_ab = nil; |
id<MyProtocolAC> obj_ac = nil; |
|
obj_a = obj_b; /* { dg-warning "does not conform" } */ |
obj_a = obj_ab; /* Ok */ |
obj_a = obj_ac; /* Ok */ |
|
obj_b = obj_a; /* { dg-warning "does not conform" } */ |
obj_b = obj_ab; /* Ok */ |
obj_b = obj_ac; /* { dg-warning "does not conform" } */ |
|
obj_ab = obj_a; /* { dg-warning "does not conform" } */ |
obj_ab = obj_b; /* { dg-warning "does not conform" } */ |
obj_ab = obj_ac; /* { dg-warning "does not conform" } */ |
|
obj_ac = obj_a; /* { dg-warning "does not conform" } */ |
obj_ac = obj_b; /* { dg-warning "does not conform" } */ |
obj_ac = obj_ab; /* { dg-warning "does not conform" } */ |
|
if (obj_a == obj_b) ; /* { dg-warning "lacks a cast" } */ |
if (obj_b == obj_a) ; /* { dg-warning "lacks a cast" } */ |
|
if (obj_a == obj_ab) ; /* Ok */ |
if (obj_ab == obj_a) ; /* Ok */ /* Spurious 2.95.4 warning here */ |
|
if (obj_a == obj_ac) ; /* Ok */ |
if (obj_ac == obj_a) ; /* Ok */ /* Spurious 2.95.4 warning here */ |
|
if (obj_b == obj_ab) ; /* Ok */ |
if (obj_ab == obj_b) ; /* Ok */ /* Spurious 2.95.4 warning here */ |
|
if (obj_b == obj_ac) ; /* { dg-warning "lacks a cast" } */ |
if (obj_ac == obj_b) ; /* { dg-warning "lacks a cast" } */ |
|
if (obj_ab == obj_ac) ; /* { dg-warning "lacks a cast" } */ |
if (obj_ac == obj_ab) ; /* { dg-warning "lacks a cast" } */ |
|
return 0; |
} |
/method-14.mm
0,0 → 1,14
/* Check if casting the receiver type causes method lookup to succeed. This was broken |
in Objective-C++. */ |
/* Contributed by Ziemowit Laski <zlaski@apple.com> */ |
/* { dg-do compile } */ |
|
@interface A |
@end |
|
@interface B: A |
- (void)f; |
@end |
|
void g(A *p) { [(B *)p f]; } |
|
/encode-9.mm
0,0 → 1,26
/* Test than @encode is properly instantiated. */ |
/* { dg-options "-lobjc" } */ |
/* { dg-do run } */ |
|
#include <string.h> |
#include <stdlib.h> |
#include <objc/objc.h> |
|
template<typename T> |
class typeOf { |
public: |
operator const char*() { return @encode(T); } |
}; |
|
int main() { |
typeOf<int> t; |
if (strcmp ((const char *)t, @encode(int))) |
abort(); |
|
typeOf<const char*> c; |
if (strcmp ((const char *)c, @encode(const char*))) |
abort(); |
|
return 0; |
} |
|
/empty-private-1.mm
0,0 → 1,9
/* Test for no entry after @private token. */ |
|
/* { do-do compile } */ |
|
@interface foo |
{ |
@private |
} |
@end |
/ivar-list-semi.mm
0,0 → 1,12
/* Allow for an optional semicolon following the ivar block. */ |
/* Contributed by: Ziemowit Laski <zlaski@apple.com>. */ |
|
#include "../objc-obj-c++-shared/TestsuiteObject.h" |
|
@interface Tink : TestsuiteObject { |
@private |
unsigned long mCode[4]; |
}; |
- (id)initWithProc:(void *)inProc; |
- (void *)getUniqueProc; |
@end |
/at-class-1.mm
0,0 → 1,11
/* Test @class. */ |
/* { dg-do compile } */ |
|
@class Object; /* Ok */ |
|
@class Object, ; /* { dg-error "expected identifier" } */ |
@class Object, ; /* { dg-error "expected identifier" } */ |
@class Object, AnotherObject, ; /* { dg-error "expected identifier" } */ |
@class Object, AnotherObject, TestObject ; /* Ok */ |
|
@class Object /* { dg-error "expected .;." } */ |
/cxx-scope-2.mm
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-obj-c++-shared/TestsuiteObject.h" |
#include <iostream> |
#include <string> |
|
@interface iostream: TestsuiteObject |
@end |
|
int main(void) { |
id i = [std::iostream new]; /* { dg-error "not an Objective\\-C class name or alias" } */ |
i = [iostream new]; |
i = [std::basic_string<char> new]; /* { dg-error "not an Objective\\-C class name or alias" } */ |
|
return 0; |
} |
/demangle-1.mm
0,0 → 1,35
/* Test demangling a C++ function. */ |
/* { dg-do run } */ |
|
#include <cstring> |
#include <cstdlib> |
#include <iostream> |
|
class demangle_test |
{ |
public: |
/* Return 0 if the demangling test succeeds. */ |
static int test_function1 () |
{ |
std::cout << __PRETTY_FUNCTION__ << "\n"; |
return std::strcmp (__PRETTY_FUNCTION__, "static int demangle_test::test_function1()"); |
} |
|
/* Return 0 if the demangling test succeeds. */ |
static int test_function2 (int ignored) |
{ |
std::cout << __PRETTY_FUNCTION__ << "\n"; |
return std::strcmp (__PRETTY_FUNCTION__, "static int demangle_test::test_function2(int)"); |
} |
}; |
|
int main () |
{ |
if (demangle_test::test_function1 () != 0) |
abort (); |
|
if (demangle_test::test_function2 (0) != 0) |
abort (); |
|
return 0; |
} |
/sync-3.mm
0,0 → 1,128
/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, December 2010. */ |
/* { dg-options "-fobjc-exceptions" } */ |
/* { dg-do compile } */ |
|
/* Test that the compiler is checking the argument of @synchronized(), |
and produce errors when invalid types are used. */ |
|
#include <objc/objc.h> |
|
@interface MyObject |
{ |
Class isa; |
} |
@end |
|
@implementation MyObject |
@end |
|
@protocol MyProtocol; |
|
typedef MyObject MyObjectTypedef; |
typedef MyObject *MyObjectPtrTypedef; |
typedef int intTypedef; |
|
typedef struct { float x; float y; } point, *point_ptr; |
|
int test (id object) |
{ |
int dummy = 0; |
|
{ |
int x; |
@synchronized (x) /* { dg-error ".@synchronized. argument is not an object" } */ |
{ dummy++; } |
} |
|
{ |
intTypedef x; |
@synchronized (x) /* { dg-error ".@synchronized. argument is not an object" } */ |
{ dummy++; } |
} |
|
{ |
int *x; |
@synchronized (x) /* { dg-error ".@synchronized. argument is not an object" } */ |
{ dummy++; } |
} |
|
{ |
point x; |
@synchronized (x) /* { dg-error ".@synchronized. argument is not an object" } */ |
{ dummy++; } |
} |
|
{ |
point_ptr x; |
@synchronized (x) /* { dg-error ".@synchronized. argument is not an object" } */ |
{ dummy++; } |
} |
|
{ |
id x; |
@synchronized (x) /* Ok */ |
{ dummy++; } |
} |
|
{ |
id <MyProtocol> x; |
@synchronized (x) /* Ok */ |
{ dummy++; } |
} |
|
{ |
MyObject *x; |
@synchronized (x) /* Ok */ |
{ dummy++; } |
} |
|
{ |
MyObject <MyProtocol> *x; |
@synchronized (x) /* Ok */ |
{ dummy++; } |
} |
|
{ |
static MyObject *x; |
@synchronized (x) /* Ok */ |
{ dummy++; } |
} |
|
{ |
MyObjectTypedef *x; |
@synchronized (x) /* Ok */ |
{ dummy++; } |
} |
|
{ |
MyObjectTypedef <MyProtocol> *x; |
@synchronized (x) /* Ok */ |
{ dummy++; } |
} |
|
{ |
MyObjectPtrTypedef x; |
@synchronized (x) /* Ok */ |
{ dummy++; } |
} |
|
{ |
Class x; |
@synchronized (x) /* Ok */ |
{ dummy++; } |
} |
|
@synchronized (1) /* { dg-error ".@synchronized. argument is not an object" } */ |
{ dummy++; } |
|
@synchronized ("Test") /* { dg-error ".@synchronized. argument is not an object" } */ |
{ dummy++; } |
|
@synchronized () /* { dg-error "expected" } */ |
{ dummy++; } |
|
@synchronized (int) /* { dg-error "expected" } */ |
{ dummy++; } |
|
return dummy; |
} |
/selector-2.mm
0,0 → 1,17
/* Test that we don't ICE when issuing a -Wselector warning. */ |
/* { dg-options "-Wselector" } */ |
/* { dg-do compile } */ |
|
#include <objc/objc.h> |
|
@interface Foo |
@end |
@implementation Foo |
-(void) foo |
{ |
SEL a; |
a = @selector(b1ar); |
} |
@end |
/* { dg-warning "creating selector for nonexistent method .b1ar." "" { target *-*-* } 0 } */ |
|
/template-7.mm
0,0 → 1,21
// Test that objective-c++ does not confuse a template parameter named 'Object' |
// with an interface of the same name. |
// Author: Fariborz Jahanian <fjahanian@apple.com> |
// { dg-do compile } |
// { dg-options "" } |
typedef struct objc_class *Class; |
|
@interface Object |
{ |
Class isa; |
} |
@end |
|
template <class Object> |
struct pyobject_type |
{ |
static Object* checked_downcast(Object* x) |
{ |
return x; |
} |
}; |
/try-catch-13.mm
0,0 → 1,67
/* Ensure that variables declared volatile by the user (as opposed to |
synthesized by the EH-volatization machinery) _do_ trigger |
"discards qualifiers from target pointer type" warnings. */ |
|
/* { dg-options "-fobjc-exceptions" } */ |
/* { dg-do compile } */ |
|
@interface TestMyTests |
- (void) testSpoon; |
@end |
|
extern void some_func (int *); |
|
@implementation TestMyTests |
- (void) testSpoon { |
volatile int i = 5; |
int q = 99; |
|
do { |
@try { |
typeof(i) j = 6; |
typeof(q) k = 66; |
some_func (&j); |
/* { dg-error "invalid conversion" "" { target *-*-* } 23 } */ |
/* { dg-error "initializing argument" "" { target *-*-* } 12 } */ |
some_func (&k); |
} |
@catch (id exc) { |
@throw; |
} |
} while(0); |
|
do { |
@try { |
typeof(i) j = 7; |
typeof(q) k = 77; |
some_func (&k); |
some_func (&j); |
/* { dg-error "invalid conversion" "" { target *-*-* } 38 } */ |
/* The following is disabled as it is already checked above and the testsuites seems |
to count multiple different identical errors on the same line only once */ |
/* dg-error "initializing argument" "" { target *-*-* } 12 */ |
} |
@catch (id exc) { |
@throw; |
} |
} while(0); |
|
do { |
@try { |
typeof(q) k = 88; |
typeof(i) j = 8; |
some_func (&j); |
/* { dg-error "invalid conversion" "" { target *-*-* } 53 } */ |
/* The following is disabled as it is already checked above and the testsuites seems |
to count multiple different identical errors on the same line only once */ |
/* dg-error "initializing argument" "" { target *-*-* } 12 */ |
some_func (&k); |
} |
@catch (id exc) { |
@throw; |
} |
} while(0); |
|
} |
@end |
|
/exceptions-2.mm
0,0 → 1,54
/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, November 2010. */ |
|
/* FIXME: This does not test running the code, because Objective-C exceptions at the moment |
do not execute correctly in Objective-C++. See PR objc++/23616. Once that is fixed, |
this test should be changed to use 'dg-do run' instead of just 'dg-do compile'. */ |
/* { dg-do compile } */ |
/* { dg-options "-fobjc-exceptions" } */ |
|
/* This test checks the syntax @catch (...) which catches any |
exceptions. Check that code using it runs correctly. */ |
|
#include "../objc-obj-c++-shared/TestsuiteObject.m" |
#include <stdlib.h> |
|
@interface MyObject : TestsuiteObject |
@end |
|
@implementation MyObject |
@end |
|
int test (id object) |
{ |
int i = 0; |
|
@try |
{ |
@throw object; |
} |
@catch (MyObject *o) |
{ |
i += 1; |
} |
@catch (...) |
{ |
i += 2; |
} |
@finally |
{ |
i += 4; |
} |
|
return i; |
} |
|
int main (void) |
{ |
if (test ([MyObject new]) != 5) |
abort (); |
|
if (test ([TestsuiteObject new]) != 6) |
abort (); |
|
return 0; |
} |
/basic.mm
0,0 → 1,24
// A basic sanity check for Objective-C++. |
// { dg-do run } |
/* { dg-xfail-run-if "Needs OBJC2 ABI" { *-*-darwin* && { lp64 && { ! objc2 } } } { "-fnext-runtime" } { "" } } */ |
|
#include "../objc-obj-c++-shared/TestsuiteObject.m" |
#include <iostream> |
|
@interface Greeter : TestsuiteObject |
- (void) greet: (const char *)msg; |
@end |
|
@implementation Greeter |
- (void) greet: (const char *)msg |
{ std::cout << msg << __VERSION__ << std::endl;} |
@end |
|
int |
main () |
{ |
std::cout << "Hello from C++" << __VERSION__ << std::endl; |
Greeter *obj = [Greeter new]; |
[obj greet: "Hello from Objective-C++"]; |
} |
|
/comp-types-13.mm
0,0 → 1,19
/* When assigning function pointers, allow for covariant return types |
and contravariant argument types. */ |
/* { dg-do compile } */ |
#include "../objc-obj-c++-shared/TestsuiteObject.h" |
|
@class Derived; |
|
TestsuiteObject *ExternFunc (TestsuiteObject *filePath, TestsuiteObject *key); |
typedef id FuncSignature (TestsuiteObject *arg1, Derived *arg2); |
|
@interface Derived: TestsuiteObject |
+ (void)registerFunc:(FuncSignature *)function; |
@end |
|
void foo(void) |
{ |
[Derived registerFunc: ExternFunc]; |
} |
|
/syntax-error-7.mm
0,0 → 1,13
/* { dg-do compile } */ |
|
@interface Foo |
-(void) someMethod; |
@end |
|
@implementation Foo |
-(void) |
-(void) someMethod /* { dg-error "expected before .-." } */ |
{ |
} |
@end /* { dg-warning "incomplete implementation of class" } */ |
/* { dg-warning "method definition for ..someMethod. not found" "" { target *-*-* } 12 } */ |
/stubify-1.mm
0,0 → 1,39
/* 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-skip-if "" { *-*-* } { "-fgnu-runtime" } { "" } } */ |
/* { dg-require-effective-target ilp32 } */ |
/* { dg-options "-Os -mdynamic-no-pic -fno-exceptions -mmacosx-version-min=10.4" } */ |
|
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" } } */ |
/bitfield-5.mm
0,0 → 1,29
|
/* Make sure that bitfield types are printed correctly, and that ivar redeclaration |
(@interface vs. @implementation) checks take the bitfield width into account. */ |
/* Author: Ziemowit Laski <zlaski@apple.com> */ |
/* { dg-do compile } */ |
|
@interface Base { |
int i; |
} |
@end |
|
@interface WithBitfields: Base { |
void *isa; |
unsigned a: 3; |
signed b: 4; |
int c: 5; |
} |
@end |
|
@implementation WithBitfields { |
char *isa; /* { dg-error "conflicting instance variable type .char \\*isa." } */ |
/* { dg-error "previous declaration of .void \\*isa." "" { target *-*-* } 13 } */ |
unsigned a: 5; /* { dg-error "conflicting instance variable type .unsigned( int)? a: 5." } */ |
/* { dg-error "previous declaration of .unsigned( int)? a: 3." "" { target *-*-* } 14 } */ |
signed b: 4; /* This one is fine. */ |
int c: 3; /* { dg-error "conflicting instance variable type .int c: 3." } */ |
/* { dg-error "previous declaration of .int c: 5." "" { target *-*-* } 16 } */ |
} |
@end |
/method-8.mm
0,0 → 1,30
/* Tests of duplication. */ |
/* { dg-do compile } */ |
|
@interface class1 |
- (int) meth1; /* { dg-message "previous declaration" } */ |
- (void) meth1; /* { dg-error "duplicate declaration of method .\\-meth1." } */ |
@end |
|
@interface class2 |
+ (void) meth1; /* { dg-message "previous declaration" } */ |
+ (int) meth1; /* { dg-error "duplicate declaration of method .\\+meth1." } */ |
@end |
|
@interface class3 |
- (int) meth1; |
@end |
|
@implementation class3 |
- (int) meth1 { return 0; } /* { dg-error "previously defined here" } */ |
- (int) meth1 { return 0; } /* { dg-error "redefinition of" } */ |
@end |
|
@interface class4 |
+ (void) meth1; |
@end |
|
@implementation class4 |
+ (void) meth1 {} /* { dg-error "previously defined here" } */ |
+ (void) meth1 {} /* { dg-error "redefinition of" } */ |
@end |
/gnu-api-2-class-meta.mm
0,0 → 1,327
/* Test the Modern GNU Objective-C Runtime API. |
|
This is test 'class-meta', covering calling functions starting with |
'class' but using a meta class as argument. |
|
Functions that manipulate methods (adding, replacing methods) |
usually take a meta class argument to manipulate the class methods |
instead of the instance ones. This is an important part of the API |
that needs testing. |
|
Functions that manipulate instances, instance variables, properties |
and protocols at the moment must take a normal class as argument; |
calling them with a meta class as argument is of no particular use |
and generally produces a behaviour that is undocumented and/or |
undefined (and this is true with all runtimes). As in the future |
this behaviour may be defined or documented (for example, if class |
variables are implemented as instance variables of meta classes) we |
avoid testing it for compatibility with future runtimes. */ |
|
/* { dg-do run } */ |
/* { dg-skip-if "No API#2 pre-Darwin9" { *-*-darwin[5-8]* } { "-fnext-runtime" } { "" } } */ |
/* { dg-xfail-run-if "Needs OBJC2 ABI" { *-*-darwin* && { lp64 && { ! objc2 } } } { "-fnext-runtime" } { "" } } */ |
|
/* To get the modern GNU Objective-C Runtime API, you include |
objc/runtime.h. */ |
#include <objc/runtime.h> |
#include <stdlib.h> |
#include <iostream> |
#include <cstring> |
|
@interface MyRootClass |
{ Class isa; } |
+ alloc; |
- init; |
+ initialize; |
@end |
|
@implementation MyRootClass |
+ alloc { return class_createInstance (self, 0); } |
- init { return self; } |
+ initialize { return self; } |
@end |
|
static id static_variable = nil; |
|
@interface MySubClass : MyRootClass |
+ (void) setVariable: (id)value; |
+ (id) variable; |
@end |
|
@implementation MySubClass |
+ (void) setVariable: (id)value { static_variable = value; } |
+ (id) variable { return static_variable; } |
@end |
|
@interface DifferentClass : MyRootClass |
+ (id) myClass; |
@end |
|
@implementation DifferentClass |
+ (id) myClass { return self; } |
@end |
|
@interface MySubClass (MySelf) |
+ (id) mySelf; |
@end |
|
int main () |
{ |
/* Functions are tested in alphabetical order. */ |
|
/* Calling class_addIvar() with a meta class is not documented and |
(currently) of no use. */ |
/* std::cout << "Testing class_addIvar ()...\n"; */ |
|
std::cout << "Testing class_addMethod () on a meta class...\n"; |
{ |
/* Here we test adding methods to meta classes, ie, adding class methods. */ |
Class new_class = objc_allocateClassPair (objc_getClass ("MyRootClass"), "MySubClass2", 0); |
Method method1 = class_getInstanceMethod (objc_getMetaClass ("MySubClass"), @selector (setVariable:)); |
Method method2 = class_getInstanceMethod (objc_getMetaClass ("MySubClass"), @selector (variable)); |
|
if (new_class == Nil) |
abort (); |
|
if (! class_addMethod (object_getClass (new_class), @selector (setVariable:), method_getImplementation (method1), |
method_getTypeEncoding (method1))) |
abort (); |
|
if (! class_addMethod (object_getClass (new_class), @selector (variable), method_getImplementation (method2), |
method_getTypeEncoding (method2))) |
abort (); |
|
/* Test that if the method already exists in the class, |
class_addMethod() returns NO. */ |
if (class_addMethod (object_getClass (new_class), @selector (variable), method_getImplementation (method2), |
method_getTypeEncoding (method2))) |
abort (); |
|
objc_registerClassPair (new_class); |
|
/* Now, MySubClass2 is basically the same as MySubClass! We'll |
use the +variable and +setVariable: methods on it. */ |
{ |
Class c = objc_getClass ("MySubClass2"); |
id o = [[MyRootClass alloc] init]; |
|
[c setVariable: o]; |
|
if ([c variable] != o) |
abort (); |
} |
|
/* Now, try that if you take an existing class and try to add an |
already existing method, class_addMethod returns NO. This is |
subtly different from before, when 'new_class' was still in |
construction. Now it's a real class and the libobjc internals |
differ between the two cases. */ |
if (class_addMethod (object_getClass (new_class), @selector (variable), method_getImplementation (method2), |
method_getTypeEncoding (method2))) |
abort (); |
} |
|
/* Calling class_addProtocol() on a meta class is not documented and |
(currently) of no use. */ |
/* std::cout << "Testing class_addProtocol () on a meta class...\n"; */ |
|
/* Calling class_conformsToProtocol() on a meta class is not |
documented and (currently) of no use. */ |
/* std::cout << "Testing class_conformsToProtocol () on a meta class...\n"; */ |
|
/* Calling class_copyIvarList() on a meta class is not documented |
and (currently) of no use. */ |
/* std::cout << "Testing class_copyIvarList () on a meta class...\n"; */ |
|
std::cout << "Testing class_copyMethodList () on a meta class...\n"; |
{ |
/* Test that you can copy the method list of a meta class. They |
are the class methods of the class. */ |
unsigned int count; |
Method * list = class_copyMethodList (objc_getMetaClass ("MySubClass"), &count); |
|
if (count != 2) |
abort (); |
|
if (! ((std::strcmp (sel_getName (method_getName (list[0])), "variable") == 0 |
&& std::strcmp (sel_getName (method_getName (list[1])), "setVariable:") == 0) |
|| (std::strcmp (sel_getName (method_getName (list[0])), "setVariable:") == 0 |
&& std::strcmp (sel_getName (method_getName (list[1])), "variable") == 0))) |
abort (); |
|
if (list[2] != NULL) |
abort (); |
} |
|
/* Calling class_copyPropertyList() on a meta class is not |
documented and (currently) of no use. */ |
/* std::cout << "Testing class_copyPropertyList () on a meta class...\n"; */ |
|
/* Calling class_copyProtocolList() on a meta class is not |
documented and (currently) of no use. */ |
/* std::cout << "Testing class_copyProtocolList () on a meta class...\n"; */ |
|
/* Calling class_createInstance() on a meta class is not documented |
and (currently) of no use. */ |
/* std::cout << "Testing class_createInstance () on a meta class...\n"; */ |
|
/* Calling class_getClassMethod () on a meta class is not documented |
and (currently) of no use. */ |
/* std::cout << "Testing class_getClassMethod () on a meta class...\n"; */ |
|
/* Calling class_getClassVariable () on a meta class is not |
documented and (currently) of no use. */ |
/* std::cout << "Testing class_getClassVariable () on a meta class ...\n"; */ |
|
std::cout << "Testing class_getInstanceMethod () on a meta class...\n"; |
{ |
/* The instance method of a meta class is the class method with |
the same name of the class. */ |
Method method_1 = class_getInstanceMethod (objc_getMetaClass ("MySubClass"), |
@selector(variable)); |
Method method_2 = class_getClassMethod (objc_getClass ("MySubClass"), |
@selector(variable)); |
|
if (method_1 == NULL || method_2 == NULL) |
abort (); |
|
if (method_1 != method_2) |
abort (); |
|
if (std::strcmp (sel_getName (method_getName (method_1)), "variable") != 0) |
abort (); |
} |
|
/* Calling class_getInstanceSize() with a meta class is not |
documented and (currently) of no use. */ |
/* std::cout << "Testing class_getInstanceSize () on a meta class...\n"; */ |
|
/* Calling class_getInstanceVariable() with a meta class is not |
documented and (currently) of no use. */ |
/* std::cout << "Testing class_getInstanceVariable () on a meta class...\n"; */ |
|
/* Calling class_getIvarLayout() with a meta class is not documented |
and (currently) of no use. */ |
/* std::cout << "Testing class_getIvarLayout () on a meta class...\n"; */ |
|
std::cout << "Testing class_getMethodImplementation () on a meta class...\n"; |
{ |
/* Getting the method implementation with a meta class returns a |
class method. */ |
MySubClass *object = [[MySubClass alloc] init]; |
IMP imp = class_getMethodImplementation (objc_getMetaClass ("MySubClass"), |
@selector(variable)); |
|
if (imp == NULL) |
abort (); |
|
[MySubClass setVariable: object]; |
|
if ((*imp)(objc_getClass ("MySubClass"), @selector(variable)) != object) |
abort (); |
} |
|
/* This function does not exist with the GNU runtime. */ |
/* std::cout << "Testing class_getMethodImplementation_stret () on a meta class...\n"; */ |
|
std::cout << "Testing class_getName () on a meta class...\n"; |
{ |
/* Traditionally, a meta class has the same name as the class. */ |
if (std::strcmp (class_getName (objc_getMetaClass ("MyRootClass")), |
"MyRootClass") != 0) |
abort (); |
} |
|
/* Calling class_getProperty() with a meta class is not documented |
and (currently) of no use. */ |
/* std::cout << "Testing class_getProperty ()...\n"; */ |
|
std::cout << "Testing class_getSuperclass () on a meta class...\n"; |
{ |
/* The superclass of a meta class is the meta class of the superclass. */ |
if (class_getSuperclass (objc_getMetaClass ("MySubClass")) != objc_getMetaClass ("MyRootClass")) |
abort (); |
|
/* Test that it works on a newly created, but not registered, class. */ |
{ |
Class new_class = objc_allocateClassPair (objc_getClass ("MyRootClass"), "MySubClass3", 0); |
|
if (class_getSuperclass (object_getClass (new_class)) != object_getClass (objc_getClass ("MyRootClass"))) |
abort (); |
} |
} |
|
/* Calling class_getVersion() with a meta class is not documented |
and (currently) of no use. */ |
/* std::cout << "Testing class_getVersion ()...\n"; */ |
|
/* Calling class_getWeakIvarLayout() with a meta class is not |
documented and (currently) of no use. */ |
/* std::cout << "Testing class_getWeakIvarLayout () on a meta class...\n"; */ |
|
/* class_isMetaClass() is already tested in gnu-api-2-class.m */ |
/* std::cout << "Testing class_isMetaClass ()...\n"; */ |
|
std::cout << "Testing class_replaceMethod () on a meta class...\n"; |
{ |
/* We are going to replace the [MySubclass +variable] method with |
the [DifferentClass +myClass] one. */ |
Method new_method = class_getClassMethod (objc_getClass ("DifferentClass"), |
@selector (myClass)); |
Method old_method = class_getClassMethod (objc_getClass ("MySubClass"), |
@selector (variable)); |
const char *new_types = method_getTypeEncoding (new_method); |
IMP new_imp = method_getImplementation (new_method); |
const char *old_types = method_getTypeEncoding (old_method); |
IMP old_imp = class_replaceMethod (objc_getMetaClass ("MySubClass"), @selector (variable), |
method_getImplementation (new_method), |
method_getTypeEncoding (new_method)); |
id o = [[MyRootClass alloc] init]; |
|
[MySubClass setVariable: o]; |
|
/* Try the new method implementation. */ |
if ([MySubClass variable] != objc_getClass ("MySubClass")) |
abort (); |
|
/* Put the original method back. */ |
class_replaceMethod (objc_getMetaClass ("MySubClass"), @selector (variable), |
old_imp, old_types); |
|
/* Test it's back to what it was. */ |
if ([MySubClass variable] != o) |
abort (); |
|
{ |
/* Finally, try adding a new method. */ |
class_replaceMethod (objc_getMetaClass ("DifferentClass"), @selector (mySelf), |
new_imp, new_types); |
|
if ([(Class)objc_getClass ("DifferentClass") mySelf] != objc_getClass ("DifferentClass")) |
abort (); |
} |
} |
|
std::cout << "Testing class_respondsToSelector () on a meta class...\n"; |
{ |
/* A meta class responds to a selector if and only if the class |
responds to the corresponding class method. */ |
if (! class_respondsToSelector (objc_getMetaClass ("MySubClass"), @selector(setVariable:))) |
abort (); |
|
if (class_respondsToSelector (objc_getMetaClass ("MyRootClass"), @selector(setVariable:))) |
abort (); |
} |
|
/* This is not really implemented with the GNU runtime. */ |
/* std::cout << "Testing class_setIvarLayout () on a meta class...\n"; */ |
|
/* Calling class_setVersion() with a meta class is not documented |
and (currently) of no use. */ |
/* std::cout << "Testing class_setVersion () on a meta class...\n"; */ |
|
/* This is not really implemented with the GNU runtime. */ |
/* std::cout << "Testing class_setWeakIvarLayout () on a meta class...\n"; */ |
|
return (0); |
} |
/pr28049.mm
0,0 → 1,2
/* { dg-do compile } */ |
+ /* { dg-error "expected" } */ |
/isa-field-1.mm
0,0 → 1,64
/* Ensure there are no bizarre difficulties with accessing the 'isa' field of objects. */ |
/* { dg-do compile } */ |
|
#include "../objc-obj-c++-shared/TestsuiteObject.h" |
#include "../objc-obj-c++-shared/runtime.h" |
|
@interface TestsuiteObject (Test) |
- (Class) test1: (id)object; |
@end |
|
@interface Derived: TestsuiteObject |
- (Class) test2: (id)object; |
@end |
|
@implementation TestsuiteObject (Test) |
|
Class test1(id object) { |
#ifdef __NEXT_RUNTIME__ |
Class cls = object->isa; |
#else |
Class cls = object->class_pointer; |
#endif |
return cls; |
} |
- (Class) test1: (id)object { |
#ifdef __NEXT_RUNTIME__ |
Class cls = object->isa; |
#else |
Class cls = object->class_pointer; |
#endif |
return cls; |
} |
|
@end |
|
@implementation Derived |
|
Class test2(id object) { |
#ifdef __NEXT_RUNTIME__ |
Class cls = object->isa; |
#else |
Class cls = object->class_pointer; |
#endif |
return cls; |
} |
- (Class) test2: (id)object { |
#ifdef __NEXT_RUNTIME__ |
Class cls = object->isa; |
#else |
Class cls = object->class_pointer; |
#endif |
return cls; |
} |
|
@end |
|
Class test3(id object) { |
#ifdef __NEXT_RUNTIME__ |
Class cls = object->isa; |
#else |
Class cls = object->class_pointer; |
#endif |
return cls; |
} |
/try-catch-1.mm
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-obj-c++-shared/TestsuiteObject.h" |
#include <stdio.h> |
#include <setjmp.h> |
|
@interface Frob: TestsuiteObject |
@end |
|
@implementation Frob: TestsuiteObject |
@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); |
} |
} |
/local-decl-1.mm
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-obj-c++-shared/TestsuiteObject.h" |
|
@interface Sprite: TestsuiteObject { |
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 |
/encode-4.mm
0,0 → 1,93
/* Test Objective-C method encodings. */ |
|
/* The _encoded_ parameter offsets for Objective-C methods are |
computed inductively as follows: |
- The first paramter (self) has offset 0; |
- The k-th parameter (k > 1) has offset equal to the |
sum of: |
- the offset of the k-1-st paramter |
- the (void *)-promoted size of the k-1-st parameter. |
|
Note that the encoded offsets need not correspond |
to the actual placement of parameters (relative to 'self') |
on the stack! Your target's ABI may have very different |
opinions on the matter. */ |
|
/* Contributed by Ziemowit Laski <zlaski@apple.com>. */ |
/* { dg-do run } */ |
/* { dg-xfail-run-if "Needs OBJC2 ABI" { *-*-darwin* && { lp64 && { ! objc2 } } } { "-fnext-runtime" } { "" } } */ |
#include "../objc-obj-c++-shared/TestsuiteObject.m" |
#include "../objc-obj-c++-shared/runtime.h" |
|
#include <stdio.h> |
#include <stdlib.h> |
|
#define CHECK_IF(expr) if(!(expr)) abort() |
|
@interface Foo: TestsuiteObject |
typedef struct { float x, y; } XXPoint; |
typedef struct { float width, height; } XXSize; |
typedef struct _XXRect { XXPoint origin; XXSize size; } XXRect; |
-(id)setRect:(XXRect)r withInt:(int)i; |
-(void) char:(signed char)c float:(float)f double:(double)d long:(long)l; |
@end |
|
XXRect my_rect; |
unsigned offs1, offs2, offs3, offs4, offs5, offs6, offs7; |
|
@implementation Foo |
-(id)setRect:(XXRect)r withInt:(int)i { |
unsigned offs = sizeof(self); |
CHECK_IF(offs == offs3); |
offs += sizeof(_cmd); |
CHECK_IF(offs == offs4); |
offs += sizeof(r); |
CHECK_IF(offs == offs5); |
offs += sizeof(i); |
CHECK_IF(offs == offs1); |
return nil; |
} |
-(void) char:(signed char)c float:(float)f double:(double)d long:(long)l { |
unsigned offs = sizeof(self); |
CHECK_IF(offs == offs3); |
offs += sizeof(_cmd); |
CHECK_IF(offs == offs4); |
offs += sizeof((int)c); |
CHECK_IF(offs == offs5); |
offs += sizeof(f); |
CHECK_IF(offs == offs6); |
offs += sizeof(d); |
CHECK_IF(offs == offs7); |
offs += sizeof(l); |
CHECK_IF(offs == offs1); |
} |
@end |
|
|
int main(void) { |
Foo *foo = [[Foo alloc] init]; |
Class fooClass = objc_getClass("Foo"); |
Method meth; |
const char *string; |
|
meth = class_getInstanceMethod(fooClass, @selector(setRect:withInt:)); |
offs2 = 9999; |
sscanf(method_getTypeEncoding(meth), "@%u@%u:%u{_XXRect={?=ff}{?=ff}}%ui%u", &offs1, &offs2, &offs3, |
&offs4, &offs5); |
CHECK_IF(!offs2); |
[foo setRect:my_rect withInt:123]; |
|
meth = class_getInstanceMethod(fooClass, @selector(char:float:double:long:)); |
offs2 = 9999; |
if (sizeof (long) == 8) |
string = "v%u@%u:%uc%uf%ud%uq%u"; |
else |
string = "v%u@%u:%uc%uf%ud%ul%u"; |
sscanf(method_getTypeEncoding(meth), string, &offs1, &offs2, &offs3, |
&offs4, &offs5, &offs6, &offs7); |
CHECK_IF(!offs2); |
[foo char:'c' float:2.3 double:3.5 long:2345L]; |
|
return 0; |
} |
|
/method-23.mm
0,0 → 1,44
/* Check if array and function parameters get decayed to pointers as |
they should. */ |
/* { dg-do run } */ |
/* { dg-options "-O2" } */ |
/* { dg-xfail-run-if "Needs OBJC2 ABI" { *-*-darwin* && { lp64 && { ! objc2 } } } { "-fnext-runtime" } { "" } } */ |
|
#include "../objc-obj-c++-shared/TestsuiteObject.m" |
#include <string.h> |
#include <stdlib.h> |
|
static char global_buf[20]; |
|
char *strcpy_like_callee(const char *s) { |
strcpy(global_buf, s); |
return global_buf; |
} |
|
typedef char io_string_t[512]; |
typedef char *(func_type)(const char *); |
|
@interface DeviceObject: TestsuiteObject |
- (void) func:(func_type)func stucPathInIORegistry:(io_string_t)ioRegPath; |
@end |
@implementation DeviceObject |
- (void) func:(func_type)func stucPathInIORegistry:(io_string_t)ioRegPath |
{ |
func(ioRegPath); |
} |
@end |
|
int main (void) { |
io_string_t my_string; |
DeviceObject *obj = [DeviceObject new]; |
|
strcpy (my_string, "Hello!"); |
strcpy (global_buf, "Good-bye!"); |
|
[obj func:strcpy_like_callee stucPathInIORegistry:my_string]; |
|
if (strcmp (global_buf, "Hello!")) |
abort (); |
|
return 0; |
} |
/comp-types-7.mm
0,0 → 1,38
/* Test assignments and comparisons involving category protocols. */ |
/* Author: Nicola Pero <nicola@brainstorm.co.uk>. */ |
/* { dg-do compile } */ |
|
#include <objc/objc.h> |
|
@protocol MyProtocol |
- (void) method; |
@end |
|
@interface MyClass |
@end |
|
@interface MyClass (Addition) <MyProtocol> |
- (void) method; |
@end |
|
@interface MyOtherClass : MyClass |
@end |
|
int main() |
{ |
id <MyProtocol> obj_p = nil; |
MyClass *obj_cp = nil; |
MyOtherClass *obj_cp2 = nil; |
|
obj_cp = obj_p; /* { dg-warning "distinct Objective\\-C type" } */ |
obj_cp2 = obj_p; /* { dg-warning "distinct Objective\\-C type" } */ |
obj_p = obj_cp; /* Ok */ |
obj_p = obj_cp2; /* Ok */ |
|
if (obj_cp == obj_p) ; /* Ok */ |
if (obj_cp2 == obj_p) ; /* Ok */ |
if (obj_p == obj_cp) ; /* Ok */ |
if (obj_p == obj_cp2) ; /* Ok */ |
|
return 0; |
} |
/try-catch-9.mm
0,0 → 1,69
/* 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-do run } */ |
/* { dg-xfail-run-if "PR23616" { *-*-* } { "-fgnu-runtime" } { "-fnext-runtime" } } */ |
/* { dg-xfail-if "Needs OBJC2 ABI" { *-*-darwin* && { lp64 && { ! objc2 } } } { "-fnext-runtime" "-fgnu-runtime" } { "" } } |
/* { dg-prune-output ".*internal compiler error.*" } */ |
/* { dg-options "-fobjc-exceptions -O2" } */ |
|
#include "../objc-obj-c++-shared/TestsuiteObject.m" |
#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 = [TestsuiteObject new]; |
arg1 = 17; |
arg2 = &gf2; |
|
@throw [TestsuiteObject new]; |
} |
@catch (TestsuiteObject *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; |
} |
|
/method-17.mm
0,0 → 1,33
/* When there is only one candidate method available, make sure the |
compiler uses its argument/return types when constructing the |
message sends (so that proper C/C++ argument conversions may |
take place). */ |
/* { dg-do run } */ |
/* { dg-xfail-run-if "Needs OBJC2 ABI" { *-*-darwin* && { lp64 && { ! objc2 } } } { "-fnext-runtime" } { "" } } */ |
#include "../objc-obj-c++-shared/TestsuiteObject.m" |
#include <stdlib.h> |
|
#define CHECK_IF(expr) if(!(expr)) abort() |
|
static double d = 4.5920234e2; |
|
@interface Foo : TestsuiteObject |
-(void) brokenType: (int)x floatingPoint: (double)y; |
@end |
|
|
@implementation Foo |
-(void) brokenType: (int)x floatingPoint: (double)y |
{ |
CHECK_IF(x == 459); |
CHECK_IF(y == d); |
} |
@end |
|
int main(void) |
{ |
Foo *foo=[Foo new]; |
[foo brokenType: (int)d floatingPoint: d]; |
return 0; |
} |
|
/naming-1.mm
0,0 → 1,31
/* Testing for detecting duplicate ivars. */ |
/* { dg-do compile } */ |
|
typedef struct S { int i; } NSDictionary; |
|
@interface A |
{ |
NSDictionary * _userInfo1; /* { dg-message "previous declaration" } */ |
NSDictionary * _userInfo2; /* { dg-message "previous declaration" } */ |
NSDictionary * _userInfo3; /* { dg-message "previous declaration" } */ |
NSDictionary * _userInfo4; /* { dg-message "previous declaration" } */ |
} |
@end |
|
@interface B : A |
{ |
NSDictionary * _userInfo1; /* { dg-error "duplicate instance variable" } */ |
NSDictionary * _userInfo2; /* { dg-error "duplicate instance variable" } */ |
} |
@end |
|
@interface C : A |
@end |
|
@interface D : C |
{ |
NSDictionary * _userInfo3; /* { dg-error "duplicate instance variable" } */ |
NSDictionary * _userInfo4; /* { dg-error "duplicate instance variable" } */ |
} |
@end |
|
/lookup-1.mm
0,0 → 1,8
/* Simple test to check Objectivec-C++ qualified type lookup. */ |
/* Devang Patel <dpatel@apple.com>. */ |
|
@interface A |
{ |
A *ap; |
} |
@end |
/no-extra-load.mm
0,0 → 1,24
// Radar 3926484 |
|
// { dg-do compile } |
|
#include "../objc-obj-c++-shared/TestsuiteObject.h" |
#include <iostream> |
|
@interface Greeter : TestsuiteObject |
- (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" } } */ |
/template-2.mm
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; |
/property/at-property-15.mm
0,0 → 1,20
/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, November 2010. */ |
/* { dg-do compile } */ |
/* { dg-options "-Wno-property-assign-default" } */ |
|
#include <objc/objc.h> |
|
/* Test that -Wno-property-assign-default turns off all "object |
property xxx has no assign, return or copy attribute" warnings. */ |
|
@interface MyRootClass |
{ |
Class isa; |
} |
|
@property id property_a; /* Would normally generate a warning. */ |
@property (readonly) id property_b; |
@property id *property_c; |
@property Class property_d; |
@property MyRootClass *property_e; /* Would normally generate a warning. */ |
@end |
/property/synthesize-7.mm
0,0 → 1,86
/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, November 2010. */ |
/* { dg-do run } */ |
/* { dg-xfail-run-if "Needs OBJC2 ABI" { *-*-darwin* && { lp64 && { ! objc2 } } } { "-fnext-runtime" } { "" } } */ |
|
/* Test @synthesize with protocols of protocols. */ |
|
#include <stdlib.h> |
#include <objc/objc.h> |
#include <objc/runtime.h> |
|
@protocol ProtocolA |
@property int countA; |
@end |
|
@protocol ProtocolB <ProtocolA> |
@property int countB; |
@end |
|
@protocol ProtocolC <ProtocolB> |
@property int countC; |
@end |
|
@protocol ProtocolD |
@property int countD; |
@end |
|
@interface MyRootClass <ProtocolC> |
{ |
Class isa; |
int countA; |
int countB; |
int countC; |
} |
+ (id) initialize; |
+ (id) alloc; |
- (id) init; |
@end |
|
@implementation MyRootClass |
+ (id) initialize { return self; } |
+ (id) alloc { return class_createInstance (self, 0); } |
- (id) init { return self; } |
@synthesize countA; |
@synthesize countB; |
@synthesize countC; |
@end |
|
@interface MySubClass : MyRootClass <ProtocolD> |
{ |
int countD; |
} |
@end |
|
@implementation MySubClass |
@synthesize countD; |
@end |
|
int main (void) |
{ |
MySubClass *object = [[MySubClass alloc] init]; |
int i; |
|
for (i = 0; i < 10; i++) |
{ |
object.countA += i; |
object.countB += i + 1; |
object.countC += i + 2; |
object.countD += i + 3; |
} |
|
if (object.countA != 45) |
abort (); |
|
if (object.countB != 55) |
abort (); |
|
if (object.countC != 65) |
abort (); |
|
if (object.countD != 75) |
abort (); |
|
return 0; |
} |
|
|
/property/at-property-25.mm
0,0 → 1,87
/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, November 2010. */ |
/* { dg-do compile } */ |
|
/* Test warnings and non-warnings with @optional @properties. */ |
|
#include <stdlib.h> |
#include <objc/objc.h> |
#include <objc/runtime.h> |
|
@interface MyRootClass |
{ |
Class isa; |
} |
+ (id) initialize; |
+ (id) alloc; |
- (id) init; |
@end |
|
@implementation MyRootClass |
+ (id) initialize { return self; } |
+ (id) alloc { return class_createInstance (self, 0); } |
- (id) init { return self; } |
@end |
|
@protocol count |
@optional |
@property int count1; |
@property (readonly) int count2; |
@end |
|
|
/* A class that implements all the properties. */ |
@interface MySubClass1 : MyRootClass <count> |
{ |
int count1; |
int count2; |
} |
@end |
|
@implementation MySubClass1 |
@synthesize count1; |
@synthesize count2; |
@end |
|
|
/* A class that implements nothing; no warnings as the properties are |
all optional. */ |
@interface MySubClass2 : MyRootClass <count> |
@end |
|
@implementation MySubClass2 |
@end |
|
|
@protocol count2 |
@required |
@property int count1; |
@property (readonly) int count2; |
@end |
|
/* A class that implements all the properties. */ |
@interface MySubClass3 : MyRootClass <count2> |
{ |
int count1; |
int count2; |
} |
@end |
|
@implementation MySubClass3 |
@synthesize count1; |
@synthesize count2; |
@end |
|
|
/* A class that implements nothing; warnings as the properties are |
all required. */ |
@interface MySubClass4 : MyRootClass <count2> |
@end |
|
@implementation MySubClass4 |
@end |
|
/* { dg-warning "incomplete implementation of class" "" { target *-*-* } 81 } */ |
/* { dg-warning "method definition for ..setCount1:. not found" "" { target *-*-* } 81 } */ |
/* { dg-warning "method definition for ..count1. not found" "" { target *-*-* } 81 } */ |
/* { dg-warning "method definition for ..count2. not found" "" { target *-*-* } 81 } */ |
/* { dg-warning "class .MySubClass4. does not fully implement the .count2. protocol" "" { target *-*-* } 81 } */ |
/property/dotsyntax-11.mm
0,0 → 1,61
/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, November 2010. */ |
/* { dg-do compile } */ |
|
/* Test the error reporting for the dot-syntax in the scenario where |
we have a setter, but not a getter, yet a getter is requested. */ |
|
#include <stdlib.h> |
#include <objc/objc.h> |
#include <objc/runtime.h> |
|
static int c; |
|
@interface MyRootClass |
{ |
Class isa; |
int a; |
} |
+ (id) initialize; |
+ (id) alloc; |
- (id) init; |
- (void) setCount: (int)count; |
+ (void) setClassCount: (int)count; |
@end |
|
@implementation MyRootClass |
+ (id) initialize { return self; } |
+ (id) alloc { return class_createInstance (self, 0); } |
- (id) init { return self; } |
- (void) setCount: (int)count |
{ |
a = count; |
} |
+ (void) setClassCount: (int)count |
{ |
c = count; |
} |
@end |
|
@interface MySubClass : MyRootClass |
+ (int) testMe; |
- (int) testMe; |
@end |
|
@implementation MySubClass |
- (int) testMe |
{ |
super.count = 400; |
if (super.count != 400) /* { dg-error "no .count. getter found" } */ |
abort (); |
|
return super.count; /* { dg-error "no .count. getter found" } */ |
} |
+ (int) testMe |
{ |
super.classCount = 4000; |
if (super.classCount != 4000) /* { dg-error "no .classCount. getter found" } */ |
abort (); |
|
return super.classCount; /* { dg-error "no .classCount. getter found" } */ |
} |
@end |
/property/at-property-19.mm
0,0 → 1,74
/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, October 2010. */ |
/* { dg-do run } */ |
/* { dg-xfail-run-if "Needs OBJC2 ABI" { *-*-darwin* && { lp64 && { ! objc2 } } } { "-fnext-runtime" } { "" } } */ |
|
/* Test looking up a @property in a protocol of a category of a superclass. */ |
|
#include <stdlib.h> |
#include <objc/objc.h> |
#include <objc/runtime.h> |
|
@interface MyRootClass |
{ |
Class isa; |
int a; |
} |
+ (id) initialize; |
+ (id) alloc; |
- (id) init; |
@end |
|
@implementation MyRootClass |
+ (id) initialize { return self; } |
+ (id) alloc { return class_createInstance (self, 0); } |
- (id) init { return self; } |
@end |
|
/* Use a different getter/setter, so that the only way to compile |
object.count is to find the actual @property. */ |
@protocol count |
@property (getter=number, setter=setNumber:) int count; |
@end |
|
@interface MySubClass : MyRootClass |
- (int) testMe; |
@end |
|
@interface MySubClass (Category) <count> |
@end |
|
@implementation MySubClass (Category) |
- (int) number |
{ |
return a; |
} |
- (void) setNumber: (int)count |
{ |
a = count; |
} |
@end |
|
@implementation MySubClass |
- (int) testMe |
{ |
self.count = 400; |
if (self.count != 400) |
abort (); |
|
return self.count; |
} |
@end |
|
int main (void) |
{ |
MySubClass *object = [[MySubClass alloc] init]; |
|
object.count = 44; |
if (object.count != 44) |
abort (); |
|
if ([object testMe] != 400) |
abort (); |
|
return 0; |
} |
/property/fsf-property-method-access.mm
0,0 → 1,75
/* test access in methods, auto-generated getter/setter based on property name. */ |
/* { dg-do run } */ |
/* { dg-xfail-run-if "Needs OBJC2 ABI" { *-*-darwin* && { lp64 && { ! objc2 } } } { "-fnext-runtime" } { "" } } */ |
|
#ifdef __cplusplus |
extern "C" { |
#endif |
|
extern int printf (const char *fmt,...); |
extern void abort (void); |
|
#include <objc/objc.h> |
#include <objc/runtime.h> |
|
#ifdef __cplusplus |
} |
#endif |
|
@interface Bar |
{ |
@public |
Class isa; |
int FooBar; |
} |
+ (id) initialize; |
+ (id) alloc ; |
- (id) init; |
|
- (int) lookAtProperty; |
- (void) setProperty: (int) v; |
|
@property int FooBar; |
@end |
|
@implementation Bar |
|
+initialize { return self;} |
+ (id) alloc { return class_createInstance(self, 0);} |
|
- (id) init {return self;} |
|
@synthesize FooBar; |
|
- (int) lookAtProperty { return FooBar; } |
- (void) setProperty: (int) v { FooBar = v; } |
|
@end |
|
int main(int argc, char *argv[]) { |
int res; |
Bar *f = [[Bar alloc] init]; |
|
/* First, establish that the property getter & setter have been synthesized |
and operate correctly. */ |
[f setProperty:11]; |
|
if (f.FooBar != 11) |
{ printf ("setProperty did not set FooBar\n"); abort ();} |
|
res = [f lookAtProperty]; |
if (res != 11 ) |
{ printf ("[f lookAtProperty] = %d\n", res); abort ();} |
|
/* Make sure we haven't messed up the shortcut form. */ |
/* read ... */ |
res = f.FooBar; |
if (res != 11 ) |
{ printf ("f.FooBar = %d\n", res); abort ();} |
|
/* ... write. */ |
f.FooBar = 0; |
/* printf ("seems OK\n", res); */ |
return f.FooBar; |
} |
|
/property/dotsyntax-21.mm
0,0 → 1,113
/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, November 2010. */ |
/* { dg-do run } */ |
/* { dg-xfail-run-if "Needs OBJC2 ABI" { *-*-darwin* && { lp64 && { ! objc2 } } } { "-fnext-runtime" } { "" } } */ |
|
/* Test dot-syntax with super in a category. */ |
|
#include <stdlib.h> |
#include <objc/objc.h> |
#include <objc/runtime.h> |
|
@interface MyRootClass |
{ |
Class isa; |
int a; |
} |
+ (id) initialize; |
+ (id) alloc; |
- (id) init; |
- (int) count; |
- (void) setCount: (int)count; |
@end |
|
@implementation MyRootClass |
+ (id) initialize { return self; } |
+ (id) alloc { return class_createInstance (self, 0); } |
- (id) init { return self; } |
- (int) count |
{ |
return a; |
} |
- (void) setCount: (int)count |
{ |
a = count; |
} |
@end |
|
/* First, test 'super' in the main implementation of a subclass. */ |
@interface MySubClass : MyRootClass |
- (int) superCount; |
- (void) setSuperCount: (int)count; |
@end |
|
@implementation MySubClass |
- (int) superCount |
{ |
return super.count; |
} |
- (void) setSuperCount: (int)count |
{ |
super.count = count; |
} |
@end |
|
/* Now, test 'super' in a category of a subclass. */ |
@interface MySubClass (Category) |
- (int) superCount2; |
- (void) setSuperCount2: (int)count; |
- (int) test: (int)x; |
@end |
|
@implementation MySubClass (Category) |
- (int) superCount2 |
{ |
return super.count; |
} |
- (void) setSuperCount2: (int)count |
{ |
super.count = count; |
} |
- (int) test: (int)x |
{ |
/* For positive x, the following will leave super.count |
unchanged. */ |
super.count++; |
--super.count; |
|
super.count = (x < 0 ? x : super.count); |
|
if ((x = super.count)) |
super.count += 1; |
|
if ((x = super.count)) |
super.count -= 1; |
|
/* Finally, also put a bit of self.count in the mix. */ |
self.count++; |
super.count--; |
|
return super.count; |
} |
@end |
|
int main (void) |
{ |
MySubClass *object = [[MySubClass alloc] init]; |
|
object.count = 10; |
if (object.count != 10) |
abort (); |
|
object.superCount = 11; |
if (object.superCount != 11) |
abort (); |
|
object.superCount2 = 12; |
if (object.superCount2 != 12) |
abort (); |
|
if ([object test: 45] != 12) |
abort (); |
|
return 0; |
} |
/property/at-property-29.mm
0,0 → 1,14
/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, January 2011. */ |
/* { dg-do compile } */ |
|
#include <objc/objc.h> |
|
@interface MyRootClass |
{ |
Class isa; |
} |
/* Test missing '=' in setter/getter attributes. */ |
@property (getter) int property_a; /* { dg-error "missing .=. .after .getter. attribute." } */ |
@property (setter) int property_b; /* { dg-error "missing .=. .after .setter. attribute." } */ |
@property (assign, getter) int property_c; /* { dg-error "missing .=. .after .getter. attribute." } */ |
@end |
/property/dotsyntax-15.mm
0,0 → 1,80
/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, November 2010. */ |
/* { dg-do compile } */ |
|
/* Test dot-syntax with accessors to be looked up in protocols. */ |
|
#include <stdlib.h> |
#include <objc/objc.h> |
#include <objc/runtime.h> |
|
@protocol ProtocolA |
- (int) countA; |
- (void) setCountA: (int)aNumber; |
@end |
|
@protocol ProtocolB |
- (int) countB; |
- (void) setCountB: (int)aNumber; |
@end |
|
@protocol ProtocolC |
- (int) countC; |
- (void) setCountC: (int)aNumber; |
@end |
|
@interface MyRootClass |
{ |
Class isa; |
} |
+ (id) initialize; |
+ (id) alloc; |
- (id) init; |
@end |
|
@interface MySubClass <ProtocolA, ProtocolB, ProtocolC> |
@end |
|
int function (MySubClass *object, int x) |
{ |
object.countA = x; |
object.countB = x; |
object.countC = object.countB; |
|
return object.countC; |
} |
|
int function2 (MyRootClass <ProtocolA, ProtocolB, ProtocolC> *object, int x) |
{ |
object.countA = x; |
object.countB = x; |
object.countC = object.countB; |
|
return object.countC; |
} |
|
int function3 (MyRootClass <ProtocolA, ProtocolB> *object, int x) |
{ |
object.countA = x; |
object.countB = x; |
object.countC = object.countB; /* { dg-error "request for member .countC. in" } */ |
|
return object.countC; /* { dg-error "request for member .countC. in" } */ |
} |
|
int function4 (id <ProtocolA, ProtocolB, ProtocolC> object, int x) |
{ |
object.countA = x; |
object.countB = x; |
object.countC = object.countB; |
|
return object.countC; |
} |
|
int function5 (id <ProtocolA, ProtocolB> object, int x) |
{ |
object.countA = x; |
object.countB = x; |
object.countC = object.countB; /* { dg-error "request for member .countC. in" } */ |
|
return object.countC; /* { dg-error "request for member .countC. in" } */ |
} |
/property/dotsyntax-19.mm
0,0 → 1,113
/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, November 2010. */ |
/* { dg-do run } */ |
/* { dg-xfail-run-if "Needs OBJC2 ABI" { *-*-darwin* && { lp64 && { ! objc2 } } } { "-fnext-runtime" } { "" } } */ |
|
/* Test dot-syntax with more tricky assignments. */ |
|
#include <stdlib.h> |
#include <objc/objc.h> |
#include <objc/runtime.h> |
|
@interface MyRootClass |
{ |
Class isa; |
id a; |
id b; |
int p1; |
float p2; |
} |
+ (id) initialize; |
+ (id) alloc; |
- (id) init; |
|
@property (assign) id object1; |
@property (assign) id object2; |
- (id) test; |
- (id) myself; |
- (id) nilObject; |
|
@property int p1; |
@property float p2; |
@end |
|
@implementation MyRootClass |
+ (id) initialize { return self; } |
+ (id) alloc { return class_createInstance (self, 0); } |
- (id) init { return self; } |
@synthesize object1 = a; |
@synthesize object2 = b; |
- (id) test |
{ |
/* Test multiple assignments with 'self'. */ |
self.object1 = self.object2 = self; |
|
if (self.object1 != self || self.object2 != self) |
abort (); |
|
/* Test multiple assignments with a conditional and method calls. */ |
self.object1 = self.object2 = (self ? [self myself] : [self nilObject]); |
|
if (self.object1 != self || self.object2 != self) |
abort (); |
|
self.object1 = self.object2 = (self ? [self nilObject] : [self myself]); |
|
if (self.object1 != nil || self.object2 != nil) |
abort (); |
|
return self.object1; |
} |
- (id) myself |
{ |
return self; |
} |
- (id) nilObject |
{ |
return nil; |
} |
|
@synthesize p1; |
@synthesize p2; |
@end |
|
int main (void) |
{ |
MyRootClass *object = [[MyRootClass alloc] init]; |
MyRootClass *object1 = [[MyRootClass alloc] init]; |
|
[object test]; |
|
/* Now, test multiple assignments with different types. Use |
int/float as they seem to happily crash the compiler in gimplify |
if proper conversions are not being generated by the |
frontend. ;-) */ |
object.p1 = object.p2 = 12; |
|
if (object.p1 != 12 || object.p2 != 12) |
abort (); |
|
object.p1 = object.p2 = 2.7; |
|
if (object.p1 != 2) |
abort (); |
|
/* Just try a different loop, mixing in a few different standard C |
constructs to cover a few other cases. */ |
object.p1 = 10; |
object1.p1 = 0; |
while (object.p1) |
{ |
object1.p1 += ((object.p2 = 4.56) ? 0 : object.p1); |
object.p1--; |
} |
|
if (object.p1 != 0 || object1.p1 != 0) |
abort (); |
|
if ((object.p1 = 0)) |
abort (); |
|
return 0; |
} |
|
|
/property/dynamic-3.mm
0,0 → 1,49
/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, November 2010. */ |
/* { dg-do compile } */ |
|
#include <objc/objc.h> |
|
@interface MyRootClass |
{ |
Class isa; |
} |
@end |
|
@implementation MyRootClass |
@end |
|
/* Test @property/@dynamic in a category. First, a case where |
@dynamic should turn off all warnings. */ |
|
@interface MyRootClass (Category) |
@property int a; |
- (int) test; |
@end |
@implementation MyRootClass (Category) |
@dynamic a; |
- (int) test |
{ |
return self.a; /* This should compile into [self a] with no warnings. */ |
} |
@end |
|
|
|
/* Test @property/@dynamic in a category. Second, a case with a |
missing setter and no @dynamic. A warning should be generated. */ |
|
@interface MyRootClass (Category2) |
@property int b; |
- (int) test; |
@end |
@implementation MyRootClass (Category2) |
- (int) b |
{ |
return 0; |
} |
- (int) test |
{ |
return self.b; |
} |
@end /* { dg-warning "incomplete implementation" } */ |
/* { dg-warning "method definition for .-setB:. not found" "" { target *-*-* } 48 } */ |
/property/at-property-3.mm
0,0 → 1,15
/* { dg-do compile } */ |
|
#include <objc/objc.h> |
|
@interface MyRootClass |
{ |
Class isa; |
} |
@property volatile int a; /* This is allowed */ |
@property extern int b; /* { dg-error "invalid type" } */ |
@property static int c; /* { dg-error "invalid type" } */ |
@property inline int d; /* { dg-error "declared as an .inline." } */ |
@property typedef int e; /* { dg-error "invalid type" } */ |
@property __thread int f; /* { dg-error "invalid type" } */ |
@end |
/property/dotsyntax-deprecated-1.mm
0,0 → 1,41
/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, October 2010. */ |
/* { dg-do compile } */ |
|
/* Test the 'dot syntax' with deprecated methods. */ |
|
#include <objc/objc.h> |
|
@interface MyClass |
{ |
Class isa; |
} |
+ (int) classCount __attribute__ ((deprecated)); |
+ (void) setClassCount: (int)value __attribute__ ((deprecated)); |
|
- (int) count __attribute__ ((deprecated)); |
- (void) setCount: (int)value __attribute__ ((deprecated)); |
|
- (int) classCount2; |
- (void) setClassCount2: (int)value; |
|
- (int) count2; |
- (void) setCount2: (int)value; |
@end |
|
void foo (void) |
{ |
MyClass *object = nil; |
|
|
if (object.count > 0) /* { dg-warning "is deprecated" } */ |
object.count = 20; /* { dg-warning "is deprecated" } */ |
|
if (MyClass.classCount < -7) /* { dg-warning "is deprecated" } */ |
MyClass.classCount = 11; /* { dg-warning "is deprecated" } */ |
|
if (object.classCount2 > 0) |
object.classCount2 = 19; |
|
if (object.count2 < -7) |
object.count2 = 74; |
} |
/property/property-neg-1.mm
0,0 → 1,13
/* { dg-do compile } */ |
|
@interface Bar |
{ |
int iVar; |
} |
@property int fooBar; |
@end |
|
@implementation Bar |
@end /* { dg-warning "incomplete implementation of class .Bar." } */ |
/* { dg-warning "method definition for .-setFooBar:. not found" "" { target *-*-* } 11 } */ |
/* { dg-warning "method definition for .-fooBar. not found" "" { target *-*-* } 11 } */ |
/property/at-property-7.mm
0,0 → 1,58
/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, October 2010. */ |
/* { dg-do run } */ |
/* { dg-xfail-run-if "Needs OBJC2 ABI" { *-*-darwin* && { lp64 && { ! objc2 } } } { "-fnext-runtime" } { "" } } */ |
|
/* Test the property syntax with non-synthesized setter/getter |
and with a non-standard name for the getter. */ |
|
#include <stdlib.h> |
#include <objc/objc.h> |
#include <objc/runtime.h> |
|
@interface MyRootClass |
{ |
Class isa; |
int a; |
} |
@property (getter = getA, nonatomic) int a; |
+ (id) initialize; |
+ (id) alloc; |
- (id) init; |
@end |
|
@implementation MyRootClass |
+ (id) initialize { return self; } |
+ (id) alloc { return class_createInstance (self, 0); } |
- (id) init { return self; } |
|
- (int) getA |
{ |
return a; |
} |
- (void) setA: (int)value |
{ |
a = value; |
} |
@end |
|
int main (void) |
{ |
MyRootClass *object = [[MyRootClass alloc] init]; |
|
object.a = 14; |
|
if (object.a != 14) |
abort (); |
|
object.a = 23; |
|
if (object.a != 23) |
abort (); |
|
object.a = 78; |
|
if (object.a != 78) |
abort (); |
|
return (0); |
} |
/property/property-neg-5.mm
0,0 → 1,5
/* { dg-do compile } */ |
|
@interface Foo |
@property ( readonly, getter = HELLO, setter = THERE : ) int value; /* { dg-error ".readonly. attribute conflicts with .setter. attribute" } */ |
@end |
/property/dotsyntax-4.mm
0,0 → 1,44
/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, November 2010. */ |
/* { dg-do compile } */ |
|
/* Test the 'dot syntax' without a declarated property. This tests |
syntax errors in the case where the object is a Class. */ |
|
|
#include <stdlib.h> |
#include <objc/objc.h> |
#include <objc/runtime.h> |
|
@interface MyRootClass |
{ |
Class isa; |
} |
+ (id) initialize; |
+ (id) alloc; |
- (id) init; |
@end |
|
@implementation MyRootClass |
+ (id) initialize { return self; } |
+ (id) alloc { return class_createInstance (self, 0); } |
- (id) init { return self; } |
@end |
|
int main (void) |
{ |
MyRootClass.invalid = 40; /* { dg-error "could not find setter.getter" } */ |
if (MyRootClass.invalid != 40) /* { dg-error "could not find setter.getter" } */ |
abort (); |
|
MyRootClass.; /* { dg-error "expected identifier" } */ |
if (MyRootClass.) /* { dg-error "expected identifier" } */ |
abort (); |
|
MyRootClass.int; /* { dg-error "expected identifier" } */ |
/* { dg-error "expected" "" { target *-*-* } 37 } */ |
if (MyRootClass.int) /* { dg-error "expected identifier" } */ |
/* { dg-error "expected" "" { target *-*-* } 39 } */ |
abort (); |
|
return 0; |
} |
/property/dotsyntax-8.mm
0,0 → 1,62
/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, November 2010. */ |
/* { dg-do run } */ |
/* { dg-xfail-run-if "Needs OBJC2 ABI" { *-*-darwin* && { lp64 && { ! objc2 } } } { "-fnext-runtime" } { "" } } */ |
|
/* Test the 'dot syntax' with typedefs. */ |
|
#include <stdlib.h> |
#include <objc/objc.h> |
#include <objc/runtime.h> |
|
static int c; |
|
@interface MyRootClass |
{ |
Class isa; |
int a; |
} |
+ (id) initialize; |
+ (id) alloc; |
- (id) init; |
- (int) count; |
- (void) setCount: (int)count; |
+ (int) classCount; |
+ (void) setClassCount: (int)count; |
@end |
|
@implementation MyRootClass |
+ (id) initialize { return self; } |
+ (id) alloc { return class_createInstance (self, 0); } |
- (id) init { return self; } |
- (int) count |
{ |
return a; |
} |
- (void) setCount: (int)count |
{ |
a = count; |
} |
+ (int) classCount |
{ |
return c; |
} |
+ (void) setClassCount: (int)count |
{ |
c = count; |
} |
@end |
|
typedef MyRootClass MyType; |
|
int main (void) |
{ |
MyType *object = [[MyRootClass alloc] init]; |
|
object.count = 1974; |
if (object.count != 1974) |
abort (); |
|
return 0; |
} |
|
|
/property/synthesize-2.mm
0,0 → 1,52
/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, October 2010. */ |
/* { dg-do run } */ |
/* { dg-xfail-run-if "Needs OBJC2 ABI" { *-*-darwin* && { lp64 && { ! objc2 } } } { "-fnext-runtime" } { "" } } */ |
|
#include <objc/objc.h> |
#include <objc/runtime.h> |
#include <stdlib.h> |
|
@interface MyRootClass |
{ |
Class isa; |
} |
+ (id) initialize; |
+ (id) alloc; |
- (id) init; |
@end |
|
@implementation MyRootClass |
+ (id) initialize { return self; } |
+ (id) alloc { return class_createInstance (self, 0); } |
- (id) init { return self; } |
@end |
|
@interface Test : MyRootClass |
{ |
int v1; |
} |
@property int v1; |
/* TODO: Test more types of properties with different semantics |
(retain, copy, atomic, nonatomic, and test various C and |
Objective-C types). */ |
@end |
|
@implementation Test |
@synthesize v1; |
@end |
|
int main () |
{ |
Test *object = [[Test alloc] init]; |
|
/* Check that the synthesized methods exist and work. Do not invoke |
them via property syntax - that is another test. Here we just |
want to test the synthesis of the methods. */ |
[object setV1: 400]; |
|
if ([object v1] != 400) |
abort (); |
|
return (0); |
} |
|
/property/at-property-10.mm
0,0 → 1,97
/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, October 2010. */ |
/* { dg-do run } */ |
/* { dg-xfail-run-if "Needs OBJC2 ABI" { *-*-darwin* && { lp64 && { ! objc2 } } } { "-fnext-runtime" } { "" } } */ |
|
/* Test the property syntax in a number of expressions. */ |
|
#include <stdlib.h> |
#include <objc/objc.h> |
#include <objc/runtime.h> |
|
@interface MyRootClass |
{ |
Class isa; |
int a; |
} |
@property (nonatomic) int a; |
+ (id) initialize; |
+ (id) alloc; |
- (id) init; |
@end |
|
@implementation MyRootClass |
+ (id) initialize { return self; } |
+ (id) alloc { return class_createInstance (self, 0); } |
- (id) init { return self; } |
@synthesize a; |
@end |
|
int |
test (int g) |
{ |
return g; |
} |
|
int main (void) |
{ |
MyRootClass *object = [[MyRootClass alloc] init]; |
MyRootClass *object2 = [[MyRootClass alloc] init]; |
|
object.a = 14; |
object.a = object.a + object.a; |
|
if (object.a != 28) |
abort (); |
|
object.a = 99; |
object.a++; |
|
if (object.a != 100) |
abort (); |
|
object.a = 99; |
object.a *= 2; |
|
if (object.a != 198) |
abort (); |
|
{ |
int f = object.a; |
|
if (f != 198) |
abort (); |
|
if (f != object.a) |
abort (); |
|
if (object.a != f) |
abort (); |
|
object.a = object.a; |
|
if (object.a != 198) |
abort (); |
} |
|
if (test (object.a) != 198) |
abort (); |
|
object.a = -object.a; |
|
if (object.a != -198) |
abort (); |
|
for (object.a = 0; object.a < 99; object.a++) |
object2.a = object.a; |
|
if (object2.a != object.a - 1) |
abort (); |
|
if (object2.a != 98) |
abort (); |
|
if (object.a != 99) |
abort (); |
|
return (0); |
} |
/property/at-property-20.mm
0,0 → 1,81
/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, November 2010. */ |
/* { dg-do compile } */ |
|
#include <objc/objc.h> |
|
/* Test that if you have a property declared in a class and a |
sub-class, the types match (unless it's a readonly property, in |
which case a "specialization" is enough). */ |
|
@protocol MyProtocolA |
- (void) doNothingA; |
@end |
|
@protocol MyProtocolB |
- (void) doNothingB; |
@end |
|
@interface MyRootClass |
{ |
Class isa; |
} |
@end |
|
@interface MySubClass1 : MyRootClass |
@end |
|
@interface MySubClass2 : MyRootClass |
@end |
|
@interface MySubClass3 : MyRootClass <MyProtocolA> |
@end |
|
@interface MySubClass4 : MySubClass1 |
@end |
|
/* Now, the test. */ |
|
@interface MyClass : MyRootClass |
{ } |
@property (assign) id <MyProtocolA> a; /* { dg-message "originally specified here" } */ |
@property int b; /* { dg-message "originally specified here" } */ |
@property float c; /* { dg-message "originally specified here" } */ |
@property (assign) MyRootClass *d; /* { dg-message "originally specified here" } */ |
@property (assign) MySubClass1 *e; /* { dg-message "originally specified here" } */ |
@property (assign, readonly) MySubClass1 *f; /* { dg-message "originally specified here" } */ |
@property (assign) MySubClass3 *g; /* { dg-message "originally specified here" } */ |
@property (assign, readonly) MySubClass3 *h; /* { dg-message "originally specified here" } */ |
@end |
|
/* The following are all OK because they are identical. */ |
@interface MyClass2 : MyClass |
{ } |
@property (assign) id a; |
@property int b; |
@property float c; |
@property (assign) MyRootClass *d; |
@property (assign) MySubClass1 *e; |
@property (assign, readonly) MySubClass1 *f; |
@property (assign) MySubClass3 *g; |
@property (assign, readonly) MySubClass3 *h; |
@end |
|
/* The following are not OK. */ |
@interface MyClass3 : MyClass |
{ } |
@property (assign) MySubClass1 *a; /* { dg-warning "type of property .a. conflicts with previous declaration" } */ |
@property float b; /* { dg-warning "type of property .b. conflicts with previous declaration" } */ |
@property int c; /* { dg-warning "type of property .c. conflicts with previous declaration" } */ |
@property (assign) id d; /* { dg-warning "type of property .d. conflicts with previous declaration" } */ |
@property (assign) MyRootClass *e; /* { dg-warning "type of property .e. conflicts with previous declaration" } */ |
@property (assign, readonly) MyRootClass *f; /* { dg-warning "type of property .f. conflicts with previous declaration" } */ |
@property (assign) MySubClass2 *g; /* { dg-warning "type of property .g. conflicts with previous declaration" } */ |
@property (assign, readonly) MySubClass2 *h; /* { dg-warning "type of property .h. conflicts with previous declaration" } */ |
@end |
|
/* The following are OK. */ |
@interface MyClass4 : MyClass |
{ } |
@property (assign, readonly) MySubClass4 *f; |
@property (assign, readonly) MySubClass3 <MyProtocolB> *h; |
@end |
/property/property-encoding-1.mm
0,0 → 1,182
/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, March 2011. */ |
/* Test encoding properties. */ |
/* { dg-do run } */ |
/* { dg-skip-if "No API#2 pre-Darwin9" { *-*-darwin[5-8]* } { "-fnext-runtime" } { "" } } */ |
|
#include <objc/runtime.h> |
#include <stdlib.h> |
#include <stdio.h> |
#include <string.h> |
|
@interface MyRootClass |
{ Class isa; } |
+ alloc; |
- init; |
+ initialize; |
@end |
|
@implementation MyRootClass |
+ alloc { return class_createInstance (self, 0); } |
- init { return self; } |
+ initialize { return self; } |
@end |
|
@interface MySubClass : MyRootClass |
{ |
char char_property; |
short short_property; |
int int_property; |
long long_property; |
float float_property; |
double double_property; |
int *int_pointer_property; |
|
id propertyA; |
id propertyB; |
id propertyC; |
id propertyD; |
int propertyE; |
id propertyF; |
|
id other_variable; |
} |
@property char char_property; |
@property short short_property; |
@property int int_property; |
@property long long_property; |
@property float float_property; |
@property double double_property; |
@property int *int_pointer_property; |
|
@property (assign, getter=getP, setter=setP:) id propertyA; |
@property (assign) id propertyB; |
@property (copy) id propertyC; |
@property (retain) id propertyD; |
@property (nonatomic) int propertyE; |
@property (nonatomic, readonly, copy) id propertyF; |
|
@property (assign) id propertyG; |
@property (assign, readonly, getter=X) id propertyH; |
@end |
|
@implementation MySubClass |
@synthesize char_property; |
@synthesize short_property; |
@synthesize int_property; |
@synthesize long_property; |
@synthesize float_property; |
@synthesize double_property; |
@synthesize int_pointer_property; |
|
@synthesize propertyA; |
@synthesize propertyB; |
@synthesize propertyC; |
@synthesize propertyD; |
@synthesize propertyE; |
@synthesize propertyF; |
|
@synthesize propertyG = other_variable; |
@dynamic propertyH; |
@end |
|
#ifdef __OBJC2__ |
void error (objc_property_t p) |
{ |
printf ("Error - property_getAttributes (\"%s\") returns \"%s\"\n", |
property_getName (p), |
property_getAttributes (p)); |
abort (); |
} |
|
/* Concatenate 3 strings and return the result. */ |
char *concat (const char *a, const char *b, const char *c) |
{ |
/* We happily leak memory here. This is a test. */ |
char *x = (char *)malloc (sizeof (char) * 128); |
snprintf (x, 128, "%s%s%s", a, b, c); |
return x; |
} |
|
#endif |
|
int main (void) |
{ |
#ifdef __OBJC2__ |
Class c = objc_getClass ("MySubClass"); |
objc_property_t p; |
|
p = class_getProperty (c, "char_property"); |
/* Usually we expect "Tc,Vchar_property", but if a char is of |
different size, it may be encoded differently than "c". */ |
if (strcmp (concat ("T", @encode (char), ",Vchar_property"), |
property_getAttributes (p)) != 0) |
error (p); |
|
p = class_getProperty (c, "short_property"); |
if (strcmp (concat ("T", @encode (short), ",Vshort_property"), |
property_getAttributes (p)) != 0) |
error (p); |
|
p = class_getProperty (c, "int_property"); |
if (strcmp (concat ("T", @encode (int), ",Vint_property"), |
property_getAttributes (p)) != 0) |
error (p); |
|
p = class_getProperty (c, "long_property"); |
if (strcmp (concat ("T", @encode (long), ",Vlong_property"), |
property_getAttributes (p)) != 0) |
error (p); |
|
p = class_getProperty (c, "float_property"); |
if (strcmp (concat ("T", @encode (float), ",Vfloat_property"), |
property_getAttributes (p)) != 0) |
error (p); |
|
p = class_getProperty (c, "double_property"); |
if (strcmp (concat ("T", @encode (double), ",Vdouble_property"), |
property_getAttributes (p)) != 0) |
error (p); |
|
p = class_getProperty (c, "int_pointer_property"); |
if (strcmp (concat ("T", @encode (int *), ",Vint_pointer_property"), |
property_getAttributes (p)) != 0) |
error (p); |
|
/* Objects are always encoded as '@' hence the string does not |
depend on the architecture. */ |
p = class_getProperty (c, "propertyA"); |
if (strcmp ("T@,GgetP,SsetP:,VpropertyA", property_getAttributes (p)) != 0) |
error (p); |
|
p = class_getProperty (c, "propertyB"); |
if (strcmp ("T@,VpropertyB", property_getAttributes (p)) != 0) |
error (p); |
|
p = class_getProperty (c, "propertyC"); |
if (strcmp ("T@,C,VpropertyC", property_getAttributes (p)) != 0) |
error (p); |
|
p = class_getProperty (c, "propertyD"); |
if (strcmp ("T@,&,VpropertyD", property_getAttributes (p)) != 0) |
error (p); |
|
p = class_getProperty (c, "propertyE"); |
if (strcmp (concat ("T", @encode (int), ",N,VpropertyE"), |
property_getAttributes (p)) != 0) |
error (p); |
|
p = class_getProperty (c, "propertyF"); |
if (strcmp ("T@,R,C,N,VpropertyF", property_getAttributes (p)) != 0) |
error (p); |
|
p = class_getProperty (c, "propertyG"); |
if (strcmp ("T@,Vother_variable", property_getAttributes (p)) != 0) |
error (p); |
|
p = class_getProperty (c, "propertyH"); |
if (strcmp ("T@,R,D,GX", property_getAttributes (p)) != 0) |
error (p); |
#endif |
|
return 0; |
} |
/property/synthesize-6.mm
0,0 → 1,30
/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, November 2010. */ |
/* { dg-do compile } */ |
|
/* Test that each @synthesize is using a different instance variable, |
and that it must belong to the class (not to a superclass). */ |
|
#include <objc/objc.h> |
|
@interface Test |
{ |
int v; |
int w; |
} |
@property int v1; |
@property int v2; |
@end |
@implementation Test |
@synthesize v1 = v; /* { dg-message "originally specified here" } */ |
@synthesize v2 = v; /* { dg-error "property .v2. is using the same instance variable as property .v1." } */ |
@end |
@interface Test2 : Test |
@property int w1; |
@end |
|
@implementation Test2 |
@synthesize w1; /* { dg-error "ivar .w1. used by .@synthesize. declaration must be an existing ivar" } */ |
@end |
/* { dg-warning "incomplete implementation" "" { target *-*-* } 27 } */ |
/* { dg-message "method definition for .-setW1:. not found" "" { target *-*-* } 27 } */ |
/* { dg-message "method definition for .-w1. not found" "" { target *-*-* } 27 } */ |
/property/at-property-14.mm
0,0 → 1,20
/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, November 2010. */ |
/* { dg-do compile } */ |
|
#include <objc/objc.h> |
|
@interface MyRootClass |
{ |
Class isa; |
} |
|
/* Test the warnings on 'assign'. */ |
@property id property_a; /* { dg-warning "object property .property.a. has no .assign., .retain. or .copy. attribute" } */ |
/* { dg-message ".assign. can be unsafe for Objective-C objects" "" { target *-*-* } 12 } */ |
|
@property (readonly) id property_b; /* No 'assign' warning (assign semantics do not matter if the property is readonly). */ |
@property id *property_c; /* No 'assign' warning (the type is not an Objective-C object). */ |
@property Class property_d; /* No 'assign' warning (Classes are static objects so assign semantics do not matter for them). */ |
@property MyRootClass *property_e; /* { dg-warning "object property .property.e. has no .assign., .retain. or .copy. attribute" } */ |
/* { dg-message ".assign. can be unsafe for Objective-C objects" "" { target *-*-* } 18 } */ |
@end |
/property/at-property-24.mm
0,0 → 1,118
/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, November 2010. */ |
/* { dg-do run } */ |
/* { dg-xfail-run-if "Needs OBJC2 ABI" { *-*-darwin* && { lp64 && { ! objc2 } } } { "-fnext-runtime" } { "" } } */ |
|
/* Test @optional @properties. */ |
|
#include <stdlib.h> |
#include <objc/objc.h> |
#include <objc/runtime.h> |
|
@interface MyRootClass |
{ |
Class isa; |
} |
+ (id) initialize; |
+ (id) alloc; |
- (id) init; |
@end |
|
@implementation MyRootClass |
+ (id) initialize { return self; } |
+ (id) alloc { return class_createInstance (self, 0); } |
- (id) init { return self; } |
@end |
|
/* Use a different getters/setters, so that the only way to compile |
object.countX is to find the actual @property. */ |
@protocol count |
@required |
/* @required + @synthesize. */ |
@property (getter=number1, setter=setNumber1:) int count1; |
/* @required + manual setters/getters. */ |
@property (getter=number2, setter=setNumber2:) int count2; |
|
@optional |
/* @optional + @synthesize. */ |
@property (getter=number3, setter=setNumber3:) int count3; |
/* @optional + manual setters/getters. */ |
@property (getter=number4, setter=setNumber4:) int count4; |
|
@optional |
/* @optional + readonly, with a setter added in the class itself. */ |
@property (readonly, getter=number5) int count5; |
@end |
|
@interface MySubClass : MyRootClass <count> |
{ |
int count1; |
int count2; |
int count3; |
int count4; |
int count5; |
} |
- (void) setCount5: (int)value; |
@end |
|
@implementation MySubClass |
@synthesize count1; |
- (int) number2 |
{ |
return count2; |
} |
- (void) setNumber2: (int)value |
{ |
count2 = value; |
} |
@synthesize count3; |
- (int) number4 |
{ |
return count4; |
} |
- (void) setNumber4: (int)value |
{ |
count4 = value; |
} |
- (int) number5 |
{ |
return count5; |
} |
- (void) setCount5: (int)value |
{ |
count5 = value; |
} |
@end |
|
int main (void) |
{ |
MySubClass *object = [[MySubClass alloc] init]; |
|
/* First, test that @required and @optional properties work as |
expected if implemented either via @synthesize or manually. */ |
object.count1 = 44; |
if (object.count1 != 44) |
abort (); |
|
object.count2 = 88; |
if (object.count2 != 88) |
abort (); |
|
object.count3 = 77; |
if (object.count3 != 77) |
abort (); |
|
object.count4 = 11; |
if (object.count4 != 11) |
abort (); |
|
/* Now, test the complication: @optional @property which is |
readonly, but which has a setter manually implemented. |
Apparently it is possible to use the dotsyntax and the @optional |
@property getter is used when reading, while the manual setter is |
used when writing. */ |
object.count5 = 99; |
if (object.count5 != 99) |
abort (); |
|
return 0; |
} |
/property/dotsyntax-10.mm
0,0 → 1,86
/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, November 2010. */ |
/* { dg-do run } */ |
/* { dg-xfail-run-if "Needs OBJC2 ABI" { *-*-darwin* && { lp64 && { ! objc2 } } } { "-fnext-runtime" } { "" } } */ |
|
/* Test dot-syntax with 'super'. */ |
|
#include <stdlib.h> |
#include <objc/objc.h> |
#include <objc/runtime.h> |
|
static int c; |
|
@interface MyRootClass |
{ |
Class isa; |
int a; |
} |
+ (id) initialize; |
+ (id) alloc; |
- (id) init; |
- (int) count; |
- (void) setCount: (int)count; |
+ (int) classCount; |
+ (void) setClassCount: (int)count; |
@end |
|
@implementation MyRootClass |
+ (id) initialize { return self; } |
+ (id) alloc { return class_createInstance (self, 0); } |
- (id) init { return self; } |
- (int) count |
{ |
return a; |
} |
- (void) setCount: (int)count |
{ |
a = count; |
} |
+ (int) classCount |
{ |
return c; |
} |
+ (void) setClassCount: (int)count |
{ |
c = count; |
} |
@end |
|
@interface MySubClass : MyRootClass |
+ (int) testMe; |
- (int) testMe; |
@end |
|
@implementation MySubClass |
- (int) testMe |
{ |
super.count = 400; |
if (super.count != 400) |
abort (); |
|
return super.count; |
} |
+ (int) testMe |
{ |
super.classCount = 4000; |
if (super.classCount != 4000) |
abort (); |
|
return super.classCount; |
} |
@end |
|
int main (void) |
{ |
MySubClass *object = [[MySubClass alloc] init]; |
|
if ([object testMe] != 400) |
abort (); |
|
if ([MySubClass testMe] != 4000) |
abort (); |
|
return 0; |
} |
|
|
/property/at-property-18.mm
0,0 → 1,46
/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, November 2010. */ |
/* { dg-do compile } */ |
|
#include <objc/objc.h> |
|
/* Test that if you have a property declared in a class and a |
category, the attributes match. This is almost the same as |
at-property-16.m, but for a category. It is a separate file |
because it is difficult to test multiple messages for the same |
line. */ |
|
@interface MyRootClass |
{ |
Class isa; |
} |
@property (assign) id a; |
@property (retain) id b; |
@property int c; |
@property (nonatomic) int d; |
@property int e; |
@property int f; |
@property int g; |
@property (readonly) int h; |
@property (readonly,getter=getMe) int i; |
@property (nonatomic) float j; |
@end |
@interface MyRootClass (Category) |
@property (retain) id a; /* { dg-warning "assign semantics attributes of property .a. conflict with previous declaration" } */ |
/* { dg-message "originally specified here" "" { target *-*-* } 16 } */ |
@property (assign) id b; /* { dg-warning "assign semantics attributes of property .b. conflict with previous declaration" } */ |
/* { dg-message "originally specified here" "" { target *-*-* } 17 } */ |
@property (nonatomic) int c; /* { dg-warning ".nonatomic. attribute of property .c. conflicts with previous declaration" } */ |
/* { dg-message "originally specified here" "" { target *-*-* } 18 } */ |
@property int d; /* { dg-warning ".nonatomic. attribute of property .d. conflicts with previous declaration" } */ |
/* { dg-message "originally specified here" "" { target *-*-* } 19 } */ |
@property (setter=setX:) int e; /* { dg-warning ".setter. attribute of property .e. conflicts with previous declaration" } */ |
/* { dg-message "originally specified here" "" { target *-*-* } 20 } */ |
@property (getter=x) int f; /* { dg-warning ".getter. attribute of property .f. conflicts with previous declaration" } */ |
/* { dg-message "originally specified here" "" { target *-*-* } 21 } */ |
@property (readonly) int g; /* { dg-warning ".readonly. attribute of property .g. conflicts with previous declaration" } */ |
/* { dg-message "originally specified here" "" { target *-*-* } 22 } */ |
@property (readwrite) int h; /* Ok */ |
@property (readonly) int i; /* { dg-warning ".getter. attribute of property .i. conflicts with previous declaration" } */ |
/* { dg-message "originally specified here" "" { target *-*-* } 24 } */ |
@property (nonatomic) float j; /* Ok */ |
@end |
/property/dotsyntax-20.mm
0,0 → 1,67
/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, November 2010. */ |
/* { dg-do compile } */ |
/* { dg-options "-Wall" } */ |
|
/* Test warnings with the dot-syntax. */ |
|
#include <stdlib.h> |
#include <objc/objc.h> |
#include <objc/runtime.h> |
|
@interface MyRootClass |
{ |
Class isa; |
id a; |
id b; |
int p1; |
int p2; |
} |
+ (id) initialize; |
+ (id) alloc; |
- (id) init; |
|
@property int p1; |
@property int p2; |
@end |
|
@implementation MyRootClass |
+ (id) initialize { return self; } |
+ (id) alloc { return class_createInstance (self, 0); } |
- (id) init { return self; } |
@synthesize p1; |
@synthesize p2; |
@end |
|
int main (void) |
{ |
MyRootClass *object = [[MyRootClass alloc] init]; |
|
/* First, test that the artificial code generated by dot-syntax does |
not generate unexpected warnings. */ |
|
/* All of the following should generate no warnings. */ |
object.p1 = 0; |
object.p2 = 0; |
object.p1 = object.p2 = 0; |
if (object.p1 > 0) |
object.p2 = 0; |
|
object.p1++; |
++object.p1; |
object.p1--; |
--object.p1; |
|
while (object.p1) |
object.p1--; |
|
/* Now test some warnings. */ |
object.p1; /* This warning does not seem to be produced in C++. dg-warning "value computed is not used" */ |
|
/* TODO: It would be good to get the following to warn. */ |
if (object.p1 = 0) /* dg-warning "suggest parentheses around assignment used as truth value" */ |
abort (); |
|
return 0; |
} |
|
|
/property/at-property-28.mm
0,0 → 1,29
/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, December 2010. */ |
/* { dg-do compile } */ |
|
/* Test errors when extending a property in a class extension. */ |
|
#include <objc/objc.h> |
#include <objc/runtime.h> |
|
@interface MyRootClass |
{ |
Class isa; |
} |
@property (readonly, retain) id property1; /* { dg-message "originally specified here" } */ |
@property (readonly) int property2; /* { dg-message "originally specified here" } */ |
@property (readonly, getter=y) int property3; /* { dg-message "originally specified here" } */ |
@property (readonly) int property4; /* Ok */ |
@property (readonly) int property5; /* { dg-message "originally specified here" } */ |
@end |
|
@interface MyRootClass () |
@property (readwrite, copy) id property1; /* { dg-warning "assign semantics attributes of property .property1. conflict with previous declaration" } */ |
@property (readwrite, nonatomic) int property2; /* { dg-warning ".nonatomic. attribute of property .property2. conflicts with previous declaration" } */ |
@property (readwrite, getter=x) int property3; /* { dg-warning ".getter. attribute of property .property3. conflicts with previous declaration" } */ |
@property (readwrite) int property4; /* Ok */ |
@property (readwrite) float property5; /* { dg-warning "type of property .property5. conflicts with previous declaration" } */ |
@end |
|
|
|
/property/dotsyntax-14.mm
0,0 → 1,77
/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, November 2010. */ |
/* { dg-do compile } */ |
|
/* Test dot-syntax with accessors to be looked up in protocol @properties. */ |
|
#include <stdlib.h> |
#include <objc/objc.h> |
#include <objc/runtime.h> |
|
@protocol ProtocolA |
@property int countA; |
@end |
|
@protocol ProtocolB |
@property int countB; |
@end |
|
@protocol ProtocolC |
@property int countC; |
@end |
|
@interface MyRootClass |
{ |
Class isa; |
} |
+ (id) initialize; |
+ (id) alloc; |
- (id) init; |
@end |
|
@interface MySubClass <ProtocolA, ProtocolB, ProtocolC> |
@end |
|
int function (MySubClass *object, int x) |
{ |
object.countA = x; |
object.countB = x; |
object.countC = object.countB; |
|
return object.countC; |
} |
|
int function2 (MyRootClass <ProtocolA, ProtocolB, ProtocolC> *object, int x) |
{ |
object.countA = x; |
object.countB = x; |
object.countC = object.countB; |
|
return object.countC; |
} |
|
int function3 (MyRootClass <ProtocolA, ProtocolB> *object, int x) |
{ |
object.countA = x; |
object.countB = x; |
object.countC = object.countB; /* { dg-error "request for member .countC. in" } */ |
|
return object.countC; /* { dg-error "request for member .countC. in" } */ |
} |
|
int function4 (id <ProtocolA, ProtocolB, ProtocolC> object, int x) |
{ |
object.countA = x; |
object.countB = x; |
object.countC = object.countB; |
|
return object.countC; |
} |
|
int function5 (id <ProtocolA, ProtocolB> object, int x) |
{ |
object.countA = x; |
object.countB = x; |
object.countC = object.countB; /* { dg-error "request for member .countC. in" } */ |
|
return object.countC; /* { dg-error "request for member .countC. in" } */ |
} |
/property/dynamic-2.mm
0,0 → 1,45
/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, October 2010. */ |
/* { dg-do compile } */ |
|
#include <objc/objc.h> |
|
@interface MyRootClass |
{ |
Class isa; |
} |
@end |
|
@implementation MyRootClass |
@end |
|
@dynamic isa; /* { dg-error "misplaced .@dynamic. Objective-C.. construct" } */ |
|
@interface Test : MyRootClass |
{ |
int v1; |
} |
@end |
@implementation Test |
@end |
|
|
@interface Test (Category) |
@property int v1; |
@end |
@implementation Test (Category) |
@dynamic v1; |
@end |
|
|
@interface AnotherTest : MyRootClass |
{ |
} |
@property int one; |
@end |
|
@implementation AnotherTest |
@dynamic one; |
@dynamic one; /* { dg-error "property .one. already specified in .@dynamic." } */ |
/* { dg-message "originally specified here" "" { target *-*-* } 41 } */ |
@dynamic three; /* { dg-error "no declaration of property .three. found in the interface" } */ |
@end |
/property/at-property-deprecated-2.mm
0,0 → 1,25
/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, October 2010. */ |
/* { dg-do compile } */ |
|
/* Test that deprecation warnings are produced when a setter/getter of |
a @property is used directly. */ |
|
#include <objc/objc.h> |
|
@interface MyClass |
{ |
Class isa; |
int variable; |
} |
@property (assign, nonatomic) int property __attribute__ ((deprecated)); |
@end |
|
void foo (void) |
{ |
MyClass *object = nil; |
|
if ([object property] > 0) /* { dg-warning "is deprecated" } */ |
{ |
[object setProperty: 43]; /* { dg-warning "is deprecated" } */ |
} |
} |
/property/dotsyntax-18.mm
0,0 → 1,90
/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, November 2010. */ |
/* { dg-do run } */ |
/* { dg-xfail-run-if "Needs OBJC2 ABI" { *-*-darwin* && { lp64 && { ! objc2 } } } { "-fnext-runtime" } { "" } } */ |
|
/* Test dot-syntax with tricky assignments. */ |
|
#include <stdlib.h> |
#include <objc/objc.h> |
#include <objc/runtime.h> |
|
@interface MyRootClass |
{ |
Class isa; |
int a; |
} |
+ (id) initialize; |
+ (id) alloc; |
- (id) init; |
- (int) count; |
- (void) setCount: (int)count; |
- (int) somethingToExecuteOnlyOnce; |
@end |
|
@implementation MyRootClass |
+ (id) initialize { return self; } |
+ (id) alloc { return class_createInstance (self, 0); } |
- (id) init { return self; } |
- (int) count |
{ |
return a; |
} |
- (void) setCount: (int)count |
{ |
a = count; |
} |
- (int) somethingToExecuteOnlyOnce |
{ |
a++; |
return 10; |
} |
@end |
|
int main (void) |
{ |
MyRootClass *object1 = [[MyRootClass alloc] init]; |
MyRootClass *object2 = [[MyRootClass alloc] init]; |
MyRootClass *object3 = [[MyRootClass alloc] init]; |
int i; |
|
object1.count = 10; |
if (object1.count != 10) |
abort (); |
|
object2.count = 10; |
if (object2.count != 10) |
abort (); |
|
/* Test multiple assignments to a constant. */ |
object1.count = object2.count = 20; |
|
if (object1.count != 20 || object2.count != 20) |
abort (); |
|
i = object1.count = 30; |
|
if (i != 30 || object1.count != 30) |
abort (); |
|
i = object2.count = 30; |
|
if (i != 30 || object2.count != 30) |
abort (); |
|
/* Test a simple assignment to something with a side-effect; the |
'rhs' should be evaluated only once. */ |
object1.count = ([object2 somethingToExecuteOnlyOnce] > 0 ? 30 : 45); |
|
if (object1.count != 30 || object2.count != 31) |
abort (); |
|
/* Test multiple assignments with side effects. */ |
object3.count = object1.count = ([object2 somethingToExecuteOnlyOnce] > 0 ? 30 : 45); |
|
if (object1.count != 30 || object2.count != 32 || object3.count != 30) |
abort (); |
|
return 0; |
} |
|
|
/property/at-property-2.mm
0,0 → 1,13
/* { dg-do compile } */ |
|
#include <objc/objc.h> |
|
@interface MyRootClass |
{ |
Class isa; |
} |
@property int name __attribute__((deprecated)); |
@property int table __attribute__((xxx)); /* { dg-warning ".xxx. attribute directive ignored" } */ |
@property void function (void); /* { dg-error "declaration of function .function. in invalid context" } */ |
@property typedef int j; /* { dg-error "invalid type for property" } */ |
@end |
/property/dynamic-6.mm
0,0 → 1,26
/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, November 2010. */ |
/* { dg-do compile } */ |
|
/* Test case when an accessor from a @property matches a method |
required by a protocol. If the @property is @dynamic, then no |
warning should be generated. */ |
|
#include <objc/objc.h> |
#include <objc/runtime.h> |
#include <stdlib.h> |
|
@protocol Count |
- (int) count; |
@end |
|
@interface MyRootClass <Count> |
{ |
Class isa; |
} |
@property int count; |
@end |
|
@implementation MyRootClass |
/* This @dynamic turns off any warnings for -count and -setCount:. */ |
@dynamic count; |
@end |
/property/at-property-6.mm
0,0 → 1,61
/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, October 2010. */ |
/* { dg-do run } */ |
/* { dg-xfail-run-if "Needs OBJC2 ABI" { *-*-darwin* && { lp64 && { ! objc2 } } } { "-fnext-runtime" } { "" } } */ |
|
/* Test the property syntax with non-synthesized setter/getter |
and with standard names. */ |
|
#include <stdlib.h> |
#include <objc/objc.h> |
#include <objc/runtime.h> |
|
@interface MyRootClass |
{ |
Class isa; |
int a; |
} |
@property (nonatomic) int a; |
+ (id) initialize; |
+ (id) alloc; |
- (id) init; |
@end |
|
@implementation MyRootClass |
+ (id) initialize { return self; } |
+ (id) alloc { return class_createInstance (self, 0); } |
- (id) init { return self; } |
|
- (int) a |
{ |
return a; |
} |
- (void) setA: (int)value |
{ |
a = value; |
} |
@end |
|
int main (void) |
{ |
MyRootClass *object = [[MyRootClass alloc] init]; |
|
if (object.a != 0) |
abort (); |
|
object.a = 14; |
|
if (object.a != 14) |
abort (); |
|
object.a = 23; |
|
if (object.a != 23) |
abort (); |
|
object.a = 78; |
|
if (object.a != 78) |
abort (); |
|
return (0); |
} |
/property/property-neg-4.mm
0,0 → 1,17
/* { dg-do compile } */ |
|
@interface Person |
{ |
char *fullName; |
} |
@property char *fullName; |
+ (void) testClass; |
@end |
|
|
@implementation Person |
@synthesize fullName; |
+ (void) testClass { |
self.fullName = "MyName"; /* { dg-error "request for member .fullName." } */ |
} |
@end |
/property/dotsyntax-3.mm
0,0 → 1,64
/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, November 2010. */ |
/* { dg-do run } */ |
/* { dg-xfail-run-if "Needs OBJC2 ABI" { *-*-darwin* && { lp64 && { ! objc2 } } } { "-fnext-runtime" } { "" } } */ |
|
/* Test the 'dot syntax' without a declarated property. This tests the case where |
the object is a Class. */ |
|
|
#include <stdlib.h> |
#include <objc/objc.h> |
#include <objc/runtime.h> |
|
static int a; |
static id b; |
|
@interface MyRootClass |
{ |
Class isa; |
} |
+ (id) initialize; |
+ (id) alloc; |
- (id) init; |
+ (int) count; |
+ (void) setCount: (int)value; |
+ (id) next; |
+ (void) setNext: (id)value; |
@end |
|
@implementation MyRootClass |
+ (id) initialize { return self; } |
+ (id) alloc { return class_createInstance (self, 0); } |
- (id) init { return self; } |
+ (int) count |
{ |
return a; |
} |
+ (void) setCount: (int)value |
{ |
a = value; |
} |
+ (id) next |
{ |
return b; |
} |
+ (void) setNext: (id)value |
{ |
b = value; |
} |
@end |
|
int main (void) |
{ |
MyRootClass *object = [[MyRootClass alloc] init]; |
|
MyRootClass.count = 40; |
if (MyRootClass.count != 40) |
abort (); |
|
MyRootClass.next = object; |
if (MyRootClass.next != object) |
abort (); |
|
return 0; |
} |
/property/dotsyntax-7.mm
0,0 → 1,48
/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, November 2010. */ |
/* { dg-do run } */ |
/* { dg-xfail-run-if "Needs OBJC2 ABI" { *-*-darwin* && { lp64 && { ! objc2 } } } { "-fnext-runtime" } { "" } } */ |
|
/* Test dot syntax of a casted expression. */ |
|
#include <stdlib.h> |
#include <objc/objc.h> |
#include <objc/runtime.h> |
|
@interface MyRootClass |
{ |
Class isa; |
int a; |
} |
+ (id) initialize; |
+ (id) alloc; |
- (id) init; |
- (int) count; |
- (void) setCount: (int)count; |
@end |
|
@implementation MyRootClass |
+ (id) initialize { return self; } |
+ (id) alloc { return class_createInstance (self, 0); } |
- (id) init { return self; } |
- (int) count |
{ |
return a; |
} |
- (void) setCount: (int)count |
{ |
a = count; |
} |
@end |
|
int main (void) |
{ |
id object = [[MyRootClass alloc] init]; |
|
((MyRootClass *)object).count = 200; |
if (((MyRootClass *)object).count != 200) |
abort (); |
|
return 0; |
} |
|
|
/property/synthesize-1.mm
0,0 → 1,53
/* { dg-do compile } */ |
|
#include <objc/objc.h> |
|
@interface MyRootClass |
{ |
Class isa; |
} |
@end |
|
@implementation MyRootClass |
@end |
|
@synthesize isa; /* { dg-error "misplaced .@synthesize. Objective-C.. construct" } */ |
|
@interface Test : MyRootClass |
{ |
int v1; |
int v2; |
int v3; |
int v4; |
int v5; |
int v6; |
int v7; |
int v8; |
} |
@property int v1; |
@property int v2; |
@property int v3; |
@property int v4; |
@property int v5; |
@property int v6; |
@property int v7; |
@property int v8; |
@end |
|
@implementation Test |
@synthesize; /* { dg-error "expected identifier" } */ |
@synthesize v1, ; /* { dg-error "expected identifier" } */ |
@synthesize v2, v3 = ; /* { dg-error "expected identifier" } */ |
@synthesize v4, v5=v6, v6 = v5,v7; |
@synthesize v8; |
/* Some of the @synthesize above will fail due to syntax errors. The |
compiler will then complain that the methods implementing the |
properties are missing. That is correct, but we are not |
interested. The following ones shut up the compiler. */ |
- (int) v1 { return v1; } |
- (void) setV1: (int)a { v1 = a; } |
- (int) v2 { return v2; } |
- (void) setV2: (int)a { v2 = a; } |
- (int) v3 { return v3; } |
- (void) setV3: (int)a { v3 = a; } |
@end |
/property/synthesize-5.mm
0,0 → 1,18
/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, November 2010. */ |
/* { dg-do compile } */ |
|
/* Test that @synthesize does not ICE if asked to use a non-existing |
ivar. */ |
|
#include <objc/objc.h> |
|
@interface Test |
@property int v1; |
@end |
|
@implementation Test |
@synthesize v1; /* { dg-error "must be an existing ivar" } */ |
@end |
/* { dg-warning "incomplete implementation" "" { target *-*-* } 15 } */ |
/* { dg-warning "method definition for .-setV1:. not found" "" { target *-*-* } 15 } */ |
/* { dg-warning "method definition for .-v1. not found" "" { target *-*-* } 15 } */ |
/property/property.exp
0,0 → 1,43
# GCC Objective-C++ testsuite that uses the `dg.exp' driver. |
# Copyright (C) 2004, 2007, 2010 Free Software Foundation, Inc. |
|
# This program is free software; you can redistribute it and/or modify |
# it under the terms of the GNU General Public License as published by |
# the Free Software Foundation; either version 3 of the License, or |
# (at your option) any later version. |
# |
# This program is distributed in the hope that it will be useful, |
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
# GNU General Public License for more details. |
# |
# You should have received a copy of the GNU General Public License |
# along with GCC; see the file COPYING3. If not see |
# <http://www.gnu.org/licenses/>. |
|
# 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. |
# but Properties are not supported by the runtime lib before Darwin 9. |
if [istarget "*-*-darwin\[9123\]*" ] { |
dg-runtest $tests "-fnext-runtime" $DEFAULT_OBJCXXFLAGS |
} |
|
# All done. |
dg-finish |
/property/at-property-13.mm
0,0 → 1,72
/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, October 2010. */ |
/* { dg-do run } */ |
/* { dg-xfail-run-if "Needs OBJC2 ABI" { *-*-darwin* && { lp64 && { ! objc2 } } } { "-fnext-runtime" } { "" } } */ |
|
/* Test retain and copy synthesized methods. */ |
|
#include <stdlib.h> |
#include <objc/objc.h> |
#include <objc/runtime.h> |
|
@interface MyRootClass |
{ |
Class isa; |
int copy_count; |
id a; |
id b; |
} |
@property (copy) id a; |
@property (retain) id b; |
+ (id) initialize; |
+ (id) alloc; |
- (id) init; |
- (id) copyWithZone: (void *)zone; |
- (int) copyCount; |
- (id) autorelease; |
- (oneway void) release; |
- (id) retain; |
@end |
|
/* This class implements copyWithZone, which doesn't do anything other |
than increasing a counter of how many copies were made. */ |
@implementation MyRootClass |
+ (id) initialize { return self; } |
+ (id) alloc { return class_createInstance (self, 0); } |
- (id) init { return self; } |
- (id) copyWithZone: (void *)zone { copy_count++; return self; } |
- (int) copyCount { return copy_count; } |
- (id) autorelease { return self; } |
- (oneway void) release { return; } |
- (id) retain { return self; } |
@synthesize a; |
@synthesize b; |
@end |
|
int main (void) |
{ |
MyRootClass *object = [[MyRootClass alloc] init]; |
MyRootClass *argument = [[MyRootClass alloc] init]; |
|
/* This should copy argument. */ |
object.a = argument; |
if (object.a != argument) |
abort (); |
|
/* Test that it was copied. */ |
if ([object.a copyCount] != 1) |
abort (); |
|
/* We just test that the retain accessors seem to work and that they |
don't copy. We don't test that retain was actually called, |
because if garbage collection is enabled, it may never be |
called! */ |
object.b = argument; |
if (object.b != argument) |
abort (); |
|
/* Test that it was not copied. */ |
if ([object.b copyCount] != 1) |
abort (); |
|
return (0); |
} |
/property/at-property-23.mm
0,0 → 1,18
/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, November 2010. */ |
/* { dg-do compile } */ |
|
/* Test that properties of type arrays or bitfields are rejected. */ |
|
#include <stdlib.h> |
#include <objc/objc.h> |
#include <objc/runtime.h> |
|
@interface MyRootClass |
{ |
Class isa; |
} |
@property int a[8]; /* { dg-error "property can not be an array" } */ |
@property int b:8; /* { dg-error "expected" } */ |
@property int c[]; /* { dg-error "property can not be an array" } */ |
/* { dg-error "ISO C.. forbids zero-size array" "" { target *-*-* } 16 } */ |
@end |
/property/synthesize-9.mm
0,0 → 1,80
/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, November 2010. */ |
/* { dg-do compile } */ |
|
/* Test that when using @synthesize with a readonly property, the |
instance variable can be a specialization of the property type. */ |
|
#include <objc/objc.h> |
|
@protocol MyProtocol |
- (void)aMethod; |
@end |
|
@interface ClassA |
@end |
|
@interface ClassB : ClassA |
@end |
|
|
/* This is all OK. */ |
@interface Test |
{ |
int v; |
float w; |
id x; |
Test *y; |
id <MyProtocol> *z; |
ClassA *a; |
ClassB *b; |
ClassA <MyProtocol> *c; |
} |
@property (assign, readonly) int v; |
@property (assign, readonly) float w; |
@property (assign, readonly) id x; |
@property (assign, readonly) Test *y; |
@property (assign, readonly) id <MyProtocol> *z; |
@property (assign, readonly) ClassA *a; |
@property (assign, readonly) ClassB *b; |
@end |
|
@implementation Test |
@synthesize v; |
@synthesize w; |
@synthesize x; |
@synthesize y; |
@synthesize z; |
@synthesize a; |
@synthesize b; |
@end |
|
|
/* This is sometimes OK, sometimes not OK. */ |
@interface Test2 |
{ |
int v; /* { dg-message "originally specified here" } */ |
float w; /* { dg-message "originally specified here" } */ |
id x; /* { dg-message "originally specified here" } */ |
Test *y; |
id <MyProtocol> *z; /* { dg-message "originally specified here" } */ |
ClassA *a; /* { dg-message "originally specified here" } */ |
ClassB *b; |
} |
@property (assign, readonly) float v; |
@property (assign, readonly) id w; |
@property (assign, readonly) int x; |
@property (assign, readonly) id y; |
@property (assign, readonly) Test *z; |
@property (assign, readonly) ClassB *a; |
@property (assign, readonly) ClassA *b; |
@end |
|
@implementation Test2 |
@synthesize v; /* { dg-error "property .v. is using instance variable .v. of incompatible type" } */ |
@synthesize w; /* { dg-error "property .w. is using instance variable .w. of incompatible type" } */ |
@synthesize x; /* { dg-error "property .x. is using instance variable .x. of incompatible type" } */ |
@synthesize y; |
@synthesize z; /* { dg-error "property .z. is using instance variable .z. of incompatible type" } */ |
@synthesize a; /* { dg-error "property .a. is using instance variable .a. of incompatible type" } */ |
@synthesize b; |
@end |
/property/at-property-17.mm
0,0 → 1,98
/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, November 2010. */ |
/* { dg-do compile } */ |
|
#include <objc/objc.h> |
|
/* Test that if you have a property declared in a class, with |
getters/setters in the superclass, there are no warnings. */ |
|
@interface MyRootClass |
{ |
Class isa; |
int myCount; |
int myCount2; |
int myCount3; |
} |
- (int)count; |
- (void)setCount: (int)number; |
- (int)count2; |
- (void)setCount2: (int)number; |
- (int)count3; |
@end |
|
@implementation MyRootClass |
- (int) count |
{ |
return myCount; |
} |
- (void) setCount: (int)number |
{ |
myCount = number; |
} |
- (int) count2 |
{ |
return myCount2; |
} |
- (void) setCount2: (int)number |
{ |
myCount2 = number; |
} |
- (int) count3 |
{ |
return myCount3; |
} |
@end |
|
|
|
/* Try with a subclass. */ |
@interface MyClass : MyRootClass |
@property int count; |
@end |
|
@implementation MyClass |
@end /* No warnings. */ |
|
|
|
/* Try with a category. */ |
@interface MyRootClass (count) |
@property int count; |
@end |
|
@implementation MyRootClass (count) |
@end /* No warnings. */ |
|
|
|
/* Try with a category of a subclass. */ |
@interface MyClass2 : MyClass |
@end |
|
@implementation MyClass2 |
@end |
|
@interface MyClass2 (count2) |
@property int count2; |
@end |
|
@implementation MyClass2 (count2) |
@end /* No warnings. */ |
|
|
|
/* Now, try with a category of a subclass, but with a missing setter, |
which should generate a warning. */ |
@interface MyClass3 : MyClass |
@end |
|
@implementation MyClass3 |
@end |
|
@interface MyClass3 (count3) |
@property int count3; |
@end |
|
@implementation MyClass3 (count3) |
@end /* { dg-warning "incomplete implementation" } */ |
/* { dg-warning "method definition for .-setCount3:. not found" "" { target *-*-* } 97 } */ |
/property/at-property-27.mm
0,0 → 1,66
/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, December 2010. */ |
/* { dg-do run } */ |
/* { dg-xfail-run-if "Needs OBJC2 ABI" { *-*-darwin* && { lp64 && { ! objc2 } } } { "-fnext-runtime" } { "" } } */ |
|
/* Test overriding a readonly @property with a readwrite one in a class extension. */ |
|
#include <stdlib.h> |
#include <objc/objc.h> |
#include <objc/runtime.h> |
|
@interface MyRootClass |
{ |
Class isa; |
} |
+ (id) initialize; |
+ (id) alloc; |
- (id) init; |
@end |
|
@implementation MyRootClass |
+ (id) initialize { return self; } |
+ (id) alloc { return class_createInstance (self, 0); } |
- (id) init { return self; } |
@end |
|
@protocol count2 |
/* Use a different getters/setters, so that the only way to compile |
object.countX is to find the actual @property. */ |
@property (readonly, getter=number2) int count2; |
@end |
|
@interface MySubClass : MyRootClass |
{ |
int count1; |
int count2; |
} |
@property (readonly, getter=number1) int count1; |
@end |
|
@interface MySubClass () |
@property (readwrite, getter=number1, setter=setNumber1:) int count1; |
@end |
|
@interface MySubClass () <count2> |
@property (readwrite, getter=number2, setter=setNumber2:) int count2; |
@end |
|
@implementation MySubClass |
@synthesize count1; |
@synthesize count2; |
@end |
|
int main (void) |
{ |
MySubClass *object = [[MySubClass alloc] init]; |
|
object.count1 = 20; |
if (object.count1 != 20) |
abort (); |
|
object.count2 = 11; |
if (object.count2 != 11) |
abort (); |
|
return 0; |
} |
/property/dotsyntax-13.mm
0,0 → 1,53
/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, November 2010. */ |
/* { dg-do run } */ |
/* { dg-xfail-run-if "Needs OBJC2 ABI" { *-*-darwin* && { lp64 && { ! objc2 } } } { "-fnext-runtime" } { "" } } */ |
|
/* Test dot-syntax with a local variable. */ |
|
#include <stdlib.h> |
#include <objc/objc.h> |
#include <objc/runtime.h> |
|
@interface MyRootClass |
{ |
Class isa; |
int a; |
} |
+ (id) initialize; |
+ (id) alloc; |
- (id) init; |
- (int) count; |
- (void) setCount: (int)count; |
@end |
|
@implementation MyRootClass |
+ (id) initialize { return self; } |
+ (id) alloc { return class_createInstance (self, 0); } |
- (id) init { return self; } |
- (int) count |
{ |
return a; |
} |
- (void) setCount: (int)count |
{ |
a = count; |
} |
@end |
|
int main (void) |
{ |
MyRootClass *object = [[MyRootClass alloc] init]; |
int i; |
|
for (i = 0; i < 10; i++) |
{ |
object.count = i; |
|
if (object.count != i) |
abort (); |
} |
|
return 0; |
} |
|
|
/property/dynamic-1.mm
0,0 → 1,34
/* { dg-do compile } */ |
|
#include <objc/objc.h> |
|
@interface MyRootClass |
{ |
Class isa; |
} |
@end |
|
@implementation MyRootClass |
@end |
|
@dynamic isa; /* { dg-error "misplaced .@dynamic. Objective-C.. construct" } */ |
|
@interface Test : MyRootClass |
{ |
int v1; |
int v2; |
int v3; |
int v4; |
} |
@property int v1; |
@property int v2; |
@property int v3; |
@property int v4; |
@end |
|
@implementation Test |
@dynamic; /* { dg-error "expected identifier" } */ |
@dynamic v1, ; /* { dg-error "expected identifier" } */ |
@dynamic v1, v2, v3; |
@dynamic v4; |
@end |
/property/property-1.mm
0,0 → 1,30
/* This program tests use of property provided setter/getter functions. */ |
/* { dg-do run } */ |
/* { dg-xfail-run-if "Needs OBJC2 ABI" { *-*-darwin* && { lp64 && { ! objc2 } } } { "-fnext-runtime" } { "" } } */ |
|
#import "../../objc-obj-c++-shared/TestsuiteObject.m" |
|
@interface Bar : TestsuiteObject |
{ |
int iVar; |
} |
@property (setter=MySetter:) int FooBar; |
@end |
|
@implementation Bar |
@synthesize FooBar=iVar; |
|
- (void) MySetter : (int) value { iVar = value; } |
|
@end |
|
int main(int argc, char *argv[]) { |
Bar *f = [Bar new]; |
f.FooBar = 1; |
|
f.FooBar += 3; |
|
f.FooBar -= 4; |
return f.FooBar; |
} |
|
/property/dotsyntax-17.mm
0,0 → 1,67
/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, November 2010. */ |
/* { dg-do compile } */ |
|
/* Test errors with the dot-syntax with pre/post increment and decrement. */ |
|
#include <stdlib.h> |
#include <objc/objc.h> |
#include <objc/runtime.h> |
|
@interface MyRootClass |
{ |
Class isa; |
int count; |
int a; |
} |
+ (id) initialize; |
+ (id) alloc; |
- (id) init; |
@property (assign, readonly) int count; |
- (void) setWriteOnlyCount: (int)value; |
@end |
|
@implementation MyRootClass |
+ (id) initialize { return self; } |
+ (id) alloc { return class_createInstance (self, 0); } |
- (id) init { return self; } |
@synthesize count; |
- (void) setWriteOnlyCount: (int)value |
{ |
a = value; |
} |
@end |
|
int main (void) |
{ |
MyRootClass *object = [[MyRootClass alloc] init]; |
|
object.count = 10; /* { dg-error "readonly property can not be set" } */ |
if (object.count != 10) /* Ok */ |
abort (); |
|
/* Test errors when trying to change a readonly property using |
pre/post increment/decrement operators. */ |
object.count++; /* { dg-error "readonly property can not be set" } */ |
|
++object.count; /* { dg-error "readonly property can not be set" } */ |
|
object.count--; /* { dg-error "readonly property can not be set" } */ |
|
--object.count; /* { dg-error "readonly property can not be set" } */ |
|
/* Test errors when trying to change something using Objective-C 2.0 |
dot-syntax but there is a setter but no getter. */ |
object.writeOnlyCount = 10; /* Ok */ |
|
object.writeOnlyCount++; /* { dg-error "no .writeOnlyCount. getter found" } */ |
|
++object.writeOnlyCount; /* { dg-error "no .writeOnlyCount. getter found" } */ |
|
object.writeOnlyCount--; /* { dg-error "no .writeOnlyCount. getter found" } */ |
|
--object.writeOnlyCount; /* { dg-error "no .writeOnlyCount. getter found" } */ |
|
return 0; |
} |
|
|
/property/at-property-deprecated-1.mm
0,0 → 1,37
/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, October 2010. */ |
/* { dg-do compile } */ |
|
/* Test that properties can be deprecated. */ |
|
#include <stdlib.h> |
#include <objc/objc.h> |
#include <objc/runtime.h> |
|
@interface MyRootClass |
{ |
Class isa; |
int a; |
} |
@property int a __attribute__((deprecated)); |
+ (id) initialize; |
+ (id) alloc; |
- (id) init; |
@end |
|
@implementation MyRootClass |
+ (id) initialize { return self; } |
+ (id) alloc { return class_createInstance (self, 0); } |
- (id) init { return self; } |
@synthesize a; |
@end |
|
int main (void) |
{ |
MyRootClass *object = [[MyRootClass alloc] init]; |
|
object.a = 40; /* { dg-warning "is deprecated" } */ |
if (object.a != 40) /* { dg-warning "is deprecated" } */ |
abort (); |
|
return (0); |
} |
/property/cxx-property-2.mm
0,0 → 1,22
/* { dg-do compile } */ |
|
/* All these C++ keywords are acceptable in ObjC method names, hence |
should be accepted for property getters and setters. */ |
|
@interface Test |
{ |
Class isa; |
} |
@property (getter=namespace) int p0; |
@property (setter=namespace:) int p1; |
@property (getter=and) int p2; |
@property (setter=and:) int p3; |
@property (getter=class) int p4; |
@property (setter=class:) int p5; |
@property (getter=new) int p6; |
@property (setter=new:) int p7; |
@property (getter=delete) int p8; |
@property (setter=delete:) int p9; |
@property (getter=delete) int p10; |
@property (setter=delete:) int p11; |
@end |
/property/synthesize-11.mm
0,0 → 1,31
/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, November 2010. */ |
/* { dg-do compile } */ |
|
/* Test errors when @synthesize is used with bitfield instance variables in an incorrect way. */ |
|
#include <stdlib.h> |
#include <objc/objc.h> |
#include <objc/runtime.h> |
|
@interface MyRootClass |
{ |
Class isa; |
int countA : 2; /* { dg-message "originally specified here" } */ |
int countB : 3; /* { dg-message "originally specified here" } */ |
} |
+ (id) initialize; |
+ (id) alloc; |
- (id) init; |
@property int countA; |
@property (nonatomic) short countB; |
@end |
|
@implementation MyRootClass |
+ (id) initialize { return self; } |
+ (id) alloc { return class_createInstance (self, 0); } |
- (id) init { return self; } |
@synthesize countA; /* { dg-error ".atomic. property .countA. is using bit-field instance variable .countA." } */ |
@synthesize countB; /* { dg-error "property .countB. is using instance variable .countB. of incompatible type" } */ |
@end /* { dg-warning "incomplete implementation of class" } */ |
/* { dg-message "method definition for ..setCountA.. not found" "" { target *-*-* } 29 } */ |
/* { dg-message "method definition for ..countA. not found" "" { target *-*-* } 29 } */ |
/property/at-property-1.mm
0,0 → 1,20
/* { dg-do compile } */ |
|
#include <objc/objc.h> |
|
@interface MyRootClass |
{ |
Class isa; |
} |
@property; /* { dg-error "expected identifier" } */ |
@property int; /* { dg-error "expected identifier" } */ |
@property int a; |
@property int b, c; |
@property () int d; /* { dg-error "expected identifier" } */ |
@property (readonly) int e; |
@property (readonly,) int f; /* { dg-error "expected identifier" } */ |
@property (xxx) int g; /* { dg-error "unknown property attribute" } */ |
@property (readonly,xxx) int h; /* { dg-error "unknown property attribute" } */ |
@property ( int i; /* { dg-error "expected identifier" } */ |
/* { dg-error "expected ... " "" { target *-*-* } 18 } */ |
@end |
/property/dynamic-5.mm
0,0 → 1,53
/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, November 2010. */ |
/* { dg-do run } */ |
/* { dg-xfail-run-if "Needs OBJC2 ABI" { *-*-darwin* && { lp64 && { ! objc2 } } } { "-fnext-runtime" } { "" } } */ |
|
/* Test @dynamic in the real scenario where a class declares a |
@property, uses @dynamic to avoid implementing it, then subclasses |
implement it. */ |
|
#include <objc/objc.h> |
#include <objc/runtime.h> |
#include <stdlib.h> |
|
@interface MyRootClass |
{ |
Class isa; |
} |
@property int a; |
+ (id) initialize; |
+ (id) alloc; |
- (id) init; |
@end |
|
@implementation MyRootClass |
+ (id) initialize { return self; } |
+ (id) alloc { return class_createInstance (self, 0); } |
- (id) init { return self; } |
@dynamic a; |
@end |
|
@interface Test : MyRootClass |
{ |
int v1; |
} |
@end |
|
@implementation Test |
@synthesize a = v1; |
@end |
|
int main (void) |
{ |
/* Note how 'object' is declared to be of class 'MyRootClass', but |
actually is of the subclass which implements the property for |
real. */ |
MyRootClass *object = [[Test alloc] init]; |
|
object.a = 40; |
|
if (object.a != 40) |
abort (); |
|
return 0; |
} |
/property/at-property-5.mm
0,0 → 1,34
/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, October 2010. */ |
/* { dg-do compile } */ |
|
#include <objc/objc.h> |
|
@interface MyRootClass |
{ |
Class isa; |
id property_a; |
int property_b; |
int property_c; |
int property_d; |
id property_e; |
id property_f; |
id property_g; |
id property_h; |
} |
|
/* Test various error messages. */ |
@property id property_a; /* { dg-warning "object property .property.a. has no .assign., .retain. or .copy. attribute" } */ |
/* { dg-message ".assign. can be unsafe for Objective-C objects" "" { target *-*-* } 20 } */ |
@property int property_b = 4; /* { dg-error "expected" } */ |
@property (retain) int property_c; /* { dg-error ".retain. attribute is only valid for Objective-C objects" } */ |
@property (copy) int property_d; /* { dg-error ".copy. attribute is only valid for Objective-C objects" } */ |
|
@property (retain) id property_e; |
@property (retain) id property_f; |
@property (retain) id property_g; |
@property (retain) id property_h; |
@property (retain) id property_e; /* { dg-error "redeclaration of property .property_e." } */ |
/* { dg-message "originally specified here" "" { target *-*-* } 26 } */ |
@end |
|
@property id test; /* { dg-error "misplaced .@property. Objective-C.. construct" } */ |
/property/property-neg-3.mm
0,0 → 1,14
/* { dg-do compile } */ |
|
@interface Person |
{ |
char *firstName; |
} |
@property char *firstName; |
@end |
|
@implementation Person |
@dynamic firstName; |
@synthesize firstName; /* { dg-error "property .firstName. already specified in .@dynamic." } */ |
/* { dg-message "originally specified here" "" { target *-*-* } 11 } */ |
@end |
/property/at-property-9.mm
0,0 → 1,50
/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, October 2010. */ |
/* { dg-do run } */ |
/* { dg-xfail-run-if "Needs OBJC2 ABI" { *-*-darwin* && { lp64 && { ! objc2 } } } { "-fnext-runtime" } { "" } } */ |
|
/* Test the property syntax with synthesized setter/getter |
and with a non-standard name for the getter and setter. */ |
|
#include <stdlib.h> |
#include <objc/objc.h> |
#include <objc/runtime.h> |
|
@interface MyRootClass |
{ |
Class isa; |
int a; |
} |
@property (getter = giveMeA, setter = writeA:, nonatomic) int a; |
+ (id) initialize; |
+ (id) alloc; |
- (id) init; |
@end |
|
@implementation MyRootClass |
+ (id) initialize { return self; } |
+ (id) alloc { return class_createInstance (self, 0); } |
- (id) init { return self; } |
@synthesize a; |
@end |
|
int main (void) |
{ |
MyRootClass *object = [[MyRootClass alloc] init]; |
|
object.a = 14; |
|
if (object.a != 14) |
abort (); |
|
object.a = 23; |
|
if (object.a != 23) |
abort (); |
|
object.a = 78; |
|
if (object.a != 78) |
abort (); |
|
return (0); |
} |
/property/dotsyntax-2.mm
0,0 → 1,72
/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, November 2010. */ |
/* { dg-do run } */ |
/* { dg-xfail-run-if "Needs OBJC2 ABI" { *-*-darwin* && { lp64 && { ! objc2 } } } { "-fnext-runtime" } { "" } } */ |
|
/* Test the 'dot syntax' without a declarated property. This tests the case where |
only the setter (or only the getter) exists. */ |
|
#include <stdlib.h> |
#include <objc/objc.h> |
#include <objc/runtime.h> |
|
@interface MyRootClass |
{ |
Class isa; |
int a; |
id b; |
} |
+ (id) initialize; |
+ (id) alloc; |
- (id) init; |
- (int) a; |
- (void) setCount: (int)value; |
- (id) b; |
- (void) setNext: (id)value; |
@end |
|
@implementation MyRootClass |
+ (id) initialize { return self; } |
+ (id) alloc { return class_createInstance (self, 0); } |
- (id) init { return self; } |
- (int) a |
{ |
return a; |
} |
- (void) setCount: (int)value |
{ |
a = value; |
} |
- (id) b |
{ |
return b; |
} |
- (void) setNext: (id)value |
{ |
b = value; |
} |
@end |
|
int main (void) |
{ |
MyRootClass *object = [[MyRootClass alloc] init]; |
|
/* This should work because -setCount: exists (even if -count does |
not). */ |
object.count = 40; |
|
/* This should work because -a exists (even if -setA: does not). */ |
if (object.a != 40) |
abort (); |
|
/* This should work because -setNext: exists (even if -next does |
not). */ |
object.next = object; |
|
/* This should work because -b exists (even if -setB: does not). */ |
if (object.b != object) |
abort (); |
|
return 0; |
} |
|
|
/property/property-neg-7.mm
0,0 → 1,20
/* { dg-do compile } */ |
|
@interface NSArray |
{ |
int count; |
} |
@property(readonly) int count; |
@end |
|
@implementation NSArray |
@synthesize count; |
@end |
|
void foo (NSArray *ans[], id pid, id apid[], int i) { |
NSArray *test; |
test.count = 1; /* { dg-error "readonly property can not be set" } */ |
((NSArray *)pid).count = 1; /* { dg-error "readonly property can not be set" } */ |
((NSArray *)apid[i]).count = 1; /* { dg-error "readonly property can not be set" } */ |
ans[i].count = 3; /* { dg-error "readonly property can not be set" } */ |
} |
/property/dotsyntax-6.mm
0,0 → 1,106
/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, November 2010. */ |
/* { dg-do run } */ |
/* { dg-xfail-run-if "Needs OBJC2 ABI" { *-*-darwin* && { lp64 && { ! objc2 } } } { "-fnext-runtime" } { "" } } */ |
|
/* Test nested 'dot syntax' (xxx.yyy.zzz or [xxx yyy].zzz). */ |
|
#include <stdlib.h> |
#include <objc/objc.h> |
#include <objc/runtime.h> |
|
@class MyRootClass; |
|
static MyRootClass *shared_root = nil; |
|
@interface MyRootClass |
{ |
Class isa; |
int a; |
int b; |
MyRootClass *next; |
} |
@property int b; |
@property (assign) MyRootClass *next; |
+ (id) initialize; |
+ (MyRootClass *)sharedInstance; |
+ (id) alloc; |
- (id) init; |
- (MyRootClass *)same; |
- (int) count; |
- (void) setCount: (int)count; |
@end |
|
@implementation MyRootClass |
@synthesize b; |
@synthesize next; |
+ (id) initialize { return self; } |
+ (id) alloc { return class_createInstance (self, 0); } |
- (id) init { return self; } |
+ (MyRootClass *)sharedInstance |
{ |
if (!shared_root) |
shared_root = [[self alloc] init]; |
|
return shared_root; |
} |
- (MyRootClass *)same |
{ |
return self; |
} |
- (int) count |
{ |
return a; |
} |
- (void) setCount: (int)count |
{ |
a = count; |
} |
@end |
|
int main (void) |
{ |
MyRootClass *object = [[MyRootClass alloc] init]; |
|
/* Test ClassName.accessor.accessor. */ |
MyRootClass.sharedInstance.count = 500; |
if (MyRootClass.sharedInstance.count != 500) |
abort (); |
|
/* Test object.accessor.accessor. */ |
object.same.count = 1000; |
if (object.same.count != 1000) |
abort (); |
|
/* Test object.accessor.property. */ |
object.same.next = object; |
if (object.same.next != object) |
abort (); |
|
/* Test lots of nesting. */ |
if (object.next.next.same.same.next.next.same != object) |
abort (); |
|
/* Test more nesting. */ |
MyRootClass.sharedInstance.next = object; |
MyRootClass.sharedInstance.next.next.next.next.next.count = 2000; |
if (MyRootClass.sharedInstance.next.next.next.next.next.count != 2000) |
abort (); |
|
/* Test more nesting. */ |
MyRootClass.sharedInstance.same.same.same.same.same.count = 3000; |
if (MyRootClass.sharedInstance.same.same.same.same.same.count != 3000) |
abort (); |
|
/* Test [object method].property. */ |
[MyRootClass sharedInstance].count = 5000; |
if ([MyRootClass sharedInstance].count != 5000) |
abort (); |
|
/* Just a final check. */ |
if (shared_root.count != 5000) |
abort (); |
|
return 0; |
} |
|
|
/property/synthesize-4.mm
0,0 → 1,67
/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, November 2010. */ |
/* { dg-do run } */ |
/* { dg-xfail-run-if "Needs OBJC2 ABI" { *-*-darwin* && { lp64 && { ! objc2 } } } { "-fnext-runtime" } { "" } } */ |
|
/* Test @synthesize for a @property where the setter/getter are also |
declared by the user. This is fine. */ |
|
#include <objc/objc.h> |
#include <objc/runtime.h> |
#include <stdlib.h> |
|
@interface MyRootClass |
{ |
Class isa; |
} |
+ (id) initialize; |
+ (id) alloc; |
- (id) init; |
@end |
|
@implementation MyRootClass |
+ (id) initialize { return self; } |
+ (id) alloc { return class_createInstance (self, 0); } |
- (id) init { return self; } |
@end |
|
@protocol MyProtocol |
@property int v1; |
@end |
|
@protocol MyProtocol2 |
@property int v2; |
@end |
|
@interface Test : MyRootClass <MyProtocol, MyProtocol2> |
{ |
int v1; |
int _v2; |
} |
- (int)v1; |
- (void)setV1: (int)aNumber; |
- (int)v2; |
@end |
|
@implementation Test |
@synthesize v1; |
@synthesize v2 = _v2; |
@end |
|
int main (void) |
{ |
Test *object = [[Test alloc] init]; |
|
/* We use dot-syntax here as this is just a general test that |
user-declared setters/getters don't cause confusion. */ |
object.v1 = 400; |
|
if (object.v1 != 400) |
abort (); |
|
object.v2 = 31; |
|
if (object.v2 != 31) |
abort (); |
|
return 0; |
} |
/property/at-property-12.mm
0,0 → 1,47
/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, October 2010. */ |
/* { dg-do run } */ |
/* { dg-xfail-run-if "Needs OBJC2 ABI" { *-*-darwin* && { lp64 && { ! objc2 } } } { "-fnext-runtime" } { "" } } */ |
|
/* Test atomic, assign synthesized methods. */ |
|
#include <stdlib.h> |
#include <objc/objc.h> |
#include <objc/runtime.h> |
|
@interface MyRootClass |
{ |
Class isa; |
int a; |
id b; |
} |
@property int a; |
@property (assign) id b; |
+ (id) initialize; |
+ (id) alloc; |
- (id) init; |
@end |
|
@implementation MyRootClass |
+ (id) initialize { return self; } |
+ (id) alloc { return class_createInstance (self, 0); } |
- (id) init { return self; } |
@synthesize a; |
@synthesize b; |
@end |
|
int main (void) |
{ |
MyRootClass *object = [[MyRootClass alloc] init]; |
|
object.a = 40; |
if (object.a != 40) |
abort (); |
|
object.b = object; |
if (object.b != object) |
abort (); |
|
return (0); |
} |
|
|
/property/at-property-22.mm
0,0 → 1,172
/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, November 2010. */ |
/* { dg-do run } */ |
/* { dg-xfail-run-if "Needs OBJC2 ABI" { *-*-darwin* && { lp64 && { ! objc2 } } } { "-fnext-runtime" } { "" } } */ |
|
/* Test properties of different types. */ |
|
#include <stdlib.h> |
#include <objc/objc.h> |
#include <objc/runtime.h> |
|
enum colour { Red, Black }; |
|
@interface MyRootClass |
{ |
Class isa; |
} |
+ (id) initialize; |
+ (id) alloc; |
- (id) init; |
+ (Class) class; |
@end |
|
@implementation MyRootClass |
+ (id) initialize { return self; } |
+ (id) alloc { return class_createInstance (self, 0); } |
- (id) init { return self; } |
+ (Class) class { return self; } |
@end |
|
|
@interface MyClass : MyRootClass |
{ |
/* A bunch of C types. */ |
char pchar; |
short pshort; |
int pint; |
long plong; |
float pfloat; |
double pdouble; |
enum colour penum; |
|
/* A bunch of pointers to C types. */ |
char *pcharp; |
short *pshortp; |
int *pintp; |
long *plongp; |
float *pfloatp; |
double *pdoublep; |
enum colour *penump; |
|
/* A bunch of Objective-C types. */ |
id pid; |
Class pclass; |
MyClass *pMyClassp; |
} |
@property (assign) char pchar; |
@property (assign) short pshort; |
@property (assign) int pint; |
@property (assign) long plong; |
@property (assign) float pfloat; |
@property (assign) double pdouble; |
@property (assign) enum colour penum; |
|
@property (assign) char *pcharp; |
@property (assign) short *pshortp; |
@property (assign) int *pintp; |
@property (assign) long *plongp; |
@property (assign) float *pfloatp; |
@property (assign) double *pdoublep; |
@property (assign) enum colour *penump; |
|
@property (assign) id pid; |
@property (assign) Class pclass; |
@property (assign) MyClass *pMyClassp; |
@end |
|
@implementation MyClass |
@synthesize pchar; |
@synthesize pshort; |
@synthesize pint; |
@synthesize plong; |
@synthesize pfloat; |
@synthesize pdouble; |
@synthesize penum; |
|
@synthesize pcharp; |
@synthesize pshortp; |
@synthesize pintp; |
@synthesize plongp; |
@synthesize pfloatp; |
@synthesize pdoublep; |
@synthesize penump; |
|
@synthesize pid; |
@synthesize pclass; |
@synthesize pMyClassp; |
@end |
|
int main (void) |
{ |
MyClass *object = [[MyClass alloc] init]; |
|
object.pchar = 1; |
if (object.pchar != 1) |
abort (); |
|
object.pshort = 2; |
if (object.pshort != 2) |
abort (); |
|
object.pint = 3; |
if (object.pint != 3) |
abort (); |
|
object.plong = 4; |
if (object.plong != 4) |
abort (); |
|
object.pfloat = 0; |
if (object.pfloat != 0) |
abort (); |
|
object.pdouble = 0; |
if (object.pdouble != 0) |
abort (); |
|
object.penum = Black; |
if (object.penum != Black) |
abort (); |
|
object.pcharp = (char *)0; |
if (object.pcharp != 0) |
abort (); |
|
object.pshortp = (short *)0; |
if (object.pshortp != 0) |
abort (); |
|
object.pintp = (int *)0; |
if (object.pintp != 0) |
abort (); |
|
object.plongp = (long *)0; |
if (object.plongp != 0) |
abort (); |
|
object.pfloatp = (float *)0; |
if (object.pfloatp != 0) |
abort (); |
|
object.pdoublep = (double *)0; |
if (object.pdoublep != 0) |
abort (); |
|
object.penump = (enum colour *)0; |
if (object.penump != 0) |
abort (); |
|
object.pid = object; |
if (object.pid != object) |
abort (); |
|
object.pclass = [MyClass class]; |
if (object.pclass != [MyClass class]) |
abort (); |
|
object.pMyClassp = object; |
if (object.pMyClassp != object) |
abort (); |
|
return 0; |
} |
/property/synthesize-8.mm
0,0 → 1,80
/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, November 2010. */ |
/* { dg-do compile } */ |
|
/* Test that when using @synthesize the instance variable and the |
property have exactly the same type. */ |
|
#include <objc/objc.h> |
|
@protocol MyProtocol |
- (void)aMethod; |
@end |
|
@interface ClassA |
@end |
|
@interface ClassB : ClassA |
@end |
|
|
/* This is all OK. */ |
@interface Test |
{ |
int v; |
float w; |
id x; |
Test *y; |
id <MyProtocol> *z; |
ClassA *a; |
ClassB *b; |
ClassA <MyProtocol> *c; |
} |
@property (assign) int v; |
@property (assign) float w; |
@property (assign) id x; |
@property (assign) Test *y; |
@property (assign) id <MyProtocol> *z; |
@property (assign) ClassA *a; |
@property (assign) ClassB *b; |
@end |
|
@implementation Test |
@synthesize v; |
@synthesize w; |
@synthesize x; |
@synthesize y; |
@synthesize z; |
@synthesize a; |
@synthesize b; |
@end |
|
|
/* This is not OK. */ |
@interface Test2 |
{ |
int v; /* { dg-message "originally specified here" } */ |
float w; /* { dg-message "originally specified here" } */ |
id x; /* { dg-message "originally specified here" } */ |
Test *y; /* { dg-message "originally specified here" } */ |
id <MyProtocol> *z; /* { dg-message "originally specified here" } */ |
ClassA *a; /* { dg-message "originally specified here" } */ |
ClassB *b; /* { dg-message "originally specified here" } */ |
} |
@property (assign) float v; |
@property (assign) id w; |
@property (assign) int x; |
@property (assign) id y; |
@property (assign) Test *z; |
@property (assign) ClassB *a; |
@property (assign) ClassA *b; |
@end |
|
@implementation Test2 |
@synthesize v; /* { dg-error "property .v. is using instance variable .v. of incompatible type" } */ |
@synthesize w; /* { dg-error "property .w. is using instance variable .w. of incompatible type" } */ |
@synthesize x; /* { dg-error "property .x. is using instance variable .x. of incompatible type" } */ |
@synthesize y; /* { dg-error "property .y. is using instance variable .y. of incompatible type" } */ |
@synthesize z; /* { dg-error "property .z. is using instance variable .z. of incompatible type" } */ |
@synthesize a; /* { dg-error "property .a. is using instance variable .a. of incompatible type" } */ |
@synthesize b; /* { dg-error "property .b. is using instance variable .b. of incompatible type" } */ |
@end |
/property/at-property-16.mm
0,0 → 1,46
/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, November 2010. */ |
/* { dg-do compile } */ |
|
#include <objc/objc.h> |
|
/* Test that if you have a property declared in a class and a |
sub-class, the attributes match. */ |
|
@interface MyRootClass |
{ |
Class isa; |
} |
@property (assign) id a; /* { dg-message "originally specified here" } */ |
@property (retain) id b; /* { dg-message "originally specified here" } */ |
@property int c; /* { dg-message "originally specified here" } */ |
@property (nonatomic) int d; /* { dg-message "originally specified here" } */ |
@property int e; /* { dg-message "originally specified here" } */ |
@property int f; /* { dg-message "originally specified here" } */ |
@property int g; /* { dg-message "originally specified here" } */ |
@property (readonly) int h; /* Ok */ |
@property (readonly,getter=getMe) int i; /* { dg-message "originally specified here" } */ |
@end |
|
@interface MyClass : MyRootClass |
@property (assign) id a; |
@property (retain) id b; |
@property int c; |
@property (nonatomic) int d; |
@property int e; |
@property int f; |
@property int g; |
@property (readonly) int h; |
@property (readonly,getter=getMe) int i; |
@end |
|
@interface MyClass2 : MyRootClass |
@property (retain) id a; /* { dg-warning "assign semantics attributes of property .a. conflict with previous declaration" } */ |
@property (assign) id b; /* { dg-warning "assign semantics attributes of property .b. conflict with previous declaration" } */ |
@property (nonatomic) int c; /* { dg-warning ".nonatomic. attribute of property .c. conflicts with previous declaration" } */ |
@property int d; /* { dg-warning ".nonatomic. attribute of property .d. conflicts with previous declaration" } */ |
@property (setter=setX:) int e; /* { dg-warning ".setter. attribute of property .e. conflicts with previous declaration" } */ |
@property (getter=x) int f; /* { dg-warning ".getter. attribute of property .f. conflicts with previous declaration" } */ |
@property (readonly) int g; /* { dg-warning ".readonly. attribute of property .g. conflicts with previous declaration" } */ |
@property (readwrite) int h; /* Ok */ |
@property (readonly) int i; /* { dg-warning ".getter. attribute of property .i. conflicts with previous declaration" } */ |
@end |
/property/at-property-26.mm
0,0 → 1,85
/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, December 2010. */ |
/* { dg-do run } */ |
/* { dg-xfail-run-if "Needs OBJC2 ABI" { *-*-darwin* && { lp64 && { ! objc2 } } } { "-fnext-runtime" } { "" } } */ |
|
/* Test @properties in class extensions. */ |
|
#include <stdlib.h> |
#include <objc/objc.h> |
#include <objc/runtime.h> |
|
@interface MyRootClass |
{ |
Class isa; |
} |
+ (id) initialize; |
+ (id) alloc; |
- (id) init; |
@end |
|
@implementation MyRootClass |
+ (id) initialize { return self; } |
+ (id) alloc { return class_createInstance (self, 0); } |
- (id) init { return self; } |
@end |
|
@protocol count4 |
/* Use a different getters/setters, so that the only way to compile |
object.countX is to find the actual @property. */ |
@property (getter=number4, setter=setNumber4:) int count4; |
@end |
|
@interface MySubClass : MyRootClass |
{ |
int count1; |
int count2; |
int count3; |
int count4; |
} |
@property (getter=number1, setter=setNumber1:) int count1; |
@end |
|
@interface MySubClass () |
@property (getter=number2, setter=setNumber2:) int count2; |
@end |
|
@interface MySubClass () <count4> |
@property (getter=number3, setter=setNumber3:) int count3; |
@end |
|
@implementation MySubClass |
@synthesize count1; |
@synthesize count2; |
- (int) number3 |
{ |
return count3; |
} |
- (void) setNumber3: (int)value |
{ |
count3 = value; |
} |
@synthesize count4; |
@end |
|
int main (void) |
{ |
MySubClass *object = [[MySubClass alloc] init]; |
|
object.count1 = 20; |
if (object.count1 != 20) |
abort (); |
|
object.count2 = 11; |
if (object.count2 != 11) |
abort (); |
|
object.count3 = 19; |
if (object.count3 != 19) |
abort (); |
|
object.count4 = 74; |
if (object.count4 != 74) |
abort (); |
|
return 0; |
} |
/property/dotsyntax-12.mm
0,0 → 1,105
/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, November 2010. */ |
/* { dg-do run } */ |
/* { dg-xfail-run-if "Needs OBJC2 ABI" { *-*-darwin* && { lp64 && { ! objc2 } } } { "-fnext-runtime" } { "" } } */ |
|
/* Test looking up a setter or getter which are in a protocol attached |
to a category of a superclass. */ |
|
#include <stdlib.h> |
#include <objc/objc.h> |
#include <objc/runtime.h> |
|
static int c; |
|
@interface MyRootClass |
{ |
Class isa; |
int a; |
} |
+ (id) initialize; |
+ (id) alloc; |
- (id) init; |
@end |
|
@implementation MyRootClass |
+ (id) initialize { return self; } |
+ (id) alloc { return class_createInstance (self, 0); } |
- (id) init { return self; } |
@end |
|
@protocol count |
- (int) count; |
- (void) setCount: (int)count; |
@end |
|
@protocol classCount |
+ (int) classCount; |
+ (void) setClassCount: (int)count; |
@end |
|
@interface MyRootClass (Category) <count, classCount> |
@end |
|
@implementation MyRootClass (Category) |
- (int) count |
{ |
return a; |
} |
- (void) setCount: (int)count |
{ |
a = count; |
} |
+ (int) classCount |
{ |
return c; |
} |
+ (void) setClassCount: (int)count |
{ |
c = count; |
} |
@end |
|
@interface MySubClass : MyRootClass |
+ (int) testMe; |
- (int) testMe; |
@end |
|
@implementation MySubClass |
- (int) testMe |
{ |
self.count = 400; |
if (self.count != 400) |
abort (); |
|
return self.count; |
} |
+ (int) testMe |
{ |
self.classCount = 4000; |
if (self.classCount != 4000) |
abort (); |
|
return self.classCount; |
} |
@end |
|
int main (void) |
{ |
MySubClass *object = [[MySubClass alloc] init]; |
|
object.count = 44; |
if (object.count != 44) |
abort (); |
|
MySubClass.classCount = 40; |
if (MySubClass.classCount != 40) |
abort (); |
|
if ([object testMe] != 400) |
abort (); |
|
if ([MySubClass testMe] != 4000) |
abort (); |
|
return 0; |
} |
/property/dotsyntax-22.mm
0,0 → 1,19
/* PR objc/47784. This testcase used to crash the compiler. */ |
|
typedef struct { |
float x; |
} SomeType; |
|
@interface MyClass |
|
@property(assign,readwrite) SomeType position; |
|
@end |
|
void example (MyClass *x) |
{ |
const SomeType SomeTypeZero = {0.0f}; |
|
x.position= SomeTypeZero; |
} |
|
/property/fsf-property-basic.mm
0,0 → 1,70
/* Basic test, auto-generated getter/setter based on property name. */ |
/* { dg-do run } */ |
/* { dg-xfail-run-if "Needs OBJC2 ABI" { *-*-darwin* && { lp64 && { ! objc2 } } } { "-fnext-runtime" } { "" } } */ |
|
#ifdef __cplusplus |
extern "C" { |
#endif |
|
extern int printf (const char *fmt,...); |
extern void abort (void); |
|
#include <objc/objc.h> |
#include <objc/runtime.h> |
|
#ifdef __cplusplus |
} |
#endif |
|
@interface Bar |
{ |
@public |
Class isa; |
int FooBar; |
} |
+ (id) initialize; |
+ (id) alloc ; |
- (id) init; |
- (int) whatIsFooBar; |
@property int FooBar; |
@end |
|
@implementation Bar |
|
+initialize { return self;} |
+ (id) alloc { return class_createInstance (self, 0); } |
|
- (id) init {return self;} |
|
- (int) whatIsFooBar { return self->FooBar; } |
@synthesize FooBar; |
@end |
|
int main(int argc, char *argv[]) { |
int res; |
Bar *f = [[Bar alloc] init]; |
|
/* First, establish that the property getter & setter have been synthesized |
and operate correctly. */ |
[f setFooBar:1]; |
|
if ([f whatIsFooBar] != 1) |
{ printf ("setFooBar did not set FooBar\n"); abort ();} |
|
res = [f FooBar]; |
|
if (res != 1 ) |
{ printf ("[f FooBar] = %d\n", res); abort ();} |
|
/* Now check the short-cut object.property syntax. */ |
/* Read... */ |
res = f.FooBar; |
if (res != 1 ) |
{ printf ("f.FooBar = %d\n", res); abort ();} |
|
/* .... write. */ |
f.FooBar = 0; |
/* printf ("seems OK\n", res); */ |
return f.FooBar; |
} |
|
/property/dotsyntax-16.mm
0,0 → 1,91
/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, November 2010. */ |
/* { dg-do run } */ |
/* { dg-xfail-run-if "Needs OBJC2 ABI" { *-*-darwin* && { lp64 && { ! objc2 } } } { "-fnext-runtime" } { "" } } */ |
|
/* Test dot-syntax with pre/post increment and decrement. */ |
|
#include <stdlib.h> |
#include <objc/objc.h> |
#include <objc/runtime.h> |
|
@interface MyRootClass |
{ |
Class isa; |
int a; |
} |
+ (id) initialize; |
+ (id) alloc; |
- (id) init; |
- (int) count; |
- (void) setCount: (int)count; |
@end |
|
@implementation MyRootClass |
+ (id) initialize { return self; } |
+ (id) alloc { return class_createInstance (self, 0); } |
- (id) init { return self; } |
- (int) count |
{ |
return a; |
} |
- (void) setCount: (int)count |
{ |
a = count; |
} |
@end |
|
int main (void) |
{ |
MyRootClass *object = [[MyRootClass alloc] init]; |
|
object.count = 10; |
if (object.count != 10) |
abort (); |
|
/* First, test that they increment/decrement as expected. */ |
object.count++; |
if (object.count != 11) |
abort (); |
|
++object.count; |
if (object.count != 12) |
abort (); |
|
object.count--; |
if (object.count != 11) |
abort (); |
|
--object.count; |
if (object.count != 10) |
abort (); |
|
/* Now, test that they are pre/post increment/decrement, as |
expected. */ |
if (object.count++ != 10) |
abort (); |
|
if (object.count != 11) |
abort (); |
|
if (++object.count != 12) |
abort (); |
|
if (object.count != 12) |
abort (); |
|
if (object.count-- != 12) |
abort (); |
|
if (object.count != 11) |
abort (); |
|
if (--object.count != 10) |
abort (); |
|
if (object.count != 10) |
abort (); |
|
return 0; |
} |
|
|
/property/fsf-property-named-ivar.mm
0,0 → 1,69
/* Basic test, auto-generated getter/setter based on named ivar */ |
/* { dg-do run } */ |
/* { dg-xfail-run-if "Needs OBJC2 ABI" { *-*-darwin* && { lp64 && { ! objc2 } } } { "-fnext-runtime" } { "" } } */ |
|
#ifdef __cplusplus |
extern "C" { |
#endif |
|
extern int printf (const char *fmt,...); |
extern void abort (void); |
|
#include <objc/objc.h> |
#include <objc/runtime.h> |
|
#ifdef __cplusplus |
} |
#endif |
|
@interface Bar |
{ |
@public |
Class isa; |
int var; |
} |
+ (id) initialize; |
+ (id) alloc ; |
- (id) init; |
|
@property int FooBar; |
@end |
|
@implementation Bar |
|
+initialize { return self;} |
+ (id) alloc { return class_createInstance (self, 0); } |
|
- (id) init {return self;} |
|
@synthesize FooBar = var; |
@end |
|
int main(int argc, char *argv[]) { |
int res; |
Bar *f = [[Bar alloc] init]; |
|
/* First, establish that the property getter & setter have been synthesized |
and operate correctly. */ |
[f setFooBar:1234]; |
|
if (f->var != 1234) |
{ printf ("setFooBar did not set var correctly\n"); abort ();} |
|
res = [f FooBar]; |
|
if (res != 1234 ) |
{ printf ("[f FooBar] = %d\n", res); abort ();} |
|
/* Now check the short-cut object.property syntax. */ |
/* Read .... */ |
res = f.FooBar; |
if (res != 1234 ) |
{ printf ("f.FooBar = %d\n", res); abort ();} |
|
/* ... and write. */ |
f.FooBar = 0; |
/* printf ("seems OK\n", res); */ |
return f.FooBar; |
} |
|
/property/cxx-property-1.mm
0,0 → 1,10
/* Testcase from PR obj-c++/48275. */ |
/* { dg-do compile } */ |
|
@interface Test |
{ |
int ns; |
} |
@property (getter=namespace) int ns; |
|
@end |
/property/synthesize-10.mm
0,0 → 1,53
/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, November 2010. */ |
/* { dg-do run } */ |
/* { dg-xfail-run-if "Needs OBJC2 ABI" { *-*-darwin* && { lp64 && { ! objc2 } } } { "-fnext-runtime" } { "" } } */ |
|
/* Test @synthesize with bitfield instance variables. */ |
|
#include <stdlib.h> |
#include <objc/objc.h> |
#include <objc/runtime.h> |
|
@interface MyRootClass |
{ |
Class isa; |
int countA : 2; |
int countB : 3; |
int countC : 4; |
} |
+ (id) initialize; |
+ (id) alloc; |
- (id) init; |
@property (nonatomic) int countA; |
@property (nonatomic) int countB; |
@property (nonatomic) int countC; |
@end |
|
@implementation MyRootClass |
+ (id) initialize { return self; } |
+ (id) alloc { return class_createInstance (self, 0); } |
- (id) init { return self; } |
@synthesize countA; |
@synthesize countB; |
@synthesize countC; |
@end |
|
int main (void) |
{ |
MyRootClass *object = [[MyRootClass alloc] init]; |
|
object.countA = 1; |
object.countB = 3; |
object.countC = 4; |
|
if (object.countA != 1) |
abort (); |
|
if (object.countB != 3) |
abort (); |
|
if (object.countC != 4) |
abort (); |
|
return 0; |
} |
/property/dynamic-4.mm
0,0 → 1,45
/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, November 2010. */ |
/* { dg-do compile } */ |
|
#include <objc/objc.h> |
|
@interface MyRootClass |
{ |
Class isa; |
} |
@end |
|
@implementation MyRootClass |
@end |
|
/* Test @property/@dynamic with protocols. */ |
|
@protocol MyProtocol |
@property int a; |
@end |
|
|
/* This class is declared to conform to the protocol, but because of |
@dynamic, no warnings are issued even if the getter/setter for the |
@property are missing. */ |
@interface MyClass1 : MyRootClass <MyProtocol> |
@end |
|
@implementation MyClass1 |
@dynamic a; |
@end |
|
|
/* This class is declared to conform to the protocol and warnings are |
issued because the setter for the @property is missing. */ |
@interface MyClass2 : MyRootClass <MyProtocol> |
@end |
|
@implementation MyClass2 |
- (int) a |
{ |
return 0; |
} |
@end /* { dg-warning "incomplete implementation" } */ |
/* { dg-warning "method definition for .-setA:. not found" "" { target *-*-* } 43 } */ |
/* { dg-warning "class .MyClass2. does not fully implement the .MyProtocol. protocol" "" { target *-*-* } 43 } */ |
/property/at-property-4.mm
0,0 → 1,40
/* { dg-do compile } */ |
|
#include <objc/objc.h> |
|
@interface MyRootClass |
{ |
Class isa; |
} |
- (int) myGetter; |
- (int) myGetterB; |
- (int) myGetter2; |
- (void) mySetter: (int)property; |
- (void) mySetterB: (int)property; |
- (void) mySetter2: (int)property; |
|
/* Test that all the new property attributes can be parsed. */ |
@property (assign) id property_a; |
@property (copy) id property_b; |
@property (nonatomic) int property_c; |
@property (readonly) int property_d; |
@property (readwrite) int property_e; |
@property (retain) id property_f; |
@property (release) int property_g; /* { dg-error "unknown property attribute" } */ |
|
@property (getter=myGetter) int property_h; |
@property (setter=mySetter:) int property_i; |
|
/* Now test various problems. */ |
|
@property (readonly, readwrite) int a; /* { dg-error ".readonly. attribute conflicts with .readwrite. attribute" } */ |
@property (readonly, setter=mySetterB:) int b; /* { dg-error ".readonly. attribute conflicts with .setter. attribute" } */ |
|
@property (assign, retain) id c; /* { dg-error ".assign. attribute conflicts with .retain. attribute" } */ |
@property (assign, copy) id d; /* { dg-error ".assign. attribute conflicts with .copy. attribute" } */ |
@property (copy, retain) id e; /* { dg-error ".retain. attribute conflicts with .copy. attribute" } */ |
|
@property (setter=mySetter:,setter=mySetter2:) int f; /* { dg-error ".setter. attribute may only be specified once" } */ |
@property (getter=myGetter, getter=myGetter2 ) int g; /* { dg-error ".getter. attribute may only be specified once" } */ |
|
@end |
/property/property-neg-2.mm
0,0 → 1,8
/* { dg-do compile } */ |
|
@interface Bar |
@end |
|
@implementation Bar |
@property int FooBar; /* { dg-error "property declaration not in @interface or @protocol context" } */ |
@end |
/property/dotsyntax-1.mm
0,0 → 1,63
/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, November 2010. */ |
/* { dg-do run } */ |
/* { dg-xfail-run-if "Needs OBJC2 ABI" { *-*-darwin* && { lp64 && { ! objc2 } } } { "-fnext-runtime" } { "" } } */ |
|
/* Test the 'dot syntax' without a declarated property. */ |
|
#include <stdlib.h> |
#include <objc/objc.h> |
#include <objc/runtime.h> |
|
@interface MyRootClass |
{ |
Class isa; |
int a; |
id b; |
} |
+ (id) initialize; |
+ (id) alloc; |
- (id) init; |
- (int) count; |
- (void) setCount: (int)value; |
- (id) next; |
- (void) setNext: (id)value; |
@end |
|
@implementation MyRootClass |
+ (id) initialize { return self; } |
+ (id) alloc { return class_createInstance (self, 0); } |
- (id) init { return self; } |
- (int) count |
{ |
return a; |
} |
- (void) setCount: (int)value |
{ |
a = value; |
} |
- (id) next |
{ |
return b; |
} |
- (void) setNext: (id)value |
{ |
b = value; |
} |
@end |
|
int main (void) |
{ |
MyRootClass *object = [[MyRootClass alloc] init]; |
|
object.count = 40; |
if (object.count != 40) |
abort (); |
|
object.next = object; |
if (object.next != object) |
abort (); |
|
return 0; |
} |
|
|
/property/at-property-8.mm
0,0 → 1,58
/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, October 2010. */ |
/* { dg-do run } */ |
/* { dg-xfail-run-if "Needs OBJC2 ABI" { *-*-darwin* && { lp64 && { ! objc2 } } } { "-fnext-runtime" } { "" } } */ |
|
/* Test the property syntax with non-synthesized setter/getter |
and with a non-standard name for the setter. */ |
|
#include <stdlib.h> |
#include <objc/objc.h> |
#include <objc/runtime.h> |
|
@interface MyRootClass |
{ |
Class isa; |
int a; |
} |
@property (setter = writeA:, nonatomic) int a; |
+ (id) initialize; |
+ (id) alloc; |
- (id) init; |
@end |
|
@implementation MyRootClass |
+ (id) initialize { return self; } |
+ (id) alloc { return class_createInstance (self, 0); } |
- (id) init { return self; } |
|
- (int) a |
{ |
return a; |
} |
- (void) writeA: (int)value |
{ |
a = value; |
} |
@end |
|
int main (void) |
{ |
MyRootClass *object = [[MyRootClass alloc] init]; |
|
object.a = 14; |
|
if (object.a != 14) |
abort (); |
|
object.a = 23; |
|
if (object.a != 23) |
abort (); |
|
object.a = 78; |
|
if (object.a != 78) |
abort (); |
|
return (0); |
} |
/property/property-neg-6.mm
0,0 → 1,9
/* Check for proper declaration of @property. */ |
/* { dg-do compile } */ |
|
@interface Bar |
{ |
int iVar; |
} |
@property int FooBar /* { dg-error "expected ';' at end of input" } */ |
/* { dg-error "expected '@end' at end of input" "" { target *-*-* } 8 } */ |
/property/dotsyntax-5.mm
0,0 → 1,78
/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, November 2010. */ |
/* { dg-do run } */ |
/* { dg-xfail-run-if "Needs OBJC2 ABI" { *-*-darwin* && { lp64 && { ! objc2 } } } { "-fnext-runtime" } { "" } } */ |
|
/* Test the 'dot syntax' with self, both in instance and class methods. */ |
|
#include <stdlib.h> |
#include <objc/objc.h> |
#include <objc/runtime.h> |
|
static int c; |
|
@interface MyRootClass |
{ |
Class isa; |
int a; |
} |
+ (id) initialize; |
+ (id) alloc; |
- (id) init; |
- (int) count; |
- (void) setCount: (int)count; |
+ (int) classCount; |
+ (void) setClassCount: (int)count; |
@end |
|
@implementation MyRootClass |
+ (id) initialize { return self; } |
+ (id) alloc { return class_createInstance (self, 0); } |
- (id) init { return self; } |
- (int) count |
{ |
return a; |
} |
- (void) setCount: (int)count |
{ |
a = count; |
} |
+ (int) classCount |
{ |
return c; |
} |
+ (void) setClassCount: (int)count |
{ |
c = count; |
} |
- (int) testMe |
{ |
self.count = 400; |
if (self.count != 400) |
abort (); |
|
return self.count; |
} |
+ (int) testMe |
{ |
self.classCount = 4000; |
if (self.classCount != 4000) |
abort (); |
|
return self.classCount; |
} |
@end |
|
int main (void) |
{ |
MyRootClass *object = [[MyRootClass alloc] init]; |
|
if ([object testMe] != 400) |
abort (); |
|
if ([MyRootClass testMe] != 4000) |
abort (); |
|
return 0; |
} |
|
|
/property/dotsyntax-9.mm
0,0 → 1,77
/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, November 2010. */ |
/* { dg-do run } */ |
/* { dg-xfail-run-if "Needs OBJC2 ABI" { *-*-darwin* && { lp64 && { ! objc2 } } } { "-fnext-runtime" } { "" } } */ |
|
/* Test that setter/getters for dot-syntax are properly found even if |
not declared in the @interface, but available in the local |
@implementation before the current line (ie, [object name] can be |
compiled in that case, so object.name should be compiled too). */ |
|
#include <stdlib.h> |
#include <objc/objc.h> |
#include <objc/runtime.h> |
|
static int c; |
|
@interface MyRootClass |
{ |
Class isa; |
int a; |
} |
+ (id) initialize; |
+ (id) alloc; |
- (id) init; |
@end |
|
@implementation MyRootClass |
+ (id) initialize { return self; } |
+ (id) alloc { return class_createInstance (self, 0); } |
- (id) init { return self; } |
- (int) count |
{ |
return a; |
} |
- (void) setCount: (int)count |
{ |
a = count; |
} |
+ (int) classCount |
{ |
return c; |
} |
+ (void) setClassCount: (int)count |
{ |
c = count; |
} |
- (int) testMe |
{ |
self.count = 400; |
if (self.count != 400) |
abort (); |
|
return self.count; |
} |
+ (int) testMe |
{ |
self.classCount = 4000; |
if (self.classCount != 4000) |
abort (); |
|
return self.classCount; |
} |
@end |
|
int main (void) |
{ |
MyRootClass *object = [[MyRootClass alloc] init]; |
|
if ([object testMe] != 400) |
abort (); |
|
if ([MyRootClass testMe] != 4000) |
abort (); |
|
return 0; |
} |
|
|
/property/at-property-11.mm
0,0 → 1,44
/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, October 2010. */ |
/* { dg-do run } */ |
/* { dg-xfail-run-if "Needs OBJC2 ABI" { *-*-darwin* && { lp64 && { ! objc2 } } } { "-fnext-runtime" } { "" } } */ |
|
/* Test that properties are found even if implemented in superclasses. */ |
|
#include <stdlib.h> |
#include <objc/objc.h> |
#include <objc/runtime.h> |
|
@interface MyRootClass |
{ |
Class isa; |
int a; |
} |
@property (nonatomic) int a; |
+ (id) initialize; |
+ (id) alloc; |
- (id) init; |
@end |
|
@implementation MyRootClass |
+ (id) initialize { return self; } |
+ (id) alloc { return class_createInstance (self, 0); } |
- (id) init { return self; } |
@synthesize a; |
@end |
|
@interface MySubClass : MyRootClass |
@end |
|
@implementation MySubClass |
@end |
|
int main (void) |
{ |
MySubClass *object = [[MySubClass alloc] init]; |
|
object.a = 40; |
if (object.a != 40) |
abort (); |
|
return (0); |
} |
/property/synthesize-3.mm
0,0 → 1,66
/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, November 2010. */ |
/* { dg-do run } */ |
/* { dg-xfail-run-if "Needs OBJC2 ABI" { *-*-darwin* && { lp64 && { ! objc2 } } } { "-fnext-runtime" } { "" } } */ |
|
/* Test @synthesize for a @property which is not declared directly in |
the @interface, but in a @protocol that the @interface conforms |
to. */ |
|
#include <objc/objc.h> |
#include <objc/runtime.h> |
#include <stdlib.h> |
|
@interface MyRootClass |
{ |
Class isa; |
} |
+ (id) initialize; |
+ (id) alloc; |
- (id) init; |
@end |
|
@implementation MyRootClass |
+ (id) initialize { return self; } |
+ (id) alloc { return class_createInstance (self, 0); } |
- (id) init { return self; } |
@end |
|
@protocol MyProtocol |
@property int v1; |
@end |
|
@protocol MyProtocol2 |
@property int v2; |
@end |
|
@interface Test : MyRootClass <MyProtocol, MyProtocol2> |
{ |
int v1; |
int _v2; |
} |
@end |
|
@implementation Test |
@synthesize v1; |
@synthesize v2 = _v2; |
@end |
|
int main (void) |
{ |
Test *object = [[Test alloc] init]; |
|
/* Check that the synthesized methods exist and work. Do not invoke |
them via property syntax - that is another test. Here we just |
want to test the synthesis of the methods. */ |
[object setV1: 400]; |
|
if ([object v1] != 400) |
abort (); |
|
[object setV2: 31]; |
|
if ([object v2] != 31) |
abort (); |
|
return 0; |
} |
/property/at-property-21.mm
0,0 → 1,23
/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, November 2010. */ |
/* { dg-do compile } */ |
|
#include <objc/objc.h> |
|
@protocol MyProtocol |
- (void) message; |
@end |
|
@interface MyRootClass |
{ |
Class isa; |
} |
|
/* Test the warnings on 'assign' with protocols. */ |
@property id <MyProtocol> property_a; /* { dg-warning "object property .property.a. has no .assign., .retain. or .copy. attribute" } */ |
/* { dg-message ".assign. can be unsafe for Objective-C objects" "" { target *-*-* } 16 } */ |
|
@property MyRootClass <MyProtocol> *property_b; /* { dg-warning "object property .property.b. has no .assign., .retain. or .copy. attribute" } */ |
/* { dg-message ".assign. can be unsafe for Objective-C objects" "" { target *-*-* } 19 } */ |
|
@property Class <MyProtocol> property_c; /* No 'assign' warning (Classes are static objects so assign semantics do not matter for them). */ |
@end |
/syntax-error-2.mm
0,0 → 1,16
/* Recover gracefully from a syntax error. */ |
|
@implementation Whatever /* { dg-warning "cannot find interface declaration for .Whatever." } */ |
|
- (void) function |
{ |
if( 1 ) |
{ |
else /* { dg-error "expected .\}. before .else." } */ |
{ |
} |
} |
|
- (void) another {} |
|
@end |
/method-conflict-1.mm
0,0 → 1,26
/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, December 2010. */ |
/* { dg-do compile } */ |
|
#include <objc/objc.h> |
|
/* Test that you can not declare two methods, in the same protocol, |
with the same name but conflicting method signatures. */ |
|
@protocol MyProtocol |
+ (int) method1: (int)x; /* { dg-message "previous declaration" } */ |
+ (float) method1: (int)x; /* { dg-error "duplicate declaration of method .\\+method1." } */ |
|
- (int) method2: (int)x; /* { dg-message "previous declaration" } */ |
- (int) method2: (float)x; /* { dg-error "duplicate declaration of method .\\-method2." } */ |
|
@optional |
+ (int *) method3: (int)x; /* { dg-message "previous declaration" } */ |
+ (int *) method3: (int **)x; /* { dg-error "duplicate declaration of method .\\+method3." } */ |
|
- (id) method4: (id)x; /* { dg-message "previous declaration" } */ |
- (void) method4: (id)x; /* { dg-error "duplicate declaration of method .\\-method4." } */ |
@end |
|
/* We don't test conflicting types between @required and @optional |
methods, as that is tested in method-conflict-2. */ |
|
/protocol-qualifier-2.mm
0,0 → 1,31
/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, November 2010. */ |
/* { dg-do compile } */ |
|
/* Test that protocol qualifiers are maintained correctly when a |
@class is replaced by its @interface. */ |
|
#include <objc/objc.h> |
|
@protocol MyProtocol |
- (void) method; |
@end |
|
@class MyClass; |
|
static MyClass <MyProtocol> *object1; |
static MyClass *object2; |
|
/* Declarating the @interface now will need to update all the existing |
ObjC types referring to MyClass with the new information. We need |
to test that protocol information is not lost in the process. */ |
@interface MyClass |
@end |
|
void test1 (void) |
{ |
[object1 method]; /* Ok */ |
[object2 method]; /* { dg-warning ".MyClass. may not respond to ..method." } */ |
/* { dg-warning "without a matching method" "" { target *-*-* } 27 } */ |
/* { dg-warning "will be assumed to return" "" { target *-*-* } 27 } */ |
/* { dg-warning "as arguments" "" { target *-*-* } 27 } */ |
} |
/method-3.mm
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]; |
} |
/selector-5.mm
0,0 → 1,13
/* { dg-options "" } */ |
/* { dg-do compile } */ |
|
#include <objc/objc.h> |
|
int main() |
{ |
SEL foo = @selector(foo::); |
return 0; |
} |
|
/* { dg-final { scan-assembler "foo::" } } */ |
|
/protocol-optional-1.mm
0,0 → 1,48
/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, November 2010. */ |
/* { dg-do compile } */ |
|
#include <objc/objc.h> |
|
/* Test that @optional for @protocol works. */ |
|
@protocol MyProtocol |
+ (int)classMethod; |
- (int)method; |
@optional |
+ (int)optionalClassMethod; |
- (int)optionalMethod; |
@end |
|
@interface MyRootClass <MyProtocol> |
@end |
|
/* The implementation implements both the @required methods, but none |
of the @optional ones. There should be no warnings as the |
@optional methods are optional. ;-) */ |
@implementation MyRootClass |
+ (int)classMethod |
{ |
return 20; |
} |
- (int)method |
{ |
return 11; |
} |
@end |
|
int function (id <MyProtocol> object1, |
MyRootClass *object2) |
{ |
/* Test that there are no warnings if you try to use an @optional |
method with an object of the class. */ |
int i = 0; |
|
i += [object1 method]; |
i += [object2 method]; |
i += [MyRootClass classMethod]; |
i += [object1 optionalMethod]; |
i += [object2 optionalMethod]; |
i += [MyRootClass optionalClassMethod]; |
|
return i; |
} |
/try-catch-16.mm
0,0 → 1,20
/* Test if addition of 'volatile' to object causes bogus error in presence of try-catch. */ |
/* { dg-options "-fobjc-exceptions" } */ |
/* { dg-do compile } */ |
|
extern void func( void * outData) ; |
struct Point { |
short v; |
short h; |
}; |
|
|
void foo () |
{ |
Point eventLocation; |
@try { |
} @catch (id iiii) { |
} |
|
func( &eventLocation ); |
} |
/exceptions-5.mm
0,0 → 1,115
/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, November 2010. */ |
/* { dg-options "-fobjc-exceptions" } */ |
/* { dg-do compile } */ |
|
/* Test that you can use an unnamed argument with @catch. This test is the same |
as exceptions-3.mm, but with no name for @catch arguments. */ |
|
#include <objc/objc.h> |
|
@interface MyObject |
{ |
Class isa; |
} |
@end |
|
@implementation MyObject |
@end |
|
@protocol MyProtocol; |
|
typedef MyObject MyObjectTypedef; |
typedef MyObject *MyObjectPtrTypedef; |
typedef int intTypedef; |
|
int test (id object) |
{ |
int dummy = 0; |
|
@try { @throw object; } |
@catch (int) /* { dg-error "@catch parameter is not a known Objective-C class type" } */ |
{ |
dummy++; |
} |
|
@try { @throw object; } |
@catch (intTypedef) /* { dg-error "@catch parameter is not a known Objective-C class type" } */ |
{ |
dummy++; |
} |
|
@try { @throw object; } |
@catch (int *) /* { dg-error "@catch parameter is not a known Objective-C class type" } */ |
{ |
dummy++; |
} |
|
@try { @throw object; } |
@catch (id) /* Ok */ |
{ |
dummy++; |
} |
|
@try { @throw object; } |
@catch (id <MyProtocol>) /* { dg-error "@catch parameter can not be protocol-qualified" } */ |
{ |
dummy++; |
} |
|
@try { @throw object; } |
@catch (MyObject *) /* Ok */ |
{ |
dummy++; |
} |
|
@try { @throw object; } |
@catch (MyObject <MyProtocol> *) /* { dg-error "@catch parameter can not be protocol-qualified" } */ |
{ |
dummy++; |
} |
|
@try { @throw object; } |
@catch (MyObject) /* { dg-error "@catch parameter is not a known Objective-C class type" } */ |
{ /* { dg-error "no matching function" "" { target *-*-* } 72 } */ |
dummy++; /* { dg-message "MyObject" "" { target *-*-* } 13 } */ |
} /* { dg-message "candidate" "" { target *-*-* } 13 } */ |
/* { dg-message "candidate" "" { target *-*-* } 72 } */ |
|
@try { @throw object; } |
@catch (static MyObject *) /* { dg-error "storage class" } */ |
{ |
dummy++; |
} |
|
@try { @throw object; } |
@catch (MyObjectTypedef *) /* Ok */ |
{ |
dummy++; |
} |
|
@try { @throw object; } |
@catch (MyObjectTypedef <MyProtocol> *) /* { dg-error "@catch parameter can not be protocol-qualified" } */ |
{ |
dummy++; |
} |
|
@try { @throw object; } |
@catch (MyObjectPtrTypedef) /* Ok */ |
{ |
dummy++; |
} |
|
@try { @throw object; } |
@catch (Class) /* { dg-error "@catch parameter is not a known Objective-C class type" } */ |
{ |
dummy++; |
} |
|
@try { @throw object; } |
@catch (...) /* Ok */ |
{ |
dummy++; |
} |
|
return dummy; |
} |
/cxx-ivars-3.mm
0,0 → 1,54
// Check if ObjC classes with non-POD C++ ivars are specially marked in the metadata. |
|
// { dg-do run { target *-*-darwin* } } |
// { dg-skip-if "" { *-*-* } { "-fgnu-runtime" } { "" } } |
// { dg-options "-fobjc-call-cxx-cdtors -mmacosx-version-min=10.4" } |
// This test has no equivalent or meaning for m64/ABI V2 |
// { dg-xfail-run-if "No Test Avail" { *-*-darwin* && lp64 } { "-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) |
{ |
#ifndef __LP64__ |
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)); |
|
#else |
/* No test needed or available. */ |
abort (); |
#endif |
return 0; |
} |
/method-lookup-1.mm
0,0 → 1,94
/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, June 2011. */ |
/* { dg-do compile } */ |
|
@class NotKnown; |
|
@protocol MyProtocol |
+ (id) classMethod; |
- (id) instanceMethod; |
@end |
|
@protocol MyProtocol2 |
+ (id) classMethod2; |
- (id) instanceMethod2; |
@end |
|
void test (Class x, Class <MyProtocol> y, id w, id <MyProtocol> z, NotKnown *a, NotKnown <MyProtocol> *b) |
{ |
/* "Class x" means that "x" responds to any class methods, and may |
also respond to instance methods because instance methods of the |
root class are class methods. */ |
[x classMethod]; /* No warning here. */ |
|
[x instanceMethod]; /* No warning here. */ |
|
|
/* "Class <MyProtocol> y" means that "y" responds to any class |
methods specified in the protocol MyProtocol, but not to other |
class or instance methods. If a class method is not found, an |
instance method from the protocol may be used instead but that is |
suspicious and gets a warning. */ |
[y classMethod]; /* No warning here. */ |
|
[y instanceMethod]; /* { dg-warning "found .\\-instanceMethod. instead of .\\+instanceMethod. in protocol" } */ |
|
[y classMethod2]; /* { dg-warning ".\\+classMethod2. not found in protocol" } */ |
|
[y instanceMethod2]; /* { dg-warning ".\\+instanceMethod2. not found in protocol" } */ |
|
|
/* If a class is specified by name, the @interface must be available |
to check what it responds to. */ |
[NotKnown classMethod]; /* { dg-warning ".interface of class .NotKnown. not found" } */ |
|
|
/* "id w" means that "w" responds to anything, both class and |
instance methods. */ |
[w instanceMethod]; /* No warning here. */ |
|
[w instanceMethod2]; /* No warning here. */ |
|
[w classMethod]; /* No warning here. */ |
|
[w classMethod2]; /* No warning here. */ |
|
|
/* "id <MyProtocol> z" means that "z" responds to any instance |
methods in the protocol, but not class methods. To select class |
methods, you use "Class <MyProtocol> z". */ |
[z instanceMethod]; /* No warning here. */ |
|
[z instanceMethod2]; /* { dg-warning ".\\-instanceMethod2. not found in protocol" } */ |
|
[z classMethod]; /* { dg-warning ".\\-classMethod. not found in protocol" } */ |
|
[z classMethod2]; /* { dg-warning ".\\-classMethod2. not found in protocol" } */ |
|
|
/* "NotKnown *a" means that "a" is an instance of NotKnown. Since |
the programmer explicitly specified the class name, it must be |
because they expect the compiler to do type-checking; the |
@interface must be available to do this check, otherwise the |
compiler does not know what "a" responds to. */ |
[a instanceMethod]; /* { dg-warning ".interface of class .NotKnown. not found" } */ |
|
/* But, if you cast it to "id", then you're disabling type-checking |
and the warnings should go away. */ |
[(id)a instanceMethod]; /* No warning here. */ |
|
|
/* "NotKnown <MyProtocol> *b" means that "a" is an instance of |
NotKnown, and also implements protocol <MyProtocol>. If you send |
a message that is part of the protocol, then the compiler can do |
type-checking and all is fine. */ |
[b instanceMethod]; |
|
/* But if you send a message that is not part of the protocol, then |
you'll get a warning that the method can not be found in the |
protocol. */ |
[b instanceMethod2]; /* { dg-warning ".\\-instanceMethod2. not found in protocol" } */ |
|
/* But, if you cast it to "id", then you're disabling type-checking |
and the warnings should go away. */ |
[(id)b instanceMethod2]; /* No warning here. */ |
} |
/pr24393.mm
0,0 → 1,10
/* { dg-do compile } */ |
#include <objc/objc.h> |
|
@interface Foo |
{ |
Class isa; |
} |
- (void) doSomething:(id object; /* { dg-error "xpected .\\)." } */ |
- (void) someOtherMethod; |
@end |
/protocol-inheritance-2.mm
0,0 → 1,57
/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, November 2010. */ |
/* { dg-do compile } */ |
|
#include <objc/objc.h> |
|
/* Test standard warnings when a class conforms to a protocol but some |
methods are implemented in the superclass. Use -Wno-protocol to |
turn these off. */ |
|
@protocol MyProtocol |
- (int)method; |
@end |
|
@protocol MyProtocol2 |
- (int)method2; |
@end |
|
/* The superclass implements the method required by the protocol. */ |
@interface MyRootClass |
{ |
Class isa; |
} |
- (int)method; |
@end |
|
@implementation MyRootClass |
- (int)method |
{ |
return 23; |
} |
@end |
|
/* The subclass inherits the method (does not implement it directly) |
and unless -Wno-protocol is used, we emit a warning. */ |
@interface MySubClass : MyRootClass <MyProtocol> |
@end |
|
@implementation MySubClass |
@end |
|
/* { dg-warning "incomplete implementation of class .MySubClass." "" { target *-*-* } 39 } */ |
/* { dg-warning "method definition for .\\-method. not found" "" { target *-*-* } 39 } */ |
/* { dg-warning "class .MySubClass. does not fully implement the .MyProtocol. protocol" "" { target *-*-* } 39 } */ |
|
|
/* The subclass instead does not inherit the method method2 (and does |
not implement it directly) so it does not conform to the |
protocol MyProtocol2. */ |
@interface MySubClass2 : MyRootClass <MyProtocol2> |
@end |
|
@implementation MySubClass2 |
@end /* Warnings here, below. */ |
|
/* { dg-warning "incomplete implementation of class .MySubClass2." "" { target *-*-* } 53 } */ |
/* { dg-warning "method definition for .\\-method2. not found" "" { target *-*-* } 53 } */ |
/* { dg-warning "class .MySubClass2. does not fully implement the .MyProtocol2. protocol" "" { target *-*-* } 53 } */ |
/super-dealloc-2.mm
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 |
/proto-lossage-3.mm
0,0 → 1,29
/* Crash due to descriptionFor(Instance|Class)Method applied to |
a protocol with no instance/class methods respectively. |
Problem report and original fix by richard@brainstorm.co.uk. */ |
/* { dg-do run } */ |
/* { dg-xfail-run-if "Needs OBJC2 ABI" { *-*-darwin* && { lp64 && { ! objc2 } } } { "-fnext-runtime" } { "" } } */ |
#include <objc/Protocol.h> |
#include "../objc-obj-c++-shared/runtime.h" |
|
@interface MyClass |
- name; |
@end |
|
@protocol NoInstanceMethods |
+ testMethod; |
@end |
|
@protocol NoClassMethods |
- testMethod; |
@end |
|
int |
main() |
{ |
protocol_getMethodDescription (@protocol(NoInstanceMethods), @selector(name), YES, YES); |
protocol_getMethodDescription (@protocol(NoInstanceMethods), @selector(name), YES, NO); |
protocol_getMethodDescription (@protocol(NoClassMethods), @selector(name), YES, YES); |
protocol_getMethodDescription (@protocol(NoClassMethods), @selector(name), YES, NO); |
return 0; |
} |
/try-catch-4.mm
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) { |
} |
} |
/comp-types-2.mm
0,0 → 1,88
/* Test various ObjC types assignments and comparisons. */ |
/* Author: Nicola Pero <nicola@brainstorm.co.uk>. */ |
/* { dg-do compile } */ |
|
#include <objc/objc.h> |
|
@protocol MyProtocol |
- (void) foo; |
@end |
|
@interface MyClass |
@end |
|
@interface MyOtherClass <MyProtocol> |
- (void) foo; |
@end |
|
int main() |
{ |
id obj = nil; |
id<MyProtocol> obj_p = nil; |
MyClass *obj_c = nil; |
MyOtherClass *obj_cp = nil; |
Class obj_C = Nil; |
|
/* Assigning to an 'id' variable should never |
generate a warning. */ |
obj = obj_p; /* Ok */ |
obj = obj_c; /* Ok */ |
obj = obj_cp; /* Ok */ |
obj = obj_C; /* Ok */ |
|
/* Assigning to a 'MyClass *' variable should always generate a |
warning, unless done from an 'id'. */ |
obj_c = obj; /* Ok */ |
obj_c = obj_p; /* { dg-warning "distinct Objective\\-C type" } */ |
obj_c = obj_cp; /* { dg-warning "distinct Objective\\-C type" } */ |
obj_c = obj_C; /* { dg-warning "distinct Objective\\-C type" } */ |
|
/* Assigning to an 'id<MyProtocol>' variable should generate a |
warning if done from a 'MyClass *' (which doesn't implement |
MyProtocol), but not from an 'id' or from a 'MyOtherClass *' |
(which implements MyProtocol). */ |
obj_p = obj; /* Ok */ |
obj_p = obj_c; /* { dg-warning "does not implement" } */ |
obj_p = obj_cp; /* Ok */ |
obj_p = obj_C; /* { dg-warning "distinct Objective\\-C type" } */ |
|
/* Assigning to a 'MyOtherClass *' variable should always generate |
a warning, unless done from an 'id' or an 'id<MyProtocol>' (since |
MyOtherClass implements MyProtocol). */ |
obj_cp = obj; /* Ok */ |
obj_cp = obj_c; /* { dg-warning "distinct Objective\\-C type" } */ |
obj_cp = obj_p; /* Ok */ |
obj_cp = obj_C; /* { dg-warning "distinct Objective\\-C type" } */ |
|
/* Any comparison involving an 'id' must be without warnings. */ |
if (obj == obj_p) ; /* Ok */ /*Bogus warning here in 2.95.4*/ |
if (obj_p == obj) ; /* Ok */ |
if (obj == obj_c) ; /* Ok */ |
if (obj_c == obj) ; /* Ok */ |
if (obj == obj_cp) ; /* Ok */ |
if (obj_cp == obj) ; /* Ok */ |
if (obj == obj_C) ; /* Ok */ |
if (obj_C == obj) ; /* Ok */ |
|
/* Any comparison between 'MyClass *' and anything which is not an 'id' |
must generate a warning. */ |
if (obj_c == obj_p) ; /* { dg-warning "lacks a cast" } */ |
if (obj_p == obj_c) ; /* { dg-warning "lacks a cast" } */ |
if (obj_c == obj_cp) ; /* { dg-warning "lacks a cast" } */ |
if (obj_cp == obj_c) ; /* { dg-warning "lacks a cast" } */ |
if (obj_c == obj_C) ; /* { dg-warning "lacks a cast" } */ |
if (obj_C == obj_c) ; /* { dg-warning "lacks a cast" } */ |
|
/* Any comparison between 'MyOtherClass *' (which implements |
MyProtocol) and an 'id' implementing MyProtocol are Ok. */ |
if (obj_cp == obj_p) ; /* Ok */ |
if (obj_p == obj_cp) ; /* Ok */ |
|
|
if (obj_p == obj_C) ; /* { dg-warning "lacks a cast" } */ |
if (obj_C == obj_p) ; /* { dg-warning "lacks a cast" } */ |
if (obj_cp == obj_C) ; /* { dg-warning "lacks a cast" } */ |
if (obj_C == obj_cp) ; /* { dg-warning "lacks a cast" } */ |
|
return 0; |
} |
/method-12.mm
0,0 → 1,31
/* Check that sending messages to variables of type 'Class' does not involve instance methods, unless they reside in root classes. */ |
/* Author: Ziemowit Laski <zlaski@apple.com> */ |
/* { dg-options "-Wstrict-selector-match" } */ |
/* { dg-do compile } */ |
|
#include <objc/Protocol.h> |
|
@interface Base |
- (unsigned)port; |
@end |
|
@interface Derived: Base |
- (Object *)port; |
+ (Protocol *)port; |
- (id)starboard; |
@end |
|
void foo(void) { |
Class receiver; |
|
[receiver port]; /* { dg-warning "multiple methods named .\\+port. found" } */ |
/* { dg-message "using .\\-\\(unsigned( int)?\\)port." "" { target *-*-* } 9 } */ |
/* { dg-message "also found .\\+\\(Protocol \\*\\)port." "" { target *-*-* } 14 } */ |
|
[receiver starboard]; /* { dg-warning "no .\\+starboard. method found" } */ |
/* { dg-warning "Messages without a matching method signature" "" { target *-*-* } 25 } */ |
/* { dg-warning "will be assumed to return .id. and accept" "" { target *-*-* } 25 } */ |
/* { dg-warning ".\.\.\.. as arguments" "" { target *-*-* } 25 } */ |
|
[Class port]; /* { dg-error ".Class. is not an Objective\\-C class name or alias" } */ |
} |
/encode-7.mm
0,0 → 1,68
/* Check if array arguments of ObjC methods are decayed to pointer types |
in a proper fashion: |
(1) The _encodings_ for the array arguments should remain to be '[4i]' and |
such, since this has been the case since at least gcc 3.3. |
(2) However, when building the static C functions out of ObjC method signatures, |
we need to decay the arrays into pointers (as C does). |
(3) If array size is not known (e.g., 'int a[]'), then the type shall be |
encoded as a pointer. */ |
|
/* Contributed by Alexander Malmberg <alexander@malmberg.org> */ |
|
#include "../objc-obj-c++-shared/TestsuiteObject.m" |
#include "../objc-obj-c++-shared/runtime.h" |
#include <stdlib.h> |
#include <stdio.h> |
#define CHECK_IF(expr) if(!(expr)) abort() |
|
@interface Test : TestsuiteObject |
{ float j; } |
-(void) test2: (int [5])a with: (int [])b; |
-(id) test3: (Test **)b; /* { dg-message "previous declaration of .\\-\\(id\\)test3:\\(Test \\*\\*\\)b." } */ |
@end |
|
@implementation Test |
-(void) test2: (int [5])a with: (int [])b |
{ |
a[3] = *b; |
} |
-(void) test3: (Test [3][4])b { /* { dg-warning "conflicting types for .\\-\\(void\\)test3:\\(Test \\\[3\\\]\\\[4\\\]\\)b." } */ |
} |
@end |
|
int bb[6] = { 0, 1, 2, 3, 4, 5 }; |
int *b = bb; |
Test *cc[4]; |
Test **c = cc; |
|
int offs1, offs2, offs3, offs4, offs5, offs6; |
|
int main(int argc, char **argv) |
{ |
Class testClass = objc_getClass("Test"); |
Method meth; |
|
cc[0] = [Test new]; |
CHECK_IF (bb[3] == 3); |
[*c test2: b with: bb + 4]; |
CHECK_IF (bb[3] == 4); |
bb[3] = 0; |
[*c test2: bb with: bb + 5]; |
CHECK_IF (bb[3] == 5); |
|
meth = class_getInstanceMethod(testClass, @selector(test2:with:)); |
offs1 = offs2 = offs3 = offs4 = offs5 = offs6 = -1; |
sscanf(method_getTypeEncoding(meth), "v%d@%d:%d[%di]%d^i%d", &offs1, &offs2, &offs3, |
&offs4, &offs5, &offs6); |
CHECK_IF (!offs2 && offs4 == 5 && offs3 > 0); |
CHECK_IF (offs5 == 2 * offs3 && offs6 == 3 * offs3 && offs1 == 4 * offs3); |
|
meth = class_getInstanceMethod(testClass, @selector(test3:)); |
offs1 = offs2 = offs3 = offs4 = offs5 = offs6 = -1; |
sscanf(method_getTypeEncoding(meth), "v%d@%d:%d[%d[%d{Test=#f}]]%d", &offs1, &offs2, &offs3, |
&offs4, &offs5, &offs6); |
CHECK_IF (!offs2 && offs4 == 3 && offs5 == 4 && offs3 > 0); |
CHECK_IF (offs6 == 2 * offs3 && offs1 == 3 * offs3); |
|
return 0; |
} |
/protocol-forward-2.mm
0,0 → 1,95
/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, December 2010. */ |
/* { dg-do compile } */ |
|
/* Test that all protocols appearing in @interface declarations are |
real (ie, we saw a full @protocol definition with list of methods), |
and not just forward-references (ie, "@protocol NSObject;"). This |
test checks protocols implemented by other protocols. */ |
|
#include <objc/objc.h> |
|
@protocol MyProtocol; |
|
@interface MyClass <MyProtocol> /* { dg-warning "definition of protocol .MyProtocol. not found" } */ |
@end |
|
|
@protocol MyProtocol2 <MyProtocol> |
- (int)method2; |
@end |
|
@interface MyClass2 <MyProtocol2> /* { dg-warning "definition of protocol .MyProtocol. not found" } */ |
- (int)method2; |
@end |
|
|
@protocol MyProtocol3 <MyProtocol2> |
- (int)method3; |
@end |
|
@interface MyClass3 <MyProtocol3> /* { dg-warning "definition of protocol .MyProtocol. not found" } */ |
- (int)method2; |
- (int)method3; |
@end |
|
|
@protocol MyProtocol4 <MyProtocol3, MyProtocol2> |
- (int)method4; |
@end |
|
@interface MyClass4 <MyProtocol4> /* { dg-warning "definition of protocol .MyProtocol. not found" } */ |
- (int)method2; |
- (int)method3; |
- (int)method4; |
@end |
|
|
@protocol MyProtocol5 |
- (int)method5; |
@end |
|
@interface MyClass5 <MyProtocol5> /* Ok */ |
- (int)method5; |
@end |
|
|
@protocol MyProtocol6 <MyProtocol5> |
- (int)method6; |
@end |
|
@interface MyClass6 <MyProtocol6> /* Ok */ |
- (int)method5; |
- (int)method6; |
@end |
|
|
@protocol MyProtocol7 <MyProtocol5, MyProtocol4> |
- (int)method7; |
@end |
|
@interface MyClass7 <MyProtocol7> /* { dg-warning "definition of protocol .MyProtocol. not found" } */ |
- (int)method2; |
- (int)method3; |
- (int)method4; |
- (int)method5; |
- (int)method7; |
@end |
|
|
/* Now test that if we finally define MyProtocol, the warnings go away. */ |
@protocol MyProtocol |
- (int)method; |
@end |
|
@protocol MyProtocol8 <MyProtocol5, MyProtocol4> |
- (int)method8; |
@end |
|
@interface MyClass8 <MyProtocol8> /* Ok */ |
- (int)method; |
- (int)method2; |
- (int)method3; |
- (int)method4; |
- (int)method5; |
- (int)method8; |
@end |
/invalid-method-2.mm
0,0 → 1,18
/* { dg-do compile } */ |
|
/* Test that using an invalid type in a method declaration produces a |
friendly error without a compiler crash. */ |
|
@interface MyClass |
@end |
|
@implementation MyClass |
- (x) method /* { dg-error "expected" } */ |
{ |
return 0; |
} |
- (id) method2: (x)argument /* { dg-error "expected" } */ |
{ |
return 0; |
} |
@end |
/gnu-api-2-object.mm
0,0 → 1,164
/* Test the Modern GNU Objective-C Runtime API. |
|
This is test 'object', covering all functions starting with 'object'. */ |
|
/* { dg-do run } */ |
/* { dg-skip-if "No API#2 pre-Darwin9" { *-*-darwin[5-8]* } { "-fnext-runtime" } { "" } } */ |
/* { dg-xfail-run-if "Needs OBJC2 ABI" { *-*-darwin* && { lp64 && { ! objc2 } } } { "-fnext-runtime" } { "" } } */ |
|
/* To get the modern GNU Objective-C Runtime API, you include |
objc/runtime.h. */ |
#include <objc/runtime.h> |
#include <stdlib.h> |
#include <iostream> |
#include <cstring> |
|
@interface MyRootClass |
{ Class isa; } |
+ alloc; |
- init; |
+ initialize; |
@end |
|
@implementation MyRootClass |
+ alloc { return class_createInstance (self, 0); } |
- init { return self; } |
+ initialize { return self; } |
@end |
|
@protocol MyProtocol |
- (id) variable; |
@end |
|
@protocol MySecondProtocol |
- (id) setVariable: (id)value; |
@end |
|
@interface MySubClass : MyRootClass <MyProtocol> |
{ id variable_ivar; } |
- (void) setVariable: (id)value; |
- (id) variable; |
@end |
|
@implementation MySubClass |
- (void) setVariable: (id)value { variable_ivar = value; } |
- (id) variable { return variable_ivar; } |
@end |
|
@interface MySubSubClass : MySubClass |
- (id) test; |
@end |
|
@implementation MySubSubClass |
- (id) test { return self; } |
@end |
|
|
|
int main () |
{ |
/* Functions are tested in alphabetical order. */ |
|
std::cout << "Testing object_copy () ...\n"; |
{ |
MySubClass *object_a = [[MySubClass alloc] init]; |
MySubClass *object_b = object_copy (object_a, 0); |
|
[object_b setVariable: object_a]; |
if ([object_b variable] != object_a) |
abort (); |
} |
|
std::cout << "Testing object_dispose () ...\n"; |
{ |
MySubClass *object = [[MySubClass alloc] init]; |
|
object_dispose (object); |
} |
|
std::cout << "Testing object_getClass () ...\n"; |
{ |
MyRootClass *o = [[MySubClass alloc] init]; |
|
if (object_getClass (o) != objc_getClass ("MySubClass")) |
abort (); |
} |
|
std::cout << "Testing object_getClassName () ...\n"; |
{ |
MyRootClass *o = [[MyRootClass alloc] init]; |
|
if (std::strcmp (object_getClassName (o), "MyRootClass") != 0) |
abort (); |
} |
|
std::cout << "Testing object_getIndexedIvars () ...\n"; |
{ |
if (object_getIndexedIvars ([[MyRootClass alloc] init]) == NULL) |
abort (); |
} |
|
std::cout << "Testing object_getInstanceVariable () ...\n"; |
{ |
MySubClass *o = [[MySubClass alloc] init]; |
id value; |
|
[o setVariable: o]; |
|
if (object_getInstanceVariable (o, "variable_ivar", (void **)&value) == NULL) |
abort (); |
|
if (value != o) |
abort (); |
} |
|
std::cout << "Testing object_getIvar () ...\n"; |
{ |
MySubClass *o = [[MySubClass alloc] init]; |
Ivar ivar = class_getInstanceVariable (objc_getClass ("MySubClass"), "variable_ivar"); |
|
[o setVariable: o]; |
|
if (object_getIvar (o, ivar) != o) |
abort (); |
} |
|
std::cout << "Testing object_setClass () ...\n"; |
{ |
MySubClass *o = [[MySubClass alloc] init]; |
|
object_setClass (o, objc_getClass ("MySubSubClass")); |
|
if ([(MySubSubClass *)o test] != o) |
abort (); |
} |
|
std::cout << "Testing object_setInstanceVariable () ...\n"; |
{ |
MySubClass *o = [[MySubClass alloc] init]; |
|
[o setVariable: nil]; |
|
if (object_setInstanceVariable (o, "variable_ivar", (void *)o) == NULL) |
abort (); |
|
if ([o variable] != o) |
abort (); |
} |
|
std::cout << "Testing object_setIvar () ...\n"; |
{ |
MySubClass *o = [[MySubClass alloc] init]; |
MySubClass *value = [[MySubClass alloc] init]; |
Ivar ivar = class_getInstanceVariable (objc_getClass ("MySubClass"), "variable_ivar"); |
|
[o setVariable: o]; |
|
object_setIvar (o, ivar, value); |
|
if ([o variable] != value) |
abort (); |
} |
|
return (0); |
} |
/enhanced-proto-2.mm
0,0 → 1,23
/* { dg-do compile } */ |
|
@protocol MyProto1 |
@optional |
- (void) FOO; |
@optional |
- (void) FOO; |
@optional |
- (void) REQ; |
@optional |
@end |
|
@interface MyProto2 <MyProto1> |
@required /* { dg-error ".@required. is allowed in @protocol context only" } */ |
- (void) FOO2; |
@optional /* { dg-error ".@optional. is allowed in @protocol context only" } */ |
- (void) FOO3; |
@end |
|
@implementation MyProto2 |
- (void) FOO2{} |
- (void) FOO3{} |
@end |
/keywords-2.mm
0,0 → 1,24
/* Test that 'encode', 'end', 'compatibility_alias', 'defs', |
'protocol', 'selector', finally', 'synchronized', 'interface', |
'implementation' are not keywords if not after a '@'. |
*/ |
/* { dg-do compile } */ |
|
int encode (int end) |
{ |
int compatibility_alias = end * 2; |
int defs = compatibility_alias * 2; |
int protocol = defs * 2; |
int selector = protocol * 2; |
int finally = selector * 2; |
int synchronized = finally * 2; |
int interface = synchronized * 2; |
int implementation = interface * 2; |
|
return implementation; |
} |
|
int main (void) |
{ |
return encode (0); |
} |
/method-namespace-1.mm
0,0 → 1,29
/* Test for usage of namespace inside @implementation. */ |
/* { dg-do compile } */ |
@interface MyDocument |
@end |
|
@implementation MyDocument |
|
// This deprecated usage works |
static void foo1() { } |
|
// This preferred usage does _not_ work |
namespace |
{ |
void foo2() { } |
} |
|
namespace STD |
{ |
void foo3 () {} |
} |
|
using namespace STD; |
|
- (void) GARF { |
foo2(); |
foo3(); |
} |
|
@end |
/overload-1.mm
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*); |
}; |
/private-2.mm
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 |
/gnu-runtime-3.mm
0,0 → 1,30
/* Test that compiling for the GNU runtime works (regardless of |
the system runtime used). */ |
/* Author: Ziemowit Laski <zlaski@apple.com> */ |
/* { dg-do run } */ |
/* { dg-skip-if "" { *-*-* } { "-fnext-runtime" } { "" } } */ |
|
#include "../objc-obj-c++-shared/TestsuiteObject.m" |
#include <stdlib.h> |
|
@interface FooBar: TestsuiteObject |
- (void)boo; |
@end |
|
int called = 0; |
|
@implementation FooBar |
- (void)boo |
{ |
called ++; |
} |
@end |
|
int main () |
{ |
id fooBarInst = [[FooBar alloc] init]; |
[fooBarInst boo]; |
if (called != 1) |
abort (); |
return 0; |
} |
/naming-4.mm
0,0 → 1,145
/* Testing for detecting duplicate ivars. */ |
/* { dg-do compile } */ |
|
/* This check wants to force the compiler to use a hashtable. To do |
so, we need lots of instance variable. */ |
|
@interface A |
{ |
/* That's 200 instance variables, which is enough to trigger the |
hashtable check in the compiler. */ |
char a0; char a1; char a2; char a3; char a4; char a5; char a6; char a7; char a8; char a9; |
char b0; char b1; char b2; char b3; char b4; char b5; char b6; char b7; char b8; char b9; |
char c0; char c1; char c2; char c3; char c4; char c5; char c6; char c7; char c8; char c9; |
char d0; char d1; char d2; char d3; char d4; char d5; char d6; char d7; char d8; char d9; |
char e0; char e1; char e2; char e3; char e4; char e5; char e6; char e7; char e8; char e9; |
char f0; char f1; char f2; char f3; char f4; char f5; char f6; char f7; char f8; char f9; |
char g0; char g1; char g2; char g3; char g4; char g5; char g6; char g7; char g8; char g9; |
char h0; char h1; char h2; char h3; char h4; char h5; char h6; char h7; char h8; char h9; |
char i0; char i1; char i2; char i3; char i4; char i5; char i6; char i7; char i8; char i9; |
char j0; char j1; char j2; char j3; char j4; char j5; char j6; char j7; char j8; char j9; |
char k0; char k1; char k2; char k3; char k4; char k5; char k6; char k7; char k8; char k9; |
char l0; char l1; char l2; char l3; char l4; char l5; char l6; char l7; char l8; char l9; |
char m0; char m1; char m2; char m3; char m4; char m5; char m6; char m7; char m8; char m9; |
char n0; char n1; char n2; char n3; char n4; char n5; char n6; char n7; char n8; char n9; |
char o0; char o1; char o2; char o3; char o4; char o5; char o6; char o7; char o8; char o9; |
char p0; char p1; char p2; char p3; char p4; char p5; char p6; char p7; char p8; char p9; |
char q0; char q1; char q2; char q3; char q4; char q5; char q6; char q7; char q8; char q9; |
char r0; char r1; char r2; char r3; char r4; char r5; char r6; char r7; char r8; char r9; |
char s0; char s1; char s2; char s3; char s4; char s5; char s6; char s7; char s8; char s9; |
|
char x; /* { dg-message "previous declaration" } */ |
char x; |
|
char z; /* { dg-message "previous declaration" } */ |
char k; /* { dg-message "previous declaration" } */ |
} /* { dg-error "redeclaration" } */ |
@end |
|
@interface B : A |
{ |
/* That's another 200 instance variables, which should be enough to |
trigger the hashtable check in the compiler. */ |
char Ba0; char Ba1; char Ba2; char Ba3; char Ba4; char Ba5; char Ba6; char Ba7; char Ba8; char Ba9; |
char Bb0; char Bb1; char Bb2; char Bb3; char Bb4; char Bb5; char Bb6; char Bb7; char Bb8; char Bb9; |
char Bc0; char Bc1; char Bc2; char Bc3; char Bc4; char Bc5; char Bc6; char Bc7; char Bc8; char Bc9; |
char Bd0; char Bd1; char Bd2; char Bd3; char Bd4; char Bd5; char Bd6; char Bd7; char Bd8; char Bd9; |
char Be0; char Be1; char Be2; char Be3; char Be4; char Be5; char Be6; char Be7; char Be8; char Be9; |
char Bf0; char Bf1; char Bf2; char Bf3; char Bf4; char Bf5; char Bf6; char Bf7; char Bf8; char Bf9; |
char Bg0; char Bg1; char Bg2; char Bg3; char Bg4; char Bg5; char Bg6; char Bg7; char Bg8; char Bg9; |
char Bh0; char Bh1; char Bh2; char Bh3; char Bh4; char Bh5; char Bh6; char Bh7; char Bh8; char Bh9; |
char Bi0; char Bi1; char Bi2; char Bi3; char Bi4; char Bi5; char Bi6; char Bi7; char Bi8; char Bi9; |
char Bj0; char Bj1; char Bj2; char Bj3; char Bj4; char Bj5; char Bj6; char Bj7; char Bj8; char Bj9; |
char Bk0; char Bk1; char Bk2; char Bk3; char Bk4; char Bk5; char Bk6; char Bk7; char Bk8; char Bk9; |
char Bl0; char Bl1; char Bl2; char Bl3; char Bl4; char Bl5; char Bl6; char Bl7; char Bl8; char Bl9; |
char Bm0; char Bm1; char Bm2; char Bm3; char Bm4; char Bm5; char Bm6; char Bm7; char Bm8; char Bm9; |
char Bn0; char Bn1; char Bn2; char Bn3; char Bn4; char Bn5; char Bn6; char Bn7; char Bn8; char Bn9; |
char Bo0; char Bo1; char Bo2; char Bo3; char Bo4; char Bo5; char Bo6; char Bo7; char Bo8; char Bo9; |
char Bp0; char Bp1; char Bp2; char Bp3; char Bp4; char Bp5; char Bp6; char Bp7; char Bp8; char Bp9; |
char Bq0; char Bq1; char Bq2; char Bq3; char Bq4; char Bq5; char Bq6; char Bq7; char Bq8; char Bq9; |
char Br0; char Br1; char Br2; char Br3; char Br4; char Br5; char Br6; char Br7; char Br8; char Br9; |
char Bs0; char Bs1; char Bs2; char Bs3; char Bs4; char Bs5; char Bs6; char Bs7; char Bs8; char Bs9; |
|
char y; /* { dg-message "previous declaration" } */ |
char y; |
|
char z; /* { dg-error "duplicate instance variable" } */ |
} /* { dg-error "redeclaration" } */ |
@end |
|
@interface C : A |
{ |
char w; /* { dg-message "previous declaration" } */ |
} |
@end |
|
@interface D : C |
{ |
/* That's another 200 instance variables, which should be enough to |
trigger the hashtable check in the compiler. */ |
char Da0; char Da1; char Da2; char Da3; char Da4; char Da5; char Da6; char Da7; char Da8; char Da9; |
char Db0; char Db1; char Db2; char Db3; char Db4; char Db5; char Db6; char Db7; char Db8; char Db9; |
char Dc0; char Dc1; char Dc2; char Dc3; char Dc4; char Dc5; char Dc6; char Dc7; char Dc8; char Dc9; |
char Dd0; char Dd1; char Dd2; char Dd3; char Dd4; char Dd5; char Dd6; char Dd7; char Dd8; char Dd9; |
char De0; char De1; char De2; char De3; char De4; char De5; char De6; char De7; char De8; char De9; |
char Df0; char Df1; char Df2; char Df3; char Df4; char Df5; char Df6; char Df7; char Df8; char Df9; |
char Dg0; char Dg1; char Dg2; char Dg3; char Dg4; char Dg5; char Dg6; char Dg7; char Dg8; char Dg9; |
char Dh0; char Dh1; char Dh2; char Dh3; char Dh4; char Dh5; char Dh6; char Dh7; char Dh8; char Dh9; |
char Di0; char Di1; char Di2; char Di3; char Di4; char Di5; char Di6; char Di7; char Di8; char Di9; |
char Dj0; char Dj1; char Dj2; char Dj3; char Dj4; char Dj5; char Dj6; char Dj7; char Dj8; char Dj9; |
char Dk0; char Dk1; char Dk2; char Dk3; char Dk4; char Dk5; char Dk6; char Dk7; char Dk8; char Dk9; |
char Dl0; char Dl1; char Dl2; char Dl3; char Dl4; char Dl5; char Dl6; char Dl7; char Dl8; char Dl9; |
char Dm0; char Dm1; char Dm2; char Dm3; char Dm4; char Dm5; char Dm6; char Dm7; char Dm8; char Dm9; |
char Dn0; char Dn1; char Dn2; char Dn3; char Dn4; char Dn5; char Dn6; char Dn7; char Dn8; char Dn9; |
char Do0; char Do1; char Do2; char Do3; char Do4; char Do5; char Do6; char Do7; char Do8; char Do9; |
char Dp0; char Dp1; char Dp2; char Dp3; char Dp4; char Dp5; char Dp6; char Dp7; char Dp8; char Dp9; |
char Dq0; char Dq1; char Dq2; char Dq3; char Dq4; char Dq5; char Dq6; char Dq7; char Dq8; char Dq9; |
char Dr0; char Dr1; char Dr2; char Dr3; char Dr4; char Dr5; char Dr6; char Dr7; char Dr8; char Dr9; |
char Ds0; char Ds1; char Ds2; char Ds3; char Ds4; char Ds5; char Ds6; char Ds7; char Ds8; char Ds9; |
|
char y; /* { dg-message "previous declaration" } */ |
char y; |
|
char w; /* { dg-error "duplicate instance variable" } */ |
char k; /* { dg-error "duplicate instance variable" } */ |
} /* { dg-error "redeclaration" } */ |
@end |
|
/* Finally, make sure that anonymous instance variables don't trigger |
warnings. This is the same as the anon-1.m testcase, but forcing |
the hashtable check. */ |
@interface E : D |
{ |
char : 1; |
char : 2; |
} |
@end |
|
@interface F : E |
{ |
/* That's another 200 instance variables, which should be enough to |
trigger the hashtable check in the compiler. */ |
char Fa0; char Fa1; char Fa2; char Fa3; char Fa4; char Fa5; char Fa6; char Fa7; char Fa8; char Fa9; |
char Fb0; char Fb1; char Fb2; char Fb3; char Fb4; char Fb5; char Fb6; char Fb7; char Fb8; char Fb9; |
char Fc0; char Fc1; char Fc2; char Fc3; char Fc4; char Fc5; char Fc6; char Fc7; char Fc8; char Fc9; |
char Fd0; char Fd1; char Fd2; char Fd3; char Fd4; char Fd5; char Fd6; char Fd7; char Fd8; char Fd9; |
char Fe0; char Fe1; char Fe2; char Fe3; char Fe4; char Fe5; char Fe6; char Fe7; char Fe8; char Fe9; |
char Ff0; char Ff1; char Ff2; char Ff3; char Ff4; char Ff5; char Ff6; char Ff7; char Ff8; char Ff9; |
char Fg0; char Fg1; char Fg2; char Fg3; char Fg4; char Fg5; char Fg6; char Fg7; char Fg8; char Fg9; |
char Fh0; char Fh1; char Fh2; char Fh3; char Fh4; char Fh5; char Fh6; char Fh7; char Fh8; char Fh9; |
char Fi0; char Fi1; char Fi2; char Fi3; char Fi4; char Fi5; char Fi6; char Fi7; char Fi8; char Fi9; |
char Fj0; char Fj1; char Fj2; char Fj3; char Fj4; char Fj5; char Fj6; char Fj7; char Fj8; char Fj9; |
char Fk0; char Fk1; char Fk2; char Fk3; char Fk4; char Fk5; char Fk6; char Fk7; char Fk8; char Fk9; |
char Fl0; char Fl1; char Fl2; char Fl3; char Fl4; char Fl5; char Fl6; char Fl7; char Fl8; char Fl9; |
char Fm0; char Fm1; char Fm2; char Fm3; char Fm4; char Fm5; char Fm6; char Fm7; char Fm8; char Fm9; |
char Fn0; char Fn1; char Fn2; char Fn3; char Fn4; char Fn5; char Fn6; char Fn7; char Fn8; char Fn9; |
char Fo0; char Fo1; char Fo2; char Fo3; char Fo4; char Fo5; char Fo6; char Fo7; char Fo8; char Fo9; |
char Fp0; char Fp1; char Fp2; char Fp3; char Fp4; char Fp5; char Fp6; char Fp7; char Fp8; char Fp9; |
char Fq0; char Fq1; char Fq2; char Fq3; char Fq4; char Fq5; char Fq6; char Fq7; char Fq8; char Fq9; |
char Fr0; char Fr1; char Fr2; char Fr3; char Fr4; char Fr5; char Fr6; char Fr7; char Fr8; char Fr9; |
char Fs0; char Fs1; char Fs2; char Fs3; char Fs4; char Fs5; char Fs6; char Fs7; char Fs8; char Fs9; |
|
char : 1; |
char : 2; |
} |
@end |
/duplicate-class-1.mm
0,0 → 1,31
/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, November 2010. */ |
/* { dg-do compile } */ |
|
/* Test that a duplicated @implementation for the same class does not |
crash the compiler. */ |
|
@interface Test |
{ |
Class isa; |
} |
- (int) test; |
@end |
|
@implementation Test |
- (int) test |
{ |
return 4; |
} |
@end |
|
/* The most likely cause is that the programmer meant this to be a |
category, so check what happens if we have some different methods |
in there. */ |
@implementation Test /* { dg-error "reimplementation of class .Test." } */ |
- (int) test2 |
{ |
return [self test]; |
} |
@end |
/* { dg-warning "incomplete implementation" "" { target *-*-* } 29 } */ |
/* { dg-warning "not found" "" { target *-*-* } 29 } */ |
/try-catch-11.mm
0,0 → 1,40
/* Ensure that @try/@catch blocks do not mess with types of |
local objects (other than their volatile bits). */ |
|
/* { dg-options "-fobjc-exceptions" } */ |
/* { dg-do compile } */ |
|
#include "../objc-obj-c++-shared/TestsuiteObject.h" |
|
@protocol Proto1 |
- (int)meth1; |
@end |
|
@protocol Proto2 |
- (int)meth2; |
@end |
|
@interface MyClass: TestsuiteObject <Proto2> { |
int a; |
} |
- (int)meth2; |
- (TestsuiteObject *)parm1: (id)p1 parm2: (id<Proto1>)p2; |
@end |
|
MyClass *mc1, *mc2; |
|
@implementation MyClass |
- (int)meth2 { |
return a; |
} |
- (TestsuiteObject *)parm1: (id)p1 parm2: (id<Proto1>)p2 { |
@try { |
mc2 = p2; /* { dg-warning "type .id <Proto1>. does not conform to the .Proto2. protocol" } */ |
} |
@catch (id exc) { |
return exc; |
} |
mc1 = p1; /* no warning here! */ |
return self; |
} |
@end |
/template-5.mm
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); |
} |
/gnu-api-2-method.mm
0,0 → 1,230
/* Test the Modern GNU Objective-C Runtime API. |
|
This is test 'method', covering all functions starting with 'method'. */ |
|
/* { dg-do run } */ |
/* { dg-skip-if "No API#2 pre-Darwin9" { *-*-darwin[5-8]* } { "-fnext-runtime" } { "" } } */ |
/* { dg-xfail-run-if "Needs OBJC2 ABI" { *-*-darwin* && { lp64 && { ! objc2 } } } { "-fnext-runtime" } { "" } } */ |
|
/* To get the modern GNU Objective-C Runtime API, you include |
objc/runtime.h. */ |
#include <objc/runtime.h> |
#include <stdlib.h> |
#include <iostream> |
#include <cstring> |
|
@interface MyRootClass |
{ Class isa; } |
+ alloc; |
- init; |
+ initialize; |
@end |
|
@implementation MyRootClass |
+ alloc { return class_createInstance (self, 0); } |
- init { return self; } |
+ initialize { return self; } |
@end |
|
@protocol MyProtocol |
- (id) variable; |
@end |
|
@protocol MySecondProtocol |
- (id) setVariable: (id)value; |
@end |
|
@interface MySubClass : MyRootClass <MyProtocol> |
{ id variable_ivar; } |
- (void) setVariable: (id)value; |
- (id) variable; |
- (id) constant; |
@end |
|
@implementation MySubClass |
- (void) setVariable: (id)value { variable_ivar = value; } |
- (id) variable { return variable_ivar; } |
- (id) constant { return nil; } |
@end |
|
|
int main () |
{ |
/* Functions are tested in alphabetical order. */ |
|
std::cout <<"Testing method_copyArgumentType () ...\n"; |
{ |
Method method = class_getInstanceMethod (objc_getClass ("MySubClass"), |
@selector (setVariable:)); |
char *type = method_copyArgumentType (method, 2); |
|
if (type == NULL || type[0] != '@') |
abort (); |
} |
|
std::cout << "Testing method_copyReturnType () ...\n"; |
{ |
Method method = class_getClassMethod (objc_getClass ("MyRootClass"), |
@selector (alloc)); |
char *type = method_copyReturnType (method); |
|
/* Check that it returns an object. */ |
if (type == NULL || type[0] != '@') |
abort (); |
} |
|
std::cout << "Testing method_exchangeImplementations () ...\n"; |
{ |
Method method_a = class_getInstanceMethod (objc_getClass ("MySubClass"), |
@selector (variable)); |
Method method_b = class_getInstanceMethod (objc_getClass ("MySubClass"), |
@selector (constant)); |
MySubClass *object = [[MySubClass alloc] init]; |
|
/* Check that things work as expected before the swap. */ |
[object setVariable: object]; |
|
if ([object variable] != object || [object constant] != nil) |
abort (); |
|
/* Swap the methods. */ |
method_exchangeImplementations (method_a, method_b); |
|
/* Check that behaviour has changed. */ |
if ([object variable] != nil || [object constant] != object) |
abort (); |
|
/* Swap the methods again. */ |
method_exchangeImplementations (method_a, method_b); |
|
/* Check that behaviour is back to normal. */ |
if ([object variable] != object || [object constant] != nil) |
abort (); |
} |
|
std::cout << "Testing method_getArgumentType () ...\n"; |
{ |
Method method = class_getInstanceMethod (objc_getClass ("MyRootClass"), |
@selector (init)); |
char type[16]; |
|
method_getArgumentType (method, 1, type, 16); |
|
/* Check the second argument (_cmd), which should be a SEL. */ |
if (type[0] != ':') |
abort (); |
} |
|
std::cout << "Testing method_getDescription () ...\n"; |
{ |
Method method = class_getInstanceMethod (objc_getClass ("MySubClass"), |
@selector (variable)); |
struct objc_method_description *description = method_getDescription (method); |
|
if (std::strcmp (sel_getName (description->name), "variable") != 0) |
abort (); |
|
if (method_getDescription (NULL) != NULL) |
abort (); |
} |
|
std::cout << "Testing method_getImplementation () ...\n"; |
{ |
typedef void (*set_variable_function) (id receiver, SEL _cmd, id variable); |
Method method = class_getInstanceMethod (objc_getClass ("MySubClass"), |
@selector (setVariable:)); |
set_variable_function imp; |
MySubClass *object = [[MySubClass alloc] init]; |
|
imp = (set_variable_function)(method_getImplementation (method)); |
|
(*imp)(object, @selector (setVariable:), object); |
|
if ([object variable] != object) |
abort (); |
} |
|
std::cout << "Testing method_getName () ...\n"; |
{ |
Method method = class_getInstanceMethod (objc_getClass ("MySubClass"), |
@selector (setVariable:)); |
if (std::strcmp (sel_getName (method_getName (method)), "setVariable:") != 0) |
abort (); |
} |
|
std::cout << "Testing method_getNumberOfArguments () ...\n"; |
{ |
Method method = class_getInstanceMethod (objc_getClass ("MySubClass"), |
@selector (setVariable:)); |
if (method_getNumberOfArguments (method) != 3) |
abort (); |
|
method = class_getInstanceMethod (objc_getClass ("MySubClass"), |
@selector (variable)); |
if (method_getNumberOfArguments (method) != 2) |
abort (); |
} |
|
std::cout << "Testing method_getTypeEncoding () ...\n"; |
{ |
Method method = class_getInstanceMethod (objc_getClass ("MySubClass"), |
@selector (setVariable:)); |
const char *types = method_getTypeEncoding (method); |
|
/* Check that method type string starts with 'v' (void) */ |
if (types == NULL || types[0] != 'v') |
abort (); |
} |
|
std::cout << "Testing method_getReturnType () ...\n"; |
{ |
Method method = class_getInstanceMethod (objc_getClass ("MySubClass"), |
@selector (setVariable:)); |
char type[16]; |
|
method_getReturnType (method, type, 16); |
|
if (type[0] != 'v') |
abort (); |
|
method_getReturnType (NULL, type, 16); |
|
if (type[0] != 0) |
abort (); |
} |
|
std::cout << "Testing method_setImplementation () ...\n"; |
{ |
Method method_a = class_getInstanceMethod (objc_getClass ("MySubClass"), |
@selector (variable)); |
Method method_b = class_getInstanceMethod (objc_getClass ("MySubClass"), |
@selector (constant)); |
IMP original_imp_a = method_getImplementation (method_a); |
IMP original_imp_b = method_getImplementation (method_b); |
MySubClass *object = [[MySubClass alloc] init]; |
|
/* Check that things work as expected before the swap. */ |
[object setVariable: object]; |
|
if ([object variable] != object || [object constant] != nil) |
abort (); |
|
/* Have 'variable' use the same implementation as 'constant'. */ |
if (method_setImplementation (method_a, original_imp_b) != original_imp_a) |
abort (); |
|
/* Check that behaviour has changed. */ |
if ([object variable] != nil || [object constant] != nil) |
abort (); |
|
/* Put the original method back. */ |
if (method_setImplementation (method_a, original_imp_a) != original_imp_b) |
abort (); |
|
/* Check that behaviour is back to normal. */ |
if ([object variable] != object || [object constant] != nil) |
abort (); |
} |
|
return (0); |
} |
/class-extension-3.mm
0,0 → 1,26
/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, December 2010. */ |
/* { dg-do compile } */ |
|
/* This test tests warnings on class extensions. */ |
|
#include <objc/objc.h> |
|
@interface MyObject |
{ |
Class isa; |
int count; |
} |
- (int) test; /* { dg-message "previous declaration" } */ |
@property int count; /* { dg-message "originally specified here" } */ |
@end |
|
@interface MyObject () |
- (void) test; /* { dg-error "duplicate declaration of method .-test." } */ |
@end |
|
@interface MyObject () |
@end |
|
@interface MyObject () |
@property int count; /* { dg-error "redeclaration of property .count." } */ |
@end |
/syntax-error-5.mm
0,0 → 1,13
/* { dg-do compile } */ |
|
typedef struct S { int i; } NSDictionary; |
|
@interface A |
{ |
} |
@end |
|
@interface B : A |
{ |
NSDictionary * _userInfo; |
@end /* { dg-error "expected .\}. before .end." } */ |
/comp-types-11.mm
0,0 → 1,27
/* { dg-do compile } */ |
|
#include "../objc-obj-c++-shared/TestsuiteObject.h" |
|
@protocol Foo |
- (id)meth1; |
- (id)meth2:(int)arg; |
@end |
|
@interface Derived1: TestsuiteObject |
@end |
|
@interface Derived2: TestsuiteObject |
+ (Derived1 *)new; |
@end |
|
id<Foo> func(void) { |
TestsuiteObject *o = [TestsuiteObject new]; |
return o; /* { dg-warning "class .TestsuiteObject. does not implement the .Foo. protocol" } */ |
} |
|
@implementation Derived2 |
+ (Derived1 *)new { |
Derived2 *o = [super new]; |
return o; /* { dg-warning "distinct Objective\\-C type in return" } */ |
} |
@end |
/method-conflict-4.mm
0,0 → 1,47
/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, December 2010. */ |
/* { dg-do compile } */ |
|
#include <objc/objc.h> |
|
/* Test that the compiler can correctly compare protocols in types of |
method signatures. In this test we look at protocols implementing |
other protocols. The fact that one protocol implements another one |
doesn't mean that they are identical. */ |
|
@protocol A |
- (void) doSomething; |
@end |
|
@protocol B <A> |
- (void) doSomethingElse; |
@end |
|
@protocol C <A> |
- (void) doYetSomethingElse; |
@end |
|
@interface MyClass2 |
- (void) aMethod: (id <A>)x; /* { dg-message "previous declaration" } */ |
- (void) aMethod: (id <B>)x; /* { dg-error "duplicate declaration" } */ |
|
- (void) bMethod: (id <B>)x; /* { dg-message "previous declaration" } */ |
- (void) bMethod: (id <A>)x; /* { dg-error "duplicate declaration" } */ |
|
- (void) cMethod: (id <A, B>)x; |
- (void) cMethod: (id <B>)x; /* Ok - because if you implement B, then you also implement A, so <B> == <A, B> */ |
|
- (void) dMethod: (id <A, B>)x; |
- (void) dMethod: (id <B, A>)x; /* Ok */ |
|
- (void) eMethod: (id <A>)x; /* { dg-message "previous declaration" } */ |
- (void) eMethod: (id <B, C>)x; /* { dg-error "duplicate declaration" } */ |
|
- (void) fMethod: (id <B, C>)x; /* { dg-message "previous declaration" } */ |
- (void) fMethod: (id <A>)x; /* { dg-error "duplicate declaration" } */ |
|
- (void) gMethod: (id <A>)x; /* { dg-message "previous declaration" } */ |
- (void) gMethod: (id <A, B, C>)x; /* { dg-error "duplicate declaration" } */ |
|
- (void) hMethod: (id <A, B, C>)x; /* { dg-message "previous declaration" } */ |
- (void) hMethod: (id <A>)x; /* { dg-error "duplicate declaration" } */ |
@end |
/bitfield-3.mm
0,0 → 1,56
/* Check if bitfield ivars are correctly @encode'd when |
the NeXT runtime is used. */ |
/* Contributed by Ziemowit Laski <zlaski@apple.com>. */ |
/* { dg-do run { target *-*-darwin* } } */ |
/* { dg-skip-if "" { *-*-* } { "-fgnu-runtime" } { "" } } */ |
/* { dg-options "-fsigned-char" } */ |
|
typedef struct objc_object { struct objc_class *class_pointer; } *id; |
|
#include <stdlib.h> |
#include <string.h> |
|
#define CHECK_IF(expr) if(!(expr)) abort(); |
|
@interface Base |
{ |
struct objc_class *isa; |
int full; |
int full2: 32; |
int _refs: 8; |
int field2: 3; |
unsigned f3: 8; |
short cc; |
unsigned g: 16; |
int r2: 8; |
int r3: 8; |
int r4: 2; |
int r5: 8; |
char c; |
} |
@end |
|
@interface Derived: Base |
{ |
char d; |
int _field3: 6; |
} |
@end |
|
@implementation Base |
@end |
|
@implementation Derived |
@end |
|
int main(void) { |
const char *s1r = "{Base=#ib32b8b3b8sb16b8b8b2b8c}"; |
const char *s1 = @encode(Base); |
const char *s2r = "{Derived=#ib32b8b3b8sb16b8b8b2b8ccb6}"; |
const char *s2 = @encode(Derived); |
|
CHECK_IF(!strcmp(s1r, s1)); |
CHECK_IF(!strcmp(s2r, s2)); |
|
return 0; |
} |
/method-6.mm
0,0 → 1,18
/* 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-obj-c++-shared/TestsuiteObject.h" |
|
@class NotKnown; |
|
void foo(NotKnown *n) { |
[NotKnown new]; /* { dg-warning ".interface of class .NotKnown. not found" } */ |
[n nonexistent_method]; /* { dg-warning ".interface of class .NotKnown. not found" } */ |
/* { dg-warning "no .\\-nonexistent_method. method found" "" { target *-*-* } 12 } */ |
} |
|
/* { 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 } */ |
/fsf-package-0.m
0,0 → 1,36
/* { dg-do compile } */ |
|
#import "../objc-obj-c++-shared/TestsuiteObject.h" |
|
@interface obj : TestsuiteObject |
{ |
@public |
int v1; |
@package /* { dg-warning ".@package. presently has the same effect as .@public." } */ |
int v2; |
@protected |
int v3; |
@private |
int v4; |
} |
- (int) value; |
- (void) setValue: (int)number; |
@end |
|
@implementation obj : Object |
|
- (int) value { return v1; } |
- (void) setValue: (int)number { v1 = number; } |
|
@end |
|
void foo (void) |
{ |
obj *a; |
|
[a setValue:2]; |
a->v2 = 1; |
a->v3 = [a value] - a->v2; /* { dg-warning ".v3. is @protected" } */ |
a->v4 = a->v3 - 1; /* { dg-warning ".v4. is @private" } */ |
/* { dg-warning ".v3. is @protected" "" { target *-*-* } 35 } */ |
} |
/encode-2.mm
0,0 → 1,28
/* { dg-do assemble } */ |
/* { dg-options "-save-temps" } */ |
|
template <class T> |
struct Vec { |
T x, y; |
int z; |
}; |
|
typedef struct { |
Vec<double> dvec; |
Vec<float> fvec; |
float fscalar; |
double dscalar; |
Vec<signed char> chVec; |
int iscalar; |
} anonymous; |
|
Vec<double> dd; |
|
const char *enc = @encode(Vec<float>); |
const char *enc2 = @encode(Vec<double>); |
const char *enc3 = @encode(anonymous); |
|
/* { dg-final { scan-assembler "{Vec<float>=ffi}" } } */ |
/* { dg-final { scan-assembler "{Vec<double>=ddi}" } } */ |
/* { dg-final { scan-file "encode-2.o" "{?={Vec<double>=ddi}{Vec<float>=ffi}fd{Vec<signed char>=cci}i}" } } |
/* { dg-final cleanup-saved-temps } */ |
/torture/tls/trivial.mm
0,0 → 1,3
// { dg-require-effective-target tls } |
|
__thread int i; |
/torture/tls/thr-init-1.mm
0,0 → 1,25
// { dg-do run } |
// { dg-require-effective-target tls } |
// { dg-add-options tls } |
|
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; |
} |
/torture/tls/thr-init-2.mm
0,0 → 1,45
// { dg-do run } |
// { dg-require-effective-target tls } |
// { dg-add-options tls } |
|
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; |
} |
/torture/tls/thr-init-3.mm
0,0 → 1,40
/* { dg-do run } */ |
/* { dg-require-effective-target tls } */ |
/* { dg-add-options tls } */ |
/* { dg-xfail-run-if "Needs OBJC2 ABI" { *-*-darwin* && { lp64 && { ! objc2 } } } { "-fnext-runtime" } { "" } } */ |
|
#include "../../../objc-obj-c++-shared/TestsuiteObject.m" |
extern "C" { |
extern void abort (); |
} |
|
@interface tsObj: TestsuiteObject { |
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; |
} |
/torture/tls/diag-1.mm
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; |
} |
/torture/tls/tls.exp
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 |
/torture/trivial.mm
0,0 → 1,11
// { dg-do run } |
|
// { dg-xfail-run-if "OBJC2 runtime" { *-*-darwin* && { lp64 && { ! objc2 } } } { "-fnext-runtime" } { "-fgnu-runtime" } } |
|
#import "../../objc-obj-c++-shared/TestsuiteObject.m" |
|
int main(void) |
{ |
[TestsuiteObject class]; |
return 0; |
} |
/torture/dg-torture.exp
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 |
/torture/strings/string1.mm
0,0 → 1,22
/* Based on a test case contributed by Nicola Pero. */ |
|
/* { dg-do run } */ |
/* { dg-options "-mno-constant-cfstrings" { target *-*-darwin* } } */ |
/* { dg-xfail-run-if "Needs OBJC2 ABI" { *-*-darwin* && { lp64 && { ! objc2 } } } { "-fnext-runtime" } { "" } } */ |
/* { dg-additional-sources "../../../objc-obj-c++-shared/nsconstantstring-class-impl.mm" } */ |
|
#include <string.h> |
#include <stdlib.h> |
|
#ifndef __NEXT_RUNTIME__ |
#include <objc/NXConstStr.h> |
#else |
#include "../../../objc-obj-c++-shared/nsconstantstring-class.h" |
#endif |
|
int main(int argc, char **args) |
{ |
if (strcmp ([@"this is a string" cString], "this is a string")) |
abort (); |
return 0; |
} |
/torture/strings/const-str-10.mm
0,0 → 1,36
/* Test if ObjC constant string layout is checked properly, regardless of how |
constant string classes get derived. */ |
/* Contributed by Ziemowit Laski <zlaski@apple.com> */ |
|
/* { dg-do compile } */ |
/* { dg-skip-if "" { *-*-* } { "-fgnu-runtime" } { "" } } */ |
/* { dg-options "-mno-constant-cfstrings" { target *-*-darwin* } } */ |
|
#include <objc/Object.h> |
#include "../../../objc-obj-c++-shared/runtime.h" /* For NEXT_OBJC_USE_NEW_INTERFACE. */ |
|
@interface NSString: Object |
@end |
|
@interface NSSimpleCString : NSString { |
@protected |
char *bytes; |
unsigned int numBytes; |
} |
@end |
|
@interface NSConstantString : NSSimpleCString |
@end |
|
#ifdef NEXT_OBJC_USE_NEW_INTERFACE |
Class _NSConstantStringClassReference; |
#else |
extern struct objc_class _NSConstantStringClassReference; |
#endif |
|
const NSConstantString *appKey = @"MyApp"; |
|
/* { dg-final { scan-assembler ".section __OBJC, __cstring_object" { target { *-*-darwin* && { ! lp64 } } } } } */ |
/* { dg-final { scan-assembler ".section __DATA, __objc_stringobj" { target { *-*-darwin* && { lp64 } } } } } */ |
/* { dg-final { scan-assembler ".long\t__NSConstantStringClassReference\n\t.long\t.*\n\t.long\t5\n\t.data" { target { *-*-darwin* && { ! lp64 } } } } } */ |
/* { dg-final { scan-assembler ".quad\t_OBJC_CLASS_._NSConstantString\n\t.quad\t.*\n\t.long\t5\n\t.space" { target { *-*-darwin* && { lp64 } } } } } */ |
/torture/strings/const-str-11.mm
0,0 → 1,36
/* Test if ObjC constant string layout is checked properly, regardless of how |
constant string classes get derived. */ |
/* Contributed by Ziemowit Laski <zlaski@apple.com> */ |
|
/* { dg-do compile } */ |
/* { dg-skip-if "" { *-*-* } { "-fgnu-runtime" } { "" } } */ |
/* { dg-options "-fconstant-string-class=XStr" } */ |
/* { dg-options "-mno-constant-cfstrings -fconstant-string-class=XStr" { target *-*-darwin* } } */ |
|
#include <objc/Object.h> |
#include "../../../objc-obj-c++-shared/runtime.h" /* For NEXT_OBJC_USE_NEW_INTERFACE. */ |
|
@interface XString: Object { |
@protected |
char *bytes; |
} |
@end |
|
@interface XStr : XString { |
@public |
unsigned int len; |
} |
@end |
|
#ifdef NEXT_OBJC_USE_NEW_INTERFACE |
extern Class _XStrClassReference; |
#else |
extern struct objc_class _XStrClassReference; |
#endif |
|
const XStr *appKey = @"MyApp"; |
|
/* { dg-final { scan-assembler ".section __OBJC, __cstring_object" { target { *-*-darwin* && { ! lp64 } } } } } */ |
/* { dg-final { scan-assembler ".section __DATA, __objc_stringobj" { target { *-*-darwin* && { lp64 } } } } } */ |
/* { dg-final { scan-assembler ".long\t__XStrClassReference\n\t.long\t.*\n\t.long\t5\n\t.data" { target { *-*-darwin* && { ! lp64 } } } } } */ |
/* { dg-final { scan-assembler ".quad\t_OBJC_CLASS_._XStr\n\t.quad\t.*\n\t.long\t5\n\t.space" { target { *-*-darwin* && { lp64 } } } } } */ |
/torture/strings/strings.exp
0,0 → 1,34
# String tests that should be run at all optimization levels. |
|
# Copyright (C) 2010 Free Software Foundation, Inc. |
# |
# This file is part of GCC. |
# |
# GCC is free software; you can redistribute it and/or modify |
# it under the terms of the GNU General Public License as published by |
# the Free Software Foundation; either version 3, or (at your option) |
# any later version. |
# |
# GCC is distributed in the hope that it will be useful, |
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
# GNU General Public License for more details. |
# |
# You should have received a copy of the GNU General Public License |
# along with GCC; see the file COPYING3. If not see |
# <http://www.gnu.org/licenses/>. |
|
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 |
/torture/strings/const-str-3.mm
0,0 → 1,57
/* Test the -fconstant-string-class=Foo option under the NeXT |
runtime. */ |
/* Developed by Markus Hitter <mah@jump-ing.de>. */ |
|
/* { dg-do run { target *-*-darwin* } } */ |
/* { dg-xfail-run-if "Needs OBJC2 ABI" { *-*-darwin* && { lp64 && { ! objc2 } } } { "-fnext-runtime" } { "" } } */ |
/* { dg-options "-fconstant-string-class=Foo" } */ |
/* { dg-options "-mno-constant-cfstrings -fconstant-string-class=Foo" { target *-*-darwin* } } */ |
|
#include "../../../objc-obj-c++-shared/objc-test-suite-types.h" |
|
#include <stdio.h> |
#include <stdlib.h> |
#include <string.h> |
|
@interface Foo { |
void *dummy_class_ref; |
char *cString; |
unsigned int len; |
} |
+ initialize; |
- (char *)customString; |
@end |
|
TNS_STRING_REF_T _FooClassReference; /* Only used by NeXT. */ |
|
@implementation Foo |
+ initialize {return self;} |
- (char *)customString { |
return cString; |
} |
@end |
|
int main () { |
Foo *string = @"bla"; |
Foo *string2 = @"bla"; |
|
if(string != string2) |
abort(); |
printf("Strings are being uniqued properly\n"); |
|
#ifdef __NEXT_RUNTIME__ |
/* This memcpy has to be done before the first message is sent to a |
constant string object. Can't be moved to +initialize since _that_ |
is already a message. */ |
|
memcpy(&_FooClassReference, objc_getClass("Foo"), sizeof(_FooClassReference)); |
#endif |
|
if (strcmp ([string customString], "bla")) { |
abort (); |
} |
|
printf([@"This is a working constant string object\n" customString]); |
return 0; |
} |
|
/torture/strings/const-str-4.mm
0,0 → 1,33
/* Ensure that the preprocessor handles ObjC string constants gracefully. */ |
/* Author: Ziemowit Laski <zlaski@apple.com> */ |
|
/* { dg-do run { target *-*-darwin* } } */ |
/* { dg-options "-fconstant-string-class=MyString" } */ |
/* { dg-options "-mno-constant-cfstrings -fconstant-string-class=MyString" { target *-*-darwin* } } */ |
|
#include <stdlib.h> |
|
@interface MyString |
{ |
void *isa; |
char *str; |
int len; |
} |
@end |
|
#define kMyStringMacro1 "My String" |
#define kMyStringMacro2 @"My String" |
|
void *_MyStringClassReference; |
|
@implementation MyString |
@end |
|
int main(void) { |
MyString* aString1 = @kMyStringMacro1; |
MyString* aString2 = kMyStringMacro2; |
if(aString1 != aString2) { |
abort(); |
} |
return 0; |
} |
/torture/strings/const-str-7.mm
0,0 → 1,47
/* Test to make sure that the const objc strings are the same across |
scopes. */ |
/* Developed by Andrew Pinski <pinskia@physics.uc.edu> */ |
|
/* { dg-do run } */ |
/* { dg-options "-fconstant-string-class=Foo" } */ |
/* { dg-options "-mno-constant-cfstrings -fconstant-string-class=Foo" { target *-*-darwin* } } */ |
|
#include "../../../objc-obj-c++-shared/TestsuiteObject.m" |
#include <stdio.h> |
#include <stdlib.h> |
#include <string.h> |
#include <objc/objc.h> |
|
@interface Foo: TestsuiteObject { |
char *cString; |
unsigned int len; |
} |
- (char *)customString; |
@end |
|
#ifdef __NEXT_RUNTIME__ |
#ifdef NEXT_OBJC_USE_NEW_INTERFACE |
Class _FooClassReference; |
#else |
struct objc_class _FooClassReference; |
#endif |
#endif |
|
@implementation Foo : TestsuiteObject |
- (char *)customString { |
return cString; |
} |
@end |
|
|
int main () { |
Foo *string = @"bla"; |
{ |
Foo *string2 = @"bla"; |
|
if(string != string2) |
abort(); |
printf("Strings are being uniqued properly\n"); |
} |
return 0; |
} |
/torture/strings/const-cfstring-1.mm
0,0 → 1,62
/* Test the -fconstant-cfstrings option for constructing |
compile-time immutable CFStrings, and their interoperation |
with both Cocoa and CoreFoundation. This will only work |
on MacOS X 10.1.2 and later. */ |
/* Developed by Ziemowit Laski <zlaski@apple.com>. */ |
|
/* So far, CFString is darwin-only. */ |
/* { dg-do run { target *-*-darwin* } } */ |
/* { dg-skip-if "NeXT only" { *-*-* } { "-fgnu-runtime" } { "" } } */ |
/* { dg-xfail-run-if "Needs OBJC2 ABI" { *-*-darwin* && { lp64 && { ! objc2 } } } { "-fnext-runtime" } { "" } } */ |
/* { dg-options "-mconstant-cfstrings -framework Cocoa" } */ |
/* Darwin10's linker emits a warning that the constant strings are incompatible with writable ones. |
well, we don't implement writable ones at this juncture. */ |
/* { dg-options "-mconstant-cfstrings -framework Cocoa -Wl,-w" { target *-*-darwin[123]* } } */ |
|
#import <Foundation/NSString.h> |
#import <CoreFoundation/CFString.h> |
#include <stdlib.h> |
|
void printOut(NSString *str) { |
NSLog(@"The value of str is: %@", str); |
} |
|
CFStringRef s0a = CFSTR("Compile-time string literal"); |
CFStringRef s0b = CFSTR("Compile-time string literal"); |
|
void checkNSRange(NSRange r) { |
if (r.location != 6 || r.length != 5) { |
printOut(@"Range check failed"); |
abort(); |
} |
} |
|
void checkCFRange(CFRange r) { |
if (r.location != 6 || r.length != 5) { |
printOut(@"Range check failed"); |
abort(); |
} |
} |
|
int main(void) { |
const NSString *s1 = @"Compile-time string literal"; |
CFStringRef s2 = CFSTR("Compile-time string literal"); |
|
checkNSRange([@"Hello World" rangeOfString:@"World"]); |
checkNSRange([(id)CFSTR("Hello World") rangeOfString:@"World"]); |
checkNSRange([@"Hello World" rangeOfString:(id)CFSTR("World")]); |
checkNSRange([(id)CFSTR("Hello World") rangeOfString:(id)CFSTR("World")]); |
|
checkCFRange(CFStringFind((CFStringRef)@"Hello World", (CFStringRef)@"World", 0)); |
checkCFRange(CFStringFind(CFSTR("Hello World"), (CFStringRef)@"World", 0)); |
checkCFRange(CFStringFind((CFStringRef)@"Hello World", CFSTR("World"), 0)); |
checkCFRange(CFStringFind(CFSTR("Hello World"), CFSTR("World"), 0)); |
|
/* Check for string uniquing. */ |
if (s0a != s0b || s0a != s2 || s1 != (id)s2) { |
NSLog(@"String uniquing failed"); |
abort (); |
} |
|
return 0; |
} |
/torture/strings/const-str-8.mm
0,0 → 1,45
/* Test for assigning compile-time constant-string objects to static variables. */ |
/* Contributed by Ziemowit Laski <zlaski@apple.com> */ |
|
/* { dg-do run { target *-*-darwin* } } */ |
/* { dg-options "-fconstant-string-class=Foo" } */ |
/* { dg-options "-mno-constant-cfstrings -fconstant-string-class=Foo" { target *-*-darwin* } } */ |
|
#include "../../../objc-obj-c++-shared/TestsuiteObject.m" |
#include <stdlib.h> |
|
@interface Foo: TestsuiteObject { |
char *cString; |
unsigned int len; |
} |
@end |
|
#ifdef __NEXT_RUNTIME__ |
#ifdef NEXT_OBJC_USE_NEW_INTERFACE |
Class _FooClassReference; |
#else |
struct objc_class _FooClassReference; |
#endif |
#endif |
|
@implementation Foo : TestsuiteObject |
- (char *)customString { |
return cString; |
} |
@end |
|
static const Foo *appKey = @"MyApp"; |
static int CFPreferencesSynchronize (const Foo *ref) { |
return ref == appKey; |
} |
|
static void PrefsSynchronize(void) |
{ |
if(!CFPreferencesSynchronize(appKey)) |
abort(); |
} |
|
int main () { |
PrefsSynchronize(); |
return 0; |
} |
/torture/strings/const-str-9.mm
0,0 → 1,28
/* Test if ObjC constant strings get placed in the correct section. */ |
/* Contributed by Ziemowit Laski <zlaski@apple.com> */ |
|
/* { dg-do compile } */ |
/* { dg-skip-if "" { *-*-* } { "-fgnu-runtime" } { "" } } */ |
/* { dg-options "-mno-constant-cfstrings" { target *-*-darwin* } } */ |
|
#include <objc/Object.h> |
#include "../../../objc-obj-c++-shared/runtime.h" /* For NEXT_OBJC_USE_NEW_INTERFACE. */ |
|
@interface NSConstantString: Object { |
char *cString; |
unsigned int len; |
} |
@end |
|
#ifdef NEXT_OBJC_USE_NEW_INTERFACE |
Class _NSConstantStringClassReference; |
#else |
extern struct objc_class _NSConstantStringClassReference; |
#endif |
|
const NSConstantString *appKey = @"MyApp"; |
|
/* { dg-final { scan-assembler ".section __OBJC, __cstring_object" { target { *-*-darwin* && { ! lp64 } } } } } */ |
/* { dg-final { scan-assembler ".section __DATA, __objc_stringobj" { target { *-*-darwin* && { lp64 } } } } } */ |
/* { dg-final { scan-assembler ".long\t__NSConstantStringClassReference\n\t.long\t.*\n\t.long\t5\n\t.data" { target { *-*-darwin* && { ! lp64 } } } } } */ |
/* { dg-final { scan-assembler ".quad\t_OBJC_CLASS_._NSConstantString\n\t.quad\t.*\n\t.long\t5\n\t.space" { target { *-*-darwin* && { lp64 } } } } } */ |
/torture/strings/const-cfstring-3.mm
0,0 → 1,27
/* Test for assigning compile-time constant-string objects to static variables. */ |
/* Contributed by Ziemowit Laski <zlaski@apple.com> */ |
|
/* So far, CFString is darwin-only. */ |
/* { dg-do run { target *-*-darwin* } } */ |
/* { dg-skip-if "NeXT only" { *-*-* } { "-fgnu-runtime" } { "" } } */ |
/* { dg-options "-mconstant-cfstrings -framework Foundation" } */ |
|
#include <stdlib.h> |
|
typedef const struct __CFString * CFStringRef; |
static CFStringRef appKey = (CFStringRef) @"com.apple.soundpref"; |
|
static int CFPreferencesSynchronize (CFStringRef ref) { |
return ref == appKey; |
} |
|
static void PrefsSynchronize() |
{ |
if(!CFPreferencesSynchronize(appKey)) |
abort(); |
} |
|
int main(void) { |
PrefsSynchronize(); |
return 0; |
} |
/torture/strings/const-cfstring-4.mm
0,0 → 1,21
/* Test if constant CFStrings get placed in the correct section and that the |
layout of the object is correct for both m32 and m64. */ |
/* Contributed by Ziemowit Laski <zlaski@apple.com> */ |
|
/* So far, CFString is darwin-only. */ |
/* { dg-do compile { target *-*-darwin* } } */ |
/* { dg-skip-if "NeXT only" { *-*-* } { "-fgnu-runtime" } { "" } } */ |
/* { dg-options "-mconstant-cfstrings" } */ |
|
typedef const struct __CFString * CFStringRef; |
static CFStringRef appKey = (CFStringRef) @"com.apple.soundpref"; |
|
void *foo (void) |
{ |
void *a = (void *)appKey; |
return a; |
} |
|
/* { dg-final { scan-assembler ".section __DATA, __cfstring" } } */ |
/* { dg-final { scan-assembler ".long\t___CFConstantStringClassReference\n\t.long\t1992\n\t.long\t.*\n\t.long\t19\n" { target { *-*-darwin* && { ! lp64 } } } } } */ |
/* { dg-final { scan-assembler ".quad\t___CFConstantStringClassReference\n\t.long\t1992\n\t.space 4\n\t.quad\t.*\n\t.quad\t19\n" { target { *-*-darwin* && { lp64 } } } } } */ |
/warn6.mm
0,0 → 1,7
// PR c++/17212 |
// { dg-options "-Wformat -Wno-format-zero-length" } |
|
void f() |
{ |
__builtin_printf(""); |
} |
/super-class-2.mm
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-obj-c++-shared/TestsuiteObject.h" |
|
@class MyWpModule; |
|
@compatibility_alias MyObject TestsuiteObject; |
@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 |
/method-21.mm
0,0 → 1,25
/* Test for spurious "may or may not return a value" warnings. */ |
/* { dg-do compile } */ |
/* { dg-options "-Wreturn-type -Wextra" } */ |
|
#include "../objc-obj-c++-shared/TestsuiteObject.h" |
|
@interface Foo: TestsuiteObject |
- (id) meth1; |
- (void) meth2; |
@end |
|
extern int bar; |
|
@implementation Foo |
- (id) meth1 { |
if (bar) |
return [TestsuiteObject new]; |
return; /* { dg-error "return.statement with no value" } */ |
} |
- (void) meth2 { |
if (!bar) |
return; |
bar = 0; |
} |
@end |
/proto-lossage-6.mm
0,0 → 1,17
@class Base; |
@protocol _Protocol; |
|
@interface ClassA { |
} |
-(void) func1:(Base<_Protocol> *)inTarget; |
@end |
|
int main() |
{ |
ClassA* theA = 0; |
Base<_Protocol>* myBase = 0; |
[theA func1:myBase]; |
|
return 0; |
} |
|
/fobjc-exceptions-3.mm
0,0 → 1,30
/* Test that Objective-C exceptions cause an error with -fobjc-exceptions. */ |
/* { dg-do compile } */ |
|
@class Object; |
|
int dummy (int number, Object *o) |
{ |
@throw o; /* { dg-error ".-fobjc-exceptions. is required to enable Objective-C exception syntax" } */ |
|
@try { /* Nothing, error has already been produced. */ |
number++; |
@throw o; /* Nothing, error has already been produced. */ |
} |
@catch (id object) |
{ |
number++; |
@throw; /* Nothing, error has already been produced. */ |
} |
@finally |
{ |
number++; |
} |
|
@synchronized (o) /* Nothing, error has already been produced. */ |
{ |
number++; |
} |
|
return number; |
} |
/comp-types-5.mm
0,0 → 1,74
/* Test errors for assignments and comparisons between ObjC and C++ types. */ |
/* Author: Nicola Pero <nicola@brainstorm.co.uk>. */ |
/* { dg-do compile } */ |
|
#include <objc/objc.h> |
|
/* The NeXT runtime headers do not define NULL. */ |
#ifndef NULL |
#define NULL ((void *)0) |
#endif |
|
@protocol MyProtocol |
- (void) method; |
@end |
|
@interface MyClass |
@end |
|
int main() |
{ |
id obj = nil; |
id <MyProtocol> obj_p = nil; |
MyClass *obj_c = nil; |
Class obj_C = Nil; |
|
int i = 0; |
int *j = (int *)NULL; |
|
/* These should all generate warnings. */ |
|
obj = i; /* { dg-error "invalid conversion" } */ |
obj = j; /* { dg-error "cannot convert" } */ |
|
obj_p = i; /* { dg-error "invalid conversion" } */ |
obj_p = j; /* { dg-error "cannot convert" } */ |
|
obj_c = i; /* { dg-error "invalid conversion" } */ |
obj_c = j; /* { dg-error "cannot convert" } */ |
|
obj_C = i; /* { dg-error "invalid conversion" } */ |
obj_C = j; /* { dg-error "cannot convert" } */ |
|
i = obj; /* { dg-error "invalid conversion" } */ |
i = obj_p; /* { dg-error "invalid conversion" } */ |
i = obj_c; /* { dg-error "invalid conversion" } */ |
i = obj_C; /* { dg-error "invalid conversion" } */ |
|
j = obj; /* { dg-error "cannot convert" } */ |
j = obj_p; /* { dg-error "cannot convert" } */ |
j = obj_c; /* { dg-error "cannot convert" } */ |
j = obj_C; /* { dg-error "cannot convert" } */ |
|
if (obj == i) ; /* { dg-error "comparison between pointer and integer" } */ |
if (i == obj) ; /* { dg-error "comparison between pointer and integer" } */ |
if (obj == j) ; /* { dg-error "lacks a cast" } */ |
if (j == obj) ; /* { dg-error "lacks a cast" } */ |
|
if (obj_c == i) ; /*{ dg-error "comparison between pointer and integer" }*/ |
if (i == obj_c) ; /*{ dg-error "comparison between pointer and integer" }*/ |
if (obj_c == j) ; /* { dg-error "lacks a cast" } */ |
if (j == obj_c) ; /* { dg-error "lacks a cast" } */ |
|
if (obj_p == i) ; /*{ dg-error "comparison between pointer and integer" }*/ |
if (i == obj_p) ; /*{ dg-error "comparison between pointer and integer" }*/ |
if (obj_p == j) ; /* { dg-error "lacks a cast" } */ |
if (j == obj_p) ; /* { dg-error "lacks a cast" } */ |
|
if (obj_C == i) ; /*{ dg-error "comparison between pointer and integer" }*/ |
if (i == obj_C) ; /*{ dg-error "comparison between pointer and integer" }*/ |
if (obj_C == j) ; /* { dg-error "lacks a cast" } */ |
if (j == obj_C) ; /* { dg-error "lacks a cast" } */ |
|
return 0; |
} |
/dwarf-2.mm
0,0 → 1,4
/* { dg-options "-gdwarf-2 -dA" } */ |
/* { dg-skip-if "No Dwarf" { { alpha*-dec-osf* hppa*-*-hpux* } && { ! hppa*64*-*-* } } { "*" } { "" } } */ |
/* { dg-final { scan-assembler "0x11\[^0-9a-f\].*DW_AT_language" } } */ |
int x; |
/try-catch-7.mm
0,0 → 1,24
/* { dg-do compile } */ |
/* { dg-options "-fobjc-exceptions" } */ |
|
#include "../objc-obj-c++-shared/TestsuiteObject.h" |
|
int main (int argc, const char * argv[]) { |
TestsuiteObject * pool = [TestsuiteObject new]; |
int a; |
|
if ( 1 ) { |
@try { |
a = 1; |
} |
@catch (TestsuiteObject *e) { |
a = 2; |
} |
@finally { |
a = 3; |
} |
} |
|
[pool free]; |
return 0; |
} |
/cxx-class-1.mm
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. */ |
/* { dg-xfail-run-if "Needs OBJC2 ABI" { *-*-darwin* && { lp64 && { ! objc2 } } } { "-fnext-runtime" } { "" } } */ |
struct foo |
{ |
foo(void *a) {}; |
}; |
|
struct bar : foo |
{ |
bar() : foo((char*)0) {}; |
}; |
|
class apple : foo |
{ |
public: |
apple() : foo(0) { }; |
}; |
/method-15.mm
0,0 → 1,43
/* Check if finding multiple signatures for a method is handled gracefully when method lookup succeeds (see also method-7.m). */ |
/* Contributed by Ziemowit Laski <zlaski@apple.com> */ |
/* { dg-options "-Wstrict-selector-match" } */ |
/* { dg-do compile } */ |
|
#include "../objc-obj-c++-shared/TestsuiteObject.h" |
|
@protocol MyObject |
- (id)initWithData:(TestsuiteObject *)data; |
@end |
|
@protocol SomeOther |
- (id)initWithData:(int)data; |
@end |
|
@protocol MyCoding |
- (id)initWithData:(id<MyObject, MyCoding>)data; |
@end |
|
@interface NTGridDataObject: TestsuiteObject <MyCoding> |
{ |
TestsuiteObject<MyCoding> *_data; |
} |
+ (NTGridDataObject*)dataObject:(id<MyObject, MyCoding>)data; |
@end |
|
@implementation NTGridDataObject |
- (id)initWithData:(id<MyObject, MyCoding>)data { |
return data; |
} |
+ (NTGridDataObject*)dataObject:(id<MyObject, MyCoding>)data |
{ |
NTGridDataObject *result = [[NTGridDataObject alloc] initWithData:data]; |
/* { dg-warning "multiple methods named .\\-initWithData:. found" "" { target *-*-* } 33 } */ |
/* { dg-message "using .\\-\\(id\\)initWithData:\\(TestsuiteObject \\*\\)data." "" { target *-*-* } 9 } */ |
/* { dg-message "also found .\\-\\(id\\)initWithData:\\(id <MyObject, MyCoding>\\)data." "" { target *-*-* } 17 } */ |
/* { dg-message "also found .\\-\\(id\\)initWithData:\\(int\\)data." "" { target *-*-* } 13 } */ |
|
/* The following warning is a consequence of picking the "wrong" method signature. */ |
/* { dg-warning "passing argument 1 of .initWithData:. from distinct Objective\\-C type" "" { target *-*-* } 33 } */ |
return result; |
} |
@end |
/bad-receiver-type.mm
0,0 → 1,15
// { dg-do compile } |
// { dg-options "" } |
|
@interface A |
|
- (void)test; |
|
@end |
|
extern int foo(); |
|
void baz() |
{ |
[foo test]; /* { dg-warning "invalid receiver type" } */ |
} |
/gnu-api-2-objc.mm
0,0 → 1,266
/* Test the Modern GNU Objective-C Runtime API. |
|
This is test 'objc', covering all functions starting with 'objc'. */ |
|
/* { dg-do run } */ |
/* { dg-skip-if "No API#2 pre-Darwin9" { *-*-darwin[5-8]* } { "-fnext-runtime" } { "" } } */ |
/* { dg-xfail-run-if "Needs OBJC2 ABI" { *-*-darwin* && { lp64 && { ! objc2 } } } { "-fnext-runtime" } { "" } } */ |
|
/* To get the modern GNU Objective-C Runtime API, you include |
objc/runtime.h. */ |
#include <objc/runtime.h> |
#include <stdlib.h> |
#include <iostream> |
#include <cstring> |
|
@interface MyRootClass |
{ Class isa; } |
+ alloc; |
- init; |
+ initialize; |
@end |
|
@implementation MyRootClass |
+ alloc { return class_createInstance (self, 0); } |
- init { return self; } |
+ initialize { return self; } |
@end |
|
@protocol MyProtocol |
- (id) variable; |
@end |
|
@protocol MySecondProtocol |
- (id) setVariable: (id)value; |
@end |
|
@interface MySubClass : MyRootClass <MyProtocol> |
{ id variable_ivar; } |
- (void) setVariable: (id)value; |
- (id) variable; |
@end |
|
@implementation MySubClass |
- (void) setVariable: (id)value { variable_ivar = value; } |
- (id) variable { return variable_ivar; } |
@end |
|
/* Hack to calculate the log2 of a byte alignment. */ |
unsigned char |
log_2_of (unsigned int x) |
{ |
unsigned char result = 0; |
|
/* We count how many times we need to divide by 2 before we reach 1. |
This algorithm is good enough for the small numbers (such as 8, |
16 or 64) that we have to deal with. */ |
while (x > 1) |
{ |
x = x / 2; |
result++; |
} |
|
return result; |
} |
|
int main () |
{ |
/* Functions are tested in alphabetical order. */ |
|
std::cout << "Testing objc_allocateClassPair ()...\n"; |
{ |
Class new_root_class = objc_allocateClassPair (Nil, "MyNewRootClass", 0); |
Class new_class = objc_allocateClassPair (objc_getClass ("MyRootClass"), "MyNewSubClass", 0); |
|
/* A new root class would obviously need at least an 'isa' |
instance variable. */ |
class_addIvar (new_root_class, "isa", sizeof (Class), log_2_of (__alignof__ (Class)), |
@encode (Class)); |
|
objc_registerClassPair (new_root_class); |
objc_registerClassPair (new_class); |
|
if (std::strcmp (class_getName (new_class), "MyNewSubClass") != 0) |
abort (); |
|
if (class_getSuperclass (new_class) != objc_getClass ("MyRootClass")) |
abort (); |
|
if (std::strcmp (class_getName (new_root_class), "MyNewRootClass") != 0) |
abort (); |
|
if (class_getSuperclass (new_root_class) != Nil) |
abort (); |
|
{ |
MySubClass *o = [[(Class)objc_getClass ("MyNewSubClass") alloc] init]; |
|
if (object_getClass (o) != objc_getClass ("MyNewSubClass")) |
abort (); |
} |
} |
|
std::cout << "Testing objc_copyProtocolList ()...\n"; |
{ |
/* Make sure both our two protocols are known to the runtime. */ |
id my_protocol = @protocol (MyProtocol); |
id my_second_protocol = @protocol (MySecondProtocol); |
unsigned int count; |
Protocol ** list = objc_copyProtocolList (&count); |
|
if (count != 2) |
abort (); |
|
if (! ((std::strcmp (protocol_getName (list[0]), "MyProtocol") == 0 |
&& std::strcmp (protocol_getName (list[1]), "MySecondProtocol") == 0) |
|| (std::strcmp (protocol_getName (list[0]), "MySecondProtocol") == 0 |
&& std::strcmp (protocol_getName (list[1]), "MyProtocol") == 0))) |
abort (); |
|
if (list[2] != NULL) |
abort (); |
} |
|
std::cout << "Testing objc_disposeClassPair ()...\n"; |
{ |
Method method = class_getInstanceMethod (objc_getClass ("MySubClass"), @selector (setVariable:)); |
Class new_class = objc_allocateClassPair (objc_getClass ("MyRootClass"), "MyNewSubClass2", 0); |
|
if (new_class == Nil) |
abort (); |
|
/* Add a bit of everything to the class to exercise undoing all these changes. */ |
|
/* Instance variable. */ |
class_addIvar (new_class, "my_variable", sizeof (float), log_2_of (__alignof__ (float)), @encode (float)); |
|
/* Instance method. */ |
class_addMethod (new_class, @selector (setVariable:), method_getImplementation (method), |
method_getTypeEncoding (method)); |
|
/* Class method. */ |
class_addMethod (object_getClass (new_class), @selector (setVariable:), method_getImplementation (method), |
method_getTypeEncoding (method)); |
|
/* Protocol. */ |
class_addProtocol (new_class, @protocol (MyProtocol)); |
|
objc_disposeClassPair (new_class); |
} |
|
/* This function currently does not exist with the GNU runtime. */ |
/* std::cout << "Testing objc_duplicateClass ()...\n"; */ |
|
/* TODO - Test it when implemented in the GNU Runtime */ |
/* std::cout << "Testing objc_getAssociatedObject ()...\n"; */ |
|
std::cout << "Testing objc_getClass ()...\n"; |
{ |
if (std::strcmp (class_getName (objc_getClass ("MySubClass")), |
"MySubClass") != 0) |
abort (); |
} |
|
std::cout << "Testing objc_getClassList ()...\n"; |
{ |
Class *list; |
int i, count, other_count; |
count = objc_getClassList (NULL, 0); |
|
/* count most likely will be 5, (MyRootClass, MySubClass, |
Protocol, Object, NXConstantString). */ |
if (count < 3) |
abort (); |
|
list = (Class *)(malloc (sizeof (Class) * count)); |
other_count = objc_getClassList (list, count); |
|
if (other_count != count) |
abort (); |
|
/* Spot-check: search for class 'MyRootClass' in the list. */ |
for (i = 0; i < count; i++) |
{ |
if (std::strcmp (class_getName (list[i]), "MyRootClass") == 0) |
break; |
} |
if (i == count) |
abort (); |
|
/* Spot-check: search for class 'MySubClass' in the list. */ |
for (i = 0; i < count; i++) |
{ |
if (std::strcmp (class_getName (list[i]), "MySubClass") == 0) |
break; |
} |
if (i == count) |
abort (); |
|
/* Spot-check: search for class 'Protocol' in the list. */ |
for (i = 0; i < count; i++) |
{ |
if (std::strcmp (class_getName (list[i]), "Protocol") == 0) |
break; |
} |
if (i == count) |
abort (); |
} |
|
/* This function does not exist with the GNU runtime. */ |
/* std::cout << "Testing objc_getFutureClass ()...\n"; */ |
|
std::cout << "Testing objc_getMetaClass ()...\n"; |
{ |
if (! class_isMetaClass (objc_getMetaClass ("MyRootClass"))) |
abort (); |
} |
|
std::cout << "Testing objc_getProtocol ()...\n"; |
{ |
if (! protocol_isEqual (objc_getProtocol ("MyProtocol"), @protocol (MyProtocol))) |
abort (); |
} |
|
std::cout << "Testing objc_getRequiredClass ()...\n"; |
{ |
if (std::strcmp (class_getName (objc_getRequiredClass ("MyRootClass")), |
"MyRootClass") != 0) |
abort (); |
} |
|
std::cout << "Testing objc_lookUpClass ()...\n"; |
{ |
if (std::strcmp (class_getName (objc_lookUpClass ("MyRootClass")), |
"MyRootClass") != 0) |
abort (); |
} |
|
/* This function does not exist with the GNU runtime. */ |
/* std::cout << "Testing objc_setFutureClass ()...\n"; */ |
|
std::cout << "Testing objc_registerClassPair ()...\n"; |
{ |
Class new_class = objc_allocateClassPair (objc_getClass ("MySubClass"), "MySubSubClass", 0); |
|
class_addProtocol (new_class, @protocol (MySecondProtocol)); |
|
objc_registerClassPair (new_class); |
|
if (std::strcmp (class_getName (new_class), "MySubSubClass") != 0) |
abort (); |
|
if (class_getSuperclass (new_class) != objc_getClass ("MySubClass")) |
abort (); |
|
if (! class_conformsToProtocol (new_class, @protocol (MySecondProtocol))) |
abort (); |
} |
|
/* TODO - Test it when implemented in the GNU Runtime */ |
/* std::cout << "Testing objc_removeAssociatedObjects ()...\n"; */ |
|
/* TODO - Test it when implemented in the GNU Runtime */ |
/* std::cout << "Testing objc_setAssociatedObject ()...\n"; */ |
|
return (0); |
} |
/demangle-2.mm
0,0 → 1,53
/* Test demangling an Objective-C method. */ |
/* { dg-do run } */ |
/* { dg-xfail-run-if "Needs OBJC2 ABI" { *-*-darwin* && { lp64 && { ! objc2 } } } { "-fnext-runtime" } { "" } } */ |
|
#include <cstring> |
#include <cstdlib> |
#include <iostream> |
#include <objc/objc.h> |
|
@interface DemangleTest |
{ |
Class isa; |
} |
+ (int) testFunction1; |
+ (int) test_function2; |
+ (int) __testFunction3: (int)unused andArgument: (char)unused2; |
+ (id) initialize; |
@end |
|
@implementation DemangleTest |
+ (int) testFunction1 |
{ |
std::cout << __PRETTY_FUNCTION__ << "\n"; |
return std::strcmp (__PRETTY_FUNCTION__, "+[DemangleTest testFunction1]"); |
} |
+ (int) test_function2 |
{ |
std::cout << __PRETTY_FUNCTION__ << "\n"; |
return std::strcmp (__PRETTY_FUNCTION__, "+[DemangleTest test_function2]"); |
} |
+ (int) __testFunction3: (int)unused andArgument: (char)unused2 |
{ |
std::cout << __PRETTY_FUNCTION__ << "\n"; |
return std::strcmp (__PRETTY_FUNCTION__, "+[DemangleTest __testFunction3:andArgument:]"); |
} |
+ (id) initialize { return self; } |
@end |
|
int main () |
{ |
if ([DemangleTest testFunction1] != 0) |
abort (); |
|
if ([DemangleTest test_function2] != 0) |
abort (); |
|
if ([DemangleTest __testFunction3:0 andArgument: 'c'] != 0) |
abort (); |
|
return 0; |
} |
|
|
/layout-1.mm
0,0 → 1,17
/* Ensure that we do not get bizarre warnings referring to |
__attribute__((packed)) or some such. */ |
/* { dg-do compile } */ |
/* { dg-options "-Wpadded -Wpacked -Wabi" } */ |
|
#include "../objc-obj-c++-shared/TestsuiteObject.h" |
|
@interface Derived1: TestsuiteObject |
{ } |
@end |
|
@interface Derived2: TestsuiteObject |
- (id) foo; |
@end |
|
/* { dg-prune-output "In output included from" } Ignore this message. */ |
/* { dg-bogus "padding struct to align" "PR23610" { target *-*-* } 0 } */ |
/extra-semi.mm
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 |
/method-1.mm
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; |
} |
/attributes/attributes.exp
0,0 → 1,43
# Copyright (C) 2010 Free Software Foundation, Inc. |
# |
# This file is part of GCC. |
# |
# GCC is free software; you can redistribute it and/or modify |
# it under the terms of the GNU General Public License as published by |
# the Free Software Foundation; either version 3, or (at your option) |
# any later version. |
# |
# GCC is distributed in the hope that it will be useful, |
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
# GNU General Public License for more details. |
# |
# You should have received a copy of the GNU General Public License |
# along with GCC; see the file COPYING3. If not see |
# <http://www.gnu.org/licenses/>. |
|
# 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 |
/attributes/method-deprecated-1.mm
0,0 → 1,33
/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, October 2010. */ |
/* { dg-do compile } */ |
|
#include <objc/objc.h> |
|
@interface MyClass |
{ |
Class isa; |
} |
+ (int) method; |
- (int) method; |
+ (int) deprecatedClassMethod __attribute__((deprecated)); |
- (int) deprecatedInstanceMethod __attribute__((deprecated)); |
@end |
|
/* Test that deprecation warnings are produced, but not if the |
receiver is of type 'id'. */ |
void foo (void) |
{ |
Class c; |
id object; |
MyClass *another_object; |
|
[c method]; |
[object method]; |
[c deprecatedClassMethod]; |
[object deprecatedInstanceMethod]; |
|
[object method]; |
[another_object method]; |
[MyClass deprecatedClassMethod]; /* { dg-warning "is deprecated" } */ |
[another_object deprecatedInstanceMethod]; /* { dg-warning "is deprecated" } */ |
} |
/attributes/method-deprecated-2.mm
0,0 → 1,23
/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, October 2010. */ |
/* { dg-do compile } */ |
|
#include <objc/objc.h> |
|
@interface MyClass |
{ |
Class isa; |
} |
+ (int) deprecatedClassMethod: (id)firstObject, ... __attribute__((sentinel)) __attribute__((deprecated)); |
- (int) deprecatedInstanceMethod: (id)firstobject, ... __attribute__((sentinel)) __attribute__((deprecated)); |
@end |
|
/* Test that deprecation warnings are produced even if the method is |
also marked with another attribute too (this is to test the |
processing of multiple attributes). */ |
void foo (void) |
{ |
MyClass *object = nil; |
|
[MyClass deprecatedClassMethod: object, nil]; /* { dg-warning "is deprecated" } */ |
[object deprecatedInstanceMethod: object, nil]; /* { dg-warning "is deprecated" } */ |
} |
/attributes/method-deprecated-3.mm
0,0 → 1,21
/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, October 2010. */ |
/* { dg-do compile } */ |
|
#include <objc/objc.h> |
|
/* Test that __attribute__ ((__deprecated__)) works as well as __attribute__ ((deprecated)). */ |
@interface MyClass |
{ |
Class isa; |
} |
+ (int) deprecatedClassMethod: (id)firstObject, ... __attribute__((__deprecated__)); |
- (int) deprecatedInstanceMethod: (id)firstobject, ... __attribute__((__deprecated__)); |
@end |
|
void foo (void) |
{ |
MyClass *object = nil; |
|
[MyClass deprecatedClassMethod: object, nil]; /* { dg-warning "is deprecated" } */ |
[object deprecatedInstanceMethod: object, nil]; /* { dg-warning "is deprecated" } */ |
} |
/attributes/method-attribute-1.mm
0,0 → 1,40
/* { dg-do compile } */ |
|
#include <objc/objc.h> |
#include "../../objc-obj-c++-shared/TestsuiteObject.h" |
|
@interface obj : TestsuiteObject { |
@public |
int var; |
} |
- (int) mth; |
+ (id) dep_cls_mth __attribute__((deprecated)) ; |
- (int) dep_ins_mth __attribute__((deprecated)) ; |
- (int) dep_ins_mtharg: (int) i __attribute__((deprecated)) ; |
- (int) dep_ins_mtharg1: (int) i __attribute__((deprecated)) add: (int) j;/* { dg-error "method attributes must be specified at the end " } */ |
- (int) nodef __attribute__((deprecated)) { return var-2; } ; /* { dg-error "expected ';' before '\{' token" } */ |
__attribute__((deprecated)) |
- (int) bad_pref_mth; /* { dg-warning "prefix attributes are ignored for methods" } */ |
@end |
|
@implementation obj |
- (int) mth { return var; } |
+ (id) dep_cls_mth { return self; } |
- (int) dep_ins_mth { return var ; } |
- (int) dep_ins_mtharg: (int) i { return var + i ; } |
- (int) dep_ins_mtharg1: (int) i add: (int) j { return var + i + j ; } |
- (int) bad_pref_mth { return var; }; |
- (int) nodef { return var-2; } ; |
@end |
|
int foo (void) |
{ |
obj *p = [obj new]; |
id n = [obj dep_cls_mth]; /* { dg-warning "is deprecated" } */ |
|
[p dep_ins_mth]; /* { dg-warning "is deprecated" } */ |
[p dep_ins_mtharg:2]; /* { dg-warning "is deprecated" } */ |
[p dep_ins_mtharg1:3 add:3]; |
|
return [p mth]; |
} |
/attributes/unused-parameter-1.mm
0,0 → 1,50
/* { dg-do compile } */ |
|
#include <objc/objc.h> |
|
@interface MyRootClass |
{ |
Class isa; |
} |
- (id) method1: (id) argument1; |
- (id) method2: (id) __attribute__((unused)) argument1; |
- (id) method3: (id) __attribute__((unused)) argument1 |
andArgument: (id) argument2; |
- (id) method4: (id) __attribute__((unused)) argument1 |
andArgument: (id) __attribute__((unused)) argument2; |
- (id) method5: (id) argument1 |
andArgument: (id) __attribute__ ((unused)) argument2; |
- (id) method6: (id) argument1 |
andArgument: (id) argument2; |
@end |
|
@implementation MyRootClass |
- (id) method1: (id) argument1 |
{ |
return nil; |
} |
- (id) method2: (id) __attribute__((unused)) argument1 |
{ |
return nil; |
} |
- (id) method3: (id) __attribute__((unused)) argument1 |
andArgument: (id) argument2 |
{ |
return nil; |
} |
- (id) method4: (id) __attribute__((unused)) argument1 |
andArgument: (id) __attribute__((unused)) argument2 |
{ |
return nil; |
} |
- (id) method5: (id) argument1 |
andArgument: (id) __attribute__ ((unused)) argument2 |
{ |
return nil; |
} |
- (id) method6: (id) argument1 |
andArgument: (id) argument2 |
{ |
return nil; |
} |
@end |
/attributes/parameter-attribute-1.mm
0,0 → 1,45
/* Test __attribute__((unused)) for an Objective-C method parameter. */ |
/* { dg-do compile } */ |
/* { dg-options "-Wunused-parameter" } */ |
|
#include <objc/objc.h> |
|
@interface MyRootClass |
{ |
Class isa; |
} |
- (id) method1: (id) argument1; |
- (id) method2: (id) __attribute__((unused)) argument1; |
- (id) method3: (id) __attribute__((unused)) argument1 |
andArgument: (id) argument2; |
- (id) method4: (id) __attribute__((unused)) argument1 |
andArgument: (id) __attribute__((unused)) argument2; |
- (id) method5: (id) argument1 |
andArgument: (id) __attribute__ ((unused)) argument2; |
@end |
|
@implementation MyRootClass |
- (id) method1: (id) argument1 /* { dg-warning "unused parameter .argument1." } */ |
{ |
return nil; |
} |
- (id) method2: (id) __attribute__((unused)) argument1 |
{ |
return nil; |
} |
- (id) method3: (id) __attribute__((unused)) argument1 |
andArgument: (id) argument2 /* { dg-warning "unused parameter .argument2." } */ |
{ |
return nil; |
} |
- (id) method4: (id) __attribute__((unused)) argument1 |
andArgument: (id) __attribute__((unused)) argument2 |
{ |
return nil; |
} |
- (id) method5: (id) argument1 |
andArgument: (id) __attribute__ ((unused)) argument2 /* { dg-warning "unused parameter .argument1." } */ |
{ |
return nil; |
} |
@end |
/attributes/method-attribute-2.mm
0,0 → 1,33
/* { dg-do compile } */ |
|
#include <objc/objc.h> |
#include "../../objc-obj-c++-shared/TestsuiteObject.h" |
|
@interface obj : TestsuiteObject { |
@public |
int var; |
} |
- (int) depmth __attribute__((deprecated)); |
- (int) depmtharg:(int) iarg __attribute__((deprecated)); |
- (int) unusedarg:(int) __attribute__((unused)) uarg ; |
- (int) depunusedarg:(int) __attribute__((unused)) uarg __attribute__((deprecated)) ; |
@end |
|
@implementation obj |
- (int) depmth __attribute__((deprecated)) { return var; } /* { dg-warning "method attributes can not be specified in @implementation context" } */ |
- (int) depmtharg:(int) iarg { return var + iarg ; } |
- (int) unusedarg:(int) __attribute__((unused)) uarg { return var; } |
- (int) depunusedarg:(int) __attribute__((unused)) uarg { return var; } |
@end |
|
int foo (void) |
{ |
obj *p = [obj new]; |
|
[p depmth]; /* { dg-warning "is deprecated" } */ |
[p depmtharg:1]; /* { dg-warning "is deprecated" } */ |
[p unusedarg:2]; /* { dg-bogus "is deprecated" } */ |
[p depunusedarg:3 ]; /* { dg-warning "is deprecated" } */ |
|
return [p depmtharg:0]; /* { dg-warning "is deprecated" } */ |
} |
/attributes/parameter-attribute-2.mm
0,0 → 1,25
/* Test that we get warnings for unrecognized attributes. */ |
/* { dg-do compile } */ |
|
#include <objc/objc.h> |
|
@interface MyRootClass |
{ |
Class isa; |
} |
/* TODO: Emit warnings in the @interface as well. Currently we only emit |
them in @implementation. */ |
+ (id) method1: (id) __attribute__ ((xxxxx)) argument1; |
+ (id) method2: (id) __attribute__ ((noinline)) argument1; |
@end |
|
@implementation MyRootClass |
+ (id) method1: (id) __attribute__ ((xxxxx)) argument1 /* { dg-warning ".xxxxx. attribute directive ignored" } */ |
{ |
return argument1; |
} |
+ (id) method2: (id) __attribute__ ((noinline)) argument1 /* { dg-warning ".noinline. attribute ignored" } */ |
{ |
return argument1; |
} |
@end |
/attributes/method-attribute-3.mm
0,0 → 1,24
/* { dg-do compile } */ |
|
#include "../../objc-obj-c++-shared/TestsuiteObject.h" |
|
@interface obj : TestsuiteObject { |
@public |
int var; |
} |
- (int) vargsn: (int) count, ... __attribute__((deprecated)); |
@end |
|
@implementation obj |
- (int) vargsn: (int) count, ... |
{ |
return 0; |
} |
@end |
|
int foo (void) |
{ |
obj *p = [obj new]; |
|
return [p vargsn:0]; /* { dg-warning "'vargsn:' is deprecated .declared at" } */ |
} |
/attributes/categ-attribute-1.mm
0,0 → 1,31
/* { dg-do compile } */ |
|
#include <objc/objc.h> |
#include "../../objc-obj-c++-shared/TestsuiteObject.h" |
|
@interface obj : TestsuiteObject { |
@public |
int var; |
} |
- (int) mth; |
@end |
|
@implementation obj |
- (int) mth { return var; } |
@end |
|
__attribute ((deprecated)) |
@interface obj (dep_categ) /* { dg-warning "category attributes are not available in this version" } */ |
- (int) depmth; |
@end |
|
@implementation obj (dep_categ) |
- (int) depmth { return var + 1; } |
@end |
|
int foo (void) |
{ |
obj *p = [obj new]; |
int q = [p depmth]; |
return [p mth]; |
} |
/attributes/categ-attribute-2.mm
0,0 → 1,32
/* { dg-do compile } */ |
|
#include <objc/objc.h> |
#include "../../objc-obj-c++-shared/TestsuiteObject.h" |
|
@interface obj : TestsuiteObject { |
@public |
int var; |
} |
- (int) mth; |
@end |
|
@implementation obj |
- (int) mth { return var; } |
@end |
|
__attribute__ ((deprecated("no dep_categ"))) |
@interface obj (dep_categ) /* { dg-warning "category attributes are not available in this version" } */ |
- (int) depmth; |
@end |
|
__attribute__ ((deprecated)) |
@implementation obj (dep_categ) /* { dg-warning "prefix attributes are ignored before" } */ |
- (int) depmth { return var + 1; } |
@end |
|
int foo (void) |
{ |
obj *p = [obj new]; |
int q = [p depmth]; |
return [p mth]; |
} |
/attributes/invalid-attribute-1.mm
0,0 → 1,6
/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, January 2011. */ |
/* { dg-do compile } */ |
|
#include <objc/objc.h> |
|
__attribute__ ((deprecated)) @class A; /* { dg-error "attributes may not be specified before the ..class. Objective-C.. keyword" } */ |
/attributes/method-noreturn-1.mm
0,0 → 1,34
/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, October 2010. */ |
/* { dg-do compile } */ |
|
#include <objc/objc.h> |
#include <stdlib.h> |
|
@interface MyClass |
{ |
Class isa; |
} |
+ (id) method1 __attribute__ ((noreturn)); |
- (id) method2 __attribute__ ((noreturn)); |
+ (id) method3 __attribute__ ((noreturn)); |
- (id) method4 __attribute__ ((noreturn)); |
@end |
|
@implementation MyClass |
+ (id) method1 |
{ |
return self; /* { dg-warning "function declared .noreturn. has a .return. statement" } */ |
} /* { dg-warning ".noreturn. function does return" "" { target *-*-* } 20 } */ |
- (id) method2 |
{ |
return self; /* { dg-warning "function declared .noreturn. has a .return. statement" } */ |
} /* { dg-warning ".noreturn. function does return" "" { target *-*-* } 24 } */ |
+ (id) method3 |
{ |
abort (); |
} |
- (id) method4 |
{ |
abort (); |
} |
@end |
/attributes/method-sentinel-1.mm
0,0 → 1,36
/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, October 2010. */ |
/* { dg-do compile } */ |
/* { dg-options "-Wall" } */ |
|
#include <objc/objc.h> |
#include <stdlib.h> |
/* Ensure a compatible definition of nil. */ |
#include "../../objc-obj-c++-shared/objc-test-suite-types.h" |
|
@interface NSArray |
{ |
Class isa; |
} |
+ (id) arrayWithObject: (id)object __attribute__ ((sentinel)); /* { dg-warning "attribute only applies to variadic functions" } */ |
+ (id) arrayWithObjects: (id)firstObject, ... __attribute__ ((sentinel)); |
|
- (id) initWithObject: (id)object __attribute__ ((sentinel)); /* { dg-warning "attribute only applies to variadic functions" } */ |
- (id) initWithObjects: (id)firstObject, ... __attribute__ ((sentinel)); |
@end |
|
void test (id object) |
{ |
NSArray *array; |
|
array = [NSArray arrayWithObject: object]; |
array = [NSArray arrayWithObjects: object, nil]; |
array = [NSArray arrayWithObjects: object, object, nil]; |
array = [NSArray arrayWithObjects: object]; /* { dg-warning "not enough variable arguments" } */ |
array = [NSArray arrayWithObjects: object, object]; /* { dg-warning "missing sentinel" } */ |
|
[array initWithObject: object]; |
[array initWithObjects: object, nil]; |
[array initWithObjects: object, object, nil]; |
[array initWithObjects: object]; /* { dg-warning "not enough variable arguments" } */ |
[array initWithObjects: object, object]; /* { dg-warning "missing sentinel" } */ |
} |
/attributes/method-nonnull-1.mm
0,0 → 1,46
/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, May 2011. */ |
/* { dg-do compile } */ |
/* { dg-options "-Wall" } */ |
|
#include <objc/objc.h> |
#include <stdlib.h> |
|
@interface MyArray |
{ |
Class isa; |
} |
+ (void) addObject: (id)object __attribute__ ((nonnull)); |
- (void) addObject: (id)object __attribute__ ((nonnull)); |
|
+ (void) insertObject: (id)object atIndex: (size_t)index __attribute__ ((nonnull (1))); |
- (void) insertObject: (id)object atIndex: (size_t)index __attribute__ ((nonnull (1))); |
|
+ (void) insertObject: (id)object atIndex: (size_t)index andObject: (id)anotherObject atIndex: (size_t)anotherIndex __attribute__ ((nonnull (1, 3))); |
- (void) insertObject: (id)object atIndex: (size_t)index andObject: (id)anotherObject atIndex: (size_t)anotherIndex __attribute__ ((nonnull (1, 3))); |
|
/* Test the behaviour with invalid code. */ |
+ (void) removeObject: (id)object __attribute__ ((nonnull (0))); /* { dg-error "out-of-range" } */ |
- (void) removeObject: (id)object __attribute__ ((nonnull (0))); /* { dg-error "out-of-range" } */ |
|
+ (void) removeObject: (id)object __attribute__ ((nonnull (2))); /* { dg-error "out-of-range" } */ |
- (void) removeObject: (id)object __attribute__ ((nonnull (2))); /* { dg-error "out-of-range" } */ |
|
+ (void) removeObjectAtIndex: (size_t)object __attribute__ ((nonnull (1))); /* { dg-error "non-pointer operand" } */ |
- (void) removeObjectAtIndex: (size_t)object __attribute__ ((nonnull (1))); /* { dg-error "non-pointer operand" } */ |
|
+ (void) removeObject: (id)object __attribute__ ((nonnull (MyArray))); /* { dg-error "" } */ |
- (void) removeObject: (id)object __attribute__ ((nonnull (MyArray))); /* { dg-error "" } */ |
@end |
|
void test (MyArray *object) |
{ |
[object addObject: object]; |
[object addObject: nil]; /* { dg-warning "null argument where non-null required" } */ |
|
[object insertObject: object atIndex: 4]; |
[object insertObject: nil atIndex: 4]; /* { dg-warning "null argument where non-null required" } */ |
|
[object insertObject: object atIndex: 2 andObject: object atIndex: 3]; |
[object insertObject: nil atIndex: 2 andObject: object atIndex: 3]; /* { dg-warning "null argument where non-null required" } */ |
[object insertObject: object atIndex: 2 andObject: nil atIndex: 3]; /* { dg-warning "null argument where non-null required" } */ |
} |
/attributes/proto-attribute-1.mm
0,0 → 1,21
/* { dg-do compile } */ |
|
#include <objc/objc.h> |
|
__attribute ((deprecated)) |
@protocol dep_proto |
- (int) depprotomth; |
@end |
|
@interface obj <dep_proto> /* { dg-warning "is deprecated" } */ |
{ |
@public |
int var; |
} |
- (int) mth; |
@end |
|
@implementation obj |
- (int) mth { return var; } |
- (int) depprotomth { return var + 1; } |
@end |
/attributes/proto-attribute-2.mm
0,0 → 1,33
/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, November 2010. */ |
/* { dg-do compile } */ |
/* { dg-skip-if "No API#2 pre-Darwin9" { *-*-darwin[5-8]* } { "-fnext-runtime" } { "" } } */ |
|
/* Test deprecate attribute with a forward declarations of |
@protocol. */ |
|
#include <stdlib.h> |
#include <objc/objc.h> |
#include <objc/runtime.h> |
|
__attribute__ ((deprecated)) |
@protocol DeprecatedProtocol1; |
|
@protocol NonDeprecatedProtocol1; |
|
void function1 (id <DeprecatedProtocol1> object); /* { dg-warning "is deprecated" } */ |
void function2 (id <NonDeprecatedProtocol1> object); |
|
@class Class4; |
|
void function3 (Class4 <DeprecatedProtocol1> *object); /* { dg-warning "is deprecated" } */ |
void function4 (Class4 <NonDeprecatedProtocol1> *object); |
void function5 (Class4 <NonDeprecatedProtocol1, DeprecatedProtocol1> *object); /* { dg-warning "is deprecated" } */ |
|
int function6 (void) |
{ |
Protocol *p1 = @protocol (DeprecatedProtocol1); /* { dg-warning "is deprecated" } */ |
Protocol *p2 = @protocol (NonDeprecatedProtocol1); |
|
return (p1 == p2); |
} |
|
/attributes/class-attribute-1.mm
0,0 → 1,61
/* { dg-do compile } */ |
/* { dg-skip-if "No API#2 pre-Darwin9" { *-*-darwin[5-8]* } { "-fnext-runtime" } { "" } } */ |
|
/* Test deprecate attribute with an @interface declaration. */ |
|
#include <objc/objc.h> |
#include <objc/runtime.h> |
|
__attribute__ ((deprecated)) |
@interface DeprecatedClass |
{ |
Class isa; |
} |
+ (id) classObject; |
+ (id) new; |
@end |
|
@implementation DeprecatedClass |
+ (id) classObject { return self; } |
+ (id) new { return nil; } |
@end |
|
@interface DeprecatedClass (Category) /* { dg-warning "is deprecated" } */ |
@end |
|
@interface Subclass : DeprecatedClass /* { dg-warning "is deprecated" } */ |
@end |
|
DeprecatedClass *object; /* { dg-warning "is deprecated" } */ |
|
int function (DeprecatedClass *object) /* { dg-warning "is deprecated" } */ |
{ |
/* Note how the following deprecation warning is generated by |
"DeprecatedClass *", not by "[DeprecatedClass ...]. */ |
DeprecatedClass *x = [DeprecatedClass new]; /* { dg-warning "is deprecated" } */ |
|
if (x == object) |
return 0; |
else |
return 1; |
} |
|
id function2 (void) |
{ |
return DeprecatedClass.classObject; /* { dg-warning "is deprecated" } */ |
} |
|
@interface NormalClass |
{ |
Class isa; |
DeprecatedClass *object; /* { dg-warning "is deprecated" } */ |
} |
- (DeprecatedClass *)method; /* { dg-warning "is deprecated" } */ |
@end |
|
@implementation NormalClass |
- (DeprecatedClass *)method /* { dg-warning "is deprecated" } */ |
{ |
return nil; |
} |
@end |
/attributes/proto-attribute-3.mm
0,0 → 1,62
/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, November 2010. */ |
/* { dg-do compile } */ |
/* { dg-skip-if "No API#2 pre-Darwin9" { *-*-darwin[5-8]* } { "-fnext-runtime" } { "" } } */ |
|
|
/* Test deprecate attribute with normal @protocol declarations. */ |
|
|
#include <stdlib.h> |
#include <objc/objc.h> |
#include <objc/runtime.h> |
|
__attribute__ ((deprecated)) |
@protocol DeprecatedProtocol1 |
- (void) aMethod; |
@end |
|
@protocol NonDeprecatedProtocol1 |
- (void) anotherMethod; |
@end |
|
@protocol Protocol2 <DeprecatedProtocol1> /* { dg-warning "is deprecated" } */ |
- (void) someOtherMethod; |
@end |
|
@protocol Protocol3 <NonDeprecatedProtocol1> |
- (void) someOtherMethod2; |
@end |
|
@protocol Protocol4 <NonDeprecatedProtocol1, DeprecatedProtocol1> /* { dg-warning "is deprecated" } */ |
- (void) someOtherMethod3; |
@end |
|
|
@interface Class1 <DeprecatedProtocol1> /* { dg-warning "is deprecated" } */ |
@end |
|
@interface Class2 <NonDeprecatedProtocol1> |
@end |
|
@interface Class3 <NonDeprecatedProtocol1, DeprecatedProtocol1> /* { dg-warning "is deprecated" } */ |
@end |
|
@interface Class2 (Category1) <DeprecatedProtocol1> /* { dg-warning "is deprecated" } */ |
@end |
|
void function1 (id <DeprecatedProtocol1> object); /* { dg-warning "is deprecated" } */ |
void function2 (id <NonDeprecatedProtocol1> object); |
|
@class Class4; |
|
void function3 (Class4 <DeprecatedProtocol1> *object); /* { dg-warning "is deprecated" } */ |
void function4 (Class4 <NonDeprecatedProtocol1> *object); |
void function5 (Class4 <NonDeprecatedProtocol1, DeprecatedProtocol1> *object); /* { dg-warning "is deprecated" } */ |
|
int function6 (void) |
{ |
Protocol *p1 = @protocol (DeprecatedProtocol1); /* { dg-warning "is deprecated" } */ |
Protocol *p2 = @protocol (NonDeprecatedProtocol1); |
|
return (p1 == p2); |
} |
/attributes/method-format-1.mm
0,0 → 1,43
/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, October 2010. */ |
/* { dg-do compile } */ |
/* { dg-options "-Wall" } */ |
|
#include <objc/objc.h> |
#include <stdlib.h> |
|
@interface LogObject |
{ |
Class isa; |
} |
+ (void) log: (int)level message: (const char *) my_format, ... __attribute__ ((format (printf, 2, 3))); |
- (void) log: (int)level message: (const char *) my_format, ... __attribute__ ((format (printf, 2, 3))); |
|
+ (void) debug: (const char *) my_format, ... __attribute__ ((format (printf, 1, 2))); |
- (void) debug: (const char *) my_format, ... __attribute__ ((format (printf, 1, 2))); |
|
/* Just make sure a missing or invalid attribute won't crash the compiler. */ |
- (void) log2: (int)level message: (const char *) my_format, ... __attribute__ ((format (printf, 2))); /* { dg-error "wrong" } */ |
+ (void) debug2: (const char *) my_format, ... __attribute__ ((format (printf))); /* { dg-error "wrong" } */ |
- (void) debug2: (const char *) my_format, ... __attribute__ ((format (printf))); /* { dg-error "wrong" } */ |
+ (void) alert: (const char *) my_format __attribute__ ((format (printf, 1, 2))); /* { dg-error "args to be formatted is not ..." } */ |
- (void) alert: (const char *) my_format __attribute__ ((format (printf, 1, 2))); /* { dg-error "args to be formatted is not ..." } */ |
@end |
|
void test (LogObject *object) |
{ |
[object log: 2 message: "attribute only applies to variadic functions"]; |
[object log: 2 message: "attribute %s only applies to variadic functions", "'format'"]; |
[object log: 2 message: "attribute %s only applies to variadic functions"]; /* { dg-warning "expects a matching" } */ |
|
[object debug: "attribute only applies to variadic functions"]; |
[object debug: "attribute %s only applies to variadic functions", "'format'"]; |
[object debug: "attribute %s only applies to variadic functions"]; /* { dg-warning "expects a matching" } */ |
|
[LogObject log: 2 message: "attribute only applies to variadic functions"]; |
[LogObject log: 2 message: "attribute %s only applies to variadic functions", "'format'"]; |
[LogObject log: 2 message: "attribute %s only applies to variadic functions"]; /* { dg-warning "expects a matching" } */ |
|
[LogObject debug: "attribute only applies to variadic functions"]; |
[LogObject debug: "attribute %s only applies to variadic functions", "'format'"]; |
[LogObject debug: "attribute %s only applies to variadic functions"]; /* { dg-warning "expects a matching" } */ |
} |
/attributes/proto-attribute-4.mm
0,0 → 1,31
/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, December 2010. */ |
/* { dg-do compile } */ |
|
/* Test that you get a warning when an unknown protocol attribute is ignored. */ |
|
#include <objc/objc.h> |
|
__attribute__ ((unknown_attribute)) |
@protocol MyProtocol /* { dg-warning "ignored" } */ |
- (id) new; |
@end |
|
__attribute__ ((unknown_attribute)) |
@protocol MyProtocol2; /* { dg-warning "ignored" } */ |
|
/* Use the protocols to double-check that no more warnings are |
generated. */ |
|
@interface MyClass <MyProtocol> |
@end |
|
int test (id <MyProtocol2> x) |
{ |
if (@protocol (MyProtocol) == @protocol (MyProtocol2)) |
return 1; |
|
if (x) |
return 2; |
|
return 3; |
} |
/attributes/class-attribute-2.mm
0,0 → 1,21
/* { dg-do compile } */ |
|
#include <objc/objc.h> |
|
__attribute__ ((deprecated)) |
@interface DeprecatedClass |
{ |
Class isa; |
} |
+ (id) new; |
@end |
|
__attribute__ ((deprecated)) |
@implementation DeprecatedClass /* { dg-warning "prefix attributes are ignored" } */ |
+ (id) new { return nil; } |
@end |
|
void function (void) |
{ |
DeprecatedClass *object = [DeprecatedClass new]; /* { dg-warning "is deprecated" } */ |
} |
/attributes/class-attribute-3.mm
0,0 → 1,14
/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, December 2010. */ |
/* { dg-do compile } */ |
|
/* Test that you get a warning when an unknown class attribute is ignored. */ |
|
#include <objc/objc.h> |
|
__attribute__ ((unknown_attribute)) |
@interface MyClass /* { dg-warning "ignored" } */ |
{ |
Class isa; |
} |
+ (id) new; |
@end |
/try-catch-14.mm
0,0 → 1,24
/* { dg-options "-fobjc-exceptions" } */ |
/* { dg-do compile } */ |
|
typedef unsigned char uint8_t; |
typedef uint8_t foo[24]; |
|
void thingy(foo a) |
{ |
} |
|
int main() |
{ |
foo bar; |
|
@try { |
} |
@finally { |
} |
|
thingy(bar); |
|
return 0; |
} |
|
/template-8.mm
0,0 → 1,53
/* Test that all pending instantiations have taken place before meta-data |
generation. */ |
/* Author: Fariborz Jahanian <fjahanian@apple.com> */ |
/* Adapted by Nicola Pero <nicola.pero@meta-innovation.com> */ |
/* { dg-do run } */ |
/* { dg-skip-if "No API#2 pre-Darwin9" { *-*-darwin[5-8]* } { "-fnext-runtime" } { "" } } */ |
/* { dg-xfail-run-if "Needs OBJC2 ABI" { *-*-darwin* && { lp64 && { ! objc2 } } } { "-fnext-runtime" } { "" } } */ |
|
#include <objc/objc.h> |
#include <objc/runtime.h> |
|
@interface MyRootClass |
{ Class isa; } |
+ (id) initialize; |
+ alloc; |
- init; |
- doSomething; |
@end |
|
@implementation MyRootClass |
+ (id) initialize { return self; } |
+ alloc { return class_createInstance (self, 0); } |
- init { return self; } |
- doSomething { return self; } |
@end |
|
class Base |
{ |
public: |
Base() { } |
virtual ~Base() { } |
|
void destroy() { delete this; } |
}; |
|
template<class T> |
class Subclass : public T |
{ |
public: |
Subclass() { } |
|
virtual ~Subclass() |
{ |
[[[MyRootClass alloc] init] doSomething]; |
} |
}; |
|
int main(int argc, const char * argv[]) |
{ |
Subclass<Base>* theSubclass = new Subclass<Base>(); |
theSubclass->destroy(); |
return 0; |
} |
/selector-3.mm
0,0 → 1,29
/* Test warning for non-existent selectors. */ |
/* This is the "-fgnu-runtime" variant of objc.dg/selector-1.m. */ |
/* { dg-options "-Wselector -fgnu-runtime" } */ |
/* { dg-do compile } */ |
|
typedef struct objc_object { struct objc_class *class_pointer; } *id; |
typedef const struct objc_selector *SEL; |
|
@interface Foo |
- (void) foo; |
- (void) bar; |
@end |
|
@implementation Foo |
- (void) bar |
{ |
} |
|
- (void) foo |
{ |
SEL a,b,c; |
a = @selector(b1ar); |
b = @selector(bar); |
} |
@end |
|
/* FIXME: The error message should be on the correct line. */ |
/* { dg-warning "creating selector for nonexistent method .b1ar." "" { target *-*-* } 0 } */ |
|
/exceptions-3.mm
0,0 → 1,114
/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, November 2010. */ |
/* { dg-options "-fobjc-exceptions" } */ |
/* { dg-do compile } */ |
|
/* Test that the compiler is checking the argument of @catch(), and |
produce errors when invalid types are used. */ |
|
#include <objc/objc.h> |
|
@interface MyObject |
{ |
Class isa; |
} |
@end |
|
@implementation MyObject |
@end |
|
@protocol MyProtocol; |
|
typedef MyObject MyObjectTypedef; |
typedef MyObject *MyObjectPtrTypedef; |
typedef int intTypedef; |
|
int test (id object) |
{ |
int dummy = 0; |
|
@try { @throw object; } |
@catch (int x) /* { dg-error "@catch parameter is not a known Objective-C class type" } */ |
{ |
dummy++; |
} |
|
@try { @throw object; } |
@catch (intTypedef x) /* { dg-error "@catch parameter is not a known Objective-C class type" } */ |
{ |
dummy++; |
} |
|
@try { @throw object; } |
@catch (int *x) /* { dg-error "@catch parameter is not a known Objective-C class type" } */ |
{ |
dummy++; |
} |
|
@try { @throw object; } |
@catch (id x) /* Ok */ |
{ |
dummy++; |
} |
|
@try { @throw object; } |
@catch (id <MyProtocol> x) /* { dg-error "@catch parameter can not be protocol-qualified" } */ |
{ |
dummy++; |
} |
|
@try { @throw object; } |
@catch (MyObject *x) /* Ok */ |
{ |
dummy++; |
} |
|
@try { @throw object; } |
@catch (MyObject <MyProtocol> *x) /* { dg-error "@catch parameter can not be protocol-qualified" } */ |
{ |
dummy++; |
} |
|
@try { @throw object; } |
@catch (MyObject x) /* { dg-error "@catch parameter is not a known Objective-C class type" } */ |
{ /* { dg-error "no matching function" "" { target *-*-* } 72 } */ |
dummy++; /* { dg-message "MyObject" "" { target *-*-* } 13 } */ |
} /* { dg-message "candidate" "" { target *-*-* } 13 } */ |
/* { dg-message "candidates" "" { target *-*-* } 72 } */ |
@try { @throw object; } |
@catch (static MyObject *x) /* { dg-error "storage class" } */ |
{ |
dummy++; |
} |
|
@try { @throw object; } |
@catch (MyObjectTypedef *x) /* Ok */ |
{ |
dummy++; |
} |
|
@try { @throw object; } |
@catch (MyObjectTypedef <MyProtocol> *x) /* { dg-error "@catch parameter can not be protocol-qualified" } */ |
{ |
dummy++; |
} |
|
@try { @throw object; } |
@catch (MyObjectPtrTypedef x) /* Ok */ |
{ |
dummy++; |
} |
|
@try { @throw object; } |
@catch (Class x) /* { dg-error "@catch parameter is not a known Objective-C class type" } */ |
{ |
dummy++; |
} |
|
@try { @throw object; } |
@catch (...) /* Ok */ |
{ |
dummy++; |
} |
|
return dummy; |
} |
/strings/strings-1.mm
0,0 → 1,32
/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, November 2010. */ |
/* { dg-do compile } */ |
|
#include "../../objc-obj-c++-shared/runtime.h" |
#ifndef __NEXT_RUNTIME__ |
#include <objc/NXConstStr.h> |
#endif |
|
/* The following are correct. */ |
id test_valid1 = @"test"; |
id test_valid2 = @"te" @"st"; |
id test_valid3 = @"te" @"s" @"t"; |
id test_valid4 = @ "t" @ "e" @ "s" @ "t"; |
|
/* The following are accepted too; you can concat an ObjC string to a |
C string, the result being an ObjC string. */ |
id test_valid5 = @"te" "st"; |
id test_valid6 = @"te" "s" @"t"; |
id test_valid7 = @"te" @"s" "t"; |
|
/* The following are not correct. */ |
id test_invalid1 = @@"test"; /* { dg-error "stray .@. in program" } */ |
const char *test_invalid2 = "test"@; /* { dg-error "stray .@. in program" } */ |
const char *test_invalid3 = "test"@@; /* { dg-error "stray .@. in program" } */ |
const char *test_invalid4 = "te" @"st"; /* { dg-error "expected" } */ |
id test_invalid5 = @"te" @@"st"; /* { dg-error "repeated .@. before Objective-C string" } */ |
id test_invalid6 = @@"te" @"st"; /* { dg-error "stray .@. in program" } */ |
id test_invalid7 = @"te" @"s" @@"t"; /* { dg-error "repeated .@. before Objective-C string" } */ |
id test_invalid8 = @"te" @@"s" @"t"; /* { dg-error "repeated .@. before Objective-C string" } */ |
id test_invalid9 = @"te" @"s" @"t" @; /* { dg-error "stray .@. in program" } */ |
id test_invalidA = @"te" @ st; /* { dg-error "stray .@. in program" } */ |
/* { dg-error "expected" "" { target *-*-* } 31 } */ |
/strings/strings-2.mm
0,0 → 1,66
/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, November 2010. */ |
|
/* { dg-do run } */ |
/* { dg-xfail-run-if "Needs OBJC2 ABI" { *-*-darwin* && { lp64 && { ! objc2 } } } { "-fnext-runtime" } { "" } } */ |
/* { dg-options "-fconstant-string-class=MyTestString" } */ |
/* { dg-options "-mno-constant-cfstrings -fconstant-string-class=MyTestString" { target *-*-darwin* } } */ |
|
#include "../../objc-obj-c++-shared/objc-test-suite-types.h" |
|
#include <stdlib.h> /* For abort() */ |
|
@interface MyTestString |
{ |
void *dummy_class_ptr; |
char *string; |
unsigned int len; |
} |
+ initialize; |
/* All strings should contain the C string 'test'. Call -check to |
test that this is true. */ |
- (void) check; |
@end |
|
@implementation MyTestString |
+ initialize {return self;} |
- (void) check |
{ |
if (len != 4 || string[0] != 't' || string[1] != 'e' |
|| string[2] != 's' || string[3] != 't' || string[4] != '\0') |
abort (); |
} |
@end |
|
TNS_STRING_REF_T _MyTestStringClassReference; /* Only used by NeXT. */ |
|
int main (void) |
{ |
MyTestString *test_valid1 = @"test"; |
MyTestString *test_valid2 = @"te" @"st"; |
MyTestString *test_valid3 = @"te" @"s" @"t"; |
MyTestString *test_valid4 = @ "t" @ "e" @ "s" @ "t"; |
MyTestString *test_valid5 = @ "t" "e" "s" "t"; |
MyTestString *test_valid6 = @ "t" "e" "s" @ "t"; |
|
[test_valid1 check]; |
[test_valid2 check]; |
[test_valid3 check]; |
[test_valid4 check]; |
[test_valid5 check]; |
[test_valid6 check]; |
|
return 0; |
} |
|
#ifdef __NEXT_RUNTIME__ |
#include <string.h> |
/* The MyTestString metaclass will need to be initialized before we can |
send messages to strings. */ |
|
void testsuite_mytest_string_init (void) __attribute__((constructor)); |
void testsuite_mytest_string_init (void) { |
memcpy (&_MyTestStringClassReference, |
objc_getClass ("MyTestString"), |
sizeof (_MyTestStringClassReference)); |
} |
#endif |
/strings/const-str-1.mm
0,0 → 1,25
/* Test errors for constant strings. */ |
/* { dg-do compile } */ |
/* { dg-options "-mno-constant-cfstrings" { target *-*-darwin* } } */ |
|
#ifdef __cplusplus |
extern void baz(...); |
#endif |
|
void foo() |
{ |
baz(@"hiya"); /* { dg-error "annot find interface declaration" } */ |
} |
|
@interface NXConstantString |
{ |
void *isa; |
char *str; |
int len; |
} |
@end |
|
void bar() |
{ |
baz(@"howdah"); |
} |
/strings/const-str-2.mm
0,0 → 1,8
/* Test the -fconstant-string-class flag error. */ |
/* { dg-do compile } */ |
/* { dg-options "-fconstant-string-class=" } */ |
/* { dg-options "-mno-constant-cfstrings -fconstant-string-class=" { target *-*-darwin* } } */ |
|
{ dg-error "no class name specified|missing argument" "" { target *-*-* } 0 } |
|
void foo () {} |
/strings/strings.exp
0,0 → 1,45
# String tests that only need to run at default optimization. |
|
# Copyright (C) 2010 Free Software Foundation, Inc. |
# |
# This file is part of GCC. |
# |
# GCC is free software; you can redistribute it and/or modify |
# it under the terms of the GNU General Public License as published by |
# the Free Software Foundation; either version 3, or (at your option) |
# any later version. |
# |
# GCC is distributed in the hope that it will be useful, |
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
# GNU General Public License for more details. |
# |
# You should have received a copy of the GNU General Public License |
# along with GCC; see the file COPYING3. If not see |
# <http://www.gnu.org/licenses/>. |
|
# 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 |
/strings/const-str-12.mm
0,0 → 1,28
/* Test if ObjC types play nice in conditional expressions. */ |
/* Author: Ziemowit Laski */ |
|
/* { dg-do compile } */ |
/* { dg-options "-fconstant-string-class=Foo" } */ |
/* { dg-options "-mno-constant-cfstrings -fconstant-string-class=Foo" { target *-*-darwin* } } */ |
|
#include <objc/Object.h> |
#include "../../objc-obj-c++-shared/objc-test-suite-types.h" |
|
@interface Foo: Object { |
char *cString; |
unsigned int len; |
} |
+ (id)description; |
@end |
|
@interface Bar: Object |
+ (Foo *) getString: (int) which; |
@end |
|
TNS_STRING_REF_T _FooClassReference; /* Only used by NeXT. */ |
|
@implementation Bar |
+ (Foo *) getString: (int) which { |
return which? [Foo description]: @"Hello"; |
} |
@end |
/strings/const-str-5.mm
0,0 → 1,28
/* Positive test case for constant string layout. */ |
/* Contributed by Ziemowit Laski <zlaski@apple.com>. */ |
|
/* { dg-do compile } */ |
/* { dg-options "-fconstant-string-class=MyConstantString" } */ |
/* { dg-options "-mno-constant-cfstrings -fconstant-string-class=MyConstantString" { target *-*-darwin* } } */ |
|
@interface MyBase { |
const char *p; |
} |
@end |
|
@interface MyConstantString: MyBase { |
union equiv_u { |
void *u; |
unsigned char *c; |
} _contents; |
unsigned int _count; |
} |
@end |
|
/* The NeXT runtime initializes the 'isa' pointer of string constants at |
compile time. */ |
#ifdef __NEXT_RUNTIME__ |
extern void *_MyConstantStringClassReference; |
#endif |
|
MyConstantString *str = @"Hello"; |
/strings/const-str-6.mm
0,0 → 1,28
/* Negative test case for constant string layout. */ |
/* Contributed by Ziemowit Laski <zlaski@apple.com>. */ |
|
/* { dg-do compile } */ |
/* { dg-options "-fconstant-string-class=MyConstantString" } */ |
/* { dg-options "-mno-constant-cfstrings -fconstant-string-class=MyConstantString" { target *-*-darwin* } } */ |
|
@interface MyBase { |
char p; |
} |
@end |
|
@interface MyConstantString: MyBase { |
union equiv_u { |
void *u; |
unsigned char *c; |
} _contents; |
char _count; |
} |
@end |
|
/* The NeXT runtime initializes the 'isa' pointer of string constants at |
compile time. */ |
#ifdef __NEXT_RUNTIME__ |
extern void *_MyConstantStringClassReference; |
#endif |
|
MyConstantString *str = @"Hello"; /* { dg-error "interface .MyConstantString. does not have valid constant string layout" } */ |
/strings/const-cfstring-2.mm
0,0 → 1,27
/* Test the -Wnonportable-cfstrings option, which should give |
warnings if non-ASCII characters are embedded in constant |
CFStrings. This will only work on MacOS X 10.2 and later. */ |
/* Developed by Ziemowit Laski <zlaski@apple.com>. */ |
|
/* So far, CFString is darwin-only. */ |
/* { dg-do compile { target *-*-darwin* } } */ |
/* { dg-skip-if "NeXT only" { *-*-* } { "-fgnu-runtime" } { "" } } */ |
/* { dg-options "-mconstant-cfstrings -Wnonportable-cfstrings" } */ |
|
#import <Foundation/NSString.h> |
#import <CoreFoundation/CFString.h> |
|
#ifndef __CONSTANT_CFSTRINGS__ |
#error The -fconstant-cfstrings option is not functioning properly |
#endif |
|
void foo(void) { |
NSString *s1 = @"Compile-time string literal"; |
CFStringRef s2 = CFSTR("Compile-time string literal"); |
NSString *s3 = @"Non-ASCII literal - \222"; /* { dg-warning "non-ASCII character in CFString literal" } */ |
CFStringRef s4 = CFSTR("\222 - Non-ASCII literal"); /* { dg-warning "non-ASCII character in CFString literal" } */ |
CFStringRef s5 = CFSTR("Non-ASCII (\222) literal"); /* { dg-warning "non-ASCII character in CFString literal" } */ |
NSString *s6 = @"\0Embedded NUL"; /* { dg-warning "embedded NUL in CFString literal" } */ |
CFStringRef s7 = CFSTR("Embedded \0NUL"); /* { dg-warning "embedded NUL in CFString literal" } */ |
CFStringRef s8 = CFSTR("Embedded NUL\0"); /* { dg-warning "embedded NUL in CFString literal" } */ |
} |
/strings/const-cfstring-5.mm
0,0 → 1,26
/* Test if constant CFStrings may be passed back as ObjC strings. */ |
/* Author: Ziemowit Laski */ |
|
/* So far, CFString is darwin-only. */ |
/* { dg-do compile { target *-*-darwin* } } */ |
/* { dg-skip-if "NeXT only" { *-*-* } { "-fgnu-runtime" } { "" } } */ |
/* { dg-options "-mconstant-cfstrings" } */ |
|
#include <objc/Object.h> |
|
@interface Foo: Object { |
char *cString; |
unsigned int len; |
} |
+ (Foo *)description; |
@end |
|
@interface Bar: Object |
+ (Foo *) getString: (int) which; |
@end |
|
@implementation Bar |
+ (Foo *) getString: (int) which { |
return which? [Foo description]: @"Hello"; |
} |
@end |
/syntax-error-8.mm
0,0 → 1,26
@interface A /* { dg-error "expected ..end." } */ |
/cxx-ivars-1.mm
0,0 → 1,43
// Check if ivars may be accessed via the C++ dot notation. |
// { dg-do run } |
// { dg-options "-fno-objc-call-cxx-cdtors" } |
// { dg-xfail-run-if "Needs OBJC2 ABI" { *-*-darwin* && { lp64 && { ! objc2 } } } { "-fnext-runtime" } { "" } } |
|
#include "../objc-obj-c++-shared/TestsuiteObject.m" |
#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 : TestsuiteObject { |
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]; |
} |
|
/extern-c-1.mm
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 |
/stubify-2.mm
0,0 → 1,33
/* All calls must be properly stubified. */ |
/* Testcase extracted from TextEdit:Document.m. */ |
|
/* { dg-do compile { target *-*-darwin* } } */ |
/* { dg-skip-if "" { *-*-* } { "-fgnu-runtime" } { "" } } */ |
/* { dg-require-effective-target ilp32 } */ |
/* { dg-options "-mdynamic-no-pic -fdump-rtl-jump -mmacosx-version-min=10.4" } */ |
|
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-rtl-dump-not "symbol_ref.*\"objc_msgSend\"" "jump" } } */ |
/method-9.mm
0,0 → 1,33
/* Test for lookup of class (factory) methods. */ |
/* Author: Ziemowit Laski <zlaski@apple.com>. */ |
/* { dg-do compile } */ |
|
@interface MyBase |
- (void) rootInstanceMethod; |
@end |
|
@interface MyIntermediate: MyBase |
@end |
|
@interface MyDerived: MyIntermediate |
- (void) instanceMethod; |
+ (void) classMethod; |
@end |
|
@implementation MyDerived |
- (void) instanceMethod { |
} |
|
+ (void) classMethod { /* If a class method is not found, the root */ |
[self rootInstanceMethod]; /* class is searched for an instance method */ |
[MyIntermediate rootInstanceMethod]; /* with the same name. */ |
|
[self instanceMethod]; /* { dg-warning ".MyDerived. may not respond to .\\+instanceMethod." } */ |
[MyDerived instanceMethod]; /* { dg-warning ".MyDerived. may not respond to .\\+instanceMethod." } */ |
} |
@end |
|
/* { 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 } */ |
|
/proto-error-1.mm
0,0 → 1,4
// PR obj-c++/28434 |
// { dg-do compile } |
|
Class<> c; // { dg-error "identifier" } |
/syntax-error-10.mm
0,0 → 1,4
@interface /* { dg-error "expected identifier" } */ |
/proto-lossage-1.mm
0,0 → 1,44
/* Test for situations in which protocol conformance information |
may be lost, leading to superfluous warnings. */ |
/* Author: Ziemowit Laski <zlaski@apple.com>. */ |
/* { dg-do compile } */ |
|
/* One-line substitute for objc/objc.h */ |
typedef struct objc_object { struct objc_class *class_pointer; } *id; |
|
@protocol NSObject |
- (int)someValue; |
@end |
|
@interface NSObject <NSObject> |
@end |
|
@protocol PlateMethods |
- (void)someMethod; |
@end |
|
@interface Foo { |
NSObject <PlateMethods> *plate; |
id <PlateMethods> plate1; |
NSObject *plate2; |
} |
- (id <PlateMethods>) getPlate; |
- (id <NSObject>) getPlate1; |
- (int) getValue; |
@end |
|
@implementation Foo |
- (id <PlateMethods>) getPlate { |
return plate; /* { dg-bogus "does not implement" } */ |
} |
- (id <NSObject>) getPlate1 { |
return (id <NSObject>)plate1; /* { dg-bogus "does not conform" } */ |
} |
- (int) getValue { |
int i = [plate1 someValue]; /* { dg-warning ".\\-someValue. not found in protocol\\(s\\)" } */ |
|
int j = [(id <NSObject>)plate1 someValue]; /* { dg-bogus "not found in protocol" } */ |
int k = [(id)plate1 someValue]; /* { dg-bogus "not found in protocol" } */ |
return i + j + k; |
} |
@end |
/try-catch-2.mm
0,0 → 1,81
/* Test out '@catch(id foo) {...}', which should catch |
all uncaught exceptions. */ |
/* Developed by Ziemowit Laski <zlaski@apple.com>. */ |
|
/* { dg-do run } */ |
/* { dg-xfail-run-if "PR23616" { *-*-* } { "-fgnu-runtime" } { "-fnext-runtime" } } */ |
/* { dg-xfail-if "Needs OBJC2 ABI" { *-*-darwin* && { lp64 && { ! objc2 } } } { "-fnext-runtime" "-fgnu-runtime" } { "" } } */ |
/* { dg-options "-fobjc-exceptions" } */ |
|
#include "../objc-obj-c++-shared/TestsuiteObject.m" |
#include <stdio.h> |
#include <stdlib.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> |
|
#define CHECK_IF(expr) if(!(expr)) abort() |
|
@interface Frob: TestsuiteObject |
@end |
|
@implementation Frob: TestsuiteObject |
@end |
|
static Frob* _connection = nil; |
|
//-------------------------------------------------------------------- |
|
|
void test (TestsuiteObject* 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 [TestsuiteObject 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((TestsuiteObject *)-1); |
return 0; |
} |
|
/threedotthree-abi-1.mm
0,0 → 1,76
/* This file tests that things are encoded using the gcc-3.3 ABI which is only |
used by the NeXT runtime. */ |
/* { dg-do run { target *-*-darwin* } } */ |
/* { dg-require-effective-target ilp32 } */ |
/* { dg-skip-if "" { *-*-* } { "-fgnu-runtime" } { "" } } */ |
|
#include <stdio.h> |
#include <string.h> |
#include "../objc-obj-c++-shared/runtime.h" |
|
extern "C" void abort(); |
|
@protocol CommonProtocol |
|
-(oneway void)methodCall_On:(in bycopy id)someValue_On; |
-(oneway void)methodCall_nO:(bycopy in id)someValue_nO; |
|
-(oneway void)methodCall_Oo:(out bycopy id)someValue_Oo; |
-(oneway void)methodCall_oO:(bycopy out id)someValue_oO; |
|
-(oneway void)methodCall_rn:(in const id)someValue_rn; |
|
-(oneway void)methodCall_oOn:(in bycopy out id)someValue_oOn; |
|
@end |
|
@interface ObjCClass <CommonProtocol> |
{ |
|
} |
|
@end |
|
@implementation ObjCClass |
-(oneway void)methodCall_On:(in bycopy id)someValue_On { } |
-(oneway void)methodCall_nO:(bycopy in id)someValue_nO { } |
|
-(oneway void)methodCall_Oo:(out bycopy id)someValue_Oo { } |
-(oneway void)methodCall_oO:(bycopy out id)someValue_oO { } |
|
-(oneway void)methodCall_rn:(in const id)someValue_rn { } |
-(oneway void)methodCall_oOn:(in bycopy out id)someValue_oOn { } |
@end |
|
Protocol *proto = @protocol(CommonProtocol); |
struct objc_method_description *meth; |
struct objc_method_description meth_object; |
|
int main() |
{ |
meth_object = protocol_getMethodDescription (proto, @selector(methodCall_On:), YES, YES); |
meth = &meth_object; |
if (strcmp (meth->types, "Vv12@0:4On@8")) |
abort(); |
meth_object = protocol_getMethodDescription (proto, @selector(methodCall_nO:), YES, YES); |
meth = &meth_object; |
if (strcmp (meth->types, "Vv12@0:4nO@8")) |
abort(); |
meth_object = protocol_getMethodDescription (proto, @selector(methodCall_Oo:), YES, YES); |
meth = &meth_object; |
if (strcmp (meth->types, "Vv12@0:4Oo@8")) |
abort(); |
meth_object = protocol_getMethodDescription (proto, @selector(methodCall_oO:), YES, YES); |
meth = &meth_object; |
if (strcmp (meth->types, "Vv12@0:4oO@8")) |
abort(); |
meth_object = protocol_getMethodDescription (proto, @selector(methodCall_rn:), YES, YES); |
meth = &meth_object; |
if (strcmp (meth->types, "Vv12@0:4rn@8")) |
abort(); |
meth_object = protocol_getMethodDescription (proto, @selector(methodCall_oOn:), YES, YES); |
meth = &meth_object; |
if (strcmp (meth->types, "Vv12@0:4oOn@8")) |
abort(); |
return 0; |
} |
/method-10.mm
0,0 → 1,46
/* Test for sending messages to aliased classes (and instances thereof). */ |
/* Author: Ziemowit Laski <zlaski@apple.com>. */ |
/* { dg-options "" } */ |
/* { dg-do run } */ |
/* { dg-xfail-run-if "Needs OBJC2 ABI" { *-*-darwin* && { lp64 && { ! objc2 } } } { "-fnext-runtime" } { "" } } */ |
#include "../objc-obj-c++-shared/TestsuiteObject.m" |
#include <stdlib.h> |
|
#define CHECK_IF(expr) if(!(expr)) abort() |
|
@interface Int1: TestsuiteObject |
+ (int) classMeth; |
- (int) instanceMeth; |
@end |
|
@interface Int2: TestsuiteObject |
+ (int) classMeth; |
- (int) instanceMeth; |
@end |
|
@implementation Int1 |
+ (int) classMeth { return 345; } |
- (int) instanceMeth { return 697; } |
@end |
|
@implementation Int2 |
+ (int) classMeth { return 1345; } |
- (int) instanceMeth { return 1697; } |
@end |
|
typedef Int1 Int1Typedef; |
@compatibility_alias Int1Alias Int1Typedef; |
@compatibility_alias Int2Alias Int2; |
typedef Int2Alias Int2Typedef; |
|
int main(void) { |
Int1Alias *int1alias = [[Int1Typedef alloc] init]; |
Int2Typedef *int2typedef = [[Int2Alias alloc] init]; |
|
CHECK_IF([Int1Typedef classMeth] == 345 && [Int2Alias classMeth] == 1345); |
CHECK_IF([int1alias instanceMeth] == 697 && [int2typedef instanceMeth] == 1697); |
CHECK_IF([(Int2Typedef *)int1alias instanceMeth] == 697); |
CHECK_IF([(Int1Alias *)int2typedef instanceMeth] == 1697); |
return 0; |
} |
|
/encode-5.mm
0,0 → 1,96
/* Method encoding tests for stand-alone @protocol declarations. */ |
/* Contributed by Ziemowit Laski <zlaski@apple.com>. */ |
/* { dg-do run } */ |
/* { dg-xfail-run-if "Needs OBJC2 ABI" { *-*-darwin* && { lp64 && { ! objc2 } } } { "-fnext-runtime" } { "" } } */ |
|
#include <stdio.h> |
#include <stdlib.h> |
|
#include "../objc-obj-c++-shared/runtime.h" |
#include <objc/Protocol.h> |
|
#ifdef __cplusplus |
#define ProtoBool bool |
#else |
#define ProtoBool _Bool |
#endif |
|
#define CHECK_IF(expr) if(!(expr)) abort() |
|
enum Enum { |
zero, one, two, three |
}; |
typedef enum Enum Enum; |
typedef signed char ObjCBool; /* as used by the NeXT runtime */ |
|
@protocol Proto |
union __XXAngle { unsigned int alpha, beta; }; |
typedef struct { float x, y; union __XXAngle a; } XXPoint; |
typedef struct { double width, height; } XXSize; |
typedef struct _XXRect { XXPoint origin; XXSize size; struct _XXRect *next; } XXRect; |
- (void) char:(signed char)c float:(float)f double:(double)d unsigned:(unsigned)u short:(short)s long:(long)l; |
- (void *)setRect:(XXRect)r withBool:(ProtoBool)b withInt:(int)i; |
+ (Enum *)getEnum:(XXPoint *)pt enum:(enum Enum)e bool:(ObjCBool)b; |
+ (ProtoBool **)getBool:(ObjCBool **)b; |
@end |
|
Protocol *proto = @protocol(Proto); |
struct objc_method_description *meth; |
struct objc_method_description meth_object; |
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 == sizeof(id) && offs2 == offs1 + sizeof(SEL) && totsize >= offs2); |
} |
|
int main(void) { |
const char *string; |
|
meth_object = protocol_getMethodDescription (proto, |
@selector(char:float:double:unsigned:short:long:), YES, YES); |
meth = &meth_object; |
if (sizeof (long) == 8) |
string = "v%u@%u:%uc%uf%ud%uI%us%uq%u"; |
else |
string = "v%u@%u:%uc%uf%ud%uI%us%ul%u"; |
scan_initial(string); |
CHECK_IF(offs3 == offs2 + sizeof(int) && offs4 == offs3 + sizeof(float)); |
CHECK_IF(offs5 == offs4 + sizeof(double) && offs6 == offs5 + sizeof(unsigned)); |
CHECK_IF(offs7 == offs6 + sizeof(int) && totsize == offs7 + sizeof(long)); |
meth_object = protocol_getMethodDescription (proto, |
@selector(setRect:withBool:withInt:), YES, YES); |
meth = &meth_object; |
scan_initial("^v%u@%u:%u{_XXRect={?=ff(__XXAngle=II)}{?=dd}^{_XXRect}}%uB%ui%u"); |
CHECK_IF(offs3 == offs2 + sizeof(XXRect) && offs4 == offs3 + sizeof(int)); |
CHECK_IF(totsize == offs4 + sizeof(int)); |
meth_object = protocol_getMethodDescription (proto, |
@selector(getEnum:enum:bool:), YES, NO); |
meth = &meth_object; |
|
/* Here we have the complication that 'enum Enum' could be encoded |
as 'i' on __NEXT_RUNTIME_, and (most likely) as 'I' on the GNU |
runtime. So we get the @encode(enum Enum), then put it into the |
string in place of the traditional 'i'. |
*/ |
/* scan_initial("^i%u@%u:%u^{?=ff(__XXAngle=II)}%ui%uc%u"); */ |
{ |
char pattern[1024]; |
|
sprintf (pattern, "^%s%%u@%%u:%%u^{?=ff(__XXAngle=II)}%%u%s%%uc%%u", |
@encode(enum Enum), @encode(enum Enum)); |
scan_initial(pattern); |
} |
|
CHECK_IF(offs3 == offs2 + sizeof(XXPoint *) && offs4 == offs3 + sizeof(enum Enum)); |
CHECK_IF(totsize == offs4 + sizeof(int)); /* 'ObjCBool' is really 'char' */ |
meth_object = protocol_getMethodDescription (proto, |
@selector(getBool:), YES, NO); |
meth = &meth_object; |
scan_initial("^^B%u@%u:%u^*%u"); |
CHECK_IF(totsize == offs2 + sizeof(ObjCBool **)); |
return 0; |
} |
|
/va-meth-1.mm
0,0 → 1,75
/* Based on objc/execute/va_method.m, by Nicola Pero */ |
|
/* { dg-do run } */ |
/* { dg-xfail-run-if "Needs OBJC2 ABI" { *-*-darwin* && { lp64 && { ! objc2 } } } { "-fnext-runtime" } { "" } } */ |
#include "../objc-obj-c++-shared/TestsuiteObject.m" |
#include <stdarg.h> |
#include <stdlib.h> |
|
/* Test methods with "C-style" trailing arguments, with or without ellipsis. */ |
|
@interface MathClass: TestsuiteObject |
/* 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; |
} |
|
/ivar-invalid-type-1.mm
0,0 → 1,19
/* { dg-do compile } */ |
#include <objc/objc.h> |
|
@interface MyRootClass |
{ |
Class isa; |
} |
@end |
|
@interface MySubClass |
{ |
volatile int a; /* This is allowed */ |
extern int b; /* { dg-error "invalid type" } */ |
static int c; /* { dg-error "invalid type" } */ |
inline int d; /* { dg-error "declared as an .inline." } */ |
typedef int e; /* { dg-error "invalid type" } */ |
__thread int f; /* { dg-error "invalid type" } */ |
} |
@end |
/invalid-type-1.mm
0,0 → 1,25
/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, November 2010. */ |
/* { dg-do compile } */ |
#include <objc/objc.h> |
|
typedef int Integer; |
|
@class MyClass; |
|
typedef MyClass AClass; |
|
@protocol MyProtocol |
- (void) method; |
@end |
|
Class <MyProtocol> class_object; /* This is fine. */ |
|
id <MyProtocol> object; /* This is fine. */ |
|
AClass <MyProtocol> *object1; /* This is fine. */ |
|
Integer <MyProtocol> *object2; /* { dg-error ".Integer {aka int}. is not a template" } */ |
/* { dg-error ".MyProtocol. was not declared in this scope" "" { target *-*-* } 21 } */ |
|
Integer <NonExistingProtocol> *object3; /* { dg-error ".Integer {aka int}. is not a template" } */ |
/* { dg-error ".NonExistingProtocol. was not declared in this scope" "" { target *-*-* } 24 } */ |
/objc-gc-3.mm
0,0 → 1,65
/* Test looking up fields in superclasses in the context of write-barriers |
(where component references get rewritten). */ |
/* Contributed by Ziemowit Laski <zlaski@apple.com> */ |
|
/* { dg-do compile } */ |
/* { dg-options "-fobjc-gc" } */ |
/* { dg-prune-output "cc1objplus: warning: '-fobjc-gc' is ignored for '-fgnu-runtime'" } */ |
|
#include "../objc-obj-c++-shared/TestsuiteObject.h" |
#include "../objc-obj-c++-shared/runtime.h" |
|
@class MyWindow; |
|
@interface MyDocument : TestsuiteObject { |
MyWindow *_window; |
} |
@end |
|
@interface MyFileDocument : MyDocument { |
struct { |
unsigned int autoClose:1; |
unsigned int openForUI:1; |
unsigned int isClosing:1; |
unsigned int needsDiskCheck:1; |
unsigned int isWritable:1; |
unsigned int representsFileOnDisk:1; |
unsigned int RESERVED:26; |
} _fdFlags; |
} |
@end |
|
@interface MyTextFileDocument : MyFileDocument { |
TestsuiteObject *_textStorage; |
struct __tfdFlags { |
unsigned int immutable:1; |
unsigned int lineEnding:2; |
unsigned int isClosing:1; |
unsigned int settingsAreSet:1; |
unsigned int usesTabs:1; |
unsigned int isUTF8WithBOM:1; |
unsigned int wrapsLines:1; |
unsigned int usingDefaultLanguage:1; |
unsigned int RESERVED:23; |
} _tfdFlags; |
int _tabWidth; |
int _indentWidth; |
} |
@end |
|
@interface MyRTFFileDocument : MyTextFileDocument |
- (BOOL)readFromFile:(const char *)fileName ofType:(const char *)type; |
@end |
|
@implementation MyRTFFileDocument |
- (BOOL)readFromFile:(const char *)fileName ofType:(const char *)type { |
if (_textStorage && fileName) { |
[_textStorage free]; |
return YES; |
} else if (type) { |
_textStorage = [MyRTFFileDocument new]; |
return NO; |
} |
return (fileName && type); |
} |
@end |
/comp-types-8.mm
0,0 → 1,33
/* { dg-do compile } */ |
|
/* We used to ICE because we removed the cast to List_linked* |
in -[ListIndex_linked next]. */ |
|
@interface List |
{ |
@public |
int firstLink; |
} |
@end |
|
@interface ListIndex_linked |
{ |
@public |
List *collection; |
int link; |
} |
@end |
|
@interface List_linked: List |
@end |
|
@implementation List |
@end |
|
@implementation ListIndex_linked |
- next |
{ |
link = ((List_linked*)collection)->firstLink; |
} |
@end |
|
/pragma-1.mm
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 |
/method-18.mm
0,0 → 1,25
/* Contributed by Igor Seleznev <selez@mail.ru>. */ |
/* This used to be broken. */ |
|
#include <objc/objc.h> |
|
@interface A |
+ (A *)currentContext; |
@end |
|
@interface B |
+ (B *)currentContext; |
@end |
|
int main() |
{ |
[A currentContext]; /* { dg-bogus "multiple declarations" } */ |
return 0; |
} |
|
@implementation A |
+ (A *)currentContext { return nil; } |
@end |
@implementation B |
+ (B *)currentContext { return nil; } |
@end |
/fix-and-continue-2.mm
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-obj-c++-shared/TestsuiteObject.h" |
|
@interface Foo: TestsuiteObject |
+ (TestsuiteObject *)indexableFileTypes; |
@end |
|
@implementation Foo |
+ (TestsuiteObject *)indexableFileTypes |
{ |
static TestsuiteObject *fileTypes = 0; |
if(!fileTypes) { |
fileTypes = [TestsuiteObject new]; |
} |
return fileTypes; |
} |
@end |
/lookup-2.mm
0,0 → 1,58
/* { dg-do run } */ |
/* { dg-xfail-run-if "Needs OBJC2 ABI" { *-*-darwin* && { lp64 && { ! objc2 } } } { "-fnext-runtime" } { "" } } */ |
#include "../objc-obj-c++-shared/TestsuiteObject.m" |
#include <stdlib.h> |
|
class MyWidget { |
public: |
int a; |
MyWidget(void) { a = 17; } |
}; |
|
MyWidget gWidget; |
|
@protocol MyProto |
- (MyWidget *)widget; |
@end |
|
@interface Foo: TestsuiteObject |
@end |
|
@interface Bar: Foo <MyProto> |
@end |
|
@interface Container: TestsuiteObject |
+ (MyWidget *)elementForView:(Foo *)view; |
@end |
|
@implementation Foo |
@end |
|
@implementation Bar |
- (MyWidget *)widget { |
return &gWidget; |
} |
@end |
|
@implementation Container |
+ (MyWidget *)elementForView:(Foo *)view |
{ |
MyWidget *widget = 0; |
if (class_conformsToProtocol (object_getClass (view), |
@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; |
} |
|
/gnu-runtime-1.mm
0,0 → 1,19
/* Test that compiling for the GNU runtime works (regardless of |
the system runtime used). */ |
/* Author: Ziemowit Laski <zlaski@apple.com> */ |
/* { dg-do compile } */ |
/* { dg-skip-if "" { *-*-* } { "-fnext-runtime" } { "" } } */ |
|
#include "../objc-obj-c++-shared/TestsuiteObject.h" |
|
@interface FooBar: TestsuiteObject |
- (void)boo; |
@end |
|
int main () |
{ |
id fooBarInst = [[FooBar alloc] init]; |
[fooBarInst boo]; |
return 0; |
} |
|
/naming-2.mm
0,0 → 1,41
/* Testing for detecting duplicate ivars. */ |
/* { dg-do compile } */ |
|
typedef struct S { int i; } NSDictionary; |
|
@interface A |
{ |
NSDictionary * _userInfo; /* { dg-message "previous declaration" } */ |
int i1; |
int i2; |
int i3; |
int i4; |
int i5; |
int i6; |
int i7; |
NSDictionary * _userInfo1; /* { dg-message "previous declaration" } */ |
} |
@end |
|
@interface B : A |
{ |
NSDictionary * _userInfo1; /* { dg-error "duplicate instance variable" } */ |
int ii1; |
int ii2; |
int ii3; |
int ii4; |
int ii5; |
int ii6; |
int ii7; |
} |
@end |
|
@interface C : A |
@end |
|
@interface D : C |
{ |
NSDictionary * _userInfo; /* { dg-error "duplicate instance variable" } */ |
} |
@end |
|
/gnu-api-2-objc_msg_lookup.mm
0,0 → 1,77
/* Test the Modern GNU Objective-C Runtime API. |
|
This is test 'objc_msg_lookup', covering objc_msg_lookup(), |
objc_msg_lookup_super() and struct objc_super. */ |
|
/* { dg-do run } */ |
/* { dg-skip-if "" { *-*-* } { "-fnext-runtime" } { "" } } */ |
|
/* To get the modern GNU Objective-C Runtime API, you include |
objc/runtime.h. */ |
#include <objc/runtime.h> |
|
/* For objc_msg_lookup(), objc_msg_lookup_super() and struct |
objc_super. */ |
#include <objc/message.h> |
|
#include <stdlib.h> |
#include <iostream> |
#include <cstring> |
|
@interface MyRootClass |
{ Class isa; } |
+ alloc; |
- init; |
- (int) test; |
@end |
|
@implementation MyRootClass |
+ alloc { return class_createInstance (self, 0); } |
- init { return self; } |
- (int) test { return 20; } |
@end |
|
@interface MySubClass : MyRootClass |
- (int) test; |
@end |
|
@implementation MySubClass |
- (int) test { return 11; } |
@end |
|
int main () |
{ |
/* Functions are tested in alphabetical order. */ |
|
std::cout << "Testing objc_msg_lookup () ...\n"; |
{ |
MySubClass *object = [[MySubClass alloc] init]; |
int (* test_IMP) (id receiver, SEL selector); |
|
test_IMP = (int (*)(id, SEL))objc_msg_lookup (object, @selector (test)); |
|
if (test_IMP (object, @selector (test)) != 11) |
abort (); |
} |
|
std::cout << "Testing objc_msg_lookup_super () ...\n"; |
{ |
MySubClass *object = [[MySubClass alloc] init]; |
struct objc_super super = { 0, 0 }; |
int (* test_IMP) (id receiver, SEL selector); |
|
/* Get the implementation of -test for the superclass of object - |
as if we were calling [super test] inside a method |
implementation of object. */ |
super.self = object; |
super.super_class = class_getSuperclass (object_getClass (object)); |
test_IMP = (int (*)(id, SEL))objc_msg_lookup_super (&super, @selector (test)); |
|
/* Invoke it. The method in MyRootClass, not the one in |
MySubClass, should be invoked. */ |
if (test_IMP (object, @selector (test)) != 20) |
abort (); |
} |
|
return (0); |
} |
/template-3.mm
0,0 → 1,81
/* Test for passing arguments to ObjC methods in the context of template |
expansion. */ |
/* Contributed by Ziemowit Laski <zlaski@apple.com>. */ |
|
/* { dg-do run } */ |
/* { dg-xfail-run-if "Needs OBJC2 ABI" { *-*-darwin* && { lp64 && { ! objc2 } } } { "-fnext-runtime" } { "" } } */ |
#include "../objc-obj-c++-shared/TestsuiteObject.m" |
#include <stdlib.h> |
|
#define CHECK_IF(expr) if(!(expr)) abort() |
|
@interface ObjCClass : TestsuiteObject |
{ |
@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; |
} |
|
/class-extension-1.mm
0,0 → 1,30
/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, December 2010. */ |
/* { dg-do compile } */ |
|
/* This test tests the basic of class extensions. */ |
|
#include <objc/objc.h> |
|
@interface MyObject |
{ |
Class isa; |
} |
- (int) test; |
@end |
|
@interface MyObject () |
- (int) test2; |
- (int) test3; |
@end |
|
@implementation MyObject |
- (int) test |
{ |
return 20; |
} |
- (int) test2 |
{ |
return 20; |
} |
@end /* { dg-warning "incomplete implementation of class .MyObject." } */ |
/* { dg-warning "method definition for .-test3. not found" "" { target *-*-* } 29 } */ |
/syntax-error-3.mm
0,0 → 1,10
/* Yet another stray infinite loop... */ |
/* { dg-do compile } */ |
|
@interface Foo |
{ |
int x; |
int y; |
} |
- (int) foo ; { /* { dg-error "stray .\{. between Objective\\-C\\+\\+ methods" } */ |
@end |
/method-conflict-2.mm
0,0 → 1,34
/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, December 2010. */ |
/* { dg-do compile } */ |
|
#include <objc/objc.h> |
|
/* Test that you can not declare two methods, in the same protocol, |
with the same name and method signature, but one as @required and |
once as @optional. */ |
|
/* First, @required conflicting with @optional. */ |
@protocol MyProtocol |
|
@optional |
+ (void) method1: (id)x; /* { dg-message "previous declaration" } */ |
- (id) method2: (long)x; /* { dg-message "previous declaration" } */ |
|
@required |
+ (void) method1: (id)x; /* { dg-error "declared .@optional. and .@required. at the same time" } */ |
- (id) method2: (long)x; /* { dg-error "declared .@optional. and .@required. at the same time" } */ |
|
@end |
|
/* Second, @optional conflicting with @required. */ |
@protocol MyProtocol2 |
|
@required |
+ (void) method3: (Class)x; /* { dg-message "previous declaration" } */ |
- (id *) method4: (long)x; /* { dg-message "previous declaration" } */ |
|
@optional |
+ (void) method3: (Class)x; /* { dg-error "declared .@optional. and .@required. at the same time" } */ |
- (id *) method4: (long)x; /* { dg-error "declared .@optional. and .@required. at the same time" } */ |
|
@end |
/bitfield-1.mm
0,0 → 1,124
/* Check if ObjC class layout follows the ABI (informally) |
set in the past. ObjC structs must be laid out as if |
all ivars, including those inherited from superclasses, |
were defined at once (i.e., any padding introduced for |
superclasses should be removed). */ |
/* Contributed by Ziemowit Laski <zlaski@apple.com>. */ |
/* { dg-do run } */ |
/* { dg-options "-Wpadded -Wabi" } */ |
|
/* Leave blank lines here to keep warnings on the same lines. */ |
|
#include "../objc-obj-c++-shared/TestsuiteObject.m" |
#include <objc/objc.h> |
#include <stdlib.h> |
|
#define CHECK_IF(expr) if(!(expr)) abort() |
|
enum Enum { zero, one, two, three, four }; |
|
@interface Base: TestsuiteObject { |
@public |
unsigned a: 2; |
int b: 3; |
enum Enum c: 4; |
unsigned d: 5; |
} /* { dg-warning "padding struct size to alignment boundary" } */ |
@end |
|
struct Base_0 { /* { dg-warning "padding struct size to alignment boundary" } */ |
Class isa; |
unsigned a: 2; |
int b: 3; |
enum Enum c: 4; |
unsigned d: 5; |
}; |
|
@interface Derived: Base { |
@public |
signed e: 5; |
unsigned f: 4; |
enum Enum g: 3; |
} |
@end |
|
struct Derived_0 { |
Class isa; |
unsigned a: 2; |
int b: 3; |
enum Enum c: 4; |
unsigned d: 5; |
signed e: 5; |
int f: 4; |
enum Enum g: 3; |
}; |
|
@interface Leaf: Derived { |
@public |
signed h: 2; |
} |
@end |
|
struct Leaf_0 { |
Class isa; |
unsigned a: 2; |
int b: 3; |
enum Enum c: 4; |
unsigned d: 5; |
signed e: 5; |
unsigned f: 4; |
enum Enum g: 3; |
signed h: 2; |
}; |
|
/* Note that the semicolon after @defs(...) is optional. */ |
|
typedef struct { @defs(Base) } Base_t; /* { dg-warning "padding struct size to alignment boundary" } */ |
typedef struct { @defs(Derived); } Derived_t; |
typedef struct { @defs(Leaf); } Leaf_t; |
|
int main(void) |
{ |
struct Leaf_0 l_0; |
Leaf *l = (Leaf *)&l_0; |
Leaf_t *l_t = (Leaf_t *)&l_0; |
|
CHECK_IF(sizeof(Base_t) == sizeof(Base)); |
CHECK_IF(sizeof(Derived_t) == sizeof(Derived)); |
CHECK_IF(sizeof(Leaf_t) == sizeof(Leaf)); |
|
CHECK_IF(sizeof(struct Base_0) == sizeof(Base)); |
CHECK_IF(sizeof(struct Derived_0) == sizeof(Derived)); |
CHECK_IF(sizeof(struct Leaf_0) == sizeof(Leaf)); |
|
l_0.isa = (Class)0; |
l_0.a = 3; |
l_0.b = 0; |
l_0.c = three; |
l_0.d = 31; |
l_0.e = 0; |
l_0.f = 15; |
l_0.g = zero; |
l_0.h = -2; |
|
CHECK_IF(!l_t->isa); |
CHECK_IF(l->a == 3 && l_t->a == 3); |
CHECK_IF(!l->b && !l_t->b); |
CHECK_IF(l->c == three && l_t->c == three); |
CHECK_IF(l->d == 31 && l_t->d == 31); |
CHECK_IF(!l->e && !l_t->e); |
CHECK_IF(l->f == 15 && l_t->f == 15); |
CHECK_IF(l->g == zero && l_t->g == zero); |
CHECK_IF(l->h == -2 && l_t->h == -2); |
|
return 0; |
} |
|
/* { dg-prune-output "In file included from" } Ignore this message. */ |
/* { dg-bogus "padding struct to align" "PR23610" { target *-*-* } 0 } */ |
/* { dg-bogus "padding struct size" "PR23610" { xfail lp64 } 42 } */ |
/* { dg-bogus "padding struct size" "PR23610" { xfail lp64 } 45 } */ |
/* { dg-bogus "padding struct size" "PR23610" { xfail lp64 } 59 } */ |
/* { dg-bogus "padding struct size" "PR23610" { xfail lp64 } 62 } */ |
/* { dg-bogus "padding struct size" "PR23610" { xfail lp64 } 77 } */ |
/* { dg-bogus "padding struct size" "PR23610" { xfail lp64 } 78 } */ |
/method-4.mm
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-message "using .\\-\\(id\\)meth1:\\(Base \\*\\)arg1." } */ |
- (id) window; /* { dg-message "using .\\-\\(id\\)window" } */ |
@end |
|
@interface Derived: Base |
- (id) meth1: (Derived *)arg1; /* { dg-message "also found .\\-\\(id\\)meth1:\\(Derived \\*\\)arg1." } */ |
- (Base *) window; /* { dg-message "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" } */ |
} |
/proto-init-mimatch-1.mm
0,0 → 1,35
/* Test to warn on protocol mismatch in a variety of initializations. */ |
|
/* { dg-do compile } */ |
|
typedef struct objc_class *Class; |
|
typedef struct objc_object { |
Class isa; |
} *id; |
|
@protocol NSObject |
@end |
|
@interface NSObject <NSObject> |
@end |
|
@protocol NSCopying |
- (void)copyWithZone; |
@end |
|
@interface Foo:NSObject <NSCopying> |
@end |
|
|
extern id <NSObject> NSCopyObject(); |
|
@implementation Foo |
- (void)copyWithZone { |
Foo *copy = NSCopyObject(); /* { dg-warning "type \\'id <NSObject>\\' does not conform to the \\'NSCopying\\' protocol" } */ |
|
Foo<NSObject,NSCopying> *g = NSCopyObject(); /* { dg-warning "type \\'id <NSObject>\\' does not conform to the \\'NSCopying\\' protocol" } */ |
|
id<NSObject,NSCopying> h = NSCopyObject(); /* { dg-warning "type \\'id <NSObject>\\' does not conform to the \\'NSCopying\\' protocol" } */ |
} |
@end |
/try-catch-17.mm
0,0 → 1,18
/* Test if addition of 'volatile' to object causes bogus error in presence of try-catch. */ |
/* { dg-options "-fobjc-exceptions" } */ |
/* { dg-do compile } */ |
|
struct Point { |
short v; |
short h; |
}; |
|
void foo () |
{ |
Point eventLocation; |
@try { |
} @catch (id iiii) { |
} |
|
Point p = eventLocation; |
} |
/selector-6.mm
0,0 → 1,13
/* { dg-options "" } */ |
/* { dg-do compile } */ |
|
#include <objc/objc.h> |
|
int main() |
{ |
SEL foo = @selector(foo: a::); |
return 0; |
} |
|
/* { dg-final { scan-assembler "foo:a::" } } */ |
|
/exceptions-6.mm
0,0 → 1,29
/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, November 2010. */ |
/* { dg-options "-fobjc-exceptions" } */ |
/* { dg-do compile } */ |
|
/* Test warnings when parsing syntax errors in @throw. */ |
|
#include <objc/objc.h> |
|
void test (id object) |
{ |
@throw object; /* Ok */ |
@throw; /* { dg-error ".@throw. .rethrow. used outside of a @catch block" } */ |
@throw (object); /* Ok. */ |
@throw (id)0 |
} /* { dg-error "expected" } */ |
|
void test2 (id object) |
{ |
@throw object); /* { dg-error "expected" } */ |
@throw (...); /* { dg-error "expected" } */ |
@throw (); /* { dg-error "expected" } */ |
@throw |
} /* { dg-error "expected" } */ |
|
void test3 (id object1, id object2) |
{ |
/* This is apparently valid. */ |
@throw object1, object2; /* Ok. */ |
} |
/set-not-used-1.mm
0,0 → 1,35
|
/* { dg-do compile } */ |
/* { dg-options "-Wunused-but-set-variable" } */ |
|
#import "../objc-obj-c++-shared/TestsuiteObject.m" |
|
@interface obj : TestsuiteObject |
{ |
int value; |
} |
- (int) value; |
- (void) setValue: (int)number; |
@end |
|
@implementation obj : TestsuiteObject |
|
- (int) value { return value; } |
- (void) setValue: (int)number { value = number; } |
|
@end |
|
int main (void) |
{ |
obj *a; /* { dg-bogus "set but not used" } */ |
obj *b; /* { dg-bogus "set but not used" } */ |
obj *c; /* { dg-warning "set but not used" } */ |
|
a = [obj new]; |
b = [obj new]; |
c = [obj new]; |
|
[b setValue: [a value]]; |
|
return [a value]; |
} |
/gnu-api-2-resolve-method.mm
0,0 → 1,567
/* Test the Modern GNU Objective-C Runtime API. |
|
This is test 'resolve-method', covering +resolveClassMethod: and |
+resolveInstanceMethod:. */ |
|
/* { dg-do run } */ |
/* { dg-skip-if "" { *-*-* } { "-fnext-runtime" } { "" } } */ |
|
/* To get the modern GNU Objective-C Runtime API, you include |
objc/runtime.h. */ |
#include <objc/runtime.h> |
|
/* For __objc_msg_forward2. */ |
#include <objc/message.h> |
|
#include <stdlib.h> |
#include <iostream> |
#include <cstring> |
|
@interface MyRootClass |
{ Class isa; } |
+ alloc; |
- init; |
@end |
|
@implementation MyRootClass |
+ alloc { return class_createInstance (self, 0); } |
- init { return self; } |
@end |
|
|
/* A number of tests will try invoking methods that don't exist. We |
want to record the fact, but not abort the program, so we supply |
our own fowarding implementation which will invoke the following |
function for any method that is not found. */ |
|
/* Keep track of how many times a non-existing method was executed. */ |
static int nonExistingMethodCount = 0; |
|
/* Inspired by nil_method in libobjc. */ |
id nonExisting_method (id receiver __attribute__ ((__unused__)), |
SEL sel __attribute__ ((__unused__))) |
{ |
nonExistingMethodCount++; |
return nil; |
} |
|
/* Keep track of how many times the forwarding lookup was invoked. */ |
static int forwardingCount = 0; |
|
/* We install this forwarding hook to cause all failed method lookups |
to call our 'nonExisting_method' function. */ |
IMP forward_everything_to_non_existing_method (id receiver __attribute__ ((__unused__)), |
SEL sel __attribute__ ((__unused__))) |
{ |
forwardingCount++; |
return (IMP)nonExisting_method; |
} |
|
|
/* 'CountClass' is used to test that +resolveClassMethod: and |
+resolveInstanceMethod: are called when expected. They do nothing |
other than recording that they are called. */ |
@interface CountClass : MyRootClass |
+ (BOOL) resolveClassMethod: (SEL)selector; |
+ (BOOL) resolveInstanceMethod: (SEL)selector; |
+ (void) existingClassMethod; |
- (void) existingInstanceMethod; |
@end |
|
/* Count how many times the methods are called for class |
'CountClass'. */ |
static int resolveClassMethodCount = 0; |
static int resolveInstanceMethodCount = 0; |
|
@implementation CountClass : MyRootClass |
+ (BOOL) resolveClassMethod: (SEL)selector |
{ |
resolveClassMethodCount++; |
return NO; |
} |
+ (BOOL) resolveInstanceMethod: (SEL)selector |
{ |
resolveInstanceMethodCount++; |
return NO; |
} |
+ (void) existingClassMethod |
{ |
return; |
} |
- (void) existingInstanceMethod |
{ |
return; |
} |
@end |
|
@protocol NonExistingStuff |
+ (void) nonExistingClassMethod; |
- (void) nonExistingInstanceMethod; |
@end |
|
/* Declare a category with some non existing methods, but don't |
actually implement them. */ |
@interface CountClass (NonExistingStuff) <NonExistingStuff> |
@end |
|
|
/* 'SelfExtendingClass' is used to test that +resolveClassMethod: and |
+resolveInstanceMethod: can extend the class. Any time they are |
called, they install the requested method, mapping it to the same |
implementation as 'countHits'. */ |
@interface SelfExtendingClass : MyRootClass |
+ (int) countHits; |
+ (BOOL) resolveClassMethod: (SEL)selector; |
+ (BOOL) resolveInstanceMethod: (SEL)selector; |
@end |
|
/* How many times the countHits method (or a clone) was called. */ |
static int hitCount = 0; |
|
@implementation SelfExtendingClass : MyRootClass |
+ (int) countHits |
{ |
hitCount++; |
return hitCount; |
} |
+ (BOOL) resolveClassMethod: (SEL)selector |
{ |
/* Duplicate the 'countHits' method into the new method. */ |
Method method = class_getClassMethod (self, @selector (countHits)); |
class_addMethod (object_getClass (self), selector, |
method_getImplementation (method), |
method_getTypeEncoding (method)); |
resolveClassMethodCount++; |
return YES; |
} |
+ (BOOL) resolveInstanceMethod: (SEL)selector |
{ |
/* Duplicate the 'countHits' method into the new method. */ |
Method method = class_getClassMethod (self, @selector (countHits)); |
class_addMethod (self, selector, |
method_getImplementation (method), |
method_getTypeEncoding (method)); |
resolveInstanceMethodCount++; |
return YES; |
|
} |
@end |
|
@protocol NonExistingStuff2 |
+ (int) nonExistingCountHitsMethod; |
- (int) nonExistingCountHitsMethod; |
|
+ (int) nonExistingCountHitsMethod2; |
- (int) nonExistingCountHitsMethod2; |
|
+ (int) nonExistingCountHitsMethod3; |
- (int) nonExistingCountHitsMethod3; |
@end |
|
/* Declare a category with some non existing methods, but don't |
actually implement them. */ |
@interface SelfExtendingClass (NonExistingStuff) <NonExistingStuff2> |
@end |
|
|
int main () |
{ |
/* Functions are tested in alphabetical order. */ |
|
/* Install our test forwarding hook. */ |
__objc_msg_forward2 = forward_everything_to_non_existing_method; |
|
std::cout << "Testing [+resolveClassMethod:] ...\n"; |
{ |
Method m; |
IMP i; |
|
/** CountClass tests. **/ |
|
/* Call an existing method. No +resolveClassMethod and no |
forwarding should be triggered. */ |
[CountClass existingClassMethod]; |
|
if (resolveClassMethodCount != 0) |
abort (); |
|
if (forwardingCount != 0) |
abort (); |
|
if (nonExistingMethodCount != 0) |
abort (); |
|
/* Call a non-existing method. Both +resolveClassMethod and the |
forwarding should be triggered. */ |
[CountClass nonExistingClassMethod]; |
|
if (resolveClassMethodCount != 1) |
abort (); |
|
if (forwardingCount != 1) |
abort (); |
|
if (nonExistingMethodCount != 1) |
abort (); |
|
/* Now try the same tests with class_getClassMethod(), which |
should trigger the resolve methods too, but not the |
forwarding. */ |
m = class_getClassMethod (objc_getClass ("CountClass"), |
@selector (existingClassMethod)); |
if (resolveClassMethodCount != 1) |
abort (); |
|
if (forwardingCount != 1) |
abort (); |
|
if (nonExistingMethodCount != 1) |
abort (); |
|
m = class_getClassMethod (objc_getClass ("CountClass"), |
@selector (nonExistingClassMethod)); |
if (resolveClassMethodCount != 2) |
abort (); |
|
if (forwardingCount != 1) |
abort (); |
|
if (nonExistingMethodCount != 1) |
abort (); |
|
/* Now try the same tests with class_getMethodImplementation(), |
which should trigger the resolve methods and the forwarding |
(but not execute the forwarding, obviously). */ |
i = class_getMethodImplementation (object_getClass (objc_getClass ("CountClass")), |
@selector (existingClassMethod)); |
if (resolveClassMethodCount != 2) |
abort (); |
|
if (forwardingCount != 1) |
abort (); |
|
if (nonExistingMethodCount != 1) |
abort (); |
|
i = class_getMethodImplementation (object_getClass (objc_getClass ("CountClass")), |
@selector (nonExistingClassMethod)); |
if (resolveClassMethodCount != 3) |
abort (); |
|
if (forwardingCount != 2) |
abort (); |
|
if (nonExistingMethodCount != 1) |
abort (); |
|
|
/* Reset the counters for the next test. */ |
resolveClassMethodCount = 0; |
forwardingCount = 0; |
nonExistingMethodCount = 0; |
|
|
/** SelfExtendingClass tests. **/ |
|
/* Try the direct countHits method first. No resolving or |
forwarding should be triggered. */ |
if ([SelfExtendingClass countHits] != 1) |
abort (); |
|
if (resolveClassMethodCount != 0) |
abort (); |
|
if (forwardingCount != 0) |
abort (); |
|
if (nonExistingMethodCount != 0) |
abort (); |
|
/* Now, try calling a non-existing count method; it should be |
installed and invoked. */ |
if ([SelfExtendingClass nonExistingCountHitsMethod] != 2) |
abort (); |
|
if (resolveClassMethodCount != 1) |
abort (); |
|
if (forwardingCount != 0) |
abort (); |
|
if (nonExistingMethodCount != 0) |
abort (); |
|
/* Try it again. The method has now been installed, so it should |
be used and work, but with no additional resolving |
involved. */ |
if ([SelfExtendingClass nonExistingCountHitsMethod] != 3) |
abort (); |
|
if (resolveClassMethodCount != 1) |
abort (); |
|
if (forwardingCount != 0) |
abort (); |
|
if (nonExistingMethodCount != 0) |
abort (); |
|
|
/* Now try the same tests with class_getClassMethod(). */ |
m = class_getClassMethod (objc_getClass ("SelfExtendingClass"), |
@selector (nonExistingCountHitsMethod2)); |
if (resolveClassMethodCount != 2) |
abort (); |
|
if (forwardingCount != 0) |
abort (); |
|
if (nonExistingMethodCount != 0) |
abort (); |
|
/* Try it again. The method has now been installed, so it should |
be used and work, but with no additional resolving |
involved. */ |
if ([SelfExtendingClass nonExistingCountHitsMethod2] != 4) |
abort (); |
|
if (resolveClassMethodCount != 2) |
abort (); |
|
if (forwardingCount != 0) |
abort (); |
|
if (nonExistingMethodCount != 0) |
abort (); |
|
|
/* Now try the same tests with class_getMethodImplementation(). */ |
i = class_getMethodImplementation (object_getClass (objc_getClass ("SelfExtendingClass")), |
@selector (nonExistingCountHitsMethod3)); |
if (resolveClassMethodCount != 3) |
abort (); |
|
if (forwardingCount != 0) |
abort (); |
|
if (nonExistingMethodCount != 0) |
abort (); |
|
/* Try it again. The method has now been installed, so it should |
be used and work, but with no additional resolving |
involved. */ |
if ([SelfExtendingClass nonExistingCountHitsMethod3] != 5) |
abort (); |
|
if (resolveClassMethodCount != 3) |
abort (); |
|
if (forwardingCount != 0) |
abort (); |
|
if (nonExistingMethodCount != 0) |
abort (); |
} |
|
/* Reset the counters for the next test. */ |
nonExistingMethodCount = 0; |
forwardingCount = 0; |
hitCount = 0; |
|
std::cout << "Testing [+resolveInstanceMethod:] ...\n"; |
{ |
Method m; |
IMP i; |
CountClass *object = [[CountClass alloc] init]; |
SelfExtendingClass *object2 = [[SelfExtendingClass alloc] init]; |
|
/** CountClass tests. **/ |
|
/* Call an existing method. No +resolveInstanceMethod and no |
forwarding should be triggered. */ |
[object existingInstanceMethod]; |
|
if (resolveInstanceMethodCount != 0) |
abort (); |
|
if (forwardingCount != 0) |
abort (); |
|
if (nonExistingMethodCount != 0) |
abort (); |
|
/* Call a non-existing method. Both +resolveInstanceMethod and the |
forwarding should be triggered. */ |
[object nonExistingInstanceMethod]; |
|
if (resolveInstanceMethodCount != 1) |
abort (); |
|
if (forwardingCount != 1) |
abort (); |
|
if (nonExistingMethodCount != 1) |
abort (); |
|
/* Now try the same tests with class_getInstanceMethod(), which |
should trigger the resolve methods too, but not the |
forwarding. */ |
m = class_getInstanceMethod (objc_getClass ("CountClass"), |
@selector (existingInstanceMethod)); |
|
if (resolveInstanceMethodCount != 1) |
abort (); |
|
if (forwardingCount != 1) |
abort (); |
|
if (nonExistingMethodCount != 1) |
abort (); |
|
m = class_getInstanceMethod (objc_getClass ("CountClass"), |
@selector (nonExistingInstanceMethod)); |
|
if (resolveInstanceMethodCount != 2) |
abort (); |
|
if (forwardingCount != 1) |
abort (); |
|
if (nonExistingMethodCount != 1) |
abort (); |
|
/* Now try the same tests with class_getMethodImplementation(), |
which should trigger the resolve methods and the |
forwarding. */ |
i = class_getMethodImplementation (objc_getClass ("CountClass"), |
@selector (existingInstanceMethod)); |
if (resolveInstanceMethodCount != 2) |
abort (); |
|
if (forwardingCount != 1) |
abort (); |
|
if (nonExistingMethodCount != 1) |
abort (); |
|
i = class_getMethodImplementation (objc_getClass ("CountClass"), |
@selector (nonExistingInstanceMethod)); |
if (resolveInstanceMethodCount != 3) |
abort (); |
|
if (forwardingCount != 2) |
abort (); |
|
if (nonExistingMethodCount != 1) |
abort (); |
|
/* Reset the counters for the next test. */ |
resolveInstanceMethodCount = 0; |
forwardingCount = 0; |
nonExistingMethodCount = 0; |
|
|
/** SelfExtendingClass tests. **/ |
|
/* Try the direct countHits method first. No resolving or |
forwarding should be triggered. */ |
if ([SelfExtendingClass countHits] != 1) |
abort (); |
|
if (resolveInstanceMethodCount != 0) |
abort (); |
|
if (forwardingCount != 0) |
abort (); |
|
if (nonExistingMethodCount != 0) |
abort (); |
|
/* Now, try calling a non-existing count method; it should be |
installed and invoked. */ |
if ([object2 nonExistingCountHitsMethod] != 2) |
abort (); |
|
if (resolveInstanceMethodCount != 1) |
abort (); |
|
if (forwardingCount != 0) |
abort (); |
|
if (nonExistingMethodCount != 0) |
abort (); |
|
/* Try it again. The method has now been installed, so it should |
be used and work, but with no additional resolving |
involved. */ |
if ([object2 nonExistingCountHitsMethod] != 3) |
abort (); |
|
if (resolveInstanceMethodCount != 1) |
abort (); |
|
if (forwardingCount != 0) |
abort (); |
|
if (nonExistingMethodCount != 0) |
abort (); |
|
/* Now try the same tests with class_getInstanceMethod(). */ |
m = class_getInstanceMethod (objc_getClass ("SelfExtendingClass"), |
@selector (nonExistingCountHitsMethod2)); |
if (resolveInstanceMethodCount != 2) |
abort (); |
|
if (forwardingCount != 0) |
abort (); |
|
if (nonExistingMethodCount != 0) |
abort (); |
|
/* Try it again. The method has now been installed, so it should |
be used and work, but with no additional resolving |
involved. */ |
if ([object2 nonExistingCountHitsMethod2] != 4) |
abort (); |
|
if (resolveInstanceMethodCount != 2) |
abort (); |
|
if (forwardingCount != 0) |
abort (); |
|
if (nonExistingMethodCount != 0) |
abort (); |
|
|
/* Now try the same tests with class_getMethodImplementation(). */ |
i = class_getMethodImplementation (objc_getClass ("SelfExtendingClass"), |
@selector (nonExistingCountHitsMethod3)); |
if (resolveInstanceMethodCount != 3) |
abort (); |
|
if (forwardingCount != 0) |
abort (); |
|
if (nonExistingMethodCount != 0) |
abort (); |
|
/* Try it again. The method has now been installed, so it should |
be used and work, but with no additional resolving |
involved. */ |
if ([object2 nonExistingCountHitsMethod3] != 5) |
abort (); |
|
if (resolveInstanceMethodCount != 3) |
abort (); |
|
if (forwardingCount != 0) |
abort (); |
|
if (nonExistingMethodCount != 0) |
abort (); |
} |
|
|
return (0); |
} |
/too-many-args.mm
0,0 → 1,10
/* { dg-do compile } */ |
|
@interface SomeClass |
+ method:(int)foo; |
@end |
|
int main(void) { |
[SomeClass method:3, 4]; /* { dg-error "too many arguments to method \\'method:\\'" } */ |
return 0; |
} |
/bad-forward-decl.mm
0,0 → 1,3
class TestCPP { }; /* { dg-error "previous declaration of" } */ |
|
@class TestCPP; /* { dg-error "redeclared as different kind of symbol" } */ |
/ivar-problem-1.mm
0,0 → 1,66
/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, November 2010. */ |
/* { dg-do compile } */ |
|
/* This test checks what happens if there are 16 instance variables. |
In that case, the class was not created correctly. In this testcase, |
we have two classes, one with 15 variables and one with 16. Older |
GCCs would generate a bogus warning for the second class but not |
for the first one. This only happened for ObjC, but it's good to |
test ObjC++ as well. */ |
|
#include <stdlib.h> |
#include <objc/objc.h> |
|
@interface MyRootClass1 |
{ |
Class isa; |
int v2; |
int v3; |
int v4; |
int v5; |
int v6; |
int v7; |
int v8; |
int v9; |
int v10; |
int v11; |
int v12; |
int v13; |
int v14; |
int v15; |
} |
- (id) init; |
@end |
|
@implementation MyRootClass1 |
- (id) init { return self; } |
@end |
|
|
@interface MyRootClass2 |
{ |
Class isa; |
int v2; |
int v3; |
int v4; |
int v5; |
int v6; |
int v7; |
int v8; |
int v9; |
int v10; |
int v11; |
int v12; |
int v13; |
int v14; |
int v15; |
/* Adding the 16th variable used to cause bogus warnings to be |
generated. */ |
int v16; |
} |
- (id) init; |
@end |
|
@implementation MyRootClass2 |
- (id) init { return self; } /* This should not generate a bogus warning. */ |
@end |
/gnu-api-2-ivar.mm
0,0 → 1,83
/* Test the Modern GNU Objective-C Runtime API. |
|
This is test 'ivar', covering all functions starting with 'ivar'. */ |
|
/* { dg-do run } */ |
/* { dg-skip-if "No API#2 pre-Darwin9" { *-*-darwin[5-8]* } { "-fnext-runtime" } { "" } } */ |
/* { dg-xfail-run-if "Needs OBJC2 ABI" { *-*-darwin* && { lp64 && { ! objc2 } } } { "-fnext-runtime" } { "" } } */ |
|
/* To get the modern GNU Objective-C Runtime API, you include |
objc/runtime.h. */ |
#include <objc/runtime.h> |
#include <stdlib.h> |
#include <iostream> |
#include <cstring> |
|
@interface MyRootClass |
{ Class isa; } |
+ alloc; |
- init; |
+ initialize; |
@end |
|
@implementation MyRootClass |
+ alloc { return class_createInstance (self, 0); } |
- init { return self; } |
+ initialize { return self; } |
@end |
|
@protocol MyProtocol |
- (id) variable; |
@end |
|
@protocol MySecondProtocol |
- (id) setVariable: (id)value; |
@end |
|
@interface MySubClass : MyRootClass <MyProtocol> |
{ id variable_ivar; } |
- (void) setVariable: (id)value; |
- (id) variable; |
@end |
|
@implementation MySubClass |
- (void) setVariable: (id)value { variable_ivar = value; } |
- (id) variable { return variable_ivar; } |
@end |
|
|
int main () |
{ |
/* Functions are tested in alphabetical order. */ |
|
std::cout << "Testing ivar_getName () ...\n"; |
{ |
Ivar ivar = class_getInstanceVariable (objc_getClass ("MySubClass"), |
"variable_ivar"); |
if (strcmp (ivar_getName (ivar), "variable_ivar") != 0) |
abort (); |
|
ivar = class_getInstanceVariable (objc_getClass ("MySubClass"), |
"variable"); |
if (ivar != 0) |
abort (); |
} |
|
std::cout << "Testing ivar_getOffset () ...\n"; |
{ |
Ivar ivar = class_getInstanceVariable (objc_getClass ("MyRootClass"), |
"isa"); |
if (ivar_getOffset (ivar) != 0) |
abort (); |
} |
|
std::cout << "Testing ivar_getTypeEncoding () ...\n"; |
{ |
Ivar ivar = class_getInstanceVariable (objc_getClass ("MySubClass"), |
"variable_ivar"); |
if (strcmp (ivar_getTypeEncoding (ivar), "@") != 0) |
abort (); |
} |
|
return (0); |
} |
/proto-lossage-4.mm
0,0 → 1,52
/* Test for situations in which protocol conformance information |
may be lost while casting. */ |
/* Author: Ziemowit Laski <zlaski@apple.com>. */ |
/* { dg-do compile } */ |
|
/* One-line substitute for objc/objc.h */ |
typedef struct objc_object { struct objc_class *class_pointer; } *id; |
|
@protocol Proto |
- (long)someValue; |
@end |
|
@interface Obj |
- (long)anotherValue; |
@end |
|
long foo(void) { |
long receiver = 2; |
Obj *objrcvr; |
Obj <Proto> *objrcvr2; |
|
/* NB: Since 'receiver' is an invalid ObjC message receiver, the compiler |
should warn but then search for methods as if we were messaging 'id'. */ |
|
receiver += [receiver someValue]; /* { dg-warning "invalid receiver type .long int." } */ |
receiver += [receiver anotherValue]; /* { dg-warning "invalid receiver type .long int." } */ |
|
receiver += [(Obj *)receiver someValue]; /* { dg-warning ".Obj. may not respond to .\\-someValue." } */ |
/* { dg-error "invalid conversion" "" { target *-*-* } 28 } */ |
|
receiver += [(Obj *)receiver anotherValue]; |
receiver += [(Obj <Proto> *)receiver someValue]; |
receiver += [(Obj <Proto> *)receiver anotherValue]; |
receiver += [objrcvr someValue]; /* { dg-warning ".Obj. may not respond to .\\-someValue." } */ |
/* { dg-error "invalid conversion" "" { target *-*-* } 34 } */ |
|
receiver += [objrcvr anotherValue]; |
receiver += [(Obj <Proto> *)objrcvr someValue]; |
receiver += [(Obj <Proto> *)objrcvr anotherValue]; |
receiver += [objrcvr2 someValue]; |
receiver += [objrcvr2 anotherValue]; |
receiver += [(Obj *)objrcvr2 someValue]; /* { dg-warning ".Obj. may not respond to .\\-someValue." } */ |
/* { dg-error "invalid conversion" "" { target *-*-* } 42 } */ |
|
receiver += [(Obj *)objrcvr2 anotherValue]; |
|
return receiver; |
} |
|
/* { 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 } */ |
/fobjc-exceptions-1.mm
0,0 → 1,28
/* Test that Objective-C exceptions cause an error with -fobjc-exceptions. */ |
/* { dg-do compile } */ |
|
@class Object; |
|
int dummy (int number, Object *o) |
{ |
@try { /* { dg-error ".-fobjc-exceptions. is required to enable Objective-C exception syntax" } */ |
number++; |
@throw o; /* Nothing, error has already been produced. */ |
} |
@catch (id object) |
{ |
number++; |
@throw; /* Nothing, error has already been produced. */ |
} |
@finally |
{ |
number++; |
} |
|
@synchronized (o) /* Nothing, error has already been produced. */ |
{ |
number++; |
} |
|
return number; |
} |
/comp-types-3.mm
0,0 → 1,38
/* Test simple ObjC types casts. */ |
/* Author: Nicola Pero <nicola@brainstorm.co.uk>. */ |
/* { dg-do compile } */ |
|
#include <objc/objc.h> |
|
@protocol MyProtocol |
- (void) foo; |
@end |
|
@interface MyClass |
@end |
|
int main() |
{ |
id obj = nil; |
id<MyProtocol> obj_p = nil; |
MyClass *obj_c = nil; |
Class obj_C = Nil; |
|
/* All these casts should generate no warnings. */ |
|
obj = (id)obj_p; |
obj = (id)obj_c; |
obj = (id)obj_C; |
obj_c = (MyClass *)obj; |
obj_c = (MyClass *)obj_p; |
obj_c = (MyClass *)obj_C; |
obj_p = (id<MyProtocol>)obj; |
obj_p = (id<MyProtocol>)obj_c; |
obj_p = (id<MyProtocol>)obj_C; |
obj_C = (Class)obj; |
obj_C = (Class)obj_p; |
obj_C = (Class)obj_c; |
|
|
return 0; |
} |
/try-catch-5.mm
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" } */ |
} |
} |
/method-13.mm
0,0 → 1,27
/* Check if finding multiple signatures for a method is handled gracefully. Author: Ziemowit Laski <zlaski@apple.com> */ |
/* { dg-options "-Wstrict-selector-match" } */ |
/* { dg-do compile } */ |
#include <objc/objc.h> |
#include "../objc-obj-c++-shared/TestsuiteObject.h" |
|
@interface Class1 |
- (void)setWindow:(TestsuiteObject *)wdw; |
@end |
|
@interface Class2 |
- (void)setWindow:(Class1 *)window; |
@end |
|
id foo(void) { |
TestsuiteObject *obj = [[TestsuiteObject alloc] init]; |
id obj2 = obj; |
[obj setWindow:nil]; /* { dg-warning ".TestsuiteObject. may not respond to .\\-setWindow:." } */ |
/* { dg-warning "Messages without a matching method signature" "" { target *-*-* } 18 } */ |
/* { dg-warning "will be assumed to return .id. and accept" "" { target *-*-* } 18 } */ |
/* { dg-warning ".\.\.\.. as arguments" "" { target *-*-* } 18 } */ |
[obj2 setWindow:nil]; /* { dg-warning "multiple methods named .\\-setWindow:. found" } */ |
/* { dg-message "using .\\-\\(void\\)setWindow:\\(TestsuiteObject \\*\\)wdw." "" { target *-*-* } 8 } */ |
/* { dg-message "also found .\\-\\(void\\)setWindow:\\(Class1 \\*\\)window." "" { target *-*-* } 12 } */ |
|
return obj; |
} |
/proto-qual-1.mm
0,0 → 1,61
/* Check that protocol qualifiers are compiled and encoded properly. */ |
/* Author: Ziemowit Laski <zlaski@apple.com> */ |
|
/* { dg-do run } */ |
/* { dg-xfail-run-if "Needs OBJC2 ABI" { *-*-darwin* && { lp64 && { ! objc2 } } } { "-fnext-runtime" } { "" } } */ |
|
#include <stdio.h> |
#include <stdlib.h> |
#include "../objc-obj-c++-shared/runtime.h" |
#include <objc/Protocol.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; |
struct objc_method_description *meth; |
struct objc_method_description meth_object; |
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) { |
proto = @protocol(Retain); |
|
meth_object = protocol_getMethodDescription (proto, |
@selector(address:with:), YES, YES); |
meth = &meth_object; |
|
scan_initial("O@%u@%u:%uNR@%uo^^S%u"); |
CHECK_IF(offs3 == offs2 + aligned_sizeof(id) && totsize == offs3 + aligned_sizeof(unsigned)); |
|
meth_object = protocol_getMethodDescription (proto, |
@selector(retainArgument:with:), YES, NO); |
meth = &meth_object; |
|
scan_initial("Vv%u@%u:%uOo@%un^*%u"); |
CHECK_IF(offs3 == offs2 + aligned_sizeof(id) && totsize == offs3 + aligned_sizeof(char **)); |
return 0; |
} |
/qual-types-1.mm
0,0 → 1,69
/* Test if ObjC++ can distinguish protocol qualifiers from |
template arguments. */ |
/* Author: Ziemowit Laski <zlaski@apple.com>. */ |
|
/* { dg-do run } */ |
/* { dg-xfail-run-if "Needs OBJC2 ABI" { *-*-darwin* && { lp64 && { ! objc2 } } } { "-fnext-runtime" } { "" } } */ |
#include "../objc-obj-c++-shared/TestsuiteObject.m" |
#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: TestsuiteObject |
{ @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; } |
TestsuiteObject <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; |
} |
|
/encode-8.mm
0,0 → 1,23
/* Test if the Objective-C @encode machinery distinguishes between |
'BOOL *' (which should be encoded as '^c') and 'char *' (which |
should be encoded as '*'). */ |
/* Contributed by Ziemowit Laski <zlaski@apple.com>. */ |
/* { dg-do run { target *-*-darwin* } } */ |
/* { dg-skip-if "" { *-*-* } { "-fgnu-runtime" } { "" } } */ |
|
#include <string.h> |
#include <stdlib.h> |
#include <objc/objc.h> |
|
int main(void) { |
const char *BOOL_ptr = @encode(BOOL *); |
const char *char_ptr = @encode(char *); |
|
if(strcmp(BOOL_ptr, "^c")) |
abort(); |
|
if(strcmp(char_ptr, "*")) |
abort(); |
|
return 0; |
} |
/class-protocol-1.mm
0,0 → 1,441
/* Check Class <protocol> types */ |
/* Author: David Ayers <d.ayers@inode.at> */ |
/* { dg-do compile } */ |
|
#include <objc/objc.h> |
#include "../objc-obj-c++-shared/runtime.h" |
|
@protocol MyProto1 |
+(void)doItClass1; |
-(void)doItInstance1; |
@end |
|
@protocol MyProto2 |
+(void)doItClass2; |
-(void)doItInstance2; |
@end |
|
@interface MyClass1 <MyProto1> |
{ |
Class isa; |
} |
@end |
@implementation MyClass1 |
+(void)doItClass1{} |
-(void)doItInstance1{} |
@end |
|
@interface MyClass2 : MyClass1 <MyProto2> |
@end |
@implementation MyClass2 |
+(void)doItClass2{} |
-(void)doItInstance2{} |
@end |
|
@interface MyClass3 |
{ |
Class isa; |
} |
@end |
@interface MyClass4 : MyClass3 <MyProto1> |
@end |
|
/*----------------------------------------*/ |
|
Class cls = 0; |
Class <MyProto1> clsP1 = 0; |
Class <MyProto2> clsP2 = 0; |
|
void |
testSimple(void) |
{ |
[cls doItClass1]; |
[cls doItInstance1]; |
[cls doItClass2]; |
[cls doItInstance2]; |
|
[clsP1 doItClass1]; |
[clsP1 doItInstance1]; /* { dg-warning "instead of" } */ |
[clsP1 doItClass2]; /* { dg-warning "not found in protocol" } */ |
[clsP1 doItInstance2]; /* { dg-warning "not found in protocol" } */ |
|
[clsP2 doItClass1]; /* { dg-warning "not found in protocol" } */ |
[clsP2 doItInstance1]; /* { dg-warning "not found in protocol" } */ |
[clsP2 doItClass2]; |
[clsP2 doItInstance2]; /* { dg-warning "instead of" } */ |
|
[MyClass1 doItClass1]; |
[MyClass1 doItInstance1]; |
[MyClass1 doItClass2]; /* { dg-warning "may not respond to" } */ |
[MyClass1 doItInstance2]; /* { dg-warning "may not respond to" } */ |
|
[MyClass2 doItClass1]; |
[MyClass2 doItInstance1]; |
[MyClass2 doItClass2]; |
[MyClass2 doItInstance2]; /* { dg-warning "may not respond to" } */ |
|
[MyClass3 doItClass1]; /* { dg-warning "may not respond to" } */ |
[MyClass3 doItInstance1]; /* { dg-warning "may not respond to" } */ |
|
[MyClass4 doItClass1]; |
[MyClass4 doItInstance1]; /* { dg-warning "may not respond to" } */ |
} |
|
/*----------------------------------------*/ |
/* Protocols declared by categories */ |
|
@protocol MyProto3 |
+(void)doItClass3; |
-(void)doItInstance3; |
@end |
@protocol MyProto4 |
+(void)doItClass4; |
-(void)doItInstance4; |
@end |
|
@interface MyClass1 (Category1) <MyProto3> |
@end |
@interface MyClass2 (Category2) <MyProto4> |
@end |
|
void |
testCategory(void) |
{ |
[cls doItClass3]; |
[cls doItInstance3]; |
[cls doItClass4]; |
[cls doItInstance4]; |
|
[MyClass1 doItClass3]; |
[MyClass1 doItInstance3]; |
[MyClass1 doItClass4]; /* { dg-warning "may not respond" } */ |
[MyClass1 doItInstance4]; /* { dg-warning "may not respond" } */ |
|
[MyClass2 doItClass3]; |
[MyClass2 doItInstance3]; |
[MyClass2 doItClass4]; |
[MyClass2 doItInstance4]; /* { dg-warning "may not respond" } */ |
|
} |
|
/*----------------------------------------*/ |
/* Inherited protocols declared by categories */ |
|
@protocol MyProto5 <MyProto1> |
+(void)doItClass5; |
-(void)doItInstance5; |
@end |
|
@protocol MyProto6 <MyProto2> |
+(void)doItClass6; |
-(void)doItInstance6; |
@end |
|
@interface MyClass1 (Category3) <MyProto5> |
@end |
@interface MyClass2 (Category4) <MyProto6> |
@end |
|
Class <MyProto5> clsP5 = 0; |
Class <MyProto6> clsP6 = 0; |
|
void |
testCategoryInherited(void) |
{ |
[cls doItClass5]; |
[cls doItInstance5]; |
[cls doItClass6]; |
[cls doItInstance6]; |
|
[clsP5 doItClass1]; |
[clsP5 doItInstance1]; /* { dg-warning "instead of" } */ |
[clsP5 doItClass2]; /* { dg-warning "not found in protocol" } */ |
[clsP5 doItInstance2]; /* { dg-warning "not found in protocol" } */ |
|
[clsP6 doItClass1]; /* { dg-warning "not found in protocol" } */ |
[clsP6 doItInstance1]; /* { dg-warning "not found in protocol" } */ |
[clsP6 doItClass2]; |
[clsP6 doItInstance2]; /* { dg-warning "instead of" } */ |
|
|
[MyClass1 doItClass5]; |
[MyClass1 doItInstance5]; |
[MyClass1 doItClass6]; /* { dg-warning "may not respond" } */ |
[MyClass1 doItInstance6]; /* { dg-warning "may not respond" } */ |
|
[MyClass2 doItClass5]; |
[MyClass2 doItInstance5]; |
[MyClass2 doItClass6]; |
[MyClass2 doItInstance6]; /* { dg-warning "may not respond" } */ |
|
} |
|
/*----------------------------------------*/ |
/* Forward declared root protocols */ |
|
@protocol FwProto; |
|
@interface MyClass1 (Forward) <FwProto> /* { dg-warning "definition of protocol .FwProto. not found" } */ |
@end |
|
Class <FwProto> clsP7 = 0; |
|
void |
testForwardeDeclared1(void) |
{ |
[cls doItClass7]; /* { dg-warning "no .\\+doItClass7. method found" } */ |
[cls doItInstance7]; /* { dg-warning "no .\\+doItInstance7. method found" } */ |
|
[clsP7 doItClass7]; /* { dg-warning "not found in protocol" } */ |
/* { dg-warning "no .\\+doItClass7. method found" "" { target *-*-* } 189 } */ |
[clsP7 doItInstance7]; /* { dg-warning "not found in protocol" } */ |
/* { dg-warning "no .\\+doItInstance7. method found" "" { target *-*-* } 191 } */ |
|
[MyClass1 doItClass7]; /* { dg-warning "may not respond" } */ |
[MyClass1 doItInstance7]; /* { dg-warning "may not respond" } */ |
|
[MyClass2 doItClass7]; /* { dg-warning "may not respond" } */ |
[MyClass2 doItInstance7]; /* { dg-warning "may not respond" } */ |
|
} |
|
@protocol FwProto |
+(void)doItClass7; |
-(void)doItInstance7; |
@end |
|
void |
testForwardeDeclared2(void) |
{ |
[cls doItClass7]; |
[cls doItInstance7]; |
|
[clsP7 doItClass7]; |
[clsP7 doItInstance7]; /* { dg-warning "instead of" } */ |
|
[MyClass1 doItClass7]; |
[MyClass1 doItInstance7]; |
|
[MyClass2 doItClass7]; |
[MyClass2 doItInstance7]; |
} |
|
/*----------------------------------------*/ |
/* Inherited non root protocols */ |
|
@protocol MyProto8 |
+(void)doItClass8; |
-(void)doItInstance8; |
@end |
|
@protocol MyProto9 <MyProto8> |
+(void)doItClass9; |
-(void)doItInstance9; |
@end |
|
@interface MyClass1 (InheritedNonRoot) <MyProto9> |
@end |
|
Class <MyProto8> clsP8 = 0; |
Class <MyProto9> clsP9 = 0; |
|
void |
testInheritedNonRoot(void) |
{ |
[cls doItClass8]; |
[cls doItInstance8]; |
[cls doItClass9]; |
[cls doItInstance9]; |
|
[clsP8 doItClass8]; |
[clsP8 doItInstance8]; /* { dg-warning "instead of" } */ |
[clsP8 doItClass9]; /* { dg-warning "not found in protocol" } */ |
[clsP8 doItInstance9]; /* { dg-warning "not found in protocol" } */ |
|
[clsP9 doItClass8]; |
[clsP9 doItInstance8]; /* { dg-warning "instead of" } */ |
[clsP9 doItClass9]; |
[clsP9 doItInstance9]; /* { dg-warning "instead of" } */ |
|
[MyClass1 doItClass8]; |
[MyClass1 doItInstance8]; |
[MyClass1 doItClass9]; |
[MyClass1 doItInstance9]; |
|
[MyClass2 doItClass8]; |
[MyClass2 doItInstance8]; |
[MyClass2 doItClass9]; |
[MyClass2 doItInstance9]; |
|
} |
|
/*----------------------------------------*/ |
/* Prototype mismatch */ |
|
@protocol MyOtherProto1 |
+(id)doItClass1; |
-(id)doItInstance1; |
@end |
@interface MyOtherClass1 <MyOtherProto1> |
@end |
|
Class <MyOtherProto1> oclsP1; |
|
void |
testPrototypeMismatch(void) |
{ |
id tmp1 = [oclsP1 doItClass1]; |
id tmp2 = [oclsP1 doItInstance1]; /* { dg-warning "instead of" } */ |
|
[clsP1 doItClass1]; |
[clsP1 doItInstance1]; /* { dg-warning "instead of" } */ |
} |
|
id obj = nil; |
id <MyProto1> objP1 = nil; |
id <MyProto2> objP2 = nil; |
id <MyProto5> objP5 = nil; |
int num = 0; |
void *ptr = 0; |
|
MyClass1 *mc1 = nil; |
|
void |
testComptypes(void) |
{ |
{ /* id <protocol>, id <protocol> */ |
objP1 == objP2; /* { dg-warning "lacks a cast" } */ |
objP2 == objP1; /* { dg-warning "lacks a cast" } */ |
|
objP1 == objP5; |
objP5 == objP1; |
} |
{ /* id <protocol>, SomeClass * */ |
mc1 == objP1; |
objP1 == mc1; |
|
mc1 == objP2; /* { dg-warning "lacks a cast" } */ |
objP2 == mc1; /* { dg-warning "lacks a cast" } */ |
} |
{ /* id <protocol>, id */ |
obj == objP1; |
objP1 == obj; |
} |
{ /* id <protocol>, Class */ |
cls == objP1; /* { dg-warning "lacks a cast" } */ |
objP1 == cls; /* { dg-warning "lacks a cast" } */ |
} |
{ /* id <protocol>, non-ObjC */ |
num == objP1; /* { dg-error "between pointer" } */ |
objP1 == num; /* { dg-error "between pointer" } */ |
|
ptr == objP1; |
objP1 == ptr; |
} |
{ /* Class <protocol>, Class <protocol> */ |
clsP1 == clsP2; /* { dg-warning "lacks a cast" } */ |
clsP2 == clsP1; /* { dg-warning "lacks a cast" } */ |
|
clsP1 == clsP5; |
clsP5 == clsP1; |
} |
{ /* Class <protocol>, SomeClass * */ |
mc1 == clsP1; /* { dg-warning "lacks a cast" } */ |
clsP1 == mc1; /* { dg-warning "lacks a cast" } */ |
} |
{ /* Class <protocol>, id */ |
obj == clsP1; |
clsP1 == obj; |
} |
{ /* Class <protocol>, Class */ |
cls == clsP1; |
clsP1 == cls; |
} |
{ /* Class <protocol>, non-ObjC */ |
num == clsP1; /* { dg-error "between pointer" } */ |
clsP1 == num; /* { dg-error "between pointer" } */ |
|
ptr == clsP1; |
clsP1 == ptr; |
} |
{ /* Class <protocol>, id <protocol> */ |
clsP1 == objP1; /* { dg-warning "lacks a cast" } */ |
objP1 == clsP1; /* { dg-warning "lacks a cast" } */ |
} |
|
{ /* id <protocol>, id <protocol> */ |
objP1 = objP2; /* { dg-warning "does not conform" } */ |
objP2 = objP1; /* { dg-warning "does not conform" } */ |
|
objP1 = objP5; |
objP5 = objP1; /* { dg-warning "does not conform" } */ |
} |
{ /* id <protocol>, SomeClass * */ |
mc1 = objP1; |
objP1 = mc1; |
|
mc1 = objP2; /* { dg-warning "does not conform" } */ |
objP2 = mc1; /* { dg-warning "does not implement" } */ |
} |
{ /* id <protocol>, id */ |
obj = objP1; |
objP1 = obj; |
} |
{ /* id <protocol>, Class */ |
cls = objP1; /* { dg-warning "distinct Objective\\-C type" } */ |
objP1 = cls; /* { dg-warning "distinct Objective\\-C type" } */ |
} |
{ /* id <protocol>, non-ObjC */ |
num = objP1; /* { dg-error "invalid conversion" } */ |
objP1 = num; /* { dg-error "invalid conversion" } */ |
|
ptr = objP1; |
objP1 = ptr; /* { dg-error "invalid conversion" } */ |
} |
{ /* Class <protocol>, Class <protocol> */ |
clsP1 = clsP2; /* { dg-warning "does not conform" } */ |
clsP2 = clsP1; /* { dg-warning "does not conform" } */ |
|
clsP1 = clsP5; |
clsP5 = clsP1; /* { dg-warning "does not conform" } */ |
} |
{ /* Class <protocol>, SomeClass * */ |
/* These combinations should always elicit a warning. */ |
mc1 = clsP1; /* { dg-warning "distinct Objective\\-C type" } */ |
clsP1 = mc1; /* { dg-warning "distinct Objective\\-C type" } */ |
|
mc1 = clsP2; /* { dg-warning "distinct Objective\\-C type" } */ |
clsP2 = mc1; /* { dg-warning "distinct Objective\\-C type" } */ |
} |
{ /* Class <protocol>, id */ |
obj = clsP1; |
clsP1 = obj; |
} |
{ /* Class <protocol>, Class */ |
cls = clsP1; |
clsP1 = cls; |
} |
{ /* Class <protocol>, non-ObjC */ |
num = clsP1; /* { dg-error "invalid conversion" } */ |
clsP1 = num; /* { dg-error "invalid conversion" } */ |
|
ptr = clsP1; |
clsP1 = ptr; /* { dg-error "invalid conversion" } */ |
} |
{ /* Class <protocol>, id <protocol> */ |
clsP1 = objP1; /* { dg-warning "distinct Objective\\-C type" } */ |
objP1 = clsP1; /* { dg-warning "distinct Objective\\-C type" } */ |
} |
} |
|
int main () |
{ |
testSimple(); |
testCategory(); |
testCategoryInherited(); |
return(0); |
} |
|
/* { 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 } */ |
/fsf-nsstring-format-1.mm
0,0 → 1,51
/* Check NSString format extensions. */ |
/* { dg-do compile { target *-*-darwin* } } */ |
/* { dg-skip-if "" { *-*-* } { "-fgnu-runtime" } { "" } } */ |
/* { dg-options "-Wall" } */ |
|
#ifndef __CONSTANT_CFSTRINGS__ |
#error requires CFString |
#endif |
|
#ifdef __cplusplus |
extern "C" { |
#endif |
extern int printf (const char *fmt, ...); |
typedef const struct __CFString * CFStringRef; |
|
#ifdef __cplusplus |
} |
#endif |
|
@class NSString; |
|
int s1 (NSString *fmt, ...) __attribute__((format(NSString, 1, 2))) ; /* OK */ |
/* A CFString can represent an NSString. */ |
int s1a (CFStringRef fmt, ...) __attribute__((format(NSString, 1, 2))) ; /* OK */ |
/* But... it is possible that a CFString format might imply functionality that |
is not present in objective-c. */ |
int s1b (NSString *fmt, ...) __attribute__((format(CFString, 1, 2))) ; /* { dg-error "format argument should be a .CFString. reference" } */ |
|
int s2 (int a, NSString *fmt, ... ) __attribute__((format(__NSString__, 2, 3))) ; /* OK */ |
|
int s2a (int a, NSString *fmt, ... ) __attribute__((format(NSString, 2, 2))) ; /* { dg-error "format string argument follows the args to be formatted" } */ |
|
int s3 (const char *fmt, ... ) __attribute__((format(__NSString__, 1, 2))) ; /* { dg-error "format argument should be a .NSString. reference but a string was found" } */ |
int s4 (NSString *fmt, ... ) __attribute__((format(printf, 1, 2))) ; /* { dg-error "found a .NSString. reference but the format argument should be a string" } */ |
|
char *s5 (char dum, char *fmt1, ... ) __attribute__((format_arg(2))) ; /* OK */ |
NSString *s6 (NSString *dum, NSString *fmt1, ... ) __attribute__((format_arg(2))) ; /* OK */ |
|
char *s7 (int dum, void *fmt1, ... ) __attribute__((format_arg(2))) ; /* { dg-error "format string argument is not a string type" } */ |
int s8 (NSString *dum, NSString *fmt1, ... ) __attribute__((format_arg(2))) ; /* { dg-error "function does not return string type" } */ |
|
char *s9 (int dum, char *fmt1, ... ) __attribute__((format_arg(2))) ; /* OK */ |
NSString *s10 (int dum, NSString *fmt1, ... ) __attribute__((format_arg(2))) ; /* OK */ |
|
void foo (void) |
{ |
s1 (@"this format not checked %d %s", 3, 4); |
printf("this one is checked %d %s", 3, 4, 5); /* { dg-warning "format '%s' expects argument of type 'char.', but argument 3 has type 'int'" } */ |
/* { dg-warning "too many arguments for format" "" { target *-*-* } 48 } */ |
printf(s9 (1, (char *)"and so is this %d %d %s" , 3, 4, "hm"), 5, 6, 12); /* { dg-warning "format '%s' expects argument of type 'char.', but argument 4 has type 'int'" } */ |
} |
/cxx-scope-1.mm
0,0 → 1,54
/* Handle C++ scoping ('::') operators in ObjC message receivers gracefully. */ |
/* Author: Ziemowit Laski <zlaski@apple.com> */ |
|
/* { dg-do run } */ |
/* { dg-xfail-run-if "Needs OBJC2 ABI" { *-*-darwin* && { lp64 && { ! objc2 } } } { "-fnext-runtime" } { "" } } */ |
#include "../objc-obj-c++-shared/TestsuiteObject.m" |
#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: TestsuiteObject { |
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; |
} |
|
/method-namespace-2.mm
0,0 → 1,25
/* Test that qualified type is resolved to its proper type. */ |
/* { dg-do compile } */ |
|
@interface Object |
{ |
int I[100]; |
} |
@end |
|
namespace HC |
{ |
|
struct Object |
{ |
void test(); |
}; |
|
} // namespace HC |
|
int main() |
{ |
HC::Object* object; |
object->test(); // Must compile with no error |
return 0; |
} |
/sync-2.mm
0,0 → 1,35
/* Make sure that @synchronized parses and a very basic test runs. */ |
/* { dg-options "-fobjc-exceptions -fgnu-runtime" } */ |
|
#include "../objc-obj-c++-shared/TestsuiteObject.h" |
|
int main (void) |
{ |
TestsuiteObject *a = [TestsuiteObject new]; |
TestsuiteObject *b = [TestsuiteObject new]; |
TestsuiteObject *c = [TestsuiteObject new]; |
|
/* This single-threaded test just checks that @synchronized() uses a |
recursive mutex, and that the runtime at least doesn't crash |
immediately upon finding it. |
*/ |
@synchronized (a) |
{ |
@synchronized (a) |
{ |
@synchronized (b) |
{ |
@synchronized (b) |
{ |
@synchronized (c) |
{ |
@synchronized (c) |
{ |
return 0; |
} |
} |
} |
} |
} |
} |
} |
/encode-10.mm
0,0 → 1,46
/* Test for @encode in templates. */ |
/* { dg-options "-lobjc" } */ |
/* { dg-do run } */ |
#include <string.h> |
#include <stdlib.h> |
|
template<typename T> |
const char *my_encode(int variant) |
{ |
const char *result; |
|
switch (variant) |
{ |
case 0: |
result = @encode(T); |
break; |
case 1: |
result = @encode(T*); |
break; |
case 2: |
result = @encode(const T*); |
break; |
default: |
result = @encode(int); |
break; |
} |
|
return result; |
} |
|
int main() |
{ |
if (strcmp (@encode(char), my_encode<char>(0))) |
abort (); |
|
if (strcmp (@encode(char *), my_encode<char>(1))) |
abort (); |
|
if (strcmp (@encode(const char *), my_encode<char>(2))) |
abort (); |
|
if (strcmp (@encode(int), my_encode<char>(3))) |
abort (); |
|
return 0; |
} |
/dg.exp
0,0 → 1,42
# GCC Objective-C++ testsuite that uses the `dg.exp' driver. |
# Copyright (C) 2004, 2007, 2010 Free Software Foundation, Inc. |
|
# This program is free software; you can redistribute it and/or modify |
# it under the terms of the GNU General Public License as published by |
# the Free Software Foundation; either version 3 of the License, or |
# (at your option) any later version. |
# |
# This program is distributed in the hope that it will be useful, |
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
# GNU General Public License for more details. |
# |
# You should have received a copy of the GNU General Public License |
# along with GCC; see the file COPYING3. If not see |
# <http://www.gnu.org/licenses/>. |
|
# 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 |
/try-catch-12.mm
0,0 → 1,51
/* Ensure that typeof()-typed variables inside the @try { } block that |
"inherit" their EH-volatileness from other variables in the stack frame |
do not trigger "discards qualifiers from target pointer type" warnings. */ |
|
/* { dg-options "-fobjc-exceptions" } */ |
/* { dg-do compile } */ |
|
typedef volatile int IOSharedLockData; |
|
@interface TestMyTests |
- (void) testSpoon; |
@end |
|
extern void some_func (int *); |
|
@implementation TestMyTests |
- (void) testSpoon { |
int i = 5; |
|
do { |
@try { |
typeof(i) j = 6; |
some_func (&j); |
} |
@catch (id exc) { |
@throw; |
} |
} while(0); |
|
do { |
@try { |
typeof(i) j = 7; |
some_func (&j); |
} |
@catch (id exc) { |
@throw; |
} |
} while(0); |
|
do { |
@try { |
typeof(i) j = 8; |
some_func (&j); |
} |
@catch (id exc) { |
@throw; |
} |
} while(0); |
|
} |
@end |
/template-6.mm
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); } |
/selector-1.mm
0,0 → 1,30
/* 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 } */ |
|
@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 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" } } */ |
/exceptions-1.mm
0,0 → 1,42
/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, November 2010. */ |
/* { dg-options "-fobjc-exceptions" } */ |
/* { dg-do compile } */ |
|
/* This test checks the syntax @catch (...) which catches any |
exceptions. At the moment, @catch (...) is identical to @catch (id |
exception). */ |
|
#include <objc/objc.h> |
|
@interface MyObject |
{ |
Class isa; |
} |
@end |
|
@implementation MyObject |
@end |
|
int test (id object) |
{ |
int i = 0; |
|
@try |
{ |
@throw object; |
} |
@catch (MyObject *o) |
{ |
i += 1; |
} |
@catch (...) |
{ |
i += 2; |
} |
@finally |
{ |
i += 4; |
} |
|
return i; |
} |
/syntax-error-6.mm
0,0 → 1,12
/* { dg-do compile } */ |
|
@interface NSButton |
- (int) state; |
@end |
|
void FOO() |
{ |
NSButton * mCopyAcrobatCB; |
|
[ [ mCopyAcrobatCB state ] == 0 ] != 1; /* { dg-error "objective\\-c\\+\\+" } */ |
} |
/gnu-api-2-sel.mm
0,0 → 1,209
/* Test the Modern GNU Objective-C Runtime API. |
|
This is test 'sel', covering all functions starting with 'sel'. */ |
|
/* { dg-do run } */ |
/* { dg-skip-if "No API#2 pre-Darwin9" { *-*-darwin[5-8]* } { "-fnext-runtime" } { "" } } */ |
|
/* To get the modern GNU Objective-C Runtime API, you include |
objc/runtime.h. */ |
#include <objc/runtime.h> |
#include <stdlib.h> |
#include <iostream> |
#include <cstring> |
|
@interface MyRootClass |
{ Class isa; } |
+ alloc; |
- init; |
+ initialize; |
@end |
|
@implementation MyRootClass |
+ alloc { return class_createInstance (self, 0); } |
- init { return self; } |
+ initialize { return self; } |
@end |
|
@protocol MyProtocol |
- (id) variable; |
@end |
|
@protocol MySecondProtocol |
- (id) setVariable: (id)value; |
@end |
|
@interface MySubClass : MyRootClass <MyProtocol> |
{ id variable_ivar; } |
- (void) setVariable: (id)value; |
- (id) variable; |
- (void) method; |
@end |
|
@implementation MySubClass |
- (void) setVariable: (id)value { variable_ivar = value; } |
- (id) variable { return variable_ivar; } |
- (void) method { return; } |
@end |
|
@interface ClassA : MyRootClass |
- (id) conflictingSelectorMethod; |
@end |
|
@implementation ClassA |
- (id) conflictingSelectorMethod { return nil; } |
@end |
|
@interface ClassB : MyRootClass |
- (void) conflictingSelectorMethod; |
@end |
|
@implementation ClassB |
- (void) conflictingSelectorMethod { return; } |
@end |
|
int main () |
{ |
/* Functions are tested in alphabetical order. */ |
|
#ifdef __GNU_LIBOBJC__ |
std::cout << "Testing sel_copyTypedSelectorList ()...\n"; |
{ |
unsigned int count; |
SEL * list = sel_copyTypedSelectorList ("method", &count); |
|
/* There should only be two, since 'method' is referenced twice, |
once with types and once without (in this very test). */ |
if (count != 2) |
abort (); |
|
/* Check that both selectors are not-NULL, and have the correct |
name. We use @selector() here, which wouldn't really be |
needed, just to register a second, untyped selector with name |
'method'. */ |
if (std::strcmp (sel_getName (list[0]), sel_getName (@selector (method))) != 0) |
abort (); |
|
if (std::strcmp (sel_getName (list[1]), sel_getName (@selector (method))) != 0) |
abort (); |
|
if (list[2] != NULL) |
abort (); |
} |
#endif |
|
std::cout << "Testing sel_getName () ...\n"; |
{ |
if (std::strcmp (sel_getName (@selector (variable)), "variable") != 0) |
abort (); |
|
if (std::strcmp (sel_getName (NULL), "<null selector>") != 0) |
abort (); |
} |
|
#ifdef __GNU_LIBOBJC__ |
std::cout << "Testing sel_getTypeEncoding () ...\n"; |
{ |
/* Get a selector from a real class, so it has interesting |
types. */ |
Method method = class_getInstanceMethod (objc_getClass ("MySubClass"), |
@selector (variable)); |
|
if (std::strcmp (sel_getTypeEncoding (method_getName (method)), |
method_getTypeEncoding (method)) != 0) |
abort (); |
|
if (sel_getTypeEncoding (NULL) != NULL) |
abort (); |
} |
#endif |
|
#ifdef __GNU_LIBOBJC__ |
std::cout << "Testing sel_getTypedSelector () ...\n"; |
{ |
/* First try with a selector where we know that a typed one has |
been registered. */ |
SEL selector = sel_getTypedSelector ("variable"); |
|
if (selector == NULL) |
abort (); |
|
if (sel_getTypeEncoding (selector) == NULL) |
abort (); |
|
/* Now try a selector which was never registered. */ |
selector = sel_getTypedSelector ("not_registered"); |
|
if (selector != NULL) |
abort (); |
|
/* Now try registering a selector with no types. The following |
line is just a way to have an unused '@selector()' expression |
without the compiler complaining. */ |
if (@selector (registered_with_no_types) == NULL) |
abort (); |
|
/* Try getting it. Nothing should be returned because it is |
untyped. */ |
selector = sel_getTypedSelector ("registered_with_no_types"); |
|
if (selector != NULL) |
abort (); |
|
/* Now try a selector with multiple, conflicting types. NULL |
should be returned. */ |
selector = sel_getTypedSelector ("conflictingSelectorMethod"); |
|
if (selector != NULL) |
abort (); |
} |
#endif |
|
std::cout << "Testing sel_getUid () ...\n"; |
{ |
if (std::strcmp (sel_getName (sel_getUid ("myMethod")), "myMethod") != 0) |
abort (); |
|
if (sel_getUid (NULL) != NULL) |
abort (); |
} |
|
std::cout << "Testing sel_isEqual () ...\n"; |
{ |
if (! sel_isEqual (@selector (setVariable:), @selector (setVariable:))) |
abort (); |
} |
|
std::cout << "Testing sel_registerName () ...\n"; |
{ |
if (std::strcmp (sel_getName (sel_registerName ("myMethod")), "myMethod") != 0) |
abort (); |
|
if (sel_registerName (NULL) != NULL) |
abort (); |
} |
|
#ifdef __GNU_LIBOBJC__ |
std::cout << "Testing set_registerTypedName () ...\n"; |
{ |
const char *types = method_getTypeEncoding (class_getInstanceMethod |
(objc_getClass ("MySubClass"), |
@selector (variable))); |
SEL selector = sel_registerTypedName ("aMethod", types); |
|
if (std::strcmp (sel_getName (selector), "aMethod") != 0) |
abort (); |
|
if (std::strcmp (sel_getTypeEncoding (selector), types) != 0) |
abort (); |
|
if (sel_registerTypedName (NULL, NULL) != NULL) |
abort (); |
|
if (sel_registerTypedName (NULL, types) != NULL) |
abort (); |
} |
#endif |
|
return (0); |
} |
/comp-types-12.mm
0,0 → 1,13
/* { dg-do compile } */ |
#include "../objc-obj-c++-shared/TestsuiteObject.h" |
|
@interface Derived: TestsuiteObject |
@end |
|
extern TestsuiteObject* foo(void); |
static Derived *test(void) |
{ |
Derived *m = foo(); /* { dg-warning "initialization from distinct Objective\\-C type" } */ |
|
return m; |
} |
/class-extension-4.mm
0,0 → 1,19
/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, December 2010. */ |
/* { dg-do compile } */ |
|
/* This test tests you can not declare a class extension after the class @implementation. */ |
|
#include <objc/objc.h> |
|
@interface MyObject |
{ |
Class isa; |
} |
@end |
|
@implementation MyObject |
@end |
|
@interface MyObject () /* { dg-error "class extension for class .MyObject. declared after its ..implementation." } */ |
- (void) test; |
@end |
/bitfield-4.mm
0,0 → 1,56
/* Check if the @defs() construct preserves the correct |
layout of bitfields. */ |
/* Contributed by Ziemowit Laski <zlaski@apple.com>. */ |
/* { dg-do run } */ |
/* { dg-options "-Wpadded" } */ |
|
#include "../objc-obj-c++-shared/TestsuiteObject.m" |
|
#include <stdlib.h> |
#include <string.h> |
|
#define CHECK_IF(expr) if(!(expr)) abort() |
|
enum Enum { one, two, three, four }; |
|
@interface Base: TestsuiteObject { |
unsigned a: 2; |
int b: 3; |
enum Enum c: 4; |
unsigned d: 5; |
} /* { dg-warning "padding struct size to alignment boundary" } */ |
@end |
|
@interface Derived: Base { |
signed e: 5; |
int f: 4; |
enum Enum g: 3; |
} |
@end |
|
/* Note that the semicolon after @defs(...) is optional. */ |
|
typedef struct { @defs(Base) } Base_t; /* { dg-warning "padding struct size to alignment boundary" } */ |
typedef struct { @defs(Derived); } Derived_t; |
|
int main(void) |
{ |
CHECK_IF(sizeof(Base_t) == sizeof(Base)); |
CHECK_IF(sizeof(Derived_t) == sizeof(Derived)); |
|
#ifdef __NEXT_RUNTIME__ |
CHECK_IF(!strcmp(@encode(Base), "{Base=#b2b3b4b5}")); |
CHECK_IF(!strcmp(@encode(Derived), "{Derived=#b2b3b4b5b5b4b3}")); |
|
CHECK_IF(!strcmp(@encode(Base_t), "{?=#b2b3b4b5}")); |
CHECK_IF(!strcmp(@encode(Derived_t), "{?=#b2b3b4b5b5b4b3}")); |
#endif /* __NEXT_RUNTIME__ */ |
|
return 0; |
} |
|
/* { dg-prune-output "In file included from" } Ignore this message. */ |
/* { dg-bogus "padding struct to align" "PR23610" { target *-*-* } 0 } */ |
|
/* { dg-bogus "padding struct size" "PR23610" { xfail lp64 } 28 } */ |
/* { dg-bogus "padding struct size" "PR23610" { xfail lp64 } 34 } */ |
/method-7.mm
0,0 → 1,22
/* 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 *-*-* } 11 } */ |
[NotAClass nonexistent_method]; /* { dg-error ".NotAClass. is not an Objective\\-C class name or alias" } */ |
[u nonexistent_method]; /* { dg-warning ".interface of class .UnderSpecified. not found" } */ |
/* { dg-warning "no .\\-nonexistent_method. method found" "" { target *-*-* } 14 } */ |
[UnderSpecified nonexistent_method]; /* { dg-warning ".interface of class .UnderSpecified. not found" } */ |
/* { dg-warning "no .\\+nonexistent_method. method found" "" { target *-*-* } 16 } */ |
} |
|
/* { 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 } */ |
/lto/trivial-1_0.mm
0,0 → 1,43
/* { dg-lto-do run } */ |
/* { dg-skip-if "Needs OBJC2 ABI" { "*-*-darwin*" && lp64 } { "*" } { "" } } */ |
extern "C" { |
extern int printf (char *,...) ; |
extern void abort (void) ; |
} |
|
typedef struct objc_class *Class; |
|
struct objc_class { |
Class isa; |
/* other stuff... */ |
} ; |
|
@interface myRootObject { |
@public |
Class isa; |
} |
+initialize; |
+(Class)class; |
|
@end |
|
@implementation myRootObject |
+initialize { |
return self; |
} |
|
+(Class)class { |
return (Class)self; |
} |
|
@end |
|
int main(void) |
{ |
Class cl = [myRootObject class]; |
if (cl != (Class)0) { |
printf((char *)"trivial OK\n"); |
return 0; |
} |
abort () ; |
} |
/lto/lto.exp
0,0 → 1,84
# Copyright (C) 2010 Free Software Foundation, Inc. |
|
# This program is free software; you can redistribute it and/or modify |
# it under the terms of the GNU General Public License as published by |
# the Free Software Foundation; either version 3 of the License, or |
# (at your option) any later version. |
# |
# This program is distributed in the hope that it will be useful, |
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
# GNU General Public License for more details. |
# |
# You should have received a copy of the GNU General Public License |
# along with GCC; see the file COPYING3. If not see |
# <http://www.gnu.org/licenses/>. |
# |
# Based on gcc/testsuite/gcc.dg/lto/lto.exp. |
|
# Test link-time optimization across multiple files. |
# |
# Programs are broken into multiple files. Each one is compiled |
# separately with LTO information. The final executable is generated |
# by collecting all the generated object files using regular LTO or WHOPR. |
|
if $tracelevel then { |
strace $tracelevel |
} |
|
# Load procedures from common libraries. |
load_lib standard.exp |
load_lib obj-c++-dg.exp |
|
# Load the language-independent compabibility support procedures. |
load_lib lto.exp |
|
# If LTO has not been enabled, bail. |
if { ![check_effective_target_lto] } { |
return |
} |
|
global LTO_OPTIONS |
|
set LTO_OPTIONS [list \ |
{-O0 -flto -fgnu-runtime} \ |
{-O2 -flto -fgnu-runtime} \ |
{-O0 -flto -flto-partition=none -fgnu-runtime} \ |
{-O2 -flto -flto-partition=none -fgnu-runtime} \ |
] |
|
obj-c++_init |
lto_init no-mathlib |
|
# Define an identifier for use with this suite to avoid name conflicts |
# with other lto tests running at the same time. |
set sid "obj_cpp_lto" |
set tests [lsort [glob -nocomplain $srcdir/$subdir/*_0.mm]] |
|
# Main loop. |
foreach src $tests { |
# If we're only testing specific files and this isn't one of them, skip it. |
if ![runtest_file_p $runtests $src] then { |
continue |
} |
lto-execute $src $sid |
} |
|
# darwin targets can also run code with the NeXT runtime. |
if [istarget "*-*-darwin*" ] { |
set LTO_OPTIONS [list \ |
{-O0 -flto -fnext-runtime} \ |
{-O2 -flto -fnext-runtime} \ |
{-O0 -flto -flto-partition=none -fnext-runtime} \ |
{-O2 -flto -flto-partition=none -fnext-runtime} \ |
] |
foreach src $tests { |
# If we're only testing specific files and this isn't one of them, skip it. |
if ![runtest_file_p $runtests $src] then { |
continue |
} |
lto-execute $src $sid |
} |
} |
|
lto_finish |
/pr23709.mm
0,0 → 1,12
/* { dg-do compile } */ |
|
@interface A |
+(void)method: (int)parameter {} /* { dg-error "expected" } */ |
@end |
|
@implementation A |
+(void)method: (int)parameter |
{ |
*parameter; /* { dg-error "invalid type argument" } */ |
} |
@end |
/tls/trivial.m
0,0 → 1,3
// { dg-require-effective-target tls } |
|
__thread int i; |
/tls/init-1.mm
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; |
/tls/diag-1.mm
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; |
} |
/tls/init-2.mm
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 */ |
/tls/diag-2.mm
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'" } */ |
}; |
/tls/diag-3.mm
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; |
/tls/static-1.mm
0,0 → 1,31
// { dg-do run } |
// { dg-require-effective-target tls } |
// { dg-add-options 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; |
} |
/tls/tls.exp
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 |
/tls/diag-4.mm
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" } */ |
} |
/tls/diag-5.mm
0,0 → 1,4
/* __thread specifiers on empty declarations. */ |
/* { dg-require-effective-target tls } */ |
|
__thread struct foo; /* { dg-error "qualifiers can only be specified for objects and functions" } */ |
/tls/static-1a.mm
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; |
} |
/encode-3.mm
0,0 → 1,60
/* { dg-do run } */ |
|
extern "C" { |
extern void abort (void); |
extern int strcmp (const char *, const char *); |
} |
|
template <class T> |
struct Vec { |
T x, y; |
long z; |
long long zz; |
}; |
|
typedef struct { |
float fscalar; |
double dv[10]; |
int iscalar; |
long z; |
long long zz; |
Vec<const signed char> cv; |
} anonymous; |
|
//Vec<double> dd; |
const char *enc = @encode(Vec<float>); |
const char *enc2 = @encode(Vec<double>); |
const char *enc3 = @encode(anonymous); |
|
#ifdef __LP64__ |
#define L "q" |
#else |
#define L "l" |
#endif |
|
/* Darwin (at least, as of XCode 3.2.3/Darwin10) does not encode the read-only |
attribute on the type. Arguably, this is a bug, but we are compatible |
with this when -fnext-runtime is selected. */ |
#ifdef __NEXT_RUNTIME__ |
#define E3 "{?=f[10d]i" L "q{Vec<const signed char>=cc" L "q}}" |
#else |
#define E3 "{?=f[10d]i" L "q{Vec<const signed char>=rcrc" L "q}}" |
#endif |
|
int main(void) { |
const char *encode = @encode(long); |
|
if (strcmp (encode, L)) |
abort (); |
|
if (strcmp (enc, (const char *)"{Vec<float>=ff" L "q}")) |
abort (); |
|
if (strcmp (enc2, (const char *)"{Vec<double>=dd" L "q}")) |
abort (); |
|
if (strcmp (enc3, (const char *) E3)) |
abort (); |
|
return 0; |
} |
/pr48187.mm
0,0 → 1,39
/* { dg-do compile } */ |
|
@interface A |
{ |
] /* { dg-error "xpected" } */ |
} |
@end |
|
@interface B |
{ |
]; /* { dg-error "xpected" } */ |
} |
@end |
|
@interface C |
{ |
]; /* { dg-error "xpected" } */ |
int x; |
} |
@end |
|
@interface D |
{ |
( |
} /* { dg-error "xpected" } */ |
@end |
|
@interface E |
{ |
(; /* { dg-error "xpected" } */ |
} |
@end |
|
@interface F |
{ |
(; /* { dg-error "xpected" } */ |
int x; |
} |
@end |
/warn7.mm
0,0 → 1,10
// PR c++/50757 |
// { dg-options "-Wformat -Wno-nonnull" } |
|
extern void *f (void *__s) __attribute__ ((__nonnull__ (1))); |
|
int main() |
{ |
void* const s = 0; |
f(s); |
} |
/method-22.mm
0,0 → 1,43
/* Ensure that overload resolution does not produce warnings as |
side-effects. */ |
/* { dg-do run } */ |
/* { dg-xfail-run-if "Needs OBJC2 ABI" { *-*-darwin* && { lp64 && { ! objc2 } } } { "-fnext-runtime" } { "" } } */ |
|
#include "../objc-obj-c++-shared/TestsuiteObject.m" |
#include <stdlib.h> |
|
#define CHECK_IF(E) if(!(E)) abort () |
|
@interface MyCursor: TestsuiteObject |
+ (MyCursor *)crosshairCursor; |
@end |
|
@class MyImage; |
|
class A { |
public: |
A(); |
|
int foo(MyImage *); |
int foo(MyCursor *); |
}; |
|
A::A() {} |
int A::foo(MyCursor * c) { return 17; } |
int A::foo(MyImage * i) { return 29; } |
|
@implementation MyCursor |
+ (MyCursor *)crosshairCursor { |
return self; |
} |
@end |
|
int main(void) { |
A a; |
|
int r = a.foo([MyCursor crosshairCursor]); |
|
CHECK_IF (r == 17); |
return 0; |
} |
|
/proto-lossage-7.mm
0,0 → 1,28
/* Check that typedefs of ObjC classes preserve |
any @protocol qualifiers. */ |
/* { dg-do compile } */ |
#include <objc/Object.h> |
|
@protocol CanDoStuff; |
|
typedef Object<CanDoStuff> CanDoStuffType; |
typedef Object<CanDoStuff> *CanDoStuffTypePtr; |
|
@protocol CanDoStuff |
- (int) dostuff; |
@end |
|
@protocol MoreStuff |
- (int) morestuff; |
@end |
|
int main(void) |
{ |
CanDoStuffTypePtr dice = nil; |
CanDoStuffType *nodice = nil; |
int count; |
count = [dice dostuff]; |
count = [nodice dostuff]; |
return 0; |
} |
|
/gnu-api-2-class.mm
0,0 → 1,498
/* Test the Modern GNU Objective-C Runtime API. |
|
This is test 'class', covering all functions starting with 'class'. |
Tests calling the functions with a meta class as argument are covered |
in the separate file, gnu-api-2-class-meta.mm. */ |
|
/* { dg-do run } */ |
/* { dg-skip-if "No API#2 pre-Darwin9" { *-*-darwin[5-8]* } { "-fnext-runtime" } { "" } } */ |
/* { dg-xfail-run-if "Needs OBJC2 ABI" { *-*-darwin* && { lp64 && { ! objc2 } } } { "-fnext-runtime" } { "" } } */ |
|
/* To get the modern GNU Objective-C Runtime API, you include |
objc/runtime.h. */ |
#include <objc/runtime.h> |
#include <stdlib.h> |
#include <iostream> |
#include <cstring> |
|
@interface MyRootClass |
{ Class isa; } |
+ alloc; |
- init; |
+ initialize; |
@end |
|
@implementation MyRootClass |
+ alloc { return class_createInstance (self, 0); } |
- init { return self; } |
+ initialize { return self; } |
@end |
|
@protocol MyProtocol |
- (id) variable; |
@end |
|
@protocol MySecondProtocol |
- (id) setVariable: (id)value; |
@end |
|
@interface MySubClass : MyRootClass <MyProtocol> |
{ id variable_ivar; } |
- (void) setVariable: (id)value; |
- (id) variable; |
@end |
|
@implementation MySubClass |
- (void) setVariable: (id)value { variable_ivar = value; } |
- (id) variable { return variable_ivar; } |
@end |
|
@interface MyOtherSubClass : MySubClass |
@end |
|
@implementation MyOtherSubClass |
@end |
|
@interface DifferentClass : MyRootClass |
- (id) myClass; |
- (id) self; |
@end |
|
@implementation DifferentClass |
- (id) myClass { return object_getClass (self); } |
- (id) self { return self; } |
@end |
|
@interface MySubClass (MySelf) |
- (id) mySelf; |
@end |
|
/* Hack to calculate the log2 of a byte alignment. */ |
unsigned char |
log_2_of (unsigned int x) |
{ |
unsigned char result = 0; |
|
/* We count how many times we need to divide by 2 before we reach 1. |
This algorithm is good enough for the small numbers (such as 8, |
16 or 64) that we have to deal with. */ |
while (x > 1) |
{ |
x = x / 2; |
result++; |
} |
|
return result; |
} |
|
int main () |
{ |
/* Functions are tested in alphabetical order. */ |
|
std::cout << "Testing class_addIvar ()...\n"; |
{ |
Class new_class = objc_allocateClassPair (objc_getClass ("MySubClass"), "MySubSubClass", 0); |
|
if (new_class == Nil) |
abort (); |
|
if (! class_addIvar (new_class, "variable2_ivar", sizeof (id), |
log_2_of (__alignof__ (id)), @encode (id))) |
abort (); |
|
if (! class_addIvar (new_class, "variable3_ivar", sizeof (unsigned char), |
log_2_of (__alignof__ (unsigned char)), @encode (unsigned char))) |
abort (); |
|
if (! class_addIvar (new_class, "variable4_ivar", sizeof (unsigned long), |
log_2_of (__alignof__ (unsigned long)), @encode (unsigned long))) |
abort (); |
|
objc_registerClassPair (new_class); |
|
{ |
MySubClass *o = [[(Class)objc_getClass ("MySubSubClass") alloc] init]; |
Ivar variable2 = class_getInstanceVariable (objc_getClass ("MySubSubClass"), "variable2_ivar"); |
Ivar variable3 = class_getInstanceVariable (objc_getClass ("MySubSubClass"), "variable3_ivar"); |
Ivar variable4 = class_getInstanceVariable (objc_getClass ("MySubSubClass"), "variable4_ivar"); |
|
if (variable2 == NULL || variable3 == NULL || variable4 == NULL) |
abort (); |
|
if (std::strcmp (ivar_getName (variable2), "variable2_ivar") != 0) |
abort (); |
|
if (std::strcmp (ivar_getName (variable3), "variable3_ivar") != 0) |
abort (); |
|
if (std::strcmp (ivar_getName (variable4), "variable4_ivar") != 0) |
abort (); |
|
{ |
unsigned char *var3 = (unsigned char *)((char *)o + ivar_getOffset (variable3)); |
unsigned long *var4 = (unsigned long *)((char *)o + ivar_getOffset (variable4)); |
|
object_setIvar (o, variable2, new_class); |
*var3 = 230; |
*var4 = 89000L; |
|
if (object_getIvar (o, variable2) != new_class) |
abort (); |
|
if (*var3 != 230) |
abort (); |
|
if (*var4 != 89000L) |
abort (); |
} |
} |
} |
|
std::cout << "Testing class_addMethod ()...\n"; |
{ |
Class new_class = objc_allocateClassPair (objc_getClass ("MyRootClass"), "MySubClass2", 0); |
Method method1 = class_getInstanceMethod (objc_getClass ("MySubClass"), @selector (setVariable:)); |
Method method2 = class_getInstanceMethod (objc_getClass ("MySubClass"), @selector (variable)); |
|
if (new_class == Nil) |
abort (); |
|
if (! class_addIvar (new_class, "variable_ivar", sizeof (id), |
log_2_of (__alignof__ (id)), @encode (id))) |
abort (); |
|
if (! class_addMethod (new_class, @selector (setVariable:), method_getImplementation (method1), |
method_getTypeEncoding (method1))) |
abort (); |
|
if (! class_addMethod (new_class, @selector (variable), method_getImplementation (method2), |
method_getTypeEncoding (method2))) |
abort (); |
|
/* Test that if the method already exists in the class, |
class_addMethod() returns NO. */ |
if (class_addMethod (new_class, @selector (variable), method_getImplementation (method2), |
method_getTypeEncoding (method2))) |
abort (); |
|
objc_registerClassPair (new_class); |
|
/* Now, MySubClass2 is basically the same as MySubClass! We'll |
use the variable and setVariable: methods on it. */ |
{ |
MySubClass *o = (MySubClass *)[[(Class)objc_getClass ("MySubClass2") alloc] init]; |
|
[o setVariable: o]; |
|
if ([o variable] != o) |
abort (); |
} |
|
/* Now, try that if you take an existing class and try to add an |
already existing method, class_addMethod returns NO. This is |
subtly different from before, when 'new_class' was still in |
construction. Now it's a real class and the libobjc internals |
differ between the two cases. */ |
if (class_addMethod (new_class, @selector (variable), method_getImplementation (method2), |
method_getTypeEncoding (method2))) |
abort (); |
} |
|
std::cout << "Testing class_addProtocol ()...\n"; |
{ |
if (!class_addProtocol (objc_getClass ("MySubClass"), @protocol (MySecondProtocol))) |
abort (); |
|
if (!class_conformsToProtocol (objc_getClass ("MySubClass"), @protocol (MyProtocol))) |
abort (); |
|
if (!class_conformsToProtocol (objc_getClass ("MySubClass"), @protocol (MySecondProtocol))) |
abort (); |
} |
|
std::cout << "Testing class_conformsToProtocol ()...\n"; |
{ |
if (class_conformsToProtocol (objc_getClass ("MyRootClass"), @protocol (MyProtocol))) |
abort (); |
|
if (!class_conformsToProtocol (objc_getClass ("MySubClass"), @protocol (MyProtocol))) |
abort (); |
|
/* Test that class_conformsToProtocol checks the class, but not |
superclasses. */ |
if (class_conformsToProtocol (objc_getClass ("MyOtherSubClass"), @protocol (MyProtocol))) |
abort (); |
} |
|
std::cout << "Testing class_copyIvarList ()...\n"; |
{ |
unsigned int count; |
Ivar * list = class_copyIvarList (objc_getClass ("MySubClass"), &count); |
|
if (count != 1) |
abort (); |
|
if (std::strcmp (ivar_getName (list[0]), "variable_ivar") != 0) |
abort (); |
|
if (list[1] != NULL) |
abort (); |
} |
|
std::cout << "Testing class_copyMethodList ()...\n"; |
{ |
unsigned int count; |
Method * list = class_copyMethodList (objc_getClass ("MySubClass"), &count); |
|
if (count != 2) |
abort (); |
|
if (! ((std::strcmp (sel_getName (method_getName (list[0])), "variable") == 0 |
&& std::strcmp (sel_getName (method_getName (list[1])), "setVariable:") == 0) |
|| (std::strcmp (sel_getName (method_getName (list[0])), "setVariable:") == 0 |
&& std::strcmp (sel_getName (method_getName (list[1])), "variable") == 0))) |
abort (); |
|
if (list[2] != NULL) |
abort (); |
} |
|
/* TODO: Test new ABI (when available). */ |
std::cout << "Testing class_copyPropertyList ()...\n"; |
{ |
unsigned int count; |
objc_property_t * list = class_copyPropertyList (objc_getClass ("MySubClass"), &count); |
|
if (count != 0 || list != NULL) |
abort (); |
} |
|
std::cout << "Testing class_copyProtocolList ()...\n"; |
{ |
unsigned int count; |
Protocol ** list = class_copyProtocolList (objc_getClass ("MySubClass"), &count); |
|
/* Remember that we added MySecondProtocol in the test above. */ |
if (count != 2) |
abort (); |
|
if (! ((std::strcmp (protocol_getName (list[0]), "MyProtocol") == 0 |
&& std::strcmp (protocol_getName (list[1]), "MySecondProtocol") == 0) |
|| (std::strcmp (protocol_getName (list[0]), "MySecondProtocol") == 0 |
&& std::strcmp (protocol_getName (list[1]), "MyProtocol") == 0))) |
abort (); |
|
if (list[2] != NULL) |
abort (); |
} |
|
std::cout << "Testing class_createInstance ()...\n"; |
{ |
MySubClass *object = [[MySubClass alloc] init]; |
|
[object setVariable: object]; |
if ([object variable] != object) |
abort (); |
} |
|
std::cout << "Testing class_getClassMethod ()...\n"; |
{ |
Method method = class_getClassMethod (objc_getClass ("MySubClass"), |
@selector(alloc)); |
|
if (method == NULL) |
abort (); |
|
if (std::strcmp (sel_getName (method_getName (method)), "alloc") != 0) |
abort (); |
|
if (class_getClassMethod (objc_getClass ("MySubClass"), |
@selector(variable))) |
abort (); |
} |
|
std::cout << "Testing class_getClassVariable ()...\n"; |
{ |
if (class_getClassVariable (objc_getClass ("MySubClass"), "variable_ivar")) |
abort (); |
} |
|
std::cout << "Testing class_getInstanceMethod ()...\n"; |
{ |
Method method = class_getInstanceMethod (objc_getClass ("MySubClass"), |
@selector(variable)); |
|
if (method == NULL) |
abort (); |
|
if (std::strcmp (sel_getName (method_getName (method)), "variable") != 0) |
abort (); |
|
if (class_getInstanceMethod (objc_getClass ("MySubClass"), |
@selector(alloc))) |
abort (); |
} |
|
std::cout << "Testing class_getInstanceSize ()...\n"; |
{ |
if (class_getInstanceSize (objc_getClass ("MyRootClass")) != sizeof (struct objc_object)) |
abort (); |
} |
|
std::cout << "Testing class_getInstanceVariable ()...\n"; |
{ |
Ivar variable = class_getInstanceVariable (objc_getClass ("MySubClass"), "variable_ivar"); |
|
if (variable == NULL) |
abort (); |
|
if (std::strcmp (ivar_getName (variable), "variable_ivar") != 0) |
abort (); |
|
if (class_getInstanceVariable (objc_getClass ("MySubClass"), "variable_ivar_no")) |
abort (); |
} |
|
std::cout << "Testing class_getIvarLayout ()...\n"; |
{ |
if (class_getIvarLayout (objc_getClass ("MyRootClass")) != NULL) |
abort (); |
} |
|
std::cout << "Testing class_getMethodImplementation ()...\n"; |
{ |
MySubClass *object = [[MySubClass alloc] init]; |
IMP imp = class_getMethodImplementation (objc_getClass ("MySubClass"), |
@selector(variable)); |
|
if (imp == NULL) |
abort (); |
|
[object setVariable: object]; |
|
if ((*imp)(object, @selector(variable)) != object) |
abort (); |
} |
|
/* This function does not exist with the GNU runtime. */ |
/* std::cout << "Testing class_getMethodImplementation_stret ()...\n"; */ |
|
std::cout << "Testing class_getName ()...\n"; |
{ |
if (std::strcmp (class_getName (objc_getClass ("MyRootClass")), |
"MyRootClass") != 0) |
abort (); |
} |
|
/* TODO: Test new ABI (when available). */ |
std::cout << "Testing class_getProperty ()...\n"; |
{ |
if (class_getProperty (objc_getClass ("MyRootClass"), "property") != NULL) |
abort (); |
} |
|
std::cout << "Testing class_getSuperclass ()...\n"; |
{ |
MySubClass *object = [[MySubClass alloc] init]; |
if (class_getSuperclass (object_getClass (object)) != objc_getClass ("MyRootClass")) |
abort (); |
|
/* Test that it works on a newly created, but not registered, class. */ |
{ |
Class new_class = objc_allocateClassPair (objc_getClass ("MyRootClass"), "MySubClass3", 0); |
|
if (class_getSuperclass (new_class) != objc_getClass ("MyRootClass")) |
abort (); |
} |
} |
|
std::cout << "Testing class_getVersion ()...\n"; |
{ |
if (class_getVersion (objc_getClass ("MySubClass")) != 0) |
abort (); |
} |
|
std::cout << "Testing class_getWeakIvarLayout ()...\n"; |
{ |
if (class_getWeakIvarLayout (objc_getClass ("MyRootClass")) != NULL) |
abort (); |
} |
|
std::cout << "Testing class_isMetaClass ()...\n"; |
{ |
MySubClass *object = [[MySubClass alloc] init]; |
if (class_isMetaClass (object_getClass (object)) |
|| ! class_isMetaClass (object_getClass (object_getClass (object)))) |
abort (); |
} |
|
std::cout << "Testing class_replaceMethod ()...\n"; |
{ |
Method new_method = class_getInstanceMethod (objc_getClass ("DifferentClass"), |
@selector (myClass)); |
Method old_method = class_getInstanceMethod (objc_getClass ("MySubClass"), |
@selector (variable)); |
const char *new_types = method_getTypeEncoding (new_method); |
IMP new_imp = method_getImplementation (new_method); |
const char *old_types = method_getTypeEncoding (old_method); |
IMP old_imp = class_replaceMethod (objc_getClass ("MySubClass"), @selector (variable), |
method_getImplementation (new_method), |
method_getTypeEncoding (new_method)); |
MySubClass *o = [[MySubClass alloc] init]; |
|
[o setVariable: o]; |
|
/* Try the new method implementation. */ |
if ([o variable] != objc_getClass ("MySubClass")) |
abort (); |
|
/* Put the original method back. */ |
class_replaceMethod (objc_getClass ("MySubClass"), @selector (variable), |
old_imp, old_types); |
|
/* Test it's back to what it was. */ |
if ([o variable] != o) |
abort (); |
|
{ |
DifferentClass *o = [[DifferentClass alloc] init]; |
|
/* Finally, try adding a new method. */ |
class_replaceMethod (objc_getClass ("DifferentClass"), @selector (mySelf), |
new_imp, new_types); |
|
if ([(MySubClass*)o mySelf] != objc_getClass ("DifferentClass")) |
abort (); |
} |
} |
|
std::cout << "Testing class_respondsToSelector ()...\n"; |
{ |
if (! class_respondsToSelector (objc_getClass ("MySubClass"), @selector(setVariable:))) |
abort (); |
|
if (class_respondsToSelector (objc_getClass ("MyRootClass"), @selector(setVariable:))) |
abort (); |
} |
|
/* This is not really implemented with the GNU runtime. */ |
/* std::cout << "Testing class_setIvarLayout ()...\n"; */ |
|
std::cout << "Testing class_setVersion ()...\n"; |
{ |
class_setVersion (objc_getClass ("MySubClass"), 45); |
|
if (class_getVersion (objc_getClass ("MySubClass")) != 45) |
abort (); |
|
class_setVersion (objc_getClass ("MySubClass"), 46); |
|
if (class_getVersion (objc_getClass ("MySubClass")) != 46) |
abort (); |
} |
|
/* This is not really implemented with the GNU runtime. */ |
/* std::cout << "Testing class_setWeakIvarLayout ()...\n"; */ |
|
return (0); |
} |
/try-catch-8.mm
0,0 → 1,27
/* Test for graceful compilation of @synchronized statements. */ |
|
/* { dg-do compile } */ |
/* { dg-options "-fobjc-exceptions" } */ |
|
#include "../objc-obj-c++-shared/TestsuiteObject.h" |
|
@interface Derived: TestsuiteObject |
- (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 |
/comp-types-6.mm
0,0 → 1,33
/* Test assignments and comparisons involving `one-off' protocols. */ |
/* Author: Nicola Pero <nicola@brainstorm.co.uk>. */ |
/* { dg-do compile } */ |
|
#include <objc/objc.h> |
|
@protocol MyProtocol |
- (void) method; |
@end |
|
@interface MyClass |
@end |
|
int main() |
{ |
id obj = nil; |
id <MyProtocol> obj_p = nil; |
MyClass<MyProtocol> *obj_cp = nil; |
|
obj_cp = obj; /* Ok */ |
obj = obj_cp; /* Ok */ |
|
obj_cp = obj_p; /* Ok */ |
obj_p = obj_cp; /* Ok */ |
|
if (obj_cp == obj) ; /* Ok */ |
if (obj == obj_cp) ; /* Ok */ |
|
if (obj_cp == obj_p) ; /* Ok */ |
if (obj_p == obj_cp) ; /* Ok */ |
|
return 0; |
} |
/method-16.mm
0,0 → 1,34
|
/* Ensure that we indeed cannot obtain the value of a message send |
if the chosen method signature returns 'void'. There used to |
exist a cheesy hack that allowed it. While at it, check that |
the first lexically occurring method signature gets picked |
when sending messages to 'id'. */ |
/* Contributed by Ziemowit Laski <zlaski@apple.com> */ |
/* { dg-do compile } */ |
|
#include <objc/objc.h> |
|
@interface Object1 |
- (void)initWithData:(Object1 *)data; |
@end |
|
@interface Object2 |
- (id)initWithData:(Object1 *)data; |
@end |
|
@interface Object3 |
- (id)initWithData:(Object2 *)data; |
@end |
|
void foo(void) { |
id obj1, obj2 = 0; |
obj2 = [obj1 initWithData: obj2]; |
/* { dg-warning "multiple methods named .\\-initWithData:. found" "" { target *-*-* } 26 } */ |
/* { dg-message "using .\\-\\(void\\)initWithData:\\(Object1 \\*\\)data." "" { target *-*-* } 13 } */ |
/* { dg-message "also found .\\-\\(id\\)initWithData:\\(Object1 \\*\\)data." "" { target *-*-* } 17 } */ |
/* { dg-message "also found .\\-\\(id\\)initWithData:\\(Object2 \\*\\)data." "" { target *-*-* } 21 } */ |
|
/* The following error is a consequence of picking the "wrong" method signature. */ |
/* { dg-error "void value not ignored as it ought to be" "" { target *-*-* } 26 } */ |
} |
/template-1.mm
0,0 → 1,50
/* Test for using ObjC classes as C++ template parameters. */ |
/* Author: Ziemowit Laski <zlaski@apple.com>. */ |
|
/* { dg-do run } */ |
/* { dg-xfail-run-if "Needs OBJC2 ABI" { *-*-darwin* && { lp64 && { ! objc2 } } } { "-fnext-runtime" } { "" } } */ |
#include "../objc-obj-c++-shared/TestsuiteObject.m" |
#include <stdlib.h> |
|
#define CHECK_IF(expr) if(!(expr)) abort() |
|
@interface Base: TestsuiteObject |
- (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; |
} |
|
/fobjc-std-1.mm
0,0 → 1,82
/* Test warnings when using -fobjc-std=objc1. */ |
/* { dg-do compile } */ |
/* { dg-options "-fobjc-std=objc1" } */ |
|
#include <objc/objc.h> |
|
@interface MyRootClass |
{ |
Class isa; /* { dg-error ".@package. is not available in Objective.C 1.0" } */ |
@package |
int a; |
int b; |
} |
+ (id) alloc __attribute__ ((deprecated)); /* { dg-error "not available in Objective.C 1.0" } */ |
+ (id) name; |
- (id) init; |
- (id) testMe: (id) __attribute__((unused)) argument; /* { dg-error "not available in Objective.C 1.0" } */ |
@property (nonatomic) int a; /* { dg-error "not available in Objective.C 1.0" } */ |
@property (nonatomic) int b; /* { dg-error "not available in Objective.C 1.0" } */ |
@end |
|
@implementation MyRootClass |
+ (id) alloc { return self; } |
+ (id) name { return self; } |
- (id) init { return self; } |
- (id) testMe: (id) __attribute__((unused)) argument { return self; } /* { dg-error "not available in Objective.C 1.0" } */ |
/* There is a problem with the testsuite on the following line; the compiler seems Ok, but the testsuite still barfs. */ |
/*@synthesize a;*/ /* dg-error "not available in Objective.C 1.0" */ |
/* The following lines replace the synthesize to prevent warnings. */ |
- (int) a { return a; } |
- (void) setA: (int)value { a = value; } |
@dynamic b; /* { dg-error "not available in Objective.C 1.0" } */ |
@end |
|
__attribute__ ((deprecated)) |
@interface MyRootClass2 /* { dg-error "class attributes are not available in Objective.C 1.0" } */ |
{ |
Class isa; |
} |
@end |
|
__attribute__ ((deprecated)) |
@protocol MyProtocol /* { dg-error "protocol attributes are not available in Objective.C 1.0" } */ |
- (id) test; |
@required /* { dg-error "not available in Objective.C 1.0" } */ |
- (id) variable __attribute__ ((deprecated)); /* { dg-error "not available in Objective.C 1.0" } */ |
@optional /* { dg-error "not available in Objective.C 1.0" } */ |
@end |
#if 0 /* fast enumeration is not implemented even in Objective-C 2.0 */ |
@interface MyRootClass (NSFastEnumeration) |
- (unsigned long)countByEnumeratingWithState: (struct __objcFastEnumerationState *)state |
objects:(id *)stackbuf |
count:(unsigned int)len; |
@end |
|
@class NSArray; |
|
int array_length (NSArray *array) |
{ |
int i = 0; |
|
for (id object in array) /* dg-error "not available in Objective.C 1.0" */ |
i++; |
|
return i; |
} |
#endif |
|
id test (void) |
{ |
return MyRootClass.name; /* { dg-error "not available in Objective.C 1.0" } */ |
} |
|
@interface MyRootClass3 |
{ |
Class isa; |
} |
@end |
|
/* There is a problem with the testsuite on the following line; the compiler seems Ok, but the testsuite still barfs. */ |
/* @interface MyRootClass3 () */ /* dg-error "not available in Objective.C 1.0" */ |
/* @end */ |
/syntax-error-1.mm
0,0 → 1,26
/* Graceful handling of a syntax error. */ |
/* { dg-do compile } */ |
|
#include <objc/Object.h> |
|
class foo { |
public: |
foo(); |
virtual ~foo(); |
}; |
|
|
extern void NXLog(const char *, ...); |
|
@interface Test2 : Object { |
} |
- (void) foo2; |
@end |
|
@implementation Test2 |
- (void) foo2 |
NXLog("Hello, world!"); /* { dg-error "expected .\{. before .NXLog." } */ |
} /* { dg-error "stray .\}. between Objective\\-C\\+\\+ methods" } */ |
@end |
|
/* { dg-error "expected constructor, destructor, or type conversion before" "" { target *-*-* } 22 } */ |
/demangle-3.mm
0,0 → 1,21
/* Test demangling an Objective-C method in error messages. */ |
/* { dg-do compile } */ |
|
#include <objc/objc.h> |
|
@interface DemangleTest |
{ |
Class isa; |
} |
+ (int) testFunction1; |
@end |
|
@implementation DemangleTest |
+ (int) testFunction1 |
{ |
/* TODO: Hack the testsuite so we can test that we get |
dg-error "In function .+[DemangleTest testFunction1]." |
At the moment, the message is filtered out. */ |
z; /* { dg-error "was not declared" } */ |
} |
@end |
/protocol-qualifier-1.mm
0,0 → 1,33
/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, November 2010. */ |
/* { dg-do compile } */ |
|
/* Test that protocol qualifiers work in the same way with @class and @interface. */ |
|
#include <objc/objc.h> |
|
@protocol MyProtocol |
- (void) method; |
@end |
|
|
/* This first snippet gives no warnings, which is correct as 'object' |
implements <MyProtocol> and hence responds to 'method'. Note how |
the details of the class 'MyClass' are never used. */ |
@interface MyClass |
@end |
|
void test (MyClass <MyProtocol> *object) |
{ |
[object method]; |
} |
|
|
/* This second snippet should behave identically. 'object' still implements |
the same protocol and responds to 'method'. The details of MyClass or |
MyClass2 are irrelevant. */ |
@class MyClass2; |
|
void test2 (MyClass2 <MyProtocol> *object) |
{ |
[object method]; |
} |
/method-2.mm
0,0 → 1,57
/* 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-obj-c++-shared/TestsuiteObject.h" |
#include "../objc-obj-c++-shared/runtime.h" |
|
@class NSString; |
|
@protocol NSMenuItem |
+ (void)setUsesUserKeyEquivalents:(BOOL)flag; |
+ (BOOL)usesUserKeyEquivalents; |
@end |
|
@interface NSMenuItem : TestsuiteObject <NSMenuItem> { |
@private |
id _menu; |
} |
@end |
|
@interface NSResponder : TestsuiteObject <NSMenuItem> |
{ |
id _nextResponder; |
} |
@end |
|
@interface TestsuiteObject(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 |
/selector-4.mm
0,0 → 1,26
/* Test warning for non existing selectors. */ |
/* Contributed by Devang Patel <dpatel@apple.com>. */ |
|
/* { dg-options "-Wselector -fnext-runtime" } */ |
/* { dg-do compile } */ |
|
typedef struct objc_object { struct objc_class *class_pointer; } *id; |
typedef struct objc_selector *SEL; |
|
@interface Foo |
- (void) foo; |
- (void) bar; |
@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); |
} |
@end |
/gnu-api-2-property.mm
0,0 → 1,101
/* Test the Modern GNU Objective-C Runtime API. |
|
This is test 'property', covering all functions starting with 'property'. */ |
|
/* { dg-do run } */ |
/* { dg-skip-if "No API#2 pre-Darwin9" { *-*-darwin[5-8]* } { "-fnext-runtime" } { "" } } */ |
|
/* To get the modern GNU Objective-C Runtime API, you include |
objc/runtime.h. */ |
#include <objc/runtime.h> |
#include <stdlib.h> |
#include <iostream> |
#include <cstring> |
|
@interface MyRootClass |
{ Class isa; } |
+ alloc; |
- init; |
+ initialize; |
@end |
|
@implementation MyRootClass |
+ alloc { return class_createInstance (self, 0); } |
- init { return self; } |
+ initialize { return self; } |
@end |
|
@interface MySubClass : MyRootClass |
{ |
id propertyA; |
id propertyB; |
} |
@property (assign, getter=getP, setter=setP:) id propertyA; |
@property (assign, nonatomic) id propertyB; |
@end |
|
@implementation MySubClass |
@synthesize propertyA; |
@synthesize propertyB; |
@end |
|
|
int main () |
{ |
/* Functions are tested in alphabetical order. */ |
|
std::cout << "Testing property_getAttributes () ...\n"; |
{ |
/* The Apple/NeXT runtime seems to crash on the following. */ |
#ifdef __GNU_LIBOBJC__ |
if (property_getAttributes (NULL) != NULL) |
abort (); |
#endif |
|
/* The GNU runtime doesn't support looking up properties at |
runtime yet. */ |
#ifdef __OBJC2__ |
{ |
objc_property_t property; |
|
property = class_getProperty (objc_getClass ("MySubClass"), "propertyA"); |
if (std::strcmp (property_getAttributes (property), |
"T@,GgetP,SsetP:,VpropertyA") != 0) |
abort (); |
|
property = class_getProperty (objc_getClass ("MySubClass"), "propertyB"); |
if (std::strcmp (property_getAttributes (property), |
"T@,N,VpropertyB") != 0) |
abort (); |
} |
#endif |
} |
|
std::cout << "Testing property_getName () ...\n"; |
{ |
/* The Apple/NeXT runtime seems to crash on the following. */ |
#ifdef __GNU_LIBOBJC__ |
|
if (property_getName (NULL) != NULL) |
abort (); |
#endif |
|
/* The GNU runtime doesn't support looking up properties at |
runtime yet. */ |
#ifdef __OBJC2__ |
{ |
objc_property_t property; |
|
property = class_getProperty (objc_getClass ("MySubClass"), "propertyA"); |
if (std::strcmp (property_getName (property), "propertyA") != 0) |
abort (); |
|
property = class_getProperty (objc_getClass ("MySubClass"), "propertyB"); |
if (std::strcmp (property_getName (property), "propertyB") != 0) |
abort (); |
} |
#endif |
} |
|
return (0); |
} |
/try-catch-15.mm
0,0 → 1,34
/* Test if addition of 'volatile' to object causes bogus error in presence of try-catch. */ |
/* { dg-options "-fobjc-exceptions" } */ |
/* { dg-do compile } */ |
|
@interface Exception |
@end |
|
class CppObj { |
public: |
void constMethod() const { |
} |
}; |
|
@interface MyObject : Exception |
- (void)doSomething; |
- (void)myMethod; |
@end |
|
@implementation MyObject |
- (void)doSomething { |
} |
|
- (void)myMethod { |
CppObj cppObj; |
|
@try { |
[self doSomething]; |
} |
@catch (Exception *exception) { |
} |
|
cppObj.constMethod(); |
} |
@end |
/exceptions-4.mm
0,0 → 1,64
/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, November 2010. */ |
/* { dg-options "-fobjc-exceptions" } */ |
/* { dg-do compile } */ |
|
/* Test warnings when parsing syntax errors in @catch(). */ |
|
#include <objc/objc.h> |
|
@interface MyObject |
{ |
Class isa; |
} |
@end |
|
@implementation MyObject |
@end |
|
@interface MyObject2 |
{ |
Class isa; |
} |
@end |
|
@implementation MyObject2 |
@end |
|
@protocol MyProtocol; |
|
int test (id object) |
{ |
int dummy = 0; |
|
@try { @throw object; } |
@catch |
{ /* { dg-error "expected" } */ |
dummy++; /* { dg-error "@catch parameter is not a known Objective-C class type" "" { target *-*-* } 35 } */ |
} |
@catch () /* { dg-error "expected identifier before" } */ |
{ /* { dg-error "@catch parameter is not a known Objective-C class type" "" { target *-*-* } 38 } */ |
dummy++; |
} |
@catch (i) /* { dg-error ".i. has not been declared" } */ |
{ /* { dg-error "@catch parameter is not a known Objective-C class type" "" { target *-*-* } 42 } */ |
dummy++; |
} |
@catch (id <MyProtocol x) /* { dg-error "expected ... before .x." } */ |
{ /* { dg-error "@catch parameter can not be protocol-qualified" "" { target *-*-* } 46 } */ |
dummy++; |
} |
@catch MyObject *x /* { dg-error "expected ... before .MyObject." } */ |
{ |
dummy++; |
} |
@catch MyObject2 *x) /* { dg-error "expected ... before .MyObject2." } */ |
{ |
dummy++; |
} |
|
@try { @throw object; } |
@catch (MyObject *x) |
@catch (MyObject2 *y) /* { dg-error "expected ... before .catch." } */ |
|
return dummy; /* { dg-error "expected ... before .return." } */ |
} |
/cxx-ivars-2.mm
0,0 → 1,79
// Check if the '- .cxx_construct' and '-.cxx_destruct' methods get called |
// and if they perform their desired function. |
|
// { dg-xfail-run-if "Needs OBJC2 ABI" { *-*-darwin* && { lp64 && { ! objc2 } } } { "-fnext-runtime" } { "" } } |
// { dg-do run { target *-*-darwin* } } |
// { dg-skip-if "" { *-*-* } { "-fgnu-runtime" } { "" } } |
// { dg-options "-fobjc-call-cxx-cdtors" } |
|
#include "../objc-obj-c++-shared/TestsuiteObject.m" |
#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: TestsuiteObject { |
@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); |
} |
|
/syntax-error-9.mm
0,0 → 1,3
@implementation SaturnDoc /* { dg-warning "cannot find interface declaration" } */ |
- read: (void*)aStream ggg /* { dg-error "expected .:. at end of input" } */ |
/* { dg-error "expected ..end. at end of input" "" { target *-*-* } 2 } */ |
/typedef-alias-1.mm
0,0 → 1,17
/* Typedefs of ObjC types should work without any bogus warnings. */ |
/* { dg-do compile } */ |
|
#include "../objc-obj-c++-shared/TestsuiteObject.h" |
#include <objc/objc.h> |
|
typedef TestsuiteObject MyObject; |
|
int main (int argc, const char * argv[]) |
{ |
TestsuiteObject* a = nil; |
MyObject* b = a; |
TestsuiteObject* c = b; |
|
return 0; |
} |
|
/protocol-inheritance-1.mm
0,0 → 1,54
/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, November 2010. */ |
/* { dg-do compile } */ |
/* { dg-options "-Wno-protocol" } */ |
|
#include <objc/objc.h> |
|
/* Test the -Wno-protocol flag. With this, at a class is accepted |
(with no warnings) as conforming to a protocol even if some |
protocol methods are implemented in the superclass. */ |
|
@protocol MyProtocol |
- (int)method; |
@end |
|
@protocol MyProtocol2 |
- (int)method2; |
@end |
|
/* The superclass implements the method required by the protocol. */ |
@interface MyRootClass |
{ |
Class isa; |
} |
- (int)method; |
@end |
|
@implementation MyRootClass |
- (int)method |
{ |
return 23; |
} |
@end |
|
/* The subclass inherits the method (does not implement it directly) |
but that still makes it conform to the protocol. No warnings. */ |
@interface MySubClass : MyRootClass <MyProtocol> |
@end |
|
@implementation MySubClass |
@end /* No warnings here. */ |
|
|
/* The subclass instead does not inherit the method method2 (and does |
not implement it directly) so it does not conform to the |
protocol MyProtocol2. */ |
@interface MySubClass2 : MyRootClass <MyProtocol2> |
@end |
|
@implementation MySubClass2 |
@end /* Warnings here, below. */ |
|
/* { dg-warning "incomplete implementation of class .MySubClass2." "" { target *-*-* } 50 } */ |
/* { dg-warning "method definition for .\\-method2. not found" "" { target *-*-* } 50 } */ |
/* { dg-warning "class .MySubClass2. does not fully implement the .MyProtocol2. protocol" "" { target *-*-* } 50 } */ |
/msg-in-protocol.mm
0,0 → 1,18
/* { dg-do compile } */ |
|
#include <objc/objc.h> |
|
@class Foo; |
|
@protocol Bar |
|
- (void)bang; |
|
@end |
|
void foo() |
{ |
Foo<Bar> *foo = nil; |
[foo bang]; |
} |
|
/super-dealloc-1.mm
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 |
/proto-lossage-2.mm
0,0 → 1,21
/* Don't forget to look in protocols if a class (and its superclasses) do not |
provide a suitable method. */ |
/* { dg-do compile } */ |
|
#include "../objc-obj-c++-shared/TestsuiteObject.h" |
#include <objc/objc.h> |
|
@protocol Zot |
-(void) zot; |
@end |
|
@interface Foo : TestsuiteObject <Zot> |
@end |
|
int foo() |
{ |
Foo *f=nil; |
[f zot]; /* There should be no warnings here! */ |
return 0; |
} |
|
/try-catch-3.mm
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-obj-c++-shared/TestsuiteObject.h" |
|
const char *foo(void) |
{ |
@try { |
return "foo"; |
} |
@catch (TestsuiteObject* theException) { |
return [theException name]; |
} |
} |
/comp-types-1.mm
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); |
} |
|
/method-11.mm
0,0 → 1,29
/* Check if class references (generated for the NeXT runtime) are appropriately |
folded. This test is safe to run on all targets. */ |
/* Author: Ziemowit Laski <zlaski@apple.com>. */ |
|
/* { dg-do compile } */ |
/* { dg-skip-if "" { *-*-* } { "-fgnu-runtime" } { "" } } */ |
|
#include "../objc-obj-c++-shared/TestsuiteObject.h" |
|
typedef TestsuiteObject ObjectTypedef1; |
typedef ObjectTypedef1 ObjectTypedef2; |
@compatibility_alias ObjectAlias1 ObjectTypedef2; |
@compatibility_alias ObjectAlias2 ObjectAlias1; |
typedef ObjectAlias2 ObjectTypedef3; |
|
void foo(void) { |
id obj = [TestsuiteObject new]; |
obj = [ObjectTypedef1 new]; |
obj = [ObjectTypedef2 new]; |
obj = [ObjectTypedef3 new]; |
obj = [ObjectAlias1 new]; |
obj = [ObjectAlias2 new]; |
} |
|
/* { dg-final { scan-assembler "_OBJC_ClassRefs_0" { target { *-*-darwin* && { ! lp64 } } } } } */ |
/* { dg-final { scan-assembler "_OBJC_ClassRef_TestsuiteObject" { target { *-*-darwin* && { lp64 } } } } } */ |
/* { dg-final { scan-assembler-not "_OBJC_ClassRefs_1" { target { *-*-darwin* && { ! lp64 } } } } } */ |
/* { dg-final { scan-assembler-not "_OBJC_ClassRef_ObjectTypedef" { target { *-*-darwin* && { lp64 } } } } } */ |
/* { dg-final { scan-assembler-not "_OBJC_ClassRef_ObjectAlias" { target { *-*-darwin* && { lp64 } } } } } */ |
/encode-6.mm
0,0 → 1,86
/* Encoding tests for ObjC class layouts. */ |
/* Contributed by Ziemowit Laski <zlaski@apple.com>. */ |
/* { dg-options "" } */ |
/* { dg-do run } */ |
/* { dg-xfail-run-if "Needs OBJC2 ABI" { *-*-darwin* && { lp64 && { ! objc2 } } } { "-fnext-runtime" } { "" } } */ |
#include "../objc-obj-c++-shared/TestsuiteObject.m" |
#include "../objc-obj-c++-shared/runtime.h" |
|
#include <stdlib.h> |
#include <string.h> |
|
#define CHECK_IF(expr) if(!(expr)) abort() |
|
@class Int1, Int2; |
struct Nested; |
|
struct Innermost { |
unsigned char a, b; |
struct Nested *encl; |
}; |
|
struct Nested { |
float a, b; |
Int1 *next; |
struct Innermost innermost; |
}; |
|
@interface Int1: TestsuiteObject { |
signed char a, b; |
Int2 *int2; |
struct Nested nested; |
} |
@end |
|
@interface Int2: Int1 { |
struct Innermost *innermost; |
Int1 *base; |
} |
@end |
|
@implementation Int1 |
@end |
|
@implementation Int2 |
@end |
|
#if defined(__NEXT_RUNTIME__) && !defined(NEXT_OBJC_USE_NEW_INTERFACE) |
struct objc_ivar *ivar; |
#else |
Ivar *ivar; |
#endif |
|
static void check_ivar(const char *name, const char *type) { |
#if defined(__NEXT_RUNTIME__) && !defined(NEXT_OBJC_USE_NEW_INTERFACE) |
CHECK_IF(!strcmp(ivar->ivar_name, name)); |
CHECK_IF(!strcmp(ivar->ivar_type, type)); |
#else |
CHECK_IF(!strcmp(ivar_getName(*ivar), name)); |
CHECK_IF(!strcmp(ivar_getTypeEncoding(*ivar), type)); |
#endif |
ivar++; |
} |
|
int main(void) { |
#if defined(__NEXT_RUNTIME__) && !defined(NEXT_OBJC_USE_NEW_INTERFACE) |
ivar = ((Class)objc_getClass("Int1"))->ivars->ivar_list; |
#else |
ivar = class_copyIvarList ((Class)objc_getClass("Int1"), NULL); |
#endif |
check_ivar("a", "c"); |
check_ivar("b", "c"); |
check_ivar("int2", "@\"Int2\""); |
check_ivar("nested", |
"{Nested=\"a\"f\"b\"f\"next\"@\"Int1\"\"innermost\"{Innermost=\"a\"C\"b\"C\"encl\"^{Nested}}}"); |
|
#if defined(__NEXT_RUNTIME__) && !defined(NEXT_OBJC_USE_NEW_INTERFACE) |
ivar = ((Class)objc_getClass("Int2"))->ivars->ivar_list; |
#else |
ivar = class_copyIvarList ((Class)objc_getClass("Int2"), NULL); |
#endif |
check_ivar("innermost", "^{Innermost=CC^{Nested}}"); |
check_ivar("base", "@\"Int1\""); |
|
return 0; |
} |
|
/protocol-forward-1.mm
0,0 → 1,27
/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, December 2010. */ |
/* { dg-do compile } */ |
|
/* Test that all protocols appearing in @interface declarations are |
real (ie, we saw a full @protocol definition with list of methods), |
and not just forward-references (ie, "@protocol NSObject;"). */ |
|
#include <objc/objc.h> |
|
@protocol MyProtocol; |
|
@protocol MyProtocol2 |
- (int)method2; |
@end |
|
@interface MyClass <MyProtocol> /* { dg-warning "definition of protocol .MyProtocol. not found" } */ |
@end |
|
@interface MyClass2 <MyProtocol2> /* Ok */ |
@end |
|
@interface MyClass2 (Category) <MyProtocol> /* { dg-warning "definition of protocol .MyProtocol. not found" } */ |
@end |
|
@protocol MyProtocol3 <MyProtocol> /* Ok */ |
@end |
|
/enhanced-proto-1.mm
0,0 → 1,18
/* Test use of @optional/@required keywords in @protocol class. */ |
/* { dg-do compile } */ |
|
@protocol MyProto1 |
@optional |
- (void) FOO; |
@optional |
- (void) FOO; |
@required |
- (void) REQ; |
@optional |
@end |
|
@protocol MyProto2 <MyProto1> |
- (void) FOO2; |
@optional |
- (void) FOO3; |
@end |
/keywords-1.mm
0,0 → 1,27
/* Test that 'in', 'out', 'inout', 'bycopy', 'byref', 'oneway' |
are not keywords outside of a "protocol qualifier" context. |
*/ |
/* { dg-do compile } */ |
|
typedef int in; |
|
in out (in inout) |
{ |
int byref = inout * 2; |
|
return byref + inout; |
} |
|
@class byref; |
|
@interface inout |
@end |
|
@protocol oneway; |
|
int main (void) |
{ |
in bycopy = (in)(out (0)); |
|
return (in)bycopy; |
} |
/comp-types-9.mm
0,0 → 1,25
/* { dg-do compile } */ |
|
/* Another gimplifier ICE... */ |
|
#include "../objc-obj-c++-shared/TestsuiteObject.h" |
|
@interface MyView: TestsuiteObject { |
int _frame; |
} |
- (void)_finalize; |
@end |
|
@interface MyViewTemplate: MyView { |
void *_className; |
} |
- (id)createRealObject; |
@end |
|
@implementation MyViewTemplate |
- (id)createRealObject { |
id realObj; |
*(MyView *)realObj = *(MyView *)self; |
return realObj; |
} |
@end |
/pragma-2.mm
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 |