From b48826985b8b0bba790688ebe717cf626019a415 Mon Sep 17 00:00:00 2001 From: "Steven G. Kargl" Date: Wed, 26 Jun 2019 04:31:14 +0000 Subject: [PATCH] re PR fortran/90988 (Wrong error message with variables named "PUBLIC*") 2019-06-24 Steven G. Kargl PR Fortran/90988 * decl.c (access_attr_decl): Use temporary variable to reduce unreadability of code. Normalize jumping to return. (gfc_match_protected): Fix parsing error. Add comments to explain code. Remove dead code. (gfc_match_private): Use temporary variable to reduce unreadability of code. Fix parsing error. Move code to test for blank PRIVATE. Remove dead code. (gfc_match_public): Move code to test for blank PUBLIC. Fix parsing error. Remove dead code. 2019-06-24 Steven G. Kargl PR Fortran/90988 * gfortran.dg/pr90988_1.f90: New test. * gfortran.dg/pr90988_2.f90: Ditto. * gfortran.dg/pr90988_3.f90: Ditto. From-SVN: r272667 --- gcc/fortran/decl.c | 119 ++++++++++++++---------- gcc/testsuite/gfortran.dg/pr90988_1.f90 | 14 +++ gcc/testsuite/gfortran.dg/pr90988_2.f90 | 14 +++ gcc/testsuite/gfortran.dg/pr90988_3.f90 | 14 +++ 4 files changed, 110 insertions(+), 51 deletions(-) create mode 100644 gcc/testsuite/gfortran.dg/pr90988_1.f90 create mode 100644 gcc/testsuite/gfortran.dg/pr90988_2.f90 create mode 100644 gcc/testsuite/gfortran.dg/pr90988_3.f90 diff --git a/gcc/fortran/decl.c b/gcc/fortran/decl.c index d338a94bc74..7e4e8a29984 100644 --- a/gcc/fortran/decl.c +++ b/gcc/fortran/decl.c @@ -8788,6 +8788,7 @@ access_attr_decl (gfc_statement st) gfc_symbol *sym, *dt_sym; gfc_intrinsic_op op; match m; + gfc_access access = (st == ST_PUBLIC) ? ACCESS_PUBLIC : ACCESS_PRIVATE; if (gfc_match (" ::") == MATCH_NO && gfc_match_space () == MATCH_NO) goto done; @@ -8798,7 +8799,7 @@ access_attr_decl (gfc_statement st) if (m == MATCH_NO) goto syntax; if (m == MATCH_ERROR) - return MATCH_ERROR; + goto done; switch (type) { @@ -8818,18 +8819,12 @@ access_attr_decl (gfc_statement st) && sym->attr.flavor == FL_UNKNOWN) sym->attr.flavor = FL_PROCEDURE; - if (!gfc_add_access (&sym->attr, - (st == ST_PUBLIC) - ? ACCESS_PUBLIC : ACCESS_PRIVATE, - sym->name, NULL)) - return MATCH_ERROR; + if (!gfc_add_access (&sym->attr, access, sym->name, NULL)) + goto done; if (sym->attr.generic && (dt_sym = gfc_find_dt_in_generic (sym)) - && !gfc_add_access (&dt_sym->attr, - (st == ST_PUBLIC) - ? ACCESS_PUBLIC : ACCESS_PRIVATE, - sym->name, NULL)) - return MATCH_ERROR; + && !gfc_add_access (&dt_sym->attr, access, sym->name, NULL)) + goto done; break; @@ -8838,17 +8833,14 @@ access_attr_decl (gfc_statement st) { gfc_intrinsic_op other_op; - gfc_current_ns->operator_access[op] = - (st == ST_PUBLIC) ? ACCESS_PUBLIC : ACCESS_PRIVATE; + gfc_current_ns->operator_access[op] = access; /* Handle the case if there is another op with the same function, for INTRINSIC_EQ vs. INTRINSIC_EQ_OS and so on. */ other_op = gfc_equivalent_op (op); if (other_op != INTRINSIC_NONE) - gfc_current_ns->operator_access[other_op] = - (st == ST_PUBLIC) ? ACCESS_PUBLIC : ACCESS_PRIVATE; - + gfc_current_ns->operator_access[other_op] = access; } else { @@ -8864,8 +8856,7 @@ access_attr_decl (gfc_statement st) if (uop->access == ACCESS_UNKNOWN) { - uop->access = (st == ST_PUBLIC) - ? ACCESS_PUBLIC : ACCESS_PRIVATE; + uop->access = access; } else { @@ -8898,6 +8889,13 @@ gfc_match_protected (void) { gfc_symbol *sym; match m; + char c; + + /* PROTECTED has already been seen, but must be followed by whitespace + or ::. */ + c = gfc_peek_ascii_char (); + if (!gfc_is_whitespace (c) && c != ':') + return MATCH_NO; if (!gfc_current_ns->proc_name || gfc_current_ns->proc_name->attr.flavor != FL_MODULE) @@ -8908,14 +8906,12 @@ gfc_match_protected (void) } + gfc_match (" ::"); + if (!gfc_notify_std (GFC_STD_F2003, "PROTECTED statement at %C")) return MATCH_ERROR; - if (gfc_match (" ::") == MATCH_NO && gfc_match_space () == MATCH_NO) - { - return MATCH_ERROR; - } - + /* PROTECTED has an entity-list. */ if (gfc_match_eos () == MATCH_YES) goto syntax; @@ -8958,39 +8954,46 @@ syntax: match gfc_match_private (gfc_statement *st) { + gfc_state_data *prev; + char c; if (gfc_match ("private") != MATCH_YES) return MATCH_NO; - if (gfc_current_state () != COMP_MODULE - && !(gfc_current_state () == COMP_DERIVED - && gfc_state_stack->previous - && gfc_state_stack->previous->state == COMP_MODULE) - && !(gfc_current_state () == COMP_DERIVED_CONTAINS - && gfc_state_stack->previous && gfc_state_stack->previous->previous - && gfc_state_stack->previous->previous->state == COMP_MODULE)) - { - gfc_error ("PRIVATE statement at %C is only allowed in the " - "specification part of a module"); - return MATCH_ERROR; - } - - if (gfc_current_state () == COMP_DERIVED) + /* Try matching PRIVATE without an access-list. */ + if (gfc_match_eos () == MATCH_YES) { - if (gfc_match_eos () == MATCH_YES) + prev = gfc_state_stack->previous; + if (gfc_current_state () != COMP_MODULE + && !(gfc_current_state () == COMP_DERIVED + && prev && prev->state == COMP_MODULE) + && !(gfc_current_state () == COMP_DERIVED_CONTAINS + && prev->previous && prev->previous->state == COMP_MODULE)) { - *st = ST_PRIVATE; - return MATCH_YES; + gfc_error ("PRIVATE statement at %C is only allowed in the " + "specification part of a module"); + return MATCH_ERROR; } - gfc_syntax_error (ST_PRIVATE); - return MATCH_ERROR; + *st = ST_PRIVATE; + return MATCH_YES; } - if (gfc_match_eos () == MATCH_YES) + /* At this point, PRIVATE must be followed by whitespace or ::. */ + c = gfc_peek_ascii_char (); + if (!gfc_is_whitespace (c) && c != ':') + return MATCH_NO; + + prev = gfc_state_stack->previous; + if (gfc_current_state () != COMP_MODULE + && !(gfc_current_state () == COMP_DERIVED + && prev && prev->state == COMP_MODULE) + && !(gfc_current_state () == COMP_DERIVED_CONTAINS + && prev->previous && prev->previous->state == COMP_MODULE)) { - *st = ST_PRIVATE; - return MATCH_YES; + gfc_error ("PRIVATE statement at %C is only allowed in the " + "specification part of a module"); + return MATCH_ERROR; } *st = ST_ATTR_DECL; @@ -9001,10 +9004,30 @@ gfc_match_private (gfc_statement *st) match gfc_match_public (gfc_statement *st) { + char c; if (gfc_match ("public") != MATCH_YES) return MATCH_NO; + /* Try matching PUBLIC without an access-list. */ + if (gfc_match_eos () == MATCH_YES) + { + if (gfc_current_state () != COMP_MODULE) + { + gfc_error ("PUBLIC statement at %C is only allowed in the " + "specification part of a module"); + return MATCH_ERROR; + } + + *st = ST_PUBLIC; + return MATCH_YES; + } + + /* At this point, PUBLIC must be followed by whitespace or ::. */ + c = gfc_peek_ascii_char (); + if (!gfc_is_whitespace (c) && c != ':') + return MATCH_NO; + if (gfc_current_state () != COMP_MODULE) { gfc_error ("PUBLIC statement at %C is only allowed in the " @@ -9012,12 +9035,6 @@ gfc_match_public (gfc_statement *st) return MATCH_ERROR; } - if (gfc_match_eos () == MATCH_YES) - { - *st = ST_PUBLIC; - return MATCH_YES; - } - *st = ST_ATTR_DECL; return access_attr_decl (ST_PUBLIC); } diff --git a/gcc/testsuite/gfortran.dg/pr90988_1.f90 b/gcc/testsuite/gfortran.dg/pr90988_1.f90 new file mode 100644 index 00000000000..f8b6f133163 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/pr90988_1.f90 @@ -0,0 +1,14 @@ +! { dg-do compile } +module mymod + type :: mytyp + integer :: i + end type mytyp +contains + subroutine mysub + implicit none + type(mytyp) :: a + integer :: publici,publicj + publici = a%i + publicj = a%j ! { dg-error "is not a member" } + end subroutine mysub +end module mymod diff --git a/gcc/testsuite/gfortran.dg/pr90988_2.f90 b/gcc/testsuite/gfortran.dg/pr90988_2.f90 new file mode 100644 index 00000000000..a684ea21d46 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/pr90988_2.f90 @@ -0,0 +1,14 @@ +! { dg-do compile } +module mymod + type :: mytyp + integer :: i + end type mytyp +contains + subroutine mysub + implicit none + type(mytyp) :: a + integer :: privatei,privatej + privatei = a%i + privatej = a%j ! { dg-error "is not a member" } + end subroutine mysub +end module mymod diff --git a/gcc/testsuite/gfortran.dg/pr90988_3.f90 b/gcc/testsuite/gfortran.dg/pr90988_3.f90 new file mode 100644 index 00000000000..66ba06bdf02 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/pr90988_3.f90 @@ -0,0 +1,14 @@ +! { dg-do compile } +module mymod + type :: mytyp + integer :: i + end type mytyp +contains + subroutine mysub + implicit none + type(mytyp) :: a + integer :: protectedi,protectedj + protectedi = a%i + protectedj = a%j ! { dg-error "is not a member" } + end subroutine mysub +end module mymod -- 2.30.2