aboutsummaryrefslogtreecommitdiff
path: root/gcc/varasm.c
diff options
context:
space:
mode:
authorDJ Delorie <dj@redhat.com>2005-09-01 19:26:36 -0400
committerDJ Delorie <dj@gcc.gnu.org>2005-09-01 19:26:36 -0400
commit056061d8da51885e41182e2cd2d44b2435c25a00 (patch)
tree0d310b0b29272a8adbb7c0ca038399a3e4784a88 /gcc/varasm.c
parent4eafe8821205e06658911b724a204043dcf25ee8 (diff)
downloadgcc-056061d8da51885e41182e2cd2d44b2435c25a00.zip
gcc-056061d8da51885e41182e2cd2d44b2435c25a00.tar.gz
gcc-056061d8da51885e41182e2cd2d44b2435c25a00.tar.bz2
varasm.c (output_constant): Let the target resolve conversions of addresses to non-default pointer sizes.
* varasm.c (output_constant): Let the target resolve conversions of addresses to non-default pointer sizes. From-SVN: r103750
Diffstat (limited to 'gcc/varasm.c')
-rw-r--r--gcc/varasm.c36
1 files changed, 35 insertions, 1 deletions
diff --git a/gcc/varasm.c b/gcc/varasm.c
index a3ef4fd..a85f659 100644
--- a/gcc/varasm.c
+++ b/gcc/varasm.c
@@ -3847,12 +3847,46 @@ output_constant (tree exp, unsigned HOST_WIDE_INT size, unsigned int align)
if (size == 0 || flag_syntax_only)
return;
+ /* See if we're trying to intialize a pointer in a non-default mode
+ to the address of some declaration somewhere. If the target says
+ the mode is valid for pointers, assume the target has a way of
+ resolving it. */
+ if (TREE_CODE (exp) == NOP_EXPR
+ && POINTER_TYPE_P (TREE_TYPE (exp))
+ && targetm.valid_pointer_mode (TYPE_MODE (TREE_TYPE (exp))))
+ {
+ tree saved_type = TREE_TYPE (exp);
+
+ /* Peel off any intermediate conversions-to-pointer for valid
+ pointer modes. */
+ while (TREE_CODE (exp) == NOP_EXPR
+ && POINTER_TYPE_P (TREE_TYPE (exp))
+ && targetm.valid_pointer_mode (TYPE_MODE (TREE_TYPE (exp))))
+ exp = TREE_OPERAND (exp, 0);
+
+ /* If what we're left with is the address of something, we can
+ convert the address to the final type and output it that
+ way. */
+ if (TREE_CODE (exp) == ADDR_EXPR)
+ exp = build1 (ADDR_EXPR, saved_type, TREE_OPERAND (exp, 0));
+ }
+
/* Eliminate any conversions since we'll be outputting the underlying
constant. */
while (TREE_CODE (exp) == NOP_EXPR || TREE_CODE (exp) == CONVERT_EXPR
|| TREE_CODE (exp) == NON_LVALUE_EXPR
|| TREE_CODE (exp) == VIEW_CONVERT_EXPR)
- exp = TREE_OPERAND (exp, 0);
+ {
+ HOST_WIDE_INT type_size = int_size_in_bytes (TREE_TYPE (exp));
+ HOST_WIDE_INT op_size = int_size_in_bytes (TREE_TYPE (TREE_OPERAND (exp, 0)));
+
+ /* Make sure eliminating the conversion is really a no-op. */
+ if (type_size != op_size)
+ internal_error ("no-op convert from %wd to %wd bytes in initializer",
+ op_size, type_size);
+
+ exp = TREE_OPERAND (exp, 0);
+ }
code = TREE_CODE (TREE_TYPE (exp));
thissize = int_size_in_bytes (TREE_TYPE (exp));