aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorDaniel Kraft <d@domob.eu>2009-10-05 15:15:35 +0200
committerDaniel Kraft <domob@gcc.gnu.org>2009-10-05 15:15:35 +0200
commit916bd5f07f8a76e05c7f08d5a9b8ac5a21be23d5 (patch)
treed26b2189c89134d7ebe326b93c26899943c204b8 /gcc
parent114bbac6ff31e56fe1df19f2aa88947ae1b4ac62 (diff)
downloadgcc-916bd5f07f8a76e05c7f08d5a9b8ac5a21be23d5.zip
gcc-916bd5f07f8a76e05c7f08d5a9b8ac5a21be23d5.tar.gz
gcc-916bd5f07f8a76e05c7f08d5a9b8ac5a21be23d5.tar.bz2
re PR fortran/41403 (miscompilation of goto/label using code)
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
Diffstat (limited to 'gcc')
-rw-r--r--gcc/fortran/ChangeLog6
-rw-r--r--gcc/fortran/trans-stmt.c34
-rw-r--r--gcc/testsuite/ChangeLog6
-rw-r--r--gcc/testsuite/gfortran.dg/goto_6.f24
-rw-r--r--gcc/testsuite/gfortran.dg/goto_7.f14
5 files changed, 59 insertions, 25 deletions
diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog
index c3444d4..a844ed6 100644
--- a/gcc/fortran/ChangeLog
+++ b/gcc/fortran/ChangeLog
@@ -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.
diff --git a/gcc/fortran/trans-stmt.c b/gcc/fortran/trans-stmt.c
index 9d3197d..05ed23e 100644
--- a/gcc/fortran/trans-stmt.c
+++ b/gcc/fortran/trans-stmt.c
@@ -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);
}
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 699be08..2631d12 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -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
index 0000000..5b054b6
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/goto_6.f
@@ -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
index 0000000..e230b7b
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/goto_7.f
@@ -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