< prev index next >

src/cpu/aarch64/vm/c1_LIRGenerator_aarch64.cpp

Print this page
rev 11926 : 8166140: C1: Possible integer overflow in LIRGenerator::generate_address on several platforms
Reviewed-by:

*** 138,186 **** LIR_Address* LIRGenerator::generate_address(LIR_Opr base, LIR_Opr index, int shift, int disp, BasicType type) { assert(base->is_register(), "must be"); // accumulate fixed displacements if (index->is_constant()) { ! disp += index->as_constant_ptr()->as_jint() << shift; index = LIR_OprFact::illegalOpr; } if (index->is_register()) { // apply the shift and accumulate the displacement if (shift > 0) { LIR_Opr tmp = new_pointer_register(); __ shift_left(index, shift, tmp); index = tmp; } ! if (disp != 0) { LIR_Opr tmp = new_pointer_register(); ! if (Assembler::operand_valid_for_add_sub_immediate(disp)) { ! __ add(tmp, tmp, LIR_OprFact::intptrConst(disp)); index = tmp; } else { ! __ move(tmp, LIR_OprFact::intptrConst(disp)); __ add(tmp, index, tmp); index = tmp; } ! disp = 0; } ! } else if (disp != 0 && !Address::offset_ok_for_immed(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; } // at this point we either have base + index or base + displacement ! if (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); } } LIR_Address* LIRGenerator::emit_array_address(LIR_Opr array_opr, LIR_Opr index_opr, --- 138,187 ---- 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()) { ! large_disp += (intx)(index->as_constant_ptr()->as_jint()) << shift; index = LIR_OprFact::illegalOpr; } if (index->is_register()) { // apply the shift and accumulate the displacement if (shift > 0) { LIR_Opr tmp = new_pointer_register(); __ shift_left(index, shift, tmp); index = tmp; } ! if (large_disp != 0) { LIR_Opr tmp = new_pointer_register(); ! 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(large_disp)); __ add(tmp, index, tmp); index = tmp; } ! large_disp = 0; } ! } 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(large_disp), index); ! large_disp = 0; } // at this point we either have base + index or base + displacement ! if (large_disp == 0) { return new LIR_Address(base, index, type); } else { ! assert(Address::offset_ok_for_immed(large_disp, 0), "must be"); ! return new LIR_Address(base, large_disp, type); } } LIR_Address* LIRGenerator::emit_array_address(LIR_Opr array_opr, LIR_Opr index_opr,
< prev index next >