diff options
author | Dominique d'Humieres <dominiq@gcc.gnu.org> | 2019-05-01 19:40:22 +0200 |
---|---|---|
committer | Dominique d'Humieres <dominiq@gcc.gnu.org> | 2019-05-01 19:40:22 +0200 |
commit | db9c37294126d7c918b0cc918bd73feade0599c2 (patch) | |
tree | ead616d93576d559efec6dca4437939b85eb2c28 /gcc/fortran/match.c | |
parent | d36405344205c58beb1947719345ec80fdc00a34 (diff) | |
download | gcc-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.c | 84 |
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; |