From 7e3365b7cc2a685c5191b755964ac5db75469ee6 Mon Sep 17 00:00:00 2001 From: kenner Date: Mon, 29 Nov 2004 01:03:15 +0000 Subject: [PATCH] * tree-nested.c (check_for_nested_with_variably_modified): New. (create_nesting_tree): Call it. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@91449 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ChangeLog | 3 +++ gcc/tree-nested.c | 48 +++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 50 insertions(+), 1 deletion(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 87d29bc7e01..38eb985f09f 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,8 @@ 2004-11-28 Richard Kenner + * tree-nested.c (check_for_nested_with_variably_modified): New. + (create_nesting_tree): Call it. + * tree-ssa-alias.c (compute_points_to_and_addr_escapes): Remove special code for assigning to non-pointer. (is_escape_site): If RHS is a conversion between pointer and integer diff --git a/gcc/tree-nested.c b/gcc/tree-nested.c index 3f500f6f138..76396ca96f8 100644 --- a/gcc/tree-nested.c +++ b/gcc/tree-nested.c @@ -612,8 +612,49 @@ walk_all_functions (walk_tree_fn callback, struct nesting_info *root) } while (root); } - +/* We have to check for a fairly pathalogical case. The operands of function + nested function are to be interpreted in the context of the enclosing + function. So if any are variably-sized, they will get remapped when the + enclosing function is inlined. But that remapping would also have to be + done in the types of the PARM_DECLs of the nested function, meaning the + argument types of that function will disagree with the arguments in the + calls to that function. So we'd either have to make a copy of the nested + function corresponding to each time the enclosing function was inlined or + add a VIEW_CONVERT_EXPR to each such operand for each call to the nested + function. The former is not practical. The latter would still require + detecting this case to know when to add the conversions. So, for now at + least, we don't inline such an enclosing function. + + We have to do that check recursively, so here return indicating whether + FNDECL has such a nested function. ORIG_FN is the function we were + trying to inline to use for checking whether any argument is variably + modified by anything in it. + + It would be better to do this in tree-inline.c so that we could give + the appropriate warning for why a function can't be inlined, but that's + too late since the nesting structure has already been flattened and + adding a flag just to record this fact seems a waste of a flag. */ + +static bool +check_for_nested_with_variably_modified (tree fndecl, tree orig_fndecl) +{ + struct cgraph_node *cgn = cgraph_node (fndecl); + tree arg; + + for (cgn = cgn->nested; cgn ; cgn = cgn->next_nested) + { + for (arg = DECL_ARGUMENTS (cgn->decl); arg; arg = TREE_CHAIN (arg)) + if (variably_modified_type_p (TREE_TYPE (arg), 0), orig_fndecl) + return true; + + if (check_for_nested_with_variably_modified (cgn->decl, orig_fndecl)) + return true; + } + + return false; +} + /* Construct our local datastructure describing the function nesting tree rooted by CGN. */ @@ -632,6 +673,11 @@ create_nesting_tree (struct cgraph_node *cgn) info->inner = sub; } + /* See discussion at check_for_nested_with_variably_modified for a + discussion of why this has to be here. */ + if (check_for_nested_with_variably_modified (info->context, info->context)) + DECL_UNINLINABLE (info->context) = true; + return info; } -- 2.11.0