* tree.c (walk_tree): Don't recurse into DECL_INITIAL or DECL_SIZE
[official-gcc.git] / gcc / java / verify.c
blobd17a184bf400d87a6f10aa951d99d4833846c638
1 /* Handle verification of bytecoded methods for the GNU compiler for
2 the Java(TM) language.
3 Copyright (C) 1997, 1998, 1999 Free Software Foundation, Inc.
5 This file is part of GNU CC.
7 GNU CC is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
10 any later version.
12 GNU CC is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GNU CC; see the file COPYING. If not, write to
19 the Free Software Foundation, 59 Temple Place - Suite 330,
20 Boston, MA 02111-1307, USA.
22 Java and all Java-based marks are trademarks or registered trademarks
23 of Sun Microsystems, Inc. in the United States and other countries.
24 The Free Software Foundation is independent of Sun Microsystems, Inc. */
26 #include "config.h"
27 #include "system.h"
28 #include "tree.h"
29 #include "java-tree.h"
30 #include "javaop.h"
31 #include "java-opcodes.h"
32 #include "jcf.h"
33 #include "java-except.h"
34 #include "toplev.h"
36 static void push_pending_label PROTO ((tree));
37 static tree merge_types PROTO ((tree, tree));
38 static const char *check_pending_block PROTO ((tree));
39 static void type_stack_dup PROTO ((int, int));
40 static int start_pc_cmp PROTO ((const PTR, const PTR));
42 extern int stack_pointer;
44 /* During verification, start of the current subroutine (jsr target). */
45 tree current_subr;
47 /* A list of pending blocks, chained using LABEL_PENDING_CHAIN.
48 A pending block is one that has LABEL_CHANGED set, which means
49 it requires (re-) verification. */
50 tree pending_blocks;
52 /* Append TARGET_LABEL to the pending_block stack unless already in it. */
54 static void
55 push_pending_label (target_label)
56 tree target_label;
58 if (! LABEL_CHANGED (target_label))
60 LABEL_PENDING_CHAIN (target_label) = pending_blocks;
61 pending_blocks = target_label;
62 LABEL_CHANGED (target_label) = 1;
66 /* Note that TARGET_LABEL is a possible successor instruction.
67 Merge the type state etc.
68 Return NULL on sucess, or an error message on failure. */
70 static const char *
71 check_pending_block (target_label)
72 tree target_label;
74 int changed = merge_type_state (target_label);
76 if (changed)
78 if (changed < 0)
79 return "types could not be merged";
80 push_pending_label (target_label);
83 if (current_subr == NULL)
85 if (LABEL_IN_SUBR (target_label))
86 return "might transfer control into subroutine";
88 else
90 if (LABEL_IN_SUBR (target_label))
92 if (LABEL_SUBR_START (target_label) != current_subr)
93 return "transfer out of subroutine";
95 else if (! LABEL_VERIFIED (target_label))
97 LABEL_IN_SUBR (target_label) = 1;
98 LABEL_SUBR_START (target_label) = current_subr;
100 else
101 return "transfer out of subroutine";
103 return NULL;
106 /* Return the "merged" types of TYPE1 and TYPE2.
107 If either is primitive, the other must match (after promotion to int).
108 For reference types, return the common super-class.
109 Return TYPE_UNKNOWN if the types cannot be merged. */
111 static tree
112 merge_types (type1, type2)
113 tree type1, type2;
115 if (type1 == type2)
116 return type1;
117 if (type1 == TYPE_UNKNOWN || type2 == TYPE_UNKNOWN
118 || type1 == TYPE_RETURN_ADDR || type2 == TYPE_RETURN_ADDR)
119 return TYPE_UNKNOWN;
120 if (TREE_CODE (type1) == POINTER_TYPE && TREE_CODE (type2) == POINTER_TYPE)
122 int depth1, depth2;
123 tree tt1, tt2;
124 /* ptr_type_node is only used for a null reference,
125 which is compatible with any reference type. */
126 if (type1 == ptr_type_node || type2 == object_ptr_type_node)
127 return type2;
128 if (type2 == ptr_type_node || type1 == object_ptr_type_node)
129 return type1;
131 tt1 = HANDLE_TO_CLASS_TYPE (TREE_TYPE (type1));
132 tt2 = HANDLE_TO_CLASS_TYPE (TREE_TYPE (type2));
134 if (TYPE_ARRAY_P (tt1) || TYPE_ARRAY_P (tt2))
136 if (TYPE_ARRAY_P (tt1) == TYPE_ARRAY_P (tt2))
138 tree el_type1 = TYPE_ARRAY_ELEMENT (tt1);
139 tree el_type2 = TYPE_ARRAY_ELEMENT (tt2);
140 tree el_type = NULL_TREE;
141 if (el_type1 == el_type2)
142 el_type = el_type1;
143 else if (TREE_CODE (el_type1) == POINTER_TYPE
144 && TREE_CODE (el_type2) == POINTER_TYPE)
145 el_type = merge_types (el_type1, el_type2);
146 if (el_type != NULL_TREE)
148 HOST_WIDE_INT len1 = java_array_type_length (tt1);
149 HOST_WIDE_INT len2 = java_array_type_length (tt2);
150 if (len1 != len2)
151 len1 = -1;
152 else if (el_type1 == el_type2)
153 return type1;
154 return promote_type (build_java_array_type (el_type, len1));
157 return object_ptr_type_node;
160 if (CLASS_INTERFACE (TYPE_NAME (tt1)))
162 if (CLASS_INTERFACE (TYPE_NAME (tt2)))
164 /* This is a kludge, but matches what Sun's verifier does.
165 It can be tricked, but is safe as long as type errors
166 (i.e. interface method calls) are caught at run-time. */
167 return object_ptr_type_node;
169 else
171 if (can_widen_reference_to (tt2, tt1))
172 return type1;
173 else
174 return TYPE_UNKNOWN;
177 else if (CLASS_INTERFACE (TYPE_NAME (tt2)))
179 if (can_widen_reference_to (tt1, tt2))
180 return type2;
181 else
182 return TYPE_UNKNOWN;
185 type1 = tt1;
186 type2 = tt2;
188 depth1 = class_depth (type1);
189 depth2 = class_depth (type2);
190 for ( ; depth1 > depth2; depth1--)
191 type1 = TYPE_BINFO_BASETYPE (type1, 0);
192 for ( ; depth2 > depth1; depth2--)
193 type2 = TYPE_BINFO_BASETYPE (type2, 0);
194 while (type1 != type2)
196 type1 = TYPE_BINFO_BASETYPE (type1, 0);
197 type2 = TYPE_BINFO_BASETYPE (type2, 0);
199 return promote_type (type1);
201 if (INTEGRAL_TYPE_P (type1) && INTEGRAL_TYPE_P (type2)
202 && TYPE_PRECISION (type1) <= 32 && TYPE_PRECISION (type2) <= 32)
203 return int_type_node;
204 return TYPE_UNKNOWN;
207 /* Merge the current type state with that at LABEL.
208 Return -1 the the states are incompatible (i.e. on error),
209 0 if there was no change, and 1 if there was a change. */
212 merge_type_state (label)
213 tree label;
215 int nlocals = DECL_MAX_LOCALS(current_function_decl);
216 int cur_length = stack_pointer + nlocals;
217 tree vec = LABEL_TYPE_STATE (label);
218 tree return_map;
219 if (vec == NULL_TREE || !LABEL_VERIFIED (label))
221 if (!vec)
223 vec = make_tree_vec (cur_length);
224 LABEL_TYPE_STATE (label) = vec;
226 while (--cur_length >= 0)
227 TREE_VEC_ELT (vec, cur_length) = type_map [cur_length];
228 return 1;
230 else
232 int i;
233 int changed = 0;
234 if (LABEL_IS_SUBR_START (label) && LABEL_VERIFIED (label)
235 && current_subr != label)
236 return_map = LABEL_RETURN_TYPE_STATE (label);
237 else
238 return_map = NULL_TREE;
239 if (TREE_VEC_LENGTH (vec) != cur_length)
241 return -1;
243 for (i = 0; i < cur_length; i++)
245 tree old_type = TREE_VEC_ELT (vec, i);
246 tree new_type = merge_types (old_type, type_map [i]);
247 if (TREE_VEC_ELT (vec, i) != new_type)
249 /* If there has been a change, note that since we must re-verify.
250 However, if the label is the start of a subroutine,
251 we don't care about local variables that are neither
252 set nor used in the sub-routine. */
253 if (return_map == NULL_TREE || i >= nlocals
254 || TREE_VEC_ELT (return_map, i) != TYPE_UNUSED
255 || (TYPE_IS_WIDE (new_type)
256 && TREE_VEC_ELT (return_map, i+1) != TYPE_UNUSED))
257 changed = 1;
259 TREE_VEC_ELT (vec, i) = new_type;
260 if (new_type == TYPE_UNKNOWN)
262 if (i >= nlocals)
263 return -1;
265 else if (TYPE_IS_WIDE (new_type))
266 i++;
268 return changed;
272 /* Handle dup-like operations. */
274 static void
275 type_stack_dup (size, offset)
276 int size, offset;
278 tree type[4];
279 int index;
280 if (size + offset > stack_pointer)
281 error ("stack underflow - dup* operation");
282 for (index = 0; index < size + offset; index++)
284 type[index] = stack_type_map[stack_pointer - 1];
285 if (type[index] == void_type_node)
287 index++;
288 type[index] = stack_type_map[stack_pointer - 2];
289 if (! TYPE_IS_WIDE (type[index]))
290 fatal ("internal error - dup operation");
291 if (index == size || index == size + offset)
292 fatal ("dup operation splits 64-bit number");
294 pop_type (type[index]);
296 for (index = size; --index >= 0; )
298 if (type[index] != void_type_node)
299 push_type (type[index]);
302 for (index = size + offset; --index >= 0; )
304 if (type[index] != void_type_node)
305 push_type (type[index]);
309 /* This keeps track of a start PC and corresponding initial index. */
310 struct pc_index
312 int start_pc;
313 int index;
316 /* A helper that is used when sorting exception ranges. */
317 static int
318 start_pc_cmp (xp, yp)
319 const PTR xp;
320 const PTR yp;
322 const struct pc_index *x = (const struct pc_index *) xp;
323 const struct pc_index *y = (const struct pc_index *) yp;
324 return x->start_pc - y->start_pc;
327 /* This causes the next iteration to ignore the next instruction
328 and look for some other unhandled instruction. */
329 #define INVALIDATE_PC (prevpc = -1, oldpc = PC, PC = INVALID_PC)
330 #define INVALID_PC (-1)
332 #define VERIFICATION_ERROR(MESSAGE) \
333 do { message = MESSAGE; goto verify_error; } while (0)
335 #define PUSH_PENDING(LABEL) \
336 do { if ((message = check_pending_block (LABEL)) != NULL) \
337 goto verify_error; } while (0)
339 #ifdef __GNUC__
340 #define CHECK_PC_IN_RANGE(PC) ({if (PC < 0 || PC > length) goto bad_pc; 1;})
341 #else
342 #define CHECK_PC_IN_RANGE(PC) (PC < 0 || PC > length ? \
343 (fatal("Bad byte codes.\n"), 0) : 1)
344 #endif
346 #define BCODE byte_ops
348 /* Verify the bytecodes of the current method.
349 Return 1 on sucess, 0 on failure. */
351 verify_jvm_instructions (jcf, byte_ops, length)
352 JCF* jcf;
353 const unsigned char *byte_ops;
354 long length;
356 tree label;
357 int wide = 0;
358 int op_code;
359 int PC;
360 int oldpc = 0; /* PC of start of instruction. */
361 int prevpc = 0; /* If >= 0, PC of previous instruction. */
362 const char *message;
363 int i;
364 register unsigned char *p;
365 struct eh_range *prev_eh_ranges = NULL_EH_RANGE;
366 struct eh_range *eh_ranges;
367 tree return_type = TREE_TYPE (TREE_TYPE (current_function_decl));
368 struct pc_index *starts;
369 int eh_count;
371 jint int_value = -1;
373 pending_blocks = NULL_TREE;
375 /* Handle the exception table. */
376 method_init_exceptions ();
377 JCF_SEEK (jcf, DECL_CODE_OFFSET (current_function_decl) + length);
378 eh_count = JCF_readu2 (jcf);
380 /* We read the exception handlers in order of increasing start PC.
381 To do this we first read and sort the start PCs. */
382 starts = (struct pc_index *) xmalloc (eh_count * sizeof (struct pc_index));
383 for (i = 0; i < eh_count; ++i)
385 starts[i].start_pc = GET_u2 (jcf->read_ptr + 8 * i);
386 starts[i].index = i;
388 qsort (starts, eh_count, sizeof (struct pc_index), start_pc_cmp);
390 for (i = 0; i < eh_count; ++i)
392 int start_pc, end_pc, handler_pc, catch_type;
394 p = jcf->read_ptr + 8 * starts[i].index;
396 start_pc = GET_u2 (p);
397 end_pc = GET_u2 (p+2);
398 handler_pc = GET_u2 (p+4);
399 catch_type = GET_u2 (p+6);
401 if (start_pc < 0 || start_pc >= length
402 || end_pc < 0 || end_pc > length || start_pc >= end_pc
403 || handler_pc < 0 || handler_pc >= length
404 || (handler_pc >= start_pc && handler_pc < end_pc)
405 || ! (instruction_bits [start_pc] & BCODE_INSTRUCTION_START)
406 || (end_pc < length &&
407 ! (instruction_bits [end_pc] & BCODE_INSTRUCTION_START))
408 || ! (instruction_bits [handler_pc] & BCODE_INSTRUCTION_START))
410 error ("bad pc in exception_table");
411 free (starts);
412 return 0;
415 add_handler (start_pc, end_pc,
416 lookup_label (handler_pc),
417 catch_type == 0 ? NULL_TREE
418 : get_class_constant (jcf, catch_type));
420 instruction_bits [handler_pc] |= BCODE_EXCEPTION_TARGET;
423 free (starts);
424 handle_nested_ranges ();
426 for (PC = 0;;)
428 int index;
429 tree type, tmp;
430 if (((PC != INVALID_PC
431 && instruction_bits [PC] & BCODE_TARGET) != 0)
432 || PC == 0)
434 PUSH_PENDING (lookup_label (PC));
435 INVALIDATE_PC;
437 /* Check if there are any more pending blocks in the current
438 subroutine. Because we push pending blocks in a
439 last-in-first-out order, and because we don't push anything
440 from our caller until we are done with this subroutine or
441 anything nested in it, then we are done if the top of the
442 pending_blocks stack is not in a subroutine, or it is in our
443 caller. */
444 if (current_subr
445 && PC == INVALID_PC)
447 tree caller = LABEL_SUBR_CONTEXT (current_subr);
449 if (pending_blocks == NULL_TREE
450 || ! LABEL_IN_SUBR (pending_blocks)
451 || LABEL_SUBR_START (pending_blocks) == caller)
453 int size = DECL_MAX_LOCALS(current_function_decl)+stack_pointer;
454 tree ret_map = LABEL_RETURN_TYPE_STATE (current_subr);
455 tmp = LABEL_RETURN_LABELS (current_subr);
457 /* FIXME: If we exit a subroutine via a throw, we might
458 have returned to an earlier caller. Obviously a
459 "ret" can only return one level, but a throw may
460 return many levels.*/
461 current_subr = caller;
463 if (RETURN_MAP_ADJUSTED (ret_map))
465 /* Since we are done with this subroutine , set up
466 the (so far known) return address as pending -
467 with the merged type state. */
468 for ( ; tmp != NULL_TREE; tmp = TREE_CHAIN (tmp))
470 tree return_label = TREE_VALUE (tmp);
471 tree return_state = LABEL_TYPE_STATE (return_label);
472 if (return_state == NULL_TREE)
474 /* This means means we had not verified the
475 subroutine earlier, so this is the first jsr to
476 call it. In this case, the type_map of the return
477 address is just the current type_map - and that
478 is handled by the following PUSH_PENDING. */
480 else
482 /* In this case we have to do a merge. But first
483 restore the type_map for unused slots to those
484 that were in effect at the jsr. */
485 for (index = size; --index >= 0; )
487 type_map[index] = TREE_VEC_ELT (ret_map, index);
488 if (type_map[index] == TYPE_UNUSED)
489 type_map[index]
490 = TREE_VEC_ELT (return_state, index);
493 PUSH_PENDING (return_label);
498 if (PC == INVALID_PC)
500 label = pending_blocks;
501 if (label == NULL_TREE)
502 break; /* We're done! */
503 pending_blocks = LABEL_PENDING_CHAIN (label);
504 LABEL_CHANGED (label) = 0;
506 if (LABEL_IN_SUBR (label))
507 current_subr = LABEL_SUBR_START (label);
508 else
509 current_subr = NULL_TREE;
511 /* Restore type_map and stack_pointer from
512 LABEL_TYPE_STATE (label), and continue
513 compiling from there. */
514 load_type_state (label);
515 PC = LABEL_PC (label);
517 else if (PC >= length)
518 VERIFICATION_ERROR ("falling through end of method");
520 /* fprintf (stderr, "** %d\n", PC); */
522 oldpc = PC;
524 if (!(instruction_bits [PC] & BCODE_INSTRUCTION_START) && ! wide)
525 VERIFICATION_ERROR ("PC not at instruction start");
527 instruction_bits[PC] |= BCODE_VERIFIED;
529 eh_ranges = find_handler (oldpc);
531 op_code = byte_ops[PC++];
532 switch (op_code)
534 int is_static, is_putting;
535 case OPCODE_nop:
536 break;
537 case OPCODE_iconst_m1:
538 case OPCODE_iconst_0: case OPCODE_iconst_1: case OPCODE_iconst_2:
539 case OPCODE_iconst_3: case OPCODE_iconst_4: case OPCODE_iconst_5:
540 i = op_code - OPCODE_iconst_0;
541 goto push_int;
542 push_int:
543 if (byte_ops[PC] == OPCODE_newarray
544 || byte_ops[PC] == OPCODE_newarray)
545 int_value = i;
546 push_type (int_type_node); break;
547 case OPCODE_lconst_0: case OPCODE_lconst_1:
548 push_type (long_type_node); break;
549 case OPCODE_fconst_0: case OPCODE_fconst_1: case OPCODE_fconst_2:
550 push_type (float_type_node); break;
551 case OPCODE_dconst_0: case OPCODE_dconst_1:
552 push_type (double_type_node); break;
553 case OPCODE_bipush:
554 i = IMMEDIATE_s1;
555 goto push_int;
556 case OPCODE_sipush:
557 i = IMMEDIATE_s2;
558 goto push_int;
559 case OPCODE_iload: type = int_type_node; goto general_load;
560 case OPCODE_lload: type = long_type_node; goto general_load;
561 case OPCODE_fload: type = float_type_node; goto general_load;
562 case OPCODE_dload: type = double_type_node; goto general_load;
563 case OPCODE_aload: type = ptr_type_node; goto general_load;
564 general_load:
565 index = wide ? IMMEDIATE_u2 : IMMEDIATE_u1;
566 wide = 0;
567 goto load;
568 case OPCODE_iload_0: type = int_type_node; index = 0; goto load;
569 case OPCODE_iload_1: type = int_type_node; index = 1; goto load;
570 case OPCODE_iload_2: type = int_type_node; index = 2; goto load;
571 case OPCODE_iload_3: type = int_type_node; index = 3; goto load;
572 case OPCODE_lload_0: type = long_type_node; index = 0; goto load;
573 case OPCODE_lload_1: type = long_type_node; index = 1; goto load;
574 case OPCODE_lload_2: type = long_type_node; index = 2; goto load;
575 case OPCODE_lload_3: type = long_type_node; index = 3; goto load;
576 case OPCODE_fload_0: type = float_type_node; index = 0; goto load;
577 case OPCODE_fload_1: type = float_type_node; index = 1; goto load;
578 case OPCODE_fload_2: type = float_type_node; index = 2; goto load;
579 case OPCODE_fload_3: type = float_type_node; index = 3; goto load;
580 case OPCODE_dload_0: type = double_type_node; index = 0; goto load;
581 case OPCODE_dload_1: type = double_type_node; index = 1; goto load;
582 case OPCODE_dload_2: type = double_type_node; index = 2; goto load;
583 case OPCODE_dload_3: type = double_type_node; index = 3; goto load;
584 case OPCODE_aload_0: type = ptr_type_node; index = 0; goto load;
585 case OPCODE_aload_1: type = ptr_type_node; index = 1; goto load;
586 case OPCODE_aload_2: type = ptr_type_node; index = 2; goto load;
587 case OPCODE_aload_3: type = ptr_type_node; index = 3; goto load;
588 load:
589 if (index < 0
590 || (index + TYPE_IS_WIDE (type)
591 >= DECL_MAX_LOCALS (current_function_decl)))
592 VERIFICATION_ERROR ("invalid local variable index in load");
593 tmp = type_map[index];
594 if (tmp == TYPE_UNKNOWN || tmp == TYPE_SECOND
595 || (TYPE_IS_WIDE (type)
596 && type_map[index+1] != void_type_node)
597 || (type == ptr_type_node
598 ? TREE_CODE (tmp) != POINTER_TYPE
599 : type == int_type_node
600 ? (! INTEGRAL_TYPE_P (tmp) || TYPE_PRECISION (tmp) > 32)
601 : type != tmp))
602 VERIFICATION_ERROR("invalid local variable type in load");
603 push_type (tmp);
604 goto note_used;
605 case OPCODE_istore: type = int_type_node; goto general_store;
606 case OPCODE_lstore: type = long_type_node; goto general_store;
607 case OPCODE_fstore: type = float_type_node; goto general_store;
608 case OPCODE_dstore: type = double_type_node; goto general_store;
609 case OPCODE_astore: type = ptr_type_node; goto general_store;
610 general_store:
611 index = wide ? IMMEDIATE_u2 : IMMEDIATE_u1;
612 wide = 0;
613 goto store;
614 case OPCODE_istore_0: type = int_type_node; index = 0; goto store;
615 case OPCODE_istore_1: type = int_type_node; index = 1; goto store;
616 case OPCODE_istore_2: type = int_type_node; index = 2; goto store;
617 case OPCODE_istore_3: type = int_type_node; index = 3; goto store;
618 case OPCODE_lstore_0: type = long_type_node; index=0; goto store;
619 case OPCODE_lstore_1: type = long_type_node; index=1; goto store;
620 case OPCODE_lstore_2: type = long_type_node; index=2; goto store;
621 case OPCODE_lstore_3: type = long_type_node; index=3; goto store;
622 case OPCODE_fstore_0: type=float_type_node; index=0; goto store;
623 case OPCODE_fstore_1: type=float_type_node; index=1; goto store;
624 case OPCODE_fstore_2: type=float_type_node; index=2; goto store;
625 case OPCODE_fstore_3: type=float_type_node; index=3; goto store;
626 case OPCODE_dstore_0: type=double_type_node; index=0; goto store;
627 case OPCODE_dstore_1: type=double_type_node; index=1; goto store;
628 case OPCODE_dstore_2: type=double_type_node; index=2; goto store;
629 case OPCODE_dstore_3: type=double_type_node; index=3; goto store;
630 case OPCODE_astore_0: type = ptr_type_node; index = 0; goto store;
631 case OPCODE_astore_1: type = ptr_type_node; index = 1; goto store;
632 case OPCODE_astore_2: type = ptr_type_node; index = 2; goto store;
633 case OPCODE_astore_3: type = ptr_type_node; index = 3; goto store;
634 store:
635 if (index < 0
636 || (index + TYPE_IS_WIDE (type)
637 >= DECL_MAX_LOCALS (current_function_decl)))
639 VERIFICATION_ERROR ("invalid local variable index in store");
640 return 0;
642 type = pop_type (type);
643 type_map[index] = type;
645 /* If local variable changed, we need to reconsider eh handlers. */
646 prev_eh_ranges = NULL_EH_RANGE;
648 /* Allocate decl and rtx for this variable now, so if we're not
649 optmizing, we get a temporary that survives the whole method. */
650 find_local_variable (index, type, oldpc);
652 if (TYPE_IS_WIDE (type))
653 type_map[index+1] = TYPE_SECOND;
654 /* ... fall through to note_used ... */
655 note_used:
656 /* For store or load, note that local variable INDEX is used.
657 This is needed to verify try-finally sub-routines. */
658 if (current_subr)
660 tree vec = LABEL_RETURN_TYPE_STATE (current_subr);
661 tree subr_vec = LABEL_TYPE_STATE (current_subr);
662 int len = 1 + TYPE_IS_WIDE (type);
663 while (--len >= 0)
665 if (TREE_VEC_ELT (vec, index) == TYPE_UNUSED)
666 TREE_VEC_ELT (vec, index) = TREE_VEC_ELT (subr_vec, index);
669 break;
670 case OPCODE_iadd:
671 case OPCODE_iand:
672 case OPCODE_idiv:
673 case OPCODE_imul:
674 case OPCODE_ior:
675 case OPCODE_irem:
676 case OPCODE_ishl:
677 case OPCODE_ishr:
678 case OPCODE_isub:
679 case OPCODE_iushr:
680 case OPCODE_ixor:
681 type = int_type_node; goto binop;
682 case OPCODE_ineg:
683 case OPCODE_i2c:
684 case OPCODE_i2b:
685 case OPCODE_i2s:
686 type = int_type_node; goto unop;
687 case OPCODE_ladd:
688 case OPCODE_land:
689 case OPCODE_ldiv:
690 case OPCODE_lsub:
691 case OPCODE_lmul:
692 case OPCODE_lrem:
693 case OPCODE_lor:
694 case OPCODE_lxor:
695 type = long_type_node; goto binop;
696 case OPCODE_lneg:
697 type = long_type_node; goto unop;
698 case OPCODE_fadd: case OPCODE_fsub:
699 case OPCODE_fmul: case OPCODE_fdiv: case OPCODE_frem:
700 type = float_type_node; goto binop;
701 case OPCODE_fneg:
702 type = float_type_node; goto unop;
703 case OPCODE_dadd: case OPCODE_dsub:
704 case OPCODE_dmul: case OPCODE_ddiv: case OPCODE_drem:
705 type = double_type_node; goto binop;
706 case OPCODE_dneg:
707 type = double_type_node; goto unop;
708 unop:
709 pop_type (type);
710 push_type (type);
711 break;
712 binop:
713 pop_type (type);
714 pop_type (type);
715 push_type (type);
716 break;
717 case OPCODE_lshl:
718 case OPCODE_lshr:
719 case OPCODE_lushr:
720 pop_type (int_type_node);
721 pop_type (long_type_node);
722 push_type (long_type_node);
723 break;
724 case OPCODE_iinc:
725 index = wide ? IMMEDIATE_u2 : IMMEDIATE_u1;
726 PC += wide + 1;
727 wide = 0;
728 if (index < 0 || index >= DECL_MAX_LOCALS (current_function_decl))
729 VERIFICATION_ERROR ("invalid local variable index in iinc");
730 tmp = type_map[index];
731 if (! INTEGRAL_TYPE_P (tmp) || TYPE_PRECISION (tmp) > 32)
732 VERIFICATION_ERROR ("invalid local variable type in iinc");
733 break;
734 case OPCODE_i2l:
735 pop_type (int_type_node); push_type (long_type_node); break;
736 case OPCODE_i2f:
737 pop_type (int_type_node); push_type (float_type_node); break;
738 case OPCODE_i2d:
739 pop_type (int_type_node); push_type (double_type_node); break;
740 case OPCODE_l2i:
741 pop_type (long_type_node); push_type (int_type_node); break;
742 case OPCODE_l2f:
743 pop_type (long_type_node); push_type (float_type_node); break;
744 case OPCODE_l2d:
745 pop_type (long_type_node); push_type (double_type_node); break;
746 case OPCODE_f2i:
747 pop_type (float_type_node); push_type (int_type_node); break;
748 case OPCODE_f2l:
749 pop_type (float_type_node); push_type (long_type_node); break;
750 case OPCODE_f2d:
751 pop_type (float_type_node); push_type (double_type_node); break;
752 case OPCODE_d2i:
753 pop_type (double_type_node); push_type (int_type_node); break;
754 case OPCODE_d2l:
755 pop_type (double_type_node); push_type (long_type_node); break;
756 case OPCODE_d2f:
757 pop_type (double_type_node); push_type (float_type_node); break;
758 case OPCODE_lcmp:
759 type = long_type_node; goto compare;
760 case OPCODE_fcmpl:
761 case OPCODE_fcmpg:
762 type = float_type_node; goto compare;
763 case OPCODE_dcmpl:
764 case OPCODE_dcmpg:
765 type = double_type_node; goto compare;
766 compare:
767 pop_type (type); pop_type (type);
768 push_type (int_type_node); break;
769 case OPCODE_ifeq:
770 case OPCODE_ifne:
771 case OPCODE_iflt:
772 case OPCODE_ifge:
773 case OPCODE_ifgt:
774 case OPCODE_ifle:
775 pop_type (int_type_node); goto cond;
776 case OPCODE_ifnull:
777 case OPCODE_ifnonnull:
778 pop_type (ptr_type_node ); goto cond;
779 case OPCODE_if_icmpeq:
780 case OPCODE_if_icmpne:
781 case OPCODE_if_icmplt:
782 case OPCODE_if_icmpge:
783 case OPCODE_if_icmpgt:
784 case OPCODE_if_icmple:
785 pop_type (int_type_node); pop_type (int_type_node); goto cond;
786 case OPCODE_if_acmpeq:
787 case OPCODE_if_acmpne:
788 pop_type (object_ptr_type_node); pop_type (object_ptr_type_node);
789 goto cond;
790 cond:
791 PUSH_PENDING (lookup_label (oldpc + IMMEDIATE_s2));
792 break;
793 case OPCODE_goto:
794 PUSH_PENDING (lookup_label (oldpc + IMMEDIATE_s2));
795 INVALIDATE_PC;
796 break;
797 case OPCODE_wide:
798 switch (byte_ops[PC])
800 case OPCODE_iload: case OPCODE_lload:
801 case OPCODE_fload: case OPCODE_dload: case OPCODE_aload:
802 case OPCODE_istore: case OPCODE_lstore:
803 case OPCODE_fstore: case OPCODE_dstore: case OPCODE_astore:
804 case OPCODE_iinc:
805 case OPCODE_ret:
806 wide = 1;
807 break;
808 default:
809 VERIFICATION_ERROR ("invalid use of wide instruction");
811 break;
812 case OPCODE_return: type = void_type_node; goto ret;
813 case OPCODE_ireturn:
814 if ((TREE_CODE (return_type) == BOOLEAN_TYPE
815 || TREE_CODE (return_type) == CHAR_TYPE
816 || TREE_CODE (return_type) == INTEGER_TYPE)
817 && TYPE_PRECISION (return_type) <= 32)
818 type = return_type;
819 else
820 type = NULL_TREE;
821 goto ret;
822 case OPCODE_lreturn: type = long_type_node; goto ret;
823 case OPCODE_freturn: type = float_type_node; goto ret;
824 case OPCODE_dreturn: type = double_type_node; goto ret;
825 case OPCODE_areturn:
826 if (TREE_CODE (return_type) == POINTER_TYPE)
827 type = return_type;
828 else
829 type = NULL_TREE;
830 goto ret;
831 ret:
832 if (type != return_type)
833 VERIFICATION_ERROR ("incorrect ?return opcode");
834 if (type != void_type_node)
836 if (pop_type_0 (type) == NULL_TREE)
837 VERIFICATION_ERROR ("return value has wrong type");
839 INVALIDATE_PC;
840 break;
841 case OPCODE_getstatic: is_putting = 0; is_static = 1; goto field;
842 case OPCODE_putstatic: is_putting = 1; is_static = 1; goto field;
843 case OPCODE_getfield: is_putting = 0; is_static = 0; goto field;
844 case OPCODE_putfield: is_putting = 1; is_static = 0; goto field;
845 field:
847 int index = IMMEDIATE_u2;
848 tree field_signature = COMPONENT_REF_SIGNATURE (&current_jcf->cpool, index);
849 tree field_type = get_type_from_signature (field_signature);
850 if (is_putting)
851 pop_type (field_type);
852 if (! is_static)
854 int clindex = COMPONENT_REF_CLASS_INDEX (&current_jcf->cpool,
855 index);
856 tree self_type = get_class_constant (current_jcf, clindex);
857 /* Defer actual checking until next pass. */
858 if (pop_type_0 (self_type) == NULL_TREE)
859 VERIFICATION_ERROR ("incorrect type for field reference");
861 if (! is_putting)
862 push_type (field_type);
863 break;
865 case OPCODE_new:
866 push_type (get_class_constant (jcf, IMMEDIATE_u2));
867 break;
868 case OPCODE_dup: type_stack_dup (1, 0); break;
869 case OPCODE_dup_x1: type_stack_dup (1, 1); break;
870 case OPCODE_dup_x2: type_stack_dup (1, 2); break;
871 case OPCODE_dup2: type_stack_dup (2, 0); break;
872 case OPCODE_dup2_x1: type_stack_dup (2, 1); break;
873 case OPCODE_dup2_x2: type_stack_dup (2, 2); break;
874 case OPCODE_pop: index = 1; goto pop;
875 case OPCODE_pop2: index = 2; goto pop;
876 pop:
877 if (stack_pointer < index)
878 VERIFICATION_ERROR ("stack underflow");
879 stack_pointer -= index;
880 break;
881 case OPCODE_swap:
882 if (stack_pointer < 2)
883 VERIFICATION_ERROR ("stack underflow (in swap)");
884 else
886 tree type1 = stack_type_map[stack_pointer - 1];
887 tree type2 = stack_type_map[stack_pointer - 2];
888 if (type1 == void_type_node || type2 == void_type_node)
889 VERIFICATION_ERROR ("verifier (swap): double or long value");
890 stack_type_map[stack_pointer - 2] = type1;
891 stack_type_map[stack_pointer - 1] = type2;
893 break;
894 case OPCODE_ldc: index = IMMEDIATE_u1; goto ldc;
895 case OPCODE_ldc2_w:
896 case OPCODE_ldc_w:
897 index = IMMEDIATE_u2; goto ldc;
898 ldc:
899 if (index <= 0 || index >= JPOOL_SIZE(current_jcf))
900 VERIFICATION_ERROR ("bad constant pool index in ldc");
901 int_value = -1;
902 switch (JPOOL_TAG (current_jcf, index) & ~CONSTANT_ResolvedFlag)
904 case CONSTANT_Integer: type = int_type_node; goto check_ldc;
905 case CONSTANT_Float: type = float_type_node; goto check_ldc;
906 case CONSTANT_String: type = string_type_node; goto check_ldc;
907 case CONSTANT_Long: type = long_type_node; goto check_ldc;
908 case CONSTANT_Double: type = double_type_node; goto check_ldc;
909 check_ldc:
910 if (TYPE_IS_WIDE (type) == (op_code == OPCODE_ldc2_w))
911 break;
912 /* ... else fall through ... */
913 default:
914 VERIFICATION_ERROR ("bad constant pool tag in ldc");
916 if (type == int_type_node)
918 i = TREE_INT_CST_LOW (get_constant (current_jcf, index));
919 goto push_int;
921 push_type (type);
922 break;
924 case OPCODE_invokevirtual:
925 case OPCODE_invokespecial:
926 case OPCODE_invokestatic:
927 case OPCODE_invokeinterface:
929 int index = IMMEDIATE_u2;
930 tree sig = COMPONENT_REF_SIGNATURE (&current_jcf->cpool, index);
931 tree self_type = get_class_constant
932 (current_jcf, COMPONENT_REF_CLASS_INDEX (&current_jcf->cpool,
933 index));
934 tree method_name = COMPONENT_REF_NAME (&current_jcf->cpool, index);
935 tree method_type;
936 method_type = parse_signature_string (IDENTIFIER_POINTER (sig),
937 IDENTIFIER_LENGTH (sig));
938 if (TREE_CODE (method_type) != FUNCTION_TYPE)
939 VERIFICATION_ERROR ("bad method signature");
940 pop_argument_types (TYPE_ARG_TYPES (method_type));
942 /* Can't invoke <clinit> */
943 if (method_name == clinit_identifier_node)
944 VERIFICATION_ERROR ("invoke opcode can't invoke <clinit>");
945 /* Apart invokespecial, can't invoke <init> */
946 if (op_code != OPCODE_invokespecial
947 && method_name == init_identifier_node)
948 VERIFICATION_ERROR ("invoke opcode can't invoke <init>");
950 if (op_code != OPCODE_invokestatic)
951 pop_type (self_type);
953 switch (op_code)
955 case OPCODE_invokeinterface:
957 int nargs = IMMEDIATE_u1;
958 int notZero = IMMEDIATE_u1;
960 if (!nargs || notZero)
961 VERIFICATION_ERROR
962 ("invalid argument number in invokeinterface");
963 break;
967 if (TREE_TYPE (method_type) != void_type_node)
968 push_type (TREE_TYPE (method_type));
969 break;
972 case OPCODE_arraylength:
973 /* Type checking actually made during code generation */
974 pop_type( ptr_type_node );
975 push_type( int_type_node );
976 break;
978 /* Q&D verification *or* more checking done during code generation
979 for byte/boolean/char/short, the value popped is a int coerced
980 into the right type before being stored. */
981 case OPCODE_iastore: type = int_type_node; goto astore;
982 case OPCODE_lastore: type = long_type_node; goto astore;
983 case OPCODE_fastore: type = float_type_node; goto astore;
984 case OPCODE_dastore: type = double_type_node; goto astore;
985 case OPCODE_aastore: type = ptr_type_node; goto astore;
986 case OPCODE_bastore: type = int_type_node; goto astore;
987 case OPCODE_castore: type = int_type_node; goto astore;
988 case OPCODE_sastore: type = int_type_node; goto astore;
989 astore:
990 /* FIXME - need better verification here */
991 pop_type (type); /* new value */
992 pop_type (int_type_node); /* index */
993 pop_type (ptr_type_node); /* array */
994 break;
996 /* Q&D verification *or* more checking done during code generation
997 for byte/boolean/char/short, the value pushed is a int. */
998 case OPCODE_iaload: type = int_type_node; goto aload;
999 case OPCODE_laload: type = long_type_node; goto aload;
1000 case OPCODE_faload: type = float_type_node; goto aload;
1001 case OPCODE_daload: type = double_type_node; goto aload;
1002 case OPCODE_aaload: type = ptr_type_node; goto aload;
1003 case OPCODE_baload: type = promote_type (byte_type_node); goto aload;
1004 case OPCODE_caload: type = promote_type (char_type_node); goto aload;
1005 case OPCODE_saload: type = promote_type (short_type_node); goto aload;
1006 aload:
1007 pop_type (int_type_node);
1008 tmp = pop_type (ptr_type_node);
1009 if (is_array_type_p (tmp))
1010 type = TYPE_ARRAY_ELEMENT (TREE_TYPE (tmp));
1011 else if (tmp != TYPE_NULL)
1012 VERIFICATION_ERROR ("array load from non-array type");
1013 push_type (type);
1014 break;
1016 case OPCODE_anewarray:
1017 type = get_class_constant (current_jcf, IMMEDIATE_u2);
1018 type = promote_type (type);
1019 goto newarray;
1021 case OPCODE_newarray:
1022 index = IMMEDIATE_u1;
1023 type = decode_newarray_type (index);
1024 if (type == NULL_TREE)
1025 VERIFICATION_ERROR ("invalid type code in newarray opcode");
1026 goto newarray;
1028 newarray:
1029 if (int_value >= 0 && prevpc >= 0)
1031 /* If previous instruction pushed int constant,
1032 we want to use it. */
1033 switch (byte_ops[prevpc])
1035 case OPCODE_iconst_0: case OPCODE_iconst_1:
1036 case OPCODE_iconst_2: case OPCODE_iconst_3:
1037 case OPCODE_iconst_4: case OPCODE_iconst_5:
1038 case OPCODE_bipush: case OPCODE_sipush:
1039 case OPCODE_ldc: case OPCODE_ldc_w:
1040 break;
1041 default:
1042 int_value = -1;
1045 else
1046 int_value = -1;
1047 type = build_java_array_type (type, int_value);
1048 pop_type (int_type_node);
1049 push_type (type);
1050 break;
1052 case OPCODE_multianewarray:
1054 int ndim, i;
1055 index = IMMEDIATE_u2;
1056 ndim = IMMEDIATE_u1;
1058 if( ndim < 1 )
1059 VERIFICATION_ERROR ("number of dimension lower that 1 in multianewarray" );
1061 for( i = 0; i < ndim; i++ )
1062 pop_type (int_type_node);
1063 push_type (get_class_constant (current_jcf, index));
1064 break;
1067 case OPCODE_aconst_null:
1068 push_type (ptr_type_node);
1069 break;
1071 case OPCODE_athrow:
1072 /* FIXME: athrow also empties the stack. */
1073 pop_type (throwable_type_node);
1074 INVALIDATE_PC;
1075 break;
1077 case OPCODE_checkcast:
1078 pop_type (ptr_type_node);
1079 type = get_class_constant (current_jcf, IMMEDIATE_u2);
1080 push_type (type);
1081 break;
1082 case OPCODE_instanceof:
1083 pop_type (ptr_type_node);
1084 get_class_constant (current_jcf, IMMEDIATE_u2);
1085 push_type (int_type_node);
1086 break;
1088 case OPCODE_tableswitch:
1090 jint low, high;
1092 pop_type (int_type_node);
1093 while (PC%4)
1095 if (byte_ops[PC++])
1096 VERIFICATION_ERROR ("bad alignment in tableswitch pad");
1098 PUSH_PENDING (lookup_label (oldpc+IMMEDIATE_s4));
1099 low = IMMEDIATE_s4;
1100 high = IMMEDIATE_s4;
1102 if (low > high)
1103 VERIFICATION_ERROR ("unsorted low/high value in tableswitch");
1105 while (low++ <= high)
1106 PUSH_PENDING (lookup_label (oldpc + IMMEDIATE_s4));
1107 INVALIDATE_PC;
1108 break;
1111 case OPCODE_lookupswitch:
1113 jint npairs, last = 0, not_registered = 1;
1115 pop_type (int_type_node);
1116 while (PC%4)
1118 if (byte_ops[PC++])
1119 VERIFICATION_ERROR ("bad alignment in lookupswitch pad");
1122 PUSH_PENDING (lookup_label (oldpc+IMMEDIATE_s4));
1123 npairs = IMMEDIATE_s4;
1125 if (npairs < 0)
1126 VERIFICATION_ERROR ("invalid number of targets in lookupswitch");
1128 while (npairs--)
1130 int match = IMMEDIATE_s4;
1131 if (not_registered)
1132 not_registered = 0;
1133 else if (last >= match)
1134 VERIFICATION_ERROR ("unsorted match value in lookupswitch");
1136 last = match;
1137 PUSH_PENDING (lookup_label (oldpc + IMMEDIATE_s4));
1139 INVALIDATE_PC;
1140 break;
1143 case OPCODE_monitorenter:
1144 /* fall thru */
1145 case OPCODE_monitorexit:
1146 pop_type (ptr_type_node);
1147 break;
1149 case OPCODE_goto_w:
1150 PUSH_PENDING (lookup_label (oldpc + IMMEDIATE_s4));
1151 INVALIDATE_PC;
1152 break;
1154 case OPCODE_jsr:
1156 tree target = lookup_label (oldpc + IMMEDIATE_s2);
1157 tree return_label = lookup_label (PC);
1158 push_type (return_address_type_node);
1159 /* The return label chain will be null if this is the first
1160 time we've seen this jsr target. */
1161 if (LABEL_RETURN_LABEL (target) == NULL_TREE)
1163 tree return_type_map;
1164 int nlocals = DECL_MAX_LOCALS (current_function_decl);
1165 index = nlocals + DECL_MAX_STACK (current_function_decl);
1166 return_type_map = make_tree_vec (index);
1167 while (index > nlocals)
1168 TREE_VEC_ELT (return_type_map, --index) = TYPE_UNKNOWN;
1169 while (index > 0)
1170 TREE_VEC_ELT (return_type_map, --index) = TYPE_UNUSED;
1171 LABEL_RETURN_LABEL (target)
1172 = build_decl (LABEL_DECL, NULL_TREE, TREE_TYPE (target));
1173 LABEL_PC (LABEL_RETURN_LABEL (target)) = -1;
1174 LABEL_RETURN_TYPE_STATE (target) = return_type_map;
1175 LABEL_IS_SUBR_START (target) = 1;
1176 LABEL_IN_SUBR (target) = 1;
1177 LABEL_SUBR_START (target) = target;
1178 LABEL_SUBR_CONTEXT (target) = current_subr;
1180 else if (! LABEL_IS_SUBR_START (target)
1181 || LABEL_SUBR_CONTEXT (target) != current_subr)
1182 VERIFICATION_ERROR ("label part of different subroutines");
1184 i = merge_type_state (target);
1185 if (i != 0)
1187 if (i < 0)
1188 VERIFICATION_ERROR ("types could not be merged at jsr");
1189 push_pending_label (target);
1191 current_subr = target;
1193 /* Chain return_pc onto LABEL_RETURN_LABELS (target) if needed. */
1194 if (! value_member (return_label, LABEL_RETURN_LABELS (target)))
1196 LABEL_RETURN_LABELS (target)
1197 = tree_cons (NULL_TREE, return_label,
1198 LABEL_RETURN_LABELS (target));
1201 if (LABEL_VERIFIED (target))
1203 tree return_map = LABEL_RETURN_TYPE_STATE (target);
1204 int len = TREE_VEC_LENGTH (return_map);
1205 stack_pointer = len - DECL_MAX_LOCALS (current_function_decl);
1206 while (--len >= 0)
1208 if (TREE_VEC_ELT (return_map, len) != TYPE_UNUSED)
1209 type_map[len] = TREE_VEC_ELT (return_map, len);
1211 current_subr = LABEL_SUBR_CONTEXT (target);
1212 PUSH_PENDING (return_label);
1215 INVALIDATE_PC;
1217 break;
1218 case OPCODE_ret:
1219 if (current_subr == NULL)
1220 VERIFICATION_ERROR ("ret instruction not in a jsr subroutine");
1221 else
1223 tree ret_map = LABEL_RETURN_TYPE_STATE (current_subr);
1224 int size = DECL_MAX_LOCALS(current_function_decl)+stack_pointer;
1225 index = wide ? IMMEDIATE_u2 : IMMEDIATE_u1;
1226 wide = 0;
1227 INVALIDATE_PC;
1228 if (index < 0 || index >= DECL_MAX_LOCALS (current_function_decl)
1229 || type_map[index] != TYPE_RETURN_ADDR)
1230 VERIFICATION_ERROR ("invalid ret index");
1232 /* The next chunk of code is similar to an inlined version of
1233 * merge_type_state (LABEL_RETURN_LABEL (current_subr)).
1234 * The main differences are that LABEL_RETURN_LABEL is
1235 * pre-allocated by the jsr (but we don't know the size then);
1236 * and that we have to handle TYPE_UNUSED. */
1238 if (! RETURN_MAP_ADJUSTED (ret_map))
1239 { /* First return from this subroutine - fix stack pointer. */
1240 TREE_VEC_LENGTH (ret_map) = size;
1241 for (index = size; --index >= 0; )
1243 if (TREE_VEC_ELT (ret_map, index) != TYPE_UNUSED)
1244 TREE_VEC_ELT (ret_map, index) = type_map[index];
1246 RETURN_MAP_ADJUSTED (ret_map) = 1;
1248 else
1250 if (TREE_VEC_LENGTH (ret_map) != size)
1251 VERIFICATION_ERROR ("inconsistent stack size on ret");
1252 for (index = 0; index < size; index++)
1254 tree type = TREE_VEC_ELT (ret_map, index);
1255 if (type != TYPE_UNUSED)
1257 type = merge_types (type, type_map [index]);
1258 TREE_VEC_ELT (ret_map, index) = type;
1259 if (type == TYPE_UNKNOWN)
1261 if (index >= size - stack_pointer)
1262 VERIFICATION_ERROR
1263 ("inconsistent types on ret from jsr");
1265 else if (TYPE_IS_WIDE (type))
1266 index++;
1273 break;
1274 case OPCODE_jsr_w:
1275 case OPCODE_ret_w:
1276 default:
1277 error ("unknown opcode %d@pc=%d during verification", op_code, PC-1);
1278 return 0;
1281 prevpc = oldpc;
1283 /* The following test is true if we have entered or exited an exception
1284 handler range *or* we have done a store to a local variable.
1285 In either case we need to consider any exception handlers that
1286 might "follow" this instruction. */
1288 if (eh_ranges != prev_eh_ranges)
1290 int save_stack_pointer = stack_pointer;
1291 int index = DECL_MAX_LOCALS (current_function_decl);
1292 tree save_type = type_map[index];
1293 tree save_current_subr = current_subr;
1294 struct eh_range *ranges = find_handler (oldpc);
1295 stack_pointer = 1;
1296 for (; ranges != NULL_EH_RANGE; ranges = ranges->outer)
1298 tree chain = ranges->handlers;
1300 /* We need to determine if the handler is part of current_subr.
1301 The are two cases: (1) The exception catch range
1302 is entirely within current_subr. In that case the handler
1303 is also part of current_subr.
1304 (2) Some of the catch range is not in current_subr.
1305 In that case, the handler is *not* part of current_subr.
1307 Figuring out which is the case is not necessarily obvious,
1308 in the presence of clever code generators (and obfuscators).
1309 We make a simplifying assumption that in case (2) we
1310 have that the current_subr is entirely within the catch range.
1311 In that case we can assume if that if a caller (the jsr) of
1312 a subroutine is within the catch range, then the handler is
1313 *not* part of the subroutine, and vice versa. */
1315 current_subr = save_current_subr;
1316 for ( ; current_subr != NULL_TREE;
1317 current_subr = LABEL_SUBR_CONTEXT (current_subr))
1319 tree return_labels = LABEL_RETURN_LABELS (current_subr);
1320 /* There could be multiple return_labels, but
1321 we only need to check one. */
1322 int return_pc = LABEL_PC (TREE_VALUE (return_labels));
1323 if (return_pc <= ranges->start_pc
1324 || return_pc > ranges->end_pc)
1325 break;
1328 for ( ; chain != NULL_TREE; chain = TREE_CHAIN (chain))
1330 tree handler = TREE_VALUE (chain);
1331 tree type = TREE_PURPOSE (chain);
1332 if (type == NULL_TREE) /* a finally handler */
1333 type = throwable_type_node;
1334 type_map[index] = promote_type (type);
1336 PUSH_PENDING (handler);
1339 stack_pointer = save_stack_pointer;
1340 current_subr = save_current_subr;
1341 type_map[index] = save_type;
1342 prev_eh_ranges = eh_ranges;
1345 return 1;
1346 bad_pc:
1347 message = "program counter out of range";
1348 goto verify_error;
1349 verify_error:
1350 error ("verification error at PC=%d", oldpc);
1351 error ("%s", message);
1352 return 0;