diff options
Diffstat (limited to 'gcc/tree.c')
-rw-r--r-- | gcc/tree.c | 39 |
1 files changed, 38 insertions, 1 deletions
@@ -3564,7 +3564,8 @@ do { tree _node = (NODE); \ address is constant too. If it's a decl, its address is constant if the decl is static. Everything else is not constant and, furthermore, taking the address of a volatile variable is not volatile. */ - if (TREE_CODE (node) == INDIRECT_REF) + if (TREE_CODE (node) == INDIRECT_REF + || TREE_CODE (node) == MEM_REF) UPDATE_FLAGS (TREE_OPERAND (node, 0)); else if (CONSTANT_CLASS_P (node)) ; @@ -3878,6 +3879,42 @@ build6_stat (enum tree_code code, tree tt, tree arg0, tree arg1, return t; } +/* Build a simple MEM_REF tree with the sematics of a plain INDIRECT_REF + on the pointer PTR. */ + +tree +build_simple_mem_ref_loc (location_t loc, tree ptr) +{ + HOST_WIDE_INT offset = 0; + tree ptype = TREE_TYPE (ptr); + tree tem; + /* For convenience allow addresses that collapse to a simple base + and offset. */ + if (TREE_CODE (ptr) == ADDR_EXPR + && (handled_component_p (TREE_OPERAND (ptr, 0)) + || TREE_CODE (TREE_OPERAND (ptr, 0)) == MEM_REF)) + { + ptr = get_addr_base_and_unit_offset (TREE_OPERAND (ptr, 0), &offset); + gcc_assert (ptr); + ptr = build_fold_addr_expr (ptr); + gcc_assert (is_gimple_reg (ptr) || is_gimple_min_invariant (ptr)); + } + tem = build2 (MEM_REF, TREE_TYPE (ptype), + ptr, build_int_cst (ptype, offset)); + SET_EXPR_LOCATION (tem, loc); + return tem; +} + +/* Return the constant offset of a MEM_REF tree T. */ + +double_int +mem_ref_offset (const_tree t) +{ + tree toff = TREE_OPERAND (t, 1); + return double_int_sext (tree_to_double_int (toff), + TYPE_PRECISION (TREE_TYPE (toff))); +} + /* Similar except don't specify the TREE_TYPE and leave the TREE_SIDE_EFFECTS as 0. It is permissible for arguments to be null, |