OSDN Git Service

* objc/execute/next_mapping.h: Update for C++.
authormrs <mrs@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 26 May 2005 01:53:56 +0000 (01:53 +0000)
committermrs <mrs@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 26 May 2005 01:53:56 +0000 (01:53 +0000)
        * obj-c++.dg/selector-1.mm: Move to...
        * obj-c++.dg/selector-4.mm: here...

        * obj-c++.dg/comp-types-1.mm: New.
        * obj-c++.dg/cxx-class-1.mm: New.
        * obj-c++.dg/cxx-ivars-1.mm: New.
        * obj-c++.dg/cxx-ivars-2.mm: New.
        * obj-c++.dg/cxx-ivars-3.mm: New.
        * obj-c++.dg/cxx-scope-1.mm: New.
        * obj-c++.dg/cxx-scope-2.mm: New.
        * obj-c++.dg/defs.mm: New.
        * obj-c++.dg/empty-private-1.mm: New.
        * obj-c++.dg/encode-1.mm: New.
        * obj-c++.dg/encode-2.mm: New.
        * obj-c++.dg/encode-3.mm: New.
        * obj-c++.dg/extern-c-1.mm: New.
        * obj-c++.dg/extra-semi.mm: New.
        * obj-c++.dg/fix-and-continue-2.mm: New.
        * obj-c++.dg/isa-field-1.mm: New.
        * obj-c++.dg/ivar-list-semi.mm: New.
        * obj-c++.dg/local-decl-1.mm: New.
        * obj-c++.dg/lookup-1.mm: New.
        * obj-c++.dg/lookup-2.mm: New.
        * obj-c++.dg/method-1.mm: New.
        * obj-c++.dg/method-2.mm: New.
        * obj-c++.dg/method-3.mm: New.
        * obj-c++.dg/method-4.mm: New.
        * obj-c++.dg/method-5.mm: New.
        * obj-c++.dg/method-6.mm: New.
        * obj-c++.dg/method-7.mm: New.
        * obj-c++.dg/no-extra-load.mm: New.
        * obj-c++.dg/overload-1.mm: New.
        * obj-c++.dg/pragma-1.mm: New.
        * obj-c++.dg/pragma-2.mm: New.
        * obj-c++.dg/private-1.mm: New.
        * obj-c++.dg/private-2.mm: New.
        * obj-c++.dg/proto-qual-1.mm: New.
        * obj-c++.dg/qual-types-1.mm: New.
        * obj-c++.dg/stubify-1.mm: New.
        * obj-c++.dg/stubify-2.mm: New.
        * obj-c++.dg/super-class-1.mm: New.
        * obj-c++.dg/super-class-2.mm: New.
        * obj-c++.dg/super-dealloc-1.mm: New.
        * obj-c++.dg/super-dealloc-2.mm: New.
        * obj-c++.dg/template-1.mm: New.
        * obj-c++.dg/template-2.mm: New.
        * obj-c++.dg/template-3.mm: New.
        * obj-c++.dg/template-4.mm: New.
        * obj-c++.dg/template-5.mm: New.
        * obj-c++.dg/template-6.mm: New.
        * obj-c++.dg/try-catch-1.mm: New.
        * obj-c++.dg/try-catch-2.mm: New.
        * obj-c++.dg/try-catch-3.mm: New.
        * obj-c++.dg/try-catch-4.mm: New.
        * obj-c++.dg/try-catch-5.mm: New.
        * obj-c++.dg/try-catch-6.mm: New.
        * obj-c++.dg/try-catch-7.mm: New.
        * obj-c++.dg/try-catch-8.mm: New.
        * obj-c++.dg/try-catch-9.mm: New.
        * obj-c++.dg/va-meth-1.mm: New.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@100181 138bc75d-0d04-0410-961f-82ee72b054a4

60 files changed:
gcc/testsuite/ChangeLog
gcc/testsuite/obj-c++.dg/comp-types-1.mm [new file with mode: 0644]
gcc/testsuite/obj-c++.dg/cxx-class-1.mm [new file with mode: 0644]
gcc/testsuite/obj-c++.dg/cxx-ivars-1.mm [new file with mode: 0644]
gcc/testsuite/obj-c++.dg/cxx-ivars-2.mm [new file with mode: 0644]
gcc/testsuite/obj-c++.dg/cxx-ivars-3.mm [new file with mode: 0644]
gcc/testsuite/obj-c++.dg/cxx-scope-1.mm [new file with mode: 0644]
gcc/testsuite/obj-c++.dg/cxx-scope-2.mm [new file with mode: 0644]
gcc/testsuite/obj-c++.dg/defs.mm [new file with mode: 0644]
gcc/testsuite/obj-c++.dg/empty-private-1.mm [new file with mode: 0644]
gcc/testsuite/obj-c++.dg/encode-1.mm [new file with mode: 0644]
gcc/testsuite/obj-c++.dg/encode-2.mm [new file with mode: 0644]
gcc/testsuite/obj-c++.dg/encode-3.mm [new file with mode: 0644]
gcc/testsuite/obj-c++.dg/extern-c-1.mm [new file with mode: 0644]
gcc/testsuite/obj-c++.dg/extra-semi.mm [new file with mode: 0644]
gcc/testsuite/obj-c++.dg/fix-and-continue-2.mm [new file with mode: 0644]
gcc/testsuite/obj-c++.dg/isa-field-1.mm [new file with mode: 0644]
gcc/testsuite/obj-c++.dg/ivar-list-semi.mm [new file with mode: 0644]
gcc/testsuite/obj-c++.dg/local-decl-1.mm [new file with mode: 0644]
gcc/testsuite/obj-c++.dg/lookup-1.mm [new file with mode: 0644]
gcc/testsuite/obj-c++.dg/lookup-2.mm [new file with mode: 0644]
gcc/testsuite/obj-c++.dg/method-1.mm [new file with mode: 0644]
gcc/testsuite/obj-c++.dg/method-2.mm [new file with mode: 0644]
gcc/testsuite/obj-c++.dg/method-3.mm [new file with mode: 0644]
gcc/testsuite/obj-c++.dg/method-4.mm [new file with mode: 0644]
gcc/testsuite/obj-c++.dg/method-5.mm [new file with mode: 0644]
gcc/testsuite/obj-c++.dg/method-6.mm [new file with mode: 0644]
gcc/testsuite/obj-c++.dg/method-7.mm [new file with mode: 0644]
gcc/testsuite/obj-c++.dg/no-extra-load.mm [new file with mode: 0644]
gcc/testsuite/obj-c++.dg/overload-1.mm [new file with mode: 0644]
gcc/testsuite/obj-c++.dg/pragma-1.mm [new file with mode: 0644]
gcc/testsuite/obj-c++.dg/pragma-2.mm [new file with mode: 0644]
gcc/testsuite/obj-c++.dg/private-1.mm [new file with mode: 0644]
gcc/testsuite/obj-c++.dg/private-2.mm [new file with mode: 0644]
gcc/testsuite/obj-c++.dg/proto-qual-1.mm [new file with mode: 0644]
gcc/testsuite/obj-c++.dg/qual-types-1.mm [new file with mode: 0644]
gcc/testsuite/obj-c++.dg/selector-1.mm
gcc/testsuite/obj-c++.dg/stubify-1.mm [new file with mode: 0644]
gcc/testsuite/obj-c++.dg/stubify-2.mm [new file with mode: 0644]
gcc/testsuite/obj-c++.dg/super-class-1.mm [new file with mode: 0644]
gcc/testsuite/obj-c++.dg/super-class-2.mm [new file with mode: 0644]
gcc/testsuite/obj-c++.dg/super-dealloc-1.mm [new file with mode: 0644]
gcc/testsuite/obj-c++.dg/super-dealloc-2.mm [new file with mode: 0644]
gcc/testsuite/obj-c++.dg/template-1.mm [new file with mode: 0644]
gcc/testsuite/obj-c++.dg/template-2.mm [new file with mode: 0644]
gcc/testsuite/obj-c++.dg/template-3.mm [new file with mode: 0644]
gcc/testsuite/obj-c++.dg/template-4.mm [new file with mode: 0644]
gcc/testsuite/obj-c++.dg/template-5.mm [new file with mode: 0644]
gcc/testsuite/obj-c++.dg/template-6.mm [new file with mode: 0644]
gcc/testsuite/obj-c++.dg/try-catch-1.mm [new file with mode: 0644]
gcc/testsuite/obj-c++.dg/try-catch-2.mm [new file with mode: 0644]
gcc/testsuite/obj-c++.dg/try-catch-3.mm [new file with mode: 0644]
gcc/testsuite/obj-c++.dg/try-catch-4.mm [new file with mode: 0644]
gcc/testsuite/obj-c++.dg/try-catch-5.mm [new file with mode: 0644]
gcc/testsuite/obj-c++.dg/try-catch-6.mm [new file with mode: 0644]
gcc/testsuite/obj-c++.dg/try-catch-7.mm [new file with mode: 0644]
gcc/testsuite/obj-c++.dg/try-catch-8.mm [new file with mode: 0644]
gcc/testsuite/obj-c++.dg/try-catch-9.mm [new file with mode: 0644]
gcc/testsuite/obj-c++.dg/va-meth-1.mm [new file with mode: 0644]
gcc/testsuite/objc/execute/next_mapping.h

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