diff options
-rw-r--r-- | compiler/dex/quick/arm/utility_arm.cc | 16 | ||||
-rw-r--r-- | compiler/dex/quick/gen_common.cc | 10 | ||||
-rw-r--r-- | test/122-npe/src/Main.java | 139 |
3 files changed, 150 insertions, 15 deletions
diff --git a/compiler/dex/quick/arm/utility_arm.cc b/compiler/dex/quick/arm/utility_arm.cc index 36d065f0db..73b68a5961 100644 --- a/compiler/dex/quick/arm/utility_arm.cc +++ b/compiler/dex/quick/arm/utility_arm.cc @@ -1040,9 +1040,8 @@ LIR* ArmMir2Lir::LoadBaseDisp(RegStorage r_base, int displacement, RegStorage r_ // Use LDREXD for the atomic load. (Expect displacement > 0, don't optimize for == 0.) RegStorage r_ptr = AllocTemp(); OpRegRegImm(kOpAdd, r_ptr, r_base, displacement); - LIR* lir = NewLIR3(kThumb2Ldrexd, r_dest.GetLowReg(), r_dest.GetHighReg(), r_ptr.GetReg()); + load = NewLIR3(kThumb2Ldrexd, r_dest.GetLowReg(), r_dest.GetHighReg(), r_ptr.GetReg()); FreeTemp(r_ptr); - return lir; } else { load = LoadBaseDispBody(r_base, displacement, r_dest, size); } @@ -1174,7 +1173,7 @@ LIR* ArmMir2Lir::StoreBaseDisp(RegStorage r_base, int displacement, RegStorage r GenMemBarrier(kAnyStore); } - LIR* store; + LIR* null_ck_insn; if (is_volatile == kVolatile && (size == k64 || size == kDouble) && !cu_->compiler_driver->GetInstructionSetFeatures()-> AsArmInstructionSetFeatures()->HasAtomicLdrdAndStrd()) { @@ -1191,17 +1190,16 @@ LIR* ArmMir2Lir::StoreBaseDisp(RegStorage r_base, int displacement, RegStorage r RegStorage r_temp = AllocTemp(); RegStorage r_temp_high = AllocTemp(false); // We may not have another temp. if (r_temp_high.Valid()) { - NewLIR3(kThumb2Ldrexd, r_temp.GetReg(), r_temp_high.GetReg(), r_ptr.GetReg()); + null_ck_insn = NewLIR3(kThumb2Ldrexd, r_temp.GetReg(), r_temp_high.GetReg(), r_ptr.GetReg()); FreeTemp(r_temp_high); FreeTemp(r_temp); } else { // If we don't have another temp, clobber r_ptr in LDREXD and reload it. - NewLIR3(kThumb2Ldrexd, r_temp.GetReg(), r_ptr.GetReg(), r_ptr.GetReg()); + null_ck_insn = NewLIR3(kThumb2Ldrexd, r_temp.GetReg(), r_ptr.GetReg(), r_ptr.GetReg()); FreeTemp(r_temp); // May need the temp for kOpAdd. OpRegRegImm(kOpAdd, r_ptr, r_base, displacement); } - store = NewLIR4(kThumb2Strexd, r_temp.GetReg(), r_src.GetLowReg(), r_src.GetHighReg(), - r_ptr.GetReg()); + NewLIR4(kThumb2Strexd, r_temp.GetReg(), r_src.GetLowReg(), r_src.GetHighReg(), r_ptr.GetReg()); OpCmpImmBranch(kCondNe, r_temp, 0, fail_target); FreeTemp(r_ptr); } else { @@ -1210,7 +1208,7 @@ LIR* ArmMir2Lir::StoreBaseDisp(RegStorage r_base, int displacement, RegStorage r size = k32; } - store = StoreBaseDispBody(r_base, displacement, r_src, size); + null_ck_insn = StoreBaseDispBody(r_base, displacement, r_src, size); } if (UNLIKELY(is_volatile == kVolatile)) { @@ -1219,7 +1217,7 @@ LIR* ArmMir2Lir::StoreBaseDisp(RegStorage r_base, int displacement, RegStorage r GenMemBarrier(kAnyAny); } - return store; + return null_ck_insn; } LIR* ArmMir2Lir::OpFpRegCopy(RegStorage r_dest, RegStorage r_src) { diff --git a/compiler/dex/quick/gen_common.cc b/compiler/dex/quick/gen_common.cc index 3733507a50..d2b32b585b 100644 --- a/compiler/dex/quick/gen_common.cc +++ b/compiler/dex/quick/gen_common.cc @@ -939,15 +939,15 @@ void Mir2Lir::GenIPut(MIR* mir, int opt_flags, OpSize size, } GenNullCheck(rl_obj.reg, opt_flags); int field_offset = field_info.FieldOffset().Int32Value(); - LIR* store; + LIR* null_ck_insn; if (IsRef(size)) { - store = StoreRefDisp(rl_obj.reg, field_offset, rl_src.reg, field_info.IsVolatile() ? + null_ck_insn = StoreRefDisp(rl_obj.reg, field_offset, rl_src.reg, field_info.IsVolatile() ? kVolatile : kNotVolatile); } else { - store = StoreBaseDisp(rl_obj.reg, field_offset, rl_src.reg, size, - field_info.IsVolatile() ? kVolatile : kNotVolatile); + null_ck_insn = StoreBaseDisp(rl_obj.reg, field_offset, rl_src.reg, size, + field_info.IsVolatile() ? kVolatile : kNotVolatile); } - MarkPossibleNullPointerExceptionAfter(opt_flags, store); + MarkPossibleNullPointerExceptionAfter(opt_flags, null_ck_insn); if (IsRef(size) && !mir_graph_->IsConstantNullRef(rl_src)) { MarkGCCard(opt_flags, rl_src.reg, rl_obj.reg); } diff --git a/test/122-npe/src/Main.java b/test/122-npe/src/Main.java index 2fdcb9cab0..8f6820573f 100644 --- a/test/122-npe/src/Main.java +++ b/test/122-npe/src/Main.java @@ -191,6 +191,132 @@ public class Main { check(npe, thisLine += 7); try { + ((Value) null).volatileObjectField.toString(); + } catch (NullPointerException e) { + npe = e; + } + check(npe, thisLine += 7); + + try { + ((Value) null).volatileObjectField = "Fisk"; + } catch (NullPointerException e) { + npe = e; + } + check(npe, thisLine += 7); + + try { + useInt(((Value) null).volatileIntField); + } catch (NullPointerException e) { + npe = e; + } + check(npe, thisLine += 7); + + try { + ((Value) null).volatileIntField = 42; + } catch (NullPointerException e) { + npe = e; + } + check(npe, thisLine += 7); + + try { + useFloat(((Value) null).volatileFloatField); + } catch (NullPointerException e) { + npe = e; + } + check(npe, thisLine += 7); + + try { + ((Value) null).volatileFloatField = 42.0F; + } catch (NullPointerException e) { + npe = e; + } + check(npe, thisLine += 7); + + try { + useLong(((Value) null).volatileLongField); + } catch (NullPointerException e) { + npe = e; + } + check(npe, thisLine += 7); + + try { + ((Value) null).volatileLongField = 42L; + } catch (NullPointerException e) { + npe = e; + } + check(npe, thisLine += 7); + + try { + useDouble(((Value) null).volatileDoubleField); + } catch (NullPointerException e) { + npe = e; + } + check(npe, thisLine += 7); + + try { + ((Value) null).volatileDoubleField = 42.0d; + } catch (NullPointerException e) { + npe = e; + } + check(npe, thisLine += 7); + + try { + useInt(((Value) null).volatileByteField); + } catch (NullPointerException e) { + npe = e; + } + check(npe, thisLine += 7); + + try { + ((Value) null).volatileByteField = 42; + } catch (NullPointerException e) { + npe = e; + } + check(npe, thisLine += 7); + + try { + if (((Value) null).volatileBooleanField) { } + } catch (NullPointerException e) { + npe = e; + } + check(npe, thisLine += 7); + + try { + ((Value) null).volatileBooleanField = true; + } catch (NullPointerException e) { + npe = e; + } + check(npe, thisLine += 7); + + try { + useInt(((Value) null).volatileCharField); + } catch (NullPointerException e) { + npe = e; + } + check(npe, thisLine += 7); + + try { + ((Value) null).volatileCharField = '\u0042'; + } catch (NullPointerException e) { + npe = e; + } + check(npe, thisLine += 7); + + try { + useInt(((Value) null).volatileShortField); + } catch (NullPointerException e) { + npe = e; + } + check(npe, thisLine += 7); + + try { + ((Value) null).volatileShortField = 42; + } catch (NullPointerException e) { + npe = e; + } + check(npe, thisLine += 7); + + try { ((Object[]) null)[0].toString(); } catch (NullPointerException e) { npe = e; @@ -477,11 +603,22 @@ public class Main { static class Value { Object objectField; int intField; - float floatField; long longField; + float floatField; + long longField; double doubleField; byte byteField; boolean booleanField; char charField; short shortField; + + volatile Object volatileObjectField; + volatile int volatileIntField; + volatile float volatileFloatField; + volatile long volatileLongField; + volatile double volatileDoubleField; + volatile byte volatileByteField; + volatile boolean volatileBooleanField; + volatile char volatileCharField; + volatile short volatileShortField; } } |