diff options
author | Steven G. Kargl <kargl@gcc.gnu.org> | 2019-06-26 04:31:14 +0000 |
---|---|---|
committer | Steven G. Kargl <kargl@gcc.gnu.org> | 2019-06-26 04:31:14 +0000 |
commit | b48826985b8b0bba790688ebe717cf626019a415 (patch) | |
tree | dcd0994bcf951cec4155a3ba7327d8e8393e431a /gcc | |
parent | 07525dad06aaaf4c321f386528d8357a55a67b96 (diff) | |
download | gcc-b48826985b8b0bba790688ebe717cf626019a415.zip gcc-b48826985b8b0bba790688ebe717cf626019a415.tar.gz gcc-b48826985b8b0bba790688ebe717cf626019a415.tar.bz2 |
re PR fortran/90988 (Wrong error message with variables named "PUBLIC*")
2019-06-24 Steven G. Kargl <kargl@gcc.gnu.org>
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 <kargl@gcc.gnu.org>
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
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/fortran/decl.c | 119 | ||||
-rw-r--r-- | gcc/testsuite/gfortran.dg/pr90988_1.f90 | 14 | ||||
-rw-r--r-- | gcc/testsuite/gfortran.dg/pr90988_2.f90 | 14 | ||||
-rw-r--r-- | gcc/testsuite/gfortran.dg/pr90988_3.f90 | 14 |
4 files changed, 110 insertions, 51 deletions
diff --git a/gcc/fortran/decl.c b/gcc/fortran/decl.c index d338a94..7e4e8a2 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 0000000..f8b6f13 --- /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 0000000..a684ea2 --- /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 0000000..66ba06b --- /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 |