diff options
author | Paul Thomas <pault@gcc.gnu.org> | 2025-05-01 15:22:54 +0100 |
---|---|---|
committer | Paul Thomas <pault@gcc.gnu.org> | 2025-05-01 15:23:11 +0100 |
commit | 0abc77da9d704bba55a376bb5c162a54826ab94a (patch) | |
tree | f2cbfd1341edd5f7ed3a0e06df26cb70d0c96d7d /gcc | |
parent | 05df554536a8d33f4c438cfc7b006b3b2083246a (diff) | |
download | gcc-0abc77da9d704bba55a376bb5c162a54826ab94a.zip gcc-0abc77da9d704bba55a376bb5c162a54826ab94a.tar.gz gcc-0abc77da9d704bba55a376bb5c162a54826ab94a.tar.bz2 |
Fortran: Source allocation of pure function result rejected [PR119948]
2025-05-01 Paul Thomas <pault@gcc.gnu.org>
gcc/fortran
PR fortran/119948
* resolve.cc (gfc_impure_variable): The result of a module
procedure with an interface declaration is not impure even if
the current namespace is not the same as the symbol's.
gcc/testsuite/
PR fortran/119948
* gfortran.dg/pr119948.f90: New test.
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/fortran/resolve.cc | 10 | ||||
-rw-r--r-- | gcc/testsuite/gfortran.dg/pr119948.f90 | 50 |
2 files changed, 60 insertions, 0 deletions
diff --git a/gcc/fortran/resolve.cc b/gcc/fortran/resolve.cc index e51f83b..1e62e94 100644 --- a/gcc/fortran/resolve.cc +++ b/gcc/fortran/resolve.cc @@ -18549,6 +18549,16 @@ gfc_impure_variable (gfc_symbol *sym) if (sym->attr.use_assoc || sym->attr.in_common) return 1; + /* The namespace of a module procedure interface holds the arguments and + symbols, and so the symbol namespace can be different to that of the + procedure. */ + if (sym->ns != gfc_current_ns + && gfc_current_ns->proc_name->abr_modproc_decl + && sym->ns->proc_name->attr.function + && sym->attr.result + && !strcmp (sym->ns->proc_name->name, gfc_current_ns->proc_name->name)) + return 0; + /* Check if the symbol's ns is inside the pure procedure. */ for (ns = gfc_current_ns; ns; ns = ns->parent) { diff --git a/gcc/testsuite/gfortran.dg/pr119948.f90 b/gcc/testsuite/gfortran.dg/pr119948.f90 new file mode 100644 index 0000000..9ecb080 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/pr119948.f90 @@ -0,0 +1,50 @@ +! { dg-do compile } +! +! Test the fix for PR119948, which used to fail as indicated below with, +! "Error: Bad allocate-object at (1) for a PURE procedure" +! +! Contributed by Damian Rouson <damian@archaeologic.codes> +! +module test_m + implicit none + + type test_t + integer, allocatable :: i + end type + + interface + pure module function construct_test(arg) result(test) + implicit none + type(test_t) :: test + type(test_t), intent(in) :: arg + end function + pure module function construct_test_sub(arg) result(test) + implicit none + type(test_t) :: test + type(test_t), intent(in) :: arg + end function + end interface + +contains + module procedure construct_test + allocate(test%i, source = arg%i) ! Used to fail here + end procedure +end module + +submodule (test_m)test_s +contains + module procedure construct_test_sub + allocate(test%i, source = arg%i) ! This was OK. + end procedure +end submodule + + use test_m + type(test_t) :: res, dummy + dummy%i = 42 + res = construct_test (dummy) + if (res%i /= dummy%i) stop 1 + dummy%i = -42 + res = construct_test_sub (dummy) + if (res%i /= dummy%i) stop 2 + deallocate (res%i, dummy%i) +end |