diff options
author | Paul Thomas <pault@gcc.gnu.org> | 2023-05-23 06:33:44 +0100 |
---|---|---|
committer | Paul Thomas <pault@gcc.gnu.org> | 2023-05-23 06:33:44 +0100 |
commit | 056280dea422ba831e40dee9e6769862927998c6 (patch) | |
tree | b810fa5bb1022e50e830e602e4b2676d46e47596 | |
parent | c5300bf3110b44e2742b36f49c2a380abd08d9c5 (diff) | |
download | gcc-056280dea422ba831e40dee9e6769862927998c6.zip gcc-056280dea422ba831e40dee9e6769862927998c6.tar.gz gcc-056280dea422ba831e40dee9e6769862927998c6.tar.bz2 |
Fortran: Allow declaration of finalizable DT in a submodule [PR97122]
2023-05-23 Paul Thomas <pault@gcc.gnu.org>
Steven G. Kargl <kargl@gcc.gnu.org>
gcc/fortran
PR fortran/97122
* decl.cc (variable_decl): Clean up white space issues.
(gfc_match_final_decl): Declaration of finalizable derived type
is allowed in a submodule.
gcc/testsuite/
PR fortran/97122
* gfortran.dg/finalize_8.f03 : Replace testcase that checks
declaration of finalizable derived types in submodules works.
-rw-r--r-- | gcc/fortran/decl.cc | 13 | ||||
-rw-r--r-- | gcc/testsuite/gfortran.dg/finalize_8.f03 | 68 |
2 files changed, 48 insertions, 33 deletions
diff --git a/gcc/fortran/decl.cc b/gcc/fortran/decl.cc index 4c578d0..1de2b23 100644 --- a/gcc/fortran/decl.cc +++ b/gcc/fortran/decl.cc @@ -2697,7 +2697,7 @@ variable_decl (int elem) } gfc_seen_div0 = false; - + /* F2018:C830 (R816) An explicit-shape-spec whose bounds are not constant expressions shall appear only in a subprogram, derived type definition, BLOCK construct, or interface body. */ @@ -2768,7 +2768,7 @@ variable_decl (int elem) if (e->expr_type != EXPR_CONSTANT) { n = gfc_copy_expr (e); - if (!gfc_simplify_expr (n, 1) && gfc_seen_div0) + if (!gfc_simplify_expr (n, 1) && gfc_seen_div0) { m = MATCH_ERROR; goto cleanup; @@ -2783,12 +2783,12 @@ variable_decl (int elem) if (e->expr_type != EXPR_CONSTANT) { n = gfc_copy_expr (e); - if (!gfc_simplify_expr (n, 1) && gfc_seen_div0) + if (!gfc_simplify_expr (n, 1) && gfc_seen_div0) { m = MATCH_ERROR; goto cleanup; } - + if (n->expr_type == EXPR_CONSTANT) gfc_replace_expr (e, n); else @@ -11636,8 +11636,9 @@ gfc_match_final_decl (void) block = gfc_state_stack->previous->sym; gcc_assert (block); - if (!gfc_state_stack->previous || !gfc_state_stack->previous->previous - || gfc_state_stack->previous->previous->state != COMP_MODULE) + if (gfc_state_stack->previous->previous + && gfc_state_stack->previous->previous->state != COMP_MODULE + && gfc_state_stack->previous->previous->state != COMP_SUBMODULE) { gfc_error ("Derived type declaration with FINAL at %C must be in the" " specification part of a MODULE"); diff --git a/gcc/testsuite/gfortran.dg/finalize_8.f03 b/gcc/testsuite/gfortran.dg/finalize_8.f03 index b2027a0..b7fa10d 100644 --- a/gcc/testsuite/gfortran.dg/finalize_8.f03 +++ b/gcc/testsuite/gfortran.dg/finalize_8.f03 @@ -1,35 +1,49 @@ -! { dg-do compile } - -! Parsing of finalizer procedure definitions. -! Check that FINAL-declarations are only allowed on types defined in the -! specification part of a module. - -MODULE final_type +! { dg-do run } +! +! PR97122: Declaration of a finalizable derived type in a submodule +! IS allowed. +! +! Contributed by Ian Harvey <ian_harvey@bigpond.com> +! +MODULE m IMPLICIT NONE -CONTAINS + INTERFACE + MODULE SUBROUTINE other(i) + IMPLICIT NONE + integer, intent(inout) :: i + END SUBROUTINE other + END INTERFACE - SUBROUTINE bar - IMPLICIT NONE + integer :: mi - TYPE :: mytype - INTEGER, ALLOCATABLE :: fooarr(:) - REAL :: foobar - CONTAINS - FINAL :: myfinal ! { dg-error "in the specification part of a MODULE" } - END TYPE mytype - - CONTAINS +END MODULE m - SUBROUTINE myfinal (el) - TYPE(mytype) :: el - END SUBROUTINE myfinal +SUBMODULE (m) s + IMPLICIT NONE - END SUBROUTINE bar + TYPE :: t + integer :: i + CONTAINS + FINAL :: final_t ! Used to be an error here + END TYPE t -END MODULE final_type +CONTAINS -PROGRAM finalizer - IMPLICIT NONE - ! Do nothing here -END PROGRAM finalizer + SUBROUTINE final_t(arg) + TYPE(t), INTENT(INOUT) :: arg + mi = -arg%i + END SUBROUTINE final_t + + module subroutine other(i) ! 'ti' is finalized + integer, intent(inout) :: i + type(t) :: ti + ti%i = i + END subroutine other +END SUBMODULE s + + use m + integer :: i = 42 + call other(i) + if (mi .ne. -i) stop 1 +end |