summaryrefslogtreecommitdiffstats
path: root/runtime/verifier
diff options
context:
space:
mode:
authorAndreas Gampe <agampe@google.com>2015-08-14 14:07:43 -0700
committerAndreas Gampe <agampe@google.com>2015-08-14 14:33:39 -0700
commiteb9d1f79a79e3235f25889a25cdba465a7a0f7bf (patch)
tree1a25444c071b1105f1854acf4ec6751a89000caa /runtime/verifier
parente682a0250702c65a668e39eefdd1c49cfea5f388 (diff)
downloadart-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/verifier')
-rw-r--r--runtime/verifier/method_verifier.cc19
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 == &reg_types_.Integer()) ||
+ (modified_reg_type == &reg_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 == &reg_types_.Integer()) {
+ if (&value_type == &reg_types_.Float()) {
+ modified_reg_type = &value_type;
+ }
+ } else {
+ if (&value_type == &reg_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 {