aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Koenig <tkoenig@gcc.gnu.org>2025-04-13 10:22:07 +0200
committerThomas Koenig <tkoenig@gcc.gnu.org>2025-04-13 10:23:41 +0200
commit64319b2ccae2fdfae06347545e031e56d790dad7 (patch)
tree7e134c6d19b1ea532252e04e8f1d9f9d661270f5
parent1fda2deeea862072543035b6005c65d4c160691f (diff)
downloadgcc-64319b2ccae2fdfae06347545e031e56d790dad7.zip
gcc-64319b2ccae2fdfae06347545e031e56d790dad7.tar.gz
gcc-64319b2ccae2fdfae06347545e031e56d790dad7.tar.bz2
Fix ICE in compare_parameter.
This patch fixes an ICE by setting the typespec of a dummy argument from a global function if known. plus setting the correct flag. This also removes the corresponding assert. I'm not quite sure that the code with the subroutine attribute can be reached, but I thought better safe than sorry. gcc/fortran/ChangeLog: PR fortran/119669 * interface.cc (compare_parameter): Error when mismatch between formal argument as subroutine and function. If the dummy argument is a known function, set its typespec. gcc/testsuite/ChangeLog: PR fortran/119669 * gfortran.dg/interface_59.f90: New test.
-rw-r--r--gcc/fortran/interface.cc31
-rw-r--r--gcc/testsuite/gfortran.dg/interface_59.f9015
2 files changed, 39 insertions, 7 deletions
diff --git a/gcc/fortran/interface.cc b/gcc/fortran/interface.cc
index c702239..1e552a3 100644
--- a/gcc/fortran/interface.cc
+++ b/gcc/fortran/interface.cc
@@ -2534,16 +2534,33 @@ compare_parameter (gfc_symbol *formal, gfc_expr *actual,
gfc_find_symbol (actual_name, gsym->ns, 0, &global_asym);
if (global_asym != NULL)
{
- gcc_assert (formal->attr.function);
- if (!gfc_compare_types (&global_asym->ts, &formal->ts))
+ if (formal->attr.subroutine)
{
- gfc_error ("Type mismatch at %L passing global "
- "function %qs declared at %L (%s/%s)",
- &actual->where, actual_name, &gsym->where,
- gfc_typename (&global_asym->ts),
- gfc_dummy_typename (&formal->ts));
+ gfc_error ("Mismatch between subroutine and "
+ "function at %L", &actual->where);
return false;
}
+ else if (formal->attr.function)
+ {
+ if (!gfc_compare_types (&global_asym->ts,
+ &formal->ts))
+ {
+ gfc_error ("Type mismatch at %L passing global "
+ "function %qs declared at %L (%s/%s)",
+ &actual->where, actual_name,
+ &gsym->where,
+ gfc_typename (&global_asym->ts),
+ gfc_dummy_typename (&formal->ts));
+ return false;
+ }
+ }
+ else
+ {
+ /* The global symbol is a function. Set the formal
+ argument acordingly. */
+ formal->attr.function = 1;
+ formal->ts = global_asym->ts;
+ }
}
}
}
diff --git a/gcc/testsuite/gfortran.dg/interface_59.f90 b/gcc/testsuite/gfortran.dg/interface_59.f90
new file mode 100644
index 0000000..c9ccd67
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/interface_59.f90
@@ -0,0 +1,15 @@
+! { dg-do compile }
+! PR fortran/119669 - this used to generate an ICE.
+
+program a
+ implicit real(a-h,o-z)
+ external abstract_caller, caller, func
+! real func
+ call abstract_caller (caller, func, 1.5)
+ call abstract_caller (caller, func, 1.5)
+end program a
+
+function func (x)
+ real func, x
+ func = x * x - 1.
+end