* objc.dg/comp-types-8.m, objc.dg/encode-6.m,
authormrs <mrs@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 27 May 2005 02:55:21 +0000 (02:55 +0000)
committermrs <mrs@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 27 May 2005 02:55:21 +0000 (02:55 +0000)
        objc.dg/extra-semi.m, objc.dg/fix-and-continue-2.m,
        objc.dg/isa-field-1.m, objc.dg/lookup-1.m, objc.dg/method-15.m,
        objc.dg/method-16.m, objc.dg/method-17.m, objc.dg/method-18.m,
        objc.dg/method-19.m, objc.dg/next-runtime-1.m,
        objc.dg/no-extra-load.m, objc.dg/pragma-1.m, objc.dg/stubify-1.m,
        objc.dg/stubify-2.m, objc.dg/super-class-4.m,
        objc.dg/super-dealloc-1.m, objc.dg/super-dealloc-2.m,
        objc.dg/try-catch-6.m, objc.dg/try-catch-7.m,
        objc.dg/try-catch-8.m: New.

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

22 files changed:
gcc/testsuite/objc.dg/comp-types-8.m [new file with mode: 0644]
gcc/testsuite/objc.dg/encode-6.m [new file with mode: 0644]
gcc/testsuite/objc.dg/extra-semi.m [new file with mode: 0644]
gcc/testsuite/objc.dg/fix-and-continue-2.m [new file with mode: 0644]
gcc/testsuite/objc.dg/isa-field-1.m [new file with mode: 0644]
gcc/testsuite/objc.dg/lookup-1.m [new file with mode: 0644]
gcc/testsuite/objc.dg/method-15.m [new file with mode: 0644]
gcc/testsuite/objc.dg/method-16.m [new file with mode: 0644]
gcc/testsuite/objc.dg/method-17.m [new file with mode: 0644]
gcc/testsuite/objc.dg/method-18.m [new file with mode: 0644]
gcc/testsuite/objc.dg/method-19.m [new file with mode: 0644]
gcc/testsuite/objc.dg/next-runtime-1.m [new file with mode: 0644]
gcc/testsuite/objc.dg/no-extra-load.m [new file with mode: 0644]
gcc/testsuite/objc.dg/pragma-1.m [new file with mode: 0644]
gcc/testsuite/objc.dg/stubify-1.m [new file with mode: 0644]
gcc/testsuite/objc.dg/stubify-2.m [new file with mode: 0644]
gcc/testsuite/objc.dg/super-class-4.m [new file with mode: 0644]
gcc/testsuite/objc.dg/super-dealloc-1.m [new file with mode: 0644]
gcc/testsuite/objc.dg/super-dealloc-2.m [new file with mode: 0644]
gcc/testsuite/objc.dg/try-catch-6.m [new file with mode: 0644]
gcc/testsuite/objc.dg/try-catch-7.m [new file with mode: 0644]
gcc/testsuite/objc.dg/try-catch-8.m [new file with mode: 0644]

diff --git a/gcc/testsuite/objc.dg/comp-types-8.m b/gcc/testsuite/objc.dg/comp-types-8.m
new file mode 100644 (file)
index 0000000..7f9c64a
--- /dev/null
@@ -0,0 +1,24 @@
+/* { 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/objc.dg/encode-6.m b/gcc/testsuite/objc.dg/encode-6.m
new file mode 100644 (file)
index 0000000..263b02a
--- /dev/null
@@ -0,0 +1,22 @@
+/* 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/objc.dg/extra-semi.m b/gcc/testsuite/objc.dg/extra-semi.m
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/objc.dg/fix-and-continue-2.m b/gcc/testsuite/objc.dg/fix-and-continue-2.m
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/objc.dg/isa-field-1.m b/gcc/testsuite/objc.dg/isa-field-1.m
new file mode 100644 (file)
index 0000000..70edd0e
--- /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/objc.dg/lookup-1.m b/gcc/testsuite/objc.dg/lookup-1.m
new file mode 100644 (file)
index 0000000..eaabcb2
--- /dev/null
@@ -0,0 +1,54 @@
+/* { dg-do run } */
+
+#include <objc/Object.h>
+#include <stdlib.h>
+
+typedef struct MyWidget {
+  int a;
+} MyWidget;
+
+MyWidget gWidget = { 17 };
+
+@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/objc.dg/method-15.m b/gcc/testsuite/objc.dg/method-15.m
new file mode 100644 (file)
index 0000000..0ba3625
--- /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/objc.dg/method-16.m b/gcc/testsuite/objc.dg/method-16.m
new file mode 100644 (file)
index 0000000..c8394ff
--- /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/objc.dg/method-17.m b/gcc/testsuite/objc.dg/method-17.m
new file mode 100644 (file)
index 0000000..5e28ddc
--- /dev/null
@@ -0,0 +1,26 @@
+/* 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-warning "this function may return with or without a value" } */
+- (void) meth2 {
+  if (!bar)
+    return;
+  bar = 0;
+} /* { dg-bogus "this function may return with or without a value" } */
+@end
diff --git a/gcc/testsuite/objc.dg/method-18.m b/gcc/testsuite/objc.dg/method-18.m
new file mode 100644 (file)
index 0000000..77fd3ef
--- /dev/null
@@ -0,0 +1,29 @@
+/* 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/objc.dg/method-19.m b/gcc/testsuite/objc.dg/method-19.m
new file mode 100644 (file)
index 0000000..4716371
--- /dev/null
@@ -0,0 +1,17 @@
+/* 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/objc.dg/next-runtime-1.m b/gcc/testsuite/objc.dg/next-runtime-1.m
new file mode 100644 (file)
index 0000000..db14897
--- /dev/null
@@ -0,0 +1,18 @@
+/* Test that the correct version number (6) is set in the module descriptor
+   when compiling for the NeXT runtime.  */
+/* Author: Ziemowit Laski <zlaski@apple.com>  */
+
+/* { dg-do compile { target *-*-darwin* } } */
+/* { dg-options "-fnext-runtime" } */
+
+#include <objc/Object.h>
+
+@interface FooBar: Object
+- (void)boo;
+@end
+
+@implementation FooBar
+- (void)boo { }
+@end
+
+/* { dg-final { scan-assembler "L_OBJC_MODULES:\n\[ \t\]*\.long\t6\n" } } */
diff --git a/gcc/testsuite/objc.dg/no-extra-load.m b/gcc/testsuite/objc.dg/no-extra-load.m
new file mode 100644 (file)
index 0000000..9b50e83
--- /dev/null
@@ -0,0 +1,6 @@
+/* { dg-do compile { target *-*-darwin* } } */
+
+#import <Foundation/Foundation.h>
+main() { [NSObject new]; }
+
+/* { dg-final { scan-assembler-not "L_objc_msgSend\\\$non_lazy_ptr" } } */
diff --git a/gcc/testsuite/objc.dg/pragma-1.m b/gcc/testsuite/objc.dg/pragma-1.m
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/objc.dg/stubify-1.m b/gcc/testsuite/objc.dg/stubify-1.m
new file mode 100644 (file)
index 0000000..2b1aa61
--- /dev/null
@@ -0,0 +1,33 @@
+/* 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" } */
+
+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
+
+/* { 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/objc.dg/stubify-2.m b/gcc/testsuite/objc.dg/stubify-2.m
new file mode 100644 (file)
index 0000000..6e9b3a0
--- /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.m.03.jump "symbol_ref.*\"objc_msgSend\"" } } */
diff --git a/gcc/testsuite/objc.dg/super-class-4.m b/gcc/testsuite/objc.dg/super-class-4.m
new file mode 100644 (file)
index 0000000..5248123
--- /dev/null
@@ -0,0 +1,34 @@
+/* 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/objc.dg/super-dealloc-1.m b/gcc/testsuite/objc.dg/super-dealloc-1.m
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/objc.dg/super-dealloc-2.m b/gcc/testsuite/objc.dg/super-dealloc-2.m
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/objc.dg/try-catch-6.m b/gcc/testsuite/objc.dg/try-catch-6.m
new file mode 100644 (file)
index 0000000..5276f0f
--- /dev/null
@@ -0,0 +1,25 @@
+/* { 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/objc.dg/try-catch-7.m b/gcc/testsuite/objc.dg/try-catch-7.m
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/objc.dg/try-catch-8.m b/gcc/testsuite/objc.dg/try-catch-8.m
new file mode 100644 (file)
index 0000000..384faa3
--- /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;
+}