aboutsummaryrefslogtreecommitdiff
path: root/gcc/c-decl.c
diff options
context:
space:
mode:
authorMark Mitchell <mark@codesourcery.com>2003-04-01 07:35:11 +0000
committerMark Mitchell <mmitchel@gcc.gnu.org>2003-04-01 07:35:11 +0000
commit46e33d43a2f80c82284832820287e118c7e7c65c (patch)
tree20f14569b12a88ace119697818b500699afb7a34 /gcc/c-decl.c
parent6fa91a1d0b0546b6cfeb91dee5d9b53b58cd04b8 (diff)
downloadgcc-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.c43
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)