From e6460fcfda6ca53b908133761bf6c68ff06c3745 Mon Sep 17 00:00:00 2001 From: mmitchel Date: Tue, 5 Jun 2001 06:47:34 +0000 Subject: [PATCH] * 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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/branches/gcc-3_0-branch@42891 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ChangeLog | 12 +++++++++ gcc/c-decl.c | 33 ++++++++++++++++++++---- gcc/c-tree.h | 7 +++-- gcc/function.c | 32 +++++++++++++++++------ gcc/testsuite/gcc.c-torture/compile/20010605-1.c | 15 +++++++++++ gcc/tree.h | 1 + 6 files changed, 85 insertions(+), 15 deletions(-) create mode 100644 gcc/testsuite/gcc.c-torture/compile/20010605-1.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 7e862e99bae..a1354ce2d8a 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,15 @@ +2001-06-04 Mark Mitchell + + * 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 * doc/install.texi: Update FreeBSD information. Generalize diff --git a/gcc/c-decl.c b/gcc/c-decl.c index 1aa6c61e2c3..f31560b1a52 100644 --- a/gcc/c-decl.c +++ b/gcc/c-decl.c @@ -6082,6 +6082,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. @@ -6449,14 +6452,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; @@ -6700,9 +6717,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; @@ -6737,7 +6759,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. */ @@ -7032,6 +7054,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); } } diff --git a/gcc/c-tree.h b/gcc/c-tree.h index 939ca3fafed..ce0e0bab000 100644 --- a/gcc/c-tree.h +++ b/gcc/c-tree.h @@ -42,12 +42,15 @@ struct lang_identifier enum rid rid_code; }; -/* 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. */ diff --git a/gcc/function.c b/gcc/function.c index a1717a1947b..131ec5aeafe 100644 --- a/gcc/function.c +++ b/gcc/function.c @@ -6263,6 +6263,29 @@ expand_main_function () 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. @@ -6497,14 +6520,7 @@ expand_function_start (subr, parms_have_cleanups) tail_recursion_reentry = emit_note (NULL_PTR, 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 index 00000000000..036b796982e --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/compile/20010605-1.c @@ -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; +} diff --git a/gcc/tree.h b/gcc/tree.h index fc670440231..6e8000f9ced 100644 --- a/gcc/tree.h +++ b/gcc/tree.h @@ -2727,6 +2727,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)); -- 2.11.4.GIT