The bug was introduced in
b3830b82f4 and exposed by GCC when compiling
with -g (without -O2). Here's the thing:
if (expr->Iex.Binop.op == Iop_Add64) {
---> ULong disp = arg2->Iex.Const.con->Ico.U64;
if (arg2->tag == Iex_Const && ulong_fits_signed_20bit(disp)) {
h1 = s390_isel_int_expr(env, arg1);
This possibly segfaults when arg2 is not a constant.
Optimising GCC figures it can first check arg2->tag == Iex_Const
which is cheaper than disp = arg2->Iex.Const.con->Ico.U64;
Nice one.
Regtested with both default compiler flags and -g only.
}
/* Is this a match for "load address"? */
- if (expr->Iex.Binop.op == Iop_Add64) {
+ if (expr->Iex.Binop.op == Iop_Add64 && arg2->tag == Iex_Const) {
ULong disp = arg2->Iex.Const.con->Ico.U64;
- if (arg2->tag == Iex_Const && ulong_fits_signed_20bit(disp)) {
+ if (ulong_fits_signed_20bit(disp)) {
h1 = s390_isel_int_expr(env, arg1);
opnd.tag = S390_OPND_AMODE;
if (ulong_fits_unsigned_12bit(disp)) {