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.  */
