diff options
author | Olivier Hainque <hainque@adacore.com> | 2005-09-06 19:46:58 +0000 |
---|---|---|
committer | Eric Botcazou <ebotcazou@gcc.gnu.org> | 2005-09-06 19:46:58 +0000 |
commit | 60a23e2e02d5fafd887891c0fd910f7fdc760055 (patch) | |
tree | a66d1ad60cf6547def8ae7569332633b548ddf3d /gcc/expr.c | |
parent | 29a153937a9c2c93a6f69b3b0dbf2f9dedfed943 (diff) | |
download | gcc-60a23e2e02d5fafd887891c0fd910f7fdc760055.zip gcc-60a23e2e02d5fafd887891c0fd910f7fdc760055.tar.gz gcc-60a23e2e02d5fafd887891c0fd910f7fdc760055.tar.bz2 |
re PR middle-end/14997 (ncurses build fails with Ada)
PR middle-end/14997
* expr.c (expand_expr_real) <normal_inner_ref>: Force op0 to mem
when we would be extracting outside its bit span (bitpos+bitsize
larger than its mode), possible with some VIEW_CONVERT_EXPRs from
Ada unchecked conversions.
Co-Authored-By: Eric Botcazou <ebotcazou@adacore.com>
From-SVN: r103963
Diffstat (limited to 'gcc/expr.c')
-rw-r--r-- | gcc/expr.c | 21 |
1 files changed, 13 insertions, 8 deletions
@@ -7178,25 +7178,30 @@ expand_expr_real_1 (tree exp, rtx target, enum machine_mode tmode, || modifier == EXPAND_STACK_PARM) ? modifier : EXPAND_NORMAL); - /* If this is a constant, put it into a register if it is a - legitimate constant and OFFSET is 0 and memory if it isn't. */ + /* If this is a constant, put it into a register if it is a legitimate + constant, OFFSET is 0, and we won't try to extract outside the + register (in case we were passed a partially uninitialized object + or a view_conversion to a larger size). Force the constant to + memory otherwise. */ if (CONSTANT_P (op0)) { enum machine_mode mode = TYPE_MODE (TREE_TYPE (tem)); if (mode != BLKmode && LEGITIMATE_CONSTANT_P (op0) - && offset == 0) + && offset == 0 + && bitpos + bitsize <= GET_MODE_BITSIZE (mode)) op0 = force_reg (mode, op0); else op0 = validize_mem (force_const_mem (mode, op0)); } - /* Otherwise, if this object not in memory and we either have an - offset or a BLKmode result, put it there. This case can't occur in - C, but can in Ada if we have unchecked conversion of an expression - from a scalar type to an array or record type or for an - ARRAY_RANGE_REF whose type is BLKmode. */ + /* Otherwise, if this object not in memory and we either have an + offset, a BLKmode result, or a reference outside the object, put it + there. Such cases can occur in Ada if we have unchecked conversion + of an expression from a scalar type to an array or record type or + for an ARRAY_RANGE_REF whose type is BLKmode. */ else if (!MEM_P (op0) && (offset != 0 + || (bitpos + bitsize > GET_MODE_BITSIZE (GET_MODE (op0))) || (code == ARRAY_RANGE_REF && mode == BLKmode))) { tree nt = build_qualified_type (TREE_TYPE (tem), |