aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/ada/ChangeLog5
-rw-r--r--gcc/ada/gcc-interface/trans.c20
-rw-r--r--gcc/testsuite/ChangeLog4
-rw-r--r--gcc/testsuite/gnat.dg/opt79.adb28
-rw-r--r--gcc/testsuite/gnat.dg/opt79.ads7
5 files changed, 59 insertions, 5 deletions
diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog
index 6722542..f51693a 100644
--- a/gcc/ada/ChangeLog
+++ b/gcc/ada/ChangeLog
@@ -1,3 +1,8 @@
+2019-05-28 Eric Botcazou <ebotcazou@adacore.com>
+
+ * gcc-interface/trans.c (walk_nesting_tree): New static function.
+ (finalize_nrv): Use it to walk the entire nesting tree.
+
2019-05-07 Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE>
* gcc-interface/Makefile.in (install-gcc-specs): Use foreach.
diff --git a/gcc/ada/gcc-interface/trans.c b/gcc/ada/gcc-interface/trans.c
index 7430af1..c320481 100644
--- a/gcc/ada/gcc-interface/trans.c
+++ b/gcc/ada/gcc-interface/trans.c
@@ -3519,6 +3519,20 @@ finalize_nrv_unc_r (tree *tp, int *walk_subtrees, void *data)
return NULL_TREE;
}
+/* Apply FUNC to all the sub-trees of nested functions in NODE. FUNC is called
+ with the DATA and the address of each sub-tree. If FUNC returns a non-NULL
+ value, the traversal is stopped. */
+
+static void
+walk_nesting_tree (struct cgraph_node *node, walk_tree_fn func, void *data)
+{
+ for (node = node->nested; node; node = node->next_nested)
+ {
+ walk_tree_without_duplicates (&DECL_SAVED_TREE (node->decl), func, data);
+ walk_nesting_tree (node, func, data);
+ }
+}
+
/* Finalize the Named Return Value optimization for FNDECL. The NRV bitmap
contains the candidates for Named Return Value and OTHER is a list of
the other return values. GNAT_RET is a representative return node. */
@@ -3526,7 +3540,6 @@ finalize_nrv_unc_r (tree *tp, int *walk_subtrees, void *data)
static void
finalize_nrv (tree fndecl, bitmap nrv, vec<tree, va_gc> *other, Node_Id gnat_ret)
{
- struct cgraph_node *node;
struct nrv_data data;
walk_tree_fn func;
unsigned int i;
@@ -3547,10 +3560,7 @@ finalize_nrv (tree fndecl, bitmap nrv, vec<tree, va_gc> *other, Node_Id gnat_ret
return;
/* Prune also the candidates that are referenced by nested functions. */
- node = cgraph_node::get_create (fndecl);
- for (node = node->nested; node; node = node->next_nested)
- walk_tree_without_duplicates (&DECL_SAVED_TREE (node->decl), prune_nrv_r,
- &data);
+ walk_nesting_tree (cgraph_node::get_create (fndecl), prune_nrv_r, &data);
if (bitmap_empty_p (nrv))
return;
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index ba9467f..eac98e1 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,7 @@
+2019-05-28 Eric Botcazou <ebotcazou@adacore.com>
+
+ * gnat.dg/opt79.ad[sb]: New test.
+
2019-05-23 Uroš Bizjak <ubizjak@gmail.com>
Backported from mainline
diff --git a/gcc/testsuite/gnat.dg/opt79.adb b/gcc/testsuite/gnat.dg/opt79.adb
new file mode 100644
index 0000000..f58e25b
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/opt79.adb
@@ -0,0 +1,28 @@
+-- { dg-do compile }
+-- { dg-options "-O" }
+
+package body Opt79 is
+
+ function F (I : Integer) return Arr is
+ A : Arr;
+
+ procedure Nested is
+
+ procedure Inner is
+ begin
+ A (1) := 0;
+ end;
+
+ begin
+ Inner;
+ end;
+
+ begin
+ Nested;
+ for J in A'Range loop
+ A (J) := I;
+ end loop;
+ return A;
+ end;
+
+end Opt79;
diff --git a/gcc/testsuite/gnat.dg/opt79.ads b/gcc/testsuite/gnat.dg/opt79.ads
new file mode 100644
index 0000000..aa90c17
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/opt79.ads
@@ -0,0 +1,7 @@
+package Opt79 is
+
+ type Arr is array (1 .. 8) of Integer;
+
+ function F (I : Integer) return Arr;
+
+end Opt79;