aboutsummaryrefslogtreecommitdiff
path: root/gcc/expr.c
diff options
context:
space:
mode:
authorOlivier Hainque <hainque@adacore.com>2005-09-06 19:46:58 +0000
committerEric Botcazou <ebotcazou@gcc.gnu.org>2005-09-06 19:46:58 +0000
commit60a23e2e02d5fafd887891c0fd910f7fdc760055 (patch)
treea66d1ad60cf6547def8ae7569332633b548ddf3d /gcc/expr.c
parent29a153937a9c2c93a6f69b3b0dbf2f9dedfed943 (diff)
downloadgcc-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.c21
1 files changed, 13 insertions, 8 deletions
diff --git a/gcc/expr.c b/gcc/expr.c
index e5f5c3d..ff6adec 100644
--- a/gcc/expr.c
+++ b/gcc/expr.c
@@ -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),