This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
PATCH: Fix TYPE_LANG_SPECIFIC() lossage during volatilization
- From: Ziemowit Laski <zlaski at apple dot com>
- To: patch Patches <gcc-patches at gcc dot gnu dot org>
- Date: Thu, 30 Jun 2005 18:43:01 -0700
- Subject: PATCH: Fix TYPE_LANG_SPECIFIC() lossage during volatilization
Using ObjC exception handling on Darwin requires that local variables
be marked 'volatile' so as to not get clobbered by _setjmp()/_longjmp()
that the EH mechanism uses. To do this, objc_volatilize_decl() calls
get_qualified_type(); unfortunately, the latter knows nothing about
TYPE_LANG_SPECIFIC info and has a tendency to misplace it. So, we
roll our own objc_get_volatilized_type() instead.
[gcc/objc/ChangeLog]
2005-06-30 Ziemowit Laski <zlaski@apple.com>
* objc-act.c (objc_build_volatilized_type): New function.
(objc_volatilize_decl): Call objc_build_volatilized_type()
instead of build_qualified_type().
[gcc/testsuite/ChangeLog]
2005-06-30 Ziemowit Laski <zlaski@apple.com>
* obj-c++.dg/try-catch-11.mm: New.
* objc.dg/try-catch-10.m: New.
Index: gcc/objc/objc-act.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/objc/objc-act.c,v
retrieving revision 1.281
diff -u -3 -p -r1.281 objc-act.c
--- gcc/objc/objc-act.c 29 Jun 2005 21:01:25 -0000 1.281
+++ gcc/objc/objc-act.c 1 Jul 2005 01:33:02 -0000
@@ -185,6 +185,7 @@ static tree build_protocol_initializer (
static tree get_class_ivars (tree, bool);
static tree generate_protocol_list (tree);
static void build_protocol_reference (tree);
+static tree objc_build_volatilized_type (tree);
#ifdef OBJCPLUS
static void objc_generate_cxx_cdtors (void);
@@ -868,6 +869,41 @@ objc_build_struct (tree name, tree field
return s;
}
+/* Build a type differing from TYPE only in that TYPE_VOLATILE is set.
+ Unlike tree.c:build_qualified_type(), preserve TYPE_LANG_SPECIFIC
in the
+ process. */
+static tree
+objc_build_volatilized_type (tree type)
+{
+ tree t;
+
+ /* Check if we have not constructed the desired variant already. */
+ for (t = TYPE_MAIN_VARIANT (type); t; t = TYPE_NEXT_VARIANT (t))
+ {
+ /* The type qualifiers must (obviously) match up. */
+ if (!TYPE_VOLATILE (t)
+ || (TYPE_READONLY (t) != TYPE_READONLY (type))
+ || (TYPE_RESTRICT (t) != TYPE_RESTRICT (type)))
+ continue;
+
+ /* For pointer types, the pointees (and hence their
TYPE_LANG_SPECIFIC
+ info, if any) must match up. */
+ if (POINTER_TYPE_P (t)
+ && (TREE_TYPE (t) != TREE_TYPE (type)))
+ continue;
+
+ /* Everything matches up! */
+ return t;
+ }
+
+ /* Ok, we could not re-use any of the pre-existing variants. Create
+ a new one. */
+ t = build_variant_type_copy (type);
+ TYPE_VOLATILE (t) = 1;
+
+ return t;
+}
+
/* Mark DECL as being 'volatile' for purposes of Darwin
_setjmp()/_longjmp() exception handling. Called from
objc_mark_locals_volatile(). */
@@ -884,8 +920,7 @@ objc_volatilize_decl (tree decl)
struct volatilized_type key;
void **loc;
- t = build_qualified_type (t, (TYPE_QUALS (t)
- | TYPE_QUAL_VOLATILE));
+ t = objc_build_volatilized_type (t);
key.type = t;
loc = htab_find_slot (volatilized_htab, &key, INSERT);
Index: gcc/testsuite/obj-c++.dg/try-catch-11.mm
===================================================================
RCS file: gcc/testsuite/obj-c++.dg/try-catch-11.mm
diff -N gcc/testsuite/obj-c++.dg/try-catch-11.mm
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ gcc/testsuite/obj-c++.dg/try-catch-11.mm 1 Jul 2005 01:38:10
-0000
@@ -0,0 +1,40 @@
+/* Ensure that @try/@catch blocks do not mess with types of
+ local objects (other than their volatile bits). */
+
+/* { dg-options "-fobjc-exceptions -fnext-runtime" } */
+/* { dg-do compile } */
+
+#include <objc/Object.h>
+
+@protocol Proto1
+- (int)meth1;
+@end
+
+@protocol Proto2
+- (int)meth2;
+@end
+
+@interface MyClass: Object <Proto2> {
+ int a;
+}
+- (int)meth2;
+- (Object *)parm1: (id)p1 parm2: (id<Proto1>)p2;
+@end
+
+MyClass *mc1, *mc2;
+
+@implementation MyClass
+- (int)meth2 {
+ return a;
+}
+- (Object *)parm1: (id)p1 parm2: (id<Proto1>)p2 {
+ @try {
+ mc2 = p2; /* { dg-warning "type .id <Proto1>. does not conform
to the .Proto2. protocol" } */
+ }
+ @catch (id exc) {
+ return exc;
+ }
+ mc1 = p1; /* no warning here! */
+ return self;
+}
+@end
Index: gcc/testsuite/objc.dg/try-catch-10.m
===================================================================
RCS file: gcc/testsuite/objc.dg/try-catch-10.m
diff -N gcc/testsuite/objc.dg/try-catch-10.m
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ gcc/testsuite/objc.dg/try-catch-10.m 1 Jul 2005 01:38:10
-0000
@@ -0,0 +1,40 @@
+/* Ensure that @try/@catch blocks do not mess with types of
+ local objects (other than their volatile bits). */
+
+/* { dg-options "-fobjc-exceptions -fnext-runtime" } */
+/* { dg-do compile } */
+
+#include <objc/Object.h>
+
+@protocol Proto1
+- (int)meth1;
+@end
+
+@protocol Proto2
+- (int)meth2;
+@end
+
+@interface MyClass: Object <Proto2> {
+ int a;
+}
+- (int)meth2;
+- (Object *)parm1: (id)p1 parm2: (id<Proto1>)p2;
+@end
+
+MyClass *mc1, *mc2;
+
+@implementation MyClass
+- (int)meth2 {
+ return a;
+}
+- (Object *)parm1: (id)p1 parm2: (id<Proto1>)p2 {
+ @try {
+ mc2 = p2; /* { dg-warning "type .id <Proto1>. does not conform
to the .Proto2. protocol" } */
+ }
+ @catch (id exc) {
+ return exc;
+ }
+ mc1 = p1; /* no warning here! */
+ return self;
+}
+@end
--------------------------------------------------------------
Ziemowit Laski 1 Infinite Loop, MS 301-2K
Mac OS X Compiler Group Cupertino, CA USA 95014-2083
Apple Computer, Inc. +1.408.974.6229 Fax .5477