8166140: C1: Possible integer overflow in LIRGenerator::generate_address on several platforms
Reviewed-by: kvn
--- a/hotspot/src/cpu/aarch64/vm/c1_LIRGenerator_aarch64.cpp Mon Sep 26 08:51:36 2016 +0200
+++ b/hotspot/src/cpu/aarch64/vm/c1_LIRGenerator_aarch64.cpp Mon Sep 19 15:08:03 2016 +0200
@@ -140,10 +140,11 @@
LIR_Address* LIRGenerator::generate_address(LIR_Opr base, LIR_Opr index,
int shift, int disp, BasicType type) {
assert(base->is_register(), "must be");
+ intx large_disp = disp;
// accumulate fixed displacements
if (index->is_constant()) {
- disp += index->as_constant_ptr()->as_jint() << shift;
+ large_disp += (intx)(index->as_constant_ptr()->as_jint()) << shift;
index = LIR_OprFact::illegalOpr;
}
@@ -154,31 +155,31 @@
__ shift_left(index, shift, tmp);
index = tmp;
}
- if (disp != 0) {
+ if (large_disp != 0) {
LIR_Opr tmp = new_pointer_register();
- if (Assembler::operand_valid_for_add_sub_immediate(disp)) {
- __ add(tmp, tmp, LIR_OprFact::intptrConst(disp));
+ if (Assembler::operand_valid_for_add_sub_immediate(large_disp)) {
+ __ add(tmp, tmp, LIR_OprFact::intptrConst(large_disp));
index = tmp;
} else {
- __ move(tmp, LIR_OprFact::intptrConst(disp));
+ __ move(tmp, LIR_OprFact::intptrConst(large_disp));
__ add(tmp, index, tmp);
index = tmp;
}
- disp = 0;
+ large_disp = 0;
}
- } else if (disp != 0 && !Address::offset_ok_for_immed(disp, shift)) {
+ } else if (large_disp != 0 && !Address::offset_ok_for_immed(large_disp, shift)) {
// index is illegal so replace it with the displacement loaded into a register
index = new_pointer_register();
- __ move(LIR_OprFact::intptrConst(disp), index);
- disp = 0;
+ __ move(LIR_OprFact::intptrConst(large_disp), index);
+ large_disp = 0;
}
// at this point we either have base + index or base + displacement
- if (disp == 0) {
+ if (large_disp == 0) {
return new LIR_Address(base, index, type);
} else {
- assert(Address::offset_ok_for_immed(disp, 0), "must be");
- return new LIR_Address(base, disp, type);
+ assert(Address::offset_ok_for_immed(large_disp, 0), "must be");
+ return new LIR_Address(base, large_disp, type);
}
}
@@ -192,7 +193,7 @@
LIR_Address* addr;
if (index_opr->is_constant()) {
addr = new LIR_Address(array_opr,
- offset_in_bytes + index_opr->as_jint() * elem_size, type);
+ offset_in_bytes + (intx)(index_opr->as_jint()) * elem_size, type);
} else {
if (offset_in_bytes) {
LIR_Opr tmp = new_pointer_register();
--- a/hotspot/src/cpu/ppc/vm/c1_LIRGenerator_ppc.cpp Mon Sep 26 08:51:36 2016 +0200
+++ b/hotspot/src/cpu/ppc/vm/c1_LIRGenerator_ppc.cpp Mon Sep 19 15:08:03 2016 +0200
@@ -157,10 +157,11 @@
LIR_Address* LIRGenerator::generate_address(LIR_Opr base, LIR_Opr index,
int shift, int disp, BasicType type) {
assert(base->is_register(), "must be");
+ intx large_disp = disp;
// Accumulate fixed displacements.
if (index->is_constant()) {
- disp += index->as_constant_ptr()->as_jint() << shift;
+ large_disp += (intx)(index->as_constant_ptr()->as_jint()) << shift;
index = LIR_OprFact::illegalOpr;
}
@@ -171,31 +172,31 @@
__ shift_left(index, shift, tmp);
index = tmp;
}
- if (disp != 0) {
+ if (large_disp != 0) {
LIR_Opr tmp = new_pointer_register();
- if (Assembler::is_simm16(disp)) {
- __ add(index, LIR_OprFact::intptrConst(disp), tmp);
+ if (Assembler::is_simm16(large_disp)) {
+ __ add(index, LIR_OprFact::intptrConst(large_disp), tmp);
index = tmp;
} else {
- __ move(LIR_OprFact::intptrConst(disp), tmp);
+ __ move(LIR_OprFact::intptrConst(large_disp), tmp);
__ add(tmp, index, tmp);
index = tmp;
}
- disp = 0;
+ large_disp = 0;
}
- } else if (!Assembler::is_simm16(disp)) {
+ } else if (!Assembler::is_simm16(large_disp)) {
// Index is illegal so replace it with the displacement loaded into a register.
index = new_pointer_register();
- __ move(LIR_OprFact::intptrConst(disp), index);
- disp = 0;
+ __ move(LIR_OprFact::intptrConst(large_disp), index);
+ large_disp = 0;
}
// At this point we either have base + index or base + displacement.
- if (disp == 0) {
+ if (large_disp == 0) {
return new LIR_Address(base, index, type);
} else {
- assert(Assembler::is_simm16(disp), "must be");
- return new LIR_Address(base, disp, type);
+ assert(Assembler::is_simm16(large_disp), "must be");
+ return new LIR_Address(base, large_disp, type);
}
}
@@ -206,11 +207,11 @@
int shift = exact_log2(elem_size);
LIR_Opr base_opr;
- int offset = arrayOopDesc::base_offset_in_bytes(type);
+ intx offset = arrayOopDesc::base_offset_in_bytes(type);
if (index_opr->is_constant()) {
- int i = index_opr->as_constant_ptr()->as_jint();
- int array_offset = i * elem_size;
+ intx i = index_opr->as_constant_ptr()->as_jint();
+ intx array_offset = i * elem_size;
if (Assembler::is_simm16(array_offset + offset)) {
base_opr = array_opr;
offset = array_offset + offset;
--- a/hotspot/src/cpu/sparc/vm/c1_LIRGenerator_sparc.cpp Mon Sep 26 08:51:36 2016 +0200
+++ b/hotspot/src/cpu/sparc/vm/c1_LIRGenerator_sparc.cpp Mon Sep 19 15:08:03 2016 +0200
@@ -147,10 +147,11 @@
LIR_Address* LIRGenerator::generate_address(LIR_Opr base, LIR_Opr index,
int shift, int disp, BasicType type) {
assert(base->is_register(), "must be");
+ intx large_disp = disp;
// accumulate fixed displacements
if (index->is_constant()) {
- disp += index->as_constant_ptr()->as_jint() << shift;
+ large_disp += (intx)(index->as_constant_ptr()->as_jint()) << shift;
index = LIR_OprFact::illegalOpr;
}
@@ -161,31 +162,31 @@
__ shift_left(index, shift, tmp);
index = tmp;
}
- if (disp != 0) {
+ if (large_disp != 0) {
LIR_Opr tmp = new_pointer_register();
- if (Assembler::is_simm13(disp)) {
- __ add(tmp, LIR_OprFact::intptrConst(disp), tmp);
+ if (Assembler::is_simm13(large_disp)) {
+ __ add(tmp, LIR_OprFact::intptrConst(large_disp), tmp);
index = tmp;
} else {
- __ move(LIR_OprFact::intptrConst(disp), tmp);
+ __ move(LIR_OprFact::intptrConst(large_disp), tmp);
__ add(tmp, index, tmp);
index = tmp;
}
- disp = 0;
+ large_disp = 0;
}
- } else if (disp != 0 && !Assembler::is_simm13(disp)) {
+ } else if (large_disp != 0 && !Assembler::is_simm13(large_disp)) {
// index is illegal so replace it with the displacement loaded into a register
index = new_pointer_register();
- __ move(LIR_OprFact::intptrConst(disp), index);
- disp = 0;
+ __ move(LIR_OprFact::intptrConst(large_disp), index);
+ large_disp = 0;
}
// at this point we either have base + index or base + displacement
- if (disp == 0) {
+ if (large_disp == 0) {
return new LIR_Address(base, index, type);
} else {
- assert(Assembler::is_simm13(disp), "must be");
- return new LIR_Address(base, disp, type);
+ assert(Assembler::is_simm13(large_disp), "must be");
+ return new LIR_Address(base, large_disp, type);
}
}
@@ -196,11 +197,11 @@
int shift = exact_log2(elem_size);
LIR_Opr base_opr;
- int offset = arrayOopDesc::base_offset_in_bytes(type);
+ intx offset = arrayOopDesc::base_offset_in_bytes(type);
if (index_opr->is_constant()) {
- int i = index_opr->as_constant_ptr()->as_jint();
- int array_offset = i * elem_size;
+ intx i = index_opr->as_constant_ptr()->as_jint();
+ intx array_offset = i * elem_size;
if (Assembler::is_simm13(array_offset + offset)) {
base_opr = array_opr;
offset = array_offset + offset;
--- a/hotspot/src/cpu/x86/vm/c1_LIRGenerator_x86.cpp Mon Sep 26 08:51:36 2016 +0200
+++ b/hotspot/src/cpu/x86/vm/c1_LIRGenerator_x86.cpp Mon Sep 19 15:08:03 2016 +0200
@@ -152,7 +152,7 @@
assert(base->is_register(), "must be");
if (index->is_constant()) {
return new LIR_Address(base,
- (index->as_constant_ptr()->as_jint() << shift) + disp,
+ ((intx)(index->as_constant_ptr()->as_jint()) << shift) + disp,
type);
} else {
return new LIR_Address(base, index, (LIR_Address::Scale)shift, disp, type);
@@ -168,7 +168,7 @@
if (index_opr->is_constant()) {
int elem_size = type2aelembytes(type);
addr = new LIR_Address(array_opr,
- offset_in_bytes + index_opr->as_jint() * elem_size, type);
+ offset_in_bytes + (intx)(index_opr->as_jint()) * elem_size, type);
} else {
#ifdef _LP64
if (index_opr->type() == T_INT) {