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:
Ziemowit Laski 2005-05-24 22:18:43 +00:00 committed by Mike Stump
parent 37e0a9e890
commit d1e270fe6e
50 changed files with 2448 additions and 29 deletions

View File

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

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

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

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

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

View 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

View 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 } */

View 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

View 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

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

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

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

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

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

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

View 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

View 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

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

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

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

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

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

View 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

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

View 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" } } */

View 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" } */
}

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

View 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]; }

View 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

View 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 } */
}

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

View 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

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

View 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:" } } */

View 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

View 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

View 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 } */

View 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

View 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);
}
}

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

View File

@ -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" } */
}
}

View File

@ -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" } */

View 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

View File

@ -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 */

View File

@ -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 */

View 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

View 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

View File

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

View 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

View 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);
}
}