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 

Attachment: 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
+

Reply via email to