aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorPaul Thomas <pault@gcc.gnu.org>2025-05-01 15:22:54 +0100
committerPaul Thomas <pault@gcc.gnu.org>2025-05-01 15:23:11 +0100
commit0abc77da9d704bba55a376bb5c162a54826ab94a (patch)
treef2cbfd1341edd5f7ed3a0e06df26cb70d0c96d7d /gcc
parent05df554536a8d33f4c438cfc7b006b3b2083246a (diff)
downloadgcc-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.cc10
-rw-r--r--gcc/testsuite/gfortran.dg/pr119948.f9050
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