Hi everyone, attached is a rather trivial patch to fix a linker issue when unlimited polymorphism is used and the vtabs of intrinsic types are referenced from two different locations (e.g. module and main program). Gfortran finds the vtab defined in the scope of a module's subroutine and tries to link it to a reference in a subroutine of the main program. Then name mangling takes place (the module's name is prefixed to the vtab's identifier) and the linker later on can not link the reference in the subroutine of the main program to the module's entity. By putting the vtabs of all intrinsic types into the top-level scope this is easily fixed. The linker now is able to find the name (although it is mangled) and linking is fine.
I rather don't understand why the decision to put intrinsic type's vtabs into the local scope was choosen. There are not so many intrinsic types that they can effectively clutter the top-level scope. Instead putting the intrinsic types into local scope bloats the executable, because the same entity is created over and over again. So this time removing two lines of code did the trick. Bootstraps and regtests fine on x86_64-linux-gnu/f21. Ok for trunk? Regards, Andre -- Andre Vehreschild * Email: vehre ad gmx dot de
pr64589_1.clog
Description: Binary data
diff --git a/gcc/fortran/class.c b/gcc/fortran/class.c index 7990399..218973d 100644 --- a/gcc/fortran/class.c +++ b/gcc/fortran/class.c @@ -2511,10 +2511,8 @@ find_intrinsic_vtab (gfc_typespec *ts) sprintf (name, "__vtab_%s", tname); - /* Look for the vtab symbol in various namespaces. */ - gfc_find_symbol (name, gfc_current_ns, 0, &vtab); - if (vtab == NULL) - gfc_find_symbol (name, ns, 0, &vtab); + /* Look for the vtab symbol in the top-level namespace only. */ + gfc_find_symbol (name, ns, 0, &vtab); if (vtab == NULL) { diff --git a/gcc/testsuite/gfortran.dg/pr64589.f90 b/gcc/testsuite/gfortran.dg/pr64589.f90 new file mode 100644 index 0000000..6e65e70 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/pr64589.f90 @@ -0,0 +1,30 @@ +! { dg-do compile } +! Just need to check if compiling and linking is possible. +! +! Check that the _vtab linking issue is resolved. +! Contributed by Damian Rouson <dam...@sourceryinstitute.org> + +module m +contains + subroutine fmt() + class(*), pointer :: arg + select type (arg) + type is (integer) + end select + end subroutine +end module + +program p + call getSuffix() +contains + subroutine makeString(arg1) + class(*) :: arg1 + select type (arg1) + type is (integer) + end select + end subroutine + subroutine getSuffix() + call makeString(1) + end subroutine +end +