mirror of git://gcc.gnu.org/git/gcc.git
re PR fortran/77978 (stop codes misinterpreted in both f2003 and f2008)
2016-10-17 Steven G. Kargl <kargl@gcc.gnu.org> PR fortran/77978 * match.c (gfc_match_stopcode): Fix error reporting for several deficiencies in matching stop-codes. 2016-10-17 Steven G. Kargl <kargl@gcc.gnu.org> PR fortran/77978 * gfortran.dg/pr77978_1.f90: New test. * gfortran.dg/pr77978_2.f90: Ditto. * gfortran.dg/pr77978_3.f90: Ditto. From-SVN: r241279
This commit is contained in:
parent
8fa18c06a2
commit
4acf205523
|
|
@ -1,3 +1,9 @@
|
||||||
|
2016-10-17 Steven G. Kargl <kargl@gcc.gnu.org>
|
||||||
|
|
||||||
|
PR fortran/77978
|
||||||
|
* match.c (gfc_match_stopcode): Fix error reporting for several
|
||||||
|
deficiencies in matching stop-codes.
|
||||||
|
|
||||||
2016-10-17 Paul Thomas <pault@gcc.gnu.org>
|
2016-10-17 Paul Thomas <pault@gcc.gnu.org>
|
||||||
|
|
||||||
PR fortran/61420
|
PR fortran/61420
|
||||||
|
|
|
||||||
|
|
@ -2731,20 +2731,92 @@ gfc_match_cycle (void)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Match a number or character constant after an (ERROR) STOP or PAUSE
|
/* Match a stop-code after an (ERROR) STOP or PAUSE statement. The
|
||||||
statement. */
|
requirements for a stop-code differ in the standards.
|
||||||
|
|
||||||
|
Fortran 95 has
|
||||||
|
|
||||||
|
R840 stop-stmt is STOP [ stop-code ]
|
||||||
|
R841 stop-code is scalar-char-constant
|
||||||
|
or digit [ digit [ digit [ digit [ digit ] ] ] ]
|
||||||
|
|
||||||
|
Fortran 2003 matches Fortran 95 except R840 and R841 are now R849 and R850.
|
||||||
|
Fortran 2008 has
|
||||||
|
|
||||||
|
R855 stop-stmt is STOP [ stop-code ]
|
||||||
|
R856 allstop-stmt is ALL STOP [ stop-code ]
|
||||||
|
R857 stop-code is scalar-default-char-constant-expr
|
||||||
|
or scalar-int-constant-expr
|
||||||
|
|
||||||
|
For free-form source code, all standards contain a statement of the form:
|
||||||
|
|
||||||
|
A blank shall be used to separate names, constants, or labels from
|
||||||
|
adjacent keywords, names, constants, or labels.
|
||||||
|
|
||||||
|
A stop-code is not a name, constant, or label. So, under Fortran 95 and 2003,
|
||||||
|
|
||||||
|
STOP123
|
||||||
|
|
||||||
|
is valid, but it is invalid Fortran 2008. */
|
||||||
|
|
||||||
static match
|
static match
|
||||||
gfc_match_stopcode (gfc_statement st)
|
gfc_match_stopcode (gfc_statement st)
|
||||||
{
|
{
|
||||||
gfc_expr *e;
|
gfc_expr *e = NULL;
|
||||||
match m;
|
match m;
|
||||||
|
bool f95, f03;
|
||||||
|
|
||||||
e = NULL;
|
/* Set f95 for -std=f95. */
|
||||||
|
f95 = gfc_option.allow_std == (GFC_STD_F95_OBS | GFC_STD_F95 | GFC_STD_F77
|
||||||
|
| GFC_STD_F2008_OBS);
|
||||||
|
|
||||||
|
/* Set f03 for -std=f2003. */
|
||||||
|
f03 = gfc_option.allow_std == (GFC_STD_F95_OBS | GFC_STD_F95 | GFC_STD_F77
|
||||||
|
| GFC_STD_F2008_OBS | GFC_STD_F2003);
|
||||||
|
|
||||||
|
/* Look for a blank between STOP and the stop-code for F2008 or later. */
|
||||||
|
if (gfc_current_form != FORM_FIXED && !(f95 || f03))
|
||||||
|
{
|
||||||
|
char c = gfc_peek_ascii_char ();
|
||||||
|
|
||||||
|
/* Look for end-of-statement. There is no stop-code. */
|
||||||
|
if (c == '\n' || c == '!' || c == ';')
|
||||||
|
goto done;
|
||||||
|
|
||||||
|
if (c != ' ')
|
||||||
|
{
|
||||||
|
gfc_error ("Blank required in %s statement near %C",
|
||||||
|
gfc_ascii_statement (st));
|
||||||
|
return MATCH_ERROR;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (gfc_match_eos () != MATCH_YES)
|
if (gfc_match_eos () != MATCH_YES)
|
||||||
{
|
{
|
||||||
m = gfc_match_init_expr (&e);
|
int stopcode;
|
||||||
|
locus old_locus;
|
||||||
|
|
||||||
|
/* First look for the F95 or F2003 digit [...] construct. */
|
||||||
|
old_locus = gfc_current_locus;
|
||||||
|
m = gfc_match_small_int (&stopcode);
|
||||||
|
if (m == MATCH_YES && (f95 || f03))
|
||||||
|
{
|
||||||
|
if (stopcode < 0)
|
||||||
|
{
|
||||||
|
gfc_error ("STOP code at %C cannot be negative");
|
||||||
|
return MATCH_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (stopcode > 99999)
|
||||||
|
{
|
||||||
|
gfc_error ("STOP code at %C contains too many digits");
|
||||||
|
return MATCH_ERROR;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Reset the locus and now load gfc_expr. */
|
||||||
|
gfc_current_locus = old_locus;
|
||||||
|
m = gfc_match_expr (&e);
|
||||||
if (m == MATCH_ERROR)
|
if (m == MATCH_ERROR)
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
if (m == MATCH_NO)
|
if (m == MATCH_NO)
|
||||||
|
|
@ -2785,6 +2857,22 @@ gfc_match_stopcode (gfc_statement st)
|
||||||
|
|
||||||
if (e != NULL)
|
if (e != NULL)
|
||||||
{
|
{
|
||||||
|
gfc_simplify_expr (e, 0);
|
||||||
|
|
||||||
|
/* Test for F95 and F2003 style STOP stop-code. */
|
||||||
|
if (e->expr_type != EXPR_CONSTANT && (f95 || f03))
|
||||||
|
{
|
||||||
|
gfc_error ("STOP code at %L must be a scalar CHARACTER constant or "
|
||||||
|
"digit[digit[digit[digit[digit]]]]", &e->where);
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Use the machinery for an initialization expression to reduce the
|
||||||
|
stop-code to a constant. */
|
||||||
|
gfc_init_expr_flag = true;
|
||||||
|
gfc_reduce_init_expr (e);
|
||||||
|
gfc_init_expr_flag = false;
|
||||||
|
|
||||||
if (!(e->ts.type == BT_CHARACTER || e->ts.type == BT_INTEGER))
|
if (!(e->ts.type == BT_CHARACTER || e->ts.type == BT_INTEGER))
|
||||||
{
|
{
|
||||||
gfc_error ("STOP code at %L must be either INTEGER or CHARACTER type",
|
gfc_error ("STOP code at %L must be either INTEGER or CHARACTER type",
|
||||||
|
|
@ -2794,8 +2882,7 @@ gfc_match_stopcode (gfc_statement st)
|
||||||
|
|
||||||
if (e->rank != 0)
|
if (e->rank != 0)
|
||||||
{
|
{
|
||||||
gfc_error ("STOP code at %L must be scalar",
|
gfc_error ("STOP code at %L must be scalar", &e->where);
|
||||||
&e->where);
|
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -2807,8 +2894,7 @@ gfc_match_stopcode (gfc_statement st)
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (e->ts.type == BT_INTEGER
|
if (e->ts.type == BT_INTEGER && e->ts.kind != gfc_default_integer_kind)
|
||||||
&& e->ts.kind != gfc_default_integer_kind)
|
|
||||||
{
|
{
|
||||||
gfc_error ("STOP code at %L must be default integer KIND=%d",
|
gfc_error ("STOP code at %L must be default integer KIND=%d",
|
||||||
&e->where, (int) gfc_default_integer_kind);
|
&e->where, (int) gfc_default_integer_kind);
|
||||||
|
|
@ -2816,6 +2902,8 @@ gfc_match_stopcode (gfc_statement st)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
done:
|
||||||
|
|
||||||
switch (st)
|
switch (st)
|
||||||
{
|
{
|
||||||
case ST_STOP:
|
case ST_STOP:
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,10 @@
|
||||||
|
2016-10-17 Steven G. Kargl <kargl@gcc.gnu.org>
|
||||||
|
|
||||||
|
PR fortran/77978
|
||||||
|
* gfortran.dg/pr77978_1.f90: New test.
|
||||||
|
* gfortran.dg/pr77978_2.f90: Ditto.
|
||||||
|
* gfortran.dg/pr77978_3.f90: Ditto.
|
||||||
|
|
||||||
2016-10-17 Paul Thomas <pault@gcc.gnu.org>
|
2016-10-17 Paul Thomas <pault@gcc.gnu.org>
|
||||||
|
|
||||||
PR fortran/61420
|
PR fortran/61420
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,23 @@
|
||||||
|
! { dg-do compile }
|
||||||
|
! { dg-options "-std=f95" }
|
||||||
|
subroutine a1
|
||||||
|
integer, parameter :: i = -666
|
||||||
|
stop i ! { dg-error "cannot be negative" }
|
||||||
|
end subroutine a1
|
||||||
|
|
||||||
|
subroutine a2
|
||||||
|
stop -666 ! { dg-error "cannot be negative" }
|
||||||
|
end subroutine a2
|
||||||
|
|
||||||
|
subroutine a3
|
||||||
|
integer, parameter :: i = 123456
|
||||||
|
stop i ! { dg-error "too many digits" }
|
||||||
|
end subroutine a3
|
||||||
|
|
||||||
|
subroutine a4
|
||||||
|
stop 123456 ! { dg-error "too many digits" }
|
||||||
|
end subroutine a4
|
||||||
|
|
||||||
|
!subroutine a5
|
||||||
|
! stop merge(667,668,.true.)
|
||||||
|
!end subroutine a5
|
||||||
|
|
@ -0,0 +1,5 @@
|
||||||
|
! { dg-do compile }
|
||||||
|
! { dg-options "-std=f2008" }
|
||||||
|
subroutine a1
|
||||||
|
stop666 ! { dg-error "Blank required in STOP" }
|
||||||
|
end subroutine a1
|
||||||
|
|
@ -0,0 +1,23 @@
|
||||||
|
! { dg-do compile }
|
||||||
|
! { dg-options "-std=f2008" }
|
||||||
|
subroutine a1
|
||||||
|
integer, parameter :: i = -666
|
||||||
|
stop i
|
||||||
|
end subroutine a1
|
||||||
|
|
||||||
|
subroutine a2
|
||||||
|
stop -666
|
||||||
|
end subroutine a2
|
||||||
|
|
||||||
|
subroutine a3
|
||||||
|
integer, parameter :: i = 123456
|
||||||
|
stop i
|
||||||
|
end subroutine a3
|
||||||
|
|
||||||
|
subroutine a4
|
||||||
|
stop 123456
|
||||||
|
end subroutine a4
|
||||||
|
|
||||||
|
subroutine a5
|
||||||
|
stop merge(667,668,.true.)
|
||||||
|
end subroutine a5
|
||||||
Loading…
Reference in New Issue