]> gcc.gnu.org Git - gcc.git/commitdiff
re PR java/21045 (Anonymous inner class constructor's exceptions can't be caught...
authorBryce McKinlay <mckinlay@redhat.com>
Thu, 7 Jul 2005 14:34:53 +0000 (14:34 +0000)
committerBryce McKinlay <bryce@gcc.gnu.org>
Thu, 7 Jul 2005 14:34:53 +0000 (15:34 +0100)
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.

From-SVN: r101713

gcc/java/ChangeLog
gcc/java/parse.y
libjava/ChangeLog
libjava/testsuite/libjava.compile/PR21045.java [new file with mode: 0644]
libjava/testsuite/libjava.jacks/jacks.xfail

index bb7f08a6e74c2102a8e68d6789345376d28b1fc9..88284867b6536810a5bf4e74aed01b7031475062 100644 (file)
@@ -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
index 89e3e6e05e275ecfc90694a7eb1a1aca0cdb826c..9a094e5d61b46bd50b6ab80dd4e015a66c2bf075 100644 (file)
@@ -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'
index 657e238d87924a450821470d37fb528044f3b257..e0825bbc4ea78902105c081579d49d69b666f60f 100644 (file)
@@ -1,3 +1,9 @@
+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.
+
 2005-07-06  Tom Tromey  <tromey@redhat.com>
 
        * java/io/InputStreamReader.java (refill): Handle no-progress
diff --git a/libjava/testsuite/libjava.compile/PR21045.java b/libjava/testsuite/libjava.compile/PR21045.java
new file mode 100644 (file)
index 0000000..3d34ee1
--- /dev/null
@@ -0,0 +1,11 @@
+public class PR21045
+{
+       class InnerBase {
+               InnerBase() throws Exception, NullPointerException {}
+       }
+       void method() {
+               try {
+                       InnerBase obj = new InnerBase() {};
+               } catch (Exception e) {}
+       }
+}
index b8ac229b62f04ee9e7fd7263e27a38e4b0cc712b..68af018a5f483b57a449ddbe1362e15193fe3e26 100644 (file)
 15.9.4-runtime-creation-1
 15.9.4-runtime-creation-2
 15.9.4-runtime-creation-5
-15.9.5.1-exception-1
-15.9.5.1-exception-3
 15.9.5.1-exception-4
 15.9.5.1-superconstructor-7
 15.9.5.1-superconstructor-8
 8.3.1.2-final-29
 8.3.2-abrupt-3
 8.3.2-abrupt-5
-8.3.2-abrupt-6
-8.3.2-abrupt-7
 8.3.2.2-super-2
 8.3.2.3-illegal-forward-instance-1
 8.3.2.3-illegal-forward-instance-2
This page took 0.098154 seconds and 5 git commands to generate.