diff options
-rw-r--r-- | libjava/ChangeLog | 7 | ||||
-rw-r--r-- | libjava/verify.cc | 11 |
2 files changed, 15 insertions, 3 deletions
diff --git a/libjava/ChangeLog b/libjava/ChangeLog index ed3bafc..067b301 100644 --- a/libjava/ChangeLog +++ b/libjava/ChangeLog @@ -1,3 +1,10 @@ +2001-12-07 Tom Tromey <tromey@redhat.com> + + * verify.cc (_Jv_BytecodeVerifier::branch_prepass): Set start_PC + earlier, for error handling. + (_Jv_BytecodeVerifier::note_branch_target): Fixed branch target + check. + 2001-12-06 Tom Tromey <tromey@redhat.com> * verify.cc (_Jv_BytecodeVerifier::FLAG_JSR_TARGET): Removed. diff --git a/libjava/verify.cc b/libjava/verify.cc index 37935c4..b0206d1 100644 --- a/libjava/verify.cc +++ b/libjava/verify.cc @@ -1254,8 +1254,11 @@ private: void note_branch_target (int pc, bool is_jsr_target = false) { - if (pc <= PC && ! (flags[pc] & FLAG_INSN_START)) - verify_fail ("branch not to instruction start"); + // Don't check `pc <= PC', because we've advanced PC after + // fetching the target and we haven't yet checked the next + // instruction. + if (pc < PC && ! (flags[pc] & FLAG_INSN_START)) + verify_fail ("branch not to instruction start", start_PC); flags[pc] |= FLAG_BRANCH_TARGET; if (is_jsr_target) { @@ -1395,6 +1398,9 @@ private: PC = 0; while (PC < current_method->code_length) { + // Set `start_PC' early so that error checking can have the + // correct value. + start_PC = PC; flags[PC] |= FLAG_INSN_START; // If the previous instruction was a jsr, then the next @@ -1404,7 +1410,6 @@ private: note_branch_target (PC); last_was_jsr = false; - start_PC = PC; java_opcode opcode = (java_opcode) bytecode[PC++]; switch (opcode) { |