This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

ObjC/ObjC++: Fix try-catch failures on a darwin, second take (this one fixes them all)


This is a new patch to fix the sjlj exception handling machinery on Darwin, following
an idea I had during the recent discussions. And this one fully works :-)


The way the new patch works is that when the objc_mark_locals_volatile() is called,
instead of immediately marking the relevant local variables as volatile, we record
them into a vector as needing to be marked as volatile. At the very beginning of
finish_function(), then, we mark all the recorded local variables that need to be
volatilized as volatile (and empty the vector). Doing it later means the parser warnings
about volatile qualifiers being lost are automatically avoided (since they have already been
produced by the time we volatilize the variables) without any needs for hacks. :-)


I was worried that marking them as volatile later may cause problems, but the existing
code is already marking them as volatile much later than they are defined (by the time
the setjmp is reached, the variables may already have been used a lot). So the new code
is not any different in that respect, it still marks them as volatile after they have been defined
and maybe used (but, obviously, still before gimplify / code generation etc so the volatilization
still affects register allocation etc. and make them preserved across setjmp/longjmp).


With this new way of avoiding the warnings in place, I was able to remove all the complications
of creating objc_volatilized types etc. The code ends up being quite clean as we can simply mark
the variables as volatile in the standard way and we get no warnings as the warnings have already
been generated.


It also simplifies the C/C++ frontend as I could remove a number of clumsy hooks from there
that were there only to silence type comparison warnings; and it feels that the new solution is solid
and won't be broken easily by changes in type management or such like in the rest of the compiler


This patch fixes all the testcase failures for exceptions on NeXT/ darwin, including the warning ones
that the other one didn't. :-)


It may still be a good future idea to extract this technique and make it available in C
when a -fsafe-setjmp flag is specified, but since this is stage 3, I'm content with this patch
that just fixes the ObjC/ObjC++ exceptions on NeXT/Darwin and all the remaining NeXT/Darwin
specific testcase failures. :-)


Ok to commit ?

Thanks

Index: c-family/ChangeLog
===================================================================
--- c-family/ChangeLog  (revision 167292)
+++ c-family/ChangeLog  (working copy)
@@ -1,3 +1,12 @@
+2010-11-30  Nicola Pero  <nicola.pero@meta-innovation.com>
+
+       * c-common.h (objc_finish_function): New.
+       (objc_non_volatilized_type): Removed.
+       (objc_type_quals_match): Removed.
+       * stub-objc.c (objc_finish_function): New.
+       (objc_non_volatilized_type): Removed.
+       (objc_type_quals_match): Removed.
+
 2010-11-29  Joseph Myers  <joseph@codesourcery.com>

        * c-opts.c (check_deps_environment_vars): Use getenv instead of
Index: c-family/c-common.h
===================================================================
--- c-family/c-common.h (revision 167292)
+++ c-family/c-common.h (working copy)
@@ -996,12 +996,10 @@ 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);
 extern void objc_volatilize_decl (tree);
-extern bool objc_type_quals_match (tree, tree);
 extern tree objc_rewrite_function_call (tree, tree);
 extern tree objc_message_selector (void);
 extern tree objc_lookup_ivar (tree, tree);
@@ -1063,6 +1061,7 @@ extern const char * objc_maybe_printable
 extern bool objc_is_property_ref (tree);
 extern bool objc_string_ref_type_p (tree);
 extern void objc_check_format_arg (tree, tree);
+extern void objc_finish_function (void);

/* The following are provided by the C and C++ front-ends, and called by
ObjC/ObjC++. */
Index: c-family/stub-objc.c
===================================================================
--- c-family/stub-objc.c (revision 167292)
+++ c-family/stub-objc.c (working copy)
@@ -67,12 +67,6 @@ objc_check_global_decl (tree ARG_UNUSED
}


 tree
-objc_non_volatilized_type (tree type)
-{
-  return type;
-}
-
-tree
 objc_common_type (tree ARG_UNUSED (type1), tree ARG_UNUSED (type2))
 {
   return 0;
@@ -97,12 +91,6 @@ objc_volatilize_decl (tree ARG_UNUSED (d
 {
 }

-bool
-objc_type_quals_match (tree ARG_UNUSED (ltyp), tree ARG_UNUSED (rtyp))
-{
- return false;
-}
-
tree
objc_rewrite_function_call (tree function, tree ARG_UNUSED (first_param))
{
@@ -461,3 +449,8 @@ objc_check_format_arg (tree ARG_UNUSED (
tree ARG_UNUSED (args_list))
{
}
+
+void
+objc_finish_function (void)
+{
+}
Index: objc/objc-act.c
===================================================================
--- objc/objc-act.c (revision 167292)
+++ objc/objc-act.c (working copy)
@@ -405,6 +405,10 @@ static int objc_collecting_ivars = 0;


static char *errbuf; /* Buffer for error diagnostics */

+/* An array of all the local variables in the current function that
+   need to be marked as volatile.  */
+VEC(tree,gc) *local_variables_to_volatilize = NULL;
+
 ^L
 static int flag_typed_selectors;

@@ -2257,61 +2261,6 @@ 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. */
-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;
-
- /* 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;
- }
-
- /* 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));
- 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);
- else if (TYPE_CANONICAL (type) != type)
- TYPE_CANONICAL (t) = objc_build_volatilized_type (TYPE_CANONICAL (type));
- else
- TYPE_CANONICAL (t) = t;
-
- return t;
-}
-
/* Mark DECL as being 'volatile' for purposes of Darwin
_setjmp()/_longjmp() exception handling. Called from
objc_mark_locals_volatile(). */
@@ -2324,17 +2273,44 @@ objc_volatilize_decl (tree decl)
&& (TREE_CODE (decl) == VAR_DECL
|| TREE_CODE (decl) == PARM_DECL))
{
- tree t = TREE_TYPE (decl);
+ if (local_variables_to_volatilize == NULL)
+ local_variables_to_volatilize = VEC_alloc (tree, gc, 8);


-      t = objc_build_volatilized_type (t);
+      VEC_safe_push (tree, gc, local_variables_to_volatilize, decl);
+    }
+}

- TREE_TYPE (decl) = t;
- TREE_THIS_VOLATILE (decl) = 1;
- TREE_SIDE_EFFECTS (decl) = 1;
- DECL_REGISTER (decl) = 0;
+/* Called when parsing of a function completes; if any local variables
+ in the function were marked as variables to volatilize, change them
+ to volatile. We do this at the end of the function when the
+ warnings about discarding 'volatile' have already been produced.
+ We are making the variables as volatile just to force the compiler
+ to preserve them between setjmp/longjmp, but we don't want warnings
+ for them as they aren't really volatile. */
+void
+objc_finish_function (void)
+{
+ /* If there are any local variables to volatilize, volatilize them. */
+ if (local_variables_to_volatilize)
+ {
+ int i;
+ tree decl;
+ FOR_EACH_VEC_ELT (tree, local_variables_to_volatilize, i, decl)
+ {
+ tree t = TREE_TYPE (decl);
+
+ t = build_qualified_type (t, TYPE_QUALS (t) | TYPE_QUAL_VOLATILE);
+ TREE_TYPE (decl) = t;
+ TREE_THIS_VOLATILE (decl) = 1;
+ TREE_SIDE_EFFECTS (decl) = 1;
+ DECL_REGISTER (decl) = 0;
#ifndef OBJCPLUS
- C_DECL_REGISTER (decl) = 0;
+ C_DECL_REGISTER (decl) = 0;
#endif
+ }
+
+ /* Now we delete the vector. This sets it to NULL as well. */
+ VEC_free (tree, gc, local_variables_to_volatilize);
}
}


@@ -2691,24 +2667,6 @@ objc_have_common_type (tree ltyp, tree r
   return false;
 }

-/* Check if LTYP and RTYP have the same type qualifiers. If either type
- lives in the volatilized hash table, ignore the 'volatile' bit when
- making the comparison. */
-
-bool
-objc_type_quals_match (tree ltyp, tree rtyp)
-{
- int lquals = TYPE_QUALS (ltyp), rquals = TYPE_QUALS (rtyp);
-
- if (lookup_attribute ("objc_volatilized", TYPE_ATTRIBUTES (ltyp)))
- lquals &= ~TYPE_QUAL_VOLATILE;
-
- if (lookup_attribute ("objc_volatilized", TYPE_ATTRIBUTES (rtyp)))
- rquals &= ~TYPE_QUAL_VOLATILE;
-
- return (lquals == rquals);
-}
-
#ifndef OBJCPLUS
/* Determine if CHILD is derived from PARENT. The routine assumes that
both parameters are RECORD_TYPEs, and is non-reflexive. */
@@ -2828,16 +2786,6 @@ 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
@@ -5353,6 +5301,9 @@ objc_begin_try_stmt (location_t try_locu
error_at (try_locus, "%<-fobjc-exceptions%> is required to enable Objective-C exception syntax");
}


+  /* Collect the list of local variables.  We'll mark them as volatile
+     at the end of compilation of this function to prevent them being
+     clobbered by setjmp/longjmp.  */
   if (flag_objc_sjlj_exceptions)
     objc_mark_locals_volatile (NULL);
 }
Index: objc/ChangeLog
===================================================================
--- objc/ChangeLog      (revision 167292)
+++ objc/ChangeLog      (working copy)
@@ -1,3 +1,14 @@
+2010-11-30  Nicola Pero  <nicola.pero@meta-innovation.com>
+
+       * objc-act.c (objc_build_volatilized_type): Removed.
+       (objc_non_volatilized_type): Removed.
+       (objc_type_quals_match): Removed.
+       (local_variables_to_volatilize): New.
+       (objc_volatilize_decl): Add the decl to volatilize to
+       local_variables_to_volatilize, but don't volatilize it yet.
+       (objc_finish_function): New.
+       * objc-act.h (local_variables_to_volatilize): New.
+
 2010-11-29  Nicola Pero  <nicola.pero@meta-innovation.com>
            Mike Stump  <mikestump@comcast.net>

Index: objc/objc-act.h
===================================================================
--- objc/objc-act.h     (revision 167292)
+++ objc/objc-act.h     (working copy)
@@ -253,6 +253,10 @@ extern GTY ((length ("SIZEHASHTABLE")))

#define SIZEHASHTABLE 257

+/* An array of all the local variables in the current function that
+   need to be marked as volatile.  */
+extern GTY(()) VEC(tree,gc) *local_variables_to_volatilize;
+
 /* Objective-C/Objective-C++ @implementation list.  */

 struct GTY(()) imp_entry {
Index: ChangeLog
===================================================================
--- ChangeLog   (revision 167292)
+++ ChangeLog   (working copy)
@@ -1,3 +1,10 @@
+2010-11-30  Nicola Pero  <nicola.pero@meta-innovation.com>
+
+       * c-decl.c (finish_function): Call objc_finish_function in
+       Objective-C.
+       * c-typeck.c (convert_for_assignment): Do not call
+       objc_type_quals_match().
+
 2010-11-30  Richard Guenther  <rguenther@suse.de>

PR lto/44986
Index: cp/typeck.c
===================================================================
--- cp/typeck.c (revision 167292)
+++ cp/typeck.c (working copy)
@@ -7869,16 +7869,10 @@ comp_ptr_ttypes_real (tree to, tree from
so the usual checks are not appropriate. */
if (TREE_CODE (to) != FUNCTION_TYPE && TREE_CODE (to) != METHOD_TYPE)
{
- /* In Objective-C++, some types may have been 'volatilized' by
- the compiler for EH; when comparing them here, the volatile
- qualification must be ignored. */
- tree nv_to = objc_non_volatilized_type (to);
- tree nv_from = objc_non_volatilized_type (from);
-
- if (!at_least_as_qualified_p (nv_to, nv_from))
+ if (!at_least_as_qualified_p (to, from))
return 0;


-         if (!at_least_as_qualified_p (nv_from, nv_to))
+         if (!at_least_as_qualified_p (from, to))
            {
              if (constp == 0)
                return 0;
@@ -7886,7 +7880,7 @@ comp_ptr_ttypes_real (tree to, tree from
            }

          if (constp > 0)
-           constp &= TYPE_READONLY (nv_to);
+           constp &= TYPE_READONLY (to);
        }

       if (TREE_CODE (to) == VECTOR_TYPE)
Index: cp/decl.c
===================================================================
--- cp/decl.c   (revision 167292)
+++ cp/decl.c   (working copy)
@@ -12811,6 +12811,9 @@ finish_function (int flags)
   if (fndecl == NULL_TREE)
     return error_mark_node;

+  if (c_dialect_objc ())
+    objc_finish_function ();
+
   gcc_assert (!defer_mark_used_calls);
   defer_mark_used_calls = true;

Index: cp/ChangeLog
===================================================================
--- cp/ChangeLog        (revision 167292)
+++ cp/ChangeLog        (working copy)
@@ -1,3 +1,12 @@
+2010-11-30  Nicola Pero  <nicola.pero@meta-innovation.com>
+
+       * decl.c (finish_function): Call objc_finish_function when
+       compiling Objective-C++.
+       * call.c (standard_conversion): Do not call
+       objc_non_volatilized_type().
+       (implicit_conversion): Same change.
+       * typeck.c (comp_ptr_ttypes_real): Same change.
+
 2010-11-29  Dodji Seketeli  <dodji@redhat.com>

        PR c++/42260
Index: cp/call.c
===================================================================
--- cp/call.c   (revision 167292)
+++ cp/call.c   (working copy)
@@ -872,8 +872,6 @@ standard_conversion (tree to, tree 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 (nfrom)));
@@ -1483,9 +1481,6 @@ implicit_conversion (tree to, tree from,
       || 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: c-decl.c
===================================================================
--- c-decl.c    (revision 167292)
+++ c-decl.c    (working copy)
@@ -8184,6 +8184,9 @@ void
 finish_function (void)
 {
   tree fndecl = current_function_decl;
+
+  if (c_dialect_objc ())
+    objc_finish_function ();

if (TREE_CODE (fndecl) == FUNCTION_DECL
&& targetm.calls.promote_prototypes (TREE_TYPE (fndecl)))
Index: c-typeck.c
===================================================================
--- c-typeck.c (revision 167292)
+++ c-typeck.c (working copy)
@@ -5605,20 +5605,16 @@ convert_for_assignment (location_t locat
if (TYPE_QUALS_NO_ADDR_SPACE (ttr)
& ~TYPE_QUALS_NO_ADDR_SPACE (ttl))
{
- /* Types differing only by the presence of the 'volatile'
- qualifier are acceptable if the 'volatile' has been added
- in by the Objective-C EH machinery. */
- if (!objc_type_quals_match (ttl, ttr))
- WARN_FOR_QUALIFIERS (location, 0,
- G_("passing argument %d of %qE discards "
- "%qv qualifier from pointer target type"),
- G_("assignment discards %qv qualifier "
- "from pointer target type"),
- G_("initialization discards %qv qualifier "
- "from pointer target type"),
- G_("return discards %qv qualifier from "
- "pointer target type"),
- TYPE_QUALS (ttr) & ~TYPE_QUALS (ttl));
+ WARN_FOR_QUALIFIERS (location, 0,
+ G_("passing argument %d of %qE discards "
+ "%qv qualifier from pointer target type"),
+ G_("assignment discards %qv qualifier "
+ "from pointer target type"),
+ G_("initialization discards %qv qualifier "
+ "from pointer target type"),
+ G_("return discards %qv qualifier from "
+ "pointer target type"),
+ TYPE_QUALS (ttr) & ~TYPE_QUALS (ttl));
}
/* If this is not a case of ignoring a mismatch in signedness,
no warning. */



Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]