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 | |
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')
-rw-r--r-- | gcc/ChangeLog | 8 | ||||
-rw-r--r-- | gcc/c-decl.c | 43 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/20030331-2.c | 10 |
4 files changed, 65 insertions, 1 deletions
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 <mark@codesourcery.com> + + 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 <echristo@redhat.com> * 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..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) 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 <mark@codesourcery.com> + PR c/9936 + * gcc.dg/20030331-2.c: New test. + +2003-03-31 Mark Mitchell <mark@codesourcery.com> + 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]); + } +} |