ObjC/ObjC++: Fix try-catch failures on a darwin, second take (this one fixes them all)
Nicola Pero
nicola.pero@meta-innovation.com
Tue Nov 30 20:36:00 GMT 2010
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. */
More information about the Gcc-patches
mailing list