Commit 1f731749 by Mark Mitchell Committed by Mark Mitchell

c-tree.h (lang_decl): Add pending_sizes fields.

	* 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
parent 333e14b0
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> 2001-06-04 Loren J. Rittle <ljrittle@acm.org>
* doc/install.texi: Update FreeBSD information. Generalize * doc/install.texi: Update FreeBSD information. Generalize
......
...@@ -6167,6 +6167,9 @@ store_parm_decls () ...@@ -6167,6 +6167,9 @@ store_parm_decls ()
/* Nonzero if this definition is written with a prototype. */ /* Nonzero if this definition is written with a prototype. */
int prototype = 0; int prototype = 0;
/* The function containing FNDECL, if any. */
tree context = decl_function_context (fndecl);
if (specparms != 0 && TREE_CODE (specparms) != TREE_LIST) if (specparms != 0 && TREE_CODE (specparms) != TREE_LIST)
{ {
/* This case is when the function was defined with an ANSI prototype. /* This case is when the function was defined with an ANSI prototype.
...@@ -6534,14 +6537,28 @@ store_parm_decls () ...@@ -6534,14 +6537,28 @@ store_parm_decls ()
gen_aux_info_record (fndecl, 1, 0, prototype); gen_aux_info_record (fndecl, 1, 0, prototype);
/* Initialize the RTL code for the function. */ /* Initialize the RTL code for the function. */
init_function_start (fndecl, input_filename, lineno); init_function_start (fndecl, input_filename, lineno);
/* Begin the statement tree for this function. */ /* Begin the statement tree for this function. */
DECL_LANG_SPECIFIC (current_function_decl) 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)); 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. */ /* This function is being processed in whole-function mode. */
cfun->x_whole_function_mode_p = 1; cfun->x_whole_function_mode_p = 1;
...@@ -6786,9 +6803,14 @@ c_expand_body (fndecl, nested_p) ...@@ -6786,9 +6803,14 @@ c_expand_body (fndecl, nested_p)
if (flag_syntax_only) if (flag_syntax_only)
return; return;
/* Squirrel away our current state. */
if (nested_p) 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. */ /* Initialize the RTL code for the function. */
current_function_decl = fndecl; current_function_decl = fndecl;
...@@ -6823,7 +6845,7 @@ c_expand_body (fndecl, nested_p) ...@@ -6823,7 +6845,7 @@ c_expand_body (fndecl, nested_p)
/* Allow the body of the function to be garbage collected. */ /* Allow the body of the function to be garbage collected. */
DECL_SAVED_TREE (fndecl) = NULL_TREE; 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 expand_function_end will decrement this variable. So, we set the
variable to one here, so that after the decrement it will remain variable to one here, so that after the decrement it will remain
zero. */ zero. */
...@@ -7116,6 +7138,7 @@ lang_mark_tree (t) ...@@ -7116,6 +7138,7 @@ lang_mark_tree (t)
{ {
ggc_mark (DECL_LANG_SPECIFIC (t)); ggc_mark (DECL_LANG_SPECIFIC (t));
c_mark_lang_decl (&DECL_LANG_SPECIFIC (t)->base); c_mark_lang_decl (&DECL_LANG_SPECIFIC (t)->base);
ggc_mark_tree (DECL_LANG_SPECIFIC (t)->pending_sizes);
} }
} }
......
...@@ -41,12 +41,15 @@ struct lang_identifier ...@@ -41,12 +41,15 @@ struct lang_identifier
tree error_locus, limbo_value; tree error_locus, limbo_value;
}; };
/* Wrapping c_lang_decl in another struct is an unfortunate /* Language-specific declaration information. */
necessity. */
struct lang_decl struct lang_decl
{ {
struct c_lang_decl base; 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. */ /* Macros for access to language-specific slots in an identifier. */
......
...@@ -6270,6 +6270,29 @@ expand_main_function () ...@@ -6270,6 +6270,29 @@ expand_main_function ()
extern struct obstack permanent_obstack; 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 /* Start the RTL for a new function, and set variables used for
emitting RTL. emitting RTL.
SUBR is the FUNCTION_DECL node. SUBR is the FUNCTION_DECL node.
...@@ -6487,14 +6510,7 @@ expand_function_start (subr, parms_have_cleanups) ...@@ -6487,14 +6510,7 @@ expand_function_start (subr, parms_have_cleanups)
tail_recursion_reentry = emit_note (NULL, NOTE_INSN_DELETED); tail_recursion_reentry = emit_note (NULL, NOTE_INSN_DELETED);
/* Evaluate now the sizes of any types declared among the arguments. */ /* Evaluate now the sizes of any types declared among the arguments. */
for (tem = nreverse (get_pending_sizes ()); tem; tem = TREE_CHAIN (tem)) expand_pending_sizes (nreverse (get_pending_sizes ()));
{
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 ();
}
/* Make sure there is a line number after the function entry setup code. */ /* Make sure there is a line number after the function entry setup code. */
force_next_line_note (); force_next_line_note ();
......
int
main (int argc, char **argv)
{
int size = 10;
typedef struct {
char val[size];
} block;
block retframe_block()
{
return *(block*)0;
}
return 0;
}
...@@ -2720,6 +2720,7 @@ extern void print_obstack_name PARAMS ((char *, FILE *, ...@@ -2720,6 +2720,7 @@ extern void print_obstack_name PARAMS ((char *, FILE *,
#endif #endif
extern void expand_function_end PARAMS ((const char *, int, int)); extern void expand_function_end PARAMS ((const char *, int, int));
extern void expand_function_start PARAMS ((tree, 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_onep PARAMS ((tree));
extern int real_twop PARAMS ((tree)); extern int real_twop PARAMS ((tree));
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment