bitfield-[1-5].mm: New.
* obj-c++.dg/bitfield-[1-5].mm: New. * obj-c++.dg/class-protocol-1.mm: New. * obj-c++.dg/comp-types-1[0-1].mm: New. * obj-c++.dg/comp-types-[2-9].mm: New. * obj-c++.dg/encode-[4-8].mm: New. * obj-c++.dg/layout-1.mm: New. * obj-c++.dg/method-1[0-9].mm: New. * obj-c++.dg/method-2[0-1].mm: New. * obj-c++.dg/method-[8-9].mm: New. * obj-c++.dg/objc-gc-3.mm: New. * obj-c++.dg/try-catch-10.mm: New. * objc.dg/bitfield-5.m: New. * objc.dg/comp-types-10.m: New. * objc.dg/comp-types-9.m: New. * objc.dg/layout-1.m: New. * objc.dg/objc-gc-4.m: New. * objc.dg/try-catch-9.m: New. * objc.dg/class-protocol-1.m: Tweak diagnostics. * objc.dg/comp-types-1.m: Likewise. * objc.dg/comp-types-[5-6].m: Likewise. * objc.dg/method-9.m: Likewise. From-SVN: r100121
This commit is contained in:
parent
37e0a9e890
commit
d1e270fe6e
@ -1,3 +1,27 @@
|
||||
2005-05-24 Ziemowit Laski <zlaski@apple.com>
|
||||
|
||||
* obj-c++.dg/bitfield-[1-5].mm: New.
|
||||
* obj-c++.dg/class-protocol-1.mm: New.
|
||||
* obj-c++.dg/comp-types-1[0-1].mm: New.
|
||||
* obj-c++.dg/comp-types-[2-9].mm: New.
|
||||
* obj-c++.dg/encode-[4-8].mm: New.
|
||||
* obj-c++.dg/layout-1.mm: New.
|
||||
* obj-c++.dg/method-1[0-9].mm: New.
|
||||
* obj-c++.dg/method-2[0-1].mm: New.
|
||||
* obj-c++.dg/method-[8-9].mm: New.
|
||||
* obj-c++.dg/objc-gc-3.mm: New.
|
||||
* obj-c++.dg/try-catch-10.mm: New.
|
||||
* objc.dg/bitfield-5.m: New.
|
||||
* objc.dg/comp-types-10.m: New.
|
||||
* objc.dg/comp-types-9.m: New.
|
||||
* objc.dg/layout-1.m: New.
|
||||
* objc.dg/objc-gc-4.m: New.
|
||||
* objc.dg/try-catch-9.m: New.
|
||||
* objc.dg/class-protocol-1.m: Tweak diagnostics.
|
||||
* objc.dg/comp-types-1.m: Likewise.
|
||||
* objc.dg/comp-types-[5-6].m: Likewise.
|
||||
* objc.dg/method-9.m: Likewise.
|
||||
|
||||
2005-05-24 Janis Johnson <janis187@us.ibm.com>
|
||||
|
||||
* gcc.dg/altivec-vec-merge.c: Make test usable on GNU/Linux targets
|
||||
|
113
gcc/testsuite/obj-c++.dg/bitfield-1.mm
Normal file
113
gcc/testsuite/obj-c++.dg/bitfield-1.mm
Normal file
@ -0,0 +1,113 @@
|
||||
/* 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-options "-Wpadded -Wabi" } */
|
||||
/* { dg-do run } */
|
||||
|
||||
#include <objc/objc.h>
|
||||
#include <objc/Object.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#define CHECK_IF(expr) if(!(expr)) abort()
|
||||
|
||||
enum Enum { zero, one, two, three, four };
|
||||
|
||||
@interface Base: Object {
|
||||
@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;
|
||||
}
|
78
gcc/testsuite/obj-c++.dg/bitfield-2.mm
Normal file
78
gcc/testsuite/obj-c++.dg/bitfield-2.mm
Normal file
@ -0,0 +1,78 @@
|
||||
/* Check if bitfield ivars are inherited correctly (i.e., without
|
||||
being "promoted" to ints). */
|
||||
/* Contributed by Ziemowit Laski <zlaski@apple.com>. */
|
||||
/* { dg-do run } */
|
||||
|
||||
#include <objc/Object.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#define CHECK_IF(expr) if(!(expr)) abort();
|
||||
|
||||
@interface Base: Object
|
||||
{
|
||||
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;
|
||||
}
|
57
gcc/testsuite/obj-c++.dg/bitfield-3.mm
Normal file
57
gcc/testsuite/obj-c++.dg/bitfield-3.mm
Normal file
@ -0,0 +1,57 @@
|
||||
/* Check if bitfield ivars are correctly @encode'd when
|
||||
the NeXT runtime is used. */
|
||||
/* Contributed by Ziemowit Laski <zlaski@apple.com>. */
|
||||
/* { dg-options "-fnext-runtime -fsigned-char" } */
|
||||
/* { dg-do run { target *-*-darwin* } } */
|
||||
|
||||
typedef struct objc_object { struct objc_class *class_pointer; } *id;
|
||||
|
||||
extern "C" {
|
||||
extern void abort(void);
|
||||
extern int strcmp(const char *, const char *);
|
||||
}
|
||||
|
||||
#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;
|
||||
}
|
51
gcc/testsuite/obj-c++.dg/bitfield-4.mm
Normal file
51
gcc/testsuite/obj-c++.dg/bitfield-4.mm
Normal file
@ -0,0 +1,51 @@
|
||||
/* Check if the @defs() construct preserves the correct
|
||||
layout of bitfields. */
|
||||
/* Contributed by Ziemowit Laski <zlaski@apple.com>. */
|
||||
/* { dg-options "-lobjc -Wpadded" } */
|
||||
/* { dg-do run } */
|
||||
|
||||
#include <objc/Object.h>
|
||||
|
||||
extern "C" {
|
||||
extern void abort(void);
|
||||
extern int strcmp(const char *str1, const char *str2);
|
||||
}
|
||||
#define CHECK_IF(expr) if(!(expr)) abort()
|
||||
|
||||
enum Enum { one, two, three, four };
|
||||
|
||||
@interface Base: Object {
|
||||
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;
|
||||
}
|
29
gcc/testsuite/obj-c++.dg/bitfield-5.mm
Normal file
29
gcc/testsuite/obj-c++.dg/bitfield-5.mm
Normal file
@ -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
|
442
gcc/testsuite/obj-c++.dg/class-protocol-1.mm
Normal file
442
gcc/testsuite/obj-c++.dg/class-protocol-1.mm
Normal file
@ -0,0 +1,442 @@
|
||||
|
||||
/* Check Class <protocol> types */
|
||||
/* Author: David Ayers <d.ayers@inode.at> */
|
||||
/* { dg-do compile } */
|
||||
|
||||
#include <objc/objc.h>
|
||||
#include <objc/objc-api.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>
|
||||
@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 *-*-* } 190 } */
|
||||
[clsP7 doItInstance7]; /* { dg-warning "not found in protocol" } */
|
||||
/* { dg-warning "no .\\+doItInstance7. method found" "" { target *-*-* } 192 } */
|
||||
|
||||
[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-warning "between pointer" } */
|
||||
objP1 == num; /* { dg-warning "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-warning "between pointer" } */
|
||||
clsP1 == num; /* { dg-warning "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 } */
|
19
gcc/testsuite/obj-c++.dg/comp-types-10.mm
Normal file
19
gcc/testsuite/obj-c++.dg/comp-types-10.mm
Normal file
@ -0,0 +1,19 @@
|
||||
/* Yet another mysterious gimplifier crasher. */
|
||||
/* { dg-do compile } */
|
||||
/* { 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
|
28
gcc/testsuite/obj-c++.dg/comp-types-11.mm
Normal file
28
gcc/testsuite/obj-c++.dg/comp-types-11.mm
Normal file
@ -0,0 +1,28 @@
|
||||
/* { dg-do compile } */
|
||||
|
||||
#include <objc/Object.h>
|
||||
|
||||
@protocol Foo
|
||||
- (id)meth1;
|
||||
- (id)meth2:(int)arg;
|
||||
@end
|
||||
|
||||
@interface Derived1: Object
|
||||
@end
|
||||
|
||||
@interface Derived2: Object
|
||||
+ (Derived1 *)new;
|
||||
@end
|
||||
|
||||
id<Foo> func(void) {
|
||||
Object *o = [Object new];
|
||||
return o; /* { dg-warning "class .Object. 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
|
||||
|
88
gcc/testsuite/obj-c++.dg/comp-types-2.mm
Normal file
88
gcc/testsuite/obj-c++.dg/comp-types-2.mm
Normal file
@ -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;
|
||||
}
|
38
gcc/testsuite/obj-c++.dg/comp-types-3.mm
Normal file
38
gcc/testsuite/obj-c++.dg/comp-types-3.mm
Normal file
@ -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;
|
||||
}
|
64
gcc/testsuite/obj-c++.dg/comp-types-4.mm
Normal file
64
gcc/testsuite/obj-c++.dg/comp-types-4.mm
Normal file
@ -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;
|
||||
}
|
74
gcc/testsuite/obj-c++.dg/comp-types-5.mm
Normal file
74
gcc/testsuite/obj-c++.dg/comp-types-5.mm
Normal file
@ -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;
|
||||
}
|
33
gcc/testsuite/obj-c++.dg/comp-types-6.mm
Normal file
33
gcc/testsuite/obj-c++.dg/comp-types-6.mm
Normal file
@ -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;
|
||||
}
|
38
gcc/testsuite/obj-c++.dg/comp-types-7.mm
Normal file
38
gcc/testsuite/obj-c++.dg/comp-types-7.mm
Normal file
@ -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;
|
||||
}
|
33
gcc/testsuite/obj-c++.dg/comp-types-8.mm
Normal file
33
gcc/testsuite/obj-c++.dg/comp-types-8.mm
Normal file
@ -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
|
||||
|
25
gcc/testsuite/obj-c++.dg/comp-types-9.mm
Normal file
25
gcc/testsuite/obj-c++.dg/comp-types-9.mm
Normal file
@ -0,0 +1,25 @@
|
||||
/* { dg-do compile } */
|
||||
|
||||
/* Another gimplifier ICE... */
|
||||
|
||||
#include <objc/Object.h>
|
||||
|
||||
@interface MyView: Object {
|
||||
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
|
105
gcc/testsuite/obj-c++.dg/encode-4.mm
Normal file
105
gcc/testsuite/obj-c++.dg/encode-4.mm
Normal file
@ -0,0 +1,105 @@
|
||||
/* 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 } */
|
||||
|
||||
|
||||
#include <objc/objc.h>
|
||||
#include <objc/Object.h>
|
||||
|
||||
#ifdef __NEXT_RUNTIME__
|
||||
#define METHOD Method
|
||||
#define OBJC_GETCLASS objc_getClass
|
||||
#define CLASS_GETINSTANCEMETHOD class_getInstanceMethod
|
||||
#else
|
||||
#include <objc/objc-api.h>
|
||||
#define METHOD Method_t
|
||||
#define OBJC_GETCLASS objc_get_class
|
||||
#define CLASS_GETINSTANCEMETHOD class_get_instance_method
|
||||
#endif
|
||||
|
||||
extern "C" {
|
||||
extern int sscanf(const char *str, const char *format, ...);
|
||||
extern void abort(void);
|
||||
}
|
||||
#define CHECK_IF(expr) if(!(expr)) abort()
|
||||
|
||||
@interface Foo: Object
|
||||
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(meth->method_types, "@%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(meth->method_types, string, &offs1, &offs2, &offs3,
|
||||
&offs4, &offs5, &offs6, &offs7);
|
||||
CHECK_IF(!offs2);
|
||||
[foo char:'c' float:2.3 double:3.5 long:2345L];
|
||||
|
||||
return 0;
|
||||
}
|
74
gcc/testsuite/obj-c++.dg/encode-5.mm
Normal file
74
gcc/testsuite/obj-c++.dg/encode-5.mm
Normal file
@ -0,0 +1,74 @@
|
||||
/* Method encoding tests for stand-alone @protocol declarations. */
|
||||
/* Contributed by Ziemowit Laski <zlaski@apple.com>. */
|
||||
/* { dg-do run } */
|
||||
|
||||
#include <objc/Protocol.h>
|
||||
#ifdef __cplusplus
|
||||
#define ProtoBool bool
|
||||
#else
|
||||
#define ProtoBool _Bool
|
||||
#endif
|
||||
|
||||
#ifndef __NEXT_RUNTIME__
|
||||
#include <objc/objc-api.h>
|
||||
#endif
|
||||
|
||||
extern "C" {
|
||||
extern int sscanf(const char *str, const char *format, ...);
|
||||
extern void abort(void);
|
||||
}
|
||||
#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;
|
||||
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 = [proto descriptionForInstanceMethod: @selector(char:float:double:unsigned:short:long:)];
|
||||
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 = [proto descriptionForInstanceMethod: @selector(setRect:withBool:withInt:)];
|
||||
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 = [proto descriptionForClassMethod: @selector(getEnum:enum:bool:)];
|
||||
scan_initial("^i%u@%u:%u^{?=ff(__XXAngle=II)}%ui%uc%u");
|
||||
CHECK_IF(offs3 == offs2 + sizeof(XXPoint *) && offs4 == offs3 + sizeof(enum Enum));
|
||||
CHECK_IF(totsize == offs4 + sizeof(int)); /* 'ObjCBool' is really 'char' */
|
||||
meth = [proto descriptionForClassMethod: @selector(getBool:)];
|
||||
scan_initial("^^B%u@%u:%u^*%u");
|
||||
CHECK_IF(totsize == offs2 + sizeof(ObjCBool **));
|
||||
return 0;
|
||||
}
|
75
gcc/testsuite/obj-c++.dg/encode-6.mm
Normal file
75
gcc/testsuite/obj-c++.dg/encode-6.mm
Normal file
@ -0,0 +1,75 @@
|
||||
/* Encoding tests for ObjC class layouts. */
|
||||
/* Contributed by Ziemowit Laski <zlaski@apple.com>. */
|
||||
/* { dg-options "-lobjc" } */
|
||||
/* { dg-do run } */
|
||||
|
||||
#include <objc/Object.h>
|
||||
#ifdef __NEXT_RUNTIME__
|
||||
#include <objc/objc-class.h>
|
||||
#define OBJC_GETCLASS objc_getClass
|
||||
#else
|
||||
#include <objc/objc-api.h>
|
||||
#define OBJC_GETCLASS objc_get_class
|
||||
#endif
|
||||
|
||||
extern "C" {
|
||||
extern void abort(void);
|
||||
extern int strcmp(const char *s1, const char *s2);
|
||||
}
|
||||
#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: Object {
|
||||
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
|
||||
|
||||
struct objc_ivar *ivar;
|
||||
|
||||
static void check_ivar(const char *name, const char *type) {
|
||||
CHECK_IF(!strcmp(ivar->ivar_name, name));
|
||||
CHECK_IF(!strcmp(ivar->ivar_type, type));
|
||||
ivar++;
|
||||
}
|
||||
|
||||
int main(void) {
|
||||
ivar = ((Class)OBJC_GETCLASS("Int1"))->ivars->ivar_list;
|
||||
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}}}");
|
||||
|
||||
ivar = ((Class)OBJC_GETCLASS("Int2"))->ivars->ivar_list;
|
||||
check_ivar("innermost", "^{Innermost=CC^{Nested}}");
|
||||
check_ivar("base", "@\"Int1\"");
|
||||
|
||||
return 0;
|
||||
}
|
78
gcc/testsuite/obj-c++.dg/encode-7.mm
Normal file
78
gcc/testsuite/obj-c++.dg/encode-7.mm
Normal file
@ -0,0 +1,78 @@
|
||||
/* 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/Object.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#define CHECK_IF(expr) if(!(expr)) abort()
|
||||
|
||||
#ifdef __NEXT_RUNTIME__
|
||||
#define METHOD Method
|
||||
#define OBJC_GETCLASS objc_getClass
|
||||
#define CLASS_GETINSTANCEMETHOD class_getInstanceMethod
|
||||
#else
|
||||
#include <objc/objc-api.h>
|
||||
#define METHOD Method_t
|
||||
#define OBJC_GETCLASS objc_get_class
|
||||
#define CLASS_GETINSTANCEMETHOD class_get_instance_method
|
||||
#endif
|
||||
|
||||
@interface Test : Object
|
||||
{ float j; }
|
||||
-(void) test2: (int [5])a with: (int [])b;
|
||||
-(id) test3: (Test **)b; /* { dg-warning "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(meth->method_types, "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(meth->method_types, "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;
|
||||
}
|
23
gcc/testsuite/obj-c++.dg/encode-8.mm
Normal file
23
gcc/testsuite/obj-c++.dg/encode-8.mm
Normal file
@ -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-options "-lobjc" } */
|
||||
/* { dg-do run } */
|
||||
|
||||
#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;
|
||||
}
|
15
gcc/testsuite/obj-c++.dg/layout-1.mm
Normal file
15
gcc/testsuite/obj-c++.dg/layout-1.mm
Normal file
@ -0,0 +1,15 @@
|
||||
/* 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/Object.h>
|
||||
|
||||
@interface Derived1: Object
|
||||
{ }
|
||||
@end
|
||||
|
||||
@interface Derived2: Object
|
||||
- (id) foo;
|
||||
@end
|
||||
|
45
gcc/testsuite/obj-c++.dg/method-10.mm
Normal file
45
gcc/testsuite/obj-c++.dg/method-10.mm
Normal file
@ -0,0 +1,45 @@
|
||||
/* Test for sending messages to aliased classes (and instances thereof). */
|
||||
/* Author: Ziemowit Laski <zlaski@apple.com>. */
|
||||
/* { dg-options "-lobjc" } */
|
||||
/* { dg-do run } */
|
||||
|
||||
#include <objc/Object.h>
|
||||
|
||||
extern "C" void abort(void);
|
||||
#define CHECK_IF(expr) if(!(expr)) abort()
|
||||
|
||||
@interface Int1: Object
|
||||
+ (int) classMeth;
|
||||
- (int) instanceMeth;
|
||||
@end
|
||||
|
||||
@interface Int2: Object
|
||||
+ (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;
|
||||
}
|
25
gcc/testsuite/obj-c++.dg/method-11.mm
Normal file
25
gcc/testsuite/obj-c++.dg/method-11.mm
Normal file
@ -0,0 +1,25 @@
|
||||
/* 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-options "-fnext-runtime" } */
|
||||
/* { dg-do compile } */
|
||||
|
||||
#include <objc/Object.h>
|
||||
|
||||
typedef Object ObjectTypedef1;
|
||||
typedef ObjectTypedef1 ObjectTypedef2;
|
||||
@compatibility_alias ObjectAlias1 ObjectTypedef2;
|
||||
@compatibility_alias ObjectAlias2 ObjectAlias1;
|
||||
typedef ObjectAlias2 ObjectTypedef3;
|
||||
|
||||
void foo(void) {
|
||||
id obj = [Object new];
|
||||
obj = [ObjectTypedef1 new];
|
||||
obj = [ObjectTypedef2 new];
|
||||
obj = [ObjectTypedef3 new];
|
||||
obj = [ObjectAlias1 new];
|
||||
obj = [ObjectAlias2 new];
|
||||
}
|
||||
|
||||
/* { dg-final { scan-assembler "_OBJC_CLASS_REFERENCES_0" } } */
|
||||
/* { dg-final { scan-assembler-not "_OBJC_CLASS_REFERENCES_1" } } */
|
31
gcc/testsuite/obj-c++.dg/method-12.mm
Normal file
31
gcc/testsuite/obj-c++.dg/method-12.mm
Normal file
@ -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-warning "using .\\-\\(unsigned( int)?\\)port." "" { target *-*-* } 9 } */
|
||||
/* { dg-warning "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" } */
|
||||
}
|
27
gcc/testsuite/obj-c++.dg/method-13.mm
Normal file
27
gcc/testsuite/obj-c++.dg/method-13.mm
Normal file
@ -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/Object.h>
|
||||
|
||||
@interface Class1
|
||||
- (void)setWindow:(Object *)wdw;
|
||||
@end
|
||||
|
||||
@interface Class2
|
||||
- (void)setWindow:(Class1 *)window;
|
||||
@end
|
||||
|
||||
id foo(void) {
|
||||
Object *obj = [[Object alloc] init];
|
||||
id obj2 = obj;
|
||||
[obj setWindow:nil]; /* { dg-warning ".Object. 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-warning "using .\\-\\(void\\)setWindow:\\(Object \\*\\)wdw." "" { target *-*-* } 8 } */
|
||||
/* { dg-warning "also found .\\-\\(void\\)setWindow:\\(Class1 \\*\\)window." "" { target *-*-* } 12 } */
|
||||
|
||||
return obj;
|
||||
}
|
14
gcc/testsuite/obj-c++.dg/method-14.mm
Normal file
14
gcc/testsuite/obj-c++.dg/method-14.mm
Normal file
@ -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]; }
|
||||
|
43
gcc/testsuite/obj-c++.dg/method-15.mm
Normal file
43
gcc/testsuite/obj-c++.dg/method-15.mm
Normal file
@ -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/Object.h>
|
||||
|
||||
@protocol MyObject
|
||||
- (id)initWithData:(Object *)data;
|
||||
@end
|
||||
|
||||
@protocol SomeOther
|
||||
- (id)initWithData:(int)data;
|
||||
@end
|
||||
|
||||
@protocol MyCoding
|
||||
- (id)initWithData:(id<MyObject, MyCoding>)data;
|
||||
@end
|
||||
|
||||
@interface NTGridDataObject: Object <MyCoding>
|
||||
{
|
||||
Object<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-warning "using .\\-\\(id\\)initWithData:\\(Object \\*\\)data." "" { target *-*-* } 9 } */
|
||||
/* { dg-warning "also found .\\-\\(id\\)initWithData:\\(id <MyObject, MyCoding>\\)data." "" { target *-*-* } 17 } */
|
||||
/* { dg-warning "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
|
34
gcc/testsuite/obj-c++.dg/method-16.mm
Normal file
34
gcc/testsuite/obj-c++.dg/method-16.mm
Normal file
@ -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-warning "using .\\-\\(void\\)initWithData:\\(Object1 \\*\\)data." "" { target *-*-* } 13 } */
|
||||
/* { dg-warning "also found .\\-\\(id\\)initWithData:\\(Object1 \\*\\)data." "" { target *-*-* } 17 } */
|
||||
/* { dg-warning "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 } */
|
||||
}
|
32
gcc/testsuite/obj-c++.dg/method-17.mm
Normal file
32
gcc/testsuite/obj-c++.dg/method-17.mm
Normal file
@ -0,0 +1,32 @@
|
||||
/* 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 } */
|
||||
|
||||
#include <objc/Object.h>
|
||||
extern "C" void abort(void);
|
||||
#define CHECK_IF(expr) if(!(expr)) abort()
|
||||
|
||||
static double d = 4.5920234e2;
|
||||
|
||||
@interface Foo : Object
|
||||
-(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;
|
||||
}
|
||||
|
25
gcc/testsuite/obj-c++.dg/method-18.mm
Normal file
25
gcc/testsuite/obj-c++.dg/method-18.mm
Normal file
@ -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
|
81
gcc/testsuite/obj-c++.dg/method-19.mm
Normal file
81
gcc/testsuite/obj-c++.dg/method-19.mm
Normal file
@ -0,0 +1,81 @@
|
||||
/* 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 } */
|
||||
|
||||
#include <objc/objc.h>
|
||||
|
||||
#ifdef __NEXT_RUNTIME__
|
||||
#include <objc/objc-runtime.h>
|
||||
#define OBJC_GETCLASS objc_getClass
|
||||
#else
|
||||
#include <objc/objc-api.h>
|
||||
#define OBJC_GETCLASS objc_get_class
|
||||
#endif
|
||||
|
||||
extern "C" {
|
||||
extern void abort(void);
|
||||
extern int strcmp(const char *, const char *);
|
||||
}
|
||||
#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
|
||||
#ifdef __NEXT_RUNTIME__
|
||||
+ initialize { return self; }
|
||||
#endif
|
||||
- (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;
|
||||
}
|
17
gcc/testsuite/obj-c++.dg/method-20.mm
Normal file
17
gcc/testsuite/obj-c++.dg/method-20.mm
Normal file
@ -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:" } } */
|
25
gcc/testsuite/obj-c++.dg/method-21.mm
Normal file
25
gcc/testsuite/obj-c++.dg/method-21.mm
Normal file
@ -0,0 +1,25 @@
|
||||
/* Test for spurious "may or may not return a value" warnings. */
|
||||
/* { dg-do compile } */
|
||||
/* { dg-options "-Wextra" } */
|
||||
|
||||
#include <objc/Object.h>
|
||||
|
||||
@interface Foo: Object
|
||||
- (id) meth1;
|
||||
- (void) meth2;
|
||||
@end
|
||||
|
||||
extern int bar;
|
||||
|
||||
@implementation Foo
|
||||
- (id) meth1 {
|
||||
if (bar)
|
||||
return [Object new];
|
||||
return; /* { dg-error "return.statement with no value" } */
|
||||
}
|
||||
- (void) meth2 {
|
||||
if (!bar)
|
||||
return;
|
||||
bar = 0;
|
||||
}
|
||||
@end
|
30
gcc/testsuite/obj-c++.dg/method-8.mm
Normal file
30
gcc/testsuite/obj-c++.dg/method-8.mm
Normal file
@ -0,0 +1,30 @@
|
||||
/* Tests of duplication. */
|
||||
/* { dg-do compile } */
|
||||
|
||||
@interface class1
|
||||
- (int) meth1;
|
||||
- (void) meth1; /* { dg-error "duplicate declaration of method .\\-meth1." } */
|
||||
@end
|
||||
|
||||
@interface class2
|
||||
+ (void) meth1;
|
||||
+ (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
|
33
gcc/testsuite/obj-c++.dg/method-9.mm
Normal file
33
gcc/testsuite/obj-c++.dg/method-9.mm
Normal file
@ -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 } */
|
||||
|
63
gcc/testsuite/obj-c++.dg/objc-gc-3.mm
Normal file
63
gcc/testsuite/obj-c++.dg/objc-gc-3.mm
Normal file
@ -0,0 +1,63 @@
|
||||
/* 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 { target *-*-darwin* } } */
|
||||
/* { dg-options "-fobjc-gc" } */
|
||||
|
||||
#include <objc/Object.h>
|
||||
|
||||
@class MyWindow;
|
||||
|
||||
@interface MyDocument : Object {
|
||||
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 {
|
||||
Object *_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
|
25
gcc/testsuite/obj-c++.dg/try-catch-10.mm
Normal file
25
gcc/testsuite/obj-c++.dg/try-catch-10.mm
Normal file
@ -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);
|
||||
}
|
||||
}
|
||||
|
113
gcc/testsuite/objc.dg/bitfield-5.m
Normal file
113
gcc/testsuite/objc.dg/bitfield-5.m
Normal file
@ -0,0 +1,113 @@
|
||||
/* Check 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-options "-Wpadded" } */
|
||||
/* { dg-do run } */
|
||||
|
||||
#include <objc/objc.h>
|
||||
#include <objc/Object.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#define CHECK_IF(expr) if(!(expr)) abort()
|
||||
|
||||
enum Enum { zero, one, two, three, four };
|
||||
|
||||
@interface Base: Object {
|
||||
@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 {
|
||||
Class isa;
|
||||
unsigned a: 2;
|
||||
int b: 3;
|
||||
enum Enum c: 4;
|
||||
unsigned d: 5;
|
||||
}; /* { dg-warning "padding struct size to alignment boundary" } */
|
||||
|
||||
@interface Derived: Base {
|
||||
@public
|
||||
signed e: 5;
|
||||
unsigned f: 4;
|
||||
enum Enum g: 3;
|
||||
} /* { dg-warning "padding struct size to alignment boundary" } */
|
||||
@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;
|
||||
}; /* { dg-warning "padding struct size to alignment boundary" } */
|
||||
|
||||
@interface Leaf: Derived {
|
||||
@public
|
||||
signed h: 2;
|
||||
} /* { dg-warning "padding struct size to alignment boundary" } */
|
||||
@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;
|
||||
}; /* { dg-warning "padding struct size to alignment boundary" } */
|
||||
|
||||
/* 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; /* { dg-warning "padding struct size to alignment boundary" } */
|
||||
typedef struct { @defs(Leaf); } Leaf_t; /* { dg-warning "padding struct size to alignment boundary" } */
|
||||
|
||||
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;
|
||||
}
|
@ -313,9 +313,9 @@ testComptypes(void)
|
||||
{ /* id <protocol>, SomeClass * */
|
||||
mc1 == objP1;
|
||||
objP1 == mc1;
|
||||
|
||||
mc1 == objP2; /* { dg-warning "does not implement" } */
|
||||
objP2 == mc1; /* { dg-warning "does not implement" } */
|
||||
|
||||
mc1 == objP2; /* { dg-warning "lacks a cast" } */
|
||||
objP2 == mc1; /* { dg-warning "lacks a cast" } */
|
||||
}
|
||||
{ /* id <protocol>, id */
|
||||
obj == objP1;
|
||||
@ -371,10 +371,10 @@ testComptypes(void)
|
||||
objP5 = objP1; /* { dg-warning "does not conform" } */
|
||||
}
|
||||
{ /* id <protocol>, SomeClass * */
|
||||
mc1 = objP1; /* { dg-warning "incompatible" } */ /* FIXME: should be "" */
|
||||
mc1 = objP1;
|
||||
objP1 = mc1;
|
||||
|
||||
mc1 = objP2; /* { dg-warning "incompatible" } */ /* FIXME: should be "does not implement" */
|
||||
|
||||
mc1 = objP2; /* { dg-warning "does not conform" } */
|
||||
objP2 = mc1; /* { dg-warning "does not implement" } */
|
||||
}
|
||||
{ /* id <protocol>, id */
|
||||
@ -382,8 +382,8 @@ testComptypes(void)
|
||||
objP1 = obj;
|
||||
}
|
||||
{ /* id <protocol>, Class */
|
||||
cls = objP1; /* { dg-warning "incompatible" } */
|
||||
objP1 = cls; /* { dg-warning "incompatible" } */
|
||||
cls = objP1; /* { dg-warning "distinct Objective\\-C type" } */
|
||||
objP1 = cls; /* { dg-warning "distinct Objective\\-C type" } */
|
||||
}
|
||||
{ /* id <protocol>, non-ObjC */
|
||||
num = objP1; /* { dg-warning "makes integer" } */
|
||||
@ -401,11 +401,11 @@ testComptypes(void)
|
||||
}
|
||||
{ /* Class <protocol>, SomeClass * */
|
||||
/* These combinations should always elicit a warning. */
|
||||
mc1 = clsP1; /* { dg-warning "incompatible" } */
|
||||
clsP1 = mc1; /* { dg-warning "incompatible" } */
|
||||
mc1 = clsP1; /* { dg-warning "distinct Objective\\-C type" } */
|
||||
clsP1 = mc1; /* { dg-warning "distinct Objective\\-C type" } */
|
||||
|
||||
mc1 = clsP2; /* { dg-warning "incompatible" } */
|
||||
clsP2 = mc1; /* { dg-warning "incompatible" } */
|
||||
mc1 = clsP2; /* { dg-warning "distinct Objective\\-C type" } */
|
||||
clsP2 = mc1; /* { dg-warning "distinct Objective\\-C type" } */
|
||||
}
|
||||
{ /* Class <protocol>, id */
|
||||
obj = clsP1;
|
||||
@ -423,8 +423,8 @@ testComptypes(void)
|
||||
clsP1 = ptr;
|
||||
}
|
||||
{ /* Class <protocol>, id <protocol> */
|
||||
clsP1 = objP1; /* { dg-warning "incompatible" } */
|
||||
objP1 = clsP1; /* { dg-warning "incompatible" } */
|
||||
clsP1 = objP1; /* { dg-warning "distinct Objective\\-C type" } */
|
||||
objP1 = clsP1; /* { dg-warning "distinct Objective\\-C type" } */
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -32,9 +32,9 @@ int main()
|
||||
/* 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 "incompatible pointer type" } */
|
||||
obj_c = obj_cp; /* { dg-warning "incompatible pointer type" } */
|
||||
obj_c = obj_C; /* { dg-warning "incompatible pointer type" } */
|
||||
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
|
||||
@ -43,14 +43,15 @@ int main()
|
||||
obj_p = obj; /* Ok */
|
||||
obj_p = obj_c; /* { dg-warning "does not implement" } */
|
||||
obj_p = obj_cp; /* Ok */
|
||||
obj_p = obj_C; /* { dg-warning "incompatible pointer type" } */
|
||||
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' */
|
||||
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 "incompatible pointer type" } */
|
||||
obj_cp = obj_p; /* { dg-warning "incompatible pointer type" } */
|
||||
obj_cp = obj_C; /* { dg-warning "incompatible pointer type" } */
|
||||
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*/
|
||||
@ -64,8 +65,8 @@ int main()
|
||||
|
||||
/* Any comparison between 'MyClass *' and anything which is not an 'id'
|
||||
must generate a warning. */
|
||||
if (obj_c == obj_p) ; /* { dg-warning "does not implement" } */
|
||||
if (obj_p == obj_c) ; /* { dg-warning "does not implement" } */
|
||||
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" } */
|
||||
|
28
gcc/testsuite/objc.dg/comp-types-10.m
Normal file
28
gcc/testsuite/objc.dg/comp-types-10.m
Normal file
@ -0,0 +1,28 @@
|
||||
/* { dg-do compile } */
|
||||
|
||||
#include <objc/Object.h>
|
||||
|
||||
@protocol Foo
|
||||
- (id)meth1;
|
||||
- (id)meth2:(int)arg;
|
||||
@end
|
||||
|
||||
@interface Derived1: Object
|
||||
@end
|
||||
|
||||
@interface Derived2: Object
|
||||
+ (Derived1 *)new;
|
||||
@end
|
||||
|
||||
id<Foo> func(void) {
|
||||
Object *o = [Object new];
|
||||
return o; /* { dg-warning "class .Object. 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
|
||||
|
@ -19,8 +19,8 @@ int main()
|
||||
obj_cp = obj; /* Ok */
|
||||
obj = obj_cp; /* Ok */
|
||||
|
||||
obj_cp = obj_p; /* { dg-warning "incompatible pointer type" } */
|
||||
obj_p = obj_cp; /* Ok */ /* Spurious 2.95.4 warning here. */
|
||||
obj_cp = obj_p; /* Ok */
|
||||
obj_p = obj_cp; /* Ok */
|
||||
|
||||
if (obj_cp == obj) ; /* Ok */
|
||||
if (obj == obj_cp) ; /* Ok */
|
||||
|
@ -1,6 +1,7 @@
|
||||
/* Test assignments and comparisons involving category protocols. */
|
||||
/* Author: Nicola Pero <nicola@brainstorm.co.uk>. */
|
||||
/* { dg-do compile } */
|
||||
|
||||
#include <objc/objc.h>
|
||||
|
||||
@protocol MyProtocol
|
||||
@ -23,8 +24,8 @@ int main()
|
||||
MyClass *obj_cp = nil;
|
||||
MyOtherClass *obj_cp2 = nil;
|
||||
|
||||
obj_cp = obj_p; /* { dg-warning "incompatible pointer type" } */
|
||||
obj_cp2 = obj_p; /* { dg-warning "incompatible pointer type" } */
|
||||
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 */
|
||||
|
||||
|
19
gcc/testsuite/objc.dg/comp-types-9.m
Normal file
19
gcc/testsuite/objc.dg/comp-types-9.m
Normal file
@ -0,0 +1,19 @@
|
||||
/* Yet another mysterious gimplifier crasher. */
|
||||
/* { dg-do compile } */
|
||||
/* { 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
|
15
gcc/testsuite/objc.dg/layout-1.m
Normal file
15
gcc/testsuite/objc.dg/layout-1.m
Normal file
@ -0,0 +1,15 @@
|
||||
/* Ensure that we do not get bizarre warnings referring to
|
||||
__attribute__((packed)) or some such. */
|
||||
/* { dg-do compile } */
|
||||
/* { dg-options "-Wpadded -Wpacked" } */
|
||||
|
||||
#include <objc/Object.h>
|
||||
|
||||
@interface Derived1: Object
|
||||
{ }
|
||||
@end
|
||||
|
||||
@interface Derived2: Object
|
||||
- (id) foo;
|
||||
@end
|
||||
|
@ -39,7 +39,7 @@
|
||||
/* { dg-warning "also found .\\-\\(id\\)initWithData:\\(int\\)data." "" { target *-*-* } 15 } */
|
||||
|
||||
/* The following warning is a consequence of picking the "wrong" method signature. */
|
||||
/* { dg-warning "passing argument 1 of .initWithData:. from incompatible pointer type" "" { target *-*-* } 35 } */
|
||||
/* { dg-warning "passing argument 1 of .initWithData:. from distinct Objective\\-C type" "" { target *-*-* } 35 } */
|
||||
return result;
|
||||
}
|
||||
@end
|
||||
|
63
gcc/testsuite/objc.dg/objc-gc-4.m
Normal file
63
gcc/testsuite/objc.dg/objc-gc-4.m
Normal file
@ -0,0 +1,63 @@
|
||||
/* 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 { target *-*-darwin* } } */
|
||||
/* { dg-options "-fobjc-gc" } */
|
||||
|
||||
#include <objc/Object.h>
|
||||
|
||||
@class MyWindow;
|
||||
|
||||
@interface MyDocument : Object {
|
||||
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 {
|
||||
Object *_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
|
25
gcc/testsuite/objc.dg/try-catch-9.m
Normal file
25
gcc/testsuite/objc.dg/try-catch-9.m
Normal file
@ -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);
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user