aboutsummaryrefslogtreecommitdiff
path: root/gcc/fortran
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/fortran
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/fortran')
-rw-r--r--gcc/fortran/ChangeLog6
-rw-r--r--gcc/fortran/trans-stmt.c34
2 files changed, 15 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);
}