aboutsummaryrefslogtreecommitdiff
path: root/gcc/fortran/match.c
diff options
context:
space:
mode:
authorDominique d'Humieres <dominiq@gcc.gnu.org>2019-05-01 19:40:22 +0200
committerDominique d'Humieres <dominiq@gcc.gnu.org>2019-05-01 19:40:22 +0200
commitdb9c37294126d7c918b0cc918bd73feade0599c2 (patch)
treeead616d93576d559efec6dca4437939b85eb2c28 /gcc/fortran/match.c
parentd36405344205c58beb1947719345ec80fdc00a34 (diff)
downloadgcc-db9c37294126d7c918b0cc918bd73feade0599c2.zip
gcc-db9c37294126d7c918b0cc918bd73feade0599c2.tar.gz
gcc-db9c37294126d7c918b0cc918bd73feade0599c2.tar.bz2
re PR fortran/60144 (Misleading error message when missing "then" after "if" and "else if")
2019-05-01 Dominique d'Humieres <dominiq@gcc.gnu.org> PR fortran/60144 * match.c (gfc_match_parens): Change the location for missing ')'. (gfc_match_if): Detect a missing '('. Remove the spurious named constant error. Change the wording of some errors. (gfc_match_else): Change the wording of an error. (gfc_match_elseif): Detect a missing '('. Improve the matching process to get a better syntax analysis. PR fortran/60144 * gfortran.dg/block_name_2.f90: Adjust dg-error. * gfortran.dg/dec_type_print_3.f90.f90: Likewise * gfortran.dg/pr60144.f90: New test. From-SVN: r270776
Diffstat (limited to 'gcc/fortran/match.c')
-rw-r--r--gcc/fortran/match.c84
1 files changed, 53 insertions, 31 deletions
diff --git a/gcc/fortran/match.c b/gcc/fortran/match.c
index eba428f..268217a4 100644
--- a/gcc/fortran/match.c
+++ b/gcc/fortran/match.c
@@ -262,6 +262,8 @@ gfc_match_parens (void)
for (;;)
{
+ if (count > 0)
+ where = gfc_current_locus;
c = gfc_next_char_literal (instring);
if (c == '\n')
break;
@@ -281,7 +283,6 @@ gfc_match_parens (void)
if (c == '(' && quote == ' ')
{
count++;
- where = gfc_current_locus;
}
if (c == ')' && quote == ' ')
{
@@ -292,14 +293,10 @@ gfc_match_parens (void)
gfc_current_locus = old_loc;
- if (count > 0)
- {
- gfc_error ("Missing %<)%> in statement at or before %L", &where);
- return MATCH_ERROR;
- }
- if (count < 0)
+ if (count != 0)
{
- gfc_error ("Missing %<(%> in statement at or before %L", &where);
+ gfc_error ("Missing %qs in statement at or before %L",
+ count > 0? ")":"(", &where);
return MATCH_ERROR;
}
@@ -1495,7 +1492,17 @@ gfc_match_if (gfc_statement *if_type)
old_loc = gfc_current_locus;
- m = gfc_match (" if ( %e", &expr);
+ m = gfc_match (" if ", &expr);
+ if (m != MATCH_YES)
+ return m;
+
+ if (gfc_match_char ('(') != MATCH_YES)
+ {
+ gfc_error ("Missing %<(%> in IF-expression at %C");
+ return MATCH_ERROR;
+ }
+
+ m = gfc_match ("%e", &expr);
if (m != MATCH_YES)
return m;
@@ -1648,30 +1655,17 @@ gfc_match_if (gfc_statement *if_type)
if (flag_dec)
match ("type", gfc_match_print, ST_WRITE)
- /* The gfc_match_assignment() above may have returned a MATCH_NO
- where the assignment was to a named constant. Check that
- special case here. */
- m = gfc_match_assignment ();
- if (m == MATCH_NO)
- {
- gfc_error ("Cannot assign to a named constant at %C");
- gfc_free_expr (expr);
- gfc_undo_symbols ();
- gfc_current_locus = old_loc;
- return MATCH_ERROR;
- }
-
/* All else has failed, so give up. See if any of the matchers has
stored an error message of some sort. */
if (!gfc_error_check ())
- gfc_error ("Unclassifiable statement in IF-clause at %C");
+ gfc_error ("Syntax error in IF-clause after %C");
gfc_free_expr (expr);
return MATCH_ERROR;
got_match:
if (m == MATCH_NO)
- gfc_error ("Syntax error in IF-clause at %C");
+ gfc_error ("Syntax error in IF-clause after %C");
if (m != MATCH_YES)
{
gfc_free_expr (expr);
@@ -1714,7 +1708,7 @@ gfc_match_else (void)
|| gfc_current_block () == NULL
|| gfc_match_eos () != MATCH_YES)
{
- gfc_error ("Unexpected junk after ELSE statement at %C");
+ gfc_error ("Invalid character(s) in ELSE statement after %C");
return MATCH_ERROR;
}
@@ -1735,31 +1729,59 @@ match
gfc_match_elseif (void)
{
char name[GFC_MAX_SYMBOL_LEN + 1];
- gfc_expr *expr;
+ gfc_expr *expr, *then;
+ locus where;
match m;
- m = gfc_match (" ( %e ) then", &expr);
+ if (gfc_match_char ('(') != MATCH_YES)
+ {
+ gfc_error ("Missing %<(%> in ELSE IF expression at %C");
+ return MATCH_ERROR;
+ }
+
+ m = gfc_match (" %e ", &expr);
if (m != MATCH_YES)
return m;
- if (gfc_match_eos () == MATCH_YES)
+ if (gfc_match_char (')') != MATCH_YES)
+ {
+ gfc_error ("Missing %<)%> in ELSE IF expression at %C");
+ goto cleanup;
+ }
+
+ m = gfc_match (" then ", &then);
+
+ where = gfc_current_locus;
+
+ if (m == MATCH_YES && (gfc_match_eos () == MATCH_YES
+ || (gfc_current_block ()
+ && gfc_match_name (name) == MATCH_YES)))
goto done;
+ if (gfc_match_eos () == MATCH_YES)
+ {
+ gfc_error ("Missing THEN in ELSE IF statement after %L", &where);
+ goto cleanup;
+ }
+
if (gfc_match_name (name) != MATCH_YES
|| gfc_current_block () == NULL
|| gfc_match_eos () != MATCH_YES)
{
- gfc_error ("Unexpected junk after ELSE IF statement at %C");
+ gfc_error ("Syntax error in ELSE IF statement after %L", &where);
goto cleanup;
}
if (strcmp (name, gfc_current_block ()->name) != 0)
{
- gfc_error ("Label %qs at %C doesn't match IF label %qs",
- name, gfc_current_block ()->name);
+ gfc_error ("Label %qs after %L doesn't match IF label %qs",
+ name, &where, gfc_current_block ()->name);
goto cleanup;
}
+ if (m != MATCH_YES)
+ return m;
+
done:
new_st.op = EXEC_IF;
new_st.expr1 = expr;