aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
Diffstat (limited to 'gcc')
-rw-r--r--gcc/testsuite/ChangeLog24
-rw-r--r--gcc/testsuite/obj-c++.dg/bitfield-1.mm113
-rw-r--r--gcc/testsuite/obj-c++.dg/bitfield-2.mm78
-rw-r--r--gcc/testsuite/obj-c++.dg/bitfield-3.mm57
-rw-r--r--gcc/testsuite/obj-c++.dg/bitfield-4.mm51
-rw-r--r--gcc/testsuite/obj-c++.dg/bitfield-5.mm29
-rw-r--r--gcc/testsuite/obj-c++.dg/class-protocol-1.mm442
-rw-r--r--gcc/testsuite/obj-c++.dg/comp-types-10.mm19
-rw-r--r--gcc/testsuite/obj-c++.dg/comp-types-11.mm28
-rw-r--r--gcc/testsuite/obj-c++.dg/comp-types-2.mm88
-rw-r--r--gcc/testsuite/obj-c++.dg/comp-types-3.mm38
-rw-r--r--gcc/testsuite/obj-c++.dg/comp-types-4.mm64
-rw-r--r--gcc/testsuite/obj-c++.dg/comp-types-5.mm74
-rw-r--r--gcc/testsuite/obj-c++.dg/comp-types-6.mm33
-rw-r--r--gcc/testsuite/obj-c++.dg/comp-types-7.mm38
-rw-r--r--gcc/testsuite/obj-c++.dg/comp-types-8.mm33
-rw-r--r--gcc/testsuite/obj-c++.dg/comp-types-9.mm25
-rw-r--r--gcc/testsuite/obj-c++.dg/encode-4.mm105
-rw-r--r--gcc/testsuite/obj-c++.dg/encode-5.mm74
-rw-r--r--gcc/testsuite/obj-c++.dg/encode-6.mm75
-rw-r--r--gcc/testsuite/obj-c++.dg/encode-7.mm78
-rw-r--r--gcc/testsuite/obj-c++.dg/encode-8.mm23
-rw-r--r--gcc/testsuite/obj-c++.dg/layout-1.mm15
-rw-r--r--gcc/testsuite/obj-c++.dg/method-10.mm45
-rw-r--r--gcc/testsuite/obj-c++.dg/method-11.mm25
-rw-r--r--gcc/testsuite/obj-c++.dg/method-12.mm31
-rw-r--r--gcc/testsuite/obj-c++.dg/method-13.mm27
-rw-r--r--gcc/testsuite/obj-c++.dg/method-14.mm14
-rw-r--r--gcc/testsuite/obj-c++.dg/method-15.mm43
-rw-r--r--gcc/testsuite/obj-c++.dg/method-16.mm34
-rw-r--r--gcc/testsuite/obj-c++.dg/method-17.mm32
-rw-r--r--gcc/testsuite/obj-c++.dg/method-18.mm25
-rw-r--r--gcc/testsuite/obj-c++.dg/method-19.mm81
-rw-r--r--gcc/testsuite/obj-c++.dg/method-20.mm17
-rw-r--r--gcc/testsuite/obj-c++.dg/method-21.mm25
-rw-r--r--gcc/testsuite/obj-c++.dg/method-8.mm30
-rw-r--r--gcc/testsuite/obj-c++.dg/method-9.mm33
-rw-r--r--gcc/testsuite/obj-c++.dg/objc-gc-3.mm63
-rw-r--r--gcc/testsuite/obj-c++.dg/try-catch-10.mm25
-rw-r--r--gcc/testsuite/objc.dg/bitfield-5.m113
-rw-r--r--gcc/testsuite/objc.dg/class-protocol-1.m28
-rw-r--r--gcc/testsuite/objc.dg/comp-types-1.m21
-rw-r--r--gcc/testsuite/objc.dg/comp-types-10.m28
-rw-r--r--gcc/testsuite/objc.dg/comp-types-5.m4
-rw-r--r--gcc/testsuite/objc.dg/comp-types-6.m5
-rw-r--r--gcc/testsuite/objc.dg/comp-types-9.m19
-rw-r--r--gcc/testsuite/objc.dg/layout-1.m15
-rw-r--r--gcc/testsuite/objc.dg/method-9.m2
-rw-r--r--gcc/testsuite/objc.dg/objc-gc-4.m63
-rw-r--r--gcc/testsuite/objc.dg/try-catch-9.m25
50 files changed, 2448 insertions, 29 deletions
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index c3d153f..e46a771 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -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
diff --git a/gcc/testsuite/obj-c++.dg/bitfield-1.mm b/gcc/testsuite/obj-c++.dg/bitfield-1.mm
new file mode 100644
index 0000000..c792025
--- /dev/null
+++ b/gcc/testsuite/obj-c++.dg/bitfield-1.mm
@@ -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;
+}
diff --git a/gcc/testsuite/obj-c++.dg/bitfield-2.mm b/gcc/testsuite/obj-c++.dg/bitfield-2.mm
new file mode 100644
index 0000000..7f778b5
--- /dev/null
+++ b/gcc/testsuite/obj-c++.dg/bitfield-2.mm
@@ -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;
+}
diff --git a/gcc/testsuite/obj-c++.dg/bitfield-3.mm b/gcc/testsuite/obj-c++.dg/bitfield-3.mm
new file mode 100644
index 0000000..d607a3e
--- /dev/null
+++ b/gcc/testsuite/obj-c++.dg/bitfield-3.mm
@@ -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;
+}
diff --git a/gcc/testsuite/obj-c++.dg/bitfield-4.mm b/gcc/testsuite/obj-c++.dg/bitfield-4.mm
new file mode 100644
index 0000000..4aa2a8b
--- /dev/null
+++ b/gcc/testsuite/obj-c++.dg/bitfield-4.mm
@@ -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;
+}
diff --git a/gcc/testsuite/obj-c++.dg/bitfield-5.mm b/gcc/testsuite/obj-c++.dg/bitfield-5.mm
new file mode 100644
index 0000000..b6716df
--- /dev/null
+++ b/gcc/testsuite/obj-c++.dg/bitfield-5.mm
@@ -0,0 +1,29 @@
+
+/* Make sure that bitfield types are printed correctly, and that ivar redeclaration
+ (@interface vs. @implementation) checks take the bitfield width into account. */
+/* Author: Ziemowit Laski <zlaski@apple.com> */
+/* { dg-do compile } */
+
+@interface Base {
+ int i;
+}
+@end
+
+@interface WithBitfields: Base {
+ void *isa;
+ unsigned a: 3;
+ signed b: 4;
+ int c: 5;
+}
+@end
+
+@implementation WithBitfields {
+ char *isa; /* { dg-error "conflicting instance variable type .char \\*isa." } */
+ /* { dg-error "previous declaration of .void \\*isa." "" { target *-*-* } 13 } */
+ unsigned a: 5; /* { dg-error "conflicting instance variable type .unsigned( int)? a: 5." } */
+ /* { dg-error "previous declaration of .unsigned( int)? a: 3." "" { target *-*-* } 14 } */
+ signed b: 4; /* This one is fine. */
+ int c: 3; /* { dg-error "conflicting instance variable type .int c: 3." } */
+ /* { dg-error "previous declaration of .int c: 5." "" { target *-*-* } 16 } */
+}
+@end
diff --git a/gcc/testsuite/obj-c++.dg/class-protocol-1.mm b/gcc/testsuite/obj-c++.dg/class-protocol-1.mm
new file mode 100644
index 0000000..b8200d0
--- /dev/null
+++ b/gcc/testsuite/obj-c++.dg/class-protocol-1.mm
@@ -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 } */
diff --git a/gcc/testsuite/obj-c++.dg/comp-types-10.mm b/gcc/testsuite/obj-c++.dg/comp-types-10.mm
new file mode 100644
index 0000000..3abcde5
--- /dev/null
+++ b/gcc/testsuite/obj-c++.dg/comp-types-10.mm
@@ -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
diff --git a/gcc/testsuite/obj-c++.dg/comp-types-11.mm b/gcc/testsuite/obj-c++.dg/comp-types-11.mm
new file mode 100644
index 0000000..8cd5340
--- /dev/null
+++ b/gcc/testsuite/obj-c++.dg/comp-types-11.mm
@@ -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
+
diff --git a/gcc/testsuite/obj-c++.dg/comp-types-2.mm b/gcc/testsuite/obj-c++.dg/comp-types-2.mm
new file mode 100644
index 0000000..0704378
--- /dev/null
+++ b/gcc/testsuite/obj-c++.dg/comp-types-2.mm
@@ -0,0 +1,88 @@
+/* Test various ObjC types assignments and comparisons. */
+/* Author: Nicola Pero <nicola@brainstorm.co.uk>. */
+/* { dg-do compile } */
+
+#include <objc/objc.h>
+
+@protocol MyProtocol
+- (void) foo;
+@end
+
+@interface MyClass
+@end
+
+@interface MyOtherClass <MyProtocol>
+- (void) foo;
+@end
+
+int main()
+{
+ id obj = nil;
+ id<MyProtocol> obj_p = nil;
+ MyClass *obj_c = nil;
+ MyOtherClass *obj_cp = nil;
+ Class obj_C = Nil;
+
+ /* Assigning to an 'id' variable should never
+ generate a warning. */
+ obj = obj_p; /* Ok */
+ obj = obj_c; /* Ok */
+ obj = obj_cp; /* Ok */
+ obj = obj_C; /* Ok */
+
+ /* Assigning to a 'MyClass *' variable should always generate a
+ warning, unless done from an 'id'. */
+ obj_c = obj; /* Ok */
+ obj_c = obj_p; /* { dg-warning "distinct Objective\\-C type" } */
+ obj_c = obj_cp; /* { dg-warning "distinct Objective\\-C type" } */
+ obj_c = obj_C; /* { dg-warning "distinct Objective\\-C type" } */
+
+ /* Assigning to an 'id<MyProtocol>' variable should generate a
+ warning if done from a 'MyClass *' (which doesn't implement
+ MyProtocol), but not from an 'id' or from a 'MyOtherClass *'
+ (which implements MyProtocol). */
+ obj_p = obj; /* Ok */
+ obj_p = obj_c; /* { dg-warning "does not implement" } */
+ obj_p = obj_cp; /* Ok */
+ obj_p = obj_C; /* { dg-warning "distinct Objective\\-C type" } */
+
+ /* Assigning to a 'MyOtherClass *' variable should always generate
+ a warning, unless done from an 'id' or an 'id<MyProtocol>' (since
+ MyOtherClass implements MyProtocol). */
+ obj_cp = obj; /* Ok */
+ obj_cp = obj_c; /* { dg-warning "distinct Objective\\-C type" } */
+ obj_cp = obj_p; /* Ok */
+ obj_cp = obj_C; /* { dg-warning "distinct Objective\\-C type" } */
+
+ /* Any comparison involving an 'id' must be without warnings. */
+ if (obj == obj_p) ; /* Ok */ /*Bogus warning here in 2.95.4*/
+ if (obj_p == obj) ; /* Ok */
+ if (obj == obj_c) ; /* Ok */
+ if (obj_c == obj) ; /* Ok */
+ if (obj == obj_cp) ; /* Ok */
+ if (obj_cp == obj) ; /* Ok */
+ if (obj == obj_C) ; /* Ok */
+ if (obj_C == obj) ; /* Ok */
+
+ /* Any comparison between 'MyClass *' and anything which is not an 'id'
+ must generate a warning. */
+ if (obj_c == obj_p) ; /* { dg-warning "lacks a cast" } */
+ if (obj_p == obj_c) ; /* { dg-warning "lacks a cast" } */
+ if (obj_c == obj_cp) ; /* { dg-warning "lacks a cast" } */
+ if (obj_cp == obj_c) ; /* { dg-warning "lacks a cast" } */
+ if (obj_c == obj_C) ; /* { dg-warning "lacks a cast" } */
+ if (obj_C == obj_c) ; /* { dg-warning "lacks a cast" } */
+
+ /* Any comparison between 'MyOtherClass *' (which implements
+ MyProtocol) and an 'id' implementing MyProtocol are Ok. */
+ if (obj_cp == obj_p) ; /* Ok */
+ if (obj_p == obj_cp) ; /* Ok */
+
+
+ if (obj_p == obj_C) ; /* { dg-warning "lacks a cast" } */
+ if (obj_C == obj_p) ; /* { dg-warning "lacks a cast" } */
+ if (obj_cp == obj_C) ; /* { dg-warning "lacks a cast" } */
+ if (obj_C == obj_cp) ; /* { dg-warning "lacks a cast" } */
+
+ return 0;
+}
diff --git a/gcc/testsuite/obj-c++.dg/comp-types-3.mm b/gcc/testsuite/obj-c++.dg/comp-types-3.mm
new file mode 100644
index 0000000..2bea015
--- /dev/null
+++ b/gcc/testsuite/obj-c++.dg/comp-types-3.mm
@@ -0,0 +1,38 @@
+/* Test simple ObjC types casts. */
+/* Author: Nicola Pero <nicola@brainstorm.co.uk>. */
+/* { dg-do compile } */
+
+#include <objc/objc.h>
+
+@protocol MyProtocol
+- (void) foo;
+@end
+
+@interface MyClass
+@end
+
+int main()
+{
+ id obj = nil;
+ id<MyProtocol> obj_p = nil;
+ MyClass *obj_c = nil;
+ Class obj_C = Nil;
+
+ /* All these casts should generate no warnings. */
+
+ obj = (id)obj_p;
+ obj = (id)obj_c;
+ obj = (id)obj_C;
+ obj_c = (MyClass *)obj;
+ obj_c = (MyClass *)obj_p;
+ obj_c = (MyClass *)obj_C;
+ obj_p = (id<MyProtocol>)obj;
+ obj_p = (id<MyProtocol>)obj_c;
+ obj_p = (id<MyProtocol>)obj_C;
+ obj_C = (Class)obj;
+ obj_C = (Class)obj_p;
+ obj_C = (Class)obj_c;
+
+
+ return 0;
+}
diff --git a/gcc/testsuite/obj-c++.dg/comp-types-4.mm b/gcc/testsuite/obj-c++.dg/comp-types-4.mm
new file mode 100644
index 0000000..6867f82
--- /dev/null
+++ b/gcc/testsuite/obj-c++.dg/comp-types-4.mm
@@ -0,0 +1,64 @@
+/* Test assignments and comparisons between protocols (obscure case). */
+/* Author: Nicola Pero <nicola@brainstorm.co.uk>. */
+/* { dg-do compile } */
+
+#include <objc/objc.h>
+
+@protocol MyProtocolA
+- (void) methodA;
+@end
+
+@protocol MyProtocolB
+- (void) methodB;
+@end
+
+@protocol MyProtocolAB <MyProtocolA, MyProtocolB>
+@end
+
+@protocol MyProtocolAC <MyProtocolA>
+- (void) methodC;
+@end
+
+int main()
+{
+ id<MyProtocolA> obj_a = nil;
+ id<MyProtocolB> obj_b = nil;
+ id<MyProtocolAB> obj_ab = nil;
+ id<MyProtocolAC> obj_ac = nil;
+
+ obj_a = obj_b; /* { dg-warning "does not conform" } */
+ obj_a = obj_ab; /* Ok */
+ obj_a = obj_ac; /* Ok */
+
+ obj_b = obj_a; /* { dg-warning "does not conform" } */
+ obj_b = obj_ab; /* Ok */
+ obj_b = obj_ac; /* { dg-warning "does not conform" } */
+
+ obj_ab = obj_a; /* { dg-warning "does not conform" } */
+ obj_ab = obj_b; /* { dg-warning "does not conform" } */
+ obj_ab = obj_ac; /* { dg-warning "does not conform" } */
+
+ obj_ac = obj_a; /* { dg-warning "does not conform" } */
+ obj_ac = obj_b; /* { dg-warning "does not conform" } */
+ obj_ac = obj_ab; /* { dg-warning "does not conform" } */
+
+ if (obj_a == obj_b) ; /* { dg-warning "lacks a cast" } */
+ if (obj_b == obj_a) ; /* { dg-warning "lacks a cast" } */
+
+ if (obj_a == obj_ab) ; /* Ok */
+ if (obj_ab == obj_a) ; /* Ok */ /* Spurious 2.95.4 warning here */
+
+ if (obj_a == obj_ac) ; /* Ok */
+ if (obj_ac == obj_a) ; /* Ok */ /* Spurious 2.95.4 warning here */
+
+ if (obj_b == obj_ab) ; /* Ok */
+ if (obj_ab == obj_b) ; /* Ok */ /* Spurious 2.95.4 warning here */
+
+ if (obj_b == obj_ac) ; /* { dg-warning "lacks a cast" } */
+ if (obj_ac == obj_b) ; /* { dg-warning "lacks a cast" } */
+
+ if (obj_ab == obj_ac) ; /* { dg-warning "lacks a cast" } */
+ if (obj_ac == obj_ab) ; /* { dg-warning "lacks a cast" } */
+
+ return 0;
+}
diff --git a/gcc/testsuite/obj-c++.dg/comp-types-5.mm b/gcc/testsuite/obj-c++.dg/comp-types-5.mm
new file mode 100644
index 0000000..99f6772
--- /dev/null
+++ b/gcc/testsuite/obj-c++.dg/comp-types-5.mm
@@ -0,0 +1,74 @@
+/* Test errors for assignments and comparisons between ObjC and C++ types. */
+/* Author: Nicola Pero <nicola@brainstorm.co.uk>. */
+/* { dg-do compile } */
+
+#include <objc/objc.h>
+
+/* The NeXT runtime headers do not define NULL. */
+#ifndef NULL
+#define NULL ((void *)0)
+#endif
+
+@protocol MyProtocol
+- (void) method;
+@end
+
+@interface MyClass
+@end
+
+int main()
+{
+ id obj = nil;
+ id <MyProtocol> obj_p = nil;
+ MyClass *obj_c = nil;
+ Class obj_C = Nil;
+
+ int i = 0;
+ int *j = (int *)NULL;
+
+ /* These should all generate warnings. */
+
+ obj = i; /* { dg-error "invalid conversion" } */
+ obj = j; /* { dg-error "cannot convert" } */
+
+ obj_p = i; /* { dg-error "invalid conversion" } */
+ obj_p = j; /* { dg-error "cannot convert" } */
+
+ obj_c = i; /* { dg-error "invalid conversion" } */
+ obj_c = j; /* { dg-error "cannot convert" } */
+
+ obj_C = i; /* { dg-error "invalid conversion" } */
+ obj_C = j; /* { dg-error "cannot convert" } */
+
+ i = obj; /* { dg-error "invalid conversion" } */
+ i = obj_p; /* { dg-error "invalid conversion" } */
+ i = obj_c; /* { dg-error "invalid conversion" } */
+ i = obj_C; /* { dg-error "invalid conversion" } */
+
+ j = obj; /* { dg-error "cannot convert" } */
+ j = obj_p; /* { dg-error "cannot convert" } */
+ j = obj_c; /* { dg-error "cannot convert" } */
+ j = obj_C; /* { dg-error "cannot convert" } */
+
+ if (obj == i) ; /* { dg-error "comparison between pointer and integer" } */
+ if (i == obj) ; /* { dg-error "comparison between pointer and integer" } */
+ if (obj == j) ; /* { dg-error "lacks a cast" } */
+ if (j == obj) ; /* { dg-error "lacks a cast" } */
+
+ if (obj_c == i) ; /*{ dg-error "comparison between pointer and integer" }*/
+ if (i == obj_c) ; /*{ dg-error "comparison between pointer and integer" }*/
+ if (obj_c == j) ; /* { dg-error "lacks a cast" } */
+ if (j == obj_c) ; /* { dg-error "lacks a cast" } */
+
+ if (obj_p == i) ; /*{ dg-error "comparison between pointer and integer" }*/
+ if (i == obj_p) ; /*{ dg-error "comparison between pointer and integer" }*/
+ if (obj_p == j) ; /* { dg-error "lacks a cast" } */
+ if (j == obj_p) ; /* { dg-error "lacks a cast" } */
+
+ if (obj_C == i) ; /*{ dg-error "comparison between pointer and integer" }*/
+ if (i == obj_C) ; /*{ dg-error "comparison between pointer and integer" }*/
+ if (obj_C == j) ; /* { dg-error "lacks a cast" } */
+ if (j == obj_C) ; /* { dg-error "lacks a cast" } */
+
+ return 0;
+}
diff --git a/gcc/testsuite/obj-c++.dg/comp-types-6.mm b/gcc/testsuite/obj-c++.dg/comp-types-6.mm
new file mode 100644
index 0000000..23b84ed
--- /dev/null
+++ b/gcc/testsuite/obj-c++.dg/comp-types-6.mm
@@ -0,0 +1,33 @@
+/* Test assignments and comparisons involving `one-off' protocols. */
+/* Author: Nicola Pero <nicola@brainstorm.co.uk>. */
+/* { dg-do compile } */
+
+#include <objc/objc.h>
+
+@protocol MyProtocol
+- (void) method;
+@end
+
+@interface MyClass
+@end
+
+int main()
+{
+ id obj = nil;
+ id <MyProtocol> obj_p = nil;
+ MyClass<MyProtocol> *obj_cp = nil;
+
+ obj_cp = obj; /* Ok */
+ obj = obj_cp; /* Ok */
+
+ obj_cp = obj_p; /* Ok */
+ obj_p = obj_cp; /* Ok */
+
+ if (obj_cp == obj) ; /* Ok */
+ if (obj == obj_cp) ; /* Ok */
+
+ if (obj_cp == obj_p) ; /* Ok */
+ if (obj_p == obj_cp) ; /* Ok */
+
+ return 0;
+}
diff --git a/gcc/testsuite/obj-c++.dg/comp-types-7.mm b/gcc/testsuite/obj-c++.dg/comp-types-7.mm
new file mode 100644
index 0000000..e235581
--- /dev/null
+++ b/gcc/testsuite/obj-c++.dg/comp-types-7.mm
@@ -0,0 +1,38 @@
+/* Test assignments and comparisons involving category protocols. */
+/* Author: Nicola Pero <nicola@brainstorm.co.uk>. */
+/* { dg-do compile } */
+
+#include <objc/objc.h>
+
+@protocol MyProtocol
+- (void) method;
+@end
+
+@interface MyClass
+@end
+
+@interface MyClass (Addition) <MyProtocol>
+- (void) method;
+@end
+
+@interface MyOtherClass : MyClass
+@end
+
+int main()
+{
+ id <MyProtocol> obj_p = nil;
+ MyClass *obj_cp = nil;
+ MyOtherClass *obj_cp2 = nil;
+
+ obj_cp = obj_p; /* { dg-warning "distinct Objective\\-C type" } */
+ obj_cp2 = obj_p; /* { dg-warning "distinct Objective\\-C type" } */
+ obj_p = obj_cp; /* Ok */
+ obj_p = obj_cp2; /* Ok */
+
+ if (obj_cp == obj_p) ; /* Ok */
+ if (obj_cp2 == obj_p) ; /* Ok */
+ if (obj_p == obj_cp) ; /* Ok */
+ if (obj_p == obj_cp2) ; /* Ok */
+
+ return 0;
+}
diff --git a/gcc/testsuite/obj-c++.dg/comp-types-8.mm b/gcc/testsuite/obj-c++.dg/comp-types-8.mm
new file mode 100644
index 0000000..490f4ff
--- /dev/null
+++ b/gcc/testsuite/obj-c++.dg/comp-types-8.mm
@@ -0,0 +1,33 @@
+/* { dg-do compile } */
+
+/* We used to ICE because we removed the cast to List_linked*
+ in -[ListIndex_linked next]. */
+
+@interface List
+{
+@public
+ int firstLink;
+}
+@end
+
+@interface ListIndex_linked
+{
+@public
+ List *collection;
+ int link;
+}
+@end
+
+@interface List_linked: List
+@end
+
+@implementation List
+@end
+
+@implementation ListIndex_linked
+- next
+{
+ link = ((List_linked*)collection)->firstLink;
+}
+@end
+
diff --git a/gcc/testsuite/obj-c++.dg/comp-types-9.mm b/gcc/testsuite/obj-c++.dg/comp-types-9.mm
new file mode 100644
index 0000000..f092c9e
--- /dev/null
+++ b/gcc/testsuite/obj-c++.dg/comp-types-9.mm
@@ -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
diff --git a/gcc/testsuite/obj-c++.dg/encode-4.mm b/gcc/testsuite/obj-c++.dg/encode-4.mm
new file mode 100644
index 0000000..25c0b50
--- /dev/null
+++ b/gcc/testsuite/obj-c++.dg/encode-4.mm
@@ -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;
+}
diff --git a/gcc/testsuite/obj-c++.dg/encode-5.mm b/gcc/testsuite/obj-c++.dg/encode-5.mm
new file mode 100644
index 0000000..9a36326
--- /dev/null
+++ b/gcc/testsuite/obj-c++.dg/encode-5.mm
@@ -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;
+}
diff --git a/gcc/testsuite/obj-c++.dg/encode-6.mm b/gcc/testsuite/obj-c++.dg/encode-6.mm
new file mode 100644
index 0000000..1ee1171
--- /dev/null
+++ b/gcc/testsuite/obj-c++.dg/encode-6.mm
@@ -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;
+}
diff --git a/gcc/testsuite/obj-c++.dg/encode-7.mm b/gcc/testsuite/obj-c++.dg/encode-7.mm
new file mode 100644
index 0000000..f2cb693
--- /dev/null
+++ b/gcc/testsuite/obj-c++.dg/encode-7.mm
@@ -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;
+}
diff --git a/gcc/testsuite/obj-c++.dg/encode-8.mm b/gcc/testsuite/obj-c++.dg/encode-8.mm
new file mode 100644
index 0000000..5f61cb8
--- /dev/null
+++ b/gcc/testsuite/obj-c++.dg/encode-8.mm
@@ -0,0 +1,23 @@
+/* Test if the Objective-C @encode machinery distinguishes between
+ 'BOOL *' (which should be encoded as '^c') and 'char *' (which
+ should be encoded as '*'). */
+/* Contributed by Ziemowit Laski <zlaski@apple.com>. */
+/* { dg-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;
+}
diff --git a/gcc/testsuite/obj-c++.dg/layout-1.mm b/gcc/testsuite/obj-c++.dg/layout-1.mm
new file mode 100644
index 0000000..fe8ab3d
--- /dev/null
+++ b/gcc/testsuite/obj-c++.dg/layout-1.mm
@@ -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
+
diff --git a/gcc/testsuite/obj-c++.dg/method-10.mm b/gcc/testsuite/obj-c++.dg/method-10.mm
new file mode 100644
index 0000000..4c7ccb8
--- /dev/null
+++ b/gcc/testsuite/obj-c++.dg/method-10.mm
@@ -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;
+}
diff --git a/gcc/testsuite/obj-c++.dg/method-11.mm b/gcc/testsuite/obj-c++.dg/method-11.mm
new file mode 100644
index 0000000..c8d092d
--- /dev/null
+++ b/gcc/testsuite/obj-c++.dg/method-11.mm
@@ -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" } } */
diff --git a/gcc/testsuite/obj-c++.dg/method-12.mm b/gcc/testsuite/obj-c++.dg/method-12.mm
new file mode 100644
index 0000000..21f4bb9
--- /dev/null
+++ b/gcc/testsuite/obj-c++.dg/method-12.mm
@@ -0,0 +1,31 @@
+/* Check that sending messages to variables of type 'Class' does not involve instance methods, unless they reside in root classes. */
+/* Author: Ziemowit Laski <zlaski@apple.com> */
+/* { dg-options "-Wstrict-selector-match" } */
+/* { dg-do compile } */
+
+#include <objc/Protocol.h>
+
+@interface Base
+- (unsigned)port;
+@end
+
+@interface Derived: Base
+- (Object *)port;
++ (Protocol *)port;
+- (id)starboard;
+@end
+
+void foo(void) {
+ Class receiver;
+
+ [receiver port]; /* { dg-warning "multiple methods named .\\+port. found" } */
+ /* { dg-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" } */
+}
diff --git a/gcc/testsuite/obj-c++.dg/method-13.mm b/gcc/testsuite/obj-c++.dg/method-13.mm
new file mode 100644
index 0000000..adf6dfe
--- /dev/null
+++ b/gcc/testsuite/obj-c++.dg/method-13.mm
@@ -0,0 +1,27 @@
+/* Check if finding multiple signatures for a method is handled gracefully. Author: Ziemowit Laski <zlaski@apple.com> */
+/* { dg-options "-Wstrict-selector-match" } */
+/* { dg-do compile } */
+
+#include <objc/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;
+}
diff --git a/gcc/testsuite/obj-c++.dg/method-14.mm b/gcc/testsuite/obj-c++.dg/method-14.mm
new file mode 100644
index 0000000..4a13b7d
--- /dev/null
+++ b/gcc/testsuite/obj-c++.dg/method-14.mm
@@ -0,0 +1,14 @@
+/* Check if casting the receiver type causes method lookup to succeed. This was broken
+ in Objective-C++. */
+/* Contributed by Ziemowit Laski <zlaski@apple.com> */
+/* { dg-do compile } */
+
+@interface A
+@end
+
+@interface B: A
+- (void)f;
+@end
+
+void g(A *p) { [(B *)p f]; }
+
diff --git a/gcc/testsuite/obj-c++.dg/method-15.mm b/gcc/testsuite/obj-c++.dg/method-15.mm
new file mode 100644
index 0000000..9d9099e
--- /dev/null
+++ b/gcc/testsuite/obj-c++.dg/method-15.mm
@@ -0,0 +1,43 @@
+/* Check if finding multiple signatures for a method is handled gracefully when method lookup succeeds (see also method-7.m). */
+/* Contributed by Ziemowit Laski <zlaski@apple.com> */
+/* { dg-options "-Wstrict-selector-match" } */
+/* { dg-do compile } */
+
+#include <objc/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
diff --git a/gcc/testsuite/obj-c++.dg/method-16.mm b/gcc/testsuite/obj-c++.dg/method-16.mm
new file mode 100644
index 0000000..f4a9efc
--- /dev/null
+++ b/gcc/testsuite/obj-c++.dg/method-16.mm
@@ -0,0 +1,34 @@
+
+/* Ensure that we indeed cannot obtain the value of a message send
+ if the chosen method signature returns 'void'. There used to
+ exist a cheesy hack that allowed it. While at it, check that
+ the first lexically occurring method signature gets picked
+ when sending messages to 'id'. */
+/* Contributed by Ziemowit Laski <zlaski@apple.com> */
+/* { dg-do compile } */
+
+#include <objc/objc.h>
+
+@interface Object1
+- (void)initWithData:(Object1 *)data;
+@end
+
+@interface Object2
+- (id)initWithData:(Object1 *)data;
+@end
+
+@interface Object3
+- (id)initWithData:(Object2 *)data;
+@end
+
+void foo(void) {
+ id obj1, obj2 = 0;
+ obj2 = [obj1 initWithData: obj2];
+ /* { dg-warning "multiple methods named .\\-initWithData:. found" "" { target *-*-* } 26 } */
+ /* { dg-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 } */
+}
diff --git a/gcc/testsuite/obj-c++.dg/method-17.mm b/gcc/testsuite/obj-c++.dg/method-17.mm
new file mode 100644
index 0000000..556830f
--- /dev/null
+++ b/gcc/testsuite/obj-c++.dg/method-17.mm
@@ -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;
+}
+
diff --git a/gcc/testsuite/obj-c++.dg/method-18.mm b/gcc/testsuite/obj-c++.dg/method-18.mm
new file mode 100644
index 0000000..411caac
--- /dev/null
+++ b/gcc/testsuite/obj-c++.dg/method-18.mm
@@ -0,0 +1,25 @@
+/* Contributed by Igor Seleznev <selez@mail.ru>. */
+/* This used to be broken. */
+
+#include <objc/objc.h>
+
+@interface A
++ (A *)currentContext;
+@end
+
+@interface B
++ (B *)currentContext;
+@end
+
+int main()
+{
+ [A currentContext]; /* { dg-bogus "multiple declarations" } */
+ return 0;
+}
+
+@implementation A
++ (A *)currentContext { return nil; }
+@end
+@implementation B
++ (B *)currentContext { return nil; }
+@end
diff --git a/gcc/testsuite/obj-c++.dg/method-19.mm b/gcc/testsuite/obj-c++.dg/method-19.mm
new file mode 100644
index 0000000..55890f5
--- /dev/null
+++ b/gcc/testsuite/obj-c++.dg/method-19.mm
@@ -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;
+}
diff --git a/gcc/testsuite/obj-c++.dg/method-20.mm b/gcc/testsuite/obj-c++.dg/method-20.mm
new file mode 100644
index 0000000..9698225
--- /dev/null
+++ b/gcc/testsuite/obj-c++.dg/method-20.mm
@@ -0,0 +1,17 @@
+/* Test if context-sensitive "in", "out", "byref", etc., qualifiers can be
+ used as method selectors. */
+/* Author: Ziemowit Laski <zlaski@apple.com>. */
+/* { dg-do compile } */
+
+@interface Foo
+- (void)insertNewButtonImage:(Foo *)newButtonImage in:(Foo *)buttonCell;
++ (oneway void)oneway:(int)i2 byref:(int)i3 out:(float)f4 bycopy:(float)f5;
+@end
+
+@implementation Foo
+- (void)insertNewButtonImage:(Foo *)newButtonImage in:(Foo *)buttonCell { }
++ (oneway void)oneway:(int)i2 byref:(int)i3 out:(float)f4 bycopy:(float)f5 { }
+@end
+
+/* { dg-final { scan-assembler "insertNewButtonImage:in:" } } */
+/* { dg-final { scan-assembler "oneway:byref:out:bycopy:" } } */
diff --git a/gcc/testsuite/obj-c++.dg/method-21.mm b/gcc/testsuite/obj-c++.dg/method-21.mm
new file mode 100644
index 0000000..94291a5
--- /dev/null
+++ b/gcc/testsuite/obj-c++.dg/method-21.mm
@@ -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
diff --git a/gcc/testsuite/obj-c++.dg/method-8.mm b/gcc/testsuite/obj-c++.dg/method-8.mm
new file mode 100644
index 0000000..310437a
--- /dev/null
+++ b/gcc/testsuite/obj-c++.dg/method-8.mm
@@ -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
diff --git a/gcc/testsuite/obj-c++.dg/method-9.mm b/gcc/testsuite/obj-c++.dg/method-9.mm
new file mode 100644
index 0000000..4509c4a
--- /dev/null
+++ b/gcc/testsuite/obj-c++.dg/method-9.mm
@@ -0,0 +1,33 @@
+/* Test for lookup of class (factory) methods. */
+/* Author: Ziemowit Laski <zlaski@apple.com>. */
+/* { dg-do compile } */
+
+@interface MyBase
+- (void) rootInstanceMethod;
+@end
+
+@interface MyIntermediate: MyBase
+@end
+
+@interface MyDerived: MyIntermediate
+- (void) instanceMethod;
++ (void) classMethod;
+@end
+
+@implementation MyDerived
+- (void) instanceMethod {
+}
+
++ (void) classMethod { /* If a class method is not found, the root */
+ [self rootInstanceMethod]; /* class is searched for an instance method */
+ [MyIntermediate rootInstanceMethod]; /* with the same name. */
+
+ [self instanceMethod]; /* { dg-warning ".MyDerived. may not respond to .\\+instanceMethod." } */
+ [MyDerived instanceMethod]; /* { dg-warning ".MyDerived. may not respond to .\\+instanceMethod." } */
+}
+@end
+
+/* { dg-warning "Messages without a matching method signature" "" { target *-*-* } 0 } */
+/* { dg-warning "will be assumed to return .id. and accept" "" { target *-*-* } 0 } */
+/* { dg-warning ".\.\.\.. as arguments" "" { target *-*-* } 0 } */
+
diff --git a/gcc/testsuite/obj-c++.dg/objc-gc-3.mm b/gcc/testsuite/obj-c++.dg/objc-gc-3.mm
new file mode 100644
index 0000000..df0a44c
--- /dev/null
+++ b/gcc/testsuite/obj-c++.dg/objc-gc-3.mm
@@ -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
diff --git a/gcc/testsuite/obj-c++.dg/try-catch-10.mm b/gcc/testsuite/obj-c++.dg/try-catch-10.mm
new file mode 100644
index 0000000..5f6daa4
--- /dev/null
+++ b/gcc/testsuite/obj-c++.dg/try-catch-10.mm
@@ -0,0 +1,25 @@
+/* Check that taking the address of a local variable marked 'volatile'
+ by the compiler does not generate untoward errors. */
+/* Developed by Ziemowit Laski <zlaski@apple.com>. */
+
+/* { dg-options "-fobjc-exceptions" } */
+/* { dg-do compile } */
+
+
+void foo (int *arg1, int *arg2)
+{
+ *arg1 = *arg2;
+}
+
+void bar (int arg) {
+ int rcvr;
+
+ @try {
+ rcvr = arg;
+ }
+ @finally {
+ int *rcvr0 = &rcvr;
+ foo (rcvr0, &arg);
+ }
+}
+
diff --git a/gcc/testsuite/objc.dg/bitfield-5.m b/gcc/testsuite/objc.dg/bitfield-5.m
new file mode 100644
index 0000000..ddd3b03
--- /dev/null
+++ b/gcc/testsuite/objc.dg/bitfield-5.m
@@ -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;
+}
diff --git a/gcc/testsuite/objc.dg/class-protocol-1.m b/gcc/testsuite/objc.dg/class-protocol-1.m
index ffa2435..f97f231 100644
--- a/gcc/testsuite/objc.dg/class-protocol-1.m
+++ b/gcc/testsuite/objc.dg/class-protocol-1.m
@@ -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" } */
}
}
diff --git a/gcc/testsuite/objc.dg/comp-types-1.m b/gcc/testsuite/objc.dg/comp-types-1.m
index 310b226..5bf59a7 100644
--- a/gcc/testsuite/objc.dg/comp-types-1.m
+++ b/gcc/testsuite/objc.dg/comp-types-1.m
@@ -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" } */
diff --git a/gcc/testsuite/objc.dg/comp-types-10.m b/gcc/testsuite/objc.dg/comp-types-10.m
new file mode 100644
index 0000000..8cd5340
--- /dev/null
+++ b/gcc/testsuite/objc.dg/comp-types-10.m
@@ -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
+
diff --git a/gcc/testsuite/objc.dg/comp-types-5.m b/gcc/testsuite/objc.dg/comp-types-5.m
index f4d3dfc..c112ecb 100644
--- a/gcc/testsuite/objc.dg/comp-types-5.m
+++ b/gcc/testsuite/objc.dg/comp-types-5.m
@@ -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 */
diff --git a/gcc/testsuite/objc.dg/comp-types-6.m b/gcc/testsuite/objc.dg/comp-types-6.m
index 9403b53..e235581 100644
--- a/gcc/testsuite/objc.dg/comp-types-6.m
+++ b/gcc/testsuite/objc.dg/comp-types-6.m
@@ -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 */
diff --git a/gcc/testsuite/objc.dg/comp-types-9.m b/gcc/testsuite/objc.dg/comp-types-9.m
new file mode 100644
index 0000000..3abcde5
--- /dev/null
+++ b/gcc/testsuite/objc.dg/comp-types-9.m
@@ -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
diff --git a/gcc/testsuite/objc.dg/layout-1.m b/gcc/testsuite/objc.dg/layout-1.m
new file mode 100644
index 0000000..6fb1142
--- /dev/null
+++ b/gcc/testsuite/objc.dg/layout-1.m
@@ -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
+
diff --git a/gcc/testsuite/objc.dg/method-9.m b/gcc/testsuite/objc.dg/method-9.m
index 28f6a1b..ade5d64 100644
--- a/gcc/testsuite/objc.dg/method-9.m
+++ b/gcc/testsuite/objc.dg/method-9.m
@@ -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
diff --git a/gcc/testsuite/objc.dg/objc-gc-4.m b/gcc/testsuite/objc.dg/objc-gc-4.m
new file mode 100644
index 0000000..df0a44c
--- /dev/null
+++ b/gcc/testsuite/objc.dg/objc-gc-4.m
@@ -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
diff --git a/gcc/testsuite/objc.dg/try-catch-9.m b/gcc/testsuite/objc.dg/try-catch-9.m
new file mode 100644
index 0000000..5f6daa4
--- /dev/null
+++ b/gcc/testsuite/objc.dg/try-catch-9.m
@@ -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);
+ }
+}
+