aboutsummaryrefslogtreecommitdiff
path: root/gcc/fortran/class.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/fortran/class.c')
-rw-r--r--gcc/fortran/class.c24
1 files changed, 23 insertions, 1 deletions
diff --git a/gcc/fortran/class.c b/gcc/fortran/class.c
index e110f2c..6ac543c 100644
--- a/gcc/fortran/class.c
+++ b/gcc/fortran/class.c
@@ -2190,6 +2190,7 @@ gfc_find_derived_vtab (gfc_symbol *derived)
gfc_namespace *ns;
gfc_symbol *vtab = NULL, *vtype = NULL, *found_sym = NULL, *def_init = NULL;
gfc_symbol *copy = NULL, *src = NULL, *dst = NULL;
+ gfc_gsymbol *gsym = NULL;
/* Find the top-level namespace. */
for (ns = gfc_current_ns; ns; ns = ns->parent)
@@ -2200,6 +2201,20 @@ gfc_find_derived_vtab (gfc_symbol *derived)
if (!derived->attr.unlimited_polymorphic && derived->attr.is_class)
derived = gfc_get_derived_super_type (derived);
+ /* Find the gsymbol for the module of use associated derived types. */
+ if ((derived->attr.use_assoc || derived->attr.used_in_submodule)
+ && !derived->attr.vtype && !derived->attr.is_class)
+ gsym = gfc_find_gsymbol (gfc_gsym_root, derived->module);
+ else
+ gsym = NULL;
+
+ /* Work in the gsymbol namespace if the top-level namespace is a module.
+ This ensures that the vtable is unique, which is required since we use
+ its address in SELECT TYPE. */
+ if (gsym && gsym->ns && ns && ns->proc_name
+ && ns->proc_name->attr.flavor == FL_MODULE)
+ ns = gsym->ns;
+
if (ns)
{
char name[GFC_MAX_SYMBOL_LEN+1], tname[GFC_MAX_SYMBOL_LEN+1];
@@ -2208,7 +2223,14 @@ gfc_find_derived_vtab (gfc_symbol *derived)
sprintf (name, "__vtab_%s", tname);
/* Look for the vtab symbol in various namespaces. */
- gfc_find_symbol (name, gfc_current_ns, 0, &vtab);
+ if (gsym && gsym->ns)
+ {
+ gfc_find_symbol (name, gsym->ns, 0, &vtab);
+ if (vtab)
+ ns = gsym->ns;
+ }
+ if (vtab == NULL)
+ gfc_find_symbol (name, gfc_current_ns, 0, &vtab);
if (vtab == NULL)
gfc_find_symbol (name, ns, 0, &vtab);
if (vtab == NULL)