From 46e33d43a2f80c82284832820287e118c7e7c65c Mon Sep 17 00:00:00 2001 From: Mark Mitchell Date: Tue, 1 Apr 2003 07:35:11 +0000 Subject: [PATCH] re PR middle-end/9936 (ICE with local function and variable-length 2d array) PR c/9936 * c-decl.c (grokdeclarator): Clear SAVE_EXPR_CONTEXT for variably-sized arrays in parameters. (set_save_expr_context): New function. (c_expand_body): Use it, via walk_tree. PR c/9936 * gcc.dg/20030331-2.c: New test. From-SVN: r65128 --- gcc/ChangeLog | 8 ++++++++ gcc/c-decl.c | 43 ++++++++++++++++++++++++++++++++++++++- gcc/testsuite/ChangeLog | 5 +++++ gcc/testsuite/gcc.dg/20030331-2.c | 10 +++++++++ 4 files changed, 65 insertions(+), 1 deletion(-) create mode 100644 gcc/testsuite/gcc.dg/20030331-2.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 01ca1ce..a2ebf09 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,11 @@ +2003-03-31 Mark Mitchell + + PR c/9936 + * c-decl.c (grokdeclarator): Clear SAVE_EXPR_CONTEXT for + variably-sized arrays in parameters. + (set_save_expr_context): New function. + (c_expand_body): Use it, via walk_tree. + 2003-03-31 Eric Christopher * combine.c (can_combine_p): Allow ZERO_EXTRACT and STRICT_LOW_PART. diff --git a/gcc/c-decl.c b/gcc/c-decl.c index c9dd711..e0354f0 100644 --- a/gcc/c-decl.c +++ b/gcc/c-decl.c @@ -4103,7 +4103,20 @@ grokdeclarator (declarator, declspecs, decl_context, initialized) } if (size_varies) - itype = variable_size (itype); + { + /* We must be able to distinguish the + SAVE_EXPR_CONTEXT for the variably-sized type + so that we can set it correctly in + set_save_expr_context. The convention is + that all SAVE_EXPRs that need to be reset + have NULL_TREE for their SAVE_EXPR_CONTEXT. */ + tree cfd = current_function_decl; + if (decl_context == PARM) + current_function_decl = NULL_TREE; + itype = variable_size (itype); + if (decl_context == PARM) + current_function_decl = cfd; + } itype = build_index_type (itype); } } @@ -6508,6 +6521,25 @@ c_expand_deferred_function (fndecl) } } +/* Called to move the SAVE_EXPRs for parameter declarations in a + nested function into the nested function. DATA is really the + nested FUNCTION_DECL. */ + +static tree +set_save_expr_context (tree *tp, + int *walk_subtrees, + void *data) +{ + if (TREE_CODE (*tp) == SAVE_EXPR && !SAVE_EXPR_CONTEXT (*tp)) + SAVE_EXPR_CONTEXT (*tp) = (tree) data; + /* Do not walk back into the SAVE_EXPR_CONTEXT; that will cause + circularity. */ + else if (DECL_P (*tp)) + *walk_subtrees = 0; + + return NULL_TREE; +} + /* Generate the RTL for the body of FNDECL. If NESTED_P is nonzero, then we are already in the process of generating RTL for another function. If can_defer_p is zero, we won't attempt to defer the @@ -6548,6 +6580,15 @@ c_expand_body_1 (fndecl, nested_p) /* Set up parameters and prepare for return, for the function. */ expand_function_start (fndecl, 0); + /* If the function has a variably modified type, there may be + SAVE_EXPRs in the parameter types. Their context must be set to + refer to this function; they cannot be expanded in the containing + function. */ + if (decl_function_context (fndecl) + && variably_modified_type_p (TREE_TYPE (fndecl))) + walk_tree (&TREE_TYPE (fndecl), set_save_expr_context, fndecl, + NULL); + /* If this function is `main', emit a call to `__main' to run global initializers, etc. */ if (DECL_NAME (fndecl) diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index ec6a418..c6196fb 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,5 +1,10 @@ 2003-03-31 Mark Mitchell + PR c/9936 + * gcc.dg/20030331-2.c: New test. + +2003-03-31 Mark Mitchell + PR c++/10278 * g++.dg/parse/crash2.C: New test. diff --git a/gcc/testsuite/gcc.dg/20030331-2.c b/gcc/testsuite/gcc.dg/20030331-2.c new file mode 100644 index 0000000..210524d --- /dev/null +++ b/gcc/testsuite/gcc.dg/20030331-2.c @@ -0,0 +1,10 @@ +// { dg-options "" } + +int foo() { + int yd; + float in[1][yd]; + + static void bar() { + printf("%p\n",in[0]); + } +} -- 2.7.4