Skip to content

Commit 70a00dc

Browse files
committed
Fixes for SUBMODULE, MODULE and tests
Fix internal compiler error with new_symbol not found with submodules If the compiler finds one type bound procedure is bound to the separate module procedure, export the separate module procedure dummy arguments. Otherwise, those symbols are not visible for other modules to use. INMODULE bit was also not set, which causes the separate module procedure name is not mangled properly in the backend that causes an undefined error. This only happens when the SMP is declared and defined within the same module. For ST_USERGENERIC symbols, do not use the ST_ALIAS symbol table type for the symbol if its GTYPE field is set. GTYPE is set when the ST_USERGENERIC name overloads a derived type name.
1 parent ab7f15a commit 70a00dc

File tree

7 files changed

+101
-15
lines changed

7 files changed

+101
-15
lines changed

test/f90_correct/src/submod33.f90

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -19,17 +19,16 @@ module mod_set_foo_submod33
1919
Character*8,external :: FOO
2020
Character*26 :: BAR
2121
interface
22-
module subroutine call_foo
23-
end subroutine
22+
module subroutine call_foo
23+
end subroutine
24+
25+
module subroutine check_abc
26+
end subroutine
2427
end interface
2528
end module
2629

2730
submodule (mod_set_foo_submod33) submod_set_foo_submod33
2831
character*3 :: abc
29-
interface
30-
module subroutine check_abc
31-
end subroutine
32-
end interface
3332
contains
3433
module procedure call_foo
3534
print *, FOO(BAR)

tools/flang1/flang1exe/exterf.c

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -378,6 +378,14 @@ static void export(FILE *export_fd, char *export_name, int cleanup)
378378
}
379379
}
380380
break;
381+
case ST_IDENT:
382+
if (for_module) {
383+
if (SCG(sptr) == SC_DUMMY && SCOPEG(SCOPEG(sptr)) != sym_module &&
384+
TBP_BOUND_TO_SMPG(SCOPEG(sptr))) {
385+
queue_symbol(sptr);
386+
}
387+
}
388+
break;
381389
default:
382390
break;
383391
}
@@ -2318,8 +2326,14 @@ export_symbol(int sptr)
23182326
lzprintf(outlz, "C %d %d %s\n", sptr, STYPEG(sptr), SYMNAME(sptr));
23192327
return;
23202328
}
2321-
if (stype == ST_MODULE && sptr != sym_module && !for_inliner)
2329+
if (stype == ST_MODULE && sptr != sym_module && !for_inliner &&
2330+
/* No return when this module has a separate module procedure that
2331+
* implements a type bound procedure. We need to export modules
2332+
* sptr next.
2333+
*/
2334+
!HAS_TBP_BOUND_TO_SMPG(sptr) && ANCESTORG(sym_module) != sptr) {
23222335
return;
2336+
}
23232337
}
23242338

23252339

tools/flang1/flang1exe/interf.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5145,7 +5145,7 @@ fill_ST_MODULE(SYMITEM *ps, int sptr)
51455145
NEEDMODP(sptr, NEEDMODG(0));
51465146
TYPDP(sptr, TYPDG(0));
51475147
PRIVATEP(sptr, PRIVATEG(0));
5148-
5148+
HAS_TBP_BOUND_TO_SMPP(sptr, HAS_TBP_BOUND_TO_SMPG(0));
51495149
stb.stg_base[0] = save_sym0;
51505150

51515151
} /* fill_ST_MODULE */

tools/flang1/flang1exe/module.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -667,7 +667,7 @@ apply_use(MODULE_ID m_id)
667667
INKINDP(pr->local, INKINDG(pr->global));
668668
PDNUMP(pr->local, PDNUMG(pr->global));
669669
copy_specifics(ng, pr->local);
670-
} else if (STYPEG(ng /*pr->global*/) == ST_USERGENERIC) {
670+
} else if (STYPEG(ng /*pr->global*/) == ST_USERGENERIC && !GTYPEG(ng)) {
671671
if (NMPTRG(pr->local) == NMPTRG(pr->global)) {
672672
STYPEP(pr->local, ST_ALIAS);
673673
SYMLKP(pr->local, pr->global);

tools/flang1/flang1exe/semant.c

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2339,6 +2339,17 @@ semant1(int rednum, SST *top)
23392339
* ISSUBMODULEP is used for name mangling.
23402340
*/
23412341
SEPARATEMPP(sptr, TRUE);
2342+
if (IN_MODULE)
2343+
INMODULEP(sptr, TRUE);
2344+
if (SST_FIRSTG(RHS(rhstop))) {
2345+
TBP_BOUND_TO_SMPP(sptr, TRUE);
2346+
/* We also set the HAS_TBP_BOUND_TO_SMP flag on the separate module
2347+
* procedure's module. This indicates that the module contains a
2348+
* separate module procedure declaration to which at least one TBP
2349+
* has been bound.
2350+
*/
2351+
HAS_TBP_BOUND_TO_SMPP(SCOPEG(sptr), TRUE);
2352+
}
23422353
} else {
23432354
SEPARATEMPP(sptr, TRUE);
23442355

@@ -11385,6 +11396,9 @@ semant1(int rednum, SST *top)
1138511396
} else {
1138611397
sptr2 = refsym(SST_SYMG(RHS(rhstop)), OC_OTHER);
1138711398
}
11399+
11400+
if (SEPARATEMPG(sptr2))
11401+
TBP_BOUND_TO_SMPP(sptr2, TRUE);
1138811402

1138911403
if (bindingNameRequiresOverloading(sptr)) {
1139011404
sptr = insert_sym(sptr);

tools/flang1/flang1exe/symtab.c

Lines changed: 60 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,11 @@ typedef struct {
5656
LOGICAL typ8; /* True if the type is altered by -r8 */
5757
} DTIMPL[26 + 26 + 2];
5858

59+
typedef struct {
60+
SPTR dec_sptr;
61+
SPTR def_sptr;
62+
} DEC_DEF_MAP;
63+
5964
static DTIMPL dtimplicit;
6065
static int dtimplicitsize = 0;
6166
static DTIMPL *save_dtimplicit = NULL;
@@ -64,7 +69,7 @@ static int dtimplicitstack = 0;
6469
static void cng_inttyp(int, int);
6570
static void cng_specific(int, int);
6671
static void generate_type_mismatch_errors(SPTR s1, SPTR s2);
67-
72+
static void update_arrdsc(SPTR s, DEC_DEF_MAP *smap, int num_dummies);
6873
/* entry hack? */
6974
static ENTRY onlyentry;
7075

@@ -2863,12 +2868,14 @@ SPTR
28632868
instantiate_interface(SPTR iface)
28642869
{
28652870
int dummies;
2866-
SPTR fval, hashlk_sptr, proc;
2871+
SPTR fval, hashlk_sptr, proc;
2872+
DEC_DEF_MAP *dec_def_map;
28672873
proc = insert_dup_sym(iface);
28682874
gbl.currsub = proc;
28692875

28702876
SCOPEP(proc, SCOPEG(find_explicit_interface(proc)));
28712877
dummies = PARAMCTG(iface);
2878+
NEW(dec_def_map, DEC_DEF_MAP, dummies);
28722879
fval = NOSYM;
28732880

28742881
STYPEP(proc, ST_ENTRY);
@@ -2907,7 +2914,9 @@ instantiate_interface(SPTR iface)
29072914
for (j = 0; j < dummies; ++j) {
29082915
SPTR arg = aux.dpdsc_base[iface_dpdsc + j];
29092916
if (arg > NOSYM) {
2917+
dec_def_map[j].dec_sptr = arg;
29102918
arg = insert_dup_sym(arg);
2919+
dec_def_map[j].def_sptr = arg;
29112920
SCOPEP(arg, proc);
29122921
if (DTY(DTYPEG(arg)) == TY_ARRAY && ASSUMSHPG(arg)) {
29132922
DTYPE elem_dt = array_element_dtype(DTYPEG(arg));
@@ -2920,10 +2929,10 @@ instantiate_interface(SPTR iface)
29202929
get_static_descriptor(arg);
29212930
}
29222931
if (ALLOCATTRG(arg) || POINTERG(arg)) {
2923-
newdsc = sym_get_arg_sec(arg);
2924-
SDSCP(arg, newdsc);
2925-
SCP(newdsc, SC_DUMMY);
2926-
SCOPEP(newdsc, proc);
2932+
if (!SDSCG(arg))
2933+
get_static_descriptor(arg);
2934+
if (!PTROFFG(arg))
2935+
get_all_descriptors(arg);
29272936
}
29282937

29292938
HIDDENP(arg, 0);
@@ -2935,9 +2944,54 @@ instantiate_interface(SPTR iface)
29352944
aux.dpdsc_base[proc_dpdsc + j] = arg;
29362945
}
29372946
}
2947+
2948+
if (ADJARRG(fval)) {
2949+
ADSC *ad;
2950+
int arr_dsc;
2951+
DTYPE elem_dt;
2952+
ad = AD_DPTR(DTYPEG(FVALG(iface)));
2953+
update_arrdsc(fval, dec_def_map, dummies);
2954+
elem_dt = array_element_dtype(DTYPEG(iface));
2955+
arr_dsc = mk_arrdsc();
2956+
DTY(arr_dsc + 1) = elem_dt;
2957+
DTYPEP(fval, arr_dsc);
2958+
trans_mkdescr(fval);
2959+
}
2960+
2961+
FREE(dec_def_map);
2962+
29382963
return proc;
29392964
}
29402965

2966+
/** \brief Update array bound AST SPTRs (old_sptr) using newly created SPTRs
2967+
(new_sptr) by referring to DEC_DEF_MAP. The DEC_DEF_MAP is a struct
2968+
which contains mapping info from the old_sptr to new_sptr.
2969+
*/
2970+
static void
2971+
update_arrdsc(SPTR s, DEC_DEF_MAP *smap, int num_dummies) {
2972+
int i, j;
2973+
SPTR dec_sptr_lwbd, dec_sptr_upbd;
2974+
ADSC *ad;
2975+
ad = AD_DPTR(DTYPEG(s));
2976+
sem.arrdim.ndim = AD_NUMDIM(ad);
2977+
sem.arrdim.ndefer = AD_DEFER(ad);
2978+
for (i = 0; i < sem.arrdim.ndim; ++i) {
2979+
/* restore arrdsc bound ast info from *ad */
2980+
sem.bounds[i].lwast = AD_LWAST(ad, i);
2981+
sem.bounds[i].upast = AD_UPAST(ad, i);
2982+
2983+
/* update arrdsc bound ast info */
2984+
dec_sptr_lwbd = A_SPTRG(AD_LWBD(ad, i));
2985+
dec_sptr_upbd = A_SPTRG(AD_UPBD(ad, i));
2986+
for (j = 0; j < num_dummies; ++j) {
2987+
if (dec_sptr_lwbd == smap[j].dec_sptr)
2988+
sem.bounds[i].lwast = mk_id(smap[j].def_sptr);
2989+
if (dec_sptr_upbd == smap[j].dec_sptr)
2990+
sem.bounds[i].upast = mk_id(smap[j].def_sptr);
2991+
}
2992+
}
2993+
}
2994+
29412995
/**
29422996
* reinitialize a symbol
29432997
*/

tools/flang1/utils/symtab/symtab.n

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1571,6 +1571,8 @@ for this symbol.
15711571
Flags
15721572
.FL SEPARATEMP
15731573
MODULE SUBROUTINE, MODULE FUNCTION for a separate module procedure.
1574+
.FL TBP_BOUND_TO_SMP f112
1575+
At least one type bound procedure is bound to this separate module procedure.
15741576
.FL IS_INTERFACE
15751577
Set if the procedure symbol is in an interface block.
15761578
.FL IS_PROC_DUMMY f109
@@ -2511,6 +2513,9 @@ Flags
25112513
Used to mark the submodule SUBROUTINE, submodule FUNCTION that is defined
25122514
inside interface and used by submodules. This is used to differentiate
25132515
the normal module SUBROUTINE, FUNCTION, and PROCEDURE.
2516+
.FL HAS_TBP_BOUND_TO_SMP f112
2517+
This flag is set when this module has a derived type with a type bound
2518+
procedure that is implemented by a separate module procedure
25142519
.FL NEEDMOD f1
25152520
If set, an external reference to this module needs to be generated,
25162521
so a link error will occur if a program that USEs this module is linked

0 commit comments

Comments
 (0)