Skip to content

Commit 510f948

Browse files
committed
Fix parse of "<prefix spec> <data type> <prefix spec>"
Like: PURE INTEGER MODULE FUNCTION f1(i) ... END FUNCTION
1 parent 9bdfea3 commit 510f948

File tree

2 files changed

+74
-11
lines changed

2 files changed

+74
-11
lines changed

tools/flang1/flang1exe/semant.c

Lines changed: 72 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,7 @@ static int ident_host_sub = 0;
9999
static void defer_ident_list(int ident, int proc);
100100
static void clear_ident_list();
101101
static void decr_ident_use(int ident, int proc);
102+
static void check_duplicate(bool checker, const char * op);
102103
#ifdef GSCOPEP
103104
static void fixup_ident_bounds(int);
104105
#endif
@@ -141,14 +142,20 @@ static struct {
141142
#define _LEN_ADJ 4
142143
#define _LEN_DEFER 5
143144

145+
/** \brief Subprogram prefix struct defintions for RECURESIVE, PURE,
146+
IMPURE, ELEMENTAL, and MODULE.
147+
*/
144148
static struct subp_prefix_t {
145-
LOGICAL recursive;
146-
LOGICAL pure;
147-
LOGICAL impure;
148-
LOGICAL elemental;
149-
bool module;
149+
bool recursive; /** processing RECURSIVE attribute */
150+
bool pure; /** processing PURE attribute */
151+
bool impure; /** processing IMPURE attribute */
152+
bool elemental; /** processing ELEMENTAL attribute */
153+
bool module; /** processing MODULE attribute */
150154
} subp_prefix;
151155

156+
static void clear_subp_prefix_settings(struct subp_prefix_t *);
157+
static void check_module_prefix();
158+
152159
static int generic_rutype;
153160
static int mscall;
154161
static int cref;
@@ -515,7 +522,7 @@ semant_init(int noparse)
515522
sem.p_dealloc = NULL;
516523
sem.p_dealloc_delete = NULL;
517524
sem.alloc_std = 0;
518-
BZERO(&subp_prefix, struct subp_prefix_t, 1);
525+
clear_subp_prefix_settings(&subp_prefix);
519526
sem.accl.type = 0; /* PUBLIC/PRIVATE statement not yet seen */
520527
sem.accl.next = NULL; /* access list is empty */
521528
sem.in_struct_constr = 0;
@@ -776,7 +783,7 @@ static int restored = 0;
776783
void
777784
semant1(int rednum, SST *top)
778785
{
779-
int sptr, sptr1, sptr2, dtype, dtypeset, ss, numss;
786+
int sptr, sptr1, sptr2, dtype, dtypeset, ss, numss, sptr_temp;
780787
int stype, stype1, i;
781788
int begin, end, count;
782789
int opc;
@@ -1936,7 +1943,7 @@ semant1(int rednum, SST *top)
19361943
push_scope_level(sem.mod_sym, SCOPE_NORMAL);
19371944
push_scope_level(sem.mod_sym, SCOPE_MODULE);
19381945
SST_ASTP(LHS, 0);
1939-
BZERO(&subp_prefix, struct subp_prefix_t, 1);
1946+
clear_subp_prefix_settings(&subp_prefix);
19401947

19411948
/* SUBMODULEs work as if they are hosted within their immediate parents. */
19421949
if (sptr1 > NOSYM) {
@@ -2220,6 +2227,14 @@ semant1(int rednum, SST *top)
22202227
}
22212228
errsev(70);
22222229
}
2230+
/* C1548: checking MODULE prefix for subprograms that were
2231+
declared as separate module procedures */
2232+
if (!sem.interface && subp_prefix.module) {
2233+
sptr_temp = SST_SYMG(RHS(rhstop));
2234+
if (!SEPARATEMPG(sptr_temp) && !SEPARATEMPG(ref_ident(sptr_temp)))
2235+
error(1056, ERR_Severe, gbl.lineno, NULL, NULL);
2236+
}
2237+
22232238
/* First internal subprogram after CONTAINS, semfin may have altered the
22242239
* symbol table
22252240
* (esp. INVOBJ) for the host subprogram processing. Restore the state to
@@ -2309,7 +2324,7 @@ semant1(int rednum, SST *top)
23092324
ELEMENTALP(sptr, subp_prefix.elemental);
23102325
if (subp_prefix.module) {
23112326
if (!IN_MODULE && !INMODULEG(sptr)) {
2312-
ERR310("MODULE prefix allowed only within a module", CNULL);
2327+
ERR310("MODULE prefix allowed only within a module or submodule", CNULL);
23132328
} else if (sem.interface) {
23142329
/* Use SEPARATEMPP to mark this is submod related subroutines,
23152330
* functions, procdures to differentiate regular module. The
@@ -2323,7 +2338,7 @@ semant1(int rednum, SST *top)
23232338
SEPARATEMPP(sptr, TRUE);
23242339
}
23252340
}
2326-
BZERO(&subp_prefix, struct subp_prefix_t, 1);
2341+
clear_subp_prefix_settings(&subp_prefix);
23272342
if (gbl.rutype == RU_FUNC) {
23282343
/* for a FUNCTION (including ENTRY's), compiler created
23292344
* symbols are created to represent the return values and
@@ -2387,6 +2402,7 @@ semant1(int rednum, SST *top)
23872402
* <subr prefix> ::= <prefix spec>
23882403
*/
23892404
case SUBR_PREFIX2:
2405+
check_module_prefix();
23902406
if (sem.interface) {
23912407
/* set curr_scope to parent's scope, so subprogram ID
23922408
* gets scope of parent */
@@ -2411,6 +2427,7 @@ semant1(int rednum, SST *top)
24112427
* <prefix> ::= RECURSIVE |
24122428
*/
24132429
case PREFIX1:
2430+
check_duplicate(subp_prefix.recursive, "RECURSIVE");
24142431
subp_prefix.recursive = TRUE;
24152432
if (subp_prefix.elemental) {
24162433
errsev(460);
@@ -2420,12 +2437,14 @@ semant1(int rednum, SST *top)
24202437
* <prefix> ::= PURE |
24212438
*/
24222439
case PREFIX2:
2440+
check_duplicate(subp_prefix.pure, "PURE");
24232441
subp_prefix.pure = TRUE;
24242442
break;
24252443
/*
24262444
* <prefix> ::= ELEMENTAL |
24272445
*/
24282446
case PREFIX3:
2447+
check_duplicate(subp_prefix.elemental, "ELEMENTAL");
24292448
subp_prefix.elemental = TRUE;
24302449
if (subp_prefix.recursive) {
24312450
errsev(460);
@@ -2443,13 +2462,15 @@ semant1(int rednum, SST *top)
24432462
* <prefix> ::= IMPURE
24442463
*/
24452464
case PREFIX5:
2465+
check_duplicate(subp_prefix.impure, "IMPURE");
24462466
subp_prefix.impure = TRUE;
24472467
break;
24482468

24492469
/*
24502470
* <prefix> ::= MODULE
24512471
*/
24522472
case PREFIX6:
2473+
check_duplicate(subp_prefix.module, "MODULE");
24532474
subp_prefix.module = TRUE;
24542475
break;
24552476

@@ -2514,6 +2535,12 @@ semant1(int rednum, SST *top)
25142535
* <func prefix> ::= <prefix spec> <data type>
25152536
*/
25162537
case FUNC_PREFIX3:
2538+
/* fall through */
2539+
/*
2540+
* <func prefix> ::= <prefix spec> <data type> <prefix spec>
2541+
*/
2542+
case FUNC_PREFIX4:
2543+
check_module_prefix();
25172544
if (sem.interface) {
25182545
/* set curr_scope to parent's scope, so subprogram ID
25192546
* gets scope of parent */
@@ -9906,6 +9933,13 @@ semant1(int rednum, SST *top)
99069933
itemp->next == ITEM_END) {
99079934
/* MODULE PROCEDURE <id> - begin separate module subprogram */
99089935
sptr = itemp->t.sptr;
9936+
9937+
/* C1548: checking MODULE prefix for subprograms that were
9938+
declared as separate module procedures */
9939+
if (!sem.interface &&
9940+
!SEPARATEMPG(sptr) && !SEPARATEMPG(ref_ident(sptr)))
9941+
error(1056, ERR_Severe, gbl.lineno, NULL, NULL);
9942+
99099943
gbl.currsub = instantiate_interface(sptr);
99109944
sem.module_procedure = TRUE;
99119945
gbl.rutype = FVALG(sptr) > NOSYM ? RU_FUNC : RU_SUBR;
@@ -13411,6 +13445,34 @@ clear_ident_list()
1341113445
dirty_ident_base = FALSE;
1341213446
}
1341313447

13448+
/** \brief Emit a warning if a duplicate subproblem prefix is used.
13449+
*/
13450+
static void
13451+
check_duplicate(bool checker, const char *op)
13452+
{
13453+
if (checker)
13454+
error(1054, ERR_Warning, gbl.lineno, op, NULL);
13455+
}
13456+
13457+
/** \brief Reset subprogram prefixes to zeroes
13458+
*/
13459+
static void
13460+
clear_subp_prefix_settings(struct subp_prefix_t *subp)
13461+
{
13462+
BZERO(subp, struct subp_prefix_t, 1);
13463+
}
13464+
13465+
/** \brief MODULE prefix checking for subprograms
13466+
C1547: cannot be inside a an abstract interface
13467+
*/
13468+
static void
13469+
check_module_prefix()
13470+
{
13471+
if (sem.interface && subp_prefix.module &&
13472+
sem.interf_base[sem.interface - 1].abstract)
13473+
error(1055, ERR_Severe, gbl.lineno, NULL, NULL);
13474+
}
13475+
1341413476
static void
1341513477
decr_ident_use(int ident, int proc)
1341613478
{

tools/flang1/utils/prstab/gram.txt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,8 @@
9696

9797
<func prefix> ::= <data type> |
9898
<data type> <prefix spec> |
99-
<prefix spec> <data type>
99+
<prefix spec> <data type> |
100+
<prefix spec> <data type> <prefix spec>
100101

101102
<entry id> ::= ENTRY <id>
102103

0 commit comments

Comments
 (0)