On Fri, May 18, 2018 at 9:43 AM Eric Botcazou <ebotca...@adacore.com> wrote:

> Hi,

> the compiler has had built-in support for nested functions for a long
time,
> which makes it possible to support them in GNU C (as an extension) and in
Ada;
> Fortran uses them too but marginally.  The support was entirely rewritten
for
> GCC 4 and a few rough edges have remained since then, which are quite
visible
> in languages where they are first-class citizens like Ada.

> The first rough edge is the stack usage at -O0: it is twice as large as
needed
> for variables subject to up-level references.  So you declare an array of
2KB
> bytes on the stack, factor out some code that reads it into a child
function
> and then you suddenly need 4KB of stack instead of 2KB.  Even at -O0 this
can
> be annoying for very embedded platforms.

> The attached patch fixes it and also contains a tweak to
use_pointer_in_frame
> for the sake of consistency but with no functional changes in practice.

> Tested on x86-64/Linux, OK for the mainline?

+             /* If the next declaration is a PARM_DECL pointing to the
DECL,
+                we need to adjust its VALUE_EXPR directly, since chains of
+                VALUE_EXPRs run afoul of garbage collection.  This occurs
+                in Ada for Out parameters that aren't copied in.  */
+             if (next
+                 && TREE_CODE (next) == PARM_DECL
+                 && DECL_HAS_VALUE_EXPR_P (next)
+                 && DECL_VALUE_EXPR (next) == decl)
+               SET_DECL_VALUE_EXPR (next, x);

maybe you can explain the GC issue a bit.  I also think that you should
adjust
the next DECL_VALUE_EXRP before setting DECL_VALUE_EXPR on decl so
we can do sth like the following to verify we do not face this very
situation
(it's of course incomplete verification, we could search for a suitable
place
in some of the IL verifiers but I'm not sure there is one early enough and
catching all decls).

diff --git a/gcc/tree.c b/gcc/tree.c
index 68165f4deed..ded12782aea 100644
--- a/gcc/tree.c
+++ b/gcc/tree.c
@@ -6340,7 +6340,14 @@ decl_value_expr_lookup (tree from)

    h = value_expr_for_decl->find_with_hash (&in, DECL_UID (from));
    if (h)
-    return h->to;
+    {
+      /* Chains of value-exprs run afoul of garbage collection, make
+         sure we never end up with those.  */
+      gcc_checking_assert ((TREE_CODE (h->to) != PARM_DECL
+                           && TREE_CODE (h->to) != VAR_DECL)
+                          || !DECL_HAS_VALUE_EXPR_P (h->to));
+      return h->to;
+    }
    return NULL_TREE;
  }

@@ -6351,6 +6358,12 @@ decl_value_expr_insert (tree from, tree to)
  {
    struct tree_decl_map *h;

+  /* Chains of value-exprs run afoul of garbage collection, make
+     sure we never end up with those.  */
+  gcc_checking_assert ((TREE_CODE (to) != PARM_DECL
+                       && TREE_CODE (to) != VAR_DECL)
+                      || !DECL_HAS_VALUE_EXPR_P (to));
+
    h = ggc_alloc<tree_decl_map> ();
    h->base.from = from;
    h->to = to;



> 2018-05-18  Eric Botcazou  <ebotca...@adacore.com>

>          * tree-nested.c (use_pointer_in_frame): Tweak.
>          (lookup_field_for_decl): Add assertion and declare the
transformation.


> 2018-05-18  Eric Botcazou  <ebotca...@adacore.com>

>          * gnat.dg/stack_usage5.adb: New test.

> --
> Eric Botcazou

Reply via email to