re PR middle-end/24135 (nonlocal goto from nested function gets 'undefined symbol...
authorRichard Henderson <rth@redhat.com>
Mon, 3 Oct 2005 20:57:45 +0000 (13:57 -0700)
committerRichard Henderson <rth@gcc.gnu.org>
Mon, 3 Oct 2005 20:57:45 +0000 (13:57 -0700)
        PR 24135
        * tree-nested.c (convert_nl_goto_reference): Lookup a translation
        before creating a new one.

From-SVN: r104911

gcc/ChangeLog
gcc/testsuite/gcc.c-torture/execute/pr24135.c [new file with mode: 0644]
gcc/tree-nested.c

index 19dd74e8409843703de0afd10b80f202a2e35595..957ac6cfdd2a7ebe4fcd1563947f105ff4893889 100644 (file)
@@ -1,3 +1,9 @@
+2005-10-03  Richard Henderson  <rth@redhat.com>
+
+       PR 24135
+       * tree-nested.c (convert_nl_goto_reference): Lookup a translation
+       before creating a new one.
+
 2005-10-03  David Edelsohn  <edelsohn@gnu.org>
 
        * config/rs6000/t-aix43 (LDFLAGS): New.
diff --git a/gcc/testsuite/gcc.c-torture/execute/pr24135.c b/gcc/testsuite/gcc.c-torture/execute/pr24135.c
new file mode 100644 (file)
index 0000000..fdeda16
--- /dev/null
@@ -0,0 +1,46 @@
+#ifndef NO_TRAMPOLINES
+extern void abort (void);
+
+int x(int a, int b)
+{
+  __label__ xlab;
+  __label__ xlab2;
+
+  void y(int b)
+    {
+       switch (b)
+        {
+          case 1: goto xlab;
+          case 2: goto xlab;
+        }
+    }
+
+  a = a + 2;
+  y (b);
+
+ xlab:
+  return a;
+
+ xlab2:
+  a++;
+  return a;
+
+}
+
+int main ()
+{
+  int i, j;
+
+  for (j = 1; j <= 2; ++j)
+    for (i = 1; i <= 2; ++i)
+      {
+       int a = x (j, i);
+       if (a != 2 + j)
+         abort ();
+      }
+
+  return 0;
+}
+#else
+int main() { return 0; }
+#endif
index d42c583ce518328770cbed2eb418460ed399ee11..27819db3e445c5bbfb05cb06274d58664197f404 100644 (file)
@@ -1089,7 +1089,7 @@ convert_nl_goto_reference (tree *tp, int *walk_subtrees, void *data)
   struct walk_stmt_info *wi = data;
   struct nesting_info *info = wi->info, *i;
   tree t = *tp, label, new_label, target_context, x, arg, field;
-  struct var_map_elt *elt;
+  struct var_map_elt *elt, dummy;
   void **slot;
 
   *walk_subtrees = 0;
@@ -1110,17 +1110,23 @@ convert_nl_goto_reference (tree *tp, int *walk_subtrees, void *data)
      control transfer.  This new label will be marked LABEL_NONLOCAL; this
      mark will trigger proper behavior in the cfg, as well as cause the
      (hairy target-specific) non-local goto receiver code to be generated
-     when we expand rtl.  */
-  new_label = create_artificial_label ();
-  DECL_NONLOCAL (new_label) = 1;
-
-  /* Enter this association into var_map so that we can insert the new
-     label into the IL during a second pass.  */
-  elt = ggc_alloc (sizeof (*elt));
-  elt->old = label;
-  elt->new = new_label;
-  slot = htab_find_slot (i->var_map, elt, INSERT);
-  *slot = elt;
+     when we expand rtl.  Enter this association into var_map so that we
+     can insert the new label into the IL during a second pass.  */
+  dummy.old = label;
+  slot = htab_find_slot (i->var_map, &dummy, INSERT);
+  elt = *slot;
+  if (elt == NULL)
+    {
+      new_label = create_artificial_label ();
+      DECL_NONLOCAL (new_label) = 1;
+
+      elt = ggc_alloc (sizeof (*elt));
+      elt->old = label;
+      elt->new = new_label;
+      *slot = elt;
+    }
+  else
+    new_label = elt->new;
   
   /* Build: __builtin_nl_goto(new_label, &chain->nl_goto_field).  */
   field = get_nl_goto_field (i);