From 455c08cb645ee4c1e64faa02e1d5e137bd66619a Mon Sep 17 00:00:00 2001 From: Richard Henderson <rth@redhat.com> Date: Sun, 7 Aug 2005 12:01:09 -0700 Subject: [PATCH] re PR middle-end/21894 (Invalid operand to binary operator with nested function) PR 21894 * tree-nested.c (convert_local_reference): Save and restore val_only around component_ref and friends. Clear walk_subtrees by default. From-SVN: r102832 --- gcc/ChangeLog | 6 +++ .../gcc.c-torture/compile/nested-2.c | 16 ++++++ gcc/tree-nested.c | 51 ++++++++++--------- 3 files changed, 48 insertions(+), 25 deletions(-) create mode 100644 gcc/testsuite/gcc.c-torture/compile/nested-2.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index be5749bdc79a..f4e7a4f3f0ca 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 000000000000..6e61b323b6ff --- /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 4f6ec71c40e0..45c9bfee2e00 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: -- GitLab