diff options
-rw-r--r-- | gcc/objc/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/objc/objc-act.c | 17 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 2 | ||||
-rw-r--r-- | gcc/testsuite/obj-c++.dg/except-1.mm | 65 |
4 files changed, 89 insertions, 0 deletions
diff --git a/gcc/objc/ChangeLog b/gcc/objc/ChangeLog index 29b1d42..7418b0b 100644 --- a/gcc/objc/ChangeLog +++ b/gcc/objc/ChangeLog @@ -1,3 +1,8 @@ +2005-10-20 Geoffrey Keating <geoffk@apple.com> + + * objc-act.c (synth_module_prologue): Clear TREE_NOTHROW + on objc_msgSend and like builtin functions. + 2005-10-17 Andreas Krebbel <krebbel1@de.ibm.com> * objc-act.c (objc_build_component_ref): Adjust call to diff --git a/gcc/objc/objc-act.c b/gcc/objc/objc-act.c index 25bc6b1..f889c22 100644 --- a/gcc/objc/objc-act.c +++ b/gcc/objc/objc-act.c @@ -1597,6 +1597,10 @@ synth_module_prologue (void) (xref_tag (RECORD_TYPE, get_identifier (UTAG_IVAR_LIST))); + /* TREE_NOTHROW is cleared for the message-sending functions, + because the function that gets called can throw in Obj-C++, or + could itself call something that can throw even in Obj-C. */ + if (flag_next_runtime) { /* NB: In order to call one of the ..._stret (struct-returning) @@ -1626,12 +1630,21 @@ synth_module_prologue (void) type, 0, NOT_BUILT_IN, NULL, NULL_TREE); + /* These can throw, because the function that gets called can throw + in Obj-C++, or could itself call something that can throw even + in Obj-C. */ + TREE_NOTHROW (umsg_decl) = 0; + TREE_NOTHROW (umsg_nonnil_decl) = 0; + TREE_NOTHROW (umsg_stret_decl) = 0; + TREE_NOTHROW (umsg_nonnil_stret_decl) = 0; + /* id objc_msgSend_Fast (id, SEL, ...) __attribute__ ((hard_coded_address (OFFS_MSGSEND_FAST))); */ #ifdef OFFS_MSGSEND_FAST umsg_fast_decl = builtin_function (TAG_MSGSEND_FAST, type, 0, NOT_BUILT_IN, NULL, NULL_TREE); + TREE_NOTHROW (umsg_fast_decl) = 0; DECL_ATTRIBUTES (umsg_fast_decl) = tree_cons (get_identifier ("hard_coded_address"), build_int_cst (NULL_TREE, OFFS_MSGSEND_FAST), @@ -1654,6 +1667,8 @@ synth_module_prologue (void) umsg_super_stret_decl = builtin_function (TAG_MSGSENDSUPER_STRET, type, 0, NOT_BUILT_IN, 0, NULL_TREE); + TREE_NOTHROW (umsg_super_decl) = 0; + TREE_NOTHROW (umsg_super_stret_decl) = 0; } else { @@ -1676,6 +1691,7 @@ synth_module_prologue (void) umsg_decl = builtin_function (TAG_MSGSEND, type, 0, NOT_BUILT_IN, NULL, NULL_TREE); + TREE_NOTHROW (umsg_decl) = 0; /* IMP objc_msg_lookup_super (struct objc_super *, SEL); */ type @@ -1686,6 +1702,7 @@ synth_module_prologue (void) umsg_super_decl = builtin_function (TAG_MSGSENDSUPER, type, 0, NOT_BUILT_IN, NULL, NULL_TREE); + TREE_NOTHROW (umsg_super_decl) = 0; /* The following GNU runtime entry point is called to initialize each module: diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 98243dc..1ba72c7 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,5 +1,7 @@ 2005-10-20 Geoffrey Keating <geoffk@apple.com> + * obj-c++.dg/except-1.mm: New. + * obj-c++.dg/stubify-2.mm: Update the name of the RTL dump file. 2005-10-21 Alan Modra <amodra@bigpond.net.au> diff --git a/gcc/testsuite/obj-c++.dg/except-1.mm b/gcc/testsuite/obj-c++.dg/except-1.mm new file mode 100644 index 0000000..79eaf12 --- /dev/null +++ b/gcc/testsuite/obj-c++.dg/except-1.mm @@ -0,0 +1,65 @@ +/* { dg-do run { target "*-*-darwin*" } } */ +/* { dg-options "-framework Foundation" } */ + +/* This tests that exceptions work. It used to fail because + objc_msgSend was marked with DECL_NOTHROW. + If you include objc/Object.h, the problem goes away, because + that file includes objc/objc-runtime.h which explicitly prototypes + objc_msgSend without 'nothrow'. */ + +#include <Foundation/Foundation.h> +#include <stdio.h> +#include <stdlib.h> + +// ObjectiveC class header +@interface ObjCclass : NSObject { +} +-(void)method1; +-(void)method2; +@end + +// C++ class header +class CPPclass { +public: + void function1(); +}; + + +// Main +int main(int argc, char *argv[]) +{ + ObjCclass * foo = [[ObjCclass alloc] init]; + [foo method1]; + exit (0); +} + + +// ObjectiveC implementation +@implementation ObjCclass + +-(void) method1 +{ + try { + [self method2]; + } + catch(...) { + return; + } +} + +-(void) method2 +{ + CPPclass foo; + foo.function1(); +} + +@end + + +// C++ implementation +void CPPclass::function1() +{ + throw (1); + /* Shouldn't be here because we threw. */ + abort (); +} |