diff options
author | Andreas Gampe <agampe@google.com> | 2015-08-14 14:07:43 -0700 |
---|---|---|
committer | Andreas Gampe <agampe@google.com> | 2015-08-14 14:33:39 -0700 |
commit | eb9d1f79a79e3235f25889a25cdba465a7a0f7bf (patch) | |
tree | 1a25444c071b1105f1854acf4ec6751a89000caa /runtime | |
parent | e682a0250702c65a668e39eefdd1c49cfea5f388 (diff) | |
download | art-eb9d1f79a79e3235f25889a25cdba465a7a0f7bf.zip art-eb9d1f79a79e3235f25889a25cdba465a7a0f7bf.tar.gz art-eb9d1f79a79e3235f25889a25cdba465a7a0f7bf.tar.bz2 |
ART: Relax verifier aput checking
When checking on a null array, the cases of aput and aput-wide are
shared between integral and floating point types. Be careful to not
reject a valid program.
Bug: 21867457
Bug: 23201502
(cherry picked from commit 4bf4c78a6e8b7da7cf306e1dd17ff5a55d0c6c98)
Change-Id: I6c54a389c06e40a2dae00995aa16ff08a089e512
Diffstat (limited to 'runtime')
-rw-r--r-- | runtime/verifier/method_verifier.cc | 19 |
1 files changed, 18 insertions, 1 deletions
diff --git a/runtime/verifier/method_verifier.cc b/runtime/verifier/method_verifier.cc index 015e908..df9a6da 100644 --- a/runtime/verifier/method_verifier.cc +++ b/runtime/verifier/method_verifier.cc @@ -3828,7 +3828,24 @@ void MethodVerifier::VerifyAPut(const Instruction* inst, if (array_type.IsZero()) { // Null array type; this code path will fail at runtime. // Still check that the given value matches the instruction's type. - work_line_->VerifyRegisterType(this, inst->VRegA_23x(), insn_type); + // Note: this is, as usual, complicated by the fact the the instruction isn't fully typed + // and fits multiple register types. + const RegType* modified_reg_type = &insn_type; + if ((modified_reg_type == ®_types_.Integer()) || + (modified_reg_type == ®_types_.LongLo())) { + // May be integer or float | long or double. Overwrite insn_type accordingly. + const RegType& value_type = work_line_->GetRegisterType(this, inst->VRegA_23x()); + if (modified_reg_type == ®_types_.Integer()) { + if (&value_type == ®_types_.Float()) { + modified_reg_type = &value_type; + } + } else { + if (&value_type == ®_types_.DoubleLo()) { + modified_reg_type = &value_type; + } + } + } + work_line_->VerifyRegisterType(this, inst->VRegA_23x(), *modified_reg_type); } else if (!array_type.IsArrayTypes()) { Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "not array type " << array_type << " with aput"; } else { |