== TREE_INT_CST_LOW (op1))
{
tree ntype = TYPE_UNSIGNED (type)
- ? lang_hooks.types.signed_type (type)
+ ? signed_type_for (type)
: unsigned_type_for (type);
tree temp = fold_convert (ntype, TREE_OPERAND (t, 0));
temp = fold_build2 (RSHIFT_EXPR, ntype, temp, op1);
else if (type == bitsizetype)
ctype = sbitsizetype;
else
- ctype = lang_hooks.types.signed_type (type);
+ ctype = signed_type_for (type);
/* If either operand is not a constant, do the conversions to the signed
type and subtract. The hardware will do the right thing with any
/* Make sure shorter operand is extended the right way
to match the longer operand. */
- primarg1 = fold_convert (get_signed_or_unsigned_type
+ primarg1 = fold_convert (signed_or_unsigned_type_for
(unsignedp1, TREE_TYPE (primarg1)), primarg1);
if (operand_equal_p (arg0, fold_convert (type, primarg1), 0))
unsigned int precision = TYPE_PRECISION (type);
tree tmask;
- tmask = build_int_cst_type (lang_hooks.types.signed_type (type), -1);
+ tmask = build_int_cst_type (signed_type_for (type), -1);
return
tree_int_cst_equal (mask,
{
if (TYPE_UNSIGNED (etype))
{
- etype = lang_hooks.types.signed_type (etype);
+ etype = signed_type_for (etype);
exp = fold_convert (etype, exp);
}
return fold_build2 (GT_EXPR, type, exp,
value = const_binop (MINUS_EXPR, high, low, 0);
+
+ if (POINTER_TYPE_P (etype))
+ {
+ if (value != 0 && !TREE_OVERFLOW (value))
+ {
+ low = fold_convert (sizetype, low);
+ low = fold_build1 (NEGATE_EXPR, sizetype, low);
+ return build_range_check (type,
+ fold_build2 (POINTER_PLUS_EXPR, etype, exp, low),
+ 1, build_int_cst (etype, 0), value);
+ }
+ return 0;
+ }
+
if (value != 0 && !TREE_OVERFLOW (value))
return build_range_check (type,
fold_build2 (MINUS_EXPR, etype, exp, low),
case GE_EXPR:
case GT_EXPR:
if (TYPE_UNSIGNED (TREE_TYPE (arg1)))
- arg1 = fold_convert (lang_hooks.types.signed_type
+ arg1 = fold_convert (signed_type_for
(TREE_TYPE (arg1)), arg1);
tem = fold_build1 (ABS_EXPR, TREE_TYPE (arg1), arg1);
return pedantic_non_lvalue (fold_convert (type, tem));
case LE_EXPR:
case LT_EXPR:
if (TYPE_UNSIGNED (TREE_TYPE (arg1)))
- arg1 = fold_convert (lang_hooks.types.signed_type
+ arg1 = fold_convert (signed_type_for
(TREE_TYPE (arg1)), arg1);
tem = fold_build1 (ABS_EXPR, TREE_TYPE (arg1), arg1);
return negate_expr (fold_convert (type, tem));
zero or one, and the conversion to a signed type can never overflow.
We could get an overflow if this conversion is done anywhere else. */
if (TYPE_UNSIGNED (type))
- temp = fold_convert (lang_hooks.types.signed_type (type), temp);
+ temp = fold_convert (signed_type_for (type), temp);
temp = const_binop (LSHIFT_EXPR, temp, size_int (modesize - 1), 0);
temp = const_binop (RSHIFT_EXPR, temp, size_int (modesize - p - 1), 0);
must avoid building ABS_EXPR itself as unsigned. */
if (TYPE_UNSIGNED (ctype) && !TYPE_UNSIGNED (type))
{
- tree cstype = (*lang_hooks.types.signed_type) (ctype);
+ tree cstype = (*signed_type_for) (ctype);
if ((t1 = extract_muldiv (op0, c, code, cstype, strict_overflow_p))
!= 0)
{
offset is set to NULL_TREE. Base will be canonicalized to
something you can get the element type from using
TREE_TYPE (TREE_TYPE (base)). Offset will be the offset
- in bytes to the base. */
+ in bytes to the base in sizetype. */
static bool
extract_array_ref (tree expr, tree *base, tree *offset)
/* One canonical form is a PLUS_EXPR with the first
argument being an ADDR_EXPR with a possible NOP_EXPR
attached. */
- if (TREE_CODE (expr) == PLUS_EXPR)
+ if (TREE_CODE (expr) == POINTER_PLUS_EXPR)
{
tree op0 = TREE_OPERAND (expr, 0);
tree inner_base, dummy1;
/* Strip NOP_EXPRs here because the C frontends and/or
- folders present us (int *)&x.a + 4B possibly. */
+ folders present us (int *)&x.a p+ 4 possibly. */
STRIP_NOPS (op0);
if (extract_array_ref (op0, &inner_base, &dummy1))
{
*base = inner_base;
- if (dummy1 == NULL_TREE)
- *offset = TREE_OPERAND (expr, 1);
- else
- *offset = fold_build2 (PLUS_EXPR, TREE_TYPE (expr),
- dummy1, TREE_OPERAND (expr, 1));
+ *offset = fold_convert (sizetype, TREE_OPERAND (expr, 1));
+ if (dummy1 != NULL_TREE)
+ *offset = fold_build2 (PLUS_EXPR, sizetype,
+ dummy1, *offset);
return true;
}
}
*base = TREE_OPERAND (op0, 0);
*offset = fold_build2 (MULT_EXPR, TREE_TYPE (idx), idx,
array_ref_element_size (op0));
+ *offset = fold_convert (sizetype, *offset);
}
else
{
&& TYPE_PRECISION (TREE_TYPE (arg00))
== GET_MODE_BITSIZE (TYPE_MODE (TREE_TYPE (arg00))))
{
- tree stype = lang_hooks.types.signed_type (TREE_TYPE (arg00));
+ tree stype = signed_type_for (TREE_TYPE (arg00));
return fold_build2 (code == EQ_EXPR ? GE_EXPR : LT_EXPR,
result_type, fold_convert (stype, arg00),
build_int_cst (stype, 0));
return fold_build2 (code, type, arg0_inner, arg1);
}
-/* Tries to replace &a[idx] CODE s * delta with &a[idx CODE delta], if s is
+/* Tries to replace &a[idx] p+ s * delta with &a[idx + delta], if s is
step of the array. Reconstructs s and delta in the case of s * delta
being an integer constant (and thus already folded).
ADDR is the address. MULT is the multiplicative expression.
NULL_TREE is returned. */
static tree
-try_move_mult_to_index (enum tree_code code, tree addr, tree op1)
+try_move_mult_to_index (tree addr, tree op1)
{
tree s, delta, step;
tree ref = TREE_OPERAND (addr, 0), pref;
tree itype;
bool mdim = false;
+ /* Strip the nops that might be added when converting op1 to sizetype. */
+ STRIP_NOPS (op1);
+
/* Canonicalize op1 into a possibly non-constant delta
and an INTEGER_CST s. */
if (TREE_CODE (op1) == MULT_EXPR)
|| TREE_CODE (TYPE_MAX_VALUE (itype)) != INTEGER_CST)
continue;
- tmp = fold_binary (code, itype,
+ tmp = fold_binary (PLUS_EXPR, itype,
fold_convert (itype,
TREE_OPERAND (ref, 1)),
fold_convert (itype, delta));
pos = TREE_OPERAND (pos, 0);
}
- TREE_OPERAND (pos, 1) = fold_build2 (code, itype,
+ TREE_OPERAND (pos, 1) = fold_build2 (PLUS_EXPR, itype,
fold_convert (itype,
TREE_OPERAND (pos, 1)),
fold_convert (itype, delta));
if (TREE_TYPE (a1) != typea)
return NULL_TREE;
- diff = fold_build2 (MINUS_EXPR, typea, a1, a);
- if (!integer_onep (diff))
- return NULL_TREE;
+ if (POINTER_TYPE_P (typea))
+ {
+ /* Convert the pointer types into integer before taking the difference. */
+ tree ta = fold_convert (ssizetype, a);
+ tree ta1 = fold_convert (ssizetype, a1);
+ diff = fold_binary (MINUS_EXPR, ssizetype, ta1, ta);
+ }
+ else
+ diff = fold_binary (MINUS_EXPR, typea, a1, a);
+
+ if (!diff || !integer_onep (diff))
+ return NULL_TREE;
return fold_build2 (GE_EXPR, type, a, y);
}
return native_interpret_expr (type, buffer, len);
}
+/* Build an expression for the address of T. Folds away INDIRECT_REF
+ to avoid confusing the gimplify process. When IN_FOLD is true
+ avoid modifications of T. */
+
+static tree
+build_fold_addr_expr_with_type_1 (tree t, tree ptrtype, bool in_fold)
+{
+ /* The size of the object is not relevant when talking about its address. */
+ if (TREE_CODE (t) == WITH_SIZE_EXPR)
+ t = TREE_OPERAND (t, 0);
+
+ /* Note: doesn't apply to ALIGN_INDIRECT_REF */
+ if (TREE_CODE (t) == INDIRECT_REF
+ || TREE_CODE (t) == MISALIGNED_INDIRECT_REF)
+ {
+ t = TREE_OPERAND (t, 0);
+
+ if (TREE_TYPE (t) != ptrtype)
+ t = build1 (NOP_EXPR, ptrtype, t);
+ }
+ else if (!in_fold)
+ {
+ tree base = t;
+
+ while (handled_component_p (base))
+ base = TREE_OPERAND (base, 0);
+
+ if (DECL_P (base))
+ TREE_ADDRESSABLE (base) = 1;
+
+ t = build1 (ADDR_EXPR, ptrtype, t);
+ }
+ else
+ t = build1 (ADDR_EXPR, ptrtype, t);
+
+ return t;
+}
+
+/* Build an expression for the address of T with type PTRTYPE. This
+ function modifies the input parameter 'T' by sometimes setting the
+ TREE_ADDRESSABLE flag. */
+
+tree
+build_fold_addr_expr_with_type (tree t, tree ptrtype)
+{
+ return build_fold_addr_expr_with_type_1 (t, ptrtype, false);
+}
+
+/* Build an expression for the address of T. This function modifies
+ the input parameter 'T' by sometimes setting the TREE_ADDRESSABLE
+ flag. When called from fold functions, use fold_addr_expr instead. */
+
+tree
+build_fold_addr_expr (tree t)
+{
+ return build_fold_addr_expr_with_type_1 (t,
+ build_pointer_type (TREE_TYPE (t)),
+ false);
+}
+
+/* Same as build_fold_addr_expr, builds an expression for the address
+ of T, but avoids touching the input node 't'. Fold functions
+ should use this version. */
+
+static tree
+fold_addr_expr (tree t)
+{
+ tree ptrtype = build_pointer_type (TREE_TYPE (t));
+
+ return build_fold_addr_expr_with_type_1 (t, ptrtype, true);
+}
/* Fold a unary expression of code CODE and type TYPE with operand
OP0. Return the folded expression if folding is successful.
if (! offset && bitpos == 0
&& TYPE_MAIN_VARIANT (TREE_TYPE (type))
== TYPE_MAIN_VARIANT (TREE_TYPE (base)))
- return fold_convert (type, build_fold_addr_expr (base));
+ return fold_convert (type, fold_addr_expr (base));
}
if ((TREE_CODE (op0) == MODIFY_EXPR
}
}
- /* Convert (T1)(X op Y) into ((T1)X op (T1)Y), for pointer type,
+ /* Convert (T1)(X p+ Y) into ((T1)X p+ Y), for pointer type,
when one of the new casts will fold away. Conservatively we assume
- that this happens when X or Y is NOP_EXPR or Y is INTEGER_CST. */
- if (POINTER_TYPE_P (type) && POINTER_TYPE_P (TREE_TYPE (arg0))
- && BINARY_CLASS_P (arg0)
+ that this happens when X or Y is NOP_EXPR or Y is INTEGER_CST. */
+ if (POINTER_TYPE_P (type)
+ && TREE_CODE (arg0) == POINTER_PLUS_EXPR
&& (TREE_CODE (TREE_OPERAND (arg0, 1)) == INTEGER_CST
|| TREE_CODE (TREE_OPERAND (arg0, 0)) == NOP_EXPR
|| TREE_CODE (TREE_OPERAND (arg0, 1)) == NOP_EXPR))
tree arg01 = TREE_OPERAND (arg0, 1);
return fold_build2 (TREE_CODE (arg0), type, fold_convert (type, arg00),
- fold_convert (type, arg01));
+ fold_convert (sizetype, arg01));
}
/* Convert (T1)(~(T2)X) into ~(T1)X if T1 and T2 are integral types
tree op0 = TREE_OPERAND (cref0, 0);
tree op1 = TREE_OPERAND (cref1, 0);
return fold_build2 (code, type,
- build_fold_addr_expr (op0),
- build_fold_addr_expr (op1));
+ fold_addr_expr (op0),
+ fold_addr_expr (op1));
}
}
switch (code)
{
+ case POINTER_PLUS_EXPR:
+ /* 0 +p index -> (type)index */
+ if (integer_zerop (arg0))
+ return non_lvalue (fold_convert (type, arg1));
+
+ /* PTR +p 0 -> PTR */
+ if (integer_zerop (arg1))
+ return non_lvalue (fold_convert (type, arg0));
+
+ /* INT +p INT -> (PTR)(INT + INT). Stripping types allows for this. */
+ if (INTEGRAL_TYPE_P (TREE_TYPE (arg1))
+ && INTEGRAL_TYPE_P (TREE_TYPE (arg0)))
+ return fold_convert (type, fold_build2 (PLUS_EXPR, sizetype,
+ fold_convert (sizetype, arg1),
+ fold_convert (sizetype, arg0)));
+
+ /* index +p PTR -> PTR +p index */
+ if (POINTER_TYPE_P (TREE_TYPE (arg1))
+ && INTEGRAL_TYPE_P (TREE_TYPE (arg0)))
+ return fold_build2 (POINTER_PLUS_EXPR, type,
+ fold_convert (type, arg1), fold_convert (sizetype, arg0));
+
+ /* (PTR +p B) +p A -> PTR +p (B + A) */
+ if (TREE_CODE (arg0) == POINTER_PLUS_EXPR)
+ {
+ tree inner;
+ tree arg01 = fold_convert (sizetype, TREE_OPERAND (arg0, 1));
+ tree arg00 = TREE_OPERAND (arg0, 0);
+ inner = fold_build2 (PLUS_EXPR, sizetype, arg01, fold_convert (sizetype, arg1));
+ return fold_build2 (POINTER_PLUS_EXPR, type, arg00, inner);
+ }
+
+ /* PTR_CST +p CST -> CST1 */
+ if (TREE_CODE (arg0) == INTEGER_CST && TREE_CODE (arg1) == INTEGER_CST)
+ return fold_build2 (PLUS_EXPR, type, arg0, fold_convert (type, arg1));
+
+ /* Try replacing &a[i1] +p c * i2 with &a[i1 + i2], if c is step
+ of the array. Loop optimizer sometimes produce this type of
+ expressions. */
+ if (TREE_CODE (arg0) == ADDR_EXPR)
+ {
+ tem = try_move_mult_to_index (arg0, fold_convert (sizetype, arg1));
+ if (tem)
+ return fold_convert (type, tem);
+ }
+
+ return NULL_TREE;
case PLUS_EXPR:
+ /* PTR + INT -> (INT)(PTR p+ INT) */
+ if (POINTER_TYPE_P (TREE_TYPE (arg0))
+ && INTEGRAL_TYPE_P (TREE_TYPE (arg1)))
+ return fold_convert (type, fold_build2 (POINTER_PLUS_EXPR,
+ TREE_TYPE (arg0),
+ arg0,
+ fold_convert (sizetype, arg1)));
+ /* INT + PTR -> (INT)(PTR p+ INT) */
+ if (POINTER_TYPE_P (TREE_TYPE (arg1))
+ && INTEGRAL_TYPE_P (TREE_TYPE (arg0)))
+ return fold_convert (type, fold_build2 (POINTER_PLUS_EXPR,
+ TREE_TYPE (arg1),
+ arg1,
+ fold_convert (sizetype, arg0)));
/* A + (-B) -> A - B */
if (TREE_CODE (arg1) == NEGATE_EXPR)
return fold_build2 (MINUS_EXPR, type,
fold_convert (type,
parg1)));
}
-
- /* Try replacing &a[i1] + c * i2 with &a[i1 + i2], if c is step
- of the array. Loop optimizer sometimes produce this type of
- expressions. */
- if (TREE_CODE (arg0) == ADDR_EXPR)
- {
- tem = try_move_mult_to_index (PLUS_EXPR, arg0, arg1);
- if (tem)
- return fold_convert (type, tem);
- }
- else if (TREE_CODE (arg1) == ADDR_EXPR)
- {
- tem = try_move_mult_to_index (PLUS_EXPR, arg1, arg0);
- if (tem)
- return fold_convert (type, tem);
- }
}
else
{
return NULL_TREE;
case MINUS_EXPR:
+ /* Pointer simplifications for subtraction, simple reassociations. */
+ if (POINTER_TYPE_P (TREE_TYPE (arg1)) && POINTER_TYPE_P (TREE_TYPE (arg0)))
+ {
+ /* (PTR0 p+ A) - (PTR1 p+ B) -> (PTR0 - PTR1) + (A - B) */
+ if (TREE_CODE (arg0) == POINTER_PLUS_EXPR
+ && TREE_CODE (arg1) == POINTER_PLUS_EXPR)
+ {
+ tree arg00 = fold_convert (type, TREE_OPERAND (arg0, 0));
+ tree arg01 = fold_convert (type, TREE_OPERAND (arg0, 1));
+ tree arg10 = fold_convert (type, TREE_OPERAND (arg1, 0));
+ tree arg11 = fold_convert (type, TREE_OPERAND (arg1, 1));
+ return fold_build2 (PLUS_EXPR, type,
+ fold_build2 (MINUS_EXPR, type, arg00, arg10),
+ fold_build2 (MINUS_EXPR, type, arg01, arg11));
+ }
+ /* (PTR0 p+ A) - PTR1 -> (PTR0 - PTR1) + A, assuming PTR0 - PTR1 simplifies. */
+ else if (TREE_CODE (arg0) == POINTER_PLUS_EXPR)
+ {
+ tree arg00 = fold_convert (type, TREE_OPERAND (arg0, 0));
+ tree arg01 = fold_convert (type, TREE_OPERAND (arg0, 1));
+ tree tmp = fold_binary (MINUS_EXPR, type, arg00, fold_convert (type, arg1));
+ if (tmp)
+ return fold_build2 (PLUS_EXPR, type, tmp, arg01);
+ }
+ }
/* A - (-B) -> A + B */
if (TREE_CODE (arg1) == NEGATE_EXPR)
return fold_build2 (PLUS_EXPR, type, arg0, TREE_OPERAND (arg1, 0));
Also note that operand_equal_p is always false if an operand
is volatile. */
- if ((! FLOAT_TYPE_P (type) || flag_unsafe_math_optimizations)
+ if ((! FLOAT_TYPE_P (type)
+ || (flag_unsafe_math_optimizations
+ && !HONOR_NANS (TYPE_MODE (type))
+ && !HONOR_INFINITIES (TYPE_MODE (type))))
&& operand_equal_p (arg0, arg1, 0))
return fold_convert (type, integer_zero_node);
}
}
- /* Try replacing &a[i1] - c * i2 with &a[i1 - i2], if c is step
- of the array. Loop optimizer sometimes produce this type of
- expressions. */
- if (TREE_CODE (arg0) == ADDR_EXPR)
- {
- tem = try_move_mult_to_index (MINUS_EXPR, arg0, arg1);
- if (tem)
- return fold_convert (type, tem);
- }
-
if (flag_unsafe_math_optimizations
&& (TREE_CODE (arg0) == RDIV_EXPR || TREE_CODE (arg0) == MULT_EXPR)
&& (TREE_CODE (arg1) == RDIV_EXPR || TREE_CODE (arg1) == MULT_EXPR)
}
}
- /* Optimize a/sqrt(b/c) into a*sqrt(c/b). */
- if (BUILTIN_SQRT_P (fcode1))
+ /* Optimize a/root(b/c) into a*root(c/b). */
+ if (BUILTIN_ROOT_P (fcode1))
{
tree rootarg = CALL_EXPR_ARG (arg1, 0);
{
if (TYPE_UNSIGNED (itype))
{
- itype = lang_hooks.types.signed_type (itype);
+ itype = signed_type_for (itype);
arg00 = fold_convert (itype, arg00);
}
return fold_build2 (code == EQ_EXPR ? GE_EXPR : LT_EXPR,
if (code == LE_EXPR || code == GT_EXPR)
{
tree st;
- st = lang_hooks.types.signed_type (TREE_TYPE (arg1));
+ st = signed_type_for (TREE_TYPE (arg1));
return fold_build2 (code == LE_EXPR ? GE_EXPR : LT_EXPR,
type, fold_convert (st, arg0),
build_int_cst (st, 0));
if ((TREE_INT_CST_HIGH (arg1) & mask_hi) == mask_hi
&& (TREE_INT_CST_LOW (arg1) & mask_lo) == mask_lo)
{
- tem_type = lang_hooks.types.signed_type (TREE_TYPE (tem));
+ tem_type = signed_type_for (TREE_TYPE (tem));
tem = fold_convert (tem_type, tem);
}
else if ((TREE_INT_CST_HIGH (arg1) & mask_hi) == 0
fold_checksum_tree (TREE_TYPE (expr), ctx, ht);
if (TREE_CODE_CLASS (code) != tcc_type
&& TREE_CODE_CLASS (code) != tcc_declaration
- && code != TREE_LIST)
+ && code != TREE_LIST
+ && code != SSA_NAME)
fold_checksum_tree (TREE_CHAIN (expr), ctx, ht);
switch (TREE_CODE_CLASS (code))
{
return tem;
}
+/* Helper function for outputting the checksum of a tree T. When
+ debugging with gdb, you can "define mynext" to be "next" followed
+ by "call debug_fold_checksum (op0)", then just trace down till the
+ outputs differ. */
+
+void
+debug_fold_checksum (tree t)
+{
+ int i;
+ unsigned char checksum[16];
+ struct md5_ctx ctx;
+ htab_t ht = htab_create (32, htab_hash_pointer, htab_eq_pointer, NULL);
+
+ md5_init_ctx (&ctx);
+ fold_checksum_tree (t, &ctx, ht);
+ md5_finish_ctx (&ctx, checksum);
+ htab_empty (ht);
+
+ for (i = 0; i < 16; i++)
+ fprintf (stderr, "%d ", checksum[i]);
+
+ fprintf (stderr, "\n");
+}
+
/* Fold a binary tree expression with code CODE of type TYPE with
operands OP0 and OP1. Return a folded expression if successful.
Otherwise, return a tree expression with code CODE of type TYPE
case REAL_CST:
return ! REAL_VALUE_NEGATIVE (TREE_REAL_CST (t));
+ case POINTER_PLUS_EXPR:
case PLUS_EXPR:
if (FLOAT_TYPE_P (TREE_TYPE (t)))
return (tree_expr_nonnegative_warnv_p (TREE_OPERAND (t, 0),
case INTEGER_CST:
return !integer_zerop (t);
+ case POINTER_PLUS_EXPR:
case PLUS_EXPR:
if (TYPE_OVERFLOW_UNDEFINED (type))
{
return build1 (CLEANUP_POINT_EXPR, type, expr);
}
-/* Build an expression for the address of T. Folds away INDIRECT_REF to
- avoid confusing the gimplify process. */
-
-tree
-build_fold_addr_expr_with_type (tree t, tree ptrtype)
-{
- /* The size of the object is not relevant when talking about its address. */
- if (TREE_CODE (t) == WITH_SIZE_EXPR)
- t = TREE_OPERAND (t, 0);
-
- /* Note: doesn't apply to ALIGN_INDIRECT_REF */
- if (TREE_CODE (t) == INDIRECT_REF
- || TREE_CODE (t) == MISALIGNED_INDIRECT_REF)
- {
- t = TREE_OPERAND (t, 0);
- if (TREE_TYPE (t) != ptrtype)
- t = build1 (NOP_EXPR, ptrtype, t);
- }
- else
- {
- tree base = t;
-
- while (handled_component_p (base))
- base = TREE_OPERAND (base, 0);
- if (DECL_P (base))
- TREE_ADDRESSABLE (base) = 1;
-
- t = build1 (ADDR_EXPR, ptrtype, t);
- }
-
- return t;
-}
-
-tree
-build_fold_addr_expr (tree t)
-{
- return build_fold_addr_expr_with_type (t, build_pointer_type (TREE_TYPE (t)));
-}
-
/* Given a pointer value OP0 and a type TYPE, return a simplified version
of an indirection through OP0, or NULL_TREE if no simplification is
possible. */
}
/* ((foo*)&complexfoo)[1] => __imag__ complexfoo */
- if (TREE_CODE (sub) == PLUS_EXPR
+ if (TREE_CODE (sub) == POINTER_PLUS_EXPR
&& TREE_CODE (TREE_OPERAND (sub, 1)) == INTEGER_CST)
{
tree op00 = TREE_OPERAND (sub, 0);
core = get_inner_reference (TREE_OPERAND (exp, 0), &bitsize, pbitpos,
poffset, &mode, &unsignedp, &volatilep,
false);
- core = build_fold_addr_expr (core);
+ core = fold_addr_expr (core);
}
else
{