diff options
author | Francois-Xavier Coudert <coudert@clipper.ens.fr> | 2005-04-08 12:56:59 +0200 |
---|---|---|
committer | François-Xavier Coudert <fxcoudert@gcc.gnu.org> | 2005-04-08 10:56:59 +0000 |
commit | 43e1c5f7205aa500b7ce2d21c51aff439d86704b (patch) | |
tree | 5eaf3ff77e851b8c3bc1b44dda144967413a2c86 /gcc | |
parent | 66beb87a64238f7bc90dbfa6311d2b2faa10845e (diff) | |
download | gcc-43e1c5f7205aa500b7ce2d21c51aff439d86704b.zip gcc-43e1c5f7205aa500b7ce2d21c51aff439d86704b.tar.gz gcc-43e1c5f7205aa500b7ce2d21c51aff439d86704b.tar.bz2 |
re PR fortran/17229 (parser confused by arithmetic if inside an if)
PR fortran/17229
* match.c (gfc_match_arithmetic_if): New function to match an
arithmetic IF statement.
(gfc_match_if): Use gfc_match_arithmetic_if to match an
arithmetic IF statement embedded in a simple IF statement.
* gfortran.dg/pr17229.f: New test.
From-SVN: r97825
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/fortran/ChangeLog | 8 | ||||
-rw-r--r-- | gcc/fortran/match.c | 34 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/gfortran.dg/pr17229.f | 23 |
4 files changed, 70 insertions, 0 deletions
diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog index e114853a..3169f33 100644 --- a/gcc/fortran/ChangeLog +++ b/gcc/fortran/ChangeLog @@ -1,3 +1,11 @@ +2005-04-08 Francois-Xavier Coudert <coudert@clipper.ens.fr> + + PR fortran/17229 + * match.c (gfc_match_arithmetic_if): New function to match an + arithmetic IF statement. + (gfc_match_if): Use gfc_match_arithmetic_if to match an + arithmetic IF statement embedded in a simple IF statement. + 2005-04-07 Steven G. Kargl <kargls@comcast.net> * simplify.c (gfc_simplify_exponent): Fix exponent(tiny(x)) diff --git a/gcc/fortran/match.c b/gcc/fortran/match.c index f433db5..f2b5311 100644 --- a/gcc/fortran/match.c +++ b/gcc/fortran/match.c @@ -899,6 +899,39 @@ cleanup: } +/* We try to match an easy arithmetic IF statement. This only happens + * when just after having encountered a simple IF statement. This code + * is really duplicate with parts of the gfc_match_if code, but this is + * *much* easier. */ +match +gfc_match_arithmetic_if (void) +{ + gfc_st_label *l1, *l2, *l3; + gfc_expr *expr; + match m; + + m = gfc_match (" ( %e ) %l , %l , %l%t", &expr, &l1, &l2, &l3); + if (m != MATCH_YES) + return m; + + if (gfc_reference_st_label (l1, ST_LABEL_TARGET) == FAILURE + || gfc_reference_st_label (l2, ST_LABEL_TARGET) == FAILURE + || gfc_reference_st_label (l3, ST_LABEL_TARGET) == FAILURE) + { + gfc_free_expr (expr); + return MATCH_ERROR; + } + + new_st.op = EXEC_ARITHMETIC_IF; + new_st.expr = expr; + new_st.label = l1; + new_st.label2 = l2; + new_st.label3 = l3; + + return MATCH_YES; +} + + /* The IF statement is a bit of a pain. First of all, there are three forms of it, the simple IF, the IF that starts a block and the arithmetic IF. @@ -1036,6 +1069,7 @@ gfc_match_if (gfc_statement * if_type) match ("exit", gfc_match_exit, ST_EXIT) match ("forall", match_simple_forall, ST_FORALL) match ("go to", gfc_match_goto, ST_GOTO) + match ("if", gfc_match_arithmetic_if, ST_ARITHMETIC_IF) match ("inquire", gfc_match_inquire, ST_INQUIRE) match ("nullify", gfc_match_nullify, ST_NULLIFY) match ("open", gfc_match_open, ST_OPEN) diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index a8f5a50..1eae0ac 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2005-04-06 Francois-Xavier Coudert <coudert@clipper.ens.fr> + + PR fortran/17229 + * gfortran.dg/pr17229.f: New test. + 2005-04-07 Steven G. Kargl <kargls@comcast.net> * gfortran.dg/tiny_1.f90: New test. diff --git a/gcc/testsuite/gfortran.dg/pr17229.f b/gcc/testsuite/gfortran.dg/pr17229.f new file mode 100644 index 0000000..b1a4471 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/pr17229.f @@ -0,0 +1,23 @@ +! PR fortran/17229 +! { dg-do run } + integer i + logical l + + l = .false. + i = -1 + if (l) if (i) 999,999,999 + + l = .true. + if (l) if (i) 10,999,999 + go to 999 + + 10 i = 0 + if (l) if (i) 999,20,999 + go to 999 + + 20 i = 1 + if (l) if (i) 999,999,30 + go to 999 + + 999 call abort + 30 end |