diff options
author | Daniel Kraft <d@domob.eu> | 2009-10-05 15:15:35 +0200 |
---|---|---|
committer | Daniel Kraft <domob@gcc.gnu.org> | 2009-10-05 15:15:35 +0200 |
commit | 916bd5f07f8a76e05c7f08d5a9b8ac5a21be23d5 (patch) | |
tree | d26b2189c89134d7ebe326b93c26899943c204b8 /gcc | |
parent | 114bbac6ff31e56fe1df19f2aa88947ae1b4ac62 (diff) | |
download | gcc-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/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/fortran/trans-stmt.c | 34 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/testsuite/gfortran.dg/goto_6.f | 24 | ||||
-rw-r--r-- | gcc/testsuite/gfortran.dg/goto_7.f | 14 |
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 |