This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[gfortran] patch PR 17229
- From: FranÃois-Xavier Coudert <Francois-Xavier dot Coudert at lcp dot u-psud dot fr>
- To: gfortran <fortran at gcc dot gnu dot org>, gcc-patches at gcc dot gnu dot org
- Date: Wed, 06 Apr 2005 16:55:34 +0200
- Subject: [gfortran] patch PR 17229
- Organization: Laboratoire de Chimie Physique
This patch fixes PR fortran/17229, enabling gfortran to recognize an
arithmetic IF statement embedded in a simple IF statement:
if (logical) if (integer) 100, 200, 300
This is used in some scientific libraries as FMLIB/ZMLIB and is a regression
WRT g77. *strapped and regested on i686-linux for both 4.0 and mainline. OK?
FX
2005-04-06 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-06 Francois-Xavier Coudert <coudert@clipper.ens.fr>
PR fortran/17229
* gfortran.dg/pr17229.f: New test.
Index: gcc/fortran/match.c
===================================================================
RCS file: /cvsroot/gcc/gcc/gcc/fortran/match.c,v
retrieving revision 1.32
diff -p -u -r1.32 match.c
--- gcc/fortran/match.c 15 Mar 2005 02:52:37 -0000 1.32
+++ gcc/fortran/match.c 6 Apr 2005 14:50:15 -0000
@@ -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)
! 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
30 stop
999 call abort
end