PATCH: Fix TYPE_LANG_SPECIFIC() lossage during volatilization

Ziemowit Laski zlaski@apple.com
Fri Jul 1 01:42:00 GMT 2005


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



More information about the Gcc-patches mailing list