aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorRichard Guenther <rguenther@suse.de>2012-01-13 12:05:27 +0000
committerRichard Biener <rguenth@gcc.gnu.org>2012-01-13 12:05:27 +0000
commitaabb90e5ad703efbfc7a6c69c08817c2e2ccfb13 (patch)
tree3d05814c131d0a75d48d9673832203b3d531b7e4 /gcc
parentb9b16ad4092d4939889ea8a6aa2484cb92f0ab13 (diff)
downloadgcc-aabb90e5ad703efbfc7a6c69c08817c2e2ccfb13.zip
gcc-aabb90e5ad703efbfc7a6c69c08817c2e2ccfb13.tar.gz
gcc-aabb90e5ad703efbfc7a6c69c08817c2e2ccfb13.tar.bz2
re PR c/8081 (ICE with variably sized types returned from nested functions)
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. * gcc.dg/torture/pr8081.c: New testcase. From-SVN: r183153
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog6
-rw-r--r--gcc/gimplify.c5
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gcc.dg/torture/pr8081.c26
4 files changed, 42 insertions, 0 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 60830ae..6bd16d3 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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
diff --git a/gcc/gimplify.c b/gcc/gimplify.c
index 94b99a1..99ae5ee 100644
--- a/gcc/gimplify.c
+++ b/gcc/gimplify.c
@@ -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)))
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index b26ac26..cbee6be 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -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
index 0000000..6899f6a
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/pr8081.c
@@ -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;
+}