objc-act.c (objc_build_volatilized_type): New function.
authorZiemowit Laski <zlaski@apple.com>
Fri, 1 Jul 2005 01:44:12 +0000 (01:44 +0000)
committerZiemowit Laski <zlaski@gcc.gnu.org>
Fri, 1 Jul 2005 01:44:12 +0000 (01:44 +0000)
[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.

From-SVN: r101493

gcc/objc/ChangeLog
gcc/objc/objc-act.c
gcc/testsuite/ChangeLog
gcc/testsuite/obj-c++.dg/try-catch-11.mm [new file with mode: 0644]
gcc/testsuite/objc.dg/try-catch-10.m [new file with mode: 0644]

index a11966e..6963c53 100644 (file)
@@ -1,3 +1,9 @@
+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().
+
 2005-06-29  Ziemowit Laski  <zlaski@apple.com>
 
        * objc-act.c (objc_build_internal_const_str_type): New function.
index b522b8d..e44f8b0 100644 (file)
@@ -185,6 +185,7 @@ static tree build_protocol_initializer (tree, tree, tree, tree, tree);
 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 fields, tree super_name)
   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 12292e4..fe7a632 100644 (file)
@@ -1,3 +1,8 @@
+2005-06-30  Ziemowit Laski  <zlaski@apple.com>
+
+       * obj-c++.dg/try-catch-11.mm: New.
+       * objc.dg/try-catch-10.m: New.
+
 2005-06-29  David Edelsohn  <edelsohn@gnu.org>
 
        * g++.dg/other/ucnid-1.C: xfail on AIX.
diff --git a/gcc/testsuite/obj-c++.dg/try-catch-11.mm b/gcc/testsuite/obj-c++.dg/try-catch-11.mm
new file mode 100644 (file)
index 0000000..1da1b47
--- /dev/null
@@ -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  
diff --git a/gcc/testsuite/objc.dg/try-catch-10.m b/gcc/testsuite/objc.dg/try-catch-10.m
new file mode 100644 (file)
index 0000000..1da1b47
--- /dev/null
@@ -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