re PR fortran/41403 (miscompilation of goto/label using code)
authorDaniel Kraft <d@domob.eu>
Mon, 5 Oct 2009 13:15:35 +0000 (15:15 +0200)
committerDaniel Kraft <domob@gcc.gnu.org>
Mon, 5 Oct 2009 13:15:35 +0000 (15:15 +0200)
2009-10-05  Daniel Kraft  <d@domob.eu>

PR fortran/41403
* trans-stmt.c (gfc_trans_goto): Ignore statement list on assigned goto
if it is present.

2009-10-05  Daniel Kraft  <d@domob.eu>

PR fortran/41403
* gfortran.dg/goto_6.f: New test.
* gfortran.dg/goto_7.f: New test.

From-SVN: r152448

gcc/fortran/ChangeLog
gcc/fortran/trans-stmt.c
gcc/testsuite/ChangeLog
gcc/testsuite/gfortran.dg/goto_6.f [new file with mode: 0644]
gcc/testsuite/gfortran.dg/goto_7.f [new file with mode: 0644]

index c3444d4..a844ed6 100644 (file)
@@ -1,3 +1,9 @@
+2009-10-05  Daniel Kraft  <d@domob.eu>
+
+       PR fortran/41403
+       * trans-stmt.c (gfc_trans_goto): Ignore statement list on assigned goto
+       if it is present.
+
 2009-10-03  Richard Guenther  <rguenther@suse.de>
 
        * options.c (gfc_post_options): Handle -flto and -fwhopr.
index 9d3197d..05ed23e 100644 (file)
@@ -159,31 +159,15 @@ gfc_trans_goto (gfc_code * code)
 
   assigned_goto = GFC_DECL_ASSIGN_ADDR (se.expr);
 
-  code = code->block;
-  if (code == NULL)
-    {
-      target = fold_build1 (GOTO_EXPR, void_type_node, assigned_goto);
-      gfc_add_expr_to_block (&se.pre, target);
-      return gfc_finish_block (&se.pre);
-    }
-
-  /* Check the label list.  */
-  do
-    {
-      target = gfc_get_label_decl (code->label1);
-      tmp = gfc_build_addr_expr (pvoid_type_node, target);
-      tmp = fold_build2 (EQ_EXPR, boolean_type_node, tmp, assigned_goto);
-      tmp = build3_v (COND_EXPR, tmp,
-                     fold_build1 (GOTO_EXPR, void_type_node, target),
-                     build_empty_stmt (input_location));
-      gfc_add_expr_to_block (&se.pre, tmp);
-      code = code->block;
-    }
-  while (code != NULL);
-  gfc_trans_runtime_check (true, false, boolean_true_node, &se.pre, &loc,
-                          "Assigned label is not in the list");
-
-  return gfc_finish_block (&se.pre); 
+  /* We're going to ignore a label list.  It does not really change the
+     statement's semantics (because it is just a further restriction on
+     what's legal code); before, we were comparing label addresses here, but
+     that's a very fragile business and may break with optimization.  So
+     just ignore it.  */
+
+  target = fold_build1 (GOTO_EXPR, void_type_node, assigned_goto);
+  gfc_add_expr_to_block (&se.pre, target);
+  return gfc_finish_block (&se.pre);
 }
 
 
index 699be08..2631d12 100644 (file)
@@ -1,3 +1,9 @@
+2009-10-05  Daniel Kraft  <d@domob.eu>
+
+       PR fortran/41403
+       * gfortran.dg/goto_6.f: New test.
+       * gfortran.dg/goto_7.f: New test.
+
 2009-10-03  Ben Elliston  <bje@au.ibm.com>
            Bill Maddox  <maddox@google.com>
            Cary Coutant  <ccoutant@google.com>
diff --git a/gcc/testsuite/gfortran.dg/goto_6.f b/gcc/testsuite/gfortran.dg/goto_6.f
new file mode 100644 (file)
index 0000000..5b054b6
--- /dev/null
@@ -0,0 +1,24 @@
+! { dg-do run }
+! { dg-options "-w" }
+
+! PR fortran/41403
+! Assigned-goto with label list used to compare label addresses which
+! failed with optimization.  Check this works correctly now.
+! This is the most reduced Fortran code from the PR.
+
+      IVFAIL=0
+      ASSIGN 1263 TO I
+      GO TO I, (1262,1263,1264)
+ 1262 ICON01 = 1262
+      GO TO 1265
+ 1263 ICON01 = 1263
+      GO TO 1265
+ 1264 ICON01 = 1264
+ 1265 CONTINUE
+41260 IF ( ICON01 - 1263 )  21260, 11260, 21260
+11260 IVPASS = IVPASS + 1
+      GO TO 1271
+21260 IVFAIL = IVFAIL + 1
+ 1271 CONTINUE
+      IF (IVFAIL /= 0) CALL abort ()
+      END
diff --git a/gcc/testsuite/gfortran.dg/goto_7.f b/gcc/testsuite/gfortran.dg/goto_7.f
new file mode 100644 (file)
index 0000000..e230b7b
--- /dev/null
@@ -0,0 +1,14 @@
+! { dg-do compile }
+! { dg-options "-std=legacy" }
+
+! Check for error message when computed and assigned gotos reference
+! illegal label numbers.
+
+      ASSIGN 1 TO I
+      GOTO (1, 2, 3, 42), 2 ! { dg-error "is never defined" }
+      GOTO I, (1, 2, 3, 43) ! { dg-error "is never defined" }
+ 1    CONTINUE
+ 2    CONTINUE
+ 3    CONTINUE
+c     No label 42 or 43.
+      END