diff options
author | Mark Mitchell <mark@codesourcery.com> | 2003-04-01 07:35:11 +0000 |
---|---|---|
committer | Mark Mitchell <mmitchel@gcc.gnu.org> | 2003-04-01 07:35:11 +0000 |
commit | 46e33d43a2f80c82284832820287e118c7e7c65c (patch) | |
tree | 20f14569b12a88ace119697818b500699afb7a34 /gcc/c-decl.c | |
parent | 6fa91a1d0b0546b6cfeb91dee5d9b53b58cd04b8 (diff) | |
download | gcc-46e33d43a2f80c82284832820287e118c7e7c65c.zip gcc-46e33d43a2f80c82284832820287e118c7e7c65c.tar.gz gcc-46e33d43a2f80c82284832820287e118c7e7c65c.tar.bz2 |
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
Diffstat (limited to 'gcc/c-decl.c')
-rw-r--r-- | gcc/c-decl.c | 43 |
1 files changed, 42 insertions, 1 deletions
diff --git a/gcc/c-decl.c b/gcc/c-decl.c index c9dd711..e0354f0f 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) |