diff options
Diffstat (limited to 'gcc/java/verify.c')
-rw-r--r-- | gcc/java/verify.c | 28 |
1 files changed, 16 insertions, 12 deletions
diff --git a/gcc/java/verify.c b/gcc/java/verify.c index 5ac1d057e5c..25d3b3a2377 100644 --- a/gcc/java/verify.c +++ b/gcc/java/verify.c @@ -294,8 +294,6 @@ type_stack_dup (size, offset) { tree type[4]; int index; - if (size + offset > stack_pointer) - error ("stack underflow - dup* operation"); for (index = 0; index < size + offset; index++) { type[index] = stack_type_map[stack_pointer - 1]; @@ -413,7 +411,7 @@ verify_jvm_instructions (jcf, byte_ops, length) int PC; int oldpc = 0; /* PC of start of instruction. */ int prevpc = 0; /* If >= 0, PC of previous instruction. */ - const char *message; + const char *message = 0; char *pmessage; int i; int index; @@ -923,12 +921,18 @@ verify_jvm_instructions (jcf, byte_ops, length) case OPCODE_new: PUSH_TYPE (get_class_constant (jcf, IMMEDIATE_u2)); break; - case OPCODE_dup: type_stack_dup (1, 0); break; - case OPCODE_dup_x1: type_stack_dup (1, 1); break; - case OPCODE_dup_x2: type_stack_dup (1, 2); break; - case OPCODE_dup2: type_stack_dup (2, 0); break; - case OPCODE_dup2_x1: type_stack_dup (2, 1); break; - case OPCODE_dup2_x2: type_stack_dup (2, 2); break; + case OPCODE_dup: wide = 1; index = 0; goto dup; + case OPCODE_dup_x1: wide = 1; index = 1; goto dup; + case OPCODE_dup_x2: wide = 1; index = 2; goto dup; + case OPCODE_dup2: wide = 2; index = 0; goto dup; + case OPCODE_dup2_x1: wide = 2; index = 1; goto dup; + case OPCODE_dup2_x2: wide = 2; index = 2; goto dup; + dup: + if (wide + index > stack_pointer) + VERIFICATION_ERROR ("stack underflow - dup* operation"); + type_stack_dup (wide, index); + wide = 0; + break; case OPCODE_pop: index = 1; goto pop; case OPCODE_pop2: index = 2; goto pop; pop: @@ -1133,7 +1137,7 @@ verify_jvm_instructions (jcf, byte_ops, length) case OPCODE_athrow: /* FIXME: athrow also empties the stack. */ - pop_type (throwable_type_node); + POP_TYPE (throwable_type_node, "missing throwable at athrow" ); INVALIDATE_PC; break; @@ -1152,7 +1156,7 @@ verify_jvm_instructions (jcf, byte_ops, length) { jint low, high; - pop_type (int_type_node); + POP_TYPE (int_type_node, "missing int for tableswitch"); while (PC%4) { if (byte_ops[PC++]) @@ -1175,7 +1179,7 @@ verify_jvm_instructions (jcf, byte_ops, length) { jint npairs, last = 0, not_registered = 1; - pop_type (int_type_node); + POP_TYPE (int_type_node, "missing int for lookupswitch"); while (PC%4) { if (byte_ops[PC++]) |