diff options
author | Richard Kenner <kenner@gcc.gnu.org> | 1993-03-31 16:06:33 -0500 |
---|---|---|
committer | Richard Kenner <kenner@gcc.gnu.org> | 1993-03-31 16:06:33 -0500 |
commit | 896102d0c667780bf95d2766b22ac29c365fd323 (patch) | |
tree | acfb7fb24a2d895ae22b4f5ee5c1a3dd44a519ac | |
parent | 475dd3b4b88e80fb96e705432da37501b798c99f (diff) | |
download | gcc-896102d0c667780bf95d2766b22ac29c365fd323.zip gcc-896102d0c667780bf95d2766b22ac29c365fd323.tar.gz gcc-896102d0c667780bf95d2766b22ac29c365fd323.tar.bz2 |
(expand_expr, case ADDR_EXPR): Allow taking the address of any object;
used in call-by-reference situations.
From-SVN: r3970
-rw-r--r-- | gcc/expr.c | 24 |
1 files changed, 24 insertions, 0 deletions
@@ -5184,6 +5184,30 @@ expand_expr (exp, target, tmode, modifier) op0 = expand_expr (TREE_OPERAND (exp, 0), NULL_RTX, VOIDmode, (modifier == EXPAND_INITIALIZER ? modifier : EXPAND_CONST_ADDRESS)); + + /* We would like the object in memory. If it is a constant, + we can have it be statically allocated into memory. For + a non-constant (REG or SUBREG), we need to allocate some + memory and store the value into it. */ + + if (CONSTANT_P (op0)) + op0 = force_const_mem (TYPE_MODE (TREE_TYPE (TREE_OPERAND (exp, 0))), + op0); + + if (GET_CODE (op0) == REG || GET_CODE (op0) == SUBREG) + { + /* If this object is in a register, it must be not + be BLKmode. */ + tree inner_type = TREE_TYPE (TREE_OPERAND (exp, 0)); + enum machine_mode inner_mode = TYPE_MODE (inner_type); + rtx memloc + = assign_stack_temp (inner_mode, + int_size_in_bytes (inner_type), 1); + + emit_move_insn (memloc, op0); + op0 = memloc; + } + if (GET_CODE (op0) != MEM) abort (); |