diff --git a/gcc/ChangeLog b/gcc/ChangeLog index be5749bdc79a806768b6ed1c8eb1cb981cdb9f21..f4e7a4f3f0cac16c12200b7166887bdaa931123e 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2005-08-06 Richard Henderson <rth@redhat.com> + + PR 21894 + * tree-nested.c (convert_local_reference): Save and restore val_only + around component_ref and friends. Clear walk_subtrees by default. + 2005-08-06 Peter O'Gorman <peter@pogma.com> PR 21366 diff --git a/gcc/testsuite/gcc.c-torture/compile/nested-2.c b/gcc/testsuite/gcc.c-torture/compile/nested-2.c new file mode 100644 index 0000000000000000000000000000000000000000..6e61b323b6ff05546c8a39c03e296c19cbdc3a86 --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/compile/nested-2.c @@ -0,0 +1,16 @@ +/* PR 21105 */ + +void +CheckFile () +{ + char tagname[10]; + char *a = tagname; + + int validate () + { + return (a == tagname + 4); + } + + if (a == tagname) + validate (); +} diff --git a/gcc/tree-nested.c b/gcc/tree-nested.c index 4f6ec71c40e0494cb90b5aeeb042ee26f7d7f8db..45c9bfee2e004b56317f344f4496a4fd5f3854dd 100644 --- a/gcc/tree-nested.c +++ b/gcc/tree-nested.c @@ -950,7 +950,9 @@ convert_local_reference (tree *tp, int *walk_subtrees, void *data) struct walk_stmt_info *wi = data; struct nesting_info *info = wi->info; tree t = *tp, field, x; + bool save_val_only; + *walk_subtrees = 0; switch (TREE_CODE (t)) { case VAR_DECL: @@ -989,34 +991,31 @@ convert_local_reference (tree *tp, int *walk_subtrees, void *data) break; case ADDR_EXPR: - { - bool save_val_only = wi->val_only; - - wi->val_only = false; - wi->is_lhs = false; - wi->changed = false; - walk_tree (&TREE_OPERAND (t, 0), convert_local_reference, wi, NULL); - wi->val_only = save_val_only; + save_val_only = wi->val_only; + wi->val_only = false; + wi->is_lhs = false; + wi->changed = false; + walk_tree (&TREE_OPERAND (t, 0), convert_local_reference, wi, NULL); + wi->val_only = save_val_only; - /* If we converted anything ... */ - if (wi->changed) - { - tree save_context; + /* If we converted anything ... */ + if (wi->changed) + { + tree save_context; - /* Then the frame decl is now addressable. */ - TREE_ADDRESSABLE (info->frame_decl) = 1; + /* Then the frame decl is now addressable. */ + TREE_ADDRESSABLE (info->frame_decl) = 1; - save_context = current_function_decl; - current_function_decl = info->context; - recompute_tree_invarant_for_addr_expr (t); - current_function_decl = save_context; - - /* If we are in a context where we only accept values, then - compute the address into a temporary. */ - if (save_val_only) - *tp = tsi_gimplify_val (wi->info, t, &wi->tsi); - } - } + save_context = current_function_decl; + current_function_decl = info->context; + recompute_tree_invarant_for_addr_expr (t); + current_function_decl = save_context; + + /* If we are in a context where we only accept values, then + compute the address into a temporary. */ + if (save_val_only) + *tp = tsi_gimplify_val (wi->info, t, &wi->tsi); + } break; case REALPART_EXPR: @@ -1028,6 +1027,7 @@ convert_local_reference (tree *tp, int *walk_subtrees, void *data) /* Go down this entire nest and just look at the final prefix and anything that describes the references. Otherwise, we lose track of whether a NOP_EXPR or VIEW_CONVERT_EXPR needs a simple value. */ + save_val_only = wi->val_only; wi->val_only = true; wi->is_lhs = false; for (; handled_component_p (t); tp = &TREE_OPERAND (t, 0), t = *tp) @@ -1055,6 +1055,7 @@ convert_local_reference (tree *tp, int *walk_subtrees, void *data) } wi->val_only = false; walk_tree (tp, convert_local_reference, wi, NULL); + wi->val_only = save_val_only; break; default: