aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorRichard Henderson <rth@redhat.com>2005-08-07 12:01:09 -0700
committerRichard Henderson <rth@gcc.gnu.org>2005-08-07 12:01:09 -0700
commit455c08cb645ee4c1e64faa02e1d5e137bd66619a (patch)
tree63297c2ddb66e06eb687d562d3b0737c555b8572 /gcc
parentfebfc59a9523bc59d2cf4112bb394f2ee1da83ea (diff)
downloadgcc-455c08cb645ee4c1e64faa02e1d5e137bd66619a.zip
gcc-455c08cb645ee4c1e64faa02e1d5e137bd66619a.tar.gz
gcc-455c08cb645ee4c1e64faa02e1d5e137bd66619a.tar.bz2
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
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog6
-rw-r--r--gcc/testsuite/gcc.c-torture/compile/nested-2.c16
-rw-r--r--gcc/tree-nested.c51
3 files changed, 48 insertions, 25 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index be5749b..f4e7a4f 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 0000000..6e61b32
--- /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 4f6ec71..45c9bfe 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: