1 /* Handle verification of bytecoded methods for the GNU compiler for
3 Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003
4 Free Software Foundation, Inc.
6 This file is part of GCC.
8 GCC is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2, or (at your option)
13 GCC is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with GCC; see the file COPYING. If not, write to
20 the Free Software Foundation, 59 Temple Place - Suite 330,
21 Boston, MA 02111-1307, USA.
23 Java and all Java-based marks are trademarks or registered trademarks
24 of Sun Microsystems, Inc. in the United States and other countries.
25 The Free Software Foundation is independent of Sun Microsystems, Inc. */
29 #include "coretypes.h"
32 #include "java-tree.h"
34 #include "java-opcodes.h"
36 #include "java-except.h"
39 static void push_pending_label (tree
);
40 static tree
merge_types (tree
, tree
);
41 static const char *check_pending_block (tree
);
42 static void type_stack_dup (int, int);
43 static int start_pc_cmp (const void *, const void *);
44 static char *pop_argument_types (tree
);
46 extern int stack_pointer
;
48 /* During verification, start of the current subroutine (jsr target). */
51 /* A list of pending blocks, chained using LABEL_PENDING_CHAIN.
52 A pending block is one that has LABEL_CHANGED set, which means
53 it requires (re-) verification. */
56 /* Append TARGET_LABEL to the pending_block stack unless already in it. */
59 push_pending_label (tree target_label
)
61 if (! LABEL_CHANGED (target_label
))
63 LABEL_PENDING_CHAIN (target_label
) = pending_blocks
;
64 pending_blocks
= target_label
;
65 LABEL_CHANGED (target_label
) = 1;
69 /* Note that TARGET_LABEL is a possible successor instruction.
70 Merge the type state etc.
71 Return NULL on success, or an error message on failure. */
74 check_pending_block (tree target_label
)
76 int changed
= merge_type_state (target_label
);
81 return "types could not be merged";
82 push_pending_label (target_label
);
85 if (current_subr
== NULL
)
87 if (LABEL_IN_SUBR (target_label
))
88 return "might transfer control into subroutine";
92 if (LABEL_IN_SUBR (target_label
))
94 if (LABEL_SUBR_START (target_label
) != current_subr
)
95 return "transfer out of subroutine";
97 else if (! LABEL_VERIFIED (target_label
))
99 LABEL_IN_SUBR (target_label
) = 1;
100 LABEL_SUBR_START (target_label
) = current_subr
;
103 return "transfer out of subroutine";
108 /* Count the number of nested jsr calls needed to reach LABEL. */
111 subroutine_nesting (tree label
)
114 while (label
!= NULL_TREE
&& LABEL_IN_SUBR (label
))
116 if (! LABEL_IS_SUBR_START(label
))
117 label
= LABEL_SUBR_START (label
);
118 label
= LABEL_SUBR_CONTEXT (label
);
124 /* Return the "merged" types of TYPE1 and TYPE2.
125 If either is primitive, the other must match (after promotion to int).
126 For reference types, return the common super-class.
127 Return TYPE_UNKNOWN if the types cannot be merged. */
130 merge_types (tree type1
, tree type2
)
134 if (type1
== TYPE_UNKNOWN
|| type2
== TYPE_UNKNOWN
135 || type1
== TYPE_RETURN_ADDR
|| type2
== TYPE_RETURN_ADDR
)
137 if (TREE_CODE (type1
) == POINTER_TYPE
&& TREE_CODE (type2
) == POINTER_TYPE
)
141 /* ptr_type_node is only used for a null reference,
142 which is compatible with any reference type. */
143 if (type1
== ptr_type_node
|| type2
== object_ptr_type_node
)
145 if (type2
== ptr_type_node
|| type1
== object_ptr_type_node
)
148 tt1
= TREE_TYPE (type1
);
149 tt2
= TREE_TYPE (type2
);
151 /* If tt{1,2} haven't been properly loaded, now is a good time
153 if (!TYPE_SIZE (tt1
))
156 safe_layout_class (tt1
);
159 if (!TYPE_SIZE (tt2
))
162 safe_layout_class (tt2
);
165 if (TYPE_ARRAY_P (tt1
) || TYPE_ARRAY_P (tt2
))
167 if (TYPE_ARRAY_P (tt1
) == TYPE_ARRAY_P (tt2
))
169 tree el_type1
= TYPE_ARRAY_ELEMENT (tt1
);
170 tree el_type2
= TYPE_ARRAY_ELEMENT (tt2
);
171 tree el_type
= NULL_TREE
;
172 if (el_type1
== el_type2
)
174 else if (TREE_CODE (el_type1
) == POINTER_TYPE
175 && TREE_CODE (el_type2
) == POINTER_TYPE
)
176 el_type
= merge_types (el_type1
, el_type2
);
177 if (el_type
!= NULL_TREE
)
179 HOST_WIDE_INT len1
= java_array_type_length (tt1
);
180 HOST_WIDE_INT len2
= java_array_type_length (tt2
);
183 else if (el_type1
== el_type2
)
185 return promote_type (build_java_array_type (el_type
, len1
));
188 return object_ptr_type_node
;
191 if (CLASS_INTERFACE (TYPE_NAME (tt1
)))
193 /* FIXME: should see if two interfaces have a common
195 if (CLASS_INTERFACE (TYPE_NAME (tt2
)))
197 /* This is a kludge, but matches what Sun's verifier does.
198 It can be tricked, but is safe as long as type errors
199 (i.e. interface method calls) are caught at run-time. */
200 return object_ptr_type_node
;
204 if (can_widen_reference_to (tt2
, tt1
))
207 return object_ptr_type_node
;
210 else if (CLASS_INTERFACE (TYPE_NAME (tt2
)))
212 if (can_widen_reference_to (tt1
, tt2
))
215 return object_ptr_type_node
;
221 depth1
= class_depth (type1
);
222 depth2
= class_depth (type2
);
223 for ( ; depth1
> depth2
; depth1
--)
224 type1
= TYPE_BINFO_BASETYPE (type1
, 0);
225 for ( ; depth2
> depth1
; depth2
--)
226 type2
= TYPE_BINFO_BASETYPE (type2
, 0);
227 while (type1
!= type2
)
229 type1
= TYPE_BINFO_BASETYPE (type1
, 0);
230 type2
= TYPE_BINFO_BASETYPE (type2
, 0);
232 return promote_type (type1
);
234 if (INTEGRAL_TYPE_P (type1
) && INTEGRAL_TYPE_P (type2
)
235 && TYPE_PRECISION (type1
) <= 32 && TYPE_PRECISION (type2
) <= 32)
236 return int_type_node
;
240 /* Merge the current type state with that at LABEL.
241 Return -1 the the states are incompatible (i.e. on error),
242 0 if there was no change, and 1 if there was a change. */
245 merge_type_state (tree label
)
247 int nlocals
= DECL_MAX_LOCALS (current_function_decl
);
248 int cur_length
= stack_pointer
+ nlocals
;
249 tree vec
= LABEL_TYPE_STATE (label
);
251 if (vec
== NULL_TREE
)
255 vec
= make_tree_vec (cur_length
);
256 LABEL_TYPE_STATE (label
) = vec
;
258 while (--cur_length
>= 0)
259 TREE_VEC_ELT (vec
, cur_length
) = type_map
[cur_length
];
266 if (LABEL_IS_SUBR_START (label
) && LABEL_VERIFIED (label
)
267 && current_subr
!= label
)
268 return_map
= LABEL_RETURN_TYPE_STATE (label
);
270 return_map
= NULL_TREE
;
271 if (TREE_VEC_LENGTH (vec
) != cur_length
)
275 for (i
= 0; i
< cur_length
; i
++)
277 tree old_type
= TREE_VEC_ELT (vec
, i
);
278 tree new_type
= merge_types (old_type
, type_map
[i
]);
279 if (TREE_VEC_ELT (vec
, i
) != new_type
)
281 /* If there has been a change, note that since we must re-verify.
282 However, if the label is the start of a subroutine,
283 we don't care about local variables that are neither
284 set nor used in the sub-routine. */
285 if (return_map
== NULL_TREE
|| i
>= nlocals
286 || TREE_VEC_ELT (return_map
, i
) != TYPE_UNUSED
287 || (TYPE_IS_WIDE (new_type
)
288 && TREE_VEC_ELT (return_map
, i
+1) != TYPE_UNUSED
))
291 TREE_VEC_ELT (vec
, i
) = new_type
;
292 if (new_type
== TYPE_UNKNOWN
)
297 else if (TYPE_IS_WIDE (new_type
))
304 /* Handle dup-like operations. */
307 type_stack_dup (int size
, int offset
)
311 for (index
= 0; index
< size
+ offset
; index
++)
313 type
[index
] = stack_type_map
[stack_pointer
- 1];
314 if (type
[index
] == void_type_node
)
317 type
[index
] = stack_type_map
[stack_pointer
- 2];
318 if (! TYPE_IS_WIDE (type
[index
]))
320 if (index
== size
|| index
== size
+ offset
)
321 /* Dup operation splits 64-bit number. */
324 pop_type (type
[index
]);
326 for (index
= size
; --index
>= 0; )
328 if (type
[index
] != void_type_node
)
329 push_type (type
[index
]);
332 for (index
= size
+ offset
; --index
>= 0; )
334 if (type
[index
] != void_type_node
)
335 push_type (type
[index
]);
339 /* This keeps track of a start PC and corresponding initial index. */
346 /* A helper that is used when sorting exception ranges. */
348 start_pc_cmp (const void *xp
, const void *yp
)
350 const struct pc_index
*x
= (const struct pc_index
*) xp
;
351 const struct pc_index
*y
= (const struct pc_index
*) yp
;
352 return x
->start_pc
- y
->start_pc
;
355 /* This causes the next iteration to ignore the next instruction
356 and look for some other unhandled instruction. */
357 #define INVALIDATE_PC (prevpc = -1, oldpc = PC, PC = INVALID_PC)
358 #define INVALID_PC (-1)
360 #define VERIFICATION_ERROR(MESSAGE) \
361 do { message = MESSAGE; goto verify_error; } while (0)
363 #define VERIFICATION_ERROR_WITH_INDEX(MESSAGE) \
364 do { message = MESSAGE; goto error_with_index; } while (0)
366 /* Recursive helper function to pop argument types during verification.
367 ARG_TYPES is the list of formal parameter types.
368 Return NULL on success and a freshly malloc'd error message on failure. */
371 pop_argument_types (tree arg_types
)
373 if (arg_types
== end_params_node
)
375 if (TREE_CODE (arg_types
) == TREE_LIST
)
377 char *message
= pop_argument_types (TREE_CHAIN (arg_types
));
379 pop_type_0 (TREE_VALUE (arg_types
), &message
);
385 #define POP_TYPE(TYPE, MESSAGE) \
386 do { pmessage = NULL; pop_type_0 (TYPE, &pmessage); \
387 if (pmessage != NULL) goto pop_type_error; \
390 #define POP_TYPE_CONV(TYPE, POPPED_TYPE, MESSAGE) \
391 do { pmessage = NULL; POPPED_TYPE = pop_type_0 (TYPE, &pmessage); \
392 if (pmessage != NULL) goto pop_type_error; \
395 #define PUSH_TYPE(TYPE) \
396 do { if (! push_type_0 (TYPE)) { goto stack_overflow; }} while (0)
398 #define PUSH_PENDING(LABEL) \
399 do { tree tmplab = LABEL; \
400 if ((message = check_pending_block (tmplab)) != NULL) \
401 { oldpc = LABEL_PC (tmplab); goto verify_error; }} while (0)
404 #define CHECK_PC_IN_RANGE(PC) ({if (PC < 0 || PC > length) goto bad_pc; (void)1;})
406 #define CHECK_PC_IN_RANGE(PC) (PC < 0 || PC > length ? (abort (), 0) : 1)
409 #define BCODE byte_ops
411 /* Verify the bytecodes of the current method.
412 Return 1 on success, 0 on failure. */
414 verify_jvm_instructions (JCF
* jcf
, const unsigned char *byte_ops
, long length
)
420 int oldpc
= 0; /* PC of start of instruction. */
421 int prevpc
= 0; /* If >= 0, PC of previous instruction. */
422 const char *message
= 0;
427 struct eh_range
*prev_eh_ranges
= NULL_EH_RANGE
;
428 struct eh_range
*eh_ranges
;
429 tree return_type
= TREE_TYPE (TREE_TYPE (current_function_decl
));
430 struct pc_index
*starts
;
435 pending_blocks
= NULL_TREE
;
437 /* Handle the exception table. */
438 method_init_exceptions ();
439 JCF_SEEK (jcf
, DECL_CODE_OFFSET (current_function_decl
) + length
);
440 eh_count
= JCF_readu2 (jcf
);
442 /* We read the exception handlers in order of increasing start PC.
443 To do this we first read and sort the start PCs. */
444 starts
= xmalloc (eh_count
* sizeof (struct pc_index
));
445 for (i
= 0; i
< eh_count
; ++i
)
447 starts
[i
].start_pc
= GET_u2 (jcf
->read_ptr
+ 8 * i
);
450 qsort (starts
, eh_count
, sizeof (struct pc_index
), start_pc_cmp
);
452 for (i
= 0; i
< eh_count
; ++i
)
454 int start_pc
, end_pc
, handler_pc
, catch_type
;
456 p
= jcf
->read_ptr
+ 8 * starts
[i
].index
;
458 start_pc
= GET_u2 (p
);
459 end_pc
= GET_u2 (p
+2);
460 handler_pc
= GET_u2 (p
+4);
461 catch_type
= GET_u2 (p
+6);
463 if (start_pc
< 0 || start_pc
>= length
464 || end_pc
< 0 || end_pc
> length
|| start_pc
>= end_pc
465 || handler_pc
< 0 || handler_pc
>= length
466 || ! (instruction_bits
[start_pc
] & BCODE_INSTRUCTION_START
)
467 || (end_pc
< length
&&
468 ! (instruction_bits
[end_pc
] & BCODE_INSTRUCTION_START
))
469 || ! (instruction_bits
[handler_pc
] & BCODE_INSTRUCTION_START
))
471 error ("bad pc in exception_table");
476 add_handler (start_pc
, end_pc
,
477 lookup_label (handler_pc
),
478 catch_type
== 0 ? NULL_TREE
479 : get_class_constant (jcf
, catch_type
));
481 instruction_bits
[handler_pc
] |= BCODE_EXCEPTION_TARGET
;
485 handle_nested_ranges ();
490 if (((PC
!= INVALID_PC
491 && instruction_bits
[PC
] & BCODE_TARGET
) != 0)
494 PUSH_PENDING (lookup_label (PC
));
497 /* Check if there are any more pending blocks in the current
498 subroutine. Because we push pending blocks in a
499 last-in-first-out order, and because we don't push anything
500 from our caller until we are done with this subroutine or
501 anything nested in it, then we are done if the top of the
502 pending_blocks stack is not in a subroutine, or it is in our
507 if (pending_blocks
== NULL_TREE
508 || (subroutine_nesting (pending_blocks
)
509 < subroutine_nesting (current_subr
)))
511 int size
= DECL_MAX_LOCALS(current_function_decl
)+stack_pointer
;
512 tree ret_map
= LABEL_RETURN_TYPE_STATE (current_subr
);
513 tmp
= LABEL_RETURN_LABELS (current_subr
);
515 /* FIXME: If we exit a subroutine via a throw, we might
516 have returned to an earlier caller. Obviously a
517 "ret" can only return one level, but a throw may
518 return many levels.*/
519 current_subr
= LABEL_SUBR_CONTEXT (current_subr
);
521 if (RETURN_MAP_ADJUSTED (ret_map
))
523 /* Since we are done with this subroutine , set up
524 the (so far known) return address as pending -
525 with the merged type state. */
526 for ( ; tmp
!= NULL_TREE
; tmp
= TREE_CHAIN (tmp
))
528 tree return_label
= TREE_VALUE (tmp
);
529 tree return_state
= LABEL_TYPE_STATE (return_label
);
530 if (return_state
== NULL_TREE
)
532 /* This means means we had not verified the
533 subroutine earlier, so this is the first jsr to
534 call it. In this case, the type_map of the return
535 address is just the current type_map - and that
536 is handled by the following PUSH_PENDING. */
540 /* In this case we have to do a merge. But first
541 restore the type_map for unused slots to those
542 that were in effect at the jsr. */
543 for (index
= size
; --index
>= 0; )
545 type_map
[index
] = TREE_VEC_ELT (ret_map
, index
);
546 if (type_map
[index
] == TYPE_UNUSED
)
548 = TREE_VEC_ELT (return_state
, index
);
551 PUSH_PENDING (return_label
);
556 if (PC
== INVALID_PC
)
558 label
= pending_blocks
;
559 if (label
== NULL_TREE
)
560 break; /* We're done! */
561 pending_blocks
= LABEL_PENDING_CHAIN (label
);
562 LABEL_CHANGED (label
) = 0;
564 if (LABEL_IN_SUBR (label
))
565 current_subr
= LABEL_SUBR_START (label
);
567 current_subr
= NULL_TREE
;
569 /* Restore type_map and stack_pointer from
570 LABEL_TYPE_STATE (label), and continue
571 compiling from there. */
572 load_type_state (label
);
573 PC
= LABEL_PC (label
);
575 else if (PC
>= length
)
576 VERIFICATION_ERROR ("falling through end of method");
578 /* fprintf (stderr, "** %d\n", PC); */
582 if (!(instruction_bits
[PC
] & BCODE_INSTRUCTION_START
) && ! wide
)
583 VERIFICATION_ERROR ("PC not at instruction start");
585 instruction_bits
[PC
] |= BCODE_VERIFIED
;
587 eh_ranges
= find_handler (oldpc
);
589 op_code
= byte_ops
[PC
++];
592 int is_static
, is_putting
;
595 case OPCODE_iconst_m1
:
596 case OPCODE_iconst_0
: case OPCODE_iconst_1
: case OPCODE_iconst_2
:
597 case OPCODE_iconst_3
: case OPCODE_iconst_4
: case OPCODE_iconst_5
:
598 i
= op_code
- OPCODE_iconst_0
;
601 if (byte_ops
[PC
] == OPCODE_newarray
602 || byte_ops
[PC
] == OPCODE_anewarray
)
604 PUSH_TYPE (int_type_node
); break;
605 case OPCODE_lconst_0
: case OPCODE_lconst_1
:
606 PUSH_TYPE (long_type_node
); break;
607 case OPCODE_fconst_0
: case OPCODE_fconst_1
: case OPCODE_fconst_2
:
608 PUSH_TYPE (float_type_node
); break;
609 case OPCODE_dconst_0
: case OPCODE_dconst_1
:
610 PUSH_TYPE (double_type_node
); break;
617 case OPCODE_iload
: type
= int_type_node
; goto general_load
;
618 case OPCODE_lload
: type
= long_type_node
; goto general_load
;
619 case OPCODE_fload
: type
= float_type_node
; goto general_load
;
620 case OPCODE_dload
: type
= double_type_node
; goto general_load
;
621 case OPCODE_aload
: type
= ptr_type_node
; goto general_load
;
623 index
= wide
? IMMEDIATE_u2
: IMMEDIATE_u1
;
626 case OPCODE_iload_0
: type
= int_type_node
; index
= 0; goto load
;
627 case OPCODE_iload_1
: type
= int_type_node
; index
= 1; goto load
;
628 case OPCODE_iload_2
: type
= int_type_node
; index
= 2; goto load
;
629 case OPCODE_iload_3
: type
= int_type_node
; index
= 3; goto load
;
630 case OPCODE_lload_0
: type
= long_type_node
; index
= 0; goto load
;
631 case OPCODE_lload_1
: type
= long_type_node
; index
= 1; goto load
;
632 case OPCODE_lload_2
: type
= long_type_node
; index
= 2; goto load
;
633 case OPCODE_lload_3
: type
= long_type_node
; index
= 3; goto load
;
634 case OPCODE_fload_0
: type
= float_type_node
; index
= 0; goto load
;
635 case OPCODE_fload_1
: type
= float_type_node
; index
= 1; goto load
;
636 case OPCODE_fload_2
: type
= float_type_node
; index
= 2; goto load
;
637 case OPCODE_fload_3
: type
= float_type_node
; index
= 3; goto load
;
638 case OPCODE_dload_0
: type
= double_type_node
; index
= 0; goto load
;
639 case OPCODE_dload_1
: type
= double_type_node
; index
= 1; goto load
;
640 case OPCODE_dload_2
: type
= double_type_node
; index
= 2; goto load
;
641 case OPCODE_dload_3
: type
= double_type_node
; index
= 3; goto load
;
642 case OPCODE_aload_0
: type
= ptr_type_node
; index
= 0; goto load
;
643 case OPCODE_aload_1
: type
= ptr_type_node
; index
= 1; goto load
;
644 case OPCODE_aload_2
: type
= ptr_type_node
; index
= 2; goto load
;
645 case OPCODE_aload_3
: type
= ptr_type_node
; index
= 3; goto load
;
648 || (index
+ TYPE_IS_WIDE (type
)
649 >= DECL_MAX_LOCALS (current_function_decl
)))
650 VERIFICATION_ERROR_WITH_INDEX
651 ("invalid local variable index %d in load");
652 tmp
= type_map
[index
];
653 if (tmp
== TYPE_UNKNOWN
)
654 VERIFICATION_ERROR_WITH_INDEX
655 ("loading local variable %d which has unknown type");
656 else if (tmp
== TYPE_SECOND
657 || (TYPE_IS_WIDE (type
)
658 && type_map
[index
+1] != void_type_node
)
659 || (type
== ptr_type_node
660 ? TREE_CODE (tmp
) != POINTER_TYPE
661 : type
== int_type_node
662 ? (! INTEGRAL_TYPE_P (tmp
) || TYPE_PRECISION (tmp
) > 32)
664 VERIFICATION_ERROR_WITH_INDEX
665 ("loading local variable %d which has invalid type");
668 case OPCODE_istore
: type
= int_type_node
; goto general_store
;
669 case OPCODE_lstore
: type
= long_type_node
; goto general_store
;
670 case OPCODE_fstore
: type
= float_type_node
; goto general_store
;
671 case OPCODE_dstore
: type
= double_type_node
; goto general_store
;
672 case OPCODE_astore
: type
= object_ptr_type_node
; goto general_store
;
674 index
= wide
? IMMEDIATE_u2
: IMMEDIATE_u1
;
677 case OPCODE_istore_0
: type
= int_type_node
; index
= 0; goto store
;
678 case OPCODE_istore_1
: type
= int_type_node
; index
= 1; goto store
;
679 case OPCODE_istore_2
: type
= int_type_node
; index
= 2; goto store
;
680 case OPCODE_istore_3
: type
= int_type_node
; index
= 3; goto store
;
681 case OPCODE_lstore_0
: type
= long_type_node
; index
=0; goto store
;
682 case OPCODE_lstore_1
: type
= long_type_node
; index
=1; goto store
;
683 case OPCODE_lstore_2
: type
= long_type_node
; index
=2; goto store
;
684 case OPCODE_lstore_3
: type
= long_type_node
; index
=3; goto store
;
685 case OPCODE_fstore_0
: type
=float_type_node
; index
=0; goto store
;
686 case OPCODE_fstore_1
: type
=float_type_node
; index
=1; goto store
;
687 case OPCODE_fstore_2
: type
=float_type_node
; index
=2; goto store
;
688 case OPCODE_fstore_3
: type
=float_type_node
; index
=3; goto store
;
689 case OPCODE_dstore_0
: type
=double_type_node
; index
=0; goto store
;
690 case OPCODE_dstore_1
: type
=double_type_node
; index
=1; goto store
;
691 case OPCODE_dstore_2
: type
=double_type_node
; index
=2; goto store
;
692 case OPCODE_dstore_3
: type
=double_type_node
; index
=3; goto store
;
693 case OPCODE_astore_0
: type
= ptr_type_node
; index
= 0; goto store
;
694 case OPCODE_astore_1
: type
= ptr_type_node
; index
= 1; goto store
;
695 case OPCODE_astore_2
: type
= ptr_type_node
; index
= 2; goto store
;
696 case OPCODE_astore_3
: type
= ptr_type_node
; index
= 3; goto store
;
699 || (index
+ TYPE_IS_WIDE (type
)
700 >= DECL_MAX_LOCALS (current_function_decl
)))
702 VERIFICATION_ERROR_WITH_INDEX
703 ("invalid local variable index %d in store");
706 POP_TYPE_CONV (type
, type
, NULL
);
707 type_map
[index
] = type
;
709 /* If local variable changed, we need to reconsider eh handlers. */
710 prev_eh_ranges
= NULL_EH_RANGE
;
712 /* Allocate decl and rtx for this variable now, so if we're not
713 optimizing, we get a temporary that survives the whole method. */
714 find_local_variable (index
, type
, oldpc
);
716 if (TYPE_IS_WIDE (type
))
717 type_map
[index
+1] = TYPE_SECOND
;
718 /* ... fall through to note_used ... */
720 /* For store or load, note that local variable INDEX is used.
721 This is needed to verify try-finally sub-routines. */
724 tree vec
= LABEL_RETURN_TYPE_STATE (current_subr
);
725 tree subr_vec
= LABEL_TYPE_STATE (current_subr
);
726 int len
= 1 + TYPE_IS_WIDE (type
);
729 if (TREE_VEC_ELT (vec
, index
) == TYPE_UNUSED
)
730 TREE_VEC_ELT (vec
, index
) = TREE_VEC_ELT (subr_vec
, index
);
745 type
= int_type_node
; goto binop
;
750 type
= int_type_node
; goto unop
;
759 type
= long_type_node
; goto binop
;
761 type
= long_type_node
; goto unop
;
762 case OPCODE_fadd
: case OPCODE_fsub
:
763 case OPCODE_fmul
: case OPCODE_fdiv
: case OPCODE_frem
:
764 type
= float_type_node
; goto binop
;
766 type
= float_type_node
; goto unop
;
767 case OPCODE_dadd
: case OPCODE_dsub
:
768 case OPCODE_dmul
: case OPCODE_ddiv
: case OPCODE_drem
:
769 type
= double_type_node
; goto binop
;
771 type
= double_type_node
; goto unop
;
784 pop_type (int_type_node
);
785 pop_type (long_type_node
);
786 PUSH_TYPE (long_type_node
);
789 index
= wide
? IMMEDIATE_u2
: IMMEDIATE_u1
;
792 if (index
< 0 || index
>= DECL_MAX_LOCALS (current_function_decl
))
793 VERIFICATION_ERROR ("invalid local variable index in iinc");
794 tmp
= type_map
[index
];
796 || ! INTEGRAL_TYPE_P (tmp
) || TYPE_PRECISION (tmp
) > 32)
797 VERIFICATION_ERROR ("invalid local variable type in iinc");
800 pop_type (int_type_node
); PUSH_TYPE (long_type_node
); break;
802 pop_type (int_type_node
); PUSH_TYPE (float_type_node
); break;
804 pop_type (int_type_node
); PUSH_TYPE (double_type_node
); break;
806 pop_type (long_type_node
); PUSH_TYPE (int_type_node
); break;
808 pop_type (long_type_node
); PUSH_TYPE (float_type_node
); break;
810 pop_type (long_type_node
); PUSH_TYPE (double_type_node
); break;
812 pop_type (float_type_node
); PUSH_TYPE (int_type_node
); break;
814 pop_type (float_type_node
); PUSH_TYPE (long_type_node
); break;
816 pop_type (float_type_node
); PUSH_TYPE (double_type_node
); break;
818 pop_type (double_type_node
); PUSH_TYPE (int_type_node
); break;
820 pop_type (double_type_node
); PUSH_TYPE (long_type_node
); break;
822 pop_type (double_type_node
); PUSH_TYPE (float_type_node
); break;
824 type
= long_type_node
; goto compare
;
827 type
= float_type_node
; goto compare
;
830 type
= double_type_node
; goto compare
;
832 pop_type (type
); pop_type (type
);
833 PUSH_TYPE (int_type_node
); break;
840 pop_type (int_type_node
); goto cond
;
842 case OPCODE_ifnonnull
:
843 pop_type (ptr_type_node
); goto cond
;
844 case OPCODE_if_icmpeq
:
845 case OPCODE_if_icmpne
:
846 case OPCODE_if_icmplt
:
847 case OPCODE_if_icmpge
:
848 case OPCODE_if_icmpgt
:
849 case OPCODE_if_icmple
:
850 pop_type (int_type_node
); pop_type (int_type_node
); goto cond
;
851 case OPCODE_if_acmpeq
:
852 case OPCODE_if_acmpne
:
853 pop_type (object_ptr_type_node
); pop_type (object_ptr_type_node
);
856 PUSH_PENDING (lookup_label (oldpc
+ IMMEDIATE_s2
));
859 PUSH_PENDING (lookup_label (oldpc
+ IMMEDIATE_s2
));
863 switch (byte_ops
[PC
])
865 case OPCODE_iload
: case OPCODE_lload
:
866 case OPCODE_fload
: case OPCODE_dload
: case OPCODE_aload
:
867 case OPCODE_istore
: case OPCODE_lstore
:
868 case OPCODE_fstore
: case OPCODE_dstore
: case OPCODE_astore
:
874 VERIFICATION_ERROR ("invalid use of wide instruction");
877 case OPCODE_return
: type
= void_type_node
; goto ret
;
879 if ((TREE_CODE (return_type
) == BOOLEAN_TYPE
880 || TREE_CODE (return_type
) == CHAR_TYPE
881 || TREE_CODE (return_type
) == INTEGER_TYPE
)
882 && TYPE_PRECISION (return_type
) <= 32)
887 case OPCODE_lreturn
: type
= long_type_node
; goto ret
;
888 case OPCODE_freturn
: type
= float_type_node
; goto ret
;
889 case OPCODE_dreturn
: type
= double_type_node
; goto ret
;
891 if (TREE_CODE (return_type
) == POINTER_TYPE
)
897 if (type
!= return_type
)
898 VERIFICATION_ERROR ("incorrect ?return opcode");
899 if (type
!= void_type_node
)
900 POP_TYPE(type
, "return value has wrong type");
903 case OPCODE_getstatic
: is_putting
= 0; is_static
= 1; goto field
;
904 case OPCODE_putstatic
: is_putting
= 1; is_static
= 1; goto field
;
905 case OPCODE_getfield
: is_putting
= 0; is_static
= 0; goto field
;
906 case OPCODE_putfield
: is_putting
= 1; is_static
= 0; goto field
;
909 tree field_signature
, field_type
;
910 index
= IMMEDIATE_u2
;
911 if (index
<= 0 || index
>= JPOOL_SIZE(current_jcf
))
912 VERIFICATION_ERROR_WITH_INDEX ("bad constant pool index %d");
913 if (JPOOL_TAG (current_jcf
, index
) != CONSTANT_Fieldref
)
915 ("field instruction does not reference a Fieldref");
916 field_signature
= COMPONENT_REF_SIGNATURE (¤t_jcf
->cpool
, index
);
917 field_type
= get_type_from_signature (field_signature
);
919 POP_TYPE (field_type
, "incorrect type for field");
922 int clindex
= COMPONENT_REF_CLASS_INDEX (¤t_jcf
->cpool
,
924 tree self_type
= get_class_constant (current_jcf
, clindex
);
925 /* Defer actual checking until next pass. */
926 POP_TYPE(self_type
, "incorrect type for field reference");
929 PUSH_TYPE (field_type
);
933 PUSH_TYPE (get_class_constant (jcf
, IMMEDIATE_u2
));
935 case OPCODE_dup
: wide
= 1; index
= 0; goto dup
;
936 case OPCODE_dup_x1
: wide
= 1; index
= 1; goto dup
;
937 case OPCODE_dup_x2
: wide
= 1; index
= 2; goto dup
;
938 case OPCODE_dup2
: wide
= 2; index
= 0; goto dup
;
939 case OPCODE_dup2_x1
: wide
= 2; index
= 1; goto dup
;
940 case OPCODE_dup2_x2
: wide
= 2; index
= 2; goto dup
;
942 if (wide
+ index
> stack_pointer
)
943 VERIFICATION_ERROR ("stack underflow - dup* operation");
944 type_stack_dup (wide
, index
);
947 case OPCODE_pop
: index
= 1; goto pop
;
948 case OPCODE_pop2
: index
= 2; goto pop
;
950 if (stack_pointer
< index
)
951 VERIFICATION_ERROR ("stack underflow");
952 stack_pointer
-= index
;
955 if (stack_pointer
< 2)
956 VERIFICATION_ERROR ("stack underflow (in swap)");
959 tree type1
= stack_type_map
[stack_pointer
- 1];
960 tree type2
= stack_type_map
[stack_pointer
- 2];
961 if (type1
== void_type_node
|| type2
== void_type_node
)
962 VERIFICATION_ERROR ("verifier (swap): double or long value");
963 stack_type_map
[stack_pointer
- 2] = type1
;
964 stack_type_map
[stack_pointer
- 1] = type2
;
967 case OPCODE_ldc
: index
= IMMEDIATE_u1
; goto ldc
;
970 index
= IMMEDIATE_u2
; goto ldc
;
972 if (index
<= 0 || index
>= JPOOL_SIZE(current_jcf
))
973 VERIFICATION_ERROR_WITH_INDEX ("bad constant pool index %d in ldc");
975 switch (JPOOL_TAG (current_jcf
, index
) & ~CONSTANT_ResolvedFlag
)
977 case CONSTANT_Integer
: type
= int_type_node
; goto check_ldc
;
978 case CONSTANT_Float
: type
= float_type_node
; goto check_ldc
;
979 case CONSTANT_String
: type
= string_type_node
; goto check_ldc
;
980 case CONSTANT_Long
: type
= long_type_node
; goto check_ldc
;
981 case CONSTANT_Double
: type
= double_type_node
; goto check_ldc
;
983 if (TYPE_IS_WIDE (type
) == (op_code
== OPCODE_ldc2_w
))
985 /* ... else fall through ... */
987 VERIFICATION_ERROR ("bad constant pool tag in ldc");
989 if (type
== int_type_node
)
991 i
= TREE_INT_CST_LOW (get_constant (current_jcf
, index
));
997 case OPCODE_invokevirtual
:
998 case OPCODE_invokespecial
:
999 case OPCODE_invokestatic
:
1000 case OPCODE_invokeinterface
:
1002 tree sig
, method_name
, method_type
, self_type
;
1003 int self_is_interface
, tag
;
1004 index
= IMMEDIATE_u2
;
1005 if (index
<= 0 || index
>= JPOOL_SIZE(current_jcf
))
1006 VERIFICATION_ERROR_WITH_INDEX
1007 ("bad constant pool index %d for invoke");
1008 tag
= JPOOL_TAG (current_jcf
, index
);
1009 if (op_code
== OPCODE_invokeinterface
)
1011 if (tag
!= CONSTANT_InterfaceMethodref
)
1013 ("invokeinterface does not reference an InterfaceMethodref");
1017 if (tag
!= CONSTANT_Methodref
)
1018 VERIFICATION_ERROR ("invoke does not reference a Methodref");
1020 sig
= COMPONENT_REF_SIGNATURE (¤t_jcf
->cpool
, index
);
1021 self_type
= get_class_constant
1022 (current_jcf
, COMPONENT_REF_CLASS_INDEX (¤t_jcf
->cpool
,
1024 if (! CLASS_LOADED_P (self_type
))
1025 load_class (self_type
, 1);
1026 self_is_interface
= CLASS_INTERFACE (TYPE_NAME (self_type
));
1027 method_name
= COMPONENT_REF_NAME (¤t_jcf
->cpool
, index
);
1028 method_type
= parse_signature_string (IDENTIFIER_POINTER (sig
),
1029 IDENTIFIER_LENGTH (sig
));
1030 if (TREE_CODE (method_type
) != FUNCTION_TYPE
)
1031 VERIFICATION_ERROR ("bad method signature");
1032 pmessage
= pop_argument_types (TYPE_ARG_TYPES (method_type
));
1033 if (pmessage
!= NULL
)
1035 message
= "invalid argument type";
1036 goto pop_type_error
;
1039 /* Can't invoke <clinit> */
1040 if (ID_CLINIT_P (method_name
))
1041 VERIFICATION_ERROR ("invoke opcode can't invoke <clinit>");
1042 /* Apart invokespecial, can't invoke <init> */
1043 if (op_code
!= OPCODE_invokespecial
&& ID_INIT_P (method_name
))
1044 VERIFICATION_ERROR ("invoke opcode can't invoke <init>");
1046 if (op_code
!= OPCODE_invokestatic
)
1047 POP_TYPE (self_type
,
1048 "stack type not subclass of invoked method's class");
1052 case OPCODE_invokeinterface
:
1054 int nargs
= IMMEDIATE_u1
;
1055 int notZero
= IMMEDIATE_u1
;
1057 if (!nargs
|| notZero
)
1059 ("invalid argument number in invokeinterface");
1060 /* If we verify/resolve the constant pool, as we should,
1061 this test (and the one just following) are redundant. */
1062 if (! self_is_interface
)
1063 VERIFICATION_ERROR ("invokeinterface calls method not in interface");
1066 if (self_is_interface
)
1067 VERIFICATION_ERROR ("method in interface called");
1071 if (TREE_TYPE (method_type
) != void_type_node
)
1072 PUSH_TYPE (TREE_TYPE (method_type
));
1076 case OPCODE_arraylength
:
1077 /* Type checking actually made during code generation */
1078 pop_type( ptr_type_node
);
1079 PUSH_TYPE( int_type_node
);
1082 /* Q&D verification *or* more checking done during code generation
1083 for byte/boolean/char/short, the value popped is a int coerced
1084 into the right type before being stored. */
1085 case OPCODE_iastore
: type
= int_type_node
; goto astore
;
1086 case OPCODE_lastore
: type
= long_type_node
; goto astore
;
1087 case OPCODE_fastore
: type
= float_type_node
; goto astore
;
1088 case OPCODE_dastore
: type
= double_type_node
; goto astore
;
1089 case OPCODE_aastore
: type
= ptr_type_node
; goto astore
;
1090 case OPCODE_bastore
: type
= int_type_node
; goto astore
;
1091 case OPCODE_castore
: type
= int_type_node
; goto astore
;
1092 case OPCODE_sastore
: type
= int_type_node
; goto astore
;
1094 /* FIXME - need better verification here */
1095 pop_type (type
); /* new value */
1096 pop_type (int_type_node
); /* index */
1097 pop_type (ptr_type_node
); /* array */
1100 /* Q&D verification *or* more checking done during code generation
1101 for byte/boolean/char/short, the value pushed is a int. */
1102 case OPCODE_iaload
: type
= int_type_node
; goto aload
;
1103 case OPCODE_laload
: type
= long_type_node
; goto aload
;
1104 case OPCODE_faload
: type
= float_type_node
; goto aload
;
1105 case OPCODE_daload
: type
= double_type_node
; goto aload
;
1106 case OPCODE_aaload
: type
= ptr_type_node
; goto aload
;
1107 case OPCODE_baload
: type
= promote_type (byte_type_node
); goto aload
;
1108 case OPCODE_caload
: type
= promote_type (char_type_node
); goto aload
;
1109 case OPCODE_saload
: type
= promote_type (short_type_node
); goto aload
;
1111 pop_type (int_type_node
);
1112 tmp
= pop_type (ptr_type_node
);
1113 if (is_array_type_p (tmp
))
1114 type
= TYPE_ARRAY_ELEMENT (TREE_TYPE (tmp
));
1115 else if (tmp
!= TYPE_NULL
)
1116 VERIFICATION_ERROR ("array load from non-array type");
1120 case OPCODE_anewarray
:
1121 type
= get_class_constant (current_jcf
, IMMEDIATE_u2
);
1122 type
= promote_type (type
);
1125 case OPCODE_newarray
:
1126 index
= IMMEDIATE_u1
;
1127 type
= decode_newarray_type (index
);
1128 if (type
== NULL_TREE
)
1129 VERIFICATION_ERROR ("invalid type code in newarray opcode");
1133 if (int_value
>= 0 && prevpc
>= 0)
1135 /* If previous instruction pushed int constant,
1136 we want to use it. */
1137 switch (byte_ops
[prevpc
])
1139 case OPCODE_iconst_0
: case OPCODE_iconst_1
:
1140 case OPCODE_iconst_2
: case OPCODE_iconst_3
:
1141 case OPCODE_iconst_4
: case OPCODE_iconst_5
:
1142 case OPCODE_bipush
: case OPCODE_sipush
:
1143 case OPCODE_ldc
: case OPCODE_ldc_w
:
1151 type
= build_java_array_type (type
, int_value
);
1152 pop_type (int_type_node
);
1156 case OPCODE_multianewarray
:
1159 index
= IMMEDIATE_u2
;
1160 ndim
= IMMEDIATE_u1
;
1163 VERIFICATION_ERROR ("number of dimension lower that 1 in multianewarray" );
1165 for( i
= 0; i
< ndim
; i
++ )
1166 pop_type (int_type_node
);
1167 PUSH_TYPE (get_class_constant (current_jcf
, index
));
1171 case OPCODE_aconst_null
:
1172 PUSH_TYPE (ptr_type_node
);
1176 /* FIXME: athrow also empties the stack. */
1177 POP_TYPE (throwable_type_node
, "missing throwable at athrow" );
1181 case OPCODE_checkcast
:
1182 POP_TYPE (object_ptr_type_node
,
1183 "checkcast operand is not a pointer");
1184 type
= get_class_constant (current_jcf
, IMMEDIATE_u2
);
1187 case OPCODE_instanceof
:
1188 POP_TYPE (object_ptr_type_node
,
1189 "instanceof operand is not a pointer");
1190 get_class_constant (current_jcf
, IMMEDIATE_u2
);
1191 PUSH_TYPE (int_type_node
);
1194 case OPCODE_tableswitch
:
1198 POP_TYPE (int_type_node
, "missing int for tableswitch");
1202 VERIFICATION_ERROR ("bad alignment in tableswitch pad");
1204 PUSH_PENDING (lookup_label (oldpc
+IMMEDIATE_s4
));
1206 high
= IMMEDIATE_s4
;
1209 VERIFICATION_ERROR ("unsorted low/high value in tableswitch");
1211 while (low
++ <= high
)
1212 PUSH_PENDING (lookup_label (oldpc
+ IMMEDIATE_s4
));
1217 case OPCODE_lookupswitch
:
1219 jint npairs
, last
= 0, not_registered
= 1;
1221 POP_TYPE (int_type_node
, "missing int for lookupswitch");
1225 VERIFICATION_ERROR ("bad alignment in lookupswitch pad");
1228 PUSH_PENDING (lookup_label (oldpc
+IMMEDIATE_s4
));
1229 npairs
= IMMEDIATE_s4
;
1232 VERIFICATION_ERROR ("invalid number of targets in lookupswitch");
1236 int match
= IMMEDIATE_s4
;
1239 else if (last
>= match
)
1240 VERIFICATION_ERROR ("unsorted match value in lookupswitch");
1243 PUSH_PENDING (lookup_label (oldpc
+ IMMEDIATE_s4
));
1249 case OPCODE_monitorenter
:
1251 case OPCODE_monitorexit
:
1252 pop_type (ptr_type_node
);
1256 PUSH_PENDING (lookup_label (oldpc
+ IMMEDIATE_s4
));
1262 tree target
= lookup_label (oldpc
+ IMMEDIATE_s2
);
1263 tree return_label
= lookup_label (PC
);
1264 PUSH_TYPE (return_address_type_node
);
1265 /* The return label chain will be null if this is the first
1266 time we've seen this jsr target. */
1267 if (LABEL_RETURN_LABEL (target
) == NULL_TREE
)
1269 tree return_type_map
;
1270 int nlocals
= DECL_MAX_LOCALS (current_function_decl
);
1271 index
= nlocals
+ DECL_MAX_STACK (current_function_decl
);
1272 return_type_map
= make_tree_vec (index
);
1273 while (index
> nlocals
)
1274 TREE_VEC_ELT (return_type_map
, --index
) = TYPE_UNKNOWN
;
1276 TREE_VEC_ELT (return_type_map
, --index
) = TYPE_UNUSED
;
1277 LABEL_RETURN_LABEL (target
)
1278 = build_decl (LABEL_DECL
, NULL_TREE
, TREE_TYPE (target
));
1279 LABEL_PC (LABEL_RETURN_LABEL (target
)) = -1;
1280 LABEL_RETURN_TYPE_STATE (target
) = return_type_map
;
1281 LABEL_IS_SUBR_START (target
) = 1;
1282 LABEL_IN_SUBR (target
) = 1;
1283 LABEL_SUBR_START (target
) = target
;
1284 LABEL_SUBR_CONTEXT (target
) = current_subr
;
1286 else if (! LABEL_IS_SUBR_START (target
)
1287 || LABEL_SUBR_CONTEXT (target
) != current_subr
)
1288 VERIFICATION_ERROR ("label part of different subroutines");
1290 i
= merge_type_state (target
);
1294 VERIFICATION_ERROR ("types could not be merged at jsr");
1295 push_pending_label (target
);
1297 current_subr
= target
;
1299 /* Chain return_pc onto LABEL_RETURN_LABELS (target) if needed. */
1300 if (! value_member (return_label
, LABEL_RETURN_LABELS (target
)))
1302 LABEL_RETURN_LABELS (target
)
1303 = tree_cons (NULL_TREE
, return_label
,
1304 LABEL_RETURN_LABELS (target
));
1307 if (LABEL_VERIFIED (target
))
1309 tree return_map
= LABEL_RETURN_TYPE_STATE (target
);
1310 int len
= TREE_VEC_LENGTH (return_map
);
1311 stack_pointer
= len
- DECL_MAX_LOCALS (current_function_decl
);
1314 if (TREE_VEC_ELT (return_map
, len
) != TYPE_UNUSED
)
1315 type_map
[len
] = TREE_VEC_ELT (return_map
, len
);
1317 current_subr
= LABEL_SUBR_CONTEXT (target
);
1318 if (RETURN_MAP_ADJUSTED (return_map
))
1319 PUSH_PENDING (return_label
);
1326 if (current_subr
== NULL
)
1327 VERIFICATION_ERROR ("ret instruction not in a jsr subroutine");
1330 tree ret_map
= LABEL_RETURN_TYPE_STATE (current_subr
);
1331 int size
= DECL_MAX_LOCALS(current_function_decl
)+stack_pointer
;
1332 index
= wide
? IMMEDIATE_u2
: IMMEDIATE_u1
;
1335 if (index
< 0 || index
>= DECL_MAX_LOCALS (current_function_decl
)
1336 || type_map
[index
] != TYPE_RETURN_ADDR
)
1337 VERIFICATION_ERROR ("invalid ret index");
1339 /* The next chunk of code is similar to an inlined version of
1340 * merge_type_state (LABEL_RETURN_LABEL (current_subr)).
1341 * The main differences are that LABEL_RETURN_LABEL is
1342 * pre-allocated by the jsr (but we don't know the size then);
1343 * and that we have to handle TYPE_UNUSED. */
1345 if (! RETURN_MAP_ADJUSTED (ret_map
))
1346 { /* First return from this subroutine - fix stack pointer. */
1347 TREE_VEC_LENGTH (ret_map
) = size
;
1348 for (index
= size
; --index
>= 0; )
1350 if (TREE_VEC_ELT (ret_map
, index
) != TYPE_UNUSED
)
1351 TREE_VEC_ELT (ret_map
, index
) = type_map
[index
];
1353 RETURN_MAP_ADJUSTED (ret_map
) = 1;
1357 if (TREE_VEC_LENGTH (ret_map
) != size
)
1358 VERIFICATION_ERROR ("inconsistent stack size on ret");
1359 for (index
= 0; index
< size
; index
++)
1361 tree type
= TREE_VEC_ELT (ret_map
, index
);
1362 if (type
!= TYPE_UNUSED
)
1364 type
= merge_types (type
, type_map
[index
]);
1365 TREE_VEC_ELT (ret_map
, index
) = type
;
1366 if (type
== TYPE_UNKNOWN
)
1368 if (index
>= size
- stack_pointer
)
1370 ("inconsistent types on ret from jsr");
1372 else if (TYPE_IS_WIDE (type
))
1384 error ("unknown opcode %d@pc=%d during verification", op_code
, PC
-1);
1390 /* The following test is true if we have entered or exited an exception
1391 handler range *or* we have done a store to a local variable.
1392 In either case we need to consider any exception handlers that
1393 might "follow" this instruction. */
1395 if (eh_ranges
!= prev_eh_ranges
)
1397 int save_stack_pointer
= stack_pointer
;
1398 int index
= DECL_MAX_LOCALS (current_function_decl
);
1399 tree save_type
= type_map
[index
];
1400 tree save_current_subr
= current_subr
;
1401 struct eh_range
*ranges
= find_handler (oldpc
);
1403 for (; ranges
!= NULL_EH_RANGE
; ranges
= ranges
->outer
)
1405 tree chain
= ranges
->handlers
;
1407 /* We need to determine if the handler is part of current_subr.
1408 The are two cases: (1) The exception catch range
1409 is entirely within current_subr. In that case the handler
1410 is also part of current_subr.
1411 (2) Some of the catch range is not in current_subr.
1412 In that case, the handler is *not* part of current_subr.
1414 Figuring out which is the case is not necessarily obvious,
1415 in the presence of clever code generators (and obfuscators).
1416 We make a simplifying assumption that in case (2) we
1417 have that the current_subr is entirely within the catch range.
1418 In that case we can assume if that if a caller (the jsr) of
1419 a subroutine is within the catch range, then the handler is
1420 *not* part of the subroutine, and vice versa. */
1422 current_subr
= save_current_subr
;
1423 for ( ; current_subr
!= NULL_TREE
;
1424 current_subr
= LABEL_SUBR_CONTEXT (current_subr
))
1426 tree return_labels
= LABEL_RETURN_LABELS (current_subr
);
1427 /* There could be multiple return_labels, but
1428 we only need to check one. */
1429 int return_pc
= LABEL_PC (TREE_VALUE (return_labels
));
1430 if (return_pc
<= ranges
->start_pc
1431 || return_pc
> ranges
->end_pc
)
1435 for ( ; chain
!= NULL_TREE
; chain
= TREE_CHAIN (chain
))
1437 tree handler
= TREE_VALUE (chain
);
1438 tree type
= TREE_PURPOSE (chain
);
1439 if (type
== NULL_TREE
) /* a finally handler */
1440 type
= throwable_type_node
;
1441 type_map
[index
] = promote_type (type
);
1443 PUSH_PENDING (handler
);
1446 stack_pointer
= save_stack_pointer
;
1447 current_subr
= save_current_subr
;
1448 type_map
[index
] = save_type
;
1449 prev_eh_ranges
= eh_ranges
;
1454 error ("verification error at PC=%d", oldpc
);
1455 if (message
!= NULL
)
1456 error ("%s", message
);
1457 error ("%s", pmessage
);
1461 message
= "stack overflow";
1464 message
= "program counter out of range";
1467 error ("verification error at PC=%d", oldpc
);
1468 error (message
, index
);
1471 error ("verification error at PC=%d", oldpc
);
1472 error ("%s", message
);