OSDN Git Service

PR middle-end/14997
authorebotcazou <ebotcazou@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 6 Sep 2005 19:46:58 +0000 (19:46 +0000)
committerebotcazou <ebotcazou@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 6 Sep 2005 19:46:58 +0000 (19:46 +0000)
* 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.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@103963 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/expr.c

index 3d6de0f..1f93ae7 100644 (file)
@@ -1,3 +1,12 @@
+2005-09-06  Olivier Hainque  <hainque@adacore.com>
+            Eric Botcazou  <ebotcazou@adacore.com>
+
+       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.
+
 2005-09-06  Steven Bosscher  <stevenb@suse.de>
 
        * tree-ssa-pre.c (try_look_through_load): New function.
index e5f5c3d..ff6adec 100644 (file)
@@ -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),