[Fortran] Fix PR 24878, checking actual arguments against global symbols
Checks
| Context |
Check |
Description |
| linaro-tcwg-bot/tcwg_gcc_build--master-arm |
success
|
Build passed
|
| linaro-tcwg-bot/tcwg_gcc_check--master-arm |
success
|
Test passed
|
| linaro-tcwg-bot/tcwg_gcc_build--master-aarch64 |
success
|
Build passed
|
| linaro-tcwg-bot/tcwg_simplebootstrap_build--master-aarch64-bootstrap |
success
|
Build passed
|
| linaro-tcwg-bot/tcwg_gcc_check--master-aarch64 |
success
|
Test passed
|
| linaro-tcwg-bot/tcwg_simplebootstrap_build--master-arm-bootstrap |
success
|
Build passed
|
Commit Message
Hello world,
this fixes a rather old PR from 2005, where a subroutine
could be passed and called as a function. This patch checks
for that, also for the reverse, and for wrong types of functions.
I expect that this will find a few bugs in dusty deck code...
Regression-tested. OK for trunk?
Best regards
Thomas
Test procedure dummy arguments against global symbols, if available.
gcc/fortran/ChangeLog:
PR fortran/24878
* interface.cc (compare_parameter): Check global subroutines
passed as actual arguments for subroutine / function and
function type.
gcc/testsuite/ChangeLog:
PR fortran/24878
* gfortran.dg/interface_51.f90: New test.
Comments
Hi Thomas,
Am 08.02.25 um 15:31 schrieb Thomas Koenig:
> Hello world,
>
> this fixes a rather old PR from 2005, where a subroutine
> could be passed and called as a function. This patch checks
> for that, also for the reverse, and for wrong types of functions.
looks good, just two minor comments:
+ actual_name = act_sym->name ? act_sym->name : act_sym->name;
Why not just
+ actual_name = act_sym->name;
?
+ gfc_error ("Type mismatch passing global function %qs "
+ "declared at %L at %L (%s/%s)", actual_name,
+ &gsym->where, &actual->where,
+ gfc_typename (&global_asym->ts),
+ gfc_dummy_typename (&formal->ts));
These result in lines exceeding column 80.
I am also not a native speaker, but "at %L at %L" sounds strange to me.
Could you find a minor rewording?
> I expect that this will find a few bugs in dusty deck code...
... we'll see ... ;-)
> Regression-tested. OK for trunk?
OK. Thanks for the patch!
Harald
> Best regards
>
> Thomas
>
> Test procedure dummy arguments against global symbols, if available.
>
> gcc/fortran/ChangeLog:
>
> PR fortran/24878
> * interface.cc (compare_parameter): Check global subroutines
> passed as actual arguments for subroutine / function and
> function type.
>
> gcc/testsuite/ChangeLog:
>
> PR fortran/24878
> * gfortran.dg/interface_51.f90: New test.
Am 08.02.25 um 22:46 schrieb Harald Anlauf:
> looks good, just two minor comments:
>
> + actual_name = act_sym->name ? act_sym->name : act_sym->name;
>
> Why not just
>
> + actual_name = act_sym->name;
>
> ?
That was a leftover from a previous commit.
>
>
> + gfc_error ("Type mismatch passing global function %qs "
> + "declared at %L at %L (%s/%s)", actual_name,
> + &gsym->where, &actual->where,
> + gfc_typename (&global_asym->ts),
> + gfc_dummy_typename (&formal->ts));
>
> These result in lines exceeding column 80.
Fixed.
> I am also not a native speaker, but "at %L at %L" sounds strange to me.
> Could you find a minor rewording?
I tried, but I could not find anything better...
So, if anybody can think of a more clever wording, the patch for
this is pre-approved :-)
Committed as r15-7449, thanks for the review!
Best regards
Thomas
Am 09.02.25 um 20:24 schrieb Jerry D:
>
> "Type mismatch at %L when passing global function %qs "
> "declared at %L (%s/%s)"
Committed as r15-7460-gd2ff1b78d70731db1b7adc1cbac7e44688828370 .
Thanks for the help with the wording!
Best regards
Thomas
@@ -2423,6 +2423,7 @@ compare_parameter (gfc_symbol *formal, gfc_expr *actual,
gfc_component *ppc;
bool codimension = false;
gfc_array_spec *formal_as;
+ const char *actual_name;
/* If the formal arg has type BT_VOID, it's to one of the iso_c_binding
procs c_f_pointer or c_f_procpointer, and we need to accept most
@@ -2487,6 +2488,51 @@ compare_parameter (gfc_symbol *formal, gfc_expr *actual,
return false;
}
+ /* The actual symbol may disagree with a global symbol. If so, issue an
+ error, but only if no previous error has been reported on the formal
+ argument. */
+ actual_name = act_sym->name ? act_sym->name : act_sym->name;
+ if (!formal->error && actual_name)
+ {
+ gfc_gsymbol *gsym;
+ gsym = gfc_find_gsymbol (gfc_gsym_root, actual_name);
+ if (gsym != NULL)
+ {
+ if (gsym->type == GSYM_SUBROUTINE && formal->attr.function)
+ {
+ gfc_error ("Passing global subroutine %qs declared at %L "
+ "as function at %L", actual_name, &gsym->where,
+ &actual->where);
+ return false;
+ }
+ if (gsym->type == GSYM_FUNCTION && formal->attr.subroutine)
+ {
+ gfc_error ("Passing global function %qs declared at %L "
+ "as subroutine at %L", actual_name, &gsym->where,
+ &actual->where);
+ return false;
+ }
+ if (gsym->type == GSYM_FUNCTION)
+ {
+ gfc_symbol *global_asym;
+ 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))
+ {
+ gfc_error ("Type mismatch passing global function %qs "
+ "declared at %L at %L (%s/%s)", actual_name,
+ &gsym->where, &actual->where,
+ gfc_typename (&global_asym->ts),
+ gfc_dummy_typename (&formal->ts));
+ return false;
+ }
+ }
+ }
+ }
+ }
+
if (formal->attr.function && !act_sym->attr.function)
{
gfc_add_function (&act_sym->attr, act_sym->name,
@@ -2501,7 +2547,6 @@ compare_parameter (gfc_symbol *formal, gfc_expr *actual,
return true;
}
-
ppc = gfc_get_proc_ptr_comp (actual);
if (ppc && ppc->ts.interface)
{
new file mode 100644
@@ -0,0 +1,51 @@
+! { dg-do compile }
+
+! PR 24878 - passing a global subroutine as a function, or vice versa,
+! was not caught, nor were type mismatches. Original test case by
+! Uttam Pawar.
+
+program memain
+ implicit none
+ integer subr
+ external subr
+ external i4
+ external r4
+ integer r4
+
+ call foo(subr) ! { dg-error "Passing global subroutine" }
+ call bar(i4) ! { dg-error "Passing global function" }
+ call baz(r4) ! { dg-error "Type mismatch passing global function" }
+end program memain
+
+subroutine foo(ifun)
+ integer(kind=4) ifun
+ external ifun
+ integer y
+!---FNC is not a Function subprogram so calling it
+! as a function is an error.
+ Y=ifun(32)
+end subroutine foo
+
+subroutine bar(sub)
+ call sub
+end subroutine bar
+
+subroutine subr(X) ! { dg-error "Passing global subroutine" }
+ integer x
+ x = 12345
+end subroutine subr
+
+integer(kind=4) function i4() ! { dg-error "Passing global function" }
+ i4 = 42
+end function i4
+
+real(kind=4) function r4() ! { dg-error "Type mismatch passing global function" }
+ r4 = 1.0
+end function r4
+
+subroutine baz(ifun)
+ integer(kind=4) ifun
+ external ifun
+ integer y
+ y = ifun(32)
+end subroutine baz