OSDN Git Service

2012-01-13 Richard Guenther <rguenther@suse.de>
authorrguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 13 Jan 2012 12:05:27 +0000 (12:05 +0000)
committerrguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 13 Jan 2012 12:05:27 +0000 (12:05 +0000)
PR middle-end/8081
* gimplify.c (gimplify_modify_expr_rhs): For calls with a
variable-sized result always use RSO.

* gcc.dg/torture/pr8081.c: New testcase.

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

gcc/ChangeLog
gcc/gimplify.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/torture/pr8081.c [new file with mode: 0644]

index 60830ae..6bd16d3 100644 (file)
@@ -1,3 +1,9 @@
+2012-01-13  Richard Guenther  <rguenther@suse.de>
+
+       PR middle-end/8081
+       * gimplify.c (gimplify_modify_expr_rhs): For calls with a
+       variable-sized result always use RSO.
+
 2012-01-12  DJ Delorie  <dj@redhat.com>
 
        * cfgexpand.c (convert_debug_memory_address): Allow any valid
index 94b99a1..99ae5ee 100644 (file)
@@ -4417,6 +4417,11 @@ gimplify_modify_expr_rhs (tree *expr_p, tree *from_p, tree *to_p,
                /* It's OK to use the target directly if it's being
                   initialized. */
                use_target = true;
+             else if (variably_modified_type_p (TREE_TYPE (*to_p), NULL_TREE))
+               /* Always use the target and thus RSO for variable-sized types.
+                  GIMPLE cannot deal with a variable-sized assignment
+                  embedded in a call statement.  */
+               use_target = true;
              else if (TREE_CODE (*to_p) != SSA_NAME
                      && (!is_gimple_variable (*to_p)
                          || needs_to_live_in_memory (*to_p)))
index b26ac26..cbee6be 100644 (file)
@@ -1,3 +1,8 @@
+2012-01-13  Richard Guenther  <rguenther@suse.de>
+
+       PR middle-end/8081
+       * gcc.dg/torture/pr8081.c: New testcase.
+
 2012-01-13  Georg-Johann Lay  <avr@gjlay.de>
 
        * gcc.dg/pr46309.c: Set branch cost to greater 1 for avr.
diff --git a/gcc/testsuite/gcc.dg/torture/pr8081.c b/gcc/testsuite/gcc.dg/torture/pr8081.c
new file mode 100644 (file)
index 0000000..6899f6a
--- /dev/null
@@ -0,0 +1,26 @@
+/* { dg-do run } */
+
+extern void abort (void);
+int
+main (int argc, char **argv)
+{
+  int size = 10;
+  typedef struct
+    {
+      char val[size];
+    }
+  block;
+  block a, b;
+  block __attribute__((noinline))
+  retframe_block ()
+    {
+      return *(block *) &b;
+    }
+  b.val[0] = -1;
+  b.val[9] = -2;
+  a=retframe_block ();
+  if (a.val[0] != -1
+      || a.val[9] != -2)
+    abort ();
+  return 0;
+}