@@ -99,6 +99,7 @@ static int ident_host_sub = 0;
9999static void defer_ident_list (int ident , int proc );
100100static void clear_ident_list ();
101101static void decr_ident_use (int ident , int proc );
102+ static void check_duplicate (bool checker , const char * op );
102103#ifdef GSCOPEP
103104static 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+ */
144148static 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+
152159static int generic_rutype ;
153160static int mscall ;
154161static 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;
776783void
777784semant1 (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+
1341413476static void
1341513477decr_ident_use (int ident , int proc )
1341613478{
0 commit comments