Index: gcc/tree.h
===================================================================
--- gcc/tree.h	(revision 167220)
+++ gcc/tree.h	(working copy)
@@ -535,6 +535,9 @@ struct GTY(()) tree_common {
        FORCED_LABEL in
            LABEL_DECL
 
+       ARTIFICIALLY_VOLATILIZED in
+           all types
+
    volatile_flag:
 
        TREE_THIS_VOLATILE in
@@ -1234,6 +1237,13 @@ extern void omp_clause_range_check_faile
    computed gotos.  */
 #define FORCED_LABEL(NODE) (LABEL_DECL_CHECK (NODE)->base.side_effects_flag)
 
+/* In a _TYPE, nonzero means that the type was artificially made
+   volatile for the purpose of code generation when using ObjC/ObjC++
+   setjmp/longjmp exceptions (currently only on Darwin).  So the _TYPE
+   is volatile, but we want to disable all warnings about assigning to
+   it to/from non-volatile variables.  */
+#define TYPE_ARTIFICIALLY_VOLATILIZED(NODE) (TYPE_CHECK (NODE)->base.side_effects_flag)
+
 /* Nonzero means this expression is volatile in the C sense:
    its address should be of type `volatile WHATEVER *'.
    In other words, the declared item is volatile qualified.
Index: gcc/objc/objc-act.c
===================================================================
--- gcc/objc/objc-act.c	(revision 167231)
+++ gcc/objc/objc-act.c	(working copy)
@@ -2260,49 +2260,135 @@ objc_build_struct (tree klass, tree fiel
   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.  */
+/* Search for an existing type which is identical to TYPE but has
+   TYPE_VOLATILE and TYPE_ARTIFICIALLY_VOLATILIZED set.  Return
+    NULL_TREE if no such type was found.  */
 static tree
-objc_build_volatilized_type (tree type)
+objc_get_volatilized_type (tree type)
 {
-  tree t;
+  tree t, volatilized_pointee = NULL_TREE;
+
+  /* See if we already have the appropriate variant.  */
+  if (TYPE_ARTIFICIALLY_VOLATILIZED (type))
+    return type;
+
+  /* If we have a pointer, find the volatilized type for the pointee
+     first.  When we build a volatilized type, we volatilize the
+     pointee as well.  */
+  if (POINTER_TYPE_P (type))
+    {
+      volatilized_pointee = objc_get_volatilized_type (TREE_TYPE (type));
+
+      /* If there is none, we never built a volatilized type for the
+	 pointer either (otherwise, there would be one).  */
+      if (volatilized_pointee == NULL_TREE)
+	return NULL_TREE;
+    }
 
   /* 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)))
+      if (!TYPE_ARTIFICIALLY_VOLATILIZED (t))
 	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)))
+      if (!check_qualified_type 
+	  (t, type, (TYPE_QUALS (type) | TYPE_QUAL_VOLATILE)))
 	continue;
+      
+      /* For pointer types, the pointees (and hence their
+	 TYPE_LANG_SPECIFIC info, if any) must match up.  */
+      if (POINTER_TYPE_P (t))
+	{
+	  if (TREE_TYPE (t) != volatilized_pointee)
+	    continue;
+	}
+
+      /* Everything matches up!  */
+      return t;
+    }
+
+  return NULL_TREE;
+}
+
+/* Search for an existing type which is identical to TYPE but has
+   TYPE_VOLATILE not set, and TYPE_ARTIFICIALLY_VOLATILIZED not set.  */
+static tree
+objc_get_non_volatilized_type (tree type)
+{
+  tree t, non_volatilized_pointee = NULL_TREE;
+
+  /* See if we already have the appropriate variant.  */
+  if (!TYPE_ARTIFICIALLY_VOLATILIZED (type))
+    return type;
+
+  /* At this point, we know that type is artificially volatilized,
+     hence it was created from an existing,
+     non-artificially-volatilized type.  So we know that the search
+     will complete.  */
+
+  /* If we have a pointer, find the non-volatilized type for the
+     pointee first.  When we build a volatilized type, we volatilize
+     the pointee as well.  */
+  if (POINTER_TYPE_P (type))
+    {
+      non_volatilized_pointee = objc_get_non_volatilized_type (TREE_TYPE (type));
 
-      /* 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)))
+      /* If there is none, something is wrong.  */
+      gcc_assert (non_volatilized_pointee);
+    }
+  
+  for (t = TYPE_MAIN_VARIANT (type); t; t = TYPE_NEXT_VARIANT (t))
+    {
+      /* We are looking for a non-volatile type.  */
+      if (TYPE_ARTIFICIALLY_VOLATILIZED (t))
 	continue;
 
+      if (!check_qualified_type 
+	  (t, type, (TYPE_QUALS (type) & ~TYPE_QUAL_VOLATILE)))
+	continue;
+      
+      /* For pointer types, the pointees (and hence their
+	 TYPE_LANG_SPECIFIC info, if any) must match up.  */
+      if (POINTER_TYPE_P (t))
+	{
+	  if (TREE_TYPE (t) != non_volatilized_pointee)
+	    continue;
+	}
+
       /* Everything matches up!  */
       return t;
     }
 
+  /* This should be impossible.  */
+  gcc_unreachable ();  
+}
+
+/* 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 and mark the new type with TYPE_ARTIFICIALLY_VOLATILIZED.  */
+static tree
+objc_build_volatilized_type (tree type)
+{
+  tree t = objc_get_volatilized_type (type);
+
+  if (t)
+    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;
-
-  TYPE_ATTRIBUTES (t) = merge_attributes (TYPE_ATTRIBUTES (type),
-                      			  tree_cons (get_identifier ("objc_volatilized"),
-                                 	  NULL_TREE,
-                                 	  NULL_TREE));
+  TYPE_ARTIFICIALLY_VOLATILIZED (t) = 1;
+  
   if (TREE_CODE (t) == ARRAY_TYPE)
-    TREE_TYPE (t) = objc_build_volatilized_type (TREE_TYPE (t));
+    TREE_TYPE (t) = objc_build_volatilized_type (TREE_TYPE (type));
+
+  if (TYPE_HAS_OBJC_INFO (type))
+    {
+      DUP_TYPE_OBJC_INFO (t, type);
+      TYPE_OBJC_INTERFACE (t) = TYPE_OBJC_INTERFACE (type);
+      TYPE_OBJC_PROTOCOL_LIST (t) = TYPE_OBJC_PROTOCOL_LIST (type);
+    }
 
   /* Set up the canonical type information. */
   if (TYPE_STRUCTURAL_EQUALITY_P (type))
@@ -2703,10 +2789,10 @@ objc_type_quals_match (tree ltyp, tree r
 {
   int lquals = TYPE_QUALS (ltyp), rquals = TYPE_QUALS (rtyp);
 
-  if (lookup_attribute ("objc_volatilized", TYPE_ATTRIBUTES (ltyp)))
+  if (TYPE_ARTIFICIALLY_VOLATILIZED (ltyp))
     lquals &= ~TYPE_QUAL_VOLATILE;
 
-  if (lookup_attribute ("objc_volatilized", TYPE_ATTRIBUTES (rtyp)))
+  if (TYPE_ARTIFICIALLY_VOLATILIZED (rtyp))
     rquals &= ~TYPE_QUAL_VOLATILE;
 
   return (lquals == rquals);
@@ -2831,14 +2917,14 @@ objc_check_global_decl (tree decl)
     error ("redeclaration of Objective-C class %qs", IDENTIFIER_POINTER (id));
 }
 
-/* Return a non-volatalized version of TYPE. */
-
+/* Return a non-artificially-volatilized version of TYPE. This is the
+   reverse of objc_build_volatilized_type(); if the type is marked as
+   TYPE_ARTIFICIALLY_VOLATILIZED, it returns a variant without the
+   flag and which is not volatile.  */
 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;
+  return objc_get_non_volatilized_type (type);
 }
 
 /* Construct a PROTOCOLS-qualified variant of INTERFACE, where
Index: gcc/objc/ChangeLog
===================================================================
--- gcc/objc/ChangeLog	(revision 167231)
+++ gcc/objc/ChangeLog	(working copy)
@@ -1,5 +1,14 @@
 2010-11-29  Nicola Pero  <nicola.pero@meta-innovation.com>
 
+	* objc-act.c (objc_get_volatilized_type): New.
+	(objc_get_non_volatilized_type): New.
+	(objc_build_volatilized_type): Use objc_get_volatilized_type.
+	Duplicate ObjC type information when building the volatilized
+	type.  Set TYPE_ARTIFICIALLY_VOLATILIZED for the new type.
+	(objc_non_volatilized_type): Use objc_get_non_volatilized_type.
+	
+2010-11-29  Nicola Pero  <nicola.pero@meta-innovation.com>
+
 	* objc-act.c (objc_demangle): Return immediately if the string is
 	too short.  Detect names that do not need demangling, and return
 	them unchanged.
Index: gcc/ChangeLog
===================================================================
--- gcc/ChangeLog	(revision 167220)
+++ gcc/ChangeLog	(working copy)
@@ -1,3 +1,7 @@
+2010-11-28  Nicola Pero  <nicola.pero@meta-innovation.com>
+
+	* tree.h (TYPE_ARTIFICIALLY_VOLATILIZED): New.
+
 2010-11-27  Jan Hubicka  <jh@suse.cz>
 
 	* dwarf2out.c (dwarf2out_begin_function): Set cold_text_section
