summaryrefslogtreecommitdiff
path: root/gcc/java
diff options
context:
space:
mode:
authorbryce <bryce@138bc75d-0d04-0410-961f-82ee72b054a4>2005-07-07 14:34:53 +0000
committerbryce <bryce@138bc75d-0d04-0410-961f-82ee72b054a4>2005-07-07 14:34:53 +0000
commit44fcaed094c04339ba09f22197914463cd92aa69 (patch)
tree1c18a770e3b496c37eb199d56bcba0fed43cf098 /gcc/java
parentdda067b9b5ccf4b56314d719820288e9789e3885 (diff)
downloadgcc-44fcaed094c04339ba09f22197914463cd92aa69.tar.gz
2005-07-07 Bryce McKinlay <mckinlay@redhat.com>
PR java/21045 * parse.y (add_exception_to_throws): New function. (purge_unchecked_exceptions): Removed. (get_constructor_super): Renamed from verify_constructor_super. Now returns the super constructor after verification. (java_complete_expand_method): Don't use purge_unchecked_exceptions or save/restore the exception list. (check_thrown_exceptions): Add uncaught exceptions in anonymous class initializers and constructors to the throws clause of the method. 2005-07-07 Bryce McKinlay <mckinlay@redhat.com> * testsuite/libjava.compile/PR21045.java: New test. * testsuite/libjava.jacks/jacks.xfail: Remove 15.9.5.1-exception-1, 15.9.5.1-exception-3, 8.3.2-abrupt-6, 8.3.2-abrupt-7. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@101713 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/java')
-rw-r--r--gcc/java/ChangeLog12
-rw-r--r--gcc/java/parse.y110
2 files changed, 76 insertions, 46 deletions
diff --git a/gcc/java/ChangeLog b/gcc/java/ChangeLog
index bb7f08a6e74..88284867b65 100644
--- a/gcc/java/ChangeLog
+++ b/gcc/java/ChangeLog
@@ -1,3 +1,15 @@
+2005-07-07 Bryce McKinlay <mckinlay@redhat.com>
+
+ PR java/21045
+ * parse.y (add_exception_to_throws): New function.
+ (purge_unchecked_exceptions): Removed.
+ (get_constructor_super): Renamed from verify_constructor_super. Now
+ returns the super constructor after verification.
+ (java_complete_expand_method): Don't use purge_unchecked_exceptions
+ or save/restore the exception list.
+ (check_thrown_exceptions): Add uncaught exceptions in anonymous
+ class initializers and constructors to the throws clause of the method.
+
2005-07-05 Bryce McKinlay <mckinlay@redhat.com>
PR java/19674
diff --git a/gcc/java/parse.y b/gcc/java/parse.y
index 89e3e6e05e2..9a094e5d61b 100644
--- a/gcc/java/parse.y
+++ b/gcc/java/parse.y
@@ -233,13 +233,13 @@ static tree build_try_finally_statement (int, tree, tree);
static tree patch_try_statement (tree);
static tree patch_synchronized_statement (tree, tree);
static tree patch_throw_statement (tree, tree);
+static void add_exception_to_throws (tree, tree);
#ifdef USE_MAPPED_LOCATION
static void check_thrown_exceptions (source_location, tree, tree);
#else
static void check_thrown_exceptions (int, tree, tree);
#endif
static int check_thrown_exceptions_do (tree);
-static void purge_unchecked_exceptions (tree);
static bool ctors_unchecked_throws_clause_p (tree);
static void check_concrete_throws_clauses (tree, tree, tree, tree);
static void check_throws_clauses (tree, tree, tree);
@@ -256,7 +256,7 @@ static tree build_instinit_invocation (tree);
static void fix_constructors (tree);
static tree build_alias_initializer_parameter_list (int, tree, tree, int *);
static tree craft_constructor (tree, tree);
-static int verify_constructor_super (tree);
+static tree get_constructor_super (tree);
static tree create_artificial_method (tree, int, tree, tree, tree);
static void start_artificial_method_body (tree);
static void end_artificial_method_body (tree);
@@ -2082,7 +2082,7 @@ anonymous_class_creation:
must be generated following the hints provided by
the `new' expression. Whether a super constructor
of that nature exists or not is to be verified
- later on in verify_constructor_super.
+ later on in get_constructor_super.
It's during the expansion of a `new' statement
referring to an anonymous class that a ctor will
@@ -8161,11 +8161,6 @@ java_complete_expand_method (tree mdecl)
current_this = (!METHOD_STATIC (mdecl) ?
BLOCK_EXPR_DECLS (DECL_FUNCTION_BODY (mdecl)) : NULL_TREE);
- /* Purge the `throws' list of unchecked exceptions (we save a copy
- of the list and re-install it later.) */
- exception_copy = copy_list (DECL_FUNCTION_THROWS (mdecl));
- purge_unchecked_exceptions (mdecl);
-
/* Install exceptions thrown with `throws' */
PUSH_EXCEPTIONS (DECL_FUNCTION_THROWS (mdecl));
@@ -8223,9 +8218,6 @@ java_complete_expand_method (tree mdecl)
POP_EXCEPTIONS();
if (currently_caught_type_list)
abort ();
-
- /* Restore the copy of the list of exceptions. */
- DECL_FUNCTION_THROWS (mdecl) = exception_copy;
}
/* For with each class for which there's code to generate. */
@@ -9038,7 +9030,8 @@ fix_constructors (tree mdecl)
/* It is an error for the compiler to generate a default
constructor if the superclass doesn't have a constructor that
takes no argument, or the same args for an anonymous class */
- if (verify_constructor_super (mdecl))
+ tree sdecl = get_constructor_super (mdecl);
+ if (sdecl == NULL_TREE)
{
tree sclass_decl = TYPE_NAME (CLASSTYPE_SUPER (class_type));
tree save = DECL_NAME (mdecl);
@@ -9051,6 +9044,13 @@ fix_constructors (tree mdecl)
DECL_NAME (mdecl) = save;
}
+ if (ANONYMOUS_CLASS_P (class_type))
+ {
+ /* Copy throws clause from the super constructor. */
+ tree throws = DECL_FUNCTION_THROWS (sdecl);
+ DECL_FUNCTION_THROWS (mdecl) = copy_list (throws);
+ }
+
/* The constructor body must be crafted by hand. It's the
constructor we defined when we realize we didn't have the
CLASSNAME() constructor */
@@ -9135,19 +9135,18 @@ fix_constructors (tree mdecl)
}
/* Browse constructors in the super class, searching for a constructor
- that doesn't take any argument. Return 0 if one is found, 1
- otherwise. If the current class is an anonymous inner class, look
- for something that has the same signature. */
-
-static int
-verify_constructor_super (tree mdecl)
+ that doesn't take any argument. Return the constructor if one is found,
+ NULL_TREE otherwise. If the current class is an anonymous inner class,
+ look for something that has the same signature. */
+static tree
+get_constructor_super (tree mdecl)
{
tree class = CLASSTYPE_SUPER (current_class);
int super_inner = PURE_INNER_CLASS_TYPE_P (class);
tree sdecl;
if (!class)
- return 0;
+ return NULL_TREE;
if (ANONYMOUS_CLASS_P (current_class))
{
@@ -9171,7 +9170,7 @@ verify_constructor_super (tree mdecl)
break;
if (arg_type == end_params_node && m_arg_type == end_params_node)
- return 0;
+ return sdecl;
}
}
else
@@ -9182,10 +9181,10 @@ verify_constructor_super (tree mdecl)
if (super_inner)
arg = TREE_CHAIN (arg);
if (DECL_CONSTRUCTOR_P (sdecl) && arg == end_params_node)
- return 0;
+ return sdecl;
}
}
- return 1;
+ return NULL_TREE;
}
/* Generate code for all context remembered for code generation. */
@@ -15911,6 +15910,34 @@ patch_throw_statement (tree node, tree wfl_op1)
return node;
}
+/* Add EXCEPTION to the throws clause of MDECL. If MDECL already throws
+ a super-class of EXCEPTION, keep the superclass instead. If MDECL already
+ throws a sub-class of EXCEPTION, replace the sub-class with EXCEPTION. */
+static void
+add_exception_to_throws (tree mdecl, tree exception)
+{
+ tree mthrows;
+
+ /* Ignore unchecked exceptions. */
+ if (IS_UNCHECKED_EXCEPTION_P (exception))
+ return;
+
+ for (mthrows = DECL_FUNCTION_THROWS (mdecl);
+ mthrows; mthrows = TREE_CHAIN (mthrows))
+ {
+ if (inherits_from_p (exception, TREE_VALUE (mthrows)))
+ return;
+ if (inherits_from_p (TREE_VALUE (mthrows), exception))
+ {
+ TREE_VALUE (mthrows) = exception;
+ return;
+ }
+ }
+
+ mthrows = DECL_FUNCTION_THROWS (mdecl);
+ DECL_FUNCTION_THROWS (mdecl) = build_tree_list (mthrows, exception);
+}
+
/* Check that exception said to be thrown by method DECL can be
effectively caught from where DECL is invoked. THIS_EXPR is the
expression that computes `this' for the method call. */
@@ -15950,10 +15977,21 @@ check_thrown_exceptions (
#else
EXPR_WFL_LINECOL (wfl_operator) = location;
#endif
- if (DECL_FINIT_P (current_function_decl))
- parse_error_context
- (wfl_operator, "Exception %qs can't be thrown in initializer",
- lang_printable_name (TREE_VALUE (throws), 0));
+ if (ANONYMOUS_CLASS_P (DECL_CONTEXT (current_function_decl))
+ && (DECL_FINIT_P (current_function_decl)
+ || DECL_INIT_P (current_function_decl)
+ || DECL_CONSTRUCTOR_P (current_function_decl)))
+ {
+ /* Add "throws" to the initializer's exception list */
+ tree exception = TREE_VALUE (throws);
+ add_exception_to_throws (current_function_decl, exception);
+ }
+ else if (DECL_FINIT_P (current_function_decl))
+ {
+ parse_error_context
+ (wfl_operator, "Exception %qs can't be thrown in initializer",
+ lang_printable_name (TREE_VALUE (throws), 0));
+ }
else
{
parse_error_context
@@ -15990,26 +16028,6 @@ check_thrown_exceptions_do (tree exception)
return 0;
}
-static void
-purge_unchecked_exceptions (tree mdecl)
-{
- tree throws = DECL_FUNCTION_THROWS (mdecl);
- tree new = NULL_TREE;
-
- while (throws)
- {
- tree next = TREE_CHAIN (throws);
- if (!IS_UNCHECKED_EXCEPTION_P (TREE_VALUE (throws)))
- {
- TREE_CHAIN (throws) = new;
- new = throws;
- }
- throws = next;
- }
- /* List is inverted here, but it doesn't matter */
- DECL_FUNCTION_THROWS (mdecl) = new;
-}
-
/* This function goes over all of CLASS_TYPE ctors and checks whether
each of them features at least one unchecked exception in its
`throws' clause. If it's the case, it returns `true', `false'