diff options
author | DJ Delorie <dj@redhat.com> | 2005-09-01 19:26:36 -0400 |
---|---|---|
committer | DJ Delorie <dj@gcc.gnu.org> | 2005-09-01 19:26:36 -0400 |
commit | 056061d8da51885e41182e2cd2d44b2435c25a00 (patch) | |
tree | 0d310b0b29272a8adbb7c0ca038399a3e4784a88 /gcc | |
parent | 4eafe8821205e06658911b724a204043dcf25ee8 (diff) | |
download | gcc-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')
-rw-r--r-- | gcc/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/varasm.c | 36 |
2 files changed, 40 insertions, 1 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 5c8abe5..9d20f4b 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,8 @@ +2005-09-01 DJ Delorie <dj@redhat.com> + + * varasm.c (output_constant): Let the target resolve + conversions of addresses to non-default pointer sizes. + 2005-09-01 Nicolas Pitre <nico@cam.org> * config/arm/arm.c (arm_legitimize_address): Split absolute addresses 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)); |