summaryrefslogtreecommitdiffstats
path: root/runtime/verifier
diff options
context:
space:
mode:
authorJeff Hao <jeffhao@google.com>2013-09-04 16:11:55 -0700
committerJeff Hao <jeffhao@google.com>2013-09-04 16:14:13 -0700
commitc642ec8987746a2a44b990bd5354306242d709da (patch)
treebc257f588bd2623eadb8b4af0b99df3096993c42 /runtime/verifier
parent8c6326c528aa785041f0d8c08e24c6b793ba5b6e (diff)
downloadandroid_art-c642ec8987746a2a44b990bd5354306242d709da.tar.gz
android_art-c642ec8987746a2a44b990bd5354306242d709da.tar.bz2
android_art-c642ec8987746a2a44b990bd5354306242d709da.zip
Fix verifier upcasting type after instance_of.
The verifier automatically changed the type of a register to be the checked type in an instance_of instruction, even if the checked type was the register type's superclass. This would loosen the type information of the register and cause problems later. Bug: 10614872 Change-Id: I67aa2c66be754d946e928b8a64431f193539b842
Diffstat (limited to 'runtime/verifier')
-rw-r--r--runtime/verifier/method_verifier.cc5
1 files changed, 4 insertions, 1 deletions
diff --git a/runtime/verifier/method_verifier.cc b/runtime/verifier/method_verifier.cc
index 34a0f73fdf..fa00c61017 100644
--- a/runtime/verifier/method_verifier.cc
+++ b/runtime/verifier/method_verifier.cc
@@ -1921,9 +1921,12 @@ bool MethodVerifier::CodeFlowVerifyInstruction(uint32_t* start_guess) {
(instance_of_inst->VRegA_22c() != instance_of_inst->VRegB_22c())) {
// Check that the we are not attempting conversion to interface types,
// which is not done because of the multiple inheritance implications.
+ // Also don't change the type if it would result in an upcast.
+ const RegType& orig_type = work_line_->GetRegisterType(instance_of_inst->VRegB_22c());
const RegType& cast_type = ResolveClassAndCheckAccess(instance_of_inst->VRegC_22c());
- if (!cast_type.IsUnresolvedTypes() && !cast_type.GetClass()->IsInterface()) {
+ if (!cast_type.IsUnresolvedTypes() && !cast_type.GetClass()->IsInterface() &&
+ !cast_type.IsAssignableFrom(orig_type)) {
RegisterLine* update_line = new RegisterLine(code_item_->registers_size_, this);
if (inst->Opcode() == Instruction::IF_EQZ) {
fallthrough_line.reset(update_line);