]> gcc.gnu.org Git - gcc.git/commitdiff
c-tree.h (lang_decl): Add pending_sizes fields.
authorMark Mitchell <mark@codesourcery.com>
Tue, 5 Jun 2001 06:51:02 +0000 (06:51 +0000)
committerMark Mitchell <mmitchel@gcc.gnu.org>
Tue, 5 Jun 2001 06:51:02 +0000 (06:51 +0000)
* c-tree.h (lang_decl): Add pending_sizes fields.
* c-decl.c (store_parm_decls): Save pending_sizes away for nested
functions.
(c_expand_body): Expand them.
(lang_mark_tree): Mark lang_decl:pending_sizes.
* function.c (expand_pending_sizes): New function, broken out
from ...
(expand_function_start): ... here.
* tree.h (expand_pending_sizes): Declare it.

From-SVN: r42892

gcc/ChangeLog
gcc/c-decl.c
gcc/c-tree.h
gcc/function.c
gcc/testsuite/gcc.c-torture/compile/20010605-1.c [new file with mode: 0644]
gcc/tree.h

index 7107c8e5ded712de27a36ec121c4baa5e6e30dfa..ae31dd4b3ef72a423b367d1af0a150fb202e22b8 100644 (file)
@@ -1,3 +1,15 @@
+2001-06-04  Mark Mitchell  <mark@codesourcery.com>
+
+       * c-tree.h (lang_decl): Add pending_sizes fields.
+       * c-decl.c (store_parm_decls): Save pending_sizes away for nested
+       functions.
+       (c_expand_body): Expand them.
+       (lang_mark_tree): Mark lang_decl:pending_sizes.
+       * function.c (expand_pending_sizes): New function, broken out 
+       from ...
+       (expand_function_start): ... here.
+       * tree.h (expand_pending_sizes): Declare it.
+       
 2001-06-04  Loren J. Rittle  <ljrittle@acm.org>
 
        * doc/install.texi: Update FreeBSD information.  Generalize
index 88a41f9f404977660c6249eb294774bf86a3d7d7..314a306d5609ea1cb42aebd51c188c6162b510ad 100644 (file)
@@ -6167,6 +6167,9 @@ store_parm_decls ()
   /* Nonzero if this definition is written with a prototype.  */
   int prototype = 0;
 
+  /* The function containing FNDECL, if any.  */
+  tree context = decl_function_context (fndecl);
+
   if (specparms != 0 && TREE_CODE (specparms) != TREE_LIST)
     {
       /* This case is when the function was defined with an ANSI prototype.
@@ -6534,14 +6537,28 @@ store_parm_decls ()
   gen_aux_info_record (fndecl, 1, 0, prototype);
 
   /* Initialize the RTL code for the function.  */
-
   init_function_start (fndecl, input_filename, lineno);
 
   /* Begin the statement tree for this function.  */
   DECL_LANG_SPECIFIC (current_function_decl)
-    =((struct lang_decl *) ggc_alloc (sizeof (struct lang_decl)));
+    =((struct lang_decl *) ggc_alloc_cleared (sizeof (struct lang_decl)));
   begin_stmt_tree (&DECL_SAVED_TREE (current_function_decl));
 
+  /* If this is a nested function, save away the sizes of any
+     variable-size types so that we can expand them when generating
+     RTL.  */
+  if (context)
+    {
+      tree t;
+
+      DECL_LANG_SPECIFIC (fndecl)->pending_sizes 
+       = nreverse (get_pending_sizes ());
+      for (t = DECL_LANG_SPECIFIC (fndecl)->pending_sizes;
+          t;
+          t = TREE_CHAIN (t))
+       SAVE_EXPR_CONTEXT (TREE_VALUE (t)) = context;
+    }
+
   /* This function is being processed in whole-function mode.  */
   cfun->x_whole_function_mode_p = 1;
 
@@ -6786,9 +6803,14 @@ c_expand_body (fndecl, nested_p)
   if (flag_syntax_only)
     return;
 
-  /* Squirrel away our current state.  */
   if (nested_p)
-    push_function_context ();
+    {
+      /* Make sure that we will evaluate variable-sized types involved
+        in our function's type.  */
+      expand_pending_sizes (DECL_LANG_SPECIFIC (fndecl)->pending_sizes);
+      /* Squirrel away our current state.  */
+      push_function_context ();
+    }
 
   /* Initialize the RTL code for the function.  */
   current_function_decl = fndecl;
@@ -6823,7 +6845,7 @@ c_expand_body (fndecl, nested_p)
   /* Allow the body of the function to be garbage collected.  */
   DECL_SAVED_TREE (fndecl) = NULL_TREE;
 
-  /* We hard-wired immediate_size_expand to zero in start_function.
+  /* We hard-wired immediate_size_expand to zero above.
      expand_function_end will decrement this variable.  So, we set the
      variable to one here, so that after the decrement it will remain
      zero.  */
@@ -7116,6 +7138,7 @@ lang_mark_tree (t)
     {
       ggc_mark (DECL_LANG_SPECIFIC (t));
       c_mark_lang_decl (&DECL_LANG_SPECIFIC (t)->base);
+      ggc_mark_tree (DECL_LANG_SPECIFIC (t)->pending_sizes);
     }
 }
 
index 508567a91d9641cf2e29ef86f38199c1545e51ee..1ea096f88b29e7fd20fe22dae56fbcd094479218 100644 (file)
@@ -41,12 +41,15 @@ struct lang_identifier
   tree error_locus, limbo_value;
 };
 
-/* Wrapping c_lang_decl in another struct is an unfortunate
-   necessity.  */
+/* Language-specific declaration information.  */
 
 struct lang_decl
 {
   struct c_lang_decl base;
+  /* The return types and parameter types may have variable size.
+     This is a list of any SAVE_EXPRs that need to be evaluated to
+     compute those sizes.  */
+  tree pending_sizes;
 };
 
 /* Macros for access to language-specific slots in an identifier.  */
index 161173e8d698a2529df6ad1759bbf465168f4b2e..64df1bd42e6da148d4eee3c7552ba267e0784f14 100644 (file)
@@ -6270,6 +6270,29 @@ expand_main_function ()
 \f
 extern struct obstack permanent_obstack;
 
+/* The PENDING_SIZES represent the sizes of variable-sized types.
+   Create RTL for the various sizes now (using temporary variables),
+   so that we can refer to the sizes from the RTL we are generating
+   for the current function.  The PENDING_SIZES are a TREE_LIST.  The
+   TREE_VALUE of each node is a SAVE_EXPR.  */
+
+void
+expand_pending_sizes (pending_sizes)
+     tree pending_sizes;
+{
+  tree tem;
+
+  /* Evaluate now the sizes of any types declared among the arguments.  */
+  for (tem = pending_sizes; tem; tem = TREE_CHAIN (tem))
+    {
+      expand_expr (TREE_VALUE (tem), const0_rtx, VOIDmode,
+                  EXPAND_MEMORY_USE_BAD);
+      /* Flush the queue in case this parameter declaration has
+        side-effects.  */
+      emit_queue ();
+    }
+}
+
 /* Start the RTL for a new function, and set variables used for
    emitting RTL.
    SUBR is the FUNCTION_DECL node.
@@ -6487,14 +6510,7 @@ expand_function_start (subr, parms_have_cleanups)
   tail_recursion_reentry = emit_note (NULL, NOTE_INSN_DELETED);
 
   /* Evaluate now the sizes of any types declared among the arguments.  */
-  for (tem = nreverse (get_pending_sizes ()); tem; tem = TREE_CHAIN (tem))
-    {
-      expand_expr (TREE_VALUE (tem), const0_rtx, VOIDmode,
-                  EXPAND_MEMORY_USE_BAD);
-      /* Flush the queue in case this parameter declaration has
-        side-effects.  */
-      emit_queue ();
-    }
+  expand_pending_sizes (nreverse (get_pending_sizes ()));
 
   /* Make sure there is a line number after the function entry setup code.  */
   force_next_line_note ();
diff --git a/gcc/testsuite/gcc.c-torture/compile/20010605-1.c b/gcc/testsuite/gcc.c-torture/compile/20010605-1.c
new file mode 100644 (file)
index 0000000..036b796
--- /dev/null
@@ -0,0 +1,15 @@
+int
+main (int argc, char **argv)
+{
+  int size = 10;
+
+  typedef struct {
+    char val[size];
+  } block;
+  block retframe_block()
+    {
+      return *(block*)0;
+    }
+
+  return 0;
+}
index af784ad42632f362583ee23ff37eeaf5302aeb2f..8634acb6617a7e50d34d9176c1ce1452063ed2fa 100644 (file)
@@ -2720,6 +2720,7 @@ extern void print_obstack_name            PARAMS ((char *, FILE *,
 #endif
 extern void expand_function_end                PARAMS ((const char *, int, int));
 extern void expand_function_start      PARAMS ((tree, int));
+extern void expand_pending_sizes        PARAMS ((tree));
 
 extern int real_onep                   PARAMS ((tree));
 extern int real_twop                   PARAMS ((tree));
This page took 0.088863 seconds and 5 git commands to generate.