diff mbox

ObjC/ObjC++ volatilized merge from apple/trunk

Message ID 1287425205.46273660@192.168.2.230
State New
Headers show

Commit Message

Nicola Pero Oct. 18, 2010, 6:06 p.m. UTC
This patch merges from the FSF apple/trunk branch three inter-related ObjC/ObjC++ 
improvements in dealing with variables volatilized artificially in ObjC/ObjC++.  
It is most relevant to sjlj-style exception handling.

Committed to trunk (preapproved by Mike).

Thanks

In gcc/:
2010-10-18  Nicola Pero  <nicola.pero@meta-innovation.com>

        Merge from 'apple/trunk' branch on FSF servers.
        * c-parser.c (c_parser_typeof_specifier): Adapted to new parser
        the following Objective-C change:

        2005-10-07  Fariborz Jahanian <fjahanian@apple.com>

        Radar 4204796
        * c-parse.in (typespec_nonreserved_nonattr): Remove volatile from
        'volatilized' type used in a typeof operator.

In gcc/cp/:
2010-10-18  Nicola Pero  <nicola.pero@meta-innovation.com>
        
        Merge from apple/trunk branch on FSF servers.
        
        2005-03-01 Fariborz Jahanian <fjahanian@apple.com>

        Radar 4451818
        * call.c (standard_conversion, implicit_conversion): Ignore
        'volatile' attribute of artificially volatized type in objc when
        evaluating various conversion weights.

        2005-11-08  Fariborz Jahanian <fjahanian@apple.com>

        Radar 4330422
        * typeck.c (comp_ptr_ttypes_real): Remove the hack. un-volatize the
        artiificially 'volatized' type before doing pointer comparison.
        
In gcc/objc/:
2010-10-17  Nicola Pero  <nicola.pero@meta-innovation.com>

        Merge from 'apple/trunk' branch on FSF servers.
        
        2005-11-08  Fariborz Jahanian <fjahanian@apple.com>

        Radar 4330422
        * objc/objc-act.c (objc_non_volatilized_type): New

        2005-10-07  Fariborz Jahanian <fjahanian@apple.com>
        
        Radar 4204796
        * objc-act.c (objc_build_volatilized_type): Build 'volatilzed'
        types with proper attribute set and correctly.
        (objc_volatilize_decl): Remove unneeded code.
        (objc_type_quals_match): Use the new attribute to check on
        'volatilzed' type.
        (hash_init): removed unneeded code.
        
In gcc/testsuite/:
2010-10-18  Nicola Pero  <nicola.pero@meta-innovation.com>
        
        Merge from 'apple/trunk' branch on FSF servers.

        2005-03-01 Fariborz Jahanian <fjahanian@apple.com>

        Radar 4451818
        * obj-c++.dg/try-catch-16.mm: New.
        * obj-c++.dg/try-catch-17.mm: New.

        2005-11-08  Fariborz Jahanian <fjahanian@apple.com>

        Radar 4330422
        * obj-c++.dg/try-catch-15.mm: New

        2005-10-07  Fariborz Jahanian <fjahanian@apple.com>

        Radar 4204796
        * obj-c++.dg/try-catch-12.mm: New
        * obj-c++.dg/try-catch-13.mm: New
        * obj-c++.dg/try-catch-14.mm: New
        * objc.dg/try-catch-11.m: New
        * objc.dg/try-catch-12.m: New
        * objc.dg/try-catch-13.m: New
        
In gcc/c-family/:
2010-10-18  Nicola Pero  <nicola.pero@meta-innovation.com>

        Merge from 'apple/trunk' branch on FSF servers.
        
        2005-11-08  Fariborz Jahanian <fjahanian@apple.com>

        Radar 4330422
        * c-common.h (objc_non_volatilized_type): New declaration
        * stub-objc.c (objc_non_volatilized_type): New stub.

Comments

Mike Stump Oct. 18, 2010, 6:58 p.m. UTC | #1
On Oct 18, 2010, at 11:06 AM, Nicola Pero wrote:
> This patch merges from the FSF apple/trunk branch three inter-related ObjC/ObjC++ 
> improvements in dealing with variables volatilized artificially in ObjC/ObjC++.  
> It is most relevant to sjlj-style exception handling.

Just a note, there may be room here to engineer out the volatilization...  that would be better...  The problem is objc wants to use setjmp/longjmp under the covers for exception handling, but yet, wants variables to work, which means, they have to hit memory.  It uses volatile to ensure they hit memory.  It only needs them to be stable in memory at calls which can `throw', not generally, inside a basic block.  I put these here, just for future archeologists who might want to fix this up...
diff mbox

Patch

Index: gcc/c-family/ChangeLog
===================================================================
--- gcc/c-family/ChangeLog	(revision 165653)
+++ gcc/c-family/ChangeLog	(working copy)
@@ -1,6 +1,16 @@ 
+2010-10-18  Nicola Pero  <nicola.pero@meta-innovation.com>
+
+	Merge from 'apple/trunk' branch on FSF servers.
+	
+	2005-11-08  Fariborz Jahanian <fjahanian@apple.com>
+
+        Radar 4330422
+	* c-common.h (objc_non_volatilized_type): New declaration
+	* stub-objc.c (objc_non_volatilized_type): New stub.
+
 2010-10-17  Nicola Pero  <nicola.pero@meta-innovation.com>
 
-	Merge from 'apple/trunk' branch on FSF servers.		
+	Merge from 'apple/trunk' branch on FSF servers.
 
 	2006-03-27 Fariborz Jahanian <fjahanian@apple.com>
 
Index: gcc/c-family/c-common.h
===================================================================
--- gcc/c-family/c-common.h	(revision 165653)
+++ gcc/c-family/c-common.h	(working copy)
@@ -985,6 +985,7 @@  extern tree objc_is_object_ptr (tree);
 extern void objc_check_decl (tree);
 extern void objc_check_global_decl (tree);
 extern tree objc_common_type (tree, tree);
+extern tree objc_non_volatilized_type (tree);
 extern bool objc_compare_types (tree, tree, int, tree);
 extern bool objc_have_common_type (tree, tree, int, tree);
 extern bool objc_diagnose_private_ivar (tree);
Index: gcc/c-family/stub-objc.c
===================================================================
--- gcc/c-family/stub-objc.c	(revision 165653)
+++ gcc/c-family/stub-objc.c	(working copy)
@@ -67,6 +67,12 @@  objc_check_global_decl (tree ARG_UNUSED (decl))
 }
 
 tree
+objc_non_volatilized_type (tree type)
+{
+  return type;
+}
+
+tree
 objc_common_type (tree ARG_UNUSED (type1), tree ARG_UNUSED (type2))
 {
   return 0;
Index: gcc/objc/objc-act.c
===================================================================
--- gcc/objc/objc-act.c	(revision 165653)
+++ gcc/objc/objc-act.c	(working copy)
@@ -430,13 +430,6 @@  struct GTY(()) string_descriptor {
 
 static GTY((param_is (struct string_descriptor))) htab_t string_htab;
 
-/* Store the EH-volatilized types in a hash table, for easy retrieval.  */
-struct GTY(()) volatilized_type {
-  tree type;
-};
-
-static GTY((param_is (struct volatilized_type))) htab_t volatilized_htab;
-
 FILE *gen_declaration_file;
 
 /* Tells "encode_pointer/encode_aggregate" whether we are generating
@@ -1490,6 +1483,11 @@  objc_build_volatilized_type (tree type)
 	  && (TREE_TYPE (t) != TREE_TYPE (type)))
 	continue;
 
+      /* Only match up the types which were previously volatilized in similar fashion and not
+	 because they were declared as such. */
+      if (!lookup_attribute ("objc_volatilized", TYPE_ATTRIBUTES (t)))
+	continue;
+
       /* Everything matches up!  */
       return t;
     }
@@ -1499,6 +1497,13 @@  objc_build_volatilized_type (tree type)
   t = build_variant_type_copy (type);
   TYPE_VOLATILE (t) = 1;
 
+  TYPE_ATTRIBUTES (t) = merge_attributes (TYPE_ATTRIBUTES (type),
+                      			  tree_cons (get_identifier ("objc_volatilized"),
+                                 	  NULL_TREE,
+                                 	  NULL_TREE));
+  if (TREE_CODE (t) == ARRAY_TYPE)
+    TREE_TYPE (t) = objc_build_volatilized_type (TREE_TYPE (t));
+
   /* Set up the canonical type information. */
   if (TYPE_STRUCTURAL_EQUALITY_P (type))
     SET_TYPE_STRUCTURAL_EQUALITY (t);
@@ -1523,19 +1528,9 @@  objc_volatilize_decl (tree decl)
 	  || TREE_CODE (decl) == PARM_DECL))
     {
       tree t = TREE_TYPE (decl);
-      struct volatilized_type key;
-      void **loc;
 
       t = objc_build_volatilized_type (t);
-      key.type = t;
-      loc = htab_find_slot (volatilized_htab, &key, INSERT);
 
-      if (!*loc)
-	{
-	  *loc = ggc_alloc_volatilized_type ();
-	  ((struct volatilized_type *) *loc)->type = t;
-	}
-
       TREE_TYPE (decl) = t;
       TREE_THIS_VOLATILE (decl) = 1;
       TREE_SIDE_EFFECTS (decl) = 1;
@@ -1881,16 +1876,11 @@  bool
 objc_type_quals_match (tree ltyp, tree rtyp)
 {
   int lquals = TYPE_QUALS (ltyp), rquals = TYPE_QUALS (rtyp);
-  struct volatilized_type key;
 
-  key.type = ltyp;
-
-  if (htab_find_slot (volatilized_htab, &key, NO_INSERT))
+  if (lookup_attribute ("objc_volatilized", TYPE_ATTRIBUTES (ltyp)))
     lquals &= ~TYPE_QUAL_VOLATILE;
 
-  key.type = rtyp;
-
-  if (htab_find_slot (volatilized_htab, &key, NO_INSERT))
+  if (lookup_attribute ("objc_volatilized", TYPE_ATTRIBUTES (rtyp)))
     rquals &= ~TYPE_QUAL_VOLATILE;
 
   return (lquals == rquals);
@@ -1993,23 +1983,6 @@  objc_xref_basetypes (tree ref, tree basetype)
     }
 }
 
-static hashval_t
-volatilized_hash (const void *ptr)
-{
-  const_tree const typ = ((const struct volatilized_type *)ptr)->type;
-
-  return htab_hash_pointer(typ);
-}
-
-static int
-volatilized_eq (const void *ptr1, const void *ptr2)
-{
-  const_tree const typ1 = ((const struct volatilized_type *)ptr1)->type;
-  const_tree const typ2 = ((const struct volatilized_type *)ptr2)->type;
-
-  return typ1 == typ2;
-}
-
 /* Called from finish_decl.  */
 
 void
@@ -2032,6 +2005,16 @@  objc_check_global_decl (tree decl)
     error ("redeclaration of Objective-C class %qs", IDENTIFIER_POINTER (id));
 }
 
+/* Return a non-volatalized version of TYPE. */
+
+tree
+objc_non_volatilized_type (tree type)
+{
+  if (lookup_attribute ("objc_volatilized", TYPE_ATTRIBUTES (type)))
+    type = build_qualified_type (type, (TYPE_QUALS (type) & ~TYPE_QUAL_VOLATILE));
+  return type;
+}
+
 /* Construct a PROTOCOLS-qualified variant of INTERFACE, where INTERFACE may
    either name an Objective-C class, or refer to the special 'id' or 'Class'
    types.  If INTERFACE is not a valid ObjC type, just return it unchanged.  */
@@ -7498,10 +7481,6 @@  hash_init (void)
   /* Initialize the hash table used to hold the constant string objects.  */
   string_htab = htab_create_ggc (31, string_hash,
 				   string_eq, NULL);
-
-  /* Initialize the hash table used to hold EH-volatilized types.  */
-  volatilized_htab = htab_create_ggc (31, volatilized_hash,
-				      volatilized_eq, NULL);
 }
 
 /* WARNING!!!!  hash_enter is called with a method, and will peek
Index: gcc/objc/ChangeLog
===================================================================
--- gcc/objc/ChangeLog	(revision 165653)
+++ gcc/objc/ChangeLog	(working copy)
@@ -1,3 +1,22 @@ 
+2010-10-18  Nicola Pero  <nicola.pero@meta-innovation.com>
+
+	Merge from 'apple/trunk' branch on FSF servers.
+	
+	2005-11-08  Fariborz Jahanian <fjahanian@apple.com>
+
+	Radar 4330422
+	* objc/objc-act.c (objc_non_volatilized_type): New
+
+	2005-10-07  Fariborz Jahanian <fjahanian@apple.com>
+	
+        Radar 4204796
+	* objc-act.c (objc_build_volatilized_type): Build 'volatilzed'
+	types with proper attribute set and correctly.
+	(objc_volatilize_decl): Remove unneeded code.
+	(objc_type_quals_match): Use the new attribute to check on
+	'volatilzed' type.
+	(hash_init): removed unneeded code.
+	
 2010-10-17  Nicola Pero  <nicola.pero@meta-innovation.com>
 
 	Merge from 'apple/trunk' branch on FSF servers.
Index: gcc/ChangeLog
===================================================================
--- gcc/ChangeLog	(revision 165653)
+++ gcc/ChangeLog	(working copy)
@@ -1,3 +1,15 @@ 
+2010-10-18  Nicola Pero  <nicola.pero@meta-innovation.com>
+
+	Merge from 'apple/trunk' branch on FSF servers.
+	* c-parser.c (c_parser_typeof_specifier): Adapted to new parser
+	the following Objective-C change:
+
+	2005-10-07  Fariborz Jahanian <fjahanian@apple.com>
+
+	Radar 4204796
+	* c-parse.in (typespec_nonreserved_nonattr): Remove volatile from
+	'volatilized' type used in a typeof operator.
+
 2010-10-18  Eric Botcazou  <ebotcazou@adacore.com>
 
 	* tree-flow.h (gimple_purge_all_dead_abnormal_call_edges): Declare.
Index: gcc/testsuite/ChangeLog
===================================================================
--- gcc/testsuite/ChangeLog	(revision 165653)
+++ gcc/testsuite/ChangeLog	(working copy)
@@ -1,3 +1,28 @@ 
+2010-10-18  Nicola Pero  <nicola.pero@meta-innovation.com>
+	
+	Merge from 'apple/trunk' branch on FSF servers.
+
+	2005-03-01 Fariborz Jahanian <fjahanian@apple.com>
+
+	Radar 4451818
+	* obj-c++.dg/try-catch-16.mm: New.
+	* obj-c++.dg/try-catch-17.mm: New.
+
+	2005-11-08  Fariborz Jahanian <fjahanian@apple.com>
+
+	Radar 4330422
+	* obj-c++.dg/try-catch-15.mm: New
+
+	2005-10-07  Fariborz Jahanian <fjahanian@apple.com>
+
+	Radar 4204796
+	* obj-c++.dg/try-catch-12.mm: New
+	* obj-c++.dg/try-catch-13.mm: New
+	* obj-c++.dg/try-catch-14.mm: New
+	* objc.dg/try-catch-11.m: New
+	* objc.dg/try-catch-12.m: New
+	* objc.dg/try-catch-13.m: New
+	
 2010-10-18  Richard Henderson  <rth@redhat.com>
 
 	* gcc.target/ia64/20101014.c: Fix double-paste of test case.
Index: gcc/testsuite/objc.dg/try-catch-12.m
===================================================================
--- gcc/testsuite/objc.dg/try-catch-12.m	(revision 0)
+++ gcc/testsuite/objc.dg/try-catch-12.m	(revision 0)
@@ -0,0 +1,63 @@ 
+/* Ensure that variables declared volatile by the user (as opposed to
+   synthesized by the EH-volatization machinery) _do_ trigger 
+   "discards qualifiers from target pointer type" warnings.  */
+
+/* { dg-options "-fobjc-exceptions" } */
+/* { dg-do compile } */
+
+@interface TestMyTests
+- (void) testSpoon;
+@end
+
+extern void some_func (int *);
+
+@implementation TestMyTests
+- (void) testSpoon {
+  volatile int i = 5;
+  int q = 99;
+
+  do {
+    @try {
+      typeof(i) j = 6;
+      typeof(q) k = 66;
+      some_func (&j); /* { dg-warning "discards .volatile. qualifier from pointer target type" } */
+      /* { dg-message "but argument is of type" "" { target *-*-* } 12 } */
+      some_func (&k);
+    }
+    @catch (id exc) {
+      @throw;
+    }
+  } while(0);
+
+  do {
+    @try {
+      typeof(i) j = 7;
+      typeof(q) k = 77;
+      some_func (&k);
+      some_func (&j); /* { dg-warning "discards .volatile. qualifier from pointer target type" } */
+      /* The following is disabled as it is already checked above and the testsuites seems 
+	 to count multiple different identical errors on the same line only once */
+      /* dg-message "but argument is of type" "" { target *-*-* } 12 */
+    }
+    @catch (id exc) {
+      @throw;
+    }
+  } while(0);
+
+  do {
+    @try {
+      typeof(q) k = 88;
+      typeof(i) j = 8;
+      some_func (&j); /* { dg-warning "discards .volatile. qualifier from pointer target type" } */
+      /* The following is disabled as it is already checked above and the testsuites seems 
+	 to count multiple different identical errors on the same line only once */
+      /* dg-message "but argument is of type" "" { target *-*-* } 12 */
+      some_func (&k);
+    }
+    @catch (id exc) {
+      @throw;
+    }
+  } while(0);
+      
+}
+@end
Index: gcc/testsuite/objc.dg/try-catch-11.m
===================================================================
--- gcc/testsuite/objc.dg/try-catch-11.m	(revision 0)
+++ gcc/testsuite/objc.dg/try-catch-11.m	(revision 0)
@@ -0,0 +1,51 @@ 
+/* Ensure that typeof()-typed variables inside the @try { } block that
+   "inherit" their EH-volatileness from other variables in the stack frame
+   do not trigger "discards qualifiers from target pointer type" warnings.  */
+
+/* { dg-options "-fobjc-exceptions" } */
+/* { dg-do compile } */
+
+typedef volatile int IOSharedLockData;
+
+@interface TestMyTests
+- (void) testSpoon;
+@end
+
+extern void some_func (int *);
+
+@implementation TestMyTests
+- (void) testSpoon {
+  int i = 5;
+
+  do {
+    @try {
+      typeof(i) j = 6;
+      some_func (&j);
+    }
+    @catch (id exc) {
+      @throw;
+    }
+  } while(0);
+
+  do {
+    @try {
+      typeof(i) j = 7;
+      some_func (&j);
+    }
+    @catch (id exc) {
+      @throw;
+    }
+  } while(0);
+
+  do {
+    @try {
+      typeof(i) j = 8;
+      some_func (&j);
+    }
+    @catch (id exc) {
+      @throw;
+    }
+  } while(0);
+      
+}
+@end
Index: gcc/testsuite/obj-c++.dg/try-catch-13.mm
===================================================================
--- gcc/testsuite/obj-c++.dg/try-catch-13.mm	(revision 0)
+++ gcc/testsuite/obj-c++.dg/try-catch-13.mm	(revision 0)
@@ -0,0 +1,67 @@ 
+/* Ensure that variables declared volatile by the user (as opposed to
+   synthesized by the EH-volatization machinery) _do_ trigger 
+   "discards qualifiers from target pointer type" warnings.  */
+
+/* { dg-options "-fobjc-exceptions" } */
+/* { dg-do compile } */
+
+@interface TestMyTests
+- (void) testSpoon;
+@end
+
+extern void some_func (int *);
+
+@implementation TestMyTests
+- (void) testSpoon {
+  volatile int i = 5;
+  int q = 99;
+
+  do {
+    @try {
+      typeof(i) j = 6;
+      typeof(q) k = 66;
+      some_func (&j);
+/* { dg-error "invalid conversion" "" { target *-*-* } 23 } */ 
+/* { dg-error "initializing argument" "" { target *-*-* } 12 } */
+      some_func (&k);
+    }
+    @catch (id exc) {
+      @throw;
+    }
+  } while(0);
+
+  do {
+    @try {
+      typeof(i) j = 7;
+      typeof(q) k = 77;
+      some_func (&k);
+      some_func (&j);
+/* { dg-error "invalid conversion" "" { target *-*-* } 38 } */
+/* The following is disabled as it is already checked above and the testsuites seems 
+   to count multiple different identical errors on the same line only once */
+/*  dg-error "initializing argument" "" { target *-*-* } 12  */
+    }
+    @catch (id exc) {
+      @throw;
+    }
+  } while(0);
+
+  do {
+    @try {
+      typeof(q) k = 88;
+      typeof(i) j = 8;
+      some_func (&j); 
+/* { dg-error "invalid conversion" "" { target *-*-* } 53 } */
+/* The following is disabled as it is already checked above and the testsuites seems 
+   to count multiple different identical errors on the same line only once */
+/*  dg-error "initializing argument" "" { target *-*-* } 12  */
+      some_func (&k);
+    }
+    @catch (id exc) {
+      @throw;
+    }
+  } while(0);
+      
+}
+@end
+
Index: gcc/testsuite/obj-c++.dg/try-catch-16.mm
===================================================================
--- gcc/testsuite/obj-c++.dg/try-catch-16.mm	(revision 0)
+++ gcc/testsuite/obj-c++.dg/try-catch-16.mm	(revision 0)
@@ -0,0 +1,20 @@ 
+/* Test if addition of 'volatile' to object causes bogus error in presence of try-catch. */
+/* { dg-options "-fobjc-exceptions" } */
+/* { dg-do compile } */
+
+extern void func( void * outData) ;
+struct Point {
+  short v;
+  short h;
+};
+
+
+void foo ()
+{
+ Point eventLocation;
+ @try {
+ } @catch (id iiii) {
+ }
+
+   func( &eventLocation );
+}
Index: gcc/testsuite/obj-c++.dg/try-catch-14.mm
===================================================================
--- gcc/testsuite/obj-c++.dg/try-catch-14.mm	(revision 0)
+++ gcc/testsuite/obj-c++.dg/try-catch-14.mm	(revision 0)
@@ -0,0 +1,24 @@ 
+/* { dg-options "-fobjc-exceptions" } */
+/* { dg-do compile } */
+
+typedef unsigned char uint8_t;
+typedef uint8_t foo[24];
+
+void thingy(foo a)
+{
+}
+
+int main()
+{
+    foo bar;
+
+    @try {
+    } 
+    @finally {
+    }
+
+    thingy(bar);
+
+    return 0;
+}
+
Index: gcc/testsuite/obj-c++.dg/try-catch-17.mm
===================================================================
--- gcc/testsuite/obj-c++.dg/try-catch-17.mm	(revision 0)
+++ gcc/testsuite/obj-c++.dg/try-catch-17.mm	(revision 0)
@@ -0,0 +1,18 @@ 
+/* Test if addition of 'volatile' to object causes bogus error in presence of try-catch. */
+/* { dg-options "-fobjc-exceptions" } */
+/* { dg-do compile } */
+
+struct Point {
+  short v;
+  short h;
+};
+
+void foo ()
+{
+ Point eventLocation;
+ @try {
+ } @catch (id iiii) {
+ }
+
+ Point p = eventLocation;
+}
Index: gcc/testsuite/obj-c++.dg/try-catch-12.mm
===================================================================
--- gcc/testsuite/obj-c++.dg/try-catch-12.mm	(revision 0)
+++ gcc/testsuite/obj-c++.dg/try-catch-12.mm	(revision 0)
@@ -0,0 +1,51 @@ 
+/* Ensure that typeof()-typed variables inside the @try { } block that
+   "inherit" their EH-volatileness from other variables in the stack frame
+   do not trigger "discards qualifiers from target pointer type" warnings.  */
+
+/* { dg-options "-fobjc-exceptions" } */
+/* { dg-do compile } */
+
+typedef volatile int IOSharedLockData;
+
+@interface TestMyTests
+- (void) testSpoon;
+@end
+
+extern void some_func (int *);
+
+@implementation TestMyTests
+- (void) testSpoon {
+  int i = 5;
+
+  do {
+    @try {
+      typeof(i) j = 6;
+      some_func (&j);
+    }
+    @catch (id exc) {
+      @throw;
+    }
+  } while(0);
+
+  do {
+    @try {
+      typeof(i) j = 7;
+      some_func (&j);
+    }
+    @catch (id exc) {
+      @throw;
+    }
+  } while(0);
+
+  do {
+    @try {
+      typeof(i) j = 8;
+      some_func (&j);
+    }
+    @catch (id exc) {
+      @throw;
+    }
+  } while(0);
+      
+}
+@end
Index: gcc/testsuite/obj-c++.dg/try-catch-15.mm
===================================================================
--- gcc/testsuite/obj-c++.dg/try-catch-15.mm	(revision 0)
+++ gcc/testsuite/obj-c++.dg/try-catch-15.mm	(revision 0)
@@ -0,0 +1,34 @@ 
+/* Test if addition of 'volatile' to object causes bogus error in presence of try-catch. */
+/* { dg-options "-fobjc-exceptions" } */
+/* { dg-do compile } */
+
+@interface Exception
+@end
+
+class CppObj {
+public:
+    void constMethod() const {
+    }
+};
+
+@interface MyObject : Exception
+- (void)doSomething;
+- (void)myMethod;
+@end
+
+@implementation MyObject
+- (void)doSomething {
+}
+
+- (void)myMethod {
+    CppObj cppObj;
+    
+    @try {
+        [self doSomething];
+    }
+    @catch (Exception *exception) {
+    }
+    
+    cppObj.constMethod();
+}
+@end
Index: gcc/cp/typeck.c
===================================================================
--- gcc/cp/typeck.c	(revision 165653)
+++ gcc/cp/typeck.c	(working copy)
@@ -8006,12 +8006,13 @@  comp_ptr_ttypes_real (tree to, tree from, int cons
 	  /* In Objective-C++, some types may have been 'volatilized' by
 	     the compiler for EH; when comparing them here, the volatile
 	     qualification must be ignored.  */
-	  bool objc_quals_match = objc_type_quals_match (to, from);
+	  tree nv_to = objc_non_volatilized_type (to);
+	  tree nv_from = objc_non_volatilized_type (from);
 
-	  if (!at_least_as_qualified_p (to, from) && !objc_quals_match)
+	  if (!at_least_as_qualified_p (nv_to, nv_from))
 	    return 0;
 
-	  if (!at_least_as_qualified_p (from, to) && !objc_quals_match)
+	  if (!at_least_as_qualified_p (nv_from, nv_to))
 	    {
 	      if (constp == 0)
 		return 0;
@@ -8019,7 +8020,7 @@  comp_ptr_ttypes_real (tree to, tree from, int cons
 	    }
 
 	  if (constp > 0)
-	    constp &= TYPE_READONLY (to);
+	    constp &= TYPE_READONLY (nv_to);
 	}
 
       if (TREE_CODE (to) == VECTOR_TYPE)
Index: gcc/cp/ChangeLog
===================================================================
--- gcc/cp/ChangeLog	(revision 165653)
+++ gcc/cp/ChangeLog	(working copy)
@@ -1,3 +1,20 @@ 
+2010-10-18  Nicola Pero  <nicola.pero@meta-innovation.com>
+	
+	Merge from apple/trunk branch on FSF servers.
+	
+	2005-03-01 Fariborz Jahanian <fjahanian@apple.com>
+
+        Radar 4451818
+	* call.c (standard_conversion, implicit_conversion): Ignore
+	'volatile' attribute of artificially volatized type in objc when
+	evaluating various conversion weights.
+
+	2005-11-08  Fariborz Jahanian <fjahanian@apple.com>
+
+	Radar 4330422
+	* typeck.c (comp_ptr_ttypes_real): Remove the hack. un-volatize the
+	artiificially 'volatized' type before doing pointer comparison.
+	
 2010-10-18  Jakub Jelinek  <jakub@redhat.com>
 
 	PR c/46015
Index: gcc/cp/call.c
===================================================================
--- gcc/cp/call.c	(revision 165653)
+++ gcc/cp/call.c	(working copy)
@@ -832,9 +832,12 @@  standard_conversion (tree to, tree from, tree expr
 	       && !TYPE_PTRMEM_P (from)
 	       && TREE_CODE (TREE_TYPE (from)) != FUNCTION_TYPE)
 	{
+	  tree nfrom = TREE_TYPE (from);
+	  if (c_dialect_objc ())
+	    nfrom = objc_non_volatilized_type (nfrom);
 	  from = build_pointer_type
-	    (cp_build_qualified_type (void_type_node,
-				      cp_type_quals (TREE_TYPE (from))));
+	    (cp_build_qualified_type (void_type_node, 
+			              cp_type_quals (nfrom)));
 	  conv = build_conv (ck_ptr, from, conv);
 	}
       else if (TYPE_PTRMEM_P (from))
@@ -1441,6 +1444,9 @@  implicit_conversion (tree to, tree from, tree expr
       || expr == error_mark_node)
     return NULL;
 
+  if (c_dialect_objc ())
+    from = objc_non_volatilized_type (from);
+
   if (TREE_CODE (to) == REFERENCE_TYPE)
     conv = reference_binding (to, from, expr, c_cast_p, flags);
   else
Index: gcc/c-parser.c
===================================================================
--- gcc/c-parser.c	(revision 165653)
+++ gcc/c-parser.c	(working copy)
@@ -2509,6 +2509,11 @@  c_parser_typeof_specifier (c_parser *parser)
 	error_at (here, "%<typeof%> applied to a bit-field");
       mark_exp_read (expr.value);
       ret.spec = TREE_TYPE (expr.value);
+      if (c_dialect_objc() 
+	  && ret.spec != error_mark_node
+	  && lookup_attribute ("objc_volatilized", TYPE_ATTRIBUTES (ret.spec)))
+	ret.spec = build_qualified_type
+	  (ret.spec, (TYPE_QUALS (ret.spec) & ~TYPE_QUAL_VOLATILE));
       was_vm = variably_modified_type_p (ret.spec, NULL_TREE);
       /* This is returned with the type so that when the type is
 	 evaluated, this can be evaluated.  */