]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
except.c (find_handler_in_range): The upper limit for exception ranges is exclusive...
authorAndrew Haley <aph@cygnus.com>
Mon, 21 Jun 1999 09:18:50 +0000 (09:18 +0000)
committerAndrew Haley <aph@gcc.gnu.org>
Mon, 21 Jun 1999 09:18:50 +0000 (09:18 +0000)
1999-06-21  Andrew Haley  <aph@cygnus.com>
        * except.c (find_handler_in_range): The upper limit for exception
        ranges is exclusive, not inclusive: (start <= pc < end).
        (link_handler): find child pointer which points to outer by
        searching sibling list: previous code incorrectly assumed that
        outer->outer->first_child must point to outer.
        * verify.c (verify_jvm_instructions): FIXME added to code for
        `athrow'.
        (verify_jvm_instructions): Do not assume that the last block
        processed in a subroutine is a block which ends with a `ret'
        instruction.  With some control flows it is possible that the last
        block ends with an `athrow'.

From-SVN: r27658

gcc/java/ChangeLog
gcc/java/except.c
gcc/java/verify.c

index bf8e310dcfcc6c6624fc81fa0184eede8795e53f..4136698a65eef0d3549dfa12f6ab705379eccf6d 100644 (file)
@@ -1,3 +1,17 @@
+1999-06-21  Andrew Haley  <aph@cygnus.com>
+
+        * except.c (find_handler_in_range): The upper limit for exception
+        ranges is exclusive, not inclusive: (start <= pc < end).  
+        (link_handler): find child pointer which points to outer by
+        searching sibling list: previous code incorrectly assumed that
+        outer->outer->first_child must point to outer.
+        * verify.c (verify_jvm_instructions): FIXME added to code for
+        `athrow'.
+        (verify_jvm_instructions): Do not assume that the last block
+        processed in a subroutine is a block which ends with a `ret'
+        instruction.  With some control flows it is possible that the last
+        block ends with an `athrow'.
+
 Mon Jun 14 13:13:39 1999  Alexandre Petit-Bianco  <apbianco@cygnus.com>
 
        * parse.y (qualify_ambiguous_name): Reorganized the post
index c8674f31f28c4cebf83d2db12985faf8b5476c36..46d98df162c7b2bc828be8b50a610da7f4a2b171 100644 (file)
@@ -72,7 +72,7 @@ find_handler_in_range (pc, range, child)
     {
       if (pc < child->start_pc)
        break;
-      if (pc <= child->end_pc)
+      if (pc < child->end_pc)
        return find_handler_in_range (pc, child, child->first_child);
     }
   cache_range = range;
@@ -129,7 +129,12 @@ link_handler (range, outer)
       range->outer = outer->outer;
       range->next_sibling = NULL;
       range->first_child = outer;
-      outer->outer->first_child = range;
+      {
+       struct eh_range **pr = &(outer->outer->first_child);
+       while (*pr != outer)
+         pr = &(*pr)->next_sibling;
+       *pr = range;
+      }
       outer->outer = range;
       return;
     }
index df3dcac2d82e4050b7278cccd4a5aa0e81c5dc4e..ead4ea6ec1fd6225093e2b95450c1368cea369c5 100644 (file)
@@ -999,6 +999,7 @@ verify_jvm_instructions (jcf, byte_ops, length)
          break;
 
        case OPCODE_athrow:
+         // FIXME: athrow also empties the stack.
          pop_type (throwable_type_node);
          INVALIDATE_PC;
          break;
@@ -1197,21 +1198,46 @@ verify_jvm_instructions (jcf, byte_ops, length)
                    }
                }
 
+
+            }
+          break;
+        case OPCODE_jsr_w:        
+        case OPCODE_ret_w:
+        default:
+          error ("unknown opcode %d@pc=%d during verification", op_code, PC-1);
+          return 0;
+        }
+
              /* Check if there are any more pending blocks in this subroutine.
                 Because we push pending blocks in a last-in-first-out order,
                 and because we don't push anything from our caller until we
                 are done with this subroutine or anything nested in it,
                 then we are done if the top of the pending_blocks stack is
                 not in a subroutine, or it is in our caller. */
+      if (current_subr 
+         && PC == INVALID_PC)
+       {
+         tree caller = LABEL_SUBR_CONTEXT (current_subr);
+
              if (pending_blocks == NULL_TREE
                  || ! LABEL_IN_SUBR (pending_blocks)
                  || LABEL_SUBR_START (pending_blocks) == caller)
                {
-                 /* Since we are done with this subroutine (i.e. this is the
-                    last ret from it), set up the (so far known) return
-                    address as pending - with the merged type state. */
-                 tmp = LABEL_RETURN_LABELS (current_subr);
-                 current_subr = caller;
+             int size = DECL_MAX_LOCALS(current_function_decl)+stack_pointer;
+             tree ret_map = LABEL_RETURN_TYPE_STATE (current_subr);
+             tmp = LABEL_RETURN_LABELS (current_subr);
+             
+             /* FIXME: If we exit a subroutine via a throw, we might
+                have returned to an earlier caller.  Obviously a
+                "ret" can only return one level, but a throw may
+                return many levels.*/
+             current_subr = caller;
+
+             if (RETURN_MAP_ADJUSTED (ret_map))
+               {
+                 /* Since we are done with this subroutine , set up
+                    the (so far known) return address as pending -
+                    with the merged type state. */
                  for ( ; tmp != NULL_TREE;  tmp = TREE_CHAIN (tmp))
                    {
                      tree return_label = TREE_VALUE (tmp);
@@ -1241,12 +1267,6 @@ verify_jvm_instructions (jcf, byte_ops, length)
                    }
                }
            }
-         break;
-       case OPCODE_jsr_w:        
-       case OPCODE_ret_w:
-        default:
-         error ("unknown opcode %d@pc=%d during verification", op_code, PC-1);
-         return 0;
        }
 
       prevpc = oldpc;