1 /*
2  * Copyright (c) 1994-2019, NVIDIA CORPORATION.  All rights reserved.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *
16  */
17 
18 /** \file
19     \brief Fortran front-end utility routines used by Semantic Analyzer to
20            process functions, subroutines, predeclareds, etc.
21  */
22 
23 #include "gbldefs.h"
24 #include "global.h"
25 #include "error.h"
26 #include "symtab.h"
27 #include "symutl.h"
28 #include "dtypeutl.h"
29 #include "semant.h"
30 #include "scan.h"
31 #include "ilmtp.h"
32 #include "semstk.h"
33 #include "pd.h"
34 #include "machar.h"
35 #include "ast.h"
36 #include "rte.h"
37 #include "rtlRtns.h"
38 #include "version.h"
39 #include "atomic_common.h"
40 
41 static struct {
42   int nent;  /* number of arguments specified by user */
43   int nargt; /* number actually needed for AST creation */
44 } carg;
45 static void add_typroc(int);
46 static void count_actuals(ITEM *);
47 static void count_formals(int);
48 static void count_formal_args(int, int);
49 static void check_dim_error(int, int);
50 static int mk_array_type(int, int);
51 static int gen_derived_arg(SST *, int, int, int);
52 static int gen_pointer_result(int, int, int, LOGICAL, int);
53 static int gen_allocatable_result(int, int, int, LOGICAL, int);
54 static int gen_array_result(int, int, int, LOGICAL, int);
55 static int gen_char_result(int, int, int);
56 static void precompute_arg_intrin(int, int);
57 static void precompute_args(int, int);
58 static void replace_arguments(int, int);
59 static void rewrite_triples(int, int, int);
60 static void rewrite_subscr(int, int, int);
61 static void replace_formal_triples(int, int, int);
62 static int getMergeSym(int, int);
63 static void ref_pd_subr(SST *, ITEM *);
64 static void ref_intrin_subr(SST *, ITEM *);
65 static int set_kind_result(SST *, int, int);
66 static int set_shape_result(int, int);
67 static int _adjustl(int);
68 static int _adjustr(int);
69 static int _index(int, int, int);
70 static int _len_trim(int);
71 static int _repeat(int, int);
72 static int _scan(int, int, int);
73 static int _trim(int);
74 static int _verify(int, int, int);
75 static void get_byval_ref(int, int);
76 static int find_byval_ref(int, int, int);
77 static int cmp_mod_scope(SPTR);
78 
79 static void gen_init_intrin_call(SST *, int, int, int, int);
80 #ifdef I_C_ASSOCIATED
81 static int _c_associated(SST *, int);
82 #endif
83 
84 static int get_type_descr_dummy(int sptr, int arg);
85 static int get_tbp(int sptr);
86 static void fix_proc_pointer_call(SST *, ITEM **);
87 static int find_by_name_stype_arg(char *, int, int, int, int, int);
88 
89 static int _e74_sym;
90 static int _e74_cnt;
91 static int _e74_l;
92 static int _e74_u;
93 static int _e74_pos;
94 static char *_e74_kwd;
95 static void e74_cnt(int, int, int, int);
96 static void e74_arg(int, int, char *);
97 static int byvalue_ref_arg(SST *, int *, int, int);
98 static int gen_finalized_result(int fval, int func_sptr);
99 
100 #define E74_CNT(s, c, l, u) (_e74_sym = s, _e74_cnt = c, _e74_l = l, _e74_u = u)
101 #define E74_ARG(s, p, k) (_e74_sym = s, _e74_pos = p, _e74_kwd = k)
102 
103 #define ERR170(s) error(170, 2, gbl.lineno, s, CNULL)
104 #define HL_UF(s) \
105   error(0, 3, gbl.lineno, "HPF Library procedure not implemented", SYMNAME(s))
106 
107 #define GET_CVAL_ARG(i) get_sst_cval(ARG_STK(i))
108 #define GET_DBLE(x, y) \
109   x[0] = CONVAL1G(y);  \
110   x[1] = CONVAL2G(y)
111 #define GET_QUAD(x, y) \
112   x[0] = CONVAL1G(y);  \
113   x[1] = CONVAL2G(y);  \
114   x[2] = CONVAL3G(y);  \
115   x[3] = CONVAL4G(y);
116 
117 static int byval_func_ptr = 0;
118 static int byval_dscptr = 0;
119 static int byval_paramct = 0;
120 
121 #define PASS_BYVAL 1
122 #define PASS_BYREF 2
123 #define PASS_BYREF_NO_LEN 3
124 #define PASS_BYDEFAULT 0
125 
126 /** \brief Return the "static type descriptor" for object sptr. The static
127            type descriptor holds the "declared type" of an object.
128  */
129 int
get_static_type_descriptor(int sptr)130 get_static_type_descriptor(int sptr)
131 {
132   int sptrsdsc, dtype;
133 
134   dtype = DTYPEG(sptr);
135 
136   switch (DTY(dtype)) {
137   case TY_DERIVED:
138     break;
139   case TY_ARRAY:
140     dtype = DTY(dtype + 1);
141     if (DTY(dtype) == TY_DERIVED) {
142       sptr = DTY(dtype + 3);
143       break;
144     }
145   default:
146     return 0; /* TBD - probably need other cases for unlimited
147                * polymorphic entities.
148                */
149   }
150 
151   sptrsdsc = SDSCG(sptr);
152   if (sptrsdsc <= NOSYM) {
153     set_descriptor_class(1);
154     get_static_descriptor(sptr);
155     set_descriptor_class(0);
156     sptrsdsc = SDSCG(sptr);
157   }
158   DESCUSEDP(sptr, TRUE);
159   NODESCP(sptr, FALSE);
160   PARENTP(sptrsdsc, DTYPEG(sptr));
161   if (DTY(DTYPEG(sptr)) == TY_DERIVED) {
162     /* make sure all parent types get a descriptor as well */
163     DTYPE dt = DTYPEG(sptr);
164     SPTR tag = get_struct_tag_sptr(dt);
165     SPTR member = get_struct_members(dt);
166     int init_ict = get_struct_initialization_tree(dt);
167 
168     if (init_ict > 0) {
169       SPTR init_template = get_dtype_init_template(dt);
170       if (init_template > NOSYM)
171         sym_is_refd(init_template);
172     }
173 
174     while (member > NOSYM && PARENTG(member)) {
175       DTYPE dt = DTYPEG(member);
176       if ((tag = get_struct_tag_sptr(dt)) <= NOSYM)
177         break;
178       if (!SDSCG(member)) {
179         set_descriptor_class(TRUE); /* this means "needs a type pointer" */
180         get_static_descriptor(member);
181         set_descriptor_class(FALSE); /* reset static flag that was set above */
182         DESCUSEDP(member, TRUE);
183         NODESCP(member, FALSE);
184         PARENTP(SDSCG(member), dt);
185       }
186       member = get_struct_members(DTYPEG(tag));
187     }
188   }
189   return sptrsdsc;
190 }
191 
192 static int
get_type_descr_dummy(int sptr,int arg)193 get_type_descr_dummy(int sptr, int arg)
194 {
195 
196   int count, i, count_class;
197   int dscptr, count_descr;
198   LOGICAL found = FALSE;
199 
200   fix_class_args(sptr);
201   count = PARAMCTG(sptr);
202   dscptr = DPDSCG(sptr);
203   count_class = count_descr = 0;
204   for (i = 0; i < count; ++i) {
205     int arg2 = aux.dpdsc_base[dscptr + i];
206     if (!found) {
207       if (strcmp(SYMNAME(arg), SYMNAME(arg2)) != 0) {
208         if (CLASSG(arg2) && !needs_descriptor(arg2))
209           ++count_class;
210       } else {
211         found = TRUE;
212       }
213     } else if (CCSYMG(arg2) && CLASSG(arg2)) {
214       if (count_class == count_descr) {
215         return arg2;
216       }
217       ++count_descr;
218     }
219   }
220 
221   return 0;
222 }
223 
224 /** \brief Return the type descriptor associated with \a arg (and \a func_sptr
225    when
226            \a arg is a dummy argument of routine \a func_sptr).
227  */
228 int
get_type_descr_arg(int func_sptr,int arg)229 get_type_descr_arg(int func_sptr, int arg)
230 {
231   int arg2, sptr;
232 
233   if (needs_descriptor(arg)) {
234     if (SDSCG(arg) <= NOSYM)
235       get_static_descriptor(arg);
236     return SDSCG(arg);
237   }
238 
239   if (CLASSG(arg) && SCG(arg) == SC_DUMMY) {
240     sptr = get_type_descr_dummy(func_sptr, arg);
241     if (!sptr && gbl.internal > 1) {
242       sptr = get_type_descr_dummy(gbl.outersub, arg);
243     }
244 #if DEBUG
245     assert(sptr, "get_type_descr_arg: NULL dummy descriptor ", arg, 4);
246 #endif
247     return sptr;
248   }
249   if (!CLASSG(arg)) {
250     DTYPE dtype = DTYPEG(arg);
251     if (DTY(dtype) == TY_DERIVED) {
252       /* not polymorphic, so just return declared type descriptor */
253       arg = DTY(dtype + 3);
254     }
255   }
256   sptr = get_static_type_descriptor(arg);
257 
258 #if DEBUG
259   assert(sptr, "get_type_descr_arg: NULL descriptor ", arg, 4);
260 #endif
261 
262   return sptr;
263 }
264 
265 /** \brief Same as get_type_descr_arg(), but do not perform error check.
266  */
267 int
get_type_descr_arg2(int func_sptr,int arg)268 get_type_descr_arg2(int func_sptr, int arg)
269 {
270   int arg2, sptr;
271   if (needs_descriptor(arg)) {
272     int desc;
273     if (SDSCG(arg))
274       desc = SDSCG(arg);
275     else {
276       int orig_sc = get_descriptor_sc();
277       set_descriptor_sc(SC_STATIC);
278       get_static_descriptor(arg);
279       set_descriptor_sc(orig_sc);
280       desc = SDSCG(arg);
281     }
282     return desc;
283   }
284 
285   if (CLASSG(arg) && SCG(arg) == SC_DUMMY) {
286     sptr = get_type_descr_dummy(func_sptr, arg);
287     return sptr;
288   }
289 
290   sptr = get_static_type_descriptor(arg);
291 
292   return sptr;
293 }
294 
295 /* check if this is a character parameter, passed by reference,
296    no length needed in the function parameter list
297   */
298 static int
pass_char_no_len(int func_sptr,int param_sptr)299 pass_char_no_len(int func_sptr, int param_sptr)
300 {
301   return (find_byval_ref(func_sptr, param_sptr, 0) == PASS_BYREF_NO_LEN);
302 }
303 
304 /** \brief Return true if \a sptr is an SC_LOCAL and a pass by value parameter
305    of
306            \a func_sptr.
307  */
308 int
sc_local_passbyvalue(int sptr,int func_sptr)309 sc_local_passbyvalue(int sptr, int func_sptr)
310 {
311   int dscptr;
312   int i;
313   int param_sptr;
314   char *param_name;
315 
316   if (SCG(sptr) != SC_LOCAL)
317     return 0;
318 
319   /* find the _V_var on the function list */
320   dscptr = DPDSCG(func_sptr);
321   for (i = PARAMCTG(func_sptr); i > 0; dscptr++, i--) {
322     param_sptr = aux.dpdsc_base[dscptr];
323     param_name = SYMNAME(param_sptr);
324     if ((strncmp(param_name, "_V_", 3) == 0) &&
325         (strcmp(param_name + 3, SYMNAME(sptr)) == 0))
326       return 1;
327   }
328   return 0;
329 }
330 
331 /* param_sptr is a character string.  return  PASS_BYVAL,
332    PASS_BYREF, PASS_BYREF_NO_LEN
333  */
334 static int
set_char_ref_val(int func,int param)335 set_char_ref_val(int func, int param)
336 {
337   if (func == 0)
338     return (PASS_BYREF);
339   if (PASSBYVALG(param))
340     return PASS_BYVAL;
341   if (STDCALLG(func) || CFUNCG(func)) {
342     if (PASSBYREFG(param))
343       return PASS_BYREF_NO_LEN;
344 
345     if (PASSBYREFG(func))
346       return PASS_BYREF;
347 
348     /* plain func= c/stdcall is pass by value */
349     return PASS_BYVAL;
350   }
351 
352   return PASS_BYREF;
353 }
354 
355 /* find_byval_ref: check STCALLG , CFUNCG, PASSBYREFG, PASSBYVALG  and
356    decide if this parameter is pass by value , pass by reference,
357    or a character parameter pass by ref without length
358  */
359 static int
find_byval_ref(int func_sptr,int param_sptr,int any_type)360 find_byval_ref(int func_sptr, int param_sptr, int any_type)
361 {
362   int iface;
363   /* special care must be taken to mark string types
364      pass by reference when we do not pass a length
365    */
366   /* CDEC$ VALUE or REFERENCE set explicitly for this parameter */
367 
368   proc_arginfo(func_sptr, NULL, NULL, &iface);
369   if (param_sptr <= 0) {
370     if (iface == 0)
371       return (PASS_BYDEFAULT);
372     if (PASSBYVALG(iface)) {
373       return (PASS_BYVAL);
374     }
375     if (PASSBYREFG(iface)) {
376       return (PASS_BYREF);
377     }
378 /* sub defaults implied by STDARG or CFUNC */
379 #ifdef CREFP
380     if (!CREFG(iface) && (STDCALLG(iface) || CFUNCG(iface))) {
381       return (PASS_BYVAL);
382     }
383 #else
384     if (STDCALLG(iface) || CFUNCG(iface)) {
385       return (PASS_BYVAL);
386     }
387 #endif
388     return PASS_BYDEFAULT;
389   }
390 
391   if ((DTY(DTYPEG(param_sptr)) == TY_CHAR) ||
392       (DTY(DTYPEG(param_sptr)) == TY_NCHAR)) {
393     return (set_char_ref_val(iface, param_sptr));
394   }
395 
396   if (is_iso_cptr(DTYPEG(param_sptr)) && PASSBYVALG(param_sptr)) {
397     return (PASS_BYVAL);
398   }
399 
400   if (!any_type && ((DTY(DTYPEG(param_sptr)) == TY_ARRAY) ||
401                     (DTY(DTYPEG(param_sptr)) == TY_UNION))) {
402     return (PASS_BYREF);
403   }
404 
405   if (PASSBYVALG(param_sptr)) {
406     return (PASS_BYVAL);
407   }
408   if (PASSBYREFG(param_sptr)) {
409     return (PASS_BYREF);
410   }
411 
412   /* subroutine default setting of parameters :
413      sub defaults were directly set CDEC$ ATTRIBUTE VALUE or REFERENCE
414    */
415   if (iface == 0)
416     return (PASS_BYDEFAULT);
417   if (PASSBYVALG(iface)) {
418     return (PASS_BYVAL);
419   }
420   if (PASSBYREFG(iface)) {
421     return (PASS_BYREF);
422   }
423   /* sub defaults implied by STDARG or CFUNC */
424   if (STDCALLG(iface) || CFUNCG(iface)) {
425     return (PASS_BYVAL);
426   }
427 
428   return (PASS_BYDEFAULT);
429 }
430 
431 static void
init_byval()432 init_byval()
433 {
434   byval_func_ptr = 0;
435   byval_dscptr = 0;
436   byval_paramct = 0;
437 }
438 
439 /* return the next dummy parameter to check for
440    by value
441  */
442 static int
inc_dummy_param(int func_sptr)443 inc_dummy_param(int func_sptr)
444 {
445   int param_sptr;
446   int arg;
447 
448   if (byval_func_ptr == 0) {
449     byval_func_ptr = func_sptr;
450     byval_dscptr = DPDSCG(func_sptr);
451     byval_paramct = PARAMCTG(func_sptr);
452   }
453 
454   if (byval_paramct == 0)
455     return 0;
456   param_sptr = *(aux.dpdsc_base + byval_dscptr);
457   byval_dscptr++;
458   return (param_sptr);
459 }
460 
461 /** \brief Return true if param is pass by value.
462  */
463 int
get_byval(int func_sptr,int param_sptr)464 get_byval(int func_sptr, int param_sptr)
465 {
466   return find_byval_ref(func_sptr, param_sptr, 0) == PASS_BYVAL;
467 }
468 
469 /* rewrite references to types c_ptr, c_loc_ptr as
470    c-_ptr->member
471  */
472 static int
rewrite_cptr_references(int ast)473 rewrite_cptr_references(int ast)
474 {
475   int past, mast;
476   int new_ast = 0;
477   int psptr;
478   int msptr = 0;
479   int iso_dtype;
480 
481   switch (A_TYPEG(ast)) {
482   case A_ID:
483     mast = ast;
484     break;
485   case A_MEM:
486     mast = A_MEMG(ast);
487     break;
488   case A_SUBSCR:
489     mast = A_LOPG(ast);
490     break;
491   default:
492     /* no need to process further  all cases of possible
493        nested C_PTR must be in cases above  */
494     return 0;
495   }
496 
497   /* check for type C_PTR, C_FUNC_PTR, and process */
498   iso_dtype = is_iso_cptr(A_DTYPEG(mast));
499   if (iso_dtype) {
500     psptr = DTY(iso_dtype + 1);
501     new_ast = mk_member(ast, mk_id(psptr), DTYPEG(psptr));
502   }
503   return new_ast;
504 }
505 
506 /*---------------------------------------------------------------------*/
507 /*
508  * This stack entry represents a subprogram argument to be passed by value.
509  *
510  */
511 /* from %VAL() and %REF() processing */
512 static int
byvalue_ref_arg(SST * e1,int * dtype,int op,int func_sptr)513 byvalue_ref_arg(SST *e1, int *dtype, int op, int func_sptr)
514 {
515   int dum;
516   int saved_dtype;
517   int new_ast = 0;
518 
519   if (op == OP_VAL || op == OP_BYVAL) {
520     int argdt;
521     if (SST_ISNONDECC(e1))
522       cngtyp(e1, DT_INT);
523 
524     saved_dtype = A_DTYPEG(SST_ASTG(e1));
525 
526     if ((A_TYPEG(SST_ASTG(e1)) == A_FUNC) && (is_iso_cptr(saved_dtype)) && !CFUNCG(func_sptr)) {
527       /* functions returning c_ptr structs become funcs
528          returning ints, so that we simply copy the
529          (integer)pointer
530        */
531       A_DTYPEP(SST_ASTG(e1), DT_PTR);
532     } else {
533       new_ast = rewrite_cptr_references(SST_ASTG(e1));
534       if (new_ast) {
535         SST_ASTP(e1, new_ast);
536         SST_IDP(e1, S_EXPR);
537         SST_DTYPEP(e1, A_DTYPEG(new_ast));
538       }
539     }
540 
541     /* checking the AST dtype, resetting the semantic stack dtype */
542     if (A_DTYPEG(SST_ASTG(e1)) != saved_dtype) {
543       SST_DTYPEP(e1, A_DTYPEG(SST_ASTG(e1)));
544     }
545 
546     mkexpr(e1);
547     SST_IDP(e1, S_VAL);
548     argdt = SST_DTYPEG(e1);
549     *dtype = argdt;
550     if (ELEMENTALG(func_sptr))
551       argdt = DDTG(argdt);
552 
553     if (!is_iso_cptr(argdt) && !DT_ISBASIC(argdt) && DTY(argdt) != TY_STRUCT &&
554         DTY(argdt) != TY_DERIVED) {
555       /* also allow passing chars with no loc */
556       cngtyp(e1, DT_INT);
557       errsev(52);
558     }
559     SST_ASTP(e1, mk_unop(op, SST_ASTG(e1), *dtype));
560     return mkarg(e1, dtype);
561   }
562 #if DEBUG
563   assert(op == OP_REF, "byvalue_ref_arg bad op", op, 3);
564 #endif
565   /* OP_REF(character) , no length passed */
566   mkarg(e1, &dum);
567   SST_IDP(e1, S_REF);
568 
569   SST_ASTP(e1, mk_unop(op, SST_ASTG(e1), DT_INT));
570   return 1;
571 }
572 
573 /** \brief Return TRUE if sptr is a derived type with an allocatable member */
574 LOGICAL
allocatable_member(int sptr)575 allocatable_member(int sptr)
576 {
577   DTYPE dtype = DTYPEG(sptr);
578   if (DTYG(dtype) == TY_DERIVED) {
579     int sptrmem;
580     for (sptrmem = DTY(DDTG(dtype) + 1); sptrmem > NOSYM;
581          sptrmem = SYMLKG(sptrmem)) {
582       if (ALLOCATTRG(sptrmem)) {
583         return TRUE;
584       }
585       if (USELENG(sptrmem) && ALLOCG(sptrmem) && TPALLOCG(sptrmem)) {
586         return TRUE; /* uses length type parameter */
587       }
588       if (is_tbp_or_final(sptrmem)) {
589         continue; /* skip tbp */
590       }
591       if (dtype != DTYPEG(sptrmem) && !POINTERG(sptrmem) &&
592           allocatable_member(sptrmem)) {
593         return TRUE;
594       }
595     }
596   }
597   return FALSE;
598 }
599 
600 /*---------------------------------------------------------------------*/
601 LOGICAL
in_kernel_region()602 in_kernel_region()
603 {
604   int df;
605   for (df = 1; df <= sem.doif_depth; df++) {
606     switch (DI_ID(df)) {
607     case DI_CUFKERNEL:
608     case DI_ACCDO:
609     case DI_ACCLOOP:
610     case DI_ACCREGDO:
611     case DI_ACCREGLOOP:
612     case DI_ACCKERNELSDO:
613     case DI_ACCKERNELSLOOP:
614     case DI_ACCPARALLELDO:
615     case DI_ACCPARALLELLOOP:
616     case DI_ACCSERIALLOOP:
617       return TRUE;
618     }
619   }
620   return FALSE;
621 } /* in_kernel_region */
622 /*---------------------------------------------------------------------*/
623 
624 static int
get_sym_from_sst_if_available(SST * sst_actual)625 get_sym_from_sst_if_available(SST *sst_actual)
626 {
627   int sptr = 0;
628   int unused;
629   int ast;
630 
631   if (SST_IDG(sst_actual) == S_LVALUE)
632     sptr = SST_LSYMG(sst_actual);
633   else if (SST_IDG(sst_actual) == S_DERIVED || SST_IDG(sst_actual) == S_IDENT)
634     sptr = SST_SYMG(sst_actual);
635   else if (SST_IDG(sst_actual) == S_SCONST) {
636     (void)mkarg(sst_actual, &unused);
637     sptr = SST_SYMG(sst_actual);
638   }
639   return sptr;
640 }
641 
642 static LOGICAL
is_ptr_arg(SST * sst_actual)643 is_ptr_arg(SST *sst_actual)
644 {
645   SPTR sptr = get_sym_from_sst_if_available(sst_actual);
646 
647   if (sptr <= NOSYM) {
648     int ast = SST_ASTG(sst_actual);
649     if (A_TYPEG(ast) == A_INTR && A_OPTYPEG(ast) == I_NULL) {
650       return TRUE;
651     }
652     if (A_TYPEG(ast) == A_ID) {
653       sptr = A_SPTRG(ast);
654       if (sptr > NOSYM && SCG(sptr) == SC_BASED && !ALLOCATTRG(sptr) &&
655           MIDNUMG(sptr) > NOSYM && PTRVG(MIDNUMG(sptr)))
656         return TRUE;
657     }
658     if (SST_IDG(sst_actual) == S_EXPR && A_TYPEG(ast) == A_FUNC) {
659       sptr = memsym_of_ast(A_LOPG(ast));
660       sptr = FVALG(sptr);
661     }
662   }
663 
664   return sptr > NOSYM && POINTERG(sptr);
665 }
666 
667 /* Non-pointer passed to a pointer dummy: geneerate a pointer temp, associate
668  * the temp with the actual arg, and pass the temp.
669  */
670 static int
gen_and_assoc_tmp_ptr(SST * sst_actual,int std)671 gen_and_assoc_tmp_ptr(SST *sst_actual, int std)
672 {
673   int sptrtmp;
674   int ast_actual;
675   int asttmp;
676   int ast;
677   int dtype;
678   int dtype1;
679 
680   ast_actual = SST_ASTG(sst_actual);
681 
682   if (SST_IDG(sst_actual) == S_EXPR) {
683     dtype1 = A_DTYPEG(ast_actual);
684     ast = sem_tempify(sst_actual);
685     (void)add_stmt(ast);
686     ast = A_DESTG(ast);
687   } else if (ast_actual) {
688     dtype1 = A_DTYPEG(ast_actual);
689     ast = ast_actual;
690   } else {
691     int sptractual = get_sym_from_sst_if_available(sst_actual);
692     assert(sptractual, "gen_and_assoc_tmp_ptr: no symbol or AST for actual arg",
693            0, 4);
694     dtype1 = DTYPEG(sptractual);
695     ast = mk_id(sptractual);
696   }
697 
698   dtype = dtype1;
699   if (DTY(dtype) == TY_ARRAY) {
700     dtype = dup_array_dtype(dtype);
701     DTY(dtype + 1) = DTY(dtype1 + 1);
702   }
703 
704   sptrtmp = getcctmp_sc('d', sem.dtemps++, ST_VAR, dtype, SC_LOCAL);
705   asttmp = mk_id(sptrtmp);
706   POINTERP(sptrtmp, 1);
707   CCSYMP(sptrtmp, 1);
708   ARGP(sptrtmp, 1);
709   get_static_descriptor(sptrtmp);
710   get_all_descriptors(sptrtmp);
711   ADDRTKNP(sym_of_ast(ast), 1);
712   (void)add_stmt(add_ptr_assign(asttmp, ast, std));
713   return asttmp;
714 }
715 
716 static LOGICAL
need_tmp_retval(int func_sptr,int param_dummy)717 need_tmp_retval(int func_sptr, int param_dummy)
718 {
719   int fval;
720   int func_dtype;
721 
722   fval = func_sptr;
723   if (FVALG(func_sptr))
724     fval = FVALG(func_sptr);
725 
726   func_dtype = DTYPEG(func_sptr);
727 
728   if (POINTERG(fval)) {
729     return TRUE;
730   }
731   if (POINTERG(fval)) {
732     return TRUE;
733   }
734   if (ALLOCATTRG(fval) || allocatable_member(fval)) {
735     return TRUE;
736   }
737   if (DTY(func_dtype) == TY_ARRAY) {
738     return TRUE;
739   }
740   if (ADJLENG(fval)) {
741     if (!ELEMENTALG(func_sptr)) {
742       return TRUE;
743     } else if (!ARG_STK(0) || !A_SHAPEG(SST_ASTG(ARG_STK(0)))) {
744       return TRUE;
745     }
746   }
747 
748   return FALSE;
749 }
750 
751 /** \brief If applicable, generate finalization code for function result.
752  *
753  * \param fval is the result symbol.
754  * \param func_sptr is the function symbol table pointer
755  *
756  * \returns the result symbol; either fval or a new result symbol.
757  */
758 static int
gen_finalized_result(int fval,int func_sptr)759 gen_finalized_result(int fval, int func_sptr)
760 {
761   if (!ALLOCATTRG(fval) && !POINTERG(fval) && has_finalized_component(fval)) {
762     /* Need to finalize the function result after it's assigned to LHS.
763      * If the result is allocatable, then finalization is handled during
764      * automatic deallocation (i.e., the runtime call to dealloc_poly03,
765      * dealloc_poly_mbr03). If the result is pointer, then we do not finalize
766      * the object (the language spec indicates that it is processor dependent
767      * whether such objects are finalized).
768      */
769     int std = add_stmt(mk_stmt(A_CONTINUE, 0));
770 
771     if (STYPEG(fval) == ST_UNKNOWN || STYPEG(fval) == ST_IDENT) {
772       fval = getsymbol(SYMNAME(fval));
773       if (STYPEG(fval) == ST_PROC) {
774         /* function result variable name same as its function */
775         fval = insert_sym(fval);
776       } else {
777         /* function result variable name overloads another object */
778         fval = get_next_sym(SYMNAME(fval), NULL);
779       }
780       fval = declsym(fval, ST_VAR, TRUE);
781       SCP(fval, SC_LOCAL);
782       DTYPEP(fval, DTYPEG(func_sptr));
783       DCLDP(fval, 1);
784       init_derived_type(fval, 0, std);
785       std = add_stmt(mk_stmt(A_CONTINUE, 0));
786     }
787     gen_finalization_for_sym(fval, std, 0);
788   }
789   return fval;
790 }
791 
792 /** \brief Write ILMs to call a function.
793     \param stktop function to call
794     \param list   arguments to pass to function
795     \param flag   set if called from a generic resolution routine
796  */
797 int
func_call2(SST * stktop,ITEM * list,int flag)798 func_call2(SST *stktop, ITEM *list, int flag)
799 {
800   int func_sptr, sptr1, fval_sptr = 0;
801   ITEM *itemp;
802   int count, i, ii;
803   int dum;
804   int dtype;
805   int ast;
806   int argt;
807   SST *sp;
808   int param_dummy;
809   int return_value, isarray, save_func_arrinfo;
810   char *kwd_str; /* where make_kwd_str saves the string */
811   int argt_count;
812   int shaper;
813   int new_ast;
814   int psptr, msptr;
815   int callee;
816   int invobj;
817   int doif;
818 
819   return_value = 0;
820   save_func_arrinfo = 0;
821   SST_CVLENP(stktop, 0);
822   ast = astb.i0; /* initialize just in case error occurs */
823   kwd_str = NULL;
824   func_sptr = SST_SYMG(stktop);
825   if (func_sptr < 0) {
826     func_sptr = -func_sptr;
827     SST_SYMP(stktop, func_sptr);
828   }
829   switch (A_TYPEG(SST_ASTG(stktop))) {
830   case A_ID:
831   case A_LABEL:
832   case A_ENTRY:
833   case A_SUBSCR:
834   case A_SUBSTR:
835   case A_MEM:
836     callee = memsym_of_ast(SST_ASTG(stktop));
837     if (STYPEG(callee) == ST_PROC && CLASSG(callee) && IS_TBP(callee)) {
838       /* special case for user defined generic type bound operators */
839       i = 0;
840       func_sptr = get_implementation(TBPLNKG(callee), callee, 0, &i);
841       if (STYPEG(BINDG(i)) == ST_OPERATOR ||
842           STYPEG(BINDG(i)) == ST_USERGENERIC) {
843         i = get_specific_member(TBPLNKG(callee), callee);
844         func_sptr = VTABLEG(i);
845       }
846       callee = i;
847       SST_ASTP(stktop, replace_memsym_of_ast(SST_ASTG(stktop), i));
848       dtype = TBPLNKG(BINDG(i));
849       goto process_tbp;
850     }
851     break;
852   default:
853     callee = 0;
854   }
855   if (callee && CLASSG(callee) && CCSYMG(callee) &&
856       STYPEG(callee) == ST_MEMBER) {
857     func_sptr = pass_sym_of_ast(SST_ASTG(stktop));
858     dtype = DTYPEG(func_sptr);
859     if (DTY(dtype) == TY_ARRAY)
860       dtype = DTY(dtype + 1);
861     if (STYPEG(BINDG(callee)) == ST_USERGENERIC) {
862       int mem;
863       func_sptr = generic_tbp_func(BINDG(callee), stktop, list);
864       if (func_sptr) {
865         if (get_implementation(dtype, func_sptr, 0, &mem) == 0) {
866           char *name_cpy, *name;
867           name_cpy = getitem(0, strlen(SYMNAME(func_sptr)) + 1);
868           strcpy(name_cpy, SYMNAME(func_sptr));
869           name = strchr(name_cpy, '$');
870           if (name)
871             *name = '\0';
872           error(155, 3, gbl.lineno,
873                 "Could not resolve generic type bound "
874                 "procedure",
875                 name_cpy);
876           sptr1 = 0;
877         } else {
878           SST_ASTP(stktop, replace_memsym_of_ast(SST_ASTG(stktop), mem));
879           callee = mem;
880         }
881       }
882     }
883     func_sptr = get_implementation(dtype, BINDG(callee), !flag, NULL);
884   process_tbp:
885     invobj = get_tbp_argno(BINDG(callee), dtype);
886     set_pass_objects(invobj - 1, pass_sym_of_ast(SST_ASTG(stktop)));
887     callee = SST_ASTG(stktop);
888   } else
889     callee = 0;
890   FUNCP(func_sptr, 1); /* mark sptr as a function */
891   TYPDP(func_sptr, 1); /* put in 'external' statement */
892   dtype = DTYPEG(func_sptr);
893   shaper = 0;
894   isarray = DTY(dtype) == TY_ARRAY;
895 
896   if (DPDSCG(func_sptr))
897     kwd_str = make_kwd_str(func_sptr);
898 
899   /* store function st in ERRSYM for error messages; used to be set only
900    * for CHAR
901    */
902   SST_ERRSYMP(stktop, func_sptr);
903 
904   if (list == NULL)
905     list = ITEM_END;
906   if (STYPEG(func_sptr) == ST_PROC && SLNKG(func_sptr) == 0) {
907     SLNKP(func_sptr, aux.list[ST_PROC]);
908     aux.list[ST_PROC] = func_sptr;
909   }
910   count_actuals(list);
911   count = carg.nent;
912   argt_count = carg.nargt;
913 
914   if (!FUNCLINEG(func_sptr) && POINTERG(func_sptr)) {
915     error(465, 3, gbl.lineno, CNULL, CNULL);
916   }
917   init_byval();
918 
919   if (kwd_str) {
920     int dscptr; /* ptr to dummy parameter descriptor list */
921     int fval;
922 
923     if (check_arguments(func_sptr, count, list, kwd_str))
924       goto exit_;
925     for (i = 0; i < carg.nent; i++) {
926       sp = ARG_STK(i);
927       if (sp) {
928         /* add to ARGT list, handling derived type arguments as
929          * special case.
930          */
931         sptr1 = get_sym_from_sst_if_available(sp);
932         {
933           param_dummy = inc_dummy_param(func_sptr);
934 
935           if (is_iso_cloc(SST_ASTG(sp))) {
936             if (find_byval_ref(func_sptr, param_dummy, 1) == PASS_BYVAL) {
937               /* pass by val iso_c pointer to arg:
938                  C_LOC(arg)   C_FUN_LOC(arg)
939                  is plain old pass by reference
940                  without type checking: get rid of the
941                 C_LOC:
942                */
943               new_ast = ARGT_ARG(A_ARGSG(SST_ASTG(sp)), 0);
944               if (A_TYPEG(new_ast) == A_ID && (!TARGETG(A_SPTRG(new_ast))) &&
945                   (!POINTERG(A_SPTRG(new_ast))))
946                 errwarn(468);
947 
948               SST_ASTP(sp, new_ast);
949               SST_IDP(sp, S_EXPR);
950             } else if (A_TYPEG(ARGT_ARG(A_ARGSG(SST_ASTG(sp)), 0)) != A_ID) {
951               // Inlining has problems with an expression in this context.
952               // Downstream code can always handle simple variables.
953               (void)tempify(sp);
954             }
955             /* else
956              * iso_c_loc by reference pointer to pointer */
957           } else if (get_byval(func_sptr, param_dummy)) {
958             /*  function arguments not processed by lowerilm */
959             if (PASSBYVALG(param_dummy)) {
960               if (OPTARGG(param_dummy)) {
961                 int assn = sem_tempify(sp);
962                 (void)add_stmt(assn);
963                 SST_ASTP(sp, A_DESTG(assn));
964                 byvalue_ref_arg(sp, &dum, OP_REF, func_sptr);
965               } else if (!need_tmp_retval(func_sptr, param_dummy))
966                 byvalue_ref_arg(sp, &dum, OP_BYVAL, func_sptr);
967               else
968                 byvalue_ref_arg(sp, &dum, OP_VAL, func_sptr);
969             } else {
970               byvalue_ref_arg(sp, &dum, OP_VAL, func_sptr);
971             }
972           } else if (pass_char_no_len(func_sptr, param_dummy)) {
973             byvalue_ref_arg(sp, &dum, OP_REF, func_sptr);
974           } else if (INTENTG(param_dummy) == INTENT_IN &&
975                      POINTERG(param_dummy) && !is_ptr_arg(sp)) {
976             /* F2008: pass non-pointer actual arg for an
977              *        INTENT(IN), POINTER formal arg */
978             ARG_AST(i) = SST_ASTG(sp) = gen_and_assoc_tmp_ptr(sp, sem.last_std);
979           } else {
980           }
981         }
982       }
983     }
984 
985     count_formals(func_sptr);
986     argt_count = carg.nargt;
987     dscptr = DPDSCG(func_sptr);
988     fval = func_sptr;
989     if (FVALG(func_sptr))
990       fval = FVALG(func_sptr);
991     /* for ST_ENTRY, the data type info is set in the return value symbol */
992     if (POINTERG(fval)) {
993       /*
994        * since the result of the function is a pointer, a pointer
995        * temporary must be created.
996        * Note that for an 'adjustable' return value, its size
997        * may be dependent on the actual arguments.
998        *
999        * Would like to call set_descriptor_sc() at the beginning
1000        * of func2_call() and restore at the end; however, there
1001        * are still semsym things that might need to be done to user
1002        * variables.  So, only call set_descriptor_sc() when we know
1003        * we are creating temps.
1004        */
1005       set_descriptor_sc(sem.sc);
1006       if (isarray) {
1007         return_value = ref_entry(func_sptr);
1008       } else {
1009         return_value = get_next_sym(SYMNAME(func_sptr), "v");
1010         STYPEP(return_value, ST_VAR);
1011         SCP(return_value, SC_BASED);
1012         DTYPEP(return_value, dtype);
1013         DCLDP(return_value, 1);
1014         POINTERP(return_value, 1);
1015         if (DTYG(dtype) == TY_DERIVED && XBIT(58, 0x40000)) {
1016           F90POINTERP(return_value, 1);
1017         } else {
1018           get_static_descriptor(return_value);
1019           get_all_descriptors(return_value);
1020         }
1021       }
1022 #ifdef CLASSG
1023       if (HCCSYMG(return_value) && !CLASSG(return_value))
1024         CLASSP(return_value, CLASSG(FVALG(func_sptr)));
1025 #endif
1026       {
1027         /* Be warned: "return_value" is a symbol table index coming into
1028          * this block of code, but it's an AST index coming out!
1029          */
1030         return_value = gen_pointer_result(return_value, dscptr, carg.nent,
1031                                           FALSE, func_sptr);
1032         argt_count++;
1033         argt = mk_argt(argt_count); /* mk_argt stuffs away count */
1034         ARGT_ARG(argt, 0) = return_value;
1035         ii = 1;
1036         save_func_arrinfo = 1;
1037       }
1038       set_descriptor_sc(SC_LOCAL);
1039     } else if (ALLOCATTRG(fval)) {
1040       /*
1041        * result of the function is an allocatable, should be similiar
1042        * to a pointer
1043        */
1044       if (isarray) {
1045         fval_sptr = ref_entry(func_sptr);
1046       } else {
1047         fval_sptr = get_next_sym(SYMNAME(func_sptr), "v");
1048         STYPEP(fval_sptr, ST_VAR);
1049         SCP(fval_sptr, SC_BASED);
1050         DTYPEP(fval_sptr, dtype);
1051         DCLDP(fval_sptr, 1);
1052         set_descriptor_sc(sem.sc);
1053         get_static_descriptor(fval_sptr);
1054         get_all_descriptors(fval_sptr);
1055         set_descriptor_sc(SC_LOCAL);
1056       }
1057 
1058       return_value = gen_allocatable_result(
1059           fval_sptr, dscptr, carg.nent, (DTYG(dtype) == TY_DERIVED), func_sptr);
1060 #ifdef RVALLOCP
1061       if (XBIT(54, 0x1) && !isarray && DTY(dtype) != TY_DERIVED) {
1062         int sym;
1063         sym = sym_of_ast(return_value);
1064         if (MIDNUMG(sym)) {
1065           RVALLOCP(MIDNUMG(sym), 1);
1066         }
1067       }
1068 #endif
1069 
1070 #ifdef CLASSG
1071       if (HCCSYMG(fval_sptr) && !CLASSG(fval_sptr)) {
1072         CLASSP(fval_sptr, CLASSG(FVALG(func_sptr)));
1073         CLASSP(sym_of_ast(return_value), CLASSG(FVALG(func_sptr)));
1074       }
1075 #endif
1076       argt_count++;
1077       argt = mk_argt(argt_count); /* mk_argt stuffs away count */
1078       ARGT_ARG(argt, 0) = return_value;
1079       ii = 1;
1080       add_p_dealloc_item(memsym_of_ast(return_value));
1081     } else if (allocatable_member(fval)) {
1082       if (ELEMENTALG(func_sptr)) {
1083         int i;
1084         for (i = 0; i < argt_count; ++i) {
1085           shaper = A_SHAPEG(ARG_AST(i));
1086           if (shaper) {
1087             int dt = dtype_with_shape(dtype, shaper);
1088             fval_sptr = get_arr_temp(dt, FALSE, FALSE, FALSE);
1089             DTYPEP(fval_sptr, dt);
1090             STYPEP(fval_sptr, ST_ARRAY);
1091             break;
1092           }
1093         }
1094       }
1095       if (!shaper) {
1096         if (ADJARRG(fval)) {
1097           return_value = ref_entry(func_sptr);
1098           return_value = gen_array_result(return_value, dscptr, carg.nent,
1099                                           FALSE, func_sptr);
1100           fval_sptr = A_SPTRG(return_value);
1101         } else {
1102           fval_sptr = get_next_sym(SYMNAME(func_sptr), "d");
1103           if (isarray) {
1104             STYPEP(fval_sptr, ST_ARRAY);
1105           } else {
1106             STYPEP(fval_sptr, ST_VAR);
1107           }
1108           DTYPEP(fval_sptr, dtype);
1109         }
1110       }
1111 
1112       SCP(fval_sptr, sem.sc);
1113       if (ASSUMSHPG(fval) || ASUMSZG(fval)) {
1114         set_descriptor_sc(sem.sc);
1115         get_static_descriptor(fval_sptr);
1116         get_all_descriptors(fval_sptr);
1117         set_descriptor_sc(SC_LOCAL);
1118       }
1119       init_derived_type(fval_sptr, 0, STD_PREV(0));
1120       argt_count++;
1121       argt = mk_argt(argt_count); /* mk_argt stuffs away count */
1122       return_value = mk_id(fval_sptr);
1123       ARGT_ARG(argt, 0) = return_value;
1124       ii = 1;
1125       add_p_dealloc_item(fval_sptr);
1126     } else if (isarray) {
1127       /*
1128        * since the result of the function is an array, a temporary
1129        * must be allocated at run-time even if its bounds are contant.
1130        * Note that for an 'adjustable' return value, its size
1131        * may be dependent on the actual arguments.
1132        */
1133       return_value = ref_entry(func_sptr);
1134       if (!ADJLENG(fval))
1135         return_value =
1136             gen_array_result(return_value, dscptr, carg.nent, FALSE, func_sptr);
1137       else
1138         return_value = gen_char_result(return_value, dscptr, carg.nent);
1139       argt_count++;
1140       argt = mk_argt(argt_count); /* mk_argt stuffs away count */
1141       ARGT_ARG(argt, 0) = return_value;
1142       ii = 1;
1143       /*
1144        * have an array-valued function; save up information
1145        * which would allow substituting the result temp with
1146        * the LHS of an assignment.
1147        */
1148       save_func_arrinfo = 1;
1149     } else if (ADJLENG(fval)) {
1150       if (ELEMENTALG(func_sptr)) {
1151         sp = ARG_STK(0);
1152         if (sp && (shaper = A_SHAPEG(SST_ASTG(sp)))) {
1153           argt_count++;
1154           argt = mk_argt(argt_count);
1155           ARGT_ARG(argt, 0) = gen_char_result(fval, dscptr, carg.nent);
1156           ii = 1;
1157           return_value = 0;
1158         } else {
1159           return_value = gen_char_result(fval, dscptr, carg.nent);
1160         }
1161       } else {
1162         return_value = gen_char_result(fval, dscptr, carg.nent);
1163       }
1164       if (return_value) {
1165         argt_count++;
1166         argt = mk_argt(argt_count); /* mk_argt stuffs away count */
1167         ARGT_ARG(argt, 0) = return_value;
1168         ii = 1;
1169       }
1170     } else {
1171       argt = mk_argt(argt_count); /* mk_argt stuffs away count */
1172       ii = 0;
1173     }
1174 
1175     fval = gen_finalized_result(fval, func_sptr);
1176 
1177     /* return value handled, copy in the function args */
1178     for (i = 0; i < carg.nent; i++, ii++) {
1179       if (ARG_STK(i)) {
1180         ARGT_ARG(argt, ii) = SST_ASTG(ARG_STK(i));
1181       } else {
1182         /* OPTIONAL arg not present */
1183         ARGT_ARG(argt, ii) = astb.ptr0;
1184       }
1185     }
1186 
1187     if (return_value) {
1188       /* return_value is symbol if result is of derived type;
1189        * otherwise, it's an ast.
1190        */
1191       dtype = DTYPEG(A_SPTRG(return_value));
1192       if (callee) {
1193         int mem = memsym_of_ast(callee);
1194         if (STYPEG(mem) == ST_MEMBER && !strstr(SYMNAME(func_sptr), "$tbp")) {
1195           VTABLEP(mem, func_sptr);
1196         }
1197         /*dtype = DTYPEG(mem);*/
1198       }
1199       ast = mk_func_node(A_CALL, (callee) ? callee : mk_id(func_sptr),
1200                          argt_count, argt);
1201       sem.arrfn.call_std = add_stmt(ast);
1202       sem.arrfn.sptr = func_sptr;
1203       if (save_func_arrinfo) {
1204         sem.arrfn.return_value = return_value;
1205         if (ALLOCG(A_SPTRG(return_value)))
1206           sem.arrfn.alloc_std = sem.alloc_std;
1207       }
1208       ast = return_value;
1209     } else {
1210       if (callee) {
1211         int mem = memsym_of_ast(callee);
1212         if (STYPEG(mem) == ST_MEMBER && !strstr(SYMNAME(func_sptr), "$tbp")) {
1213           VTABLEP(mem, func_sptr);
1214         }
1215         /*dtype = DTYPEG(mem);*/
1216       }
1217       ast = mk_func_node(A_FUNC, (callee) ? callee : mk_id(func_sptr),
1218                          argt_count, argt);
1219     }
1220     if (ELEMENTALG(func_sptr)) {
1221       int argc;
1222       for (argc = 0; argc < argt_count; ++argc) {
1223         /* Use first shaped argument */
1224         shaper = A_SHAPEG(ARGT_ARG(argt, argc));
1225         if (shaper)
1226           break;
1227       }
1228       if (shaper == 0) {
1229         shaper = mkshape(dtype);
1230       } else {
1231         dtype = dtype_with_shape(dtype, shaper);
1232         A_SHAPEP(ast, shaper);
1233       }
1234     } else {
1235       shaper = mkshape(dtype);
1236     }
1237     A_DTYPEP(ast, dtype);
1238     if (DFLTG(func_sptr)) {
1239       int newdt = dtype;
1240       switch (DTY(dtype)) {
1241       case TY_INT:
1242         newdt = stb.user.dt_int;
1243         break;
1244       case TY_LOG:
1245         newdt = stb.user.dt_log;
1246         break;
1247       case TY_REAL:
1248         newdt = stb.user.dt_real;
1249         break;
1250       case TY_CMPLX:
1251         newdt = stb.user.dt_cmplx;
1252         break;
1253       }
1254       if (newdt != dtype) {
1255         ast = mk_convert(ast, newdt);
1256         dtype = newdt;
1257       }
1258     }
1259     goto exit_;
1260   }
1261   ii = 0;
1262   /* before processing arguments, add derived type return values if needed */
1263   argt = mk_argt(argt_count); /* mk_argt stuffs away count */
1264 
1265   for (itemp = list; itemp != ITEM_END; itemp = itemp->next) {
1266     sp = itemp->t.stkp;
1267     if (SST_IDG(sp) == S_KEYWORD) {
1268       /* form is <ident> = <expression> */
1269       error(79, 3, gbl.lineno, scn.id.name + SST_CVALG(itemp->t.stkp), CNULL);
1270       itemp->t.sptr = 1;
1271       ARGT_ARG(argt, ii) = astb.i0;
1272       ii++;
1273       continue;
1274     }
1275     if (SST_IDG(sp) == S_TRIPLE) {
1276       /* form is e1:e2:e3 */
1277       error(76, 3, gbl.lineno, SYMNAME(func_sptr), CNULL);
1278       itemp->t.sptr = 1;
1279       ARGT_ARG(argt, ii) = astb.i0;
1280       ii++;
1281       continue;
1282     }
1283     if (SST_IDG(sp) == S_LABEL) {
1284       error(155, 3, gbl.lineno, "Illegal use of alternate return specifier",
1285             CNULL);
1286       ARGT_ARG(argt, ii) = astb.i0;
1287       ii++;
1288       continue;
1289     }
1290     /* check arguments and add to ARGT list, handling derived type
1291        arguments as special case */
1292     sptr1 = 0;
1293     if (SST_IDG(sp) == S_DERIVED || SST_IDG(sp) == S_IDENT)
1294       sptr1 = SST_SYMG(sp);
1295     else if (SST_IDG(sp) == S_LVALUE)
1296       sptr1 = SST_LSYMG(sp);
1297     else if (SST_IDG(sp) == S_SCONST) {
1298       (void)mkarg(sp, &dum);
1299       sptr1 = SST_SYMG(sp);
1300     }
1301     {
1302       /* form is <ident> or <expression> */
1303       param_dummy = inc_dummy_param(func_sptr);
1304       /*  function arguments not processed bylowerilm */
1305 
1306       if ((A_TYPEG(SST_ASTG(sp)) == A_ID) &&
1307           is_iso_cptr(DTYPEG(A_SPTRG(SST_ASTG(sp))))) {
1308         if (find_byval_ref(func_sptr, param_dummy, 1) == PASS_BYVAL) {
1309           /* iso cptr passed by value needs to transform into
1310              pass by value cptr->member : (pass the pointer
1311              sitting in cptr->member by value) */
1312 
1313           psptr = A_SPTRG(SST_ASTG(sp));
1314           msptr = DTY(DTYPEG(psptr) + 1);
1315           new_ast = mk_member(SST_ASTG(sp), mk_id(msptr), DTYPEG(msptr));
1316           SST_ASTP(sp, new_ast);
1317           SST_IDP(sp, S_EXPR);
1318           SST_DTYPEP(sp, DTYPEG(msptr));
1319 
1320           byvalue_ref_arg(sp, &dum, OP_VAL, func_sptr);
1321           ARGT_ARG(argt, ii) = SST_ASTG(sp);
1322         } else {
1323           /* plain pass by ref */
1324           itemp->t.sptr = chkarg(sp, &dum);
1325           ARGT_ARG(argt, ii) = SST_ASTG(sp);
1326         }
1327       } else if (is_iso_cloc(SST_ASTG(sp))) {
1328 
1329         if (find_byval_ref(func_sptr, param_dummy, 1) == PASS_BYVAL) {
1330           /* pass by val iso_c pointer to arg:
1331              C_LOC(arg)   C_FUN_LOC(arg)
1332              is plain old pass by reference
1333              without type checking: get rid of the c_LOC
1334            */
1335           new_ast = ARGT_ARG(A_ARGSG(SST_ASTG(sp)), 0);
1336           if (A_TYPEG(new_ast) == A_ID && (!TARGETG(A_SPTRG(new_ast))) &&
1337               (!POINTERG(A_SPTRG(new_ast))))
1338             errwarn(468);
1339 
1340           SST_ASTP(sp, new_ast);
1341           SST_IDP(sp, S_EXPR);
1342           ARGT_ARG(argt, ii) = SST_ASTG(sp);
1343 
1344         } else {
1345           /* iso_c_loc by reference: pointer to pointer */
1346           ARGT_ARG(argt, ii) = SST_ASTG(sp);
1347         }
1348       } else if (get_byval(func_sptr, param_dummy)) {
1349         if (PASSBYVALG(param_dummy)) {
1350           itemp->t.sptr = byvalue_ref_arg(sp, &dum, OP_BYVAL, func_sptr);
1351         } else {
1352           itemp->t.sptr = byvalue_ref_arg(sp, &dum, OP_VAL, func_sptr);
1353         }
1354         ARGT_ARG(argt, ii) = SST_ASTG(sp);
1355       } else if (pass_char_no_len(func_sptr, param_dummy)) {
1356         itemp->t.sptr = byvalue_ref_arg(sp, &dum, OP_REF, func_sptr);
1357         ARGT_ARG(argt, ii) = SST_ASTG(sp);
1358       } else {
1359         itemp->t.sptr = chkarg(sp, &dum);
1360         ARGT_ARG(argt, ii) = SST_ASTG(sp);
1361       }
1362       ii++;
1363     }
1364   }
1365   if (callee) {
1366     int mem = memsym_of_ast(callee);
1367     if (STYPEG(mem) == ST_MEMBER && !strstr(SYMNAME(func_sptr), "$tbp")) {
1368       VTABLEP(mem, func_sptr);
1369     }
1370     dtype = DTYPEG(mem);
1371   }
1372   ast = mk_func_node(A_FUNC, (callee) ? callee : mk_id(func_sptr), argt_count,
1373                      argt);
1374   A_DTYPEP(ast, dtype);
1375   A_SHAPEP(ast, mkshape(dtype));
1376   if (dtype == DT_ASSCHAR || dtype == DT_ASSNCHAR)
1377     error(89, 3, gbl.lineno, SYMNAME(func_sptr), CNULL);
1378 
1379 exit_:
1380   SST_IDP(stktop, S_EXPR);
1381   SST_ASTP(stktop, ast);
1382   if (shaper)
1383     SST_SHAPEP(stktop, shaper);
1384   else
1385     SST_SHAPEP(stktop, A_SHAPEG(ast));
1386   SST_DTYPEP(stktop, dtype);
1387 
1388 exit_2:
1389   if (kwd_str)
1390     FREE(kwd_str);
1391 
1392   return 1;
1393 }
1394 
1395 /** \brief Resolve forward references in function func_call().
1396  *
1397  * Used by func_call() to resolve any forward refs we may
1398  * encounter since resolve_fwd_refs() in semutil.c gets called after we
1399  * finish processing this function. We also want to check to see if this
1400  * reference resolves to a generic procedure.
1401  */
1402 static void
resolve_fwd_ref(int ref)1403 resolve_fwd_ref(int ref)
1404 {
1405   int mod, decl, hashlk;
1406   int found;
1407 
1408   if (STYPEG(ref) == ST_PROC && FWDREFG(ref)) {
1409     found = 0;
1410     /* Find the module that contains the reference. */
1411     for (mod = SCOPEG(ref); mod; mod = SCOPEG(mod))
1412       if (STYPEG(mod) == ST_MODULE)
1413         break;
1414     if (mod == 0)
1415       return; /* Not in a module. */
1416 
1417     /* Look for the matching declaration. */
1418     for (decl = first_hash(ref); decl; decl = HASHLKG(decl)) {
1419       if (NMPTRG(decl) != NMPTRG(ref))
1420         continue;
1421       if (STYPEG(decl) == ST_PROC && ENCLFUNCG(decl) == mod) {
1422         hashlk = HASHLKG(ref);
1423         *(stb.stg_base + ref) = *(stb.stg_base + decl);
1424         HASHLKP(ref, hashlk);
1425         found = 1;
1426         break;
1427       }
1428     }
1429     if (found)
1430       return;
1431     /* Look for the matching generic declaration. */
1432     for (decl = first_hash(ref); decl; decl = HASHLKG(decl)) {
1433       if (NMPTRG(decl) != NMPTRG(ref))
1434         continue;
1435       if (STYPEG(decl) == ST_USERGENERIC && ENCLFUNCG(decl) == mod) {
1436         hashlk = HASHLKG(ref);
1437         *(stb.stg_base + ref) = *(stb.stg_base + decl);
1438         HASHLKP(ref, hashlk);
1439         found = 1;
1440         break;
1441       }
1442     }
1443   }
1444 }
1445 
1446 int
func_call(SST * stktop,ITEM * list)1447 func_call(SST *stktop, ITEM *list)
1448 {
1449   int func_sptr;
1450   /* Note: If we have a generic tbp (or operator), pass a 0
1451    * flag only if the generic is private. We do this to turn off
1452    * the private error check on the resolved tbp.
1453    */
1454   int ast, flag, sptr, sptr1 = NOSYM;
1455   ast = SST_ASTG(stktop);
1456   switch (A_TYPEG(ast)) {
1457   case A_ID:
1458   case A_LABEL:
1459   case A_ENTRY:
1460   case A_SUBSCR:
1461   case A_SUBSTR:
1462   case A_MEM:
1463     sptr1 = memsym_of_ast(ast);
1464     sptr = BINDG(sptr1);
1465     break;
1466   }
1467 
1468   if (A_TYPEG(ast) != A_MEM && sptr1 > NOSYM && IS_TBP(sptr1)) {
1469     /* Check for generic function that might be sharing the same
1470      * name as a type bound procedure
1471      */
1472     generic_func(SST_SYMG(stktop), stktop, list);
1473     sptr = SST_SYMG(stktop);
1474   }
1475 
1476   if ((STYPEG(sptr) == ST_USERGENERIC || STYPEG(sptr) == ST_OPERATOR) &&
1477       IS_TBP(sptr)) {
1478     return func_call2(stktop, list, sptr1 <= NOSYM || !PRIVATEG(sptr1));
1479   }
1480   /* Check to see if func_sptr is a forward reference that
1481    * resolves to an ST_PROC or a ST_USERGENERIC
1482    */
1483   func_sptr = SST_SYMG(stktop);
1484   if (func_sptr < 0) {
1485     func_sptr = -func_sptr;
1486   }
1487   resolve_fwd_ref(func_sptr);
1488   if (STYPEG(func_sptr) == ST_USERGENERIC)
1489     return generic_func(func_sptr, stktop, list);
1490 
1491   return func_call2(stktop, list, 0);
1492 }
1493 
1494 int
ptrfunc_call(SST * stktop,ITEM * list)1495 ptrfunc_call(SST *stktop, ITEM *list)
1496 {
1497   int func_sptr, sptr1, fval_sptr;
1498   int callee;
1499   ITEM *itemp;
1500   int count, i, ii;
1501   int dum;
1502   int dtproc, iface, paramct, dpdsc, fval;
1503   int dtype;
1504   int ast;
1505   int argt;
1506   SST *sp;
1507   int param_dummy;
1508   int return_value, isarray, save_func_arrinfo;
1509   char *kwd_str; /* where make_kwd_str saves the string */
1510   int argt_count;
1511   int shaper;
1512   int new_ast;
1513   int psptr, msptr;
1514   int pass_pos;
1515 
1516   fix_proc_pointer_call(stktop, &list);
1517   return_value = 0;
1518   save_func_arrinfo = 0;
1519   SST_CVLENP(stktop, 0);
1520   ast = astb.i0; /* initialize just in case error occurs */
1521   kwd_str = NULL;
1522   dtype = A_DTYPEG(astb.i0);
1523   shaper = 0;
1524   pass_pos = -1;
1525   if (SST_IDG(stktop) != S_LVALUE) {
1526     func_sptr = SST_SYMG(stktop);
1527     callee = mk_id(func_sptr);
1528   } else {
1529     func_sptr = SST_LSYMG(stktop);
1530     if (!is_procedure_ptr(func_sptr)) {
1531       /* error must have occurred */
1532       goto exit_;
1533     }
1534     callee = SST_ASTG(stktop);
1535   }
1536   dtype = DTYPEG(func_sptr);
1537 #if DEBUG
1538   assert(DTY(dtype) == TY_PTR, "ptrfunc_call, expected TY_PTR dtype", func_sptr,
1539          4);
1540 #endif
1541   dtproc = DTY(dtype + 1);
1542 #if DEBUG
1543   assert(DTY(dtproc) == TY_PROC, "ptrfunc_call, expected TY_PROC dtype",
1544          func_sptr, 4);
1545 #endif
1546   dtype = DTY(dtproc + 1);
1547   iface = DTY(dtproc + 2);
1548   paramct = DTY(dtproc + 3);
1549   dpdsc = DTY(dtproc + 4);
1550   fval = DTY(dtproc + 5);
1551   if (iface) {
1552     FUNCP(iface, 1); /* mark sptr as a function */
1553   }
1554   if (iface != func_sptr && !paramct) {
1555     proc_arginfo(iface, &paramct, &dpdsc, NULL);
1556     DTY(dtproc + 3) = paramct;
1557     DTY(dtproc + 4) = dpdsc;
1558   }
1559   add_typroc(dtproc);
1560   shaper = 0;
1561   if (iface)
1562     isarray = is_array_dtype(DTYPEG(iface));
1563   else
1564     isarray = is_array_dtype(dtype);
1565   if (dpdsc)
1566     kwd_str = make_keyword_str(paramct, dpdsc);
1567   /* store function st in ERRSYM for error messages; used to be set only
1568    * for CHAR
1569    */
1570   SST_ERRSYMP(stktop, func_sptr);
1571 
1572   if (list == NULL)
1573     list = ITEM_END;
1574   count_actuals(list);
1575   count = carg.nent;
1576   argt_count = carg.nargt;
1577 
1578   init_byval();
1579 
1580   if (kwd_str) {
1581     if (chk_arguments(func_sptr, count, list, kwd_str, paramct, dpdsc, callee,
1582                       &pass_pos))
1583       goto exit_;
1584     count_formal_args(paramct, dpdsc);
1585     argt_count = carg.nargt;
1586     if (!fval)
1587       fval = iface;
1588     /* for ST_ENTRY, the data type info is set in the return value symbol */
1589     if (POINTERG(fval)) {
1590       /*
1591        * since the result of the function is a pointer, a pointer
1592        * temporary must be created.
1593        * Note that for an 'adjustable' return value, its size
1594        * may be dependent on the actual arguments.
1595        */
1596       set_descriptor_sc(sem.sc);
1597       if (isarray) {
1598         return_value = fval;
1599       } else {
1600         return_value = get_next_sym(SYMNAME(iface), "v");
1601         STYPEP(return_value, ST_VAR);
1602         SCP(return_value, SC_BASED);
1603         DTYPEP(return_value, dtype);
1604         DCLDP(return_value, 1);
1605         POINTERP(return_value, 1);
1606         if (DTYG(dtype) == TY_DERIVED && XBIT(58, 0x40000)) {
1607           F90POINTERP(return_value, 1);
1608         } else {
1609           get_static_descriptor(return_value);
1610           get_all_descriptors(return_value);
1611         }
1612       }
1613 #ifdef CLASSG
1614       if (HCCSYMG(return_value) && !CLASSG(return_value))
1615         CLASSP(return_value, CLASSG(FVALG(func_sptr)));
1616 #endif
1617       {
1618         return_value =
1619             gen_pointer_result(return_value, dpdsc, carg.nent, FALSE, iface);
1620         argt_count++;
1621         argt = mk_argt(argt_count); /* mk_argt stuffs away count */
1622         ARGT_ARG(argt, 0) = return_value;
1623         ii = 1;
1624         save_func_arrinfo = 1;
1625       }
1626       set_descriptor_sc(SC_LOCAL);
1627     } else if (ALLOCATTRG(fval)) {
1628       /*
1629        * result of the function is an allocatable, should be similiar
1630        * to a pointer
1631        */
1632       if (isarray) {
1633         fval_sptr = fval;
1634       } else {
1635         fval_sptr = get_next_sym(SYMNAME(iface), "v");
1636         STYPEP(fval_sptr, ST_VAR);
1637         SCP(fval_sptr, SC_BASED);
1638         DTYPEP(fval_sptr, dtype);
1639         DCLDP(fval_sptr, 1);
1640         set_descriptor_sc(sem.sc);
1641         get_static_descriptor(fval_sptr);
1642         get_all_descriptors(fval_sptr);
1643         set_descriptor_sc(SC_LOCAL);
1644       }
1645       return_value = gen_allocatable_result(fval_sptr, dpdsc, carg.nent,
1646                                             (DTYG(dtype) == TY_DERIVED), iface);
1647 #ifdef CLASSG
1648       if (HCCSYMG(fval_sptr) && !CLASSG(fval_sptr))
1649         CLASSP(fval_sptr, CLASSG(FVALG(func_sptr)));
1650 #endif
1651       argt_count++;
1652       argt = mk_argt(argt_count); /* mk_argt stuffs away count */
1653       ARGT_ARG(argt, 0) = return_value;
1654       ii = 1;
1655 
1656       add_p_dealloc_item(memsym_of_ast(return_value));
1657     } else if (allocatable_member(fval)) {
1658       if (ELEMENTALG(iface)) {
1659         int i;
1660         for (i = 0; i < argt_count; ++i) {
1661           shaper = A_SHAPEG(ARG_AST(i));
1662           if (shaper) {
1663             int dt = dtype_with_shape(dtype, shaper);
1664             fval_sptr = get_arr_temp(dt, FALSE, FALSE, FALSE);
1665             DTYPEP(fval_sptr, dt);
1666             STYPEP(fval_sptr, ST_ARRAY);
1667             break;
1668           }
1669         }
1670       }
1671       if (!shaper) {
1672         if (ADJARRG(fval)) {
1673           return_value = ref_entry(iface);
1674           return_value =
1675               gen_array_result(return_value, dpdsc, carg.nent, FALSE, iface);
1676           fval_sptr = A_SPTRG(return_value);
1677         } else {
1678           fval_sptr = get_next_sym(SYMNAME(func_sptr), "d");
1679           if (isarray) {
1680             STYPEP(fval_sptr, ST_ARRAY);
1681           } else {
1682             STYPEP(fval_sptr, ST_VAR);
1683           }
1684           DTYPEP(fval_sptr, dtype);
1685         }
1686       }
1687 
1688       SCP(fval_sptr, sem.sc);
1689       if (ASSUMSHPG(fval) || ASUMSZG(fval)) {
1690         set_descriptor_sc(sem.sc);
1691         get_static_descriptor(fval_sptr);
1692         get_all_descriptors(fval_sptr);
1693         set_descriptor_sc(SC_LOCAL);
1694       }
1695       init_derived_type(fval_sptr, 0, STD_PREV(0));
1696       argt_count++;
1697       argt = mk_argt(argt_count); /* mk_argt stuffs away count */
1698       return_value = mk_id(fval_sptr);
1699       ARGT_ARG(argt, 0) = return_value;
1700       ii = 1;
1701       add_p_dealloc_item(fval_sptr);
1702     } else if (isarray) {
1703       /*
1704        * since the result of the function is an array, a temporary
1705        * must be allocated at run-time even if its bounds are contant.
1706        * Note that for an 'adjustable' return value, its size
1707        * may be dependent on the actual arguments.
1708        */
1709       if (iface)
1710         return_value = ref_entry(iface);
1711       else
1712         return_value = fval;
1713       if (!ADJLENG(fval))
1714         return_value =
1715             gen_array_result(return_value, dpdsc, carg.nent, FALSE, iface);
1716       else
1717         return_value = gen_char_result(return_value, dpdsc, carg.nent);
1718       argt_count++;
1719       argt = mk_argt(argt_count); /* mk_argt stuffs away count */
1720       ARGT_ARG(argt, 0) = return_value;
1721       ii = 1;
1722       /*
1723        * have an array-valued function; save up information
1724        * which would allow substituting the result temp with
1725        * the LHS of an assignment.
1726        */
1727       save_func_arrinfo = 1;
1728     } else if (ADJLENG(fval)) {
1729       return_value = gen_char_result(fval, dpdsc, carg.nent);
1730       argt_count++;
1731       argt = mk_argt(argt_count); /* mk_argt stuffs away count */
1732       ARGT_ARG(argt, 0) = return_value;
1733       ii = 1;
1734     } else {
1735       argt = mk_argt(argt_count); /* mk_argt stuffs away count */
1736       ii = 0;
1737     }
1738 
1739     fval = gen_finalized_result(fval, func_sptr);
1740 
1741     for (i = 0; i < carg.nent; i++) {
1742       sp = ARG_STK(i);
1743       if (sp) {
1744         /* add to ARGT list, handling derived type arguments as
1745          * special case.
1746          */
1747         sptr1 = 0;
1748         if (SST_IDG(sp) == S_LVALUE)
1749           sptr1 = SST_LSYMG(sp);
1750         else if (SST_IDG(sp) == S_DERIVED || SST_IDG(sp) == S_IDENT)
1751           sptr1 = SST_SYMG(sp);
1752         else if (SST_IDG(sp) == S_SCONST) {
1753           (void)mkarg(sp, &dum);
1754           sptr1 = SST_SYMG(sp);
1755         }
1756         {
1757           param_dummy = inc_dummy_param(iface);
1758 
1759           if (is_iso_cloc(SST_ASTG(sp))) {
1760             if (find_byval_ref(func_sptr, param_dummy, 1) == PASS_BYVAL) {
1761               /* pass by val iso_c pointer to arg:
1762                  C_LOC(arg)   C_FUN_LOC(arg)
1763                  is plain old pass by reference
1764                  without type checking: get rid of the
1765                 C_LOC:
1766                */
1767               new_ast = ARGT_ARG(A_ARGSG(SST_ASTG(sp)), 0);
1768               if (A_TYPEG(new_ast) == A_ID && (!TARGETG(A_SPTRG(new_ast))) &&
1769                   (!POINTERG(A_SPTRG(new_ast))))
1770                 errwarn(468);
1771 
1772               SST_ASTP(sp, new_ast);
1773               SST_IDP(sp, S_EXPR);
1774               ARGT_ARG(argt, ii) = SST_ASTG(sp);
1775             } else {
1776               /* iso_c_loc by reference pointer to pointer */
1777               ARGT_ARG(argt, ii) = ARG_AST(i);
1778             }
1779 
1780           } else if (get_byval(func_sptr, param_dummy)) {
1781             /*  function arguments not processed by lowerilm */
1782             if (PASSBYVALG(param_dummy)) {
1783               if (OPTARGG(param_dummy)) {
1784                 int assn = sem_tempify(sp);
1785                 (void)add_stmt(assn);
1786                 SST_ASTP(sp, A_DESTG(assn));
1787                 byvalue_ref_arg(sp, &dum, OP_REF, func_sptr);
1788               } else if (!need_tmp_retval(iface, param_dummy)) {
1789                 byvalue_ref_arg(sp, &dum, OP_BYVAL, iface);
1790               } else {
1791                 byvalue_ref_arg(sp, &dum, OP_VAL, iface);
1792               }
1793             } else {
1794               byvalue_ref_arg(sp, &dum, OP_VAL, iface);
1795             }
1796             ARGT_ARG(argt, ii) = SST_ASTG(sp);
1797           } else if (pass_char_no_len(func_sptr, param_dummy)) {
1798             byvalue_ref_arg(sp, &dum, OP_REF, func_sptr);
1799             ARGT_ARG(argt, ii) = SST_ASTG(sp);
1800           } else {
1801             ARGT_ARG(argt, ii) = ARG_AST(i);
1802           }
1803           ii++;
1804         }
1805       } else if (i == pass_pos) {
1806         ARGT_ARG(argt, ii) = A_PARENTG(callee);
1807         ii++;
1808       } else {
1809         int npad;
1810         for (npad = ARG_AST(i); npad > 0; npad--) {
1811           ARGT_ARG(argt, ii) = astb.ptr0;
1812           ii++;
1813         }
1814       }
1815     }
1816     if (return_value) {
1817       /* return_value is symbol if result is of derived type;
1818        * otherwise, it's an ast.
1819        */
1820       dtype = DTYPEG(A_SPTRG(return_value));
1821       ast = mk_func_node(A_CALL, callee, argt_count, argt);
1822       sem.arrfn.call_std = add_stmt(ast);
1823       sem.arrfn.sptr = iface;
1824       if (save_func_arrinfo) {
1825         sem.arrfn.return_value = return_value;
1826         if (ALLOCG(A_SPTRG(return_value)))
1827           sem.arrfn.alloc_std = sem.alloc_std;
1828       }
1829       ast = return_value;
1830     } else {
1831       ast = mk_func_node(A_FUNC, callee, argt_count, argt);
1832     }
1833     if (ELEMENTALG(iface)) {
1834       int argc;
1835       for (argc = 0; argc < argt_count; ++argc) {
1836         /* Use first shaped argument */
1837         shaper = A_SHAPEG(ARGT_ARG(argt, argc));
1838         if (shaper)
1839           break;
1840       }
1841       if (shaper == 0) {
1842         shaper = mkshape(dtype);
1843       } else {
1844         dtype = dtype_with_shape(dtype, shaper);
1845         A_SHAPEP(ast, shaper);
1846       }
1847     } else {
1848       shaper = mkshape(dtype);
1849     }
1850     A_DTYPEP(ast, dtype);
1851     goto exit_;
1852   }
1853   ii = 0;
1854   /* before processing arguments, add derived type return values if needed */
1855   argt = mk_argt(argt_count); /* mk_argt stuffs away count */
1856 
1857   for (itemp = list; itemp != ITEM_END; itemp = itemp->next) {
1858     sp = itemp->t.stkp;
1859     if (SST_IDG(sp) == S_KEYWORD) {
1860       /* form is <ident> = <expression> */
1861       error(79, 3, gbl.lineno, scn.id.name + SST_CVALG(itemp->t.stkp), CNULL);
1862       itemp->t.sptr = 1;
1863       ARGT_ARG(argt, ii) = astb.i0;
1864       ii++;
1865       continue;
1866     }
1867     if (SST_IDG(sp) == S_TRIPLE) {
1868       /* form is e1:e2:e3 */
1869       error(76, 3, gbl.lineno, SYMNAME(func_sptr), CNULL);
1870       itemp->t.sptr = 1;
1871       ARGT_ARG(argt, ii) = astb.i0;
1872       ii++;
1873       continue;
1874     }
1875     if (SST_IDG(sp) == S_LABEL) {
1876       error(155, 3, gbl.lineno, "Illegal use of alternate return specifier",
1877             CNULL);
1878       ARGT_ARG(argt, ii) = astb.i0;
1879       ii++;
1880       continue;
1881     }
1882     /* check arguments and add to ARGT list, handling derived type
1883        arguments as special case */
1884     sptr1 = 0;
1885     if (SST_IDG(sp) == S_DERIVED || SST_IDG(sp) == S_IDENT)
1886       sptr1 = SST_SYMG(sp);
1887     else if (SST_IDG(sp) == S_LVALUE)
1888       sptr1 = SST_LSYMG(sp);
1889     else if (SST_IDG(sp) == S_SCONST) {
1890       (void)mkarg(sp, &dum);
1891       sptr1 = SST_SYMG(sp);
1892     }
1893     {
1894       /* form is <ident> or <expression> */
1895       param_dummy = inc_dummy_param(iface);
1896       /*  function arguments not processed bylowerilm */
1897 
1898       if ((A_TYPEG(SST_ASTG(sp)) == A_ID) &&
1899           is_iso_cptr(DTYPEG(A_SPTRG(SST_ASTG(sp))))) {
1900         if (find_byval_ref(iface, param_dummy, 1) == PASS_BYVAL) {
1901           /* iso cptr passed by value needs to transform into
1902              pass by value cptr->member : (pass the pointer
1903              sitting in cptr->member by value) */
1904 
1905           psptr = A_SPTRG(SST_ASTG(sp));
1906           msptr = DTY(DTYPEG(psptr) + 1);
1907           new_ast = mk_member(SST_ASTG(sp), mk_id(msptr), DTYPEG(msptr));
1908           SST_ASTP(sp, new_ast);
1909           SST_IDP(sp, S_EXPR);
1910           SST_DTYPEP(sp, DTYPEG(msptr));
1911 
1912           byvalue_ref_arg(sp, &dum, OP_VAL, iface);
1913           ARGT_ARG(argt, ii) = SST_ASTG(sp);
1914         } else {
1915           /* plain pass by ref */
1916           itemp->t.sptr = chkarg(sp, &dum);
1917           ARGT_ARG(argt, ii) = SST_ASTG(sp);
1918         }
1919       } else if (is_iso_cloc(SST_ASTG(sp))) {
1920 
1921         if (find_byval_ref(iface, param_dummy, 1) == PASS_BYVAL) {
1922           /* pass by val iso_c pointer to arg:
1923              C_LOC(arg)   C_FUN_LOC(arg)
1924              is plain old pass by reference
1925              without type checking: get rid of the c_LOC
1926            */
1927           new_ast = ARGT_ARG(A_ARGSG(SST_ASTG(sp)), 0);
1928           if (A_TYPEG(new_ast) == A_ID && (!TARGETG(A_SPTRG(new_ast))) &&
1929               (!POINTERG(A_SPTRG(new_ast))))
1930             errwarn(468);
1931 
1932           SST_ASTP(sp, new_ast);
1933           SST_IDP(sp, S_EXPR);
1934           ARGT_ARG(argt, ii) = SST_ASTG(sp);
1935 
1936         } else {
1937           /* iso_c_loc by reference: pointer to pointer */
1938           ARGT_ARG(argt, ii) = SST_ASTG(sp);
1939         }
1940       } else if (get_byval(iface, param_dummy)) {
1941 
1942         itemp->t.sptr = byvalue_ref_arg(sp, &dum, OP_VAL, iface);
1943         ARGT_ARG(argt, ii) = SST_ASTG(sp);
1944       } else if (pass_char_no_len(iface, param_dummy)) {
1945         itemp->t.sptr = byvalue_ref_arg(sp, &dum, OP_REF, iface);
1946         ARGT_ARG(argt, ii) = SST_ASTG(sp);
1947 
1948       } else {
1949         itemp->t.sptr = chkarg(sp, &dum);
1950         ARGT_ARG(argt, ii) = SST_ASTG(sp);
1951       }
1952       ii++;
1953     }
1954   }
1955 
1956   ast = mk_func_node(A_FUNC, callee, argt_count, argt);
1957   A_DTYPEP(ast, dtype);
1958   A_SHAPEP(ast, mkshape(dtype));
1959   if (dtype == DT_ASSCHAR || dtype == DT_ASSNCHAR)
1960     error(89, 3, gbl.lineno, SYMNAME(func_sptr), CNULL);
1961 
1962 exit_:
1963   SST_IDP(stktop, S_EXPR);
1964   SST_ASTP(stktop, ast);
1965   if (shaper)
1966     SST_SHAPEP(stktop, shaper);
1967   else
1968     SST_SHAPEP(stktop, A_SHAPEG(ast));
1969   SST_DTYPEP(stktop, dtype);
1970 exit_2:
1971   if (kwd_str)
1972     FREE(kwd_str);
1973 
1974   return 1;
1975 }
1976 
1977 /*
1978  * add the proc data type to a list so that semfin can
1979  * adjust the PARAMCT and DPDSC values for functions
1980  * returning certain types.
1981  */
1982 static void
add_typroc(int dt)1983 add_typroc(int dt)
1984 {
1985   int i;
1986 
1987   for (i = 0; i < sem.typroc_avail; i++) {
1988     if (sem.typroc_base[i] == dt)
1989       return;
1990   }
1991   sem.typroc_avail++;
1992   NEED(sem.typroc_avail, sem.typroc_base, int, sem.typroc_size,
1993        sem.typroc_avail + 50);
1994   sem.typroc_base[sem.typroc_avail - 1] = dt;
1995 }
1996 
1997 static void
count_actuals(ITEM * list)1998 count_actuals(ITEM *list)
1999 {
2000   ITEM *itemp;
2001   SST *sp;
2002   int dum;
2003 
2004   carg.nargt = carg.nent = 0;
2005   for (itemp = list; itemp != ITEM_END; itemp = itemp->next) {
2006     sp = itemp->t.stkp;
2007     if (SST_IDG(sp) == S_KEYWORD)
2008       sp = SST_E3G(sp);
2009     /* adjust argument count, if derived type arguments are used as
2010        individual entities */
2011     if (SST_IDG(sp) == S_SCONST) {
2012       mkarg(sp, &dum); /* mkarg will assign to tmp- S_IDENT */
2013       carg.nargt++;
2014     } else
2015       carg.nargt++;
2016     carg.nent++;
2017   }
2018 }
2019 
2020 static void
count_formals(int sptr)2021 count_formals(int sptr)
2022 {
2023   count_formal_args(PARAMCTG(sptr), DPDSCG(sptr));
2024 }
2025 
2026 static void
count_formal_args(int paramct,int dpdsc)2027 count_formal_args(int paramct, int dpdsc)
2028 {
2029   int *dscptr;
2030   int arg;
2031   int i;
2032 
2033   carg.nargt = carg.nent = paramct;
2034   dscptr = aux.dpdsc_base + dpdsc;
2035   for (i = paramct; i > 0; i--) {
2036     arg = *dscptr++;
2037     if (CLASSG(arg) && CCSYMG(arg) /*&& OPTARGG(arg)*/) {
2038       carg.nargt--;
2039       carg.nent--;
2040     }
2041     if (DESCARRAYG(arg) && NODESCG(arg) && DTY(DTYPEG(arg)) == TY_ARRAY &&
2042         NODESCG(arg)) {
2043       carg.nargt--;
2044       carg.nent--;
2045     }
2046   }
2047 }
2048 
2049 static int
fix_character_length(int dtype,int func_sptr)2050 fix_character_length(int dtype, int func_sptr)
2051 {
2052   int dscptr, paramct, clen;
2053   if (DTY(dtype) != TY_CHAR
2054       && DTY(dtype) != TY_NCHAR
2055   )
2056     return dtype;
2057 
2058   /* we have a character datatype, replace any formal arguments in
2059    * the character length by their values, rewrite the length */
2060   dscptr = DPDSCG(func_sptr);
2061   paramct = PARAMCTG(func_sptr);
2062   ast_visit(1, 1);
2063   replace_arguments(dscptr, paramct);
2064   clen = ast_rewrite(DTY(dtype + 1));
2065   ast_unvisit();
2066   if (clen == DTY(dtype + 1))
2067     return dtype;
2068   /* character length has changed, create new character datatype */
2069   dtype = get_type(2, DTY(dtype), clen);
2070   return dtype;
2071 } /* fix_character_length */
2072 
2073 static int
gen_pointer_result(int array_value,int dscptr,int nactuals,LOGICAL is_derived,int func_sptr)2074 gen_pointer_result(int array_value, int dscptr, int nactuals,
2075                    LOGICAL is_derived, int func_sptr)
2076 {
2077   int o_dt;
2078   int dt;
2079   int arr_tmp;
2080   int pvar;
2081 
2082   o_dt = DTYPEG(array_value);
2083   if (DTY(o_dt) == TY_ARRAY) {
2084     int l;
2085     dt = dup_array_dtype(o_dt);
2086     l = fix_character_length(DTY(dt + 1), func_sptr);
2087     DTY(dt + 1) = l;
2088   } else {
2089     dt = fix_character_length(o_dt, func_sptr);
2090   }
2091   /*
2092    * Create a new pointer temporary with a new dtype record
2093    */
2094   if (is_derived) {
2095     arr_tmp = array_value;
2096     DTYPEP(arr_tmp, dt);
2097   } else {
2098     int ddt;
2099     arr_tmp = get_next_sym(SYMNAME(array_value), NULL);
2100     dup_sym(arr_tmp, stb.stg_base + array_value);
2101     DTYPEP(arr_tmp, dt);
2102     DESCRP(arr_tmp, 0);
2103     /*
2104      * set_descriptor_sc(sem.sc); already called in the caller
2105      */
2106     get_static_descriptor(arr_tmp);
2107     get_all_descriptors(arr_tmp);
2108     /* need to have different MIDNUM than arr_value */
2109     /* otherwise multiple declaration */
2110     pvar = sym_get_ptr(arr_tmp);
2111     MIDNUMP(arr_tmp, pvar);
2112     NODESCP(arr_tmp, 0);
2113     ddt = DDTG(dt);
2114     if ((DTY(dt) == TY_CHAR && dt != DT_DEFERCHAR) ||
2115         (DTY(dt) == TY_NCHAR && dt != DT_DEFERNCHAR)) {
2116       add_auto_len(arr_tmp, 0);
2117       if (CVLENG(arr_tmp))
2118         ERLYSPECP(CVLENG(arr_tmp), 1);
2119     }
2120   }
2121   if (gbl.internal > 1) {
2122     INTERNALP(arr_tmp, 1);
2123   } else {
2124     INTERNALP(arr_tmp, 0);
2125   }
2126   if (DTY(o_dt) == TY_ARRAY) {
2127     STYPEP(arr_tmp, ST_ARRAY);
2128     ALLOCP(arr_tmp, 1);
2129   } else
2130     STYPEP(arr_tmp, ST_VAR);
2131   SCOPEP(arr_tmp, stb.curr_scope);
2132   IGNOREP(arr_tmp, 0);
2133   SLNKP(arr_tmp, 0);
2134   SOCPTRP(arr_tmp, 0);
2135   SCP(arr_tmp, SC_BASED);
2136   ref_based_object(arr_tmp);
2137 
2138   return mk_id(arr_tmp);
2139 }
2140 
2141 static int
gen_allocatable_result(int array_value,int dscptr,int nactuals,LOGICAL is_derived,int func_sptr)2142 gen_allocatable_result(int array_value, int dscptr, int nactuals,
2143                        LOGICAL is_derived, int func_sptr)
2144 {
2145   int o_dt;
2146   int dt;
2147   int arr_tmp;
2148   int pvar;
2149   int astrslt;
2150   int astnull;
2151   int sptrnull;
2152 
2153   o_dt = DTYPEG(array_value);
2154   if (DTY(o_dt) == TY_ARRAY) {
2155     int l;
2156     dt = dup_array_dtype(o_dt);
2157     l = fix_character_length(DTY(dt + 1), func_sptr);
2158     DTY(dt + 1) = l;
2159   } else {
2160     dt = fix_character_length(o_dt, func_sptr);
2161   }
2162   /*
2163    * Create a new allocatable temporary with a new dtype record
2164    */
2165   arr_tmp = get_next_sym(SYMNAME(array_value), NULL);
2166   dup_sym(arr_tmp, stb.stg_base + array_value);
2167   DTYPEP(arr_tmp, dt);
2168   DESCRP(arr_tmp, 0);
2169   /*
2170    * Would like to call set_descriptor_sc() at the beginning
2171    * of func2_call() and restore at the end; however, there
2172    * are still semsym things that might need to be done to user
2173    * variables.  So, only call set_descriptor_sc() when we know
2174    * we are creating temps.
2175    */
2176   set_descriptor_sc(sem.sc);
2177   get_static_descriptor(arr_tmp);
2178   get_all_descriptors(arr_tmp);
2179   /* need to have different MIDNUM than arr_value */
2180   /* otherwise multiple declaration */
2181   pvar = sym_get_ptr(arr_tmp);
2182   MIDNUMP(arr_tmp, pvar);
2183   NODESCP(arr_tmp, 0);
2184   ALLOCATTRP(arr_tmp, 1);
2185   set_descriptor_sc(SC_LOCAL);
2186   if (DTY(o_dt) == TY_ARRAY) {
2187     STYPEP(arr_tmp, ST_ARRAY);
2188     ALLOCP(arr_tmp, 1);
2189   } else
2190     STYPEP(arr_tmp, ST_VAR);
2191   if (gbl.internal > 1) {
2192     INTERNALP(arr_tmp, 1);
2193   } else {
2194     INTERNALP(arr_tmp, 0);
2195   }
2196   SCOPEP(arr_tmp, stb.curr_scope);
2197   IGNOREP(arr_tmp, 0);
2198   SLNKP(arr_tmp, 0);
2199   SOCPTRP(arr_tmp, 0);
2200   SCP(arr_tmp, SC_BASED);
2201   astrslt = ref_based_object_sc(arr_tmp, sem.sc);
2202   ALLOCATTRP(arr_tmp, 1);
2203   astrslt = mk_id(arr_tmp);
2204 
2205   return astrslt;
2206 }
2207 
2208 /*
2209  * check whether an array descriptor has fixed bounds
2210  * and whether the bounds are 'small enough'
2211  */
2212 static int
small_enough(ADSC * ad,int numdim)2213 small_enough(ADSC *ad, int numdim)
2214 {
2215   int i;
2216   ISZ_T size;
2217   size = 1;
2218   for (i = 0; i < numdim; ++i) {
2219     int l, u;
2220     ISZ_T lv, uv;
2221     l = AD_LWBD(ad, i);
2222     if (l && !A_ALIASG(l))
2223       return 0;
2224     lv = 1; /* default */
2225     if (l) {
2226       l = A_ALIASG(l);
2227       assert(A_TYPEG(l) == A_CNST,
2228              "small_enough: expecting constant lower bound", l, 4);
2229       lv = get_isz_cval(A_SPTRG(l));
2230     }
2231     u = AD_UPBD(ad, i);
2232     if (!u || !A_ALIASG(u))
2233       return 0; /* not fixed size, or assumed-size */
2234     u = A_ALIASG(u);
2235     assert(A_TYPEG(u) == A_CNST, "small_enough: expecting constant upper bound",
2236            l, 4);
2237     uv = get_isz_cval(A_SPTRG(u));
2238     size *= (uv - lv + 1);
2239     if (size > 1000)
2240       return 0;
2241   }
2242   return 1;
2243 } /* small_enough */
2244 
2245 static int
gen_array_result(int array_value,int dscptr,int nactuals,LOGICAL is_derived,int callee)2246 gen_array_result(int array_value, int dscptr, int nactuals, LOGICAL is_derived,
2247                  int callee)
2248 {
2249   int numdim;
2250   int o_dt;
2251   int dt;
2252   int arr_tmp;
2253   int ii;
2254   ADSC *ad;
2255 
2256   o_dt = DTYPEG(array_value);
2257   ad = AD_DPTR(o_dt);
2258   numdim = AD_NUMDIM(ad);
2259   /*
2260    * 0.  Check whether the return array size is fixed size and
2261    *     small enough to simply use a local array
2262    */
2263   if (small_enough(ad, numdim)) {
2264     /* use same name, etc. */
2265     arr_tmp = get_next_sym(SYMNAME(array_value), NULL);
2266     dup_sym(arr_tmp, stb.stg_base + array_value);
2267     NODESCP(arr_tmp, 0);
2268     DESCRP(arr_tmp, 0);
2269     ARGP(arr_tmp, 1);
2270     STYPEP(arr_tmp, ST_ARRAY);
2271     SCOPEP(arr_tmp, stb.curr_scope);
2272     IGNOREP(arr_tmp, 0);
2273     DTYPEP(arr_tmp, o_dt);
2274     SLNKP(arr_tmp, 0);
2275     if (gbl.internal > 1) {
2276       INTERNALP(arr_tmp, 1);
2277     } else {
2278       INTERNALP(arr_tmp, 0);
2279     }
2280     SCP(arr_tmp, sem.sc);
2281     return mk_id(arr_tmp);
2282   }
2283   /*
2284    * 1.  Create an allocatable temporary with a deferred-shape dtype
2285    *     using the sem.arrdim data structure.
2286    */
2287   sem.arrdim.ndefer = sem.arrdim.ndim = numdim;
2288   for (ii = 0; ii < numdim; ii++)
2289     sem.bounds[ii].lowtype = S_NULL;
2290   dt = mk_arrdsc();
2291   DTY(dt + 1) = DTY(o_dt + 1);
2292 
2293   if (is_derived)
2294     arr_tmp = array_value;
2295   else {
2296     arr_tmp = get_next_sym(SYMNAME(array_value), NULL);
2297     dup_sym(arr_tmp, stb.stg_base + array_value);
2298     NODESCP(arr_tmp, 0);
2299     DESCRP(arr_tmp, 0);
2300     PARAMCTP(arr_tmp, 0);
2301   }
2302 
2303   ARGP(arr_tmp, 1);
2304   STYPEP(arr_tmp, ST_ARRAY);
2305   SCOPEP(arr_tmp, stb.curr_scope);
2306   IGNOREP(arr_tmp, 0);
2307   DTYPEP(arr_tmp, dt);
2308   SLNKP(arr_tmp, 0);
2309   if (gbl.internal > 1) {
2310     INTERNALP(arr_tmp, 1);
2311   } else {
2312     INTERNALP(arr_tmp, 0);
2313   }
2314   SCP(arr_tmp, SC_BASED);
2315   ALLOCP(arr_tmp, 1);
2316   HCCSYMP(arr_tmp, 1);
2317   ref_based_object_sc(arr_tmp, sem.sc);
2318 
2319   /*
2320    * 2.  Generate the assignments to the bounds temporaries
2321    *     of the array temp and allocate it.
2322    * 2a. The values of the temporaries may depend on the actual arguments
2323    *     (e.g., a specification expression may refer to a formal); therefore,
2324    *     the 'formals' are replaced with the actuals.
2325    * 2b. If the current context is an internal procedure whose host is a
2326    *     module subroutine and the function called is also internal. The
2327    *     values of the bounds temps may depend on the dummy arguments of
2328    *     the host.  At this point, there are two symbol table entries for
2329    *     the host:
2330    *     1) ST_ENTRY and this is the parent scope of the current internal
2331    *        routine
2332    *     2) ST_PROC since the host is within a module -- recall that when a
2333    *        module is compiled, two syms are created for the module routine:
2334    *        an ST_PROC representing the routine's interface and an ST_ENTRY
2335    *        for when the body of the routine is actually compiled.
2336    *     These sym entries are distinct and each will have their own sym
2337    *     entries for their dummy arguments.  If there are bounds declarations
2338    *     in any array formal or result which refer to a host dummy, the
2339    *     corresponding sym entry for the dummy is the ST_PROC.  When the
2340    *     callee is invoked, the host dummy is in scope of the ST_ENTRY.
2341    *     Consequently, the bounds values refer to the incorrect instance of
2342    *     the host dummy.  The ASTs of the ST_PROC's host dummies referenced
2343    *     in the bounds computations must be replaced with the ASTs of the
2344    *     corresponding ST_ENTRY's host host dummies.
2345    */
2346   ad = AD_DPTR(o_dt);
2347   if (AD_ADJARR(ad)) {
2348     precompute_arg_intrin(dscptr, nactuals);
2349     precompute_args(dscptr, nactuals);
2350   }
2351   ast_visit(1, 1);
2352   if (gbl.currmod != 0 && gbl.internal > 1 && callee && INTERNALG(callee)) {
2353     /*
2354      * In an internal procedure whose host is a module routine and the
2355      * called function is also internal.
2356      */
2357     int host = SCOPEG(gbl.currsub); /* module routine (probably an ST_ALIAS) */
2358     /*
2359      * if sem.modhost_proc is non-zero, the host's ST_PROC & ST_ENTRY were
2360      * already discovered
2361      */
2362     if (sem.modhost_proc == 0) {
2363       /* starting with the first entry in the hash list, find the ST_PROC*/
2364       sem.modhost_proc = get_symtype(ST_PROC, first_hash(host));
2365       if (sem.modhost_proc != 0) {
2366         /*
2367          * if ST_PROC found, now find the ST_ENTRY - it will follow the ST_PROC
2368          * so do not have start over at first_hash(host).
2369          */
2370         sem.modhost_entry = get_symtype(ST_ENTRY, HASHLKG(sem.modhost_proc));
2371         if (sem.modhost_entry == 0)
2372           sem.modhost_proc = 0;
2373       }
2374     }
2375     if (sem.modhost_entry != 0) {
2376       /*
2377        * scan the ST_PROC's and ST_ENTRY's arguments and replace the
2378        * ASTs of the ST_PROC's args with the ASTs of the ST_ENTRY's args.
2379        */
2380       int i;
2381       for (i = PARAMCTG(sem.modhost_proc); i > 0; i--) {
2382         int old = aux.dpdsc_base[DPDSCG(sem.modhost_proc) + i - 1];
2383         int new = aux.dpdsc_base[DPDSCG(sem.modhost_entry) + i - 1];
2384         ast_replace(mk_id(old), mk_id(new));
2385       }
2386     }
2387   }
2388   replace_arguments(dscptr, nactuals);
2389   /*
2390    * 3.  Rewrite the bounds expressions of the original
2391    *     declaration of the function.  These values become
2392    *     the bounds expressions of the array temp and are
2393    *     stored in the sem.bounds data structure.
2394    *     Reset the sem.arrdim fields of (1) since
2395    *     precompute_arg_intrin() could cause them to be set
2396    *     for another context
2397    */
2398   sem.arrdim.ndefer = sem.arrdim.ndim = numdim;
2399   for (ii = 0; ii < numdim; ii++) {
2400     sem.bounds[ii].lowtype = S_NULL;
2401     if (AD_LWBD(ad, ii)) {
2402       replace_formal_triples(AD_LWBD(ad, ii), dscptr, nactuals);
2403       sem.bounds[ii].lwast = ast_rewrite((int)AD_LWBD(ad, ii));
2404     } else {
2405       sem.bounds[ii].lwast = astb.bnd.one;
2406     }
2407     replace_formal_triples(AD_UPBD(ad, ii), dscptr, nactuals);
2408     sem.bounds[ii].upast = ast_rewrite((int)AD_UPBD(ad, ii));
2409   }
2410   ast_unvisit();
2411   /*
2412    * 4.  assign values to the bounds temporaries and
2413    *     allocate the array; the utility routine also
2414    *     saves enough information so that the array
2415    *     temporary can be deallocated.
2416    */
2417   gen_allocate_array(arr_tmp);
2418   return mk_id(arr_tmp);
2419 }
2420 
2421 static int
gen_char_result(int fval,int dscptr,int nactuals)2422 gen_char_result(int fval, int dscptr, int nactuals)
2423 {
2424   int dt, edt;
2425   int ctemp;
2426   int len;
2427 
2428   dt = DTYPEG(fval);
2429   edt = dt;
2430   if (DTY(dt) == TY_ARRAY)
2431     edt = DTY(dt + 1);
2432   ast_visit(1, 1);
2433   replace_arguments(dscptr, nactuals);
2434   len = ast_rewrite(DTY(edt + 1));
2435   ast_unvisit();
2436   if (A_TYPEG(len) == A_INTR && A_OPTYPEG(len) == I_LEN) {
2437     int aaa;
2438     aaa = ARGT_ARG(A_ARGSG(len), 0);
2439     if (A_TYPEG(aaa) == A_INTR && A_OPTYPEG(aaa) == I_TRIM) {
2440       len = ast_intr(I_LEN_TRIM, astb.bnd.dtype, 1, ARGT_ARG(A_ARGSG(aaa), 0));
2441     }
2442   }
2443   if (len != DTY(edt + 1)) {
2444     edt = get_type(2, TY_CHAR, len);
2445     if (DTY(dt) != TY_ARRAY)
2446       dt = edt;
2447     else {
2448       dt = dup_array_dtype(dt);
2449       DTY(dt + 1) = edt;
2450     }
2451   }
2452   ctemp = get_ch_temp(dt);
2453   return mk_id(ctemp);
2454 }
2455 
2456 static void
precompute_arg_intrin(int dscptr,int nactuals)2457 precompute_arg_intrin(int dscptr, int nactuals)
2458 {
2459   int numdim;
2460   int ii;
2461   int dtype;
2462 
2463   for (ii = 0; ii < nactuals; ii++) {
2464     int arg, tmp, assn;
2465     if (!ARG_STK(ii))
2466       continue;
2467     arg = ARG_AST(ii);
2468     if (A_TYPEG(arg) == A_INTR) {
2469       dtype = A_DTYPEG(arg);
2470       if (DTY(dtype) == TY_ARRAY) {
2471         int shape;
2472         shape = A_SHAPEG(arg);
2473         if (shape) {
2474           if (SHD_NDIM(shape) != ADD_NUMDIM(dtype)) {
2475             tmp = get_shape_arr_temp(arg);
2476           } else {
2477             ADSC *ad;
2478             ad = AD_DPTR(dtype);
2479             if (AD_DEFER(ad) || AD_ADJARR(ad) || AD_NOBOUNDS(ad)) {
2480               tmp = get_shape_arr_temp(arg);
2481             } else
2482               tmp = get_arr_temp(dtype, FALSE, TRUE, FALSE);
2483           }
2484         } else
2485           tmp = get_arr_temp(dtype, FALSE, TRUE, FALSE);
2486       } else {
2487         dtype = get_temp_dtype(dtype, arg);
2488         tmp = get_temp(dtype);
2489       }
2490       assn = mk_assn_stmt(mk_id(tmp), arg, dtype);
2491       (void)add_stmt(assn);
2492       ARG_AST(ii) = A_DESTG(assn);
2493       SST_ASTP(ARG_STK(ii), ARG_AST(ii));
2494     }
2495   }
2496 }
2497 
2498 static void
precompute_args(int dscptr,int nactuals)2499 precompute_args(int dscptr, int nactuals)
2500 {
2501   int numdim;
2502   int ii;
2503 
2504   for (ii = 0; ii < nactuals; ii++) {
2505     int arg, dtype, assn;
2506     if (!ARG_STK(ii))
2507       continue;
2508     arg = ARG_AST(ii);
2509     if (!A_CALLFGG(arg))
2510       continue;
2511     dtype = A_DTYPEG(arg);
2512     if (!DT_ISSCALAR(dtype) && DTY(dtype) != TY_DERIVED)
2513       continue;
2514     assn = sem_tempify(ARG_STK(ii));
2515     (void)add_stmt(assn);
2516     ARG_AST(ii) = A_DESTG(assn);
2517     SST_ASTP(ARG_STK(ii), ARG_AST(ii));
2518   }
2519 }
2520 
2521 static void
rewrite_triples(int ast_subscr,int dscptr,int nactuals)2522 rewrite_triples(int ast_subscr, int dscptr, int nactuals)
2523 {
2524   int numdim;
2525   int i, j;
2526   int sptr_actual;
2527   int ast_actual = A_LOPG(ast_subscr);
2528 
2529   if (A_TYPEG(ast_actual) == A_ID) {
2530     sptr_actual = A_SPTRG(ast_actual);
2531   } else if (A_TYPEG(ast_actual) == A_MEM) {
2532     sptr_actual = A_SPTRG(A_MEMG(ast_actual));
2533   } else {
2534     return;
2535   }
2536 
2537   for (i = 0; i < nactuals; i++) {
2538     if (ARG_STK(i)) {
2539       int sptr_arg;
2540       int arg = ARG_AST(i);
2541       if (A_TYPEG(arg) == A_ID) {
2542         sptr_arg = A_SPTRG(arg);
2543       } else if (A_TYPEG(arg) == A_MEM) {
2544         sptr_arg = A_SPTRG(A_MEMG(arg));
2545       } else {
2546         continue;
2547       }
2548       if (sptr_arg == sptr_actual) {
2549         int asd = A_ASDG(ast_subscr);
2550         int ndim = ASD_NDIM(asd);
2551         int dt_formal = DTYPEG(aux.dpdsc_base[dscptr + i]);
2552         ADSC *ad_formal = AD_DPTR(dt_formal);
2553         int changed = FALSE;
2554         for (j = 0; j < ndim; j++) {
2555           int sub = ASD_SUBS(asd, j);
2556           if (A_TYPEG(sub) == A_TRIPLE &&
2557               AD_LWBD(ad_formal, j) == A_LBDG(sub) &&
2558               AD_UPBD(ad_formal, j) == A_UPBDG(sub)) {
2559             /* the triple is from the dummy arg, replace it */
2560             ADSC *ad_actual = AD_DPTR(DTYPEG(sptr_actual));
2561             int triple = mk_triple(AD_LWBD(ad_actual, j), AD_UPBD(ad_actual, j),
2562                                    AD_EXTNTAST(ad_actual, j));
2563             ast_replace(sub, triple);
2564           }
2565         }
2566       }
2567     }
2568   }
2569 }
2570 
2571 /*
2572  * A formal array can be subscripted in a specification expression;
2573  * when this occurs, need to check if the corresponding actual argument is
2574  * an array section.   The original processing can create something like:
2575  *    act(1:10)(1)
2576  * where the formal appears as formal(1) is some expression and the actual
2577  * argument is act(1:10).  Eventually, the illegal subscripting could  lead
2578  * to an ICE.
2579  */
2580 static void
rewrite_subscr(int ast_subscr,int dscptr,int nactuals)2581 rewrite_subscr(int ast_subscr, int dscptr, int nactuals)
2582 {
2583   int ast;
2584   int sptr;
2585   int arr, rpl;
2586   int flg;
2587   int i;
2588   int actarr;
2589   int asd, numdim;
2590   int subs[7]; /* maximum number of dimensions */
2591   int triple;
2592   int subscr;
2593 
2594   arr = A_LOPG(ast_subscr);
2595   if (A_TYPEG(arr) != A_ID)
2596     return;
2597   /*
2598    * Make sure what's being subscripted is a formal array which is being
2599    * replaced by some interesting array expression ...
2600    * is
2601    */
2602   rpl = A_REPLG(arr);
2603   if (!rpl)
2604     /* not being replaced */
2605     return;
2606   sptr = A_SPTRG(arr);
2607   if (STYPEG(sptr) != ST_ARRAY && SCG(sptr) != SC_DUMMY)
2608     return;
2609   flg = 0;
2610   for (i = 0; i < nactuals; i++) {
2611     if (sptr == aux.dpdsc_base[dscptr + i]) {
2612       /* is a formal argument of the called routine */
2613       flg = 1;
2614       break;
2615     }
2616   }
2617   if (!flg)
2618     /* not a formal array argument */
2619     return;
2620 
2621   if (A_TYPEG(rpl) != A_SUBSCR)
2622     /* the replacing expression is not being subscripted */
2623     return;
2624 
2625   /*
2626    *+++++++++++++++++  WARNING  +++++++++++++++++
2627    * only allow a single subscript of the formal for now. This covers
2628    * the bug in f15222, but eventually, this will need to be generalized.
2629    */
2630   asd = A_ASDG(ast_subscr);
2631   if (ASD_NDIM(asd) != 1)
2632     return;
2633   subscr = ASD_SUBS(asd, 0);
2634 
2635   actarr = A_LOPG(rpl);
2636   if (A_TYPEG(actarr) != A_ID)
2637     /* the actual arg being subscripted is not a simple array */
2638     return;
2639 
2640   asd = A_ASDG(rpl);
2641   numdim = ASD_NDIM(asd);
2642   flg = 0;
2643   for (i = 0; i < numdim; i++) {
2644     subs[i] = ASD_SUBS(asd, i);
2645     if (A_TYPEG(subs[i]) == A_TRIPLE) {
2646       flg = 1;
2647       triple = i;
2648     }
2649   }
2650   if (!flg) {
2651     /*
2652      * strictly speaking, this is an error that should have already
2653      * been caught since the formal is subscripted, and the actual
2654      * argument which is subscripted is not array-valued!
2655      */
2656     return;
2657   }
2658   subs[triple] = subscr;
2659   /*
2660    * create a new subscripted reference where the subscript expression
2661    * of the formal is folded into the subscript expression of the
2662    * actual argument.  The new subscripted references replaces the
2663    * current subscripted reference of the formal.
2664    */
2665   ast = mk_subscr(actarr, subs, numdim, A_DTYPEG(ast_subscr));
2666   ast_replace(ast_subscr, ast);
2667 }
2668 
2669 static void
replace_formal_triples(int ast,int dscptr,int nactuals)2670 replace_formal_triples(int ast, int dscptr, int nactuals)
2671 {
2672   int cnt;
2673   int argt;
2674   int i;
2675 
2676   switch (A_TYPEG(ast)) {
2677   case A_BINOP:
2678     replace_formal_triples(A_LOPG(ast), dscptr, nactuals);
2679     replace_formal_triples(A_ROPG(ast), dscptr, nactuals);
2680     break;
2681   case A_UNOP:
2682   case A_PAREN:
2683   case A_CONV:
2684     replace_formal_triples(A_LOPG(ast), dscptr, nactuals);
2685     break;
2686   case A_INTR:
2687     cnt = A_ARGCNTG(ast);
2688     argt = A_ARGSG(ast);
2689     for (i = 0; i < cnt; i++) {
2690       /* watch for optional args */
2691       if (ARGT_ARG(argt, i) != 0) {
2692         replace_formal_triples(ARGT_ARG(argt, i), dscptr, nactuals);
2693       }
2694     }
2695     break;
2696   case A_SUBSCR:
2697     rewrite_triples(ast, dscptr, nactuals);
2698     rewrite_subscr(ast, dscptr, nactuals);
2699     break;
2700   default:
2701     ast_visit(ast, 1);
2702   }
2703 }
2704 
2705 /*
2706  * Substitute the formal arguments with the actual arguments.
2707  * Also, the appearance of formal arguments in descriptors need to
2708  * be replaced.
2709  */
2710 static void
replace_arguments(int dscptr,int nactuals)2711 replace_arguments(int dscptr, int nactuals)
2712 {
2713   int numdim;
2714   int ii;
2715 
2716   for (ii = 0; ii < nactuals; ii++) {
2717     if (ARG_STK(ii)) {
2718       int formal, formalid, arg, argid, astmem;
2719       formalid = aux.dpdsc_base[dscptr + ii];
2720       formal = mk_id(formalid);
2721       arg = ARG_AST(ii);
2722       ast_replace(formal, arg); /*formal <- actual*/
2723       argid = 0;
2724       if (A_TYPEG(arg) == A_ID) {
2725         argid = A_SPTRG(arg);
2726         astmem = 0;
2727       } else if (A_TYPEG(arg) == A_MEM) {
2728         argid = A_SPTRG(A_MEMG(arg));
2729         astmem = arg;
2730       }
2731       if (argid && formalid) {
2732         /* see if we should also replace any SDSC references
2733          * in the bounds, such as might come from translated
2734          * LBOUND(a,1) refs */
2735         if (SDSCG(formalid)) {
2736           formal = mk_id(SDSCG(formalid));
2737           if (!SDSCG(argid)) {
2738             get_static_descriptor(argid);
2739             get_all_descriptors(argid);
2740           }
2741           arg = check_member(astmem, mk_id(SDSCG(argid)));
2742           ast_replace(formal, arg);
2743         }
2744       }
2745     }
2746   }
2747 }
2748 
2749 static int
get_tbp(int sptr)2750 get_tbp(int sptr)
2751 {
2752   /* Get a type bound procedure. Assume that sptr points to a user
2753    * defined type bound procedure. We then mangle it with a $tbp suffix.
2754    * This returns the sptr of the mangled type bound procedure (binding
2755    * name).
2756    */
2757 
2758   int len;
2759   char *name;
2760 
2761   if (STYPEG(sptr) != ST_PROC) {
2762     /* If we get here with a symbol that isn't a procedure, don't create
2763      * a new ...$tbp symbol that'll never be used.
2764      */
2765     return sptr;
2766   }
2767 
2768   name = SYMNAME(sptr);
2769   len = strlen(name);
2770   if (len > 4 && strcmp("$tbp", name + (len - 4)) == 0) {
2771     return sptr;
2772   }
2773   return getsymf("%s$tbp", name);
2774 }
2775 
2776 int
get_tbp_argno(int sptr,int dty)2777 get_tbp_argno(int sptr, int dty)
2778 {
2779   if (dty <= 0)
2780     dty = TBPLNKG(sptr);
2781   if (dty > 0 && VTOFFG(sptr) != 0) {
2782     int mem, imp = get_implementation(dty, sptr, 0, &mem), first = imp;
2783     while (imp > NOSYM) {
2784       int paramct, dpdsc, bind;
2785       assert(mem > NOSYM, "get_tbp_argno: bad mem sptr", sptr, 3);
2786       /* set bind to VTABLEG(mem) if bind is a generic type bound procedure */
2787       bind = STYPEG(sptr) == ST_PROC ? BINDG(mem) : VTABLEG(mem);
2788       if (PASSG(mem) <= NOSYM && !NOPASSG(mem) && INVOBJG(bind) > 0)
2789         return INVOBJG(bind);
2790       proc_arginfo(imp, &paramct, &dpdsc, 0);
2791       if (dpdsc > 0) {
2792         /* found what must be the implementation */
2793         int invobj = find_dummy_position(imp, PASSG(mem));
2794         if (invobj == 0) {
2795           if (PASSG(mem) > NOSYM) {
2796             char *name = SYMNAME(sptr), *name2 = name;
2797             int len = strlen(name);
2798             if (len > 4 && strcmp("$tbp", name + (len - 4)) == 0) {
2799               name2 = getitem(0, len + 1);
2800               strncpy(name2, name, len - 4);
2801             }
2802             error(155, 3, gbl.lineno,
2803                   "PASS arguments for type bound procedure "
2804                   "must have same name and position as overridden type bound "
2805                   "procedure",
2806                   name2);
2807           } else if (!NOPASSG(mem)) {
2808             invobj = 1; /* when no PASS or NOPASS, pass in the first position */
2809           }
2810         }
2811         if (invobj > 0 && STYPEG(sptr) == ST_PROC)
2812           INVOBJP(sptr, invobj);
2813         return invobj;
2814       }
2815       /* Try next hash link before giving up */
2816       get_next_hash_link(imp, 0 /* magic code to clear name's VISIT flags */);
2817       imp = get_next_hash_link(imp, 1 /* magic code, STYPE must match */);
2818       if (imp > NOSYM && test_scope(imp) != 0)
2819         imp = 0;
2820     }
2821 
2822     if (first <= NOSYM)
2823       first = sptr;
2824     error(155, 3, gbl.lineno,
2825           "Type bound procedure must be a module procedure "
2826           "or an external procedure with an explicit interface - ",
2827           SYMNAME(first));
2828   }
2829   return 0;
2830 }
2831 
2832 int
get_generic_member(int dtype,int sptr)2833 get_generic_member(int dtype, int sptr)
2834 {
2835 
2836   /* This function is used to find the generic type bound procedure member
2837    * for a given dtype by matching the sptr with a member's VTABLE entry.
2838    * This function is also used in finding the type bound procedure
2839    * member with a given implementation (see chk_arguments() in
2840    * semfunc2.c).
2841    */
2842 
2843   int tag, mem;
2844 
2845   if (!dtype || DTY(dtype) != TY_DERIVED)
2846     return 0;
2847 
2848   for (mem = DTY(dtype + 1); mem > NOSYM; mem = SYMLKG(mem)) {
2849     if (CLASSG(mem) && VTABLEG(mem) && BINDG(mem) &&
2850         strcmp(SYMNAME(sptr), SYMNAME(VTABLEG(mem))) == 0) {
2851       return mem;
2852     }
2853   }
2854 
2855   tag = DTY(dtype + 3);
2856   if (PARENTG(tag)) {
2857     mem = get_generic_member(DTYPEG(PARENTG(tag)), sptr);
2858   }
2859 
2860   return (mem > NOSYM) ? mem : 0;
2861 }
2862 
2863 int
get_generic_member2(int dtype,int sptr,int argcnt,int * argno)2864 get_generic_member2(int dtype, int sptr, int argcnt, int *argno)
2865 {
2866 
2867   /* Similar to get_generic_member() above, except it assumes sptr is the
2868    * generic type bound procedure symbol (i.e., has a $tbpg suffix).
2869    */
2870   int tag, mem, candidate, exact_match;
2871 
2872   if (!dtype || DTY(dtype) != TY_DERIVED)
2873     return 0;
2874   if (argno)
2875     *argno = 0;
2876   candidate = exact_match = 0;
2877   for (mem = DTY(dtype + 1); mem > NOSYM; mem = SYMLKG(mem)) {
2878     if (CLASSG(mem) && VTABLEG(mem) && BINDG(mem) &&
2879         strcmp(SYMNAME(sptr), SYMNAME(BINDG(mem))) == 0) {
2880       if (argcnt) {
2881         int mem2, func;
2882         mem2 = 0;
2883         func = get_implementation(dtype, VTABLEG(mem), 0, &mem2);
2884         if (mem2) {
2885           int i, paramct, dpdsc, reqargs, optargs, arg2, pass_arg;
2886           proc_arginfo(func, &paramct, &dpdsc, NULL);
2887           for (pass_arg = reqargs = optargs = i = 0; i < paramct; ++i) {
2888             arg2 = aux.dpdsc_base[dpdsc + i];
2889             if (OPTARGG(arg2)) {
2890               ++optargs;
2891             } else {
2892               ++reqargs;
2893             }
2894             if (PASSG(mem2) &&
2895                 strcmp(SYMNAME(PASSG(mem2)), SYMNAME(arg2)) == 0) {
2896               pass_arg = arg2;
2897               if (argno)
2898                 *argno = i + 1;
2899             } else if (i == 0 && !PASSG(mem2) && !NOPASSG(mem2)) {
2900               pass_arg = arg2;
2901               if (argno)
2902                 *argno = i + 1;
2903             }
2904           }
2905           reqargs = (reqargs > 0) ? reqargs - (pass_arg > NOSYM) : 0;
2906           if (!optargs && argcnt == reqargs) {
2907             if (eq_dtype2(DTYPEG(pass_arg), dtype, 0))
2908               return mem;
2909             else if (eq_dtype2(DTYPEG(pass_arg), dtype, 1) && !exact_match)
2910               candidate = mem;
2911             else if (!pass_arg)
2912               candidate = mem;
2913           } else if (optargs && argcnt <= (optargs + reqargs)) {
2914             if (eq_dtype2(DTYPEG(pass_arg), dtype, 0)) {
2915               exact_match = 1;
2916               candidate = mem;
2917             } else if (eq_dtype2(DTYPEG(pass_arg), dtype, 1) && !exact_match)
2918               candidate = mem;
2919             else if (!pass_arg)
2920               candidate = mem;
2921           }
2922         }
2923       }
2924     }
2925   }
2926   tag = DTY(dtype + 3);
2927   if (candidate > NOSYM) {
2928     return candidate;
2929   }
2930 
2931   if (PARENTG(tag)) {
2932     mem = get_generic_member2(DTYPEG(PARENTG(tag)), sptr, argcnt, argno);
2933   }
2934 
2935   return (mem > NOSYM) ? mem : 0;
2936 }
2937 
2938 int
generic_tbp_has_pass_and_nopass(int dtype,int sptr)2939 generic_tbp_has_pass_and_nopass(int dtype, int sptr)
2940 {
2941 
2942   /* Checks for the special case where a generic type bound procedure has
2943    * two identical specific type bound procedures except one has nopass
2944    * and the other has pass set. Assumes that sptr is a generic tbp.
2945    */
2946 
2947   int found_nopass, found_pass;
2948   int tag, mem, rslt;
2949 
2950   if (STYPEG(sptr) != ST_USERGENERIC && STYPEG(sptr) != ST_OPERATOR)
2951     return 0;
2952   if (!dtype || DTY(dtype) != TY_DERIVED)
2953     return 0;
2954   found_nopass = found_pass = 0;
2955   for (mem = DTY(dtype + 1); mem > NOSYM; mem = SYMLKG(mem)) {
2956     if (CLASSG(mem) && VTABLEG(mem) && BINDG(mem) &&
2957         strcmp(SYMNAME(sptr), SYMNAME(BINDG(mem))) == 0) {
2958       if (NOPASSG(mem))
2959         found_nopass = 1;
2960       else
2961         found_pass = 1;
2962     }
2963   }
2964 
2965   tag = DTY(dtype + 3);
2966   if (PARENTG(tag)) {
2967     return generic_tbp_has_pass_and_nopass(DTYPEG(PARENTG(tag)), sptr);
2968   }
2969 
2970   return found_nopass && found_pass;
2971 }
2972 
2973 int
get_generic_tbp_pass_or_nopass(int dtype,int sptr,int flag)2974 get_generic_tbp_pass_or_nopass(int dtype, int sptr, int flag)
2975 {
2976 
2977   /* Get the generic tbp sptr from dtype. If flag is set, then
2978    * this routine will return the NOPASS version (if available),
2979    * else the PASS version (if available). It returns 0 if generic
2980    * tbp is not available or none available from the flag criteria.
2981    */
2982   int found_nopass, found_pass;
2983   int tag, mem, rslt;
2984 
2985   if (STYPEG(sptr) != ST_USERGENERIC && STYPEG(sptr) != ST_OPERATOR)
2986     return 0;
2987   if (!dtype || DTY(dtype) != TY_DERIVED)
2988     return 0;
2989   found_nopass = found_pass = 0;
2990   for (mem = DTY(dtype + 1); mem > NOSYM; mem = SYMLKG(mem)) {
2991     if (CLASSG(mem) && VTABLEG(mem) && BINDG(mem) &&
2992         strcmp(SYMNAME(sptr), SYMNAME(BINDG(mem))) == 0) {
2993       if (NOPASSG(mem))
2994         found_nopass = mem;
2995       else
2996         found_pass = mem;
2997     }
2998   }
2999 
3000   tag = DTY(dtype + 3);
3001   if (PARENTG(tag)) {
3002     return generic_tbp_has_pass_and_nopass(DTYPEG(PARENTG(tag)), sptr);
3003   }
3004 
3005   return (flag) ? found_nopass : found_pass;
3006 }
3007 
3008 int
get_specific_member(int dtype,int sptr)3009 get_specific_member(int dtype, int sptr)
3010 {
3011 
3012   /* Similar to get_generic_member() except it returns the member of
3013    * the specific type bound procedure. This is needed when a user
3014    * operator has the same name (except for the leading and trailing
3015    * dot `.') as a specific type bound procedure.
3016    */
3017 
3018   int tag, mem, mem2;
3019 
3020   if (!dtype || DTY(dtype) != TY_DERIVED)
3021     return 0;
3022   mem2 = 0;
3023   for (mem = DTY(dtype + 1); mem > NOSYM; mem = SYMLKG(mem)) {
3024     if (CLASSG(mem) && VTABLEG(mem) && BINDG(mem) &&
3025         STYPEG(BINDG(mem)) != ST_OPERATOR &&
3026         STYPEG(BINDG(mem)) != ST_USERGENERIC &&
3027         strcmp(SYMNAME(sptr), SYMNAME(BINDG(mem))) == 0) {
3028       return mem;
3029     }
3030   }
3031 
3032   tag = DTY(dtype + 3);
3033   if (PARENTG(tag)) {
3034     mem = get_specific_member(DTYPEG(PARENTG(tag)), sptr);
3035   }
3036 
3037   return (mem > NOSYM) ? mem : 0;
3038 }
3039 
3040 static int
find_by_name_stype_arg(char * symname,int stype,int scope,int dtype,int inv,int exact)3041 find_by_name_stype_arg(char *symname, int stype, int scope, int dtype, int inv,
3042                        int exact)
3043 {
3044   int hash, hptr, len;
3045   int paramct, dpdsc, dtype2, arg;
3046   len = strlen(symname);
3047   HASH_ID(hash, symname, len);
3048   for (hptr = stb.hashtb[hash]; hptr; hptr = HASHLKG(hptr)) {
3049     if (STYPEG(hptr) == stype && strcmp(SYMNAME(hptr), symname) == 0) {
3050       if (scope == 0 || scope == SCOPEG(hptr)) {
3051         if (!inv)
3052           return hptr;
3053         dpdsc = DPDSCG(hptr);
3054         arg = aux.dpdsc_base[dpdsc + (inv - 1)];
3055         dtype2 = DTYPEG(arg);
3056         if (eq_dtype2(dtype2, dtype, !exact && CLASSG(arg)) ||
3057             eq_dtype2(dtype, dtype2, !exact && CLASSG(arg)))
3058           return hptr;
3059       }
3060     }
3061   }
3062   return 0;
3063 }
3064 
3065 /** \brief For type bound procedures, find the implementation for the
3066  * type bound procedure binding name in dtype.
3067  *
3068  * If flag is set, then we check to see if we're accessing a PRIVATE
3069  * type bound procedure. If so, we issue an error message.
3070  *
3071  * \param dtype is the derived type record that we are searching.
3072  * \param orig_sptr is the symbol table pointer of the binding name of the
3073  *        type bound procedure to look up.
3074  * \param flag is set to check for accessing a PRIVATE type bound procedure.
3075  * \param memout if set, the function will store the type bound procedure
3076  *        symbol table pointer in this pointer argument.
3077  *
3078  * \return a symbol table pointer to the type bound procedure implementation;
3079  *         otherwise 0 (if not found).
3080  */
3081 int
get_implementation(int dtype,int orig_sptr,int flag,int * memout)3082 get_implementation(int dtype, int orig_sptr, int flag, int *memout)
3083 {
3084   int sptr = orig_sptr;
3085   int mem, tag;
3086   int imp = 0, bind;
3087   int rslt = 0;
3088   int invobj = 0;
3089   const char *tbp_name, *suffix;
3090   int tbp_name_len;
3091   int my_mem;
3092   int inherited_imp = 0;
3093   int scope;
3094   SPTR tag_scope;
3095   static bool force_resolve_once = false;
3096 
3097   if (!memout)
3098     memout = &my_mem;
3099   *memout = 0;
3100 
3101   if (dtype > 0 && DTY(dtype) == TY_ARRAY)
3102     dtype = DTY(dtype + 1);
3103   if (dtype <= 0 || DTY(dtype) != TY_DERIVED)
3104     return 0;
3105 
3106   inherited_imp = 0;
3107   sptr = get_tbp(orig_sptr);
3108   tbp_name = SYMNAME(sptr);
3109   tbp_name_len = strlen(tbp_name);
3110   if ((suffix = strstr(tbp_name, "$tbp")))
3111     tbp_name_len = suffix - tbp_name;
3112   tag = DTY(dtype + 3);
3113 
3114   for(tag_scope = SCOPEG(tag); STYPEG(tag_scope) == ST_ALIAS;) {
3115     tag_scope = SYMLKG(tag_scope);
3116   }
3117   if (sem.which_pass > 0 && STYPEG(tag_scope) != ST_MODULE &&
3118       !force_resolve_once) {
3119     /* We have a derived type that's defined inside a procedure. We
3120      * need to force a resolution on the type bound procedures since they
3121      * do not normally get resolved until we see an ENDMODULE statement
3122      * (which would not necessarily apply in this case).
3123      *
3124      * Because queue_tbp() might also call get_implementation(), we need to
3125      * use the "force_resolve_once" variable to make sure queue_tbp() is
3126      * only called once with TBP_FORCE_RESOLVED.
3127      */
3128     force_resolve_once = true;
3129     queue_tbp(0, 0, 0, 0, TBP_FORCE_RESOLVE);
3130     force_resolve_once = false;
3131   }
3132 
3133   if (PARENTG(tag)) {
3134     imp = get_implementation(DTYPEG(PARENTG(tag)), sptr, 0, memout);
3135     if (imp) {
3136       bind = BINDG(*memout);
3137       invobj = INVOBJG(bind);
3138       inherited_imp = imp;
3139     }
3140   }
3141   for (mem = DTY(dtype + 1); mem > NOSYM; mem = SYMLKG(mem)) {
3142     bind = BINDG(mem);
3143     if (bind > NOSYM && CCSYMG(mem) && CLASSG(mem) && VTABLEG(mem)) {
3144       const char *bind_name = SYMNAME(bind);
3145       int bind_name_len = strlen(bind_name);
3146       if ((suffix = strstr(bind_name, "$tbp")))
3147         bind_name_len = suffix - bind_name;
3148       if (bind_name_len == tbp_name_len &&
3149           memcmp(tbp_name, bind_name, bind_name_len) == 0) {
3150         imp = IFACEG(mem) ? IFACEG(mem) : VTABLEG(mem);
3151         invobj = INVOBJG(bind);
3152         *memout = mem;
3153         break;
3154       }
3155     }
3156   }
3157 
3158   if (!imp)
3159     return 0;
3160 
3161   /*for submod, it needs to make comparison again with gbl.currsub, as
3162     submod's scope is 0 which doesn't equal to the proc defined in
3163     parent mod with scope to it's parent mod
3164   */
3165   if (flag && PRIVATEG(*memout) && SCOPEG(*memout) != gbl.currmod &&
3166       SCOPEG(*memout) != SCOPEG(gbl.currsub)) {
3167     error(155, 3, gbl.lineno, "cannot access PRIVATE type bound procedure",
3168           SYMNAME(orig_sptr));
3169   }
3170 
3171   if (!invobj && !NOPASSG(*memout)) {
3172     invobj = 1;
3173     bind = BINDG(*memout);
3174     if (STYPEG(bind) == ST_PROC)
3175       INVOBJP(bind, invobj);
3176   }
3177   scope = DTY(dtype) == TY_DERIVED ? SCOPEG(DTY(dtype + 3)) : 0;
3178 
3179   if (scope != SCOPEG(SCOPEG(imp)) && imp != inherited_imp) {
3180 /* If imp is declared in same scoping unit as dtype, don't
3181  * perform the additional checks below.
3182  */
3183     /* Perform the additional checks below if the dtype's
3184      * implementation is not inherited from a parent type and its
3185      * defined in another scope.
3186      */
3187     rslt =
3188         find_by_name_stype_arg(SYMNAME(imp), ST_PROC, scope, dtype, invobj, 1);
3189     if (!rslt) {
3190       rslt = find_by_name_stype_arg(SYMNAME(imp), ST_PROC, scope, dtype, invobj,
3191                                     0);
3192     }
3193 
3194     if (!rslt) {
3195       rslt = find_by_name_stype_arg(SYMNAME(imp), ST_PROC, 0, dtype, invobj, 1);
3196     }
3197 
3198     if (!rslt) {
3199       rslt = find_by_name_stype_arg(SYMNAME(imp), ST_PROC, 0, dtype, invobj, 0);
3200     }
3201 
3202     if (!rslt) {
3203       rslt = find_by_name_stype_arg(SYMNAME(imp), ST_PROC, 0, 0, invobj, 0);
3204     }
3205 
3206     if (!rslt) {
3207       rslt = find_by_name_stype_arg(SYMNAME(imp), ST_PROC, 0, 0, 0, 0);
3208     }
3209   }
3210 
3211   if (!rslt) {
3212     rslt = imp;
3213   }
3214 
3215   if (rslt != VTABLEG(mem)) {
3216     VTABLEP(mem, rslt);
3217     if (DTYPEG(rslt))
3218       DTYPEP(mem, DTYPEG(rslt));
3219   }
3220 
3221   return rslt;
3222 }
3223 
3224 /*---------------------------------------------------------------------*/
3225 
3226 /** \brief Write ILMs to call a subroutine.
3227     \param stktop function to call
3228     \param list   arguments to pass to function
3229     \param flag   set if called from a generic resolution routine
3230  */
3231 void
subr_call2(SST * stktop,ITEM * list,int flag)3232 subr_call2(SST *stktop, ITEM *list, int flag)
3233 {
3234   int sptr, sptr1, stype;
3235   ITEM *itemp;
3236   int count, alt_ret;
3237   int dum, i, ii, check_generic;
3238   int ast;
3239   int argt;
3240   SST *sp;
3241   int param_dummy;
3242   char *kwd_str; /* where make_kwd_str saves the string */
3243   int tbp_mem;
3244   int doif;
3245 
3246   tbp_mem = 0;
3247   ast = 0; /* initialize just in case error occurs */
3248   kwd_str = NULL;
3249   sptr = SST_SYMG(stktop);
3250   if (sptr > 0) {
3251     check_generic = 1;
3252   } else {
3253     sptr = -sptr;
3254     SST_SYMP(stktop, sptr);
3255     check_generic = 0;
3256   }
3257 try_next_sptr:
3258   stype = STYPEG(sptr);
3259   if (stype == ST_ALIAS) {
3260     sptr = SYMLKG(sptr);
3261     stype = STYPEG(sptr);
3262   }
3263   get_next_hash_link(sptr, 0);
3264 try_next_hash_link:
3265 
3266   init_byval();
3267   if (stype != ST_PROC) {
3268     if (stype == ST_PD) {
3269       ref_pd_subr(stktop, list);
3270       return;
3271     }
3272     if (stype == ST_USERGENERIC && check_generic) {
3273       if (CLASSG(sptr)) {
3274         sptr = generic_tbp_call(sptr, stktop, list, 0);
3275         goto do_call;
3276       }
3277       generic_call(sptr, stktop, list, 0);
3278       return;
3279     }
3280     if (stype == ST_INTRIN) {
3281       /* class subroutine intrinsic? */
3282       switch (INTASTG(sptr)) {
3283       case I_C_F_POINTER:
3284       case I_C_F_PROCPOINTER:
3285         ref_intrin_subr(stktop, list);
3286         return;
3287       default:
3288         break;
3289       }
3290     }
3291     if (IS_INTRINSIC(stype)) {
3292       /* check if intrinsic is frozen */
3293       if ((sptr = newsym(sptr)) == 0) {
3294         ast = 0;
3295         goto exit_;
3296       }
3297     } else if (stype == ST_IDENT) {
3298       if (SCG(sptr) != SC_LOCAL) {
3299         if (SCG(sptr) == SC_DUMMY) {
3300           /*
3301            *  this is a dummy procedure call, but may be a user
3302            *  error.
3303            */
3304           error(125, 1, gbl.lineno, SYMNAME(sptr), CNULL);
3305         } else if (SCG(sptr) != SC_NONE) {
3306           error(84, 3, gbl.lineno, SYMNAME(sptr),
3307                 "- attempt to CALL a non-SUBROUTINE");
3308           ast = 0;
3309           goto exit_;
3310         } else
3311           error(84, 3, gbl.lineno, SYMNAME(sptr),
3312                 "- attempt to CALL a FUNCTION");
3313       }
3314     } else if (stype == ST_ENTRY) {
3315       int sptr2;
3316       if (GSAMEG(sptr) && check_generic) {
3317         if (CLASSG(sptr)) {
3318           sptr = generic_tbp_call(sptr, stktop, list, 0);
3319           goto do_call;
3320         }
3321         generic_call(GSAMEG(sptr), stktop, list, 0);
3322         return;
3323       }
3324       if (flg.recursive || RECURG(sptr)) {
3325         if (gbl.rutype != RU_SUBR) {
3326           error(84, 3, gbl.lineno, SYMNAME(sptr),
3327                 "- attempt to CALL a non-SUBROUTINE");
3328           ast = 0;
3329           goto exit_;
3330         }
3331         if (DPDSCG(sptr))
3332           kwd_str = make_kwd_str(sptr);
3333         goto do_call;
3334       }
3335       sptr2 = findByNameStypeScope(SYMNAME(sptr), ST_PROC, 0);
3336       if (sptr2) {
3337         sptr = sptr2;
3338         goto try_next_sptr;
3339       }
3340       error(88, 3, gbl.lineno, SYMNAME(sptr), CNULL);
3341       ast = 0;
3342       goto exit_;
3343     } else if (stype != ST_UNKNOWN) {
3344       error(84, 3, gbl.lineno, SYMNAME(sptr),
3345             "- attempt to CALL a non-SUBROUTINE");
3346       ast = 0;
3347       goto exit_;
3348     } else {
3349       SCP(sptr, SC_NONE); /* <var ref> could have SET storage class */
3350     }
3351     /*
3352      * it's okay to make the symbol a procedure
3353      */
3354     STYPEP(sptr, ST_PROC);
3355     DTYPEP(sptr, 0);
3356     if (SCG(sptr) == SC_NONE)
3357       SCP(sptr, SC_EXTERN);
3358     if (SLNKG(sptr) == 0) {
3359       SLNKP(sptr, aux.list[ST_PROC]);
3360       aux.list[ST_PROC] = sptr;
3361     }
3362   } else { /* stype == ST_PROC */
3363     if (GSAMEG(sptr) && check_generic) {
3364       if (CLASSG(sptr)) {
3365         sptr = generic_tbp_call(sptr, stktop, list, 0);
3366         goto do_call;
3367       }
3368       generic_call(GSAMEG(sptr), stktop, list, 0);
3369       return;
3370     }
3371     if (DTYPEG(sptr) != 0 && (DCLDG(sptr) || FUNCG(sptr)))
3372       /* sptr is a function */
3373       error(84, 3, gbl.lineno, SYMNAME(sptr), "- attempt to CALL a FUNCTION");
3374     else
3375       /* first occurrence could have been
3376        * in an EXTERNAL statement in which case its dtype
3377        * was set due to the implicit handling.
3378        */
3379       DTYPEP(sptr, 0);
3380     if (DPDSCG(sptr))
3381       kwd_str = make_kwd_str(sptr);
3382     if (STYPEG(sptr) == ST_PROC && SLNKG(sptr) == 0) {
3383       SLNKP(sptr, aux.list[ST_PROC]);
3384       aux.list[ST_PROC] = sptr;
3385     }
3386   }
3387 
3388 do_call:
3389   if (flg.xref)
3390     xrefput(sptr, 'r');
3391 
3392   alt_ret = 0;
3393   count_actuals(list);
3394   count = carg.nent;
3395 
3396   if (CLASSG(sptr)) {
3397     int sptr2;
3398     ast = SST_ASTG(stktop);
3399     switch (A_TYPEG(ast)) {
3400     case A_ID:
3401     case A_LABEL:
3402     case A_ENTRY:
3403     case A_SUBSCR:
3404     case A_SUBSTR:
3405     case A_MEM:
3406       sptr1 = memsym_of_ast(ast);
3407       sptr2 = pass_sym_of_ast(ast);
3408       if (STYPEG(BINDG(sptr1)) != ST_USERGENERIC) {
3409         sptr = BINDG(sptr1);
3410       } else {
3411         /* Replace the generic type bound procedure with the specific
3412          * type bound procedure.
3413          */
3414         int mem, dtype;
3415         dtype = DTYPEG(sptr2);
3416         if (DTY(dtype) == TY_ARRAY)
3417           dtype = DTY(dtype + 1);
3418 
3419         if (get_implementation(dtype, sptr, 0, &mem) == 0) {
3420           dtype = TBPLNKG(sptr);
3421         }
3422 
3423         if (get_implementation(dtype, sptr, 0, &mem) == 0) {
3424           char *name_cpy, *name;
3425           name_cpy = getitem(0, strlen(SYMNAME(sptr1)) + 1);
3426           strcpy(name_cpy, SYMNAME(sptr1));
3427           name = strchr(name_cpy, '$');
3428           if (name)
3429             *name = '\0';
3430           error(155, 3, gbl.lineno,
3431                 "Could not resolve generic type bound "
3432                 "procedure",
3433                 name_cpy);
3434           sptr1 = 0;
3435           break;
3436         }
3437         ast = replace_memsym_of_ast(ast, mem);
3438         SST_ASTP(stktop, ast);
3439         sptr = BINDG(mem);
3440         sptr1 = mem;
3441       }
3442       break;
3443     default:
3444       if (check_generic && CLASSG(sptr) && list != ITEM_END &&
3445           SST_DTYPEG(list->t.stkp) &&
3446           !tk_match_arg(TBPLNKG(sptr), SST_DTYPEG(list->t.stkp), FALSE)) {
3447         /* FS20530: this handles the case where there is a TBP bind name and a
3448          * user
3449          * generic with the same name and sptr points to the TBP when what is
3450          * needed
3451          * is one of the generic implementations.
3452          */
3453         sptr1 = SST_SYMG(stktop);
3454         generic_call(sptr, stktop, list, 0);
3455         if (sptr1 != SST_SYMG(stktop)) {
3456           return;
3457         }
3458       }
3459       SST_SYMP(stktop, sptr1);
3460       sptr1 = 0;
3461     }
3462 
3463     if (sptr1 && (INVOBJG(sptr) || NOPASSG(sptr1))) {
3464       int imp, dty2;
3465       int dty, basedt, basedt2;
3466       int invobj, invobj2;
3467       int i;
3468       ITEM *itemp;
3469 
3470       dty = TBPLNKG(sptr);
3471       if (dty) {
3472         if (DTY(dty) == TY_ARRAY)
3473           basedt = DTY(dty + 1);
3474         else
3475           basedt = dty;
3476         imp = get_implementation(DTYPEG(sptr2), sptr, 0, NULL);
3477         if (imp) {
3478           invobj = get_tbp_argno(sptr, DTYPEG(sptr2));
3479         } else {
3480           invobj = get_tbp_argno(sptr, basedt);
3481         }
3482         if (invobj) {
3483           for (sp = 0, i = 1, itemp = list; i <= invobj && itemp != ITEM_END;
3484                ++i) {
3485             sp = itemp->t.stkp;
3486             itemp = itemp->next;
3487           }
3488           sptr1 = 0;
3489           if (SST_IDG(sp) == S_LVALUE || SST_IDG(sp) == S_EXPR)
3490             sptr1 = SST_LSYMG(sp);
3491           else if (SST_IDG(sp) == S_DERIVED || SST_IDG(sp) == S_IDENT)
3492             sptr1 = SST_SYMG(sp);
3493           else if (SST_IDG(sp) == S_SCONST) {
3494             (void)mkarg(sp, &dum);
3495             sptr1 = SST_SYMG(sp);
3496           }
3497           dty2 = DTYPEG(sptr1);
3498           if (DTY(dty2) == TY_ARRAY)
3499             basedt2 = DTY(dty2 + 1);
3500           else
3501             basedt2 = dty2;
3502           if (0 && !eq_dtype2(basedt, basedt2, 1)) { /* TBD */
3503             error(155, 3, gbl.lineno,
3504                   "Incompatible PASS argument in type "
3505                   "bound procedure call",
3506                   CNULL);
3507           } else {
3508             imp = get_implementation(basedt2, sptr, !flag, NULL);
3509             if (!imp) {
3510               error(155, 3, gbl.lineno,
3511                     "Incompatible PASS argument in type "
3512                     "bound procedure call",
3513                     CNULL);
3514             }
3515             invobj2 = get_tbp_argno(sptr, basedt2);
3516             if (invobj != invobj2) {
3517               error(155, 4, gbl.lineno,
3518                     "Type bound procedure "
3519                     "PASS arguments must have the same "
3520                     "name and position as PASS arguments in the overloaded "
3521                     "type bound procedure",
3522                     SYMNAME(imp));
3523             }
3524 
3525             set_pass_objects(invobj - 1, sptr1);
3526 
3527             CLASSP(imp, 1);
3528             sptr = imp;
3529 
3530             tbp_mem = ast;
3531 
3532             if (kwd_str)
3533               FREE(kwd_str);
3534             if (DPDSCG(sptr)) {
3535               kwd_str = make_kwd_str(sptr);
3536             }
3537           }
3538         } else if (NOPASSG(sptr1)) {
3539           sptr = sym_of_ast(ast);
3540           imp = get_implementation(basedt, BINDG(sptr1), !flag, NULL);
3541           sptr = imp;
3542           tbp_mem = ast;
3543           if (kwd_str)
3544             FREE(kwd_str);
3545           if (DPDSCG(sptr))
3546             kwd_str = make_kwd_str(sptr);
3547         }
3548       }
3549     }
3550   }
3551 
3552   if (!tbp_mem && sptr > NOSYM && !IS_PROC_DUMMYG(sptr) && TBPLNKG(sptr)) {
3553     int sym;
3554     do {
3555       sym = get_next_hash_link(sptr, 1);
3556     } while (sym && test_scope(SCOPEG(sym)) < 0);
3557     if (sym) {
3558       sptr = sym;
3559       if (kwd_str) {
3560         FREE(kwd_str);
3561         kwd_str = NULL;
3562       }
3563       goto try_next_hash_link;
3564     }
3565     if (!kwd_str) {
3566       for (itemp = list; itemp != ITEM_END; itemp = itemp->next) {
3567         sp = itemp->t.stkp;
3568         if (SST_IDG(sp) == S_KEYWORD) {
3569           kwd_str = make_kwd_str(sptr);
3570           break;
3571         }
3572       }
3573     }
3574   }
3575 
3576   /*
3577    * loop through the argument list to evaluate all of the arguments and
3578    * saving their values (ILM pointers);
3579    */
3580   if (kwd_str) {
3581     if (check_arguments(sptr, count, list, kwd_str))
3582       goto exit_;
3583     count_formals(sptr);
3584     count = carg.nent;
3585     argt = mk_argt(carg.nargt); /* mk_argt stuffs away count */
3586     ii = 0;
3587     for (i = 0; i < count; i++) {
3588       sp = ARG_STK(i);
3589       if (sp) {
3590         /* add to ARGT list, handling derived type arguments as
3591          * special case.
3592          */
3593         sptr1 = get_sym_from_sst_if_available(sp);
3594         {
3595           param_dummy = inc_dummy_param(sptr);
3596 
3597           if (!is_iso_cloc(SST_ASTG(sp)) && (A_TYPEG(SST_ASTG(sp)) != A_FUNC) &&
3598               is_iso_cptr(A_DTYPEG(SST_ASTG(sp)))) {
3599             /* rewrite iso cptr references,
3600                do not rewrite functions returning iso_cptr,
3601                do not rewrite iso c_loc
3602              */
3603 
3604             ARGT_ARG(argt, ii) = rewrite_cptr_references(SST_ASTG(sp));
3605           } else if (get_byval(sptr, param_dummy)
3606                     && PASSBYVALG(param_dummy)
3607                     && OPTARGG(param_dummy)) {
3608             int assn = sem_tempify(sp);
3609             (void)add_stmt(assn);
3610             SST_ASTP(sp, A_DESTG(assn));
3611             byvalue_ref_arg(sp, &dum, OP_REF, sptr);
3612             ARGT_ARG(argt, ii) = SST_ASTG(sp);
3613           } else if (pass_char_no_len(sptr, param_dummy)) {
3614             byvalue_ref_arg(sp, &dum, OP_REF, sptr);
3615             ARGT_ARG(argt, ii) = SST_ASTG(sp);
3616           } else if (INTENTG(param_dummy) == INTENT_IN &&
3617                      POINTERG(param_dummy) && !is_ptr_arg(sp)) {
3618             /* F2008: pass non-pointer actual arg for an
3619              *        INTENT(IN), POINTER formal arg */
3620             ARGT_ARG(argt, ii) = gen_and_assoc_tmp_ptr(sp, sem.last_std);
3621           } else {
3622             /* byval arguments done in lowerilm.c for  subroutines */
3623             ARGT_ARG(argt, ii) = ARG_AST(i);
3624           }
3625           ii++;
3626           if (sptr1 && STYPEG(sptr1) == ST_PROC && DPDSCG(sptr1) &&
3627               SLNKG(sptr1) == 0) {
3628             SLNKP(sptr1, aux.list[ST_PROC]);
3629             aux.list[ST_PROC] = sptr1;
3630           }
3631         }
3632       } else {
3633         int npad;
3634         for (npad = ARG_AST(i); npad > 0; npad--) {
3635           ARGT_ARG(argt, ii) = astb.ptr0;
3636           ii++;
3637         }
3638       }
3639     }
3640     if (tbp_mem) {
3641       int mem = memsym_of_ast(tbp_mem);
3642       if (STYPEG(mem) == ST_MEMBER && !strstr(SYMNAME(sptr), "$tbp")) {
3643         VTABLEP(mem, sptr);
3644       }
3645     }
3646     ast = mk_func_node(A_CALL, (tbp_mem) ? tbp_mem : mk_id(sptr), carg.nargt,
3647                        argt);
3648     goto exit_;
3649   }
3650   argt = mk_argt(carg.nargt); /* mk_argt stuffs away count */
3651   if (tbp_mem) {
3652     int mem = memsym_of_ast(tbp_mem);
3653     if (STYPEG(mem) == ST_MEMBER && !strstr(SYMNAME(sptr), "$tbp")) {
3654       VTABLEP(mem, sptr);
3655     }
3656   }
3657   ast =
3658       mk_func_node(A_CALL, (tbp_mem) ? tbp_mem : mk_id(sptr), carg.nargt, argt);
3659   ii = count = 0;
3660 
3661   for (itemp = list; itemp != ITEM_END; itemp = itemp->next) {
3662     sp = itemp->t.stkp;
3663     if (SST_IDG(sp) == S_KEYWORD) {
3664       /* form is <ident> = <expression> */
3665       error(79, 3, gbl.lineno, scn.id.name + SST_CVALG(itemp->t.stkp), CNULL);
3666       ARGT_ARG(argt, ii) = astb.i0;
3667       ii++;
3668       continue;
3669     }
3670     /* check arguments and add to ARGT list, handling derived type
3671      * arguments as special case
3672      */
3673     sptr1 = 0;
3674     if (SST_IDG(sp) == S_LVALUE)
3675       sptr1 = SST_LSYMG(sp);
3676     else if (SST_IDG(sp) == S_DERIVED || SST_IDG(sp) == S_IDENT)
3677       sptr1 = SST_SYMG(sp);
3678     else if (SST_IDG(sp) == S_SCONST) {
3679       (void)mkarg(sp, &dum);
3680       sptr1 = SST_SYMG(sp);
3681     }
3682     {
3683 
3684       /* get_byvalue parameter processing is handled in lowerilm.c for
3685          subroutine calls.
3686        */
3687       param_dummy = inc_dummy_param(sptr);
3688 
3689       if (pass_char_no_len(sptr, param_dummy)) {
3690         itemp->t.sptr = byvalue_ref_arg(sp, &dum, OP_REF, sptr);
3691         ARGT_ARG(argt, ii) = SST_ASTG(sp);
3692 
3693       } else {
3694         itemp->t.sptr = chkarg(sp, &dum);
3695         ARGT_ARG(argt, ii) = SST_ASTG(sp);
3696       }
3697       ii++;
3698 
3699       if (sptr1 && STYPEG(sptr1) == ST_PROC && DPDSCG(sptr1) &&
3700           SLNKG(sptr1) == 0) {
3701         SLNKP(sptr1, aux.list[ST_PROC]);
3702         aux.list[ST_PROC] = sptr1;
3703       }
3704     }
3705     /*
3706      * a negative value returned by mkarg is a negated alternate
3707      * return label
3708      */
3709     if (itemp->t.sptr <= 0)
3710       alt_ret++;
3711   }
3712 
3713 exit_:
3714   SST_ASTP(stktop, ast);
3715 
3716   if (kwd_str)
3717     FREE(kwd_str);
3718 }
3719 
3720 void
subr_call(SST * stktop,ITEM * list)3721 subr_call(SST *stktop, ITEM *list)
3722 {
3723   subr_call2(stktop, list, 0);
3724 }
3725 
3726 static void
fix_proc_pointer_call(SST * stktop,ITEM ** list)3727 fix_proc_pointer_call(SST *stktop, ITEM **list)
3728 {
3729   /* Fix up pointer procedure call. If it's missing the pass object in the
3730    * arg list, add it. Also resolve the procedure pointer's iface if it has
3731    * not yet been resolved.
3732    */
3733 
3734   int func, pass_sym;
3735   int paramct, dpdsc, iface, ast, i;
3736   int arg, arg_sptr;
3737   int dtype, dtproc;
3738   SST *e1;
3739   ITEM *itemp, *itemp2;
3740   ast = SST_ASTG(stktop);
3741   switch (A_TYPEG(ast)) {
3742   case A_ID:
3743   case A_LABEL:
3744   case A_ENTRY:
3745   case A_SUBSCR:
3746   case A_SUBSTR:
3747   case A_MEM:
3748     func = memsym_of_ast(ast);
3749     pass_sym = pass_sym_of_ast(ast);
3750     proc_arginfo(func, &paramct, &dpdsc, &iface);
3751     break;
3752   default:
3753     return;
3754   }
3755   if (STYPEG(iface) != ST_PROC) {
3756     iface = findByNameStypeScope(SYMNAME(iface), ST_PROC, 0);
3757     if (iface) {
3758       proc_arginfo(iface, &paramct, &dpdsc, NULL);
3759       if (is_procedure_ptr(func)) {
3760         dtype = DTYPEG(func);
3761         dtproc = DTY(dtype + 1);
3762         DTY(dtproc + 3) = paramct;
3763         DTY(dtproc + 4) = dpdsc;
3764         DTY(dtproc + 2) = iface;
3765         DTY(dtproc + 1) = DTYPEG(iface);
3766       }
3767     } else
3768       return;
3769   }
3770 
3771   if (NOPASSG(func) || paramct <= 0)
3772     return;
3773 
3774   for (i = 0, itemp = *list; itemp != ITEM_END; itemp = itemp->next) {
3775     ++i;
3776   }
3777 
3778   if (*list != ITEM_END && (paramct - 1) <= i)
3779     return;
3780 
3781   if (!PASSG(func)) {
3782     /* check first arg */
3783     if (*list == ITEM_END) {
3784     insert_first_arg:
3785       e1 = (SST *)getitem(0, sizeof(SST));
3786       SST_IDP(e1, S_EXPR);
3787       SST_SYMP(e1, pass_sym);
3788       SST_ASTP(e1, check_member(ast, mk_id(pass_sym)));
3789 
3790       itemp = (ITEM *)getitem(0, sizeof(ITEM));
3791       itemp->t.stkp = e1;
3792       itemp->next = ITEM_END;
3793       *list = itemp;
3794     }
3795   } else {
3796     int pass_pos = find_dummy_position(iface, PASSG(func));
3797     if (pass_pos == 1 && *list == ITEM_END)
3798       goto insert_first_arg;
3799     if (pass_pos <= 1)
3800       return;
3801     for (i = 0, itemp = *list; itemp != ITEM_END; itemp = itemp->next) {
3802       e1 = itemp->t.stkp;
3803       if (i == pass_pos - 2) {
3804         e1 = (SST *)getitem(0, sizeof(SST));
3805         SST_IDP(e1, S_EXPR);
3806         SST_SYMP(e1, pass_sym);
3807         SST_ASTP(e1, check_member(ast, mk_id(pass_sym)));
3808         itemp2 = (ITEM *)getitem(0, sizeof(ITEM));
3809         itemp2->t.stkp = e1;
3810         itemp2->next = itemp->next;
3811         itemp->next = itemp2;
3812         break;
3813       }
3814       ++i;
3815     }
3816   }
3817 }
3818 
3819 void
ptrsubr_call(SST * stktop,ITEM * list)3820 ptrsubr_call(SST *stktop, ITEM *list)
3821 {
3822   int sptr, sptr1, stype;
3823   int callee;
3824   ITEM *itemp;
3825   int count, alt_ret;
3826   int dum, i, ii;
3827   int dtproc, iface, paramct, dpdsc;
3828   int dtype;
3829   int ast;
3830   int argt;
3831   SST *sp;
3832   int param_dummy;
3833   char *kwd_str; /* where make_kwd_str saves the string */
3834   int pass_pos;
3835 
3836   fix_proc_pointer_call(stktop, &list);
3837   ast = 0; /* initialize just in case error occurs */
3838   kwd_str = NULL;
3839   pass_pos = -1;
3840   if (SST_IDG(stktop) != S_LVALUE) {
3841     sptr = SST_SYMG(stktop);
3842     callee = mk_id(sptr);
3843   } else {
3844     sptr = SST_LSYMG(stktop);
3845     if (!is_procedure_ptr(sptr))
3846       /* error must have occurred */
3847       goto exit_;
3848     callee = SST_ASTG(stktop);
3849   }
3850   if (FUNCG(sptr))
3851     /* sptr is a function */
3852     error(84, 3, gbl.lineno, SYMNAME(sptr), "- attempt to CALL a FUNCTION");
3853   dtype = DTYPEG(sptr);
3854 #if DEBUG
3855   assert(DTY(dtype) == TY_PTR, "ptrsubr_call, expected TY_PTR dtype", sptr, 4);
3856 #endif
3857   dtproc = DTY(dtype + 1);
3858 #if DEBUG
3859   assert(DTY(dtproc) == TY_PROC, "ptrsubr_call, expected TY_PROC dtype", sptr,
3860          4);
3861 #endif
3862   dtype = DTY(dtproc + 1);
3863   iface = DTY(dtproc + 2);
3864   paramct = DTY(dtproc + 3);
3865   dpdsc = DTY(dtproc + 4);
3866   if (iface != sptr && !paramct) {
3867     proc_arginfo(iface, &paramct, &dpdsc, NULL);
3868     DTY(dtproc + 3) = paramct;
3869     DTY(dtproc + 4) = dpdsc;
3870   }
3871   init_byval();
3872   if (dpdsc)
3873     kwd_str = make_keyword_str(paramct, dpdsc);
3874 
3875   if (flg.xref)
3876     xrefput(sptr, 'r');
3877 
3878   alt_ret = 0;
3879   count_actuals(list);
3880   count = carg.nent;
3881 
3882   /*
3883    * loop through the argument list to evaluate all of the arguments and
3884    * saving their values (ILM pointers);
3885    */
3886   if (kwd_str) {
3887     if (chk_arguments(sptr, count, list, kwd_str, paramct, dpdsc, callee,
3888                       &pass_pos))
3889       goto exit_;
3890     count_formal_args(paramct, dpdsc);
3891     count = carg.nent;
3892     argt = mk_argt(carg.nargt); /* mk_argt stuffs away count */
3893     ii = 0;
3894     for (i = 0; i < count; i++) {
3895       sp = ARG_STK(i);
3896       if (sp) {
3897         /* add to ARGT list, handling derived type arguments as
3898          * special case.
3899          */
3900         sptr1 = 0;
3901         if (SST_IDG(sp) == S_LVALUE)
3902           sptr1 = SST_LSYMG(sp);
3903         else if (SST_IDG(sp) == S_DERIVED || SST_IDG(sp) == S_IDENT)
3904           sptr1 = SST_SYMG(sp);
3905         else if (SST_IDG(sp) == S_SCONST) {
3906           (void)mkarg(sp, &dum);
3907           sptr1 = SST_SYMG(sp);
3908         }
3909         {
3910           param_dummy = inc_dummy_param(sptr);
3911           if (!is_iso_cloc(SST_ASTG(sp)) && (A_TYPEG(SST_ASTG(sp)) != A_FUNC) &&
3912               is_iso_cptr(A_DTYPEG(SST_ASTG(sp)))) {
3913             /* rewrite iso cptr references,
3914                do not rewrite functions returning iso_cptr,
3915                do not rewrite iso c_loc
3916              */
3917 
3918             ARGT_ARG(argt, ii) = rewrite_cptr_references(SST_ASTG(sp));
3919             ii++;
3920           } else if (pass_char_no_len(sptr, param_dummy)) {
3921             byvalue_ref_arg(sp, &dum, OP_REF, sptr);
3922             ARGT_ARG(argt, ii) = SST_ASTG(sp);
3923             ii++;
3924           } else {
3925             /* byval arguments done in lowerilm.c for  subroutines */
3926             ARGT_ARG(argt, ii) = ARG_AST(i);
3927             ii++;
3928           }
3929           if (sptr1 && STYPEG(sptr1) == ST_PROC && DPDSCG(sptr1) &&
3930               SLNKG(sptr1) == 0) {
3931             SLNKP(sptr1, aux.list[ST_PROC]);
3932             aux.list[ST_PROC] = sptr1;
3933           }
3934         }
3935       } else if (i == pass_pos) {
3936         ARGT_ARG(argt, ii) = A_PARENTG(callee);
3937         ii++;
3938       } else {
3939         int npad;
3940         for (npad = ARG_AST(i); npad > 0; npad--) {
3941           ARGT_ARG(argt, ii) = astb.ptr0;
3942           ii++;
3943         }
3944       }
3945     }
3946     ast = mk_func_node(A_CALL, callee, carg.nargt, argt);
3947     goto exit_;
3948   }
3949   argt = mk_argt(carg.nargt); /* mk_argt stuffs away count */
3950   ast = mk_func_node(A_CALL, callee, carg.nargt, argt);
3951   ii = count = 0;
3952 
3953   for (itemp = list; itemp != ITEM_END; itemp = itemp->next) {
3954     sp = itemp->t.stkp;
3955     if (SST_IDG(sp) == S_KEYWORD) {
3956       /* form is <ident> = <expression> */
3957       error(79, 3, gbl.lineno, scn.id.name + SST_CVALG(itemp->t.stkp), CNULL);
3958       ARGT_ARG(argt, ii) = astb.i0;
3959       ii++;
3960       continue;
3961     }
3962     /* check arguments and add to ARGT list, handling derived type
3963      * arguments as special case
3964      */
3965     sptr1 = 0;
3966     if (SST_IDG(sp) == S_LVALUE)
3967       sptr1 = SST_LSYMG(sp);
3968     else if (SST_IDG(sp) == S_DERIVED || SST_IDG(sp) == S_IDENT)
3969       sptr1 = SST_SYMG(sp);
3970     else if (SST_IDG(sp) == S_SCONST) {
3971       (void)mkarg(sp, &dum);
3972       sptr1 = SST_SYMG(sp);
3973     }
3974     {
3975       /* get_byvalue parameter processing is handled in lowerilm.c for
3976          subroutine calls.
3977        */
3978       param_dummy = inc_dummy_param(sptr);
3979       if (pass_char_no_len(sptr, param_dummy)) {
3980         itemp->t.sptr = byvalue_ref_arg(sp, &dum, OP_REF, sptr);
3981         ARGT_ARG(argt, ii) = SST_ASTG(sp);
3982 
3983       } else {
3984         itemp->t.sptr = chkarg(sp, &dum);
3985         ARGT_ARG(argt, ii) = SST_ASTG(sp);
3986       }
3987       ii++;
3988     }
3989     /*
3990      * a negative value returned by mkarg is a negated alternate
3991      * return label
3992      */
3993     if (itemp->t.sptr <= 0)
3994       alt_ret++;
3995   }
3996 
3997 exit_:
3998   SST_ASTP(stktop, ast);
3999 
4000   if (kwd_str)
4001     FREE(kwd_str);
4002 }
4003 
4004 /*---------------------------------------------------------------------*/
4005 
4006 /* the purpose of these ASTs is to transfer information to the
4007  * ACL constructors in semutil2.c.  They should be ignored by
4008  * by anything not involved in data initialization.
4009  */
4010 static void
gen_init_intrin_call(SST * stkp,int pdsym,int argt_count,int dtype,int elemental)4011 gen_init_intrin_call(SST *stkp, int pdsym, int argt_count, int dtype,
4012                      int elemental)
4013 {
4014   int argt = mk_argt(argt_count); /* space for arguments */
4015   int func_ast;
4016   int ast;
4017   int i;
4018   int dtyper = dtype;
4019   SST *arg1;
4020   int arg1dtype;
4021   int dum;
4022   SST *s;
4023 
4024   for (i = 0; i < argt_count; i++) {
4025     s = (ARG_STK(i));
4026     if (!s) {
4027       ARGT_ARG(argt, i) = astb.i0;
4028     } else if (SST_IDG(s) == S_IDENT || SST_IDG(s) == S_ACONST) {
4029       SST_ASTP(s, 0);
4030       (void)mkarg(s, &dum);
4031       XFR_ARGAST(i);
4032       ARGT_ARG(argt, i) = ARG_AST(i);
4033     } else if (ARG_AST(i)) {
4034       ARGT_ARG(argt, i) = ARG_AST(i);
4035     }
4036   }
4037   func_ast = mk_id(pdsym);
4038 
4039   ast = mk_func_node(A_INTR, func_ast, argt_count, argt);
4040   A_DTYPEP(ast, dtype);
4041 
4042   if (elemental) {
4043     arg1 = ARG_STK(0);
4044     arg1dtype = SST_DTYPEG(arg1);
4045     if (DTY(arg1dtype) == TY_ARRAY) {
4046       dtyper = mk_array_type(arg1dtype, dtype);
4047       A_DTYPEP(ast, dtyper);
4048       A_SHAPEP(ast, SST_SHAPEG(arg1));
4049     }
4050   }
4051   SST_DTYPEP(stkp, dtyper);
4052 
4053   EXPSTP(pdsym, 1); /* freeze predeclared */
4054   SST_IDP(stkp, S_EXPR);
4055   SST_ASTP(stkp, ast);
4056   A_OPTYPEP(ast, INTASTG(pdsym));
4057 }
4058 
4059 /*
4060  * Generate a symbol for newer specifics of older generic intrinsics, i.e.,
4061  * those not
4062  * defined in syminidf.h
4063  */
4064 static int
gen_newer_intrin(int sptrgenr,int dtype)4065 gen_newer_intrin(int sptrgenr, int dtype)
4066 {
4067   char *intrin_nmptr = SYMNAME(sptrgenr);
4068   char nmptr[STANDARD_MAXIDLEN + 3] = ".";
4069   int sptr;
4070 
4071   if (strcmp(intrin_nmptr, "acos") == 0 || strcmp(intrin_nmptr, "asin") == 0 ||
4072       strcmp(intrin_nmptr, "atan") == 0 || strcmp(intrin_nmptr, "cosh") == 0 ||
4073       strcmp(intrin_nmptr, "sinh") == 0 || strcmp(intrin_nmptr, "tanh") == 0 ||
4074       strcmp(intrin_nmptr, "tan") == 0) {
4075     if (DT_ISCMPLX(dtype)) {
4076       switch (DTY(dtype)) {
4077       case TY_DCMPLX:
4078         strcat(nmptr, "cd");
4079         break;
4080       case TY_CMPLX:
4081         strcat(nmptr, "c");
4082         break;
4083       default:
4084         interr(
4085             "gen_newer_intrin: unknown type for inverse trigonmetric intrinsic",
4086             DTY(dtype), 2);
4087         return 0;
4088       }
4089       strcat(nmptr, intrin_nmptr);
4090 
4091       sptr = getsymbol(nmptr);
4092       STYPEP(sptr, ST_INTRIN);
4093       DTYPEP(sptr, 0);
4094       SYMLKP(sptr, sptrgenr);
4095       PNMPTRP(sptr, PNMPTRG(GREALG(sptrgenr)));
4096       PARAMCTP(sptr, 1);
4097       ILMP(sptr, ILMG(GREALG(sptrgenr)));
4098       ARRAYFP(sptr, ARRAYFG(GREALG(sptrgenr)));
4099       ARGTYPP(sptr, dtype);
4100       INTTYPP(sptr, dtype);
4101       INTASTP(sptr, NEW_INTRIN);
4102 
4103       switch (DTY(dtype)) {
4104       case TY_DCMPLX:
4105         GDCMPLXP(sptrgenr, sptr);
4106         break;
4107       case TY_CMPLX:
4108         GCMPLXP(sptrgenr, sptr);
4109         break;
4110       }
4111     }
4112     return sptr;
4113   }
4114 
4115   return 0;
4116 }
4117 
4118 static int
cmp_mod_scope(SPTR sptr)4119 cmp_mod_scope(SPTR sptr)
4120 {
4121   SPTR scope1, scope2;
4122 
4123   scope1 = stb.curr_scope;
4124   if (IS_PROC(STYPEG(scope1))) {
4125     scope1 = SCOPEG(scope1);
4126   }
4127   scope2 = SCOPEG(sptr);
4128   return scope1 == scope2;
4129 }
4130 
4131 /** \brief Handle Generic and Intrinsic function calls.
4132  */
4133 int
ref_intrin(SST * stktop,ITEM * list)4134 ref_intrin(SST *stktop, ITEM *list)
4135 {
4136   int sptr, fsptr, sptre, dtype, dtype1, argtyp, paramct;
4137   int f_dt, ddt;
4138   int opc, count, const_cnt;
4139   ITEM *ip1;
4140   SST *sp;
4141   LOGICAL frozen;
4142   ACL *expracl;
4143   int ast;
4144   int argt;
4145   int i;
4146   int intast;
4147   int shaper;
4148   int cp;
4149   int func_ast;
4150   int argdtype;
4151   int dtyper;
4152   int func_type;
4153   int dum;
4154   int dt_cast_word;
4155   int hpf_sym;
4156   int tmp, tmp_ast;
4157   char tmpnm[64];
4158   FtnRtlEnum rtlRtn;
4159   int intrin; /* one of the I_* constants */
4160   int is_real2_arg_error = 0;
4161 
4162   dtyper = 0;
4163   dtype1 = 0;
4164   sptr = 0; /* for min and max character */
4165   SST_CVLENP(stktop, 0);
4166   sptre = SST_SYMG(stktop);
4167   if (STYPEG(sptre) == ST_INTRIN) {
4168     SPTR sptr2 = findByNameStypeScope(SYMNAME(sptre), ST_ALIAS, 0);
4169     if (sptr2 > NOSYM && SYMLKG(sptr2) == sptre && PRIVATEG(sptr2) &&
4170         (!IN_MODULE || cmp_mod_scope(sptr2))) {
4171       error(1015, 3, gbl.lineno, SYMNAME(sptr2), NULL);
4172     }
4173   }
4174 
4175   if (sptre >= stb.firstusym)
4176     return generic_func(sptre, stktop, list);
4177 
4178   frozen = EXPSTG(sptre);
4179   if (list == ITEM_END)
4180     goto intrinsic_error;
4181   /*
4182    * Count number of arguments without type changing arguments in case
4183    * we need to recover by assuming reference is to an external function.
4184    */
4185   count = 0;
4186   for (ip1 = list; ip1 != ITEM_END; ip1 = ip1->next) {
4187     count++;
4188     switch (SST_IDG(ip1->t.stkp)) {
4189     case S_TRIPLE:
4190       goto intrinsic_error;
4191     default:
4192       break;
4193     }
4194   }
4195   /* position the arguments per the keyword argument string. note
4196    * that the number of arguments processed by get_kwd_args is
4197    *     max(actual arg count, number of 'non-variable' arguments).
4198    */
4199   i = KWDCNTG(sptre);
4200   if (count > i)
4201     i = count;
4202   if (get_kwd_args(list, i, KWDARGSTR(sptre)))
4203     goto intrinsic_error;
4204 
4205   intrin = INTASTG(sptre);
4206   dt_cast_word = 0;
4207   if (STYPEG(sptre) == ST_GENERIC) {
4208     /*
4209      * f2003 says that a boz literal can appear as an argument to
4210      * the real, dble, cmplx, and dcmplx intrinsics and its value
4211      * is used as the respective internal respresentation
4212      */
4213     switch (intrin) {
4214     case I_DBLE:
4215     case I_DCMPLX:
4216       dt_cast_word = DT_DBLE;
4217       break;
4218     case I_IAND:
4219       sem.mpaccatomic.rmw_op = AOP_AND;
4220       break;
4221     case I_IOR:
4222       sem.mpaccatomic.rmw_op = AOP_OR;
4223       break;
4224     case I_IEOR:
4225       sem.mpaccatomic.rmw_op = AOP_XOR;
4226       break;
4227     case I_MIN:
4228       sem.mpaccatomic.rmw_op = AOP_MIN;
4229       break;
4230     case I_MAX:
4231       sem.mpaccatomic.rmw_op = AOP_MAX;
4232       break;
4233     }
4234   }
4235   sp = ARG_STK(0); /* Save 1st arg's semantic stack pointer */
4236   dtype1 = 0;
4237   for (i = 0; i < count; i++) {
4238     sp = ARG_STK(i);
4239     argdtype = SST_DTYPEG(sp);
4240     if (argdtype == DT_WORD || argdtype == DT_DWORD) {
4241       if (dt_cast_word) {
4242         cngtyp(sp, dt_cast_word);
4243         argdtype = SST_DTYPEG(sp);
4244       } else if (argdtype == DT_WORD) {
4245       }
4246     }
4247     if (!dtype1) {
4248       f_dt = dtype1 = argdtype; /* Save 1st arg's data type */
4249       if (DTY(argdtype) == TY_ARRAY)
4250         break;
4251     } else {
4252       /* check rest of args to see if they might be array. */
4253       /* assert.  haven't seen an array argument yet. */
4254       if (DTY(argdtype) == TY_ARRAY) {
4255         f_dt = dtype1 = argdtype; /* Save data type */
4256         break;
4257       }
4258     }
4259   }
4260 
4261   if (STYPEG(sptre) == ST_GENERIC) {
4262     if (SST_ISNONDECC(sp)) {
4263       cngtyp(sp, DT_INT);
4264     }
4265     dtype = DDTG(dtype1);
4266     /* apply the KIND argument if applicable */
4267     /* determine specific intrinsic name from data type of first argument */
4268     switch (DTY(dtype)) {
4269     case TY_BLOG:
4270     case TY_BINT:
4271       sptr = GINTG(sptre);
4272       if (ARGTYPG(sptr) == INTTYPG(sptr))
4273         dtyper = dtype;
4274       break;
4275     case TY_SLOG:
4276     case TY_SINT:
4277       if ((sptr = GSINTG(sptre)))
4278         break;
4279     case TY_WORD:
4280     case TY_LOG:
4281     case TY_INT:
4282       sptr = GINTG(sptre);
4283       break;
4284     case TY_DWORD:
4285     case TY_LOG8:
4286     case TY_INT8:
4287       sptr = GINT8G(sptre);
4288       break;
4289     case TY_REAL:
4290       sptr = GREALG(sptre);
4291       break;
4292     case TY_DBLE:
4293       sptr = GDBLEG(sptre);
4294       break;
4295     case TY_QUAD:
4296       sptr = GQUADG(sptre);
4297       break;
4298     case TY_CMPLX:
4299       sptr = GCMPLXG(sptre);
4300       break;
4301     case TY_DCMPLX:
4302       sptr = GDCMPLXG(sptre);
4303       break;
4304     case TY_QCMPLX:
4305       sptr = GQCMPLXG(sptre);
4306       break;
4307     case TY_CHAR:
4308     case TY_NCHAR:
4309       if ((intrin == I_MAX || intrin == I_MIN) && sem.dinit_data) {
4310         paramct = 12;
4311         argtyp = dtype1;
4312         /* Should really check type of next argument is char also */
4313         rtlRtn = intrin == I_MAX ? RTE_max : RTE_min;
4314         sptr = sym_mkfunc_nodesc(mkRteRtnNm(rtlRtn), dtyper);
4315         gen_init_intrin_call(stktop, sptr, count, DDTG(dtype1), TRUE);
4316         A_OPTYPEP(SST_ASTG(stktop), intrin);
4317         return 1;
4318       }
4319     default:
4320       sptr = 0;
4321       break;
4322     }
4323 
4324     if (sptr == 0) {
4325       sptr = gen_newer_intrin(SST_SYMG(stktop), dtype);
4326     }
4327 
4328     if (sptr <= 0)
4329       goto intrinsic_error;
4330     assert(STYPEG(sptr) == ST_INTRIN, "ref_intrin: bad intrinsic sptr", sptr,
4331            3);
4332     /*
4333      * determine if resolved specific has the same name as the generic;
4334      * If it is, must 'freeze' the specific.
4335      */
4336     if (strcmp(SYMNAME(sptr), SYMNAME(sptre)) == 0)
4337       EXPSTP(sptr, 1);
4338   } else {
4339     /*  SPECIFICs  */
4340     static int float_intr_warn = 0;
4341     if (XBIT(124, 0x10)) {
4342       /* -i8 */
4343       /* the intrinsic ast opcodes of the following integer*8
4344        * intrinsics, must appear as special cases in
4345        * semfunc2.c:intrinsic_as_arg() so that the correct
4346        * function name is selected given the integer name.
4347        */
4348       switch (intrin) {
4349       case I_IABS:
4350         sptre = intast_sym[I_KIABS];
4351         break;
4352       case I_IDIM:
4353         sptre = intast_sym[I_KIDIM];
4354         break;
4355       case I_IDNINT:
4356         sptre = intast_sym[I_KIDNNT];
4357         break;
4358       case I_ISIGN:
4359         sptre = intast_sym[I_KISIGN];
4360         break;
4361       case I_MAX0:
4362         sptre = intast_sym[I_KMAX0];
4363         break;
4364       case I_MIN0:
4365         sptre = intast_sym[I_KMIN0];
4366         break;
4367       case I_MAX1:
4368         sptre = intast_sym[I_KMAX1];
4369         break;
4370       case I_MIN1:
4371         sptre = intast_sym[I_KMIN1];
4372         break;
4373       }
4374     }
4375     if (XBIT(124, 0x8)) {
4376       /* -r8 */
4377       /* the intrinsic ast opcodes of the following double real/complex
4378        * intrinsics, must appear as special cases in
4379        * semfunc2.c:intrinsic_as_arg() so that the correct
4380        * function name is selected given the real/complex name.
4381        */
4382       switch (intrin) {
4383       case I_ALOG:
4384         sptre = intast_sym[I_DLOG];
4385         break;
4386       case I_ALOG10:
4387         sptre = intast_sym[I_DLOG10];
4388         break;
4389       case I_AMAX1:
4390         sptre = intast_sym[I_DMAX1];
4391         break;
4392       case I_AMIN1:
4393         sptre = intast_sym[I_DMIN1];
4394         break;
4395       case I_AMOD:
4396         sptre = intast_sym[I_DMOD];
4397         break;
4398       case I_CABS:
4399         sptre = intast_sym[I_CDABS];
4400         break;
4401       case I_CSQRT:
4402         sptre = intast_sym[I_CDSQRT];
4403         break;
4404       case I_CLOG:
4405         sptre = intast_sym[I_CDLOG];
4406         break;
4407       case I_CEXP:
4408         sptre = intast_sym[I_CDEXP];
4409         break;
4410       case I_CSIN:
4411         sptre = intast_sym[I_CDSIN];
4412         break;
4413       case I_CCOS:
4414         sptre = intast_sym[I_CDCOS];
4415         break;
4416       case I_FLOATI:
4417         if (XBIT(124, 0x80000)) {
4418           sptre = intast_sym[I_DFLOTI];
4419           if (!float_intr_warn) {
4420             float_intr_warn = 1;
4421             error(155, 2, gbl.lineno,
4422                   "The type of FLOAT is now double precision with -r8", CNULL);
4423           }
4424         }
4425         break;
4426       case I_FLOATJ:
4427         if (XBIT(124, 0x80000)) {
4428           sptre = intast_sym[I_DFLOTJ];
4429           if (!float_intr_warn) {
4430             float_intr_warn = 1;
4431             error(155, 2, gbl.lineno,
4432                   "The type of FLOAT is now double precision with -r8", CNULL);
4433           }
4434         }
4435         break;
4436       case I_FLOAT:
4437         if (XBIT(124, 0x80000)) {
4438           sptre = intast_sym[I_DFLOAT];
4439           if (!float_intr_warn) {
4440             float_intr_warn = 1;
4441             error(155, 2, gbl.lineno,
4442                   "The type of FLOAT is now double precision with -r8", CNULL);
4443           }
4444         }
4445         break;
4446       }
4447     }
4448     sptr = sptre;
4449   }
4450 
4451   intast = INTASTG(sptr);
4452 
4453   /*
4454    * Assertion: sptr now points to the specific intrinsic entry ST_INTRIN
4455    * that was either specified with a generic name or a specific name.
4456    * sptre EITHER points to the generic name symbol entry or the specific
4457    * name symbol entry (if generic and specific have same names).
4458    */
4459   dtype = INTTYPG(sptr);
4460 
4461   /*
4462    * Determine intrinsic's ILM and number and type of arguments.
4463    */
4464   if (DTY(SST_DTYPEG(sp)) == TY_ARRAY) {
4465     opc = ARRAYFG(sptr); /* Get ilm for Vectors */
4466     /* Check if vectors disallowed and not a type conversion intrinsic.
4467      * Vectors okay for type conversion intrinsics.
4468      */
4469     if (ILMG(sptr) == IM_LOC)
4470       opc = IM_LOC;
4471     else if (opc == 0 && ILMG(sptr) != 0)
4472       goto intrinsic_error;
4473     /* opc == 0 */
4474   } else
4475     opc = ILMG(sptr);
4476   argtyp = ARGTYPG(sptr);
4477   paramct = PARAMCTG(sptr);
4478 
4479   if (paramct != 12 && paramct != 11 && count > paramct) {
4480     goto intrinsic_error;
4481   }
4482 
4483   if (paramct == 11) { /* CMPLX/DCMPLX intrinsic */
4484     if (ARG_STK(1))
4485       /* Two arguments in reference, cause conversion of each part to
4486        * real/dble
4487        */
4488 
4489       dtype = dtype == DT_CMPLX ? stb.user.dt_real : DT_DBLE;
4490 
4491     else /* treat like typical type conversion intrinsic */
4492       paramct = 1;
4493   } else {
4494     switch (intast) {
4495     case I_FLOAT:
4496     case I_DFLOAT:
4497       ddt = DDTG(f_dt);
4498       if (ddt == DT_INT8)
4499         argtyp = DT_INT8;
4500       break;
4501     }
4502   }
4503 
4504   if (sem.dinit_data) {
4505     switch (ILMG(sptr)) {
4506     case IM_ICHAR:
4507       gen_init_intrin_call(stktop, sptr, count, stb.user.dt_int, TRUE);
4508       return 1;
4509     case IM_IISHFT:
4510     case IM_JISHFT:
4511     case IM_KISHFT:
4512       gen_init_intrin_call(stktop, sptr, count, stb.user.dt_int, TRUE);
4513       return 1;
4514     case IM_IMAX:
4515     case IM_I8MAX:
4516     case IM_RMAX:
4517     case IM_DMAX:
4518     case IM_IMIN:
4519     case IM_I8MIN:
4520     case IM_RMIN:
4521     case IM_DMIN:
4522       gen_init_intrin_call(stktop, sptr, count, DDTG(dtype1), TRUE);
4523       return 1;
4524     case 0:
4525       switch (intrin) {
4526       case I_DBLE:
4527       case I_DFLOAT:
4528       case I_FLOAT:
4529       case I_REAL:
4530         gen_init_intrin_call(stktop, sptre, count, DDTG(dtype1), TRUE);
4531         return 1;
4532       }
4533     }
4534   }
4535 
4536   /*
4537    * Count number of constant arguments.
4538    */
4539   const_cnt = 0;
4540   for (i = 0; i < count; i++)
4541     if (ARG_STK(i) && is_sst_const(ARG_STK(i)))
4542       const_cnt++;
4543 
4544   /*  If all arguments are constants, attempt to constant fold  */
4545 
4546   if (const_cnt == count) {
4547 
4548     INT conval, con1, con2, res[4], num1[4], num2[4];
4549     int q0;
4550     int qhalf;
4551     char ch;
4552 
4553     switch (opc) {
4554     case IM_LOC:
4555 #ifdef I_C_ASSOCIATED
4556     case IM_C_ASSOC:
4557 #endif
4558       goto no_const_fold;
4559     }
4560 
4561     argt = mk_argt(count); /* space for arguments */
4562     for (i = 0; i < count; i++) {
4563       sp = ARG_STK(i);
4564       if (opc == 0) {
4565         /* type conversion: for the two argument CMPLX/DCMPLX, each
4566          * part is converted to the real type implied by the intrinsic;
4567          * otherwise, the operands are converted to the result type
4568          * of the intrinsic.
4569          */
4570         if (XBIT(124, 0x8)) {
4571           /* -r8 */
4572           if (intast == I_SNGL) {
4573             dtype = DT_REAL8;
4574           }
4575         }
4576         cngtyp(sp, dtype);
4577       } else if (DTY(argtyp) == TY_CHAR && DTY(SST_DTYPEG(sp)) == TY_CHAR) {
4578         if (opc == IM_ICHAR && i == 0)
4579           dtyper = stb.user.dt_int;
4580       } else if ((DTY(argtyp) == TY_NCHAR || DTY(argtyp) == TY_CHAR) &&
4581                  DTY(SST_DTYPEG(sp)) == TY_NCHAR) {
4582         /*
4583          * if the argument is character and the expected argument is
4584          * character, we don't call cngtyp since we represent argtyp
4585          * as a character of length 1
4586          */
4587         if (opc == IM_ICHAR && i == 0)
4588           dtyper = stb.user.dt_int;
4589       } else if (i == 2 && opc == IM_NINDEX)
4590         cngtyp(sp, DT_LOG);
4591       else if (opc == IM_ICHAR) {
4592         if (i == 0) {
4593           chktyp(sp, argtyp, TRUE);
4594           dtyper = stb.user.dt_int;
4595         } else {
4596           dtyper = set_kind_result(sp, DT_INT, TY_INT);
4597           if (!dtyper) {
4598             goto intrinsic_error;
4599           }
4600         }
4601       } else
4602         cngtyp(sp, argtyp);
4603       ARGT_ARG(argt, i) = SST_ASTG(sp);
4604     }
4605 
4606     con1 = GET_CVAL_ARG(0);
4607     if (paramct < 12) {
4608       if (paramct == 11) {
4609         /* CMPLX/DCMPLX with 2 args: cause both to make complex # */
4610         num1[0] = con1;
4611         num1[1] = GET_CVAL_ARG(1);
4612 
4613         if (DTY(dtype) == TY_REAL)
4614           conval = getcon(num1, DT_CMPLX);
4615         else
4616           conval = getcon(num1, DT_DCMPLX);
4617 
4618         goto const_return;
4619       }
4620       if (opc == 0) { /* type conversion intrinsic */
4621         conval = GET_CVAL_ARG(0);
4622         if (XBIT(124, 0x8)) {
4623           /* -r8 */
4624           if (intast == I_SNGL) {
4625             dtype = DT_REAL8;
4626             goto const_return_2;
4627           }
4628         }
4629         goto const_return;
4630       }
4631       switch (opc) {
4632       case IM_IABS:
4633         conval = con1 >= 0 ? con1 : -con1;
4634         goto const_return;
4635       case IM_ABS:
4636         xfabsv(con1, &res[0]);
4637         conval = res[0];
4638         goto const_return;
4639       case IM_DABS:
4640         GET_DBLE(num1, con1);
4641         xdabsv(num1, res);
4642         goto const_getcon;
4643       case IM_NINT:
4644         num1[0] = CONVAL2G(stb.flt0);
4645         if (xfcmp(con1, num1[0]) >= 0) {
4646           INT fv2_23 = 0x4b000000;
4647           if (xfcmp(con1, fv2_23) >= 0)
4648             xfadd(con1, CONVAL2G(stb.flt0), &res[0]);
4649           else
4650             xfadd(con1, CONVAL2G(stb.flthalf), &res[0]);
4651         } else {
4652           INT fvm2_23 = 0xcb000000;
4653           if (xfcmp(con1, fvm2_23) <= 0)
4654             xfsub(con1, CONVAL2G(stb.flt0), &res[0]);
4655           else
4656             xfsub(con1, CONVAL2G(stb.flthalf), &res[0]);
4657         }
4658         conval = cngcon(res[0], DT_REAL4, stb.user.dt_int);
4659         goto const_return;
4660       case IM_IDNINT:
4661         if (const_fold(OP_CMP, con1, stb.dbl0, DT_REAL8) >= 0) {
4662           INT dv2_52[2] = {0x43300000, 0x00000000};
4663           INT d2_52;
4664           d2_52 = getcon(dv2_52, DT_DBLE);
4665           if (const_fold(OP_CMP, con1, d2_52, DT_REAL8) >= 0)
4666             res[0] = const_fold(OP_ADD, con1, stb.dbl0, DT_REAL8);
4667           else
4668             res[0] = const_fold(OP_ADD, con1, stb.dblhalf, DT_REAL8);
4669         } else {
4670           INT dvm2_52[2] = {0xc3300000, 0x00000000};
4671           INT dm2_52;
4672           dm2_52 = getcon(dvm2_52, DT_DBLE);
4673           if (const_fold(OP_CMP, con1, dm2_52, DT_REAL8) <= 0)
4674             res[0] = const_fold(OP_SUB, con1, stb.dblhalf, DT_REAL8);
4675           else
4676             res[0] = const_fold(OP_SUB, con1, stb.dbl0, DT_REAL8);
4677         }
4678         conval = cngcon(res[0], DT_REAL8, stb.user.dt_int);
4679         goto const_return;
4680       case IM_IMAG:
4681       case IM_DIMAG:
4682         conval = CONVAL2G(con1);
4683         goto const_return;
4684       case IM_CONJG:
4685         res[0] = CONVAL1G(con1);
4686         con2 = CONVAL2G(con1);
4687         xfsub(CONVAL2G(stb.flt0), con2, &res[1]);
4688         goto const_getcon;
4689       case IM_DCONJG:
4690         res[0] = CONVAL1G(con1);
4691         con2 = CONVAL2G(con1);
4692         res[1] = const_fold(OP_SUB, (INT)stb.dbl0, con2, DT_REAL8);
4693         goto const_getcon;
4694 #ifdef IM_DPROD
4695       case IM_DPROD:
4696         con2 = GET_CVAL_ARG(1);
4697         xdble(con1, num1);
4698         xdble(con2, num2);
4699         xdmul(num1, num2, res);
4700         goto const_getcon;
4701 #endif
4702       case IM_AND8:
4703         con2 = GET_CVAL_ARG(1);
4704         GET_DBLE(num1, con1);
4705         GET_DBLE(num2, con2);
4706         and64(num1, num2, res);
4707         goto const_getcon;
4708       case IM_AND:
4709         con2 = GET_CVAL_ARG(1);
4710         conval = con1 & con2;
4711         goto const_return;
4712       case IM_OR8:
4713         con2 = GET_CVAL_ARG(1);
4714         GET_DBLE(num1, con1);
4715         GET_DBLE(num2, con2);
4716         or64(num1, num2, res);
4717         goto const_getcon;
4718       case IM_OR:
4719         con2 = GET_CVAL_ARG(1);
4720         conval = con1 | con2;
4721         goto const_return;
4722       case IM_XOR8:
4723         con2 = GET_CVAL_ARG(1);
4724         GET_DBLE(num1, con1);
4725         GET_DBLE(num2, con2);
4726         xor64(num1, num2, res);
4727         goto const_getcon;
4728       case IM_XOR:
4729         con2 = GET_CVAL_ARG(1);
4730         conval = con1 ^ con2;
4731         goto const_return;
4732       case IM_NOT8:
4733         GET_DBLE(num1, con1);
4734         not64(num1, res);
4735         goto const_getcon;
4736       case IM_NOT:
4737         conval = ~con1;
4738         goto const_return;
4739       case IM_I8MOD:
4740         /* i % j = i - (i / j)*j */
4741         con2 = GET_CVAL_ARG(1);
4742         GET_DBLE(num1, con1);
4743         GET_DBLE(num2, con2);
4744         div64(num1, num2, res);
4745         mul64(num2, res, res);
4746         sub64(num1, res, res);
4747         goto const_getcon;
4748       case IM_MOD:
4749         con2 = GET_CVAL_ARG(1);
4750         conval = con1 % con2;
4751         goto const_return;
4752       case IM_IDIM:
4753         con2 = GET_CVAL_ARG(1);
4754         conval = con1 > con2 ? con1 - con2 : 0;
4755         goto const_return;
4756       case IM_I8DIM:
4757         con2 = GET_CVAL_ARG(1);
4758         GET_DBLE(num1, con1);
4759         GET_DBLE(num2, con2);
4760         if (cmp64(num1, num2) > 0)
4761           sub64(num1, num2, res);
4762         else
4763           res[0] = res[1] = 0;
4764         goto const_getcon;
4765       case IM_DIM:
4766         con2 = GET_CVAL_ARG(1);
4767         if (xfcmp(con1, con2) > 0) {
4768           xfsub(con1, con2, &res[0]);
4769           conval = res[0];
4770         } else
4771           conval = CONVAL2G(stb.flt0);
4772         goto const_return;
4773       case IM_DDIM:
4774         con2 = GET_CVAL_ARG(1);
4775         if (const_fold(OP_CMP, con1, con2, DT_REAL8) > 0)
4776           conval = const_fold(OP_SUB, con1, con2, DT_REAL8);
4777         else
4778           conval = stb.dbl0;
4779         goto const_return;
4780       case IM_IISHFT:
4781         con2 = GET_CVAL_ARG(1);
4782         /*
4783          * because this ilm is used for the ISHFT intrinsic, count
4784          * is defined for values -16 to 16.
4785          */
4786         if (con2 >= 0) {
4787           if (con2 >= 16)
4788             conval = 0;
4789           else {
4790             conval = ULSHIFT(con1, con2);
4791             conval = ULSHIFT(conval, 16);
4792             conval = ARSHIFT(conval, 16);
4793           }
4794         } else {
4795           if (con2 <= -16)
4796             conval = 0;
4797           else {
4798             con1 &= 0xffff;
4799             conval = URSHIFT(con1, -con2);
4800           }
4801         }
4802         goto const_return;
4803       case IM_JISHFT:
4804         con2 = GET_CVAL_ARG(1);
4805         /*
4806          * because this ilm is used for the ISHFT intrinsic, count
4807          * is defined for values -32 to 32; some hw (i.e., n10) shifts
4808          * by cnt mod 32.
4809          */
4810         if (con2 >= 0) {
4811           if (con2 >= 32)
4812             conval = 0;
4813           else
4814             conval = ULSHIFT(con1, con2);
4815         } else {
4816           if (con2 <= -32)
4817             conval = 0;
4818           else
4819             conval = URSHIFT(con1, -con2);
4820         }
4821         goto const_return;
4822       case IM_KISHFT:
4823         con2 = GET_CVAL_ARG(1);
4824         /* con1 and con2 are symbol pointers */
4825         /* get the value for con2 */
4826         con2 = CONVAL2G(con2);
4827         res[0] = CONVAL1G(con1);
4828         res[1] = CONVAL2G(con1);
4829         if (con2 >= 0) {
4830           if (con2 >= 64) {
4831             res[0] = 0;
4832             res[1] = 0;
4833           } else if (con2 >= 32) {
4834             /* shift con1 by 32 bits or more */
4835             res[0] = ULSHIFT(res[1], con2 - 32);
4836             res[1] = 0;
4837           } else {
4838             /* shift by less than 32 bits; shift high-order
4839              * bits of low-order word into high-order word */
4840             res[0] = ULSHIFT(res[0], con2) | URSHIFT(res[1], 32 - con2);
4841             res[1] = ULSHIFT(res[1], con2);
4842           }
4843         } else {
4844           con2 = -con2;
4845           if (con2 >= 64) {
4846             res[0] = 0;
4847             res[1] = 0;
4848           } else if (con2 >= 32) {
4849             /* shift con1 by 32 bits or more */
4850             res[1] = URSHIFT(res[0], con2 - 32);
4851             res[0] = 0;
4852           } else {
4853             /* shift by less than 32 bits; shift low-order
4854              * bits of high-order word into low-order word */
4855             res[1] = URSHIFT(res[1], con2) | ULSHIFT(res[0], 32 - con2);
4856             res[0] = URSHIFT(res[0], con2);
4857           }
4858         }
4859         conval = getcon(res, DT_INT8);
4860         goto const_return;
4861       case IM_ICHAR:
4862         if (DTY(SST_DTYPEG(ARG_STK(0))) == TY_NCHAR) { /* kanji */
4863           int dum, clen;
4864           assert(DTY(DTYPEG(con1)) == TY_CHAR || DTY(DTYPEG(con1)) == TY_NCHAR,
4865                  "ref_intrin:KK", con1, 3);
4866           con2 = CONVAL1G(con1);
4867           clen = string_length(DTYPEG(con2));
4868           conval = kanji_char((unsigned char *)stb.n_base + CONVAL1G(con2),
4869                               clen, &dum);
4870         } else
4871           conval = stb.n_base[CONVAL1G(con1)] & 0xff;
4872 
4873         if (!dtyper)
4874           dtyper = stb.user.dt_int;
4875         dtype = dtyper;
4876         if (DTY(dtyper) == TY_INT8) {
4877           /* The user default integer is integer*8, but INTTYP(ICHAR)
4878            * may still be DT_INT4 because of -i8.  Force the type to
4879            * DT_INT8 -- a better way to do this may be to store
4880            * DT_INT8 in the INTTYP field in sym_init() if -i8
4881            * (-x 124 0x10) was present.
4882            */
4883           res[0] = 0;
4884           res[1] = conval;
4885           conval = getcon(res, DT_INT8);
4886           dtype = DT_INT8;
4887         }
4888         goto const_return_2;
4889       case IM_CHAR:
4890         ch = con1;
4891         conval = getstring(&ch, 1);
4892         goto const_return;
4893 
4894       case IM_GE:
4895       case IM_GT:
4896       case IM_LE:
4897       case IM_LT:
4898         dtype = SST_DTYPEG(ARG_STK(0));
4899         /* two arguments must both be either TY_CHAR or TY_NCHAR: */
4900         if (DTY(dtype) != DTY(SST_DTYPEG(ARG_STK(1))))
4901           goto intrinsic_error;
4902         con2 = GET_CVAL_ARG(1);
4903         conval = const_fold(OP_CMP, con1, con2, dtype);
4904 
4905         switch (opc) {
4906         case IM_GE:
4907           conval = conval >= 0 ? SCFTN_TRUE : SCFTN_FALSE;
4908           break;
4909         case IM_GT:
4910           conval = conval > 0 ? SCFTN_TRUE : SCFTN_FALSE;
4911           break;
4912         case IM_LE:
4913           conval = conval <= 0 ? SCFTN_TRUE : SCFTN_FALSE;
4914           break;
4915         case IM_LT:
4916           conval = conval < 0 ? SCFTN_TRUE : SCFTN_FALSE;
4917         }
4918 
4919         /* Convert constant result logical type if -i8 turned on */
4920 
4921         if (DTY(stb.user.dt_log) == TY_LOG8) {
4922           dtype = DT_LOG8;
4923           conval = cngcon(conval, DT_LOG4, dtype);
4924           goto const_return_2;
4925         }
4926         goto const_return;
4927       case IM_IIBSET:
4928       case IM_JIBSET:
4929         /* how many bits to use from the first argument */
4930         i = size_of(dtype);
4931         i = i * 8;
4932         con2 = GET_CVAL_ARG(1);
4933         /* take only lower bits of con2, that is, modulo i */
4934         con2 = con2 % i;
4935         /* set bit 'con2' in 'con1' */
4936         conval = con1 | (1 << con2);
4937         goto const_return;
4938       case IM_KIBSET:
4939         /* how many bits to use from the first argument */
4940         i = size_of(dtype);
4941         i = i * 8;
4942         GET_DBLE(num1, con1);
4943         con2 = GET_CVAL_ARG(1);
4944         GET_DBLE(num2, con2);
4945         con2 = num2[1];
4946         /* take only lower bits of con2, that is, modulo i */
4947         con2 = con2 % i;
4948         res[2] = res[3] = 0;
4949         res[0] = num1[0];
4950         res[1] = num1[1];
4951         if (con2 >= 32) {
4952           res[0] |= 1 << (con2 - 32);
4953         } else {
4954           res[1] |= 1 << con2;
4955         }
4956         goto const_getcon;
4957 
4958       default:
4959         switch (intast) {
4960         case I_IISIGN:
4961         case I_JISIGN:
4962         case I_ISIGN:
4963           conval = con1;
4964           if (conval < 0 && conval != 0x80000000)
4965             conval = -conval;
4966           con2 = GET_CVAL_ARG(1);
4967           if (con2 < 0 && conval != 0x80000000)
4968             conval = -conval;
4969           goto const_return;
4970         case I_KISIGN:
4971           GET_DBLE(res, con1);
4972           GET_DBLE(num1, stb.k0);
4973           if (cmp64(res, num1) < 0)
4974             neg64(res, res);
4975           con2 = GET_CVAL_ARG(1);
4976           GET_DBLE(num2, con2);
4977           if (cmp64(num2, num1) < 0)
4978             neg64(res, res);
4979           goto const_getcon;
4980         case I_SIGN:
4981           xfabsv(con1, &conval);
4982           con2 = GET_CVAL_ARG(1);
4983           num1[0] = CONVAL2G(stb.flt0);
4984           if (con2 == CONVAL2G(stb.fltm0) || xfcmp(con2, num1[0]) < 0) {
4985             /* IEEE -0.0 , or < 0.0 */
4986             xfneg(conval, &conval);
4987           }
4988           goto const_return;
4989         case I_DSIGN:
4990           GET_DBLE(res, con1);
4991           xdabsv(res, res);
4992           con2 = GET_CVAL_ARG(1);
4993           GET_DBLE(num2, con2);
4994           GET_DBLE(num1, stb.dbl0);
4995           if (con2 == stb.dblm0 || xdcmp(num2, num1) < 0) {
4996             /* IEEE -0.0 , or < 0.0 */
4997             xdneg(res, res);
4998           }
4999           goto const_getcon;
5000         default:
5001           break;
5002         }
5003         break;
5004       }
5005     } else { /* max or min intrinsic */
5006       switch (opc) {
5007       case IM_IMAX:
5008         conval = con1;
5009         for (i = 1; i < count; i++) {
5010           con1 = GET_CVAL_ARG(i);
5011           if (con1 > conval)
5012             conval = con1;
5013         }
5014         break;
5015       case IM_I8MAX:
5016         conval = con1;
5017         for (i = 1; i < count; i++) {
5018           con1 = GET_CVAL_ARG(i);
5019           if (const_fold(OP_CMP, con1, conval, DT_INT8) > 0)
5020             conval = con1;
5021         }
5022         break;
5023       case IM_RMAX:
5024         conval = con1;
5025         for (i = 1; i < count; i++) {
5026           con1 = GET_CVAL_ARG(i);
5027           if (xfcmp(con1, conval) > 0)
5028             conval = con1;
5029         }
5030         break;
5031       case IM_DMAX:
5032         conval = con1;
5033         for (i = 1; i < count; i++) {
5034           con1 = GET_CVAL_ARG(i);
5035           if (const_fold(OP_CMP, con1, conval, DT_REAL8) > 0)
5036             conval = con1;
5037         }
5038         break;
5039       case IM_IMIN:
5040         conval = con1;
5041         for (i = 1; i < count; i++) {
5042           con1 = GET_CVAL_ARG(i);
5043           if (con1 < conval)
5044             conval = con1;
5045         }
5046         break;
5047       case IM_I8MIN:
5048         conval = con1;
5049         for (i = 1; i < count; i++) {
5050           con1 = GET_CVAL_ARG(i);
5051           if (const_fold(OP_CMP, con1, conval, DT_INT8) < 0)
5052             conval = con1;
5053         }
5054         break;
5055       case IM_RMIN:
5056         conval = con1;
5057         for (i = 1; i < count; i++) {
5058           con1 = GET_CVAL_ARG(i);
5059           if (xfcmp(con1, conval) < 0)
5060             conval = con1;
5061         }
5062         break;
5063       case IM_DMIN:
5064         conval = con1;
5065         for (i = 1; i < count; i++) {
5066           con1 = GET_CVAL_ARG(i);
5067           if (const_fold(OP_CMP, con1, conval, DT_REAL8) < 0)
5068             conval = con1;
5069         }
5070         break;
5071       default:
5072         goto no_const_fold;
5073       }
5074       if (argtyp != dtype)
5075         conval = cngcon(conval, argtyp, dtype);
5076       goto const_return;
5077     }
5078     goto no_const_fold;
5079 
5080   const_getcon:
5081     conval = getcon(res, dtype);
5082   const_return:
5083     if (ARGTYPG(sptr) == INTTYPG(sptr) && dtyper) {
5084       dtype = dtyper;
5085     } else {
5086       dtype = INTTYPG(sptr);
5087     }
5088   const_return_2:
5089     SST_IDP(stktop, S_CONST);
5090     SST_DTYPEP(stktop, dtype);
5091     SST_CVALP(stktop, conval);
5092     EXPSTP(sptre, 1); /* freeze generic or specific name */
5093     SST_SHAPEP(stktop, 0);
5094 
5095     ast = mk_cval1(conval, dtype);
5096     SST_ASTP(stktop, ast);
5097 
5098     return conval;
5099   }
5100 
5101 no_const_fold:
5102   /*
5103    * Validate arguments specified.
5104    */
5105   shaper = 0;
5106   if (opc == 0 && paramct == 11)
5107     /* CMPLX/DCMPLX intrinsic */
5108     for (i = 0; i < count; XFR_ARGAST(i), i++) {
5109       sp = ARG_STK(i);
5110       chktyp(sp, DT_NUMERIC, FALSE);
5111       if (!shaper)
5112         shaper = SST_SHAPEG(sp);
5113     }
5114   else
5115     for (i = 0; i < count; XFR_ARGAST(i), i++) {
5116       sp = ARG_STK(i);
5117       if (opc == IM_LOC) {
5118         if (sc_local_passbyvalue(SST_SYMG(sp), GBL_CURRFUNC)) {
5119           error(155, 3, gbl.lineno,
5120                 "unsupported LOC of VALUE parameter:", SYMNAME(SST_SYMG(sp)));
5121         } else if (mklvalue(sp, 3) == 0)
5122           goto intrinsic_error;
5123       }
5124       else if (DTYG(SST_DTYPEG(sp)) == TY_NCHAR) {
5125         switch (opc) {
5126         case IM_ICHAR:
5127           dtyper = stb.user.dt_int;
5128         case IM_NCHAR:
5129         case IM_NINDEX:
5130         case IM_NLEN:
5131         case IM_GE:
5132         case IM_GT:
5133         case IM_LE:
5134         case IM_LT:
5135           break;
5136         default:
5137           chktyp(sp, argtyp, TRUE);
5138           continue;
5139         }
5140         mkexpr(sp);
5141       }
5142       else {
5143         switch (opc) {
5144         case IM_GE:
5145         case IM_GT:
5146         case IM_LE:
5147         case IM_LT:
5148           if (DTYG(SST_DTYPEG(sp)) != TY_CHAR)
5149             goto intrinsic_error;
5150           mkexpr(sp);
5151           break;
5152         case IM_ICHAR:
5153           if (i == 0) {
5154             chktyp(sp, argtyp, TRUE);
5155             dtyper = stb.user.dt_int;
5156           } else {
5157             dtyper = set_kind_result(sp, DT_INT, TY_INT);
5158             if (!dtyper) {
5159               goto intrinsic_error;
5160             }
5161           }
5162           break;
5163 #ifdef I_C_ASSOCIATED
5164         case IM_C_ASSOC:
5165           if (SST_IDG(sp) == S_EXPR)
5166             (void)tempify(sp);
5167           mkarg(sp, &dum);
5168           break;
5169 #endif
5170         default:
5171           if (i == 2 && opc == IM_NINDEX)
5172             cngtyp(sp, DT_LOG);
5173           else
5174             chktyp(sp, argtyp, TRUE);
5175           break;
5176         }
5177       }
5178 
5179       if (!shaper)
5180         shaper = SST_SHAPEG(sp);
5181     }
5182 
5183   if (paramct < 12) {
5184     if (paramct == 11) {
5185       /* complex intrinsic with 2 args: cause both to make complex # */
5186       /* just mark as a type conversion, vectors ok - ILMG & ARRAYF
5187        * fields of type conversions intrinsics are 0.
5188        */
5189       opc = 0;
5190     }
5191   } else { /* max or min intrinsic */
5192     if (dtype != argtyp) {
5193       SST_IDP(stktop, S_EXPR);
5194       SST_DTYPEP(stktop, argtyp);
5195       cngtyp(stktop, dtype);
5196     }
5197   }
5198 
5199   /* SUCCESSFUL GENERIC/INTRINSIC PROCESSING */
5200   /* The data type of the result comes from the specific intrinsic used.
5201    * The shape of the result comes from the shape of the 1st argument.
5202    */
5203   if (opc == IM_LOC) {
5204     shaper = 0;
5205     dtyper = DT_PTR;
5206     switch (intast) {
5207     case I_C_LOC:
5208       ddt = get_iso_ptrtype("c_ptr");
5209       if (ddt)
5210         dtyper = ddt;
5211       break;
5212     case I_C_FUNLOC:
5213       ddt = get_iso_ptrtype("c_funptr");
5214       if (ddt)
5215         dtyper = ddt;
5216       break;
5217     }
5218   } else {
5219     if (!dtyper) {
5220       switch (intast) {
5221       case I_BITEST:
5222       case I_BJTEST:
5223       case I_BKTEST:
5224       case I_BTEST:
5225         dtyper = stb.user.dt_log;
5226         break;
5227       default:
5228         dtyper = INTTYPG(sptr);
5229         break;
5230       }
5231     }
5232     if (DTY(dtype1) == TY_ARRAY && (ARRAYFG(sptr) || !opc)) {
5233       /* Assertion:  First argument is an array AND intrinsic can
5234        *             handle vectors (this includes the type conversion
5235        *             intrinsics).  Create an array data type.
5236        */
5237       dtype = dup_array_dtype(dtype1);
5238       DTY(dtype + 1) = dtyper;
5239       dtyper = dtype;
5240     } else {
5241       if (shaper)
5242         interr("ref_intrin: result has shape, but dtype is not array", dtyper,
5243                2);
5244     }
5245   }
5246 
5247   SST_DTYPEP(stktop, dtyper);
5248   SST_IDP(stktop, S_EXPR);
5249 
5250   /* It is time to freeze the symbol's use as an intrinsic reference.
5251    * Use sptre which points to the generic or specific name that was found
5252    * in the source code.  Freezing generic names does not automatically
5253    * freeze specific names unless the names are the same.
5254    */
5255 
5256   func_type = A_INTR;
5257   switch (intast) {
5258   case I_ICHAR:
5259     if (count == 2) {
5260       count = 1;
5261     }
5262     func_ast = mk_id(sptre);
5263     break;
5264   case I_MODULO:
5265     switch ((int)INTTYPG(sptr)) {
5266     case DT_SINT:
5267       rtlRtn = RTE_imodulov;
5268       break;
5269     case DT_INT4:
5270       rtlRtn = RTE_modulov;
5271       break;
5272     case DT_INT8:
5273       rtlRtn = RTE_i8modulov;
5274       break;
5275     case DT_REAL4:
5276       rtlRtn = RTE_amodulov;
5277       break;
5278     case DT_REAL8:
5279       rtlRtn = RTE_dmodulov;
5280       break;
5281     }
5282     fsptr = sym_mkfunc_nodesc(mkRteRtnNm(rtlRtn), (int)INTTYPG(sptr));
5283     EXTSYMP(sptr, fsptr);
5284     ELEMENTALP(sptr, 1);
5285     func_ast = mk_id(fsptr);
5286     break;
5287 #ifdef I_C_ASSOCIATED
5288   case I_C_ASSOCIATED:
5289     if (_c_associated(stktop, count)) {
5290       count = 2;
5291       goto use_intr_sym;
5292     }
5293     goto intrinsic_error;
5294 #endif
5295   case I_SNGL:
5296     if (XBIT(124, 0x8)) {
5297       /* -r8 */
5298       ast = ARG_AST(0);
5299       SST_ASTP(stktop, ast);
5300       SST_DTYPEP(stktop, DT_REAL8);
5301       SST_SHAPEP(stktop, shaper);
5302       EXPSTP(sptre, 1);
5303       return 1;
5304     }
5305     goto use_intr_sym;
5306   case I_IISHFTC:
5307   case I_JISHFTC:
5308   case I_ISHFTC:
5309   case I_KISHFTC:
5310     if (count == 2) { /* need to provide a size argument */
5311       ARG_AST(2) = mk_cval((INT)bits_in((int)DDTG(f_dt)), DT_INT);
5312       count++;
5313     }
5314   /*  fall thru  */
5315   default: /* name is just the name of the specific or generic */
5316   use_intr_sym:
5317     func_ast = mk_id(sptre);
5318     break;
5319   }
5320 
5321   argt = mk_argt(count); /* space for arguments */
5322   for (i = 0; i < count; i++)
5323     ARGT_ARG(argt, i) = ARG_AST(i);
5324 
5325   ast = mk_func_node(func_type, func_ast, count, argt);
5326   A_DTYPEP(ast, dtyper);
5327   A_OPTYPEP(ast, intast);
5328   A_SHAPEP(ast, shaper);
5329   SST_ASTP(stktop, ast);
5330   SST_SHAPEP(stktop, shaper);
5331   EXPSTP(sptre, 1);
5332 
5333   return 1;
5334 
5335 /*
5336  * Error recovery: Generate ILM's, and fix semantic stack
5337  */
5338 intrinsic_error:
5339 
5340   /* Need to add a check for min and max first */
5341   if (STYPEG(sptre) == ST_GENERIC && (intrin == I_MAX || intrin == I_MIN)) {
5342     if (count > 1 && ((DTY(dtype1) == TY_CHAR || DTY(dtype1) == TY_NCHAR) ||
5343                       (DTYG(dtype1) == TY_CHAR || DTYG(dtype1) == TY_NCHAR))) {
5344 
5345       /* Need to check if all arguments are the same type.
5346        * Not sure if we can check shape here, I think so(later).
5347        */
5348       argt = mk_argt(count + 2);
5349       for (i = 0; i < count; i++) {
5350         sp = ARG_STK(i);
5351         argdtype = SST_DTYPEG(sp);
5352         if (DTY(argdtype) != DTY(dtype1)) {
5353           goto intrinsic_error2;
5354         }
5355         if (ARG_AST(i)) {
5356           ARGT_ARG(argt, i + 2) = ARG_AST(i);
5357         } else if (SST_IDG(sp) == S_IDENT || SST_IDG(sp) == S_ACONST) {
5358           SST_ASTP(sp, 0);
5359           (void)mkarg(sp, &dum);
5360           XFR_ARGAST(i);
5361           ARGT_ARG(argt, i + 2) = ARG_AST(i);
5362           if (rank_of_ast((int)ARG_AST(0)) != rank_of_ast((int)ARG_AST(i))) {
5363             goto intrinsic_error2;
5364           }
5365         }
5366       }
5367       rtlRtn = intrin == I_MAX ? RTE_max : RTE_min;
5368       hpf_sym = sym_mkfunc_nodesc(mkRteRtnNm(rtlRtn), dtyper);
5369       func_ast = mk_id(hpf_sym);
5370       /* Add 2 arguments
5371        * 1) the number of argument in the list, excluding itself and the result
5372        * 2) the result
5373        */
5374       sp = ARG_STK(0);
5375       chktyp(sp, dtype1, TRUE);
5376       shaper = SST_SHAPEG(sp);
5377 
5378       /* check only the first argument */
5379       if (DTY(dtype1) == TY_ARRAY) {
5380         if (shaper) {
5381           if (SHD_NDIM(shaper) != ADD_NUMDIM(dtype1)) {
5382             tmp = get_shape_arr_temp(ARG_AST(0));
5383           } else {
5384             ADSC *ad;
5385             ad = AD_DPTR(dtype1);
5386             if (AD_DEFER(ad) || AD_ADJARR(ad) || AD_NOBOUNDS(ad)) {
5387               tmp = get_shape_arr_temp(ARG_AST(0));
5388             } else
5389               tmp = get_arr_temp(dtype1, FALSE, TRUE, FALSE);
5390           }
5391         } else
5392           tmp = get_arr_temp(dtype1, FALSE, TRUE, FALSE);
5393 
5394       } else {
5395         dtype1 = get_temp_dtype(dtype1, ARG_AST(0));
5396         tmp = get_temp(dtype1);
5397       }
5398       tmp_ast = mk_id(tmp);
5399 
5400       func_type = A_CALL;
5401       /* First number of argument list, and a result */
5402       ARGT_ARG(argt, 0) = mk_cval(count, DT_INT);
5403       ARGT_ARG(argt, 1) = tmp_ast;
5404 
5405       ast = mk_func_node(func_type, func_ast, count + 2, argt);
5406 
5407       add_stmt(ast);
5408       dtyper = dtype1;
5409       A_DTYPEP(ast, dtyper);
5410       A_DTYPEP(func_ast, dtyper);
5411       A_SHAPEP(ast, shaper);
5412 
5413       SST_ASTP(stktop, tmp_ast);
5414       SST_SHAPEP(stktop, shaper);
5415       SST_DTYPEP(stktop, dtyper);
5416       SST_IDP(stktop, S_EXPR);
5417 
5418       EXPSTP(hpf_sym, 1);
5419       ELEMENTALP(hpf_sym, 1);
5420       return 1;
5421     }
5422   }
5423 
5424 intrinsic_error2:
5425   /* Wrong number or type of arguments to intrinsic */
5426   if (frozen) {
5427     /* Replace expression term with constant 0.  Save sptr to intrinsic
5428      * in stack so that during lvalue processing the error message
5429      * generated can get the symbol's name.
5430      */
5431     error(74, 3, gbl.lineno, SYMNAME(sptre), CNULL);
5432     fix_term(stktop, stb.i0);
5433     SST_ERRSYMP(stktop, sptre);
5434   } else {
5435     /* Intrinsic name without argument list is assumed to be a variable
5436      * Intrinsic name with wrong argument list is assumed to be external
5437      */
5438     if (list == NULL) {
5439       sptr = newsym(sptre);
5440       STYPEP(sptre, ST_VAR);
5441     } else {
5442       sptr = newsym(sptre);
5443       STYPEP(sptre, ST_IDENT);
5444     }
5445 
5446     mkident(stktop);
5447     SST_SYMP(stktop, sptr);
5448     mkvarref(stktop, list);
5449   }
5450 
5451   SST_IDP(stktop, S_EXPR);
5452   return 1;
5453 }
5454 
5455 #ifdef I_C_ASSOCIATED
5456 static int
_c_associated(SST * stkp,int count)5457 _c_associated(SST *stkp, int count)
5458 {
5459   int lop, rop;
5460 
5461   lop = ARG_AST(0);
5462   if (!is_iso_cptr(A_DTYPEG(lop)))
5463     return 0;
5464   lop = rewrite_cptr_references(lop);
5465   ARG_AST(0) = lop;
5466   if (count == 2) {
5467     rop = ARG_AST(1);
5468     if (!is_iso_cptr(A_DTYPEG(rop)))
5469       return 0;
5470     rop = rewrite_cptr_references(rop);
5471     ARG_AST(1) = rop;
5472   }
5473   return 1;
5474 }
5475 #endif
5476 
5477 static void
e74_cnt(int sym,int cnt,int l,int u)5478 e74_cnt(int sym, int cnt, int l, int u)
5479 {
5480   char buf[64];
5481 
5482   buf[0] = '-';
5483   buf[1] = ' ';
5484   if (l == u)
5485     sprintf(buf + 2, "%d argument(s) present, %d argument(s) expected", cnt, l);
5486   else
5487     sprintf(buf + 2, "%d argument(s) present, %d-%d argument(s) expected", cnt,
5488             l, u);
5489   error(74, 3, gbl.lineno, SYMNAME(sym), buf);
5490 }
5491 
5492 static void
e74_arg(int sym,int pos,char * kwd)5493 e74_arg(int sym, int pos, char *kwd)
5494 {
5495   char buf[128];
5496   int i;
5497   int kwd_len;
5498   char *np;
5499   char *p, *q;
5500 
5501   if (sem.which_pass == 0)
5502     return;
5503   strcpy(buf, "- keyword argument ");
5504   if (kwd != NULL)
5505     strcat(buf, kwd);
5506   else {
5507     kwd = KWDARGSTR(sym);
5508     for (i = 0; TRUE; i++) {
5509       if (*kwd == '*' || *kwd == ' ')
5510         kwd++;
5511       if (*kwd == '#' || *kwd == '\0') {
5512         sprintf(buf + strlen(buf), "position %d", pos + 1);
5513         goto report_;
5514       }
5515       kwd_len = 0;
5516       for (np = kwd; TRUE; np++) {
5517         if (*np == ' ' || *np == '\0')
5518           break;
5519         kwd_len++;
5520       }
5521       if (i == pos)
5522         break;
5523       kwd = np;
5524     }
5525     p = kwd;
5526     q = buf + strlen(buf);
5527     while (kwd_len > 0) {
5528       *q++ = *p++;
5529       --kwd_len;
5530     }
5531     *q = 0;
5532   }
5533 report_:
5534   error(74, 3, gbl.lineno, SYMNAME(sym), buf);
5535 }
5536 
5537 static int
gen_call_class_obj_size(int sptr)5538 gen_call_class_obj_size(int sptr)
5539 {
5540   int ast;
5541   int argt;
5542   int arg;
5543   int func_ast;
5544   int hpf_sym;
5545 
5546   argt = mk_argt(1);
5547   if (SCG(sptr) == SC_DUMMY) {
5548     arg = get_type_descr_arg(gbl.currsub, sptr);
5549   } else {
5550     arg = SDSCG(sptr) ? SDSCG(sptr) : get_static_type_descriptor(sptr);
5551   }
5552 
5553   ARGT_ARG(argt, 0) = mk_id(arg);
5554   DESCUSEDP(sptr, 1);
5555 
5556   hpf_sym = sym_mkfunc_nodesc(mkRteRtnNm(RTE_class_obj_size), DT_INT8);
5557   func_ast = mk_id(hpf_sym);
5558   ast = mk_func_node(A_FUNC, func_ast, 1, argt);
5559   A_DTYPEP(ast, DT_INT8);
5560   return ast;
5561 }
5562 
5563 /* this flag disables an error message in mkexpr1 (semutil.c)
5564  * about assumed-size arrays */
5565 int dont_issue_assumedsize_error = 0;
5566 
5567 /** \brief Handle calls to Predeclared functions.
5568     \param stktop function to call
5569     \param list   arguments to pass to function
5570  */
5571 int
ref_pd(SST * stktop,ITEM * list)5572 ref_pd(SST *stktop, ITEM *list)
5573 {
5574   INT con1, con2;
5575   INT num1[4];
5576   INT res[4];
5577   INT kanj[2];
5578   INT conval = 0;
5579   INT q0, qhalf;
5580   char ch;
5581   int dtype1, dtype2, dtyper, dtyper2;
5582   int count, opc;
5583   int numdim;
5584   INT val[4];
5585   ISZ_T iszval;
5586   int dum;
5587   ITEM *ip1;
5588   int ast, arg1, arg2;
5589   int argt;
5590   int argt_count, argt_extra;
5591   int i;
5592   ADSC *ad;
5593   SST *stkp, *stkp1, *stkp2;
5594   SST *dim;
5595   SST *mask;
5596   int shape1, shape2, shaper;
5597   int tmp;
5598   int hpf_sym; /* hpf-specific sptr, if special name required for
5599                 * the predeclared for hpf
5600                 */
5601   int func_type;
5602   int arrtmp_ast;
5603   char *name;
5604   char tmpnm[64];
5605   int func_ast;
5606   ACL *shape_acl;
5607   ACL *expracl;
5608   int sptr, fsptr, baseptr;
5609   LOGICAL is_whole, is_constant;
5610   int asumsz;
5611   int assumshp;
5612   int adjarr;
5613   int pvar;
5614   int nelems, eltype;
5615   char *sname = NULL;
5616   char verstr[140]; /*140, get_version_str returns max 128 char + pf90 prefix */
5617   FtnRtlEnum rtlRtn;
5618   SPTR pdsym = SST_SYMG(stktop);
5619   int pdtype = PDNUMG(pdsym);
5620   int is_real2_arg_error = 0;
5621 
5622 /* any integer type, or hollerith, or, if -x 51 0x20 not set, real/double */
5623 #define TYPELESS(dt)                     \
5624   (DT_ISINT(dt) || DTY(dt) == TY_HOLL || \
5625    (!XBIT(51, 0x20) && (DTY(dt) == TY_REAL || DTY(dt) == TY_DBLE)))
5626 
5627   dont_issue_assumedsize_error = 0;
5628   SST_CVLENP(stktop, 0);
5629   hpf_sym = 0;
5630   func_type = A_INTR;
5631   /* Count the number of arguments to function */
5632   count = 0;
5633   for (ip1 = list; ip1 != ITEM_END; ip1 = ip1->next) {
5634     count++;
5635     if (SST_IDG(ip1->t.stkp) == S_TRIPLE) {
5636       /* form is e1:e2:e3 */
5637       error(76, 3, gbl.lineno, SYMNAME(pdsym), CNULL);
5638       goto bad_args;
5639     }
5640   }
5641 
5642   argt_count = count;
5643   argt_extra = 0;
5644   shaper = 0;
5645   switch (pdtype) {
5646   case PD_and:
5647   case PD_eqv:
5648   case PD_neqv:
5649   case PD_or:
5650     /* Validate the number of arguments and their data types */
5651     if (count != 2 || get_kwd_args(list, count, KWDARGSTR(pdsym)))
5652       goto bad_args;
5653     dtype1 = SST_DTYPEG(ARG_STK(0));
5654     dtype2 = SST_DTYPEG(ARG_STK(1));
5655     if (!TYPELESS(dtype1) || !TYPELESS(dtype2))
5656       goto bad_args;
5657 
5658     /* Choose size of operation and thus the result from the argument
5659      * having the largest size.  Then cast both arguments to this size.
5660      */
5661     dtype1 = (size_of(dtype1) > 4) ? DT_DWORD : DT_WORD;
5662     dtype2 = (size_of(dtype2) > 4) ? DT_DWORD : DT_WORD;
5663     dtyper = (dtype1 > dtype2) ? dtype1 : dtype2;
5664     (void)casttyp(ARG_STK(0), dtyper);
5665     (void)casttyp(ARG_STK(1), dtyper);
5666     XFR_ARGAST(0);
5667     XFR_ARGAST(1);
5668     break;
5669 
5670   case PD_compl:
5671     /* Validate the number of arguments and their data types */
5672     if (count != 1 || get_kwd_args(list, count, KWDARGSTR(pdsym)))
5673       goto bad_args;
5674     dtype1 = SST_DTYPEG(ARG_STK(0));
5675 
5676     if (!TYPELESS(dtype1))
5677       goto bad_args;
5678 
5679     /* Choose size of operation and thus result from the argument */
5680     if (size_of(dtype1) > 4) {
5681       (void)casttyp(ARG_STK(0), DT_DWORD);
5682       dtyper = DT_DWORD;
5683     } else {
5684       (void)casttyp(ARG_STK(0), DT_WORD);
5685       dtyper = DT_WORD;
5686     }
5687     XFR_ARGAST(0);
5688     break;
5689 
5690   case PD_zext:
5691   case PD_jzext:
5692     if (count != 1 || get_kwd_args(list, count, KWDARGSTR(pdsym)))
5693       goto bad_args;
5694     dtype1 = SST_DTYPEG(ARG_STK(0));
5695     if (!DT_ISINT(dtype1) && !DT_ISLOG(dtype1))
5696       goto bad_args;
5697     (void)mkexpr(ARG_STK(0));
5698     XFR_ARGAST(0);
5699     dtyper = DT_INT;
5700     break;
5701   case PD_izext:
5702     if (count != 1 || get_kwd_args(list, count, KWDARGSTR(pdsym)))
5703       goto bad_args;
5704     dtype1 = SST_DTYPEG(ARG_STK(0));
5705     if (!DT_ISINT(dtype1) && !DT_ISLOG(dtype1))
5706       goto bad_args;
5707     if (size_of(dtype1) > size_of(DT_SINT))
5708       goto bad_args;
5709     (void)mkexpr(ARG_STK(0));
5710     XFR_ARGAST(0);
5711     dtyper = DT_SINT;
5712     break;
5713 
5714   case PD_matmul:
5715     if (count != 2) {
5716       E74_CNT(pdsym, count, 2, 2);
5717       goto call_e74_cnt;
5718     }
5719     if (evl_kwd_args(list, 2, KWDARGSTR(pdsym)))
5720       goto exit_;
5721 
5722     stkp1 = ARG_STK(0); /* matrix_a */
5723     dtyper = SST_DTYPEG(stkp1);
5724     shape1 = SST_SHAPEG(stkp1);
5725     if (shape1 == 0) {
5726       E74_ARG(pdsym, 0, NULL);
5727       goto call_e74_arg;
5728     }
5729 
5730     ast = SST_ASTG(stkp1);
5731     sptr = SST_SYMG(stkp1);
5732 
5733     stkp = ARG_STK(1); /* matrix_b */
5734     dtype2 = SST_DTYPEG(stkp);
5735     shape2 = SST_SHAPEG(stkp);
5736     if (shape2 == 0) {
5737       E74_ARG(pdsym, 1, NULL);
5738       goto call_e74_arg;
5739     }
5740 
5741     /* Recognize and rewrite the idiom MATMUL(TRANSPOSE(...), ...).  At
5742      * present, we only handle the matrix by vector case for real and
5743      * complex.  This is an attempt to improve the performance of spec
5744      * benchmark galgel.
5745      */
5746     if (SST_IDG(stkp1) == S_EXPR && A_TYPEG(ast) == A_INTR)
5747       if (STYPEG(sptr) == ST_PD && PDNUMG(sptr) == PD_transpose)
5748         if (SHD_NDIM(shape1) == 2 && SHD_NDIM(shape2) == 1)
5749           if (DT_ISREAL_ARR(dtyper) || DT_ISCMPLX_ARR(dtyper))
5750             if (DTYG(dtyper) == DTYG(dtype2)) {
5751 
5752               pdsym = getsymbol("matmul_transpose");
5753               ARG_AST(0) = ARGT_ARG(A_ARGSG(ast), 0);
5754               /*SST_ASTP(stkp, A_LOPG(ast));*/
5755             }
5756 
5757     if (DT_ISLOG(DTY(dtyper + 1))) {
5758       if (!DT_ISLOG(DTY(dtype2 + 1))) {
5759         E74_ARG(pdsym, 1, NULL);
5760         goto call_e74_arg;
5761       }
5762     } else if (DT_ISNUMERIC(DTY(dtyper + 1))) {
5763       if (!DT_ISNUMERIC(DTY(dtype2 + 1))) {
5764         E74_ARG(pdsym, 1, NULL);
5765         goto call_e74_arg;
5766       }
5767     }
5768 
5769     switch (SHD_NDIM(shape1)) {
5770     case 1:
5771       if (SHD_NDIM(shape2) != 2) {
5772         E74_ARG(pdsym, 1, NULL);
5773         goto call_e74_arg;
5774       }
5775       /* (n) * (n, k) = (k) */
5776       /* TBD: cmp_bnd_shape(shape1, 1, shape2, 1) */
5777       add_shape_rank(1);
5778       add_shape_spec((int)SHD_LWB(shape2, 1), (int)SHD_UPB(shape2, 1),
5779                      (int)SHD_STRIDE(shape2, 1));
5780       break;
5781     case 2:
5782       switch (SHD_NDIM(shape2)) {
5783       case 1: /* (n, m) * (m) = (n) */
5784         /* TBD: cmp_bnd_shape(shape1, 2, shape2, 1) */
5785         add_shape_rank(1);
5786         add_shape_spec((int)SHD_LWB(shape1, 0), (int)SHD_UPB(shape1, 0),
5787                        (int)SHD_STRIDE(shape1, 0));
5788         break;
5789       case 2: /* (n, m) * (m, k) = (n, k) */
5790         /* TBD: cmp_bnd_shape(shape1, 2, shape2, 1) */
5791         add_shape_rank(2);
5792         add_shape_spec((int)SHD_LWB(shape1, 0), (int)SHD_UPB(shape1, 0),
5793                        (int)SHD_STRIDE(shape1, 0));
5794         add_shape_spec((int)SHD_LWB(shape2, 1), (int)SHD_UPB(shape2, 1),
5795                        (int)SHD_STRIDE(shape2, 1));
5796         break;
5797       default:
5798         E74_ARG(pdsym, 1, NULL);
5799         goto call_e74_arg;
5800       }
5801       break;
5802     default:
5803       E74_ARG(pdsym, 1, NULL);
5804       goto call_e74_arg;
5805     }
5806     shaper = mk_shape();
5807 
5808     /* check data types with respect to the rules of the equivalent binary
5809      * operations.
5810      */
5811     if (DTY(dtyper + 1) < DTY(dtype2 + 1)) {
5812       cngtyp(ARG_STK(0), dtype2);
5813       dtyper = dtype2;
5814       XFR_ARGAST(0);
5815     } else {
5816       cngtyp(ARG_STK(1), dtyper);
5817       XFR_ARGAST(1);
5818     }
5819     break;
5820   case PD_dotproduct:
5821     if (!XBIT(49, 0x40)) /* if xbit set, CM fortran intrinsics allowed */
5822       goto bad_args;
5823   case PD_dot_product:
5824     if (count != 2) {
5825       E74_CNT(pdsym, count, 2, 2);
5826       goto call_e74_cnt;
5827     }
5828     if (evl_kwd_args(list, 2, KWDARGSTR(pdsym)))
5829       goto exit_;
5830     argt_count = 2;
5831     dtype1 = SST_DTYPEG(ARG_STK(0));
5832     if (DTY(dtype1) != TY_ARRAY || rank_of_ast(ARG_AST(0)) != 1) {
5833       E74_ARG(pdsym, 0, NULL);
5834       goto call_e74_arg;
5835     }
5836     dtype2 = SST_DTYPEG(ARG_STK(1));
5837     if (DTY(dtype2) != TY_ARRAY || rank_of_ast(ARG_AST(1)) != 1) {
5838       E74_ARG(pdsym, 1, NULL);
5839       goto call_e74_arg;
5840     }
5841     dtyper = DTY(dtype1 + 1);
5842     if (DT_ISLOG(dtyper)) {
5843       if (!DT_ISLOG(DTY(dtype2 + 1))) {
5844         E74_ARG(pdsym, 1, NULL);
5845         goto call_e74_arg;
5846       }
5847     } else if (DT_ISNUMERIC(DTY(dtyper))) {
5848       if (!DT_ISNUMERIC(DTY(dtype2 + 1))) {
5849         E74_ARG(pdsym, 1, NULL);
5850         goto call_e74_arg;
5851       }
5852     } else {
5853       E74_ARG(pdsym, 1, NULL);
5854       goto call_e74_arg;
5855     }
5856 
5857     /* check data types with respect to the rules of the equivalent binary
5858      * operations.
5859      */
5860     if (dtyper < DTY(dtype2 + 1)) {
5861       cngtyp(ARG_STK(0), dtype2);
5862       dtyper = DTY(dtype2 + 1);
5863       XFR_ARGAST(0);
5864     } else {
5865       cngtyp(ARG_STK(1), dtype1);
5866       XFR_ARGAST(1);
5867     }
5868     if (pdtype == PD_dotproduct) {
5869       INTASTP(pdsym, I_DOT_PRODUCT);
5870       if (flg.standard)
5871         ERR170("dotproduct should be dot_product");
5872     }
5873     break;
5874   case PD_all:
5875   case PD_any:
5876     if (count == 0 || count > 2) {
5877       E74_CNT(pdsym, count, 1, 2);
5878       goto call_e74_cnt;
5879     }
5880     if (evl_kwd_args(list, 2, KWDARGSTR(pdsym)))
5881       goto exit_;
5882     argt_count = 2;
5883     dtype1 = SST_DTYPEG(ARG_STK(0));
5884     if (!DT_ISLOG_ARR(dtype1)) {
5885       E74_ARG(pdsym, 0, NULL);
5886       goto call_e74_arg;
5887     }
5888     dtyper = DTY(dtype1 + 1);
5889     if ((stkp = ARG_STK(1))) { /* dim */
5890       dtype2 = SST_DTYPEG(stkp);
5891       if (!DT_ISINT(dtype2)) {
5892         E74_ARG(pdsym, 1, NULL);
5893         goto call_e74_arg;
5894       }
5895       shaper = reduc_shape((int)A_SHAPEG(ARG_AST(0)), (int)SST_ASTG(stkp),
5896                            (int)STD_PREV(0));
5897       if (shaper)
5898         dtyper = dtype1;
5899     }
5900     break;
5901   case PD_count:
5902     if (count == 0 || count > 2) {
5903       E74_CNT(pdsym, count, 1, 2);
5904       goto call_e74_cnt;
5905     }
5906     if (evl_kwd_args(list, 2, KWDARGSTR(pdsym)))
5907       goto exit_;
5908     argt_count = 2;
5909     dtype1 = SST_DTYPEG(ARG_STK(0));
5910     if (!DT_ISLOG_ARR(dtype1)) {
5911       E74_ARG(pdsym, 0, NULL);
5912       goto call_e74_arg;
5913     }
5914     dtyper = stb.user.dt_int;
5915 
5916     if ((stkp = ARG_STK(1))) { /* dim */
5917       dtype2 = SST_DTYPEG(stkp);
5918       if (!DT_ISINT(dtype2)) {
5919         E74_ARG(pdsym, 1, NULL);
5920         goto call_e74_arg;
5921       }
5922       shaper = reduc_shape((int)A_SHAPEG(ARG_AST(0)), (int)SST_ASTG(stkp),
5923                            (int)STD_PREV(0));
5924       if (shaper)
5925         dtyper = aux.dt_iarray;
5926     }
5927     break;
5928   case PD_findloc:
5929     if (count < 2 || count > 6) {
5930       E74_CNT(pdsym, count, 1, 6);
5931       goto call_e74_cnt;
5932     }
5933     if (evl_kwd_args(list, 6, KWDARGSTR(pdsym)))
5934       goto exit_;
5935 
5936     argt_count = 5;
5937     stkp = ARG_STK(0);
5938     dtype1 = SST_DTYPEG(stkp);
5939     if (!DT_ISNUMERIC_ARR(dtype1) &&
5940         !(DTY(dtype1) == TY_ARRAY &&
5941           (DTYG(dtype1) == TY_CHAR || DTYG(dtype1) == TY_NCHAR))) {
5942       E74_ARG(pdsym, 0, NULL);
5943       goto call_e74_arg;
5944     }
5945 
5946     stkp = ARG_STK(1); /* value */
5947     dtype2 = SST_DTYPEG(stkp);
5948     if ((DT_ISNUMERIC_ARR(dtype1) && !DT_ISNUMERIC(dtype2)) ||
5949         DTYG(dtype1) !=
5950             DTYG(dtype2)) { // TODO: check type against input array ???
5951       E74_ARG(pdsym, 2, NULL);
5952       goto call_e74_arg;
5953     }
5954 
5955     if ((stkp = ARG_STK(4)) && SST_IDG(stkp) == S_CONST) { /* KIND */
5956       dtyper2 = set_kind_result(stkp, DT_INT, TY_INT);
5957       if (!dtyper2) {
5958         E74_ARG(pdsym, 3, NULL);
5959         goto call_e74_arg;
5960       }
5961     } else {
5962       dtyper2 = 0;
5963     }
5964 
5965     dim = 0;
5966     mask = 0;
5967 
5968     if ((stkp = ARG_STK(2))) {
5969       dtype2 = DDTG(SST_DTYPEG(stkp));
5970       if (DT_ISLOG(dtype2)) {
5971         /* mask && no dim */
5972         mask = stkp;
5973         ARG_STK(2) = 0;
5974       } else if (DT_ISINT(dtype2)) {
5975         dim = stkp;
5976       } else {
5977         E74_ARG(pdsym, 3, NULL);
5978         goto call_e74_arg;
5979       }
5980     }
5981 
5982     if (dim) {
5983       ARG_STK(2) = dim;
5984       shaper = reduc_shape((int)A_SHAPEG(ARG_AST(0)), (int)SST_ASTG(stkp),
5985                            (int)STD_PREV(0));
5986       if (shaper)
5987         dtyper = aux.dt_iarray;
5988       else
5989         dtyper = (!dtyper2) ? stb.user.dt_int : dtyper2;
5990       XFR_ARGAST(2);
5991     } else {
5992       dtyper = get_array_dtype(1, (!dtyper2) ? stb.user.dt_int : dtyper2);
5993       ad = AD_DPTR(dtyper);
5994       AD_UPBD(ad, 0) = AD_UPAST(ad, 0) =
5995           mk_isz_cval(rank_of_ast(ARG_AST(0)), astb.bnd.dtype);
5996       ARG_AST(2) = 0;
5997     }
5998 
5999     if ((stkp = ARG_STK(3))) {
6000       dtype2 = DDTG(SST_DTYPEG(stkp));
6001       if (!DT_ISLOG(dtype2) || mask) {
6002         E74_ARG(pdsym, 3, NULL);
6003         goto call_e74_arg;
6004       }
6005       mask = ARG_STK(3);
6006     }
6007 
6008     if (mask) {
6009       ARG_STK(3) = mask;
6010       if (!chkshape(mask, ARG_STK(0), FALSE)) {
6011         E74_ARG(pdsym, 3, NULL);
6012         goto call_e74_arg;
6013       }
6014       ARG_AST(3) = SST_ASTG(mask);
6015     }
6016 
6017     /* back */
6018     if ((stkp = ARG_STK(5))) {
6019       dtype2 = DDTG(SST_DTYPEG(stkp));
6020       if (!DT_ISLOG(dtype2)) {
6021         E74_ARG(pdsym, 3, NULL);
6022         goto call_e74_arg;
6023       }
6024       ARG_AST(4) = SST_ASTG(ARG_STK(5));
6025     } else {
6026       ARG_AST(4) = mk_cval(SCFTN_FALSE, DT_LOG);
6027     }
6028     break;
6029 
6030   case PD_minloc:
6031   case PD_maxloc:
6032     if (count == 0 || count > 4) {
6033       E74_CNT(pdsym, count, 1, 4);
6034       goto call_e74_cnt;
6035     }
6036     if (evl_kwd_args(list, 4, KWDARGSTR(pdsym)))
6037       goto exit_;
6038 
6039     if ((stkp = ARG_STK(3))) { /* KIND */
6040       dtyper2 = set_kind_result(stkp, DT_INT, TY_INT);
6041       if (!dtyper2) {
6042         E74_ARG(pdsym, 3, NULL);
6043         goto call_e74_arg;
6044       }
6045     } else {
6046       dtyper2 = 0;
6047     }
6048 
6049     /* back */
6050     if ((stkp = ARG_STK(4))) {
6051       dtype2 = DDTG(SST_DTYPEG(stkp));
6052       if (!DT_ISLOG(dtype2)) {
6053         E74_ARG(pdsym, 3, NULL);
6054         goto call_e74_arg;
6055       }
6056       ARG_AST(3) = SST_ASTG(ARG_STK(4));
6057     } else {
6058       ARG_AST(3) = mk_cval(SCFTN_FALSE, DT_LOG);
6059     }
6060 
6061     stkp = ARG_STK(0);
6062     argt_count = 4;
6063     dtype1 = SST_DTYPEG(stkp);
6064     if (!DT_ISNUMERIC_ARR(dtype1) &&
6065         !(DTY(dtype1) == TY_ARRAY &&
6066           (DTYG(dtype1) == TY_CHAR || DTYG(dtype1) == TY_NCHAR))) {
6067       E74_ARG(pdsym, 0, NULL);
6068       goto call_e74_arg;
6069     }
6070     if ((stkp = ARG_STK(2))) { /* mask */
6071       dtype2 = DDTG(SST_DTYPEG(stkp));
6072       if (!DT_ISLOG(dtype2)) {
6073         E74_ARG(pdsym, 2, NULL);
6074         goto call_e74_arg;
6075       }
6076       if (!chkshape(stkp, ARG_STK(0), FALSE)) {
6077         E74_ARG(pdsym, 2, NULL);
6078         goto call_e74_arg;
6079       }
6080       XFR_ARGAST(2);
6081     }
6082     if ((stkp = ARG_STK(1))) { /* dim */
6083       dtype2 = SST_DTYPEG(stkp);
6084       if (count == 2 && DT_ISLOG(DDTG(dtype2)) &&
6085           chkshape(stkp, ARG_STK(0), FALSE)) {
6086         XFR_ARGAST(1);
6087         /* shift args over */
6088         ARG_AST(2) = ARG_AST(1); /* mask */
6089         ARG_AST(1) = 0;          /* dim is 'null' */
6090         goto minloc_nodim;
6091       }
6092       if (!DT_ISINT(dtype2)) {
6093         E74_ARG(pdsym, 1, NULL);
6094         goto call_e74_arg;
6095       }
6096       shaper = reduc_shape((int)A_SHAPEG(ARG_AST(0)), (int)SST_ASTG(stkp),
6097                            (int)STD_PREV(0));
6098       if (shaper)
6099         dtyper = aux.dt_iarray;
6100       else
6101         dtyper = (!dtyper2) ? stb.user.dt_int : dtyper2;
6102     } else {
6103     minloc_nodim:
6104       dtyper = get_array_dtype(1, (!dtyper2) ? stb.user.dt_int : dtyper2);
6105       ad = AD_DPTR(dtyper);
6106       AD_UPBD(ad, 0) = AD_UPAST(ad, 0) =
6107           mk_isz_cval(rank_of_ast(ARG_AST(0)), astb.bnd.dtype);
6108     }
6109     break;
6110   case PD_minval:
6111   case PD_maxval:
6112   case PD_product:
6113   case PD_sum:
6114   case PD_norm2:
6115     if (count == 0 || count > 3) {
6116       E74_CNT(pdsym, count, 1, 3);
6117       goto call_e74_cnt;
6118     }
6119 
6120     // norm2 intrinsic does not have a mask arg
6121     argt_count = pdtype == PD_norm2 ? 2 : 3;
6122     if (evl_kwd_args(list, argt_count, KWDARGSTR(pdsym)))
6123       goto exit_;
6124     dtype1 = SST_DTYPEG(ARG_STK(0));
6125     if (!DT_ISNUMERIC_ARR(dtype1)) {
6126       if (pdtype == PD_minval || pdtype == PD_maxval) {
6127         if (!(DTY(dtype1) == TY_ARRAY &&
6128               (DTYG(dtype1) == TY_CHAR || DTYG(dtype1) == TY_NCHAR))) {
6129           E74_ARG(pdsym, 0, NULL);
6130           goto call_e74_arg;
6131         }
6132 
6133       } else {
6134         E74_ARG(pdsym, 0, NULL);
6135         goto call_e74_arg;
6136       }
6137     }
6138     if (pdtype == PD_minval || pdtype == PD_maxval) {
6139       if ((!DT_ISINT_ARR(dtype1) && !DT_ISREAL_ARR(dtype1) &&
6140            !(DTY(dtype1) == TY_ARRAY &&
6141              (DTYG(dtype1) == TY_CHAR || DTYG(dtype1) == TY_NCHAR))) ||
6142           DT_ISLOG_ARR(dtype1)) {
6143         E74_ARG(pdsym, 0, NULL);
6144         goto call_e74_arg;
6145       }
6146     }
6147 
6148     if (pdtype == PD_norm2) {
6149       if (!DT_ISREAL_ARR(dtype1)) {
6150         E74_ARG(pdsym, 0, NULL);
6151         goto call_e74_arg;
6152       }
6153       if (ARG_STK(1)) {
6154         // dim arg
6155         ast = SST_ASTG(ARG_STK(1));
6156         sptr = ast_is_sym(ast) ? memsym_of_ast(ast) : 0;
6157 
6158         // If symbol, disallow if optional dummy arguments used as dim
6159         if (sptr && OPTARGG(sptr)) {
6160           E74_ARG(pdsym, 1, NULL);
6161           goto call_e74_arg;
6162         }
6163       }
6164     }
6165 
6166     dtyper = DTY(dtype1 + 1);
6167     if ((stkp = ARG_STK(2))) { /* mask */
6168       dtype2 = DDTG(SST_DTYPEG(stkp));
6169       if (!DT_ISLOG(dtype2)) {
6170         E74_ARG(pdsym, 2, NULL);
6171         goto call_e74_arg;
6172       }
6173       if (!chkshape(stkp, ARG_STK(0), FALSE)) {
6174         E74_ARG(pdsym, 2, NULL);
6175         goto call_e74_arg;
6176       }
6177       XFR_ARGAST(2);
6178     }
6179     if ((stkp = ARG_STK(1))) { /* dim */
6180       dtype2 = SST_DTYPEG(stkp);
6181       if (!DT_ISINT(dtype2)) {
6182         if (count == 2) {
6183           if (DT_ISLOG(DDTG(dtype2)) && chkshape(stkp, ARG_STK(0), FALSE)) {
6184             XFR_ARGAST(1);
6185             /* shift args over */
6186             ARG_AST(2) = ARG_AST(1); /* mask */
6187             ARG_AST(1) = 0;          /* dim is 'null' */
6188             break;
6189           }
6190         }
6191         E74_ARG(pdsym, 1, NULL);
6192         goto call_e74_arg;
6193       }
6194 
6195       if (rank_of_ast(ARG_AST(0)) != 1) {
6196         shaper = reduc_shape((int)A_SHAPEG(ARG_AST(0)), (int)SST_ASTG(stkp),
6197                              (int)STD_PREV(0));
6198         if (shaper)
6199           dtyper = dtype1;
6200       } else
6201         check_dim_error((int)A_SHAPEG(ARG_AST(0)), (int)SST_ASTG(stkp));
6202     }
6203     break;
6204   case PD_dlbound:
6205     if (!XBIT(49, 0x40)) /* if xbit set, CM fortran intrinsics allowed */
6206       goto bad_args;
6207     pdtype = PD_lbound;
6208     goto lbound_ubound;
6209   case PD_dubound:
6210     if (!XBIT(49, 0x40)) /* if xbit set, CM fortran intrinsics allowed */
6211       goto bad_args;
6212     pdtype = PD_ubound;
6213   /*  fall thru  */
6214   case PD_lbound:
6215   case PD_ubound:
6216   lbound_ubound:
6217     if (count == 0 || count > 3) {
6218       E74_CNT(pdsym, count, 1, 3);
6219       goto call_e74_cnt;
6220     }
6221     if (get_kwd_args(list, 3, KWDARGSTR(pdsym)))
6222       goto exit_;
6223 
6224     if ((stkp = ARG_STK(2))) { /* KIND */
6225       dtyper2 = set_kind_result(stkp, DT_INT, TY_INT);
6226       if (!dtyper2) {
6227         E74_ARG(pdsym, 3, NULL);
6228         goto call_e74_arg;
6229       }
6230     } else {
6231       dtyper2 = 0;
6232     }
6233 
6234     (void)mkarg(ARG_STK(0), &dum);
6235     XFR_ARGAST(0);
6236     argt_count = 2;
6237     dtype1 = SST_DTYPEG(ARG_STK(0));
6238     if (DTY(dtype1) != TY_ARRAY) {
6239       E74_ARG(pdsym, 0, NULL);
6240       goto call_e74_arg;
6241     }
6242 
6243     if (sem.dinit_data) {
6244       int rank;
6245       int ubound[7];
6246       int lbound[7];
6247       SST bndarry;
6248       ACL *argacl;
6249       ACL **r;
6250 
6251       stkp = ARG_STK(0);
6252       ad = AD_DPTR(SST_DTYPEG(stkp));
6253       rank = AD_NUMDIM(
6254           ad); /* rank of array arg, potential upper bound of result array */
6255 
6256       for (i = 0; i < rank; i++) {
6257         ubound[i] = AD_UPAST(ad, i);
6258         lbound[i] = AD_LWAST(ad, i);
6259       }
6260 
6261       sem.arrdim.ndim = 1;
6262       sem.arrdim.ndefer = 0;
6263       sem.bounds[0].lowtype = S_CONST;
6264       sem.bounds[0].lowb = 1;
6265       sem.bounds[0].lwast = 0;
6266       sem.bounds[0].uptype = S_CONST;
6267       sem.bounds[0].upb = rank;
6268       sem.bounds[0].upast = mk_cval(rank, stb.user.dt_int);
6269       dtyper = mk_arrdsc();
6270       DTY(dtyper + 1) = (!dtyper2) ? stb.user.dt_int : dtyper2;
6271 
6272       argacl = GET_ACL(15);
6273 
6274       if (count == 2) {
6275         dtyper = stb.user.dt_int;
6276       }
6277 
6278       gen_init_intrin_call(stktop, pdsym, count, dtyper, FALSE);
6279       return 0;
6280     }
6281 
6282     shape1 = A_SHAPEG(ARG_AST(0));
6283     count = SHD_NDIM(shape1); /* rank of array arg */
6284     argt_count = count * 2 + 2;
6285     adjarr = 0;
6286     asumsz = 0;
6287     assumshp = 0;
6288     arg1 = ARG_AST(0);
6289     switch (A_TYPEG(arg1)) {
6290     case A_ID:
6291       adjarr = assumshp = asumsz = A_SPTRG(arg1);
6292       if (SCG(asumsz) != SC_DUMMY || !ASUMSZG(asumsz))
6293         asumsz = 0;
6294       if (SCG(assumshp) != SC_DUMMY || !ASSUMSHPG(assumshp))
6295         assumshp = 0;
6296       if (SCG(adjarr) != SC_DUMMY || !ADJARRG(adjarr))
6297         adjarr = 0;
6298       is_whole = TRUE;
6299       break;
6300     case A_MEM:
6301       if (A_SHAPEG(A_PARENTG(arg1))) {
6302         is_whole = FALSE;
6303       } else {
6304         is_whole = TRUE;
6305       }
6306       break;
6307     default:
6308       is_whole = FALSE;
6309       break;
6310     }
6311     sptr = find_pointer_variable(arg1);
6312     if (sptr && (POINTERG(sptr) || (ALLOCG(sptr) && SDSCG(sptr)))) {
6313       if ((stkp = ARG_STK(1))) {
6314         /* pghpf...bound(dim, static_desciptor) */
6315         (void)mkexpr(stkp);
6316         XFR_ARGAST(1);
6317         dtype2 = SST_DTYPEG(stkp);
6318         if (!DT_ISINT(dtype2)) {
6319           E74_ARG(pdsym, 1, NULL);
6320           goto call_e74_arg;
6321         }
6322         if (XBIT(68, 0x1) && XBIT(68, 0x2))
6323           dtyper = (!dtyper2) ? DT_INT8 : dtyper2;
6324         else
6325           dtyper = (!dtyper2) ? stb.user.dt_int : dtyper2;
6326         shaper = 0;
6327         ARG_AST(0) = mk_bnd_int(ARG_AST(1)); /* dim */
6328         ARG_AST(1) = check_member(arg1, mk_id(SDSCG(sptr)));
6329         /* static descriptor */
6330         func_type = A_FUNC;
6331         if (pdtype == PD_lbound) {
6332           switch (dtyper2) {
6333           case 0:
6334             rtlRtn = RTE_lboundDsc;
6335             break;
6336           case DT_BINT:
6337             rtlRtn = RTE_lbound1Dsc;
6338             break;
6339           case DT_SINT:
6340             rtlRtn = RTE_lbound2Dsc;
6341             break;
6342           case DT_INT4:
6343             rtlRtn = RTE_lbound4Dsc;
6344             break;
6345           case DT_INT8:
6346             rtlRtn = RTE_lbound8Dsc;
6347             break;
6348           default:
6349             error(155, 3, gbl.lineno, SYMNAME(gbl.currsub),
6350                   "invalid kind argument for ubound");
6351           }
6352         } else {
6353           switch (dtyper2) {
6354           case 0:
6355             rtlRtn = RTE_uboundDsc;
6356             break;
6357           case DT_BINT:
6358             rtlRtn = RTE_ubound1Dsc;
6359             break;
6360           case DT_SINT:
6361             rtlRtn = RTE_ubound2Dsc;
6362             break;
6363           case DT_INT4:
6364             rtlRtn = RTE_ubound4Dsc;
6365             break;
6366           case DT_INT8:
6367             rtlRtn = RTE_ubound8Dsc;
6368             break;
6369           default:
6370             error(155, 3, gbl.lineno, SYMNAME(gbl.currsub),
6371                   "invalid kind argument for lbound");
6372           }
6373         }
6374 
6375         /* FIXME: there is no [lu]bound[1234]*Dsc (ENTPGHPF)routines */
6376         if (XBIT(68, 0x1))
6377           hpf_sym = sym_mkfunc_nodesc(mkRteRtnNm(rtlRtn),
6378                                       (!dtyper2) ? dtyper : dtyper2);
6379         else
6380           hpf_sym = sym_mkfunc_nodesc(mkRteRtnNm(rtlRtn),
6381                                       (!dtyper2) ? dtyper : dtyper2);
6382 
6383         arrtmp_ast = 0;
6384         argt_count = 2;
6385         goto gen_call;
6386       }
6387 
6388       /* pghpf...bounda(temp, sd) */
6389 
6390       if (XBIT(68, 0x1) && XBIT(68, 0x2))
6391         dtyper = (!dtyper2) ? get_array_dtype(1, DT_INT8)
6392                             : get_array_dtype(1, dtyper2);
6393       else
6394         dtyper = (!dtyper2) ? get_array_dtype(1, stb.user.dt_int)
6395                             : get_array_dtype(1, dtyper2);
6396       ad = AD_DPTR(dtyper);
6397       AD_UPBD(ad, 0) = AD_UPAST(ad, 0) =
6398           mk_isz_cval(rank_of_ast(ARG_AST(0)), astb.bnd.dtype);
6399       tmp = get_arr_temp(dtyper, FALSE, FALSE, FALSE);
6400       arrtmp_ast = mk_id(tmp);
6401       shaper = A_SHAPEG(arrtmp_ast);
6402       ARG_AST(0) = arrtmp_ast; /* first argument is temp */
6403       ARG_AST(1) = check_member(arg1, mk_id(SDSCG(sptr)));
6404       /* static descriptor */
6405       func_type = A_CALL;
6406       if (!XBIT(68, 0x1) || XBIT(68, 0x2)) {
6407         if (pdtype == PD_lbound) {
6408           switch (dtyper2) {
6409           case 0:
6410             rtlRtn = RTE_lboundaDsc;
6411             break;
6412           case DT_BINT:
6413             rtlRtn = RTE_lbounda1Dsc;
6414             break;
6415           case DT_SINT:
6416             rtlRtn = RTE_lbounda2Dsc;
6417             break;
6418           case DT_INT4:
6419             rtlRtn = RTE_lbounda4Dsc;
6420             break;
6421           case DT_INT8:
6422             rtlRtn = RTE_lbounda8Dsc;
6423             break;
6424           default:
6425             error(155, 3, gbl.lineno, SYMNAME(gbl.currsub),
6426                   "invalid kind argument for lbound");
6427           }
6428         } else {
6429           switch (dtyper2) {
6430           case 0:
6431             rtlRtn = RTE_uboundaDsc;
6432             break;
6433           case DT_BINT:
6434             rtlRtn = RTE_ubounda1Dsc;
6435             break;
6436           case DT_SINT:
6437             rtlRtn = RTE_ubounda2Dsc;
6438             break;
6439           case DT_INT4:
6440             rtlRtn = RTE_ubounda4Dsc;
6441             break;
6442           case DT_INT8:
6443             rtlRtn = RTE_ubounda8Dsc;
6444             break;
6445           default:
6446             error(155, 3, gbl.lineno, SYMNAME(gbl.currsub),
6447                   "invalid kind argument for ubound");
6448           }
6449         }
6450       } else {
6451         /* -Mlarge_arrays, but the result is default integer */
6452         if (pdtype == PD_lbound) {
6453           switch (dtyper2) {
6454           case 0:
6455             rtlRtn = RTE_lboundazDsc;
6456             break;
6457           case DT_BINT:
6458             rtlRtn = RTE_lboundaz1Dsc;
6459             break;
6460           case DT_SINT:
6461             rtlRtn = RTE_lboundaz2Dsc;
6462             break;
6463           case DT_INT4:
6464             rtlRtn = RTE_lboundaz4Dsc;
6465             break;
6466           case DT_INT8:
6467             rtlRtn = RTE_lboundaz8Dsc;
6468             break;
6469           default:
6470             error(155, 3, gbl.lineno, SYMNAME(gbl.currsub),
6471                   "invalid kind argument for lbound");
6472           }
6473         } else {
6474           switch (dtyper2) {
6475           case 0:
6476             rtlRtn = RTE_uboundazDsc;
6477             break;
6478           case DT_BINT:
6479             rtlRtn = RTE_uboundaz1Dsc;
6480             break;
6481           case DT_SINT:
6482             rtlRtn = RTE_uboundaz2Dsc;
6483             break;
6484           case DT_INT4:
6485             rtlRtn = RTE_uboundaz4Dsc;
6486             break;
6487           case DT_INT8:
6488             rtlRtn = RTE_uboundaz8Dsc;
6489             break;
6490           default:
6491             error(155, 3, gbl.lineno, SYMNAME(gbl.currsub),
6492                   "invalid kind argument for ubound");
6493           }
6494         }
6495       }
6496 
6497       hpf_sym = sym_mkfunc_nodesc(mkRteRtnNm(rtlRtn), DT_NONE);
6498       ast = begin_call(func_type, hpf_sym, 2);
6499       add_arg(ARG_AST(0));
6500       add_arg(ARG_AST(1));
6501       /* call statement is generated, result is the temporary */
6502       (void)add_stmt(ast);
6503       ast = arrtmp_ast;
6504       goto expr_val;
6505     }
6506 
6507     if ((stkp = ARG_STK(1))) {
6508       /* f90...bound(rank, dim, l1, u1, l1, u2, ..., l<rank>, u<rank>) */
6509       (void)mkexpr(stkp);
6510       XFR_ARGAST(1);
6511       dtype2 = SST_DTYPEG(stkp);
6512       if (!DT_ISINT(dtype2)) {
6513         E74_ARG(pdsym, 1, NULL);
6514         goto call_e74_arg;
6515       }
6516       if (XBIT(68, 0x1) && XBIT(68, 0x2))
6517         dtyper = (!dtyper2) ? DT_INT8 : dtyper2;
6518       else
6519         dtyper = (!dtyper2) ? stb.user.dt_int : dtyper2;
6520       shaper = 0;
6521       if ((ast = A_ALIASG(ARG_AST(1)))) {
6522         /* dim is a constant */
6523         i = get_int_cval(A_SPTRG(ast));
6524         if (i < 1 || i > count) {
6525           error(423, 3, gbl.lineno, NULL, NULL);
6526           i = 1;
6527         }
6528         if (pdtype == PD_lbound) {
6529           if (is_whole) {
6530             if (asumsz != 0 && i == count)
6531               ast = astb.bnd.one;
6532             else {
6533               ast = lbound_of_shape(shape1, i - 1);
6534               if (ast == 0 && SHD_LWB(shape1, i - 1)) {
6535                 ast = SHD_LWB(shape1, i - 1);
6536               }
6537             }
6538           } else
6539             ast = astb.bnd.one;
6540         } else { /* ubound/dubound */
6541           if (is_whole) {
6542             if (asumsz != 0 && i == count) {
6543               error(84, 3, gbl.lineno, SYMNAME(asumsz),
6544                     "- ubound of assumed size array is unknown");
6545               ast = astb.bnd.one;
6546             } else {
6547               ast = ubound_of_shape(shape1, i - 1);
6548               if (ast == 0 && SHD_UPB(shape1, i - 1)) {
6549                 ast = SHD_UPB(shape1, i - 1);
6550               }
6551             }
6552           }
6553           /*
6554            * Before computing the extent, ensure that an upper bound
6555            * for this dimension exists.  The upper bound may be zero
6556            * if the array is an argument declared in an interface
6557            * within a module.
6558            */
6559           else if (SHD_UPB(shape1, i - 1)) {
6560             ast = extent_of_shape(shape1, i - 1);
6561             goto expr_val;
6562           } else
6563             ast = 0;
6564         }
6565         if (ast) {
6566           if (A_ALIASG(ast)) {
6567             ast = A_ALIASG(ast);
6568             iszval = get_isz_cval(A_SPTRG(ast));
6569             goto const_isz_val;
6570           }
6571           if (A_DTYPEG(ast) != dtyper)
6572             ast = mk_convert(ast, dtyper);
6573         }
6574         if (pdtype == PD_lbound) {
6575           switch (dtyper2) {
6576           case 0:
6577             rtlRtn = RTE_lb;
6578             break;
6579           case DT_BINT:
6580             rtlRtn = RTE_lb1;
6581             break;
6582           case DT_SINT:
6583             rtlRtn = RTE_lb2;
6584             break;
6585           case DT_INT4:
6586             rtlRtn = RTE_lb4;
6587             break;
6588           case DT_INT8:
6589             rtlRtn = RTE_lb8;
6590             break;
6591           default:
6592             error(155, 3, gbl.lineno, SYMNAME(gbl.currsub),
6593                   "invalid kind argument for lbound");
6594           }
6595         } else {
6596           switch (dtyper2) {
6597           case 0:
6598             rtlRtn = RTE_ub;
6599             break;
6600           case DT_BINT:
6601             rtlRtn = RTE_ub1;
6602             break;
6603           case DT_SINT:
6604             rtlRtn = RTE_ub2;
6605             break;
6606           case DT_INT4:
6607             rtlRtn = RTE_ub4;
6608             break;
6609           case DT_INT8:
6610             rtlRtn = RTE_ub8;
6611             break;
6612           default:
6613             error(155, 3, gbl.lineno, SYMNAME(gbl.currsub),
6614                   "invalid kind argument for ubound");
6615           }
6616         }
6617         if (adjarr != 0) {
6618           /* If this expression uses an adjustable dummy array, then
6619            * generate the intrinsic lbound/ubound call instead of a rewritten
6620            * bound function call.
6621            * Otherwise, the call may be wrongfully placed in an early
6622            * specification statement. This intrinsic call may be rewritten later
6623            * but after we handle the early specification statements.
6624            */
6625           argt_count = 2;
6626           goto gen_call;
6627         }
6628         if (sem.interface || (assumshp != 0 && sem.which_pass == 0)) {
6629           /*
6630            * if this expression is rewritten (i.e., when this
6631            * function specified by this interface is invoked),
6632            * ast_rewrite() will select the bound based on the
6633            * constant dim value.
6634            */
6635           argt_count = 2;
6636 
6637           (void)sym_mkfunc_nodesc(mkRteRtnNm(rtlRtn), stb.user.dt_int);
6638           goto gen_call;
6639         }
6640         /* ast is 0 => must determine the bound based on the lower and
6641          * upper bound of the specified dimension; call the function
6642          * with (rank = 1, dim = 1, lb<dim>, ub<dim>).
6643          */
6644         if (assumshp != 0 && sem.which_pass != 0) {
6645           if (pdtype == PD_lbound) {
6646             ast = SHD_LWB(shape1, i - 1);
6647             if (A_TYPEG(ast) == A_CNST && get_int_cval(A_SPTRG(ast)) != 1) {
6648               /* assumed shape array with a constant lb != 1
6649                * dpm_out.c:set_assumed_bounds my reset the
6650                * lb as per the F90 Standard section 13.13.52.
6651                * The following insures that the correct lb
6652                * is reported.
6653                */
6654               ast = ADD_LWAST(dtype1, i - 1);
6655             }
6656           } else {
6657             ast = SHD_UPB(shape1, i - 1);
6658           }
6659           if (ast) {
6660             if (A_DTYPEG(ast) != dtyper)
6661               ast = mk_convert(ast, dtyper);
6662             goto lbound_ret;
6663           }
6664         }
6665 
6666         hpf_sym = sym_mkfunc_nodesc(mkRteRtnNm(rtlRtn), dtyper);
6667         ast = begin_call(A_FUNC, hpf_sym, 4);
6668         add_arg(astb.bnd.one);
6669         add_arg(astb.bnd.one);
6670         add_arg(check_member(arg1, SHD_LWB(shape1, i - 1)));
6671         add_arg(check_member(arg1, SHD_UPB(shape1, i - 1)));
6672         A_DTYPEP(ast, dtyper);
6673         goto lbound_ret;
6674       }
6675       ARG_AST(0) = mk_isz_cval((INT)count, astb.bnd.dtype); /* rank */
6676       /* ARG_AST(1) = ARG_AST(1);			   dim */
6677       func_type = A_FUNC;
6678       if (pdtype == PD_lbound)
6679         rtlRtn = RTE_lb;
6680       else {
6681         if (asumsz != 0 && count == 1)
6682           error(84, 3, gbl.lineno, SYMNAME(asumsz),
6683                 "- ubound of assumed size array is unknown");
6684         rtlRtn = RTE_ub;
6685       }
6686 
6687       hpf_sym = sym_mkfunc_nodesc(mkRteRtnNm(rtlRtn), dtyper);
6688       arrtmp_ast = 0;
6689     } else {
6690       /*f90...bounda(temp, rank, l1, u1, l1, u2, ..., l<rank>, u<rank>) */
6691       if (XBIT(68, 0x1) && XBIT(68, 0x2))
6692         dtyper = (!dtyper2) ? get_array_dtype(1, DT_INT8)
6693                             : get_array_dtype(1, dtyper2);
6694       else
6695         dtyper = (!dtyper2) ? get_array_dtype(1, stb.user.dt_int)
6696                             : get_array_dtype(1, dtyper2);
6697       ad = AD_DPTR(dtyper);
6698       AD_UPBD(ad, 0) = AD_UPAST(ad, 0) =
6699           mk_isz_cval(rank_of_ast(ARG_AST(0)), astb.bnd.dtype);
6700       tmp = get_arr_temp(dtyper, FALSE, FALSE, FALSE);
6701       arrtmp_ast = mk_id(tmp);
6702       shaper = A_SHAPEG(arrtmp_ast);
6703       ARG_AST(0) = arrtmp_ast; /* first argument is temp */
6704       ARG_AST(1) = mk_isz_cval((INT)count, astb.bnd.dtype); /* rank */
6705       func_type = A_CALL;
6706       if (!XBIT(68, 0x1) || XBIT(68, 0x2)) {
6707         if (pdtype == PD_lbound) {
6708           switch (dtyper2) {
6709           case 0:
6710             rtlRtn = RTE_lba;
6711             break;
6712           case DT_BINT:
6713             rtlRtn = RTE_lba1;
6714             break;
6715           case DT_SINT:
6716             rtlRtn = RTE_lba2;
6717             break;
6718           case DT_INT4:
6719             rtlRtn = RTE_lba4;
6720             break;
6721           case DT_INT8:
6722             rtlRtn = RTE_lba8;
6723             break;
6724           default:
6725             error(155, 3, gbl.lineno, SYMNAME(gbl.currsub),
6726                   "invalid kind argument for lbound");
6727           }
6728         } else {
6729           if (asumsz != 0)
6730             error(84, 3, gbl.lineno, SYMNAME(asumsz),
6731                   "- ubound of assumed size array is unknown");
6732           switch (dtyper2) {
6733           case 0:
6734             rtlRtn = RTE_uba;
6735             break;
6736           case DT_BINT:
6737             rtlRtn = RTE_uba1;
6738             break;
6739           case DT_SINT:
6740             rtlRtn = RTE_uba2;
6741             break;
6742           case DT_INT4:
6743             rtlRtn = RTE_uba4;
6744             break;
6745           case DT_INT8:
6746             rtlRtn = RTE_uba8;
6747             break;
6748           default:
6749             error(155, 3, gbl.lineno, SYMNAME(gbl.currsub),
6750                   "invalid kind argument for ubound");
6751           }
6752         }
6753       } else {
6754         /* -Mlarge_arrays, but the result is default integer */
6755         if (pdtype == PD_lbound) {
6756           switch (dtyper2) {
6757           case 0:
6758             rtlRtn = RTE_lbaz;
6759             break;
6760           case DT_BINT:
6761             rtlRtn = RTE_lbaz1;
6762             break;
6763           case DT_SINT:
6764             rtlRtn = RTE_lbaz2;
6765             break;
6766           case DT_INT4:
6767             rtlRtn = RTE_lbaz4;
6768             break;
6769           case DT_INT8:
6770             rtlRtn = RTE_lbaz8;
6771             break;
6772           default:
6773             error(155, 3, gbl.lineno, SYMNAME(gbl.currsub),
6774                   "invalid kind argument for lbound");
6775           }
6776         } else {
6777           if (asumsz != 0)
6778             error(84, 3, gbl.lineno, SYMNAME(asumsz),
6779                   "- ubound of assumed size array is unknown");
6780           switch (dtyper2) {
6781           case 0:
6782             rtlRtn = RTE_ubaz;
6783             break;
6784           case DT_BINT:
6785             rtlRtn = RTE_ubaz1;
6786             break;
6787           case DT_SINT:
6788             rtlRtn = RTE_ubaz2;
6789             break;
6790           case DT_INT4:
6791             rtlRtn = RTE_ubaz4;
6792             break;
6793           case DT_INT8:
6794             rtlRtn = RTE_ubaz8;
6795             break;
6796           default:
6797             error(155, 3, gbl.lineno, SYMNAME(gbl.currsub),
6798                   "invalid kind argument for ubound");
6799           }
6800         }
6801       }
6802 
6803       hpf_sym = sym_mkfunc_nodesc(mkRteRtnNm(rtlRtn), DT_NONE);
6804     }
6805     ast = begin_call(func_type, hpf_sym, argt_count);
6806     add_arg(ARG_AST(0));
6807     add_arg(ARG_AST(1));
6808     for (i = 0; i < count; i++) {
6809       if (is_whole) {
6810         if (assumshp != 0 && A_TYPEG(SHD_LWB(shape1, i)) == A_CNST &&
6811             get_int_cval(A_SPTRG(SHD_LWB(shape1, i))) != 1) {
6812           /* assumed shape array with a constant lb != 1
6813            * dpm_out.c:set_assumed_bounds my reset the
6814            * lb as per the F90 Standard section 13.13.52.
6815            * The following insures that the correct lb
6816            * is reported.
6817            */
6818           add_arg(ADD_LWAST(dtype1, i));
6819         } else {
6820           add_arg(SHD_LWB(shape1, i));
6821         }
6822       } else {
6823         add_arg(mk_cval((INT)1, astb.bnd.dtype));
6824       }
6825       if (is_whole) {
6826         if (i < count - 1)
6827           add_arg(SHD_UPB(shape1, i));
6828         else if (asumsz != 0)
6829           add_arg(astb.ptr0);
6830         else
6831           add_arg(SHD_UPB(shape1, i));
6832       } else
6833         add_arg(extent_of_shape(shape1, i));
6834     }
6835     if (arrtmp_ast) {
6836       /* call statement is generated, result is the temporary */
6837       (void)add_stmt(ast);
6838       ast = arrtmp_ast;
6839     } else
6840       A_DTYPEP(ast, dtyper);
6841   lbound_ret:
6842     goto expr_val;
6843 
6844   case PD_cshift:
6845     if (XBIT(49, 0x40)) { /* if xbit set, CM fortran intrinsics allowed */
6846       argpos_t swap;
6847       if (count != 3) {
6848         E74_CNT(pdsym, count, 3, 3);
6849         goto call_e74_cnt;
6850       }
6851       if (evl_kwd_args(list, 3, "array dim shift"))
6852         goto exit_;
6853       /* array dim shift --> array shift dim */
6854       swap = sem.argpos[1];          /* dim */
6855       sem.argpos[1] = sem.argpos[2]; /* shift */
6856       sem.argpos[2] = swap;          /* dim */
6857     } else if (count < 2 || count > 3) {
6858       E74_CNT(pdsym, count, 2, 3);
6859       goto call_e74_cnt;
6860     } else if (evl_kwd_args(list, 3, KWDARGSTR(pdsym)))
6861       goto exit_;
6862     argt_count = 3;
6863     dtyper = SST_DTYPEG(ARG_STK(0));
6864     if (DTY(dtyper) != TY_ARRAY) {
6865       E74_ARG(pdsym, 0, NULL);
6866       goto call_e74_arg;
6867     }
6868     shaper = A_SHAPEG(ARG_AST(0));
6869 
6870     if ((stkp = ARG_STK(2))) { /* dim */
6871       dtype2 = SST_DTYPEG(stkp);
6872       if (!DT_ISINT(dtype2) && !DT_ISLOG(dtype2)) {
6873         E74_ARG(pdsym, 2, NULL);
6874         goto call_e74_arg;
6875       }
6876     } else
6877       ARG_AST(2) = astb.i1;
6878 
6879     stkp = ARG_STK(1); /* shift */
6880     dtype1 = SST_DTYPEG(stkp);
6881     dtype2 = DDTG(dtype1);
6882     if (!DT_ISINT(dtype2) && !DT_ISLOG(dtype2)) {
6883       E74_ARG(pdsym, 1, NULL);
6884       goto call_e74_arg;
6885     }
6886     if (DTY(dtype1) != TY_ARRAY ||
6887         rank_of_ast(ARG_AST(1)) == (SHD_NDIM(shaper) - 1))
6888       /* legal cases */;
6889     else {
6890       E74_ARG(pdsym, 1, NULL);
6891       goto call_e74_arg;
6892     }
6893     break;
6894   case PD_eoshift:
6895     if (XBIT(49, 0x40)) { /* if xbit set, CM fortran intrinsics allowed */
6896       argpos_t swap;
6897       if (count < 3 || count > 4) {
6898         E74_CNT(pdsym, count, 3, 4);
6899         goto call_e74_cnt;
6900       }
6901       if (evl_kwd_args(list, 4, "array dim shift *boundary"))
6902         goto exit_;
6903       /* array dim shift boundary --> array shift boundary dim */
6904       swap = sem.argpos[1];          /* dim */
6905       sem.argpos[1] = sem.argpos[2]; /* shift */
6906       sem.argpos[2] = sem.argpos[3]; /* boundary */
6907       sem.argpos[3] = swap;          /* dim */
6908     } else if (count < 2 || count > 4) {
6909       E74_CNT(pdsym, count, 2, 4);
6910       goto call_e74_cnt;
6911     } else if (evl_kwd_args(list, 4, KWDARGSTR(pdsym)))
6912       goto exit_;
6913     argt_count = 4;
6914     dtyper = SST_DTYPEG(ARG_STK(0));
6915     if (DTY(dtyper) != TY_ARRAY) {
6916       E74_ARG(pdsym, 0, NULL);
6917       goto call_e74_arg;
6918     }
6919     shaper = A_SHAPEG(ARG_AST(0));
6920 
6921     if ((stkp = ARG_STK(3))) { /* dim */
6922       dtype2 = SST_DTYPEG(stkp);
6923       if (!DT_ISINT(dtype2) && !DT_ISLOG(dtype2)) {
6924         E74_ARG(pdsym, 3, NULL);
6925         goto call_e74_arg;
6926       }
6927     } else
6928       ARG_AST(3) = astb.i1;
6929 
6930     stkp = ARG_STK(1); /* shift */
6931     dtype1 = SST_DTYPEG(stkp);
6932     dtype2 = DDTG(dtype1);
6933     if (!DT_ISINT(dtype2) && !DT_ISLOG(dtype2)) {
6934       E74_ARG(pdsym, 1, NULL);
6935       goto call_e74_arg;
6936     }
6937     if (DTY(dtype1) != TY_ARRAY ||
6938         rank_of_ast(ARG_AST(1)) == (SHD_NDIM(shaper) - 1))
6939       /* legal cases */;
6940     else {
6941       E74_ARG(pdsym, 1, NULL);
6942       goto call_e74_arg;
6943     }
6944 
6945     if ((stkp = ARG_STK(2))) { /* boundary */
6946       dtype1 = SST_DTYPEG(stkp);
6947       dtype2 = DDTG(dtype1);
6948       if (dtype2 != DDTG(dtyper)) {
6949         E74_ARG(pdsym, 2, NULL);
6950         goto call_e74_arg;
6951       }
6952       if (DTY(dtype1) != TY_ARRAY ||
6953           rank_of_ast(ARG_AST(2)) == (SHD_NDIM(shaper) - 1))
6954         /* legal cases */;
6955       else {
6956         E74_ARG(pdsym, 2, NULL);
6957         goto call_e74_arg;
6958       }
6959     }
6960     break;
6961   case PD_number_of_processors:
6962     if (count > 1) {
6963       E74_CNT(pdsym, count, 0, 1);
6964       goto call_e74_cnt;
6965     }
6966     if (evl_kwd_args(list, 1, KWDARGSTR(pdsym)))
6967       goto exit_;
6968     dtyper = stb.user.dt_int;
6969     if ((stkp = ARG_STK(0))) { /* dim */
6970       dtype1 = SST_DTYPEG(stkp);
6971       if (!DT_ISINT(dtype1)) {
6972         E74_ARG(pdsym, 0, NULL);
6973         goto call_e74_arg;
6974       }
6975 
6976       hpf_sym = sym_mkfunc_nodesc(mkRteRtnNm(RTE_number_of_processors),
6977                                   stb.user.dt_int);
6978       argt_count = 2;
6979       ARG_AST(1) = mk_cval(size_of(dtype1), DT_INT);
6980       break;
6981     }
6982     /* something hpf-specific here. */
6983     hpf_sym = sym_mknproc();
6984     ast = mk_id(hpf_sym);
6985     SST_IDP(stktop, S_EXPR);
6986     SST_DTYPEP(stktop, dtyper);
6987     SST_SHAPEP(stktop, 0);
6988     SST_ASTP(stktop, ast);
6989     return 1;
6990   case PD_ran:
6991     if (count != 1)
6992       goto bad_args;
6993     if (get_kwd_args(list, 1, KWDARGSTR(pdsym)))
6994       goto bad_args;
6995     if (!is_varref(ARG_STK(0)) || SST_DTYPEG(ARG_STK(0)) != DT_INT) {
6996       goto bad_args;
6997     }
6998     (void)mkarg(ARG_STK(0), &dum);
6999     dtyper = stb.user.dt_real;
7000     XFR_ARGAST(0);
7001     sptr = sym_of_ast(ARG_AST(0)); /*  intent OUT arg */
7002     ADDRTKNP(sptr, 1);
7003     break;
7004   case PD_secnds:
7005     if (count != 1) {
7006       goto bad_args;
7007     }
7008     if (get_kwd_args(list, 1, KWDARGSTR(pdsym)))
7009       goto bad_args;
7010     dtype1 = SST_DTYPEG(ARG_STK(0));
7011     if (dtype1 == DT_FLOAT) {
7012       (void)mkexpr(ARG_STK(0));
7013       dtyper = DT_FLOAT;
7014     } else if (dtype1 == DT_DBLE) {
7015       (void)mkexpr(ARG_STK(0));
7016       dtyper = DT_DBLE;
7017     } else {
7018       goto bad_args;
7019     }
7020     XFR_ARGAST(0);
7021     break;
7022   case PD_shift:
7023     /* Validate the number of arguments and their data types */
7024     if (count != 2)
7025       goto bad_args;
7026     if (get_kwd_args(list, count, KWDARGSTR(pdsym)))
7027       goto bad_args;
7028     dtyper = SST_DTYPEG(ARG_STK(0));
7029     if (!TYPELESS(dtyper) || !DT_ISINT(SST_DTYPEG(ARG_STK(1)))) {
7030       goto bad_args;
7031     }
7032     /*
7033        Choose size of operation and thus the result from the first
7034      * argument having the largest size.  Then cast first argument
7035      * to this size.
7036      */
7037     dtyper = (size_of(dtyper) > 4) ? DT_DWORD : DT_WORD;
7038     (void)casttyp(ARG_STK(0), dtyper);
7039     XFR_ARGAST(0);
7040     (void)chktyp(ARG_STK(1), DT_INT, FALSE);
7041     XFR_ARGAST(1);
7042     break;
7043   case PD_transpose:
7044     if (count != 1) {
7045       E74_CNT(pdsym, count, 1, 1);
7046       goto call_e74_cnt;
7047     }
7048     if (evl_kwd_args(list, 1, KWDARGSTR(pdsym)))
7049       goto exit_;
7050     dtyper = SST_DTYPEG(ARG_STK(0));
7051     shaper = A_SHAPEG(ARG_AST(0));
7052     if (shaper == 0 || SHD_NDIM(shaper) != 2) {
7053       E74_ARG(pdsym, 0, NULL);
7054       goto call_e74_arg;
7055     }
7056     add_shape_rank(2);
7057     add_shape_spec((int)SHD_LWB(shaper, 1), (int)SHD_UPB(shaper, 1),
7058                    (int)SHD_STRIDE(shaper, 1));
7059     add_shape_spec((int)SHD_LWB(shaper, 0), (int)SHD_UPB(shaper, 0),
7060                    (int)SHD_STRIDE(shaper, 0));
7061     shaper = mk_shape();
7062     break;
7063   case PD_spread:
7064     if (count != 3) {
7065       E74_CNT(pdsym, count, 3, 3);
7066       goto call_e74_cnt;
7067     }
7068     if (evl_kwd_args(list, 3, KWDARGSTR(pdsym)))
7069       goto exit_;
7070 
7071     stkp = ARG_STK(0); /* source */
7072     shape1 = SST_SHAPEG(stkp);
7073     if (shape1 && SHD_NDIM(shape1) == 7) {
7074       E74_ARG(pdsym, 0, NULL);
7075       goto call_e74_arg;
7076     }
7077     dtype1 = SST_DTYPEG(stkp);
7078     /* assertion: it shouldn't matter that the result dtype doesn't have
7079      * the correct number of bounds.
7080      */
7081     dtyper = get_array_dtype(1, (int)DDTG(dtype1));
7082 
7083     if (!DT_ISINT(SST_DTYPEG(ARG_STK(2)))) { /* ncopies */
7084       E74_ARG(pdsym, 2, NULL);
7085       goto call_e74_arg;
7086     }
7087 
7088     stkp = ARG_STK(1); /* dim */
7089     dtype2 = SST_DTYPEG(stkp);
7090     if (!DT_ISINT(dtype2)) {
7091       E74_ARG(pdsym, 1, NULL);
7092       goto call_e74_arg;
7093     }
7094 
7095     /* store max(ncopies, 0) into temporay */
7096 
7097     tmp = getcctmp_sc('d', sem.dtemps++, ST_VAR, DT_INT, sem.sc);
7098     i = ast_intr(I_MAX, DT_INT, 2, (int)ARG_AST(2), astb.i0);
7099     ast = mk_assn_stmt(mk_id(tmp), i, DT_INT);
7100     (void)add_stmt(ast);
7101 
7102     shaper = increase_shape(shape1, (int)SST_ASTG(stkp), mk_id(tmp),
7103                             (int)STD_PREV(0));
7104     break;
7105   case PD_pack:
7106     if (count < 2 || count > 3) {
7107       E74_CNT(pdsym, count, 2, 3);
7108       goto call_e74_cnt;
7109     }
7110     if (evl_kwd_args(list, 3, KWDARGSTR(pdsym)))
7111       goto exit_;
7112     argt_count = 3;
7113 
7114     stkp = ARG_STK(0); /* array */
7115     dtyper = SST_DTYPEG(stkp);
7116     if (DTY(dtyper) != TY_ARRAY) {
7117       E74_ARG(pdsym, 0, NULL);
7118       goto call_e74_arg;
7119     }
7120     shape1 = SST_SHAPEG(stkp);
7121 
7122     stkp = ARG_STK(1); /* mask */
7123     dtype2 = SST_DTYPEG(stkp);
7124     if (!DT_ISLOG(DDTG(dtype2))) {
7125       E74_ARG(pdsym, 1, NULL);
7126       goto call_e74_arg;
7127     }
7128     if (!chkshape(stkp, ARG_STK(0), FALSE)) {
7129       E74_ARG(pdsym, 0, NULL);
7130       goto call_e74_arg;
7131     }
7132 
7133     if (A_TYPEG(SST_ASTG(stkp)) != A_ID && DTY(dtype2) == TY_ARRAY) {
7134       /*
7135          Compute mask into a temp array and use this temp as the argument
7136          - first we need a dtype for the temp
7137        */
7138       int tmp_dtype = dtype2;
7139 
7140       ad = AD_DPTR(dtype2);
7141 
7142       if (!AD_NUMDIM(ad)) {
7143         tmp_dtype = dtype_with_shape(dtype2, A_SHAPEG(SST_ASTG(stkp)));
7144       } else {
7145         tmp_dtype = dtype_with_shape(DDTG(dtype2), A_SHAPEG(SST_ASTG(stkp)));
7146       }
7147 
7148       tmp = get_arr_temp(tmp_dtype, FALSE, FALSE, FALSE);
7149       arrtmp_ast = mk_id(tmp);
7150       ast = mk_assn_stmt(arrtmp_ast, SST_ASTG(stkp), tmp_dtype);
7151       (void)add_stmt(ast);
7152       ARG_AST(1) = arrtmp_ast;
7153     } else {
7154       XFR_ARGAST(1);
7155     }
7156 
7157     if ((stkp = ARG_STK(2))) { /* vector */
7158       if (!eq_dtype(DDTG(SST_DTYPEG(stkp)), DTY(dtyper + 1))) {
7159         E74_ARG(pdsym, 2, NULL);
7160         goto call_e74_arg;
7161       }
7162       if (rank_of_ast((int)ARG_AST(2)) != 1) {
7163         E74_ARG(pdsym, 2, NULL);
7164         goto call_e74_arg;
7165       }
7166     }
7167 
7168     tmp = getcctmp_sc('d', sem.dtemps++, ST_VAR, astb.bnd.dtype, sem.sc);
7169     add_shape_rank(1);
7170     add_shape_spec(astb.bnd.one, mk_id(tmp), astb.bnd.one);
7171     shaper = mk_shape();
7172 
7173     if (stkp != NULL)
7174       /* use size of vector */
7175       ast = size_of_ast(ARG_AST(2));
7176     else if (DTY(dtype2) != TY_ARRAY)
7177       /* mask is a scalar; use size of array */
7178       ast = size_of_ast(ARG_AST(0));
7179     else {
7180       /* else compute size by the expression  'count(mask)' */
7181       int t1;
7182       t1 = mk_argt(2);              /* space for arguments */
7183       ARGT_ARG(t1, 0) = ARG_AST(1); /* mask */
7184       ARGT_ARG(t1, 1) = 0;          /* no dim argument */
7185 
7186       func_ast = mk_id(intast_sym[I_COUNT]);
7187       ast = mk_func_node(A_INTR, func_ast, 2, t1);
7188       A_DTYPEP(ast, DT_INT);
7189       A_OPTYPEP(ast, I_COUNT);
7190       A_SHAPEP(ast, 0);
7191     }
7192     ast = mk_assn_stmt(mk_id(tmp), ast, DT_INT);
7193     (void)add_stmt(ast);
7194     break;
7195   case PD_unpack:
7196     if (count != 3) {
7197       E74_CNT(pdsym, count, 3, 3);
7198       goto call_e74_cnt;
7199     }
7200     if (evl_kwd_args(list, 3, KWDARGSTR(pdsym)))
7201       goto exit_;
7202 
7203     stkp = ARG_STK(0); /* vector: any rank 1 array */
7204     dtyper = SST_DTYPEG(stkp);
7205     shape1 = SST_SHAPEG(stkp);
7206     if (DTY(dtyper) != TY_ARRAY || SHD_NDIM(shape1) != 1) {
7207       E74_ARG(pdsym, 0, NULL);
7208       goto call_e74_arg;
7209     }
7210 
7211     stkp = ARG_STK(1); /* mask: logical array */
7212     dtype1 = SST_DTYPEG(stkp);
7213     shaper = SST_SHAPEG(stkp);
7214     if (!DT_ISLOG_ARR(dtype1)) {
7215       E74_ARG(pdsym, 1, NULL);
7216       goto call_e74_arg;
7217     }
7218 
7219     stkp = ARG_STK(2);         /* field: same type as vector */
7220     dtype2 = SST_DTYPEG(stkp); /*        same shape as mask */
7221     shape2 = SST_SHAPEG(stkp);
7222     if (!eq_dtype(DDTG(dtype2), DTY(dtyper + 1))) {
7223       E74_ARG(pdsym, 2, NULL);
7224       goto call_e74_arg;
7225     }
7226     if (!chkshape(stkp, ARG_STK(1), FALSE)) {
7227       E74_ARG(pdsym, 1, NULL);
7228       goto call_e74_arg;
7229     }
7230     XFR_ARGAST(2);
7231     break;
7232   case PD_dshape:
7233     if (!XBIT(49, 0x40)) /* if xbit set, CM fortran intrinsics allowed */
7234       goto bad_args;
7235   case PD_shape:
7236     if (count < 1 || count > 2) {
7237       E74_CNT(pdsym, count, 1, 2);
7238       goto call_e74_cnt;
7239     }
7240     if (evl_kwd_args(list, 2, KWDARGSTR(pdsym)))
7241       goto exit_;
7242 
7243     if ((stkp = ARG_STK(1))) { /* KIND */
7244       dtyper2 = set_kind_result(stkp, DT_INT, TY_INT);
7245       if (!dtyper2) {
7246         E74_ARG(pdsym, 3, NULL);
7247         goto call_e74_arg;
7248       }
7249     } else {
7250       dtyper2 = 0;
7251     }
7252 
7253     dtype1 = (!dtyper2) ? stb.user.dt_int : dtyper2;
7254 
7255     dtyper = get_array_dtype(1, dtype1);
7256 
7257     if (sem.dinit_data) {
7258       int rank;
7259 
7260       /* build return type */
7261       stkp = ARG_STK(0);
7262       ad = AD_DPTR(SST_DTYPEG(stkp));
7263       rank = AD_NUMDIM(ad); /* rank of array arg, upper bound of result array */
7264       sem.arrdim.ndim = 1;
7265       sem.arrdim.ndefer = 0;
7266       sem.bounds[0].lowtype = S_CONST;
7267       sem.bounds[0].lowb = 1;
7268       sem.bounds[0].lwast = 0;
7269       sem.bounds[0].uptype = S_CONST;
7270       sem.bounds[0].upb = rank;
7271       sem.bounds[0].upast =
7272           mk_cval(rank, (!dtyper2) ? stb.user.dt_int : dtyper2);
7273       dtyper = mk_arrdsc();
7274       DTY(dtyper + 1) = (!dtyper2) ? stb.user.dt_int : dtyper2;
7275 
7276       gen_init_intrin_call(stktop, pdsym, count, dtyper, FALSE);
7277       return 0;
7278     }
7279 
7280     ad = AD_DPTR(dtyper);
7281     count = rank_of_ast(ARG_AST(0));
7282     AD_NUMELM(ad) = AD_UPBD(ad, 0) = AD_UPAST(ad, 0) =
7283         mk_isz_cval(count, astb.bnd.dtype);
7284     shape1 = A_SHAPEG(ARG_AST(0));
7285     argt_count = 3 * count + 2;
7286     tmp = get_arr_temp(dtyper, FALSE, FALSE, FALSE);
7287     arrtmp_ast = mk_id(tmp);
7288     shaper = A_SHAPEG(arrtmp_ast);
7289     sptr = find_pointer_variable(ARG_AST(0));
7290     if (sptr && (POINTERG(sptr) || (ALLOCG(sptr) && SDSCG(sptr)))) {
7291       hpf_sym = sym_mkfunc_nodesc(mkRteRtnNm(RTE_shapeDsc), DT_NONE);
7292       ast = begin_call(A_CALL, hpf_sym, 2);
7293       add_arg(arrtmp_ast);
7294       add_arg(check_member(ARG_AST(0), mk_id(SDSCG(sptr)))); /* rank */
7295     } else {
7296       switch (dtyper2) {
7297       case 0:
7298         rtlRtn = RTE_shape;
7299         break;
7300       case DT_BINT:
7301         rtlRtn = RTE_shape1;
7302         break;
7303       case DT_SINT:
7304         rtlRtn = RTE_shape2;
7305         break;
7306       case DT_INT4:
7307         rtlRtn = RTE_shape4;
7308         break;
7309       case DT_INT8:
7310         rtlRtn = RTE_shape;
7311         break;
7312       default:
7313         error(155, 3, gbl.lineno, SYMNAME(gbl.currsub),
7314               "invalid kind argument for shape");
7315       }
7316       hpf_sym = sym_mkfunc_nodesc(mkRteRtnNm(rtlRtn), DT_NONE);
7317       ast = begin_call(A_CALL, hpf_sym, argt_count);
7318       add_arg(arrtmp_ast);
7319       add_arg(mk_isz_cval((INT)count, astb.bnd.dtype)); /* rank */
7320       for (i = 0; i < count; i++) {
7321         add_arg((int)SHD_LWB(shape1, i));
7322         add_arg((int)SHD_UPB(shape1, i));
7323         add_arg((int)SHD_STRIDE(shape1, i));
7324       }
7325     }
7326     (void)add_stmt(ast);
7327     ast = arrtmp_ast;
7328     goto expr_val;
7329 
7330   case PD_reshape:
7331     if (count < 2 || count > 4) {
7332       E74_CNT(pdsym, count, 2, 4);
7333       goto call_e74_cnt;
7334     }
7335     if (get_kwd_args(list, 4, KWDARGSTR(pdsym)))
7336       goto exit_;
7337 
7338     stkp = ARG_STK(1); /* shape */
7339     dtype1 = SST_DTYPEG(stkp);
7340     if (!DT_ISINT_ARR(dtype1)) {
7341       E74_ARG(pdsym, 1, NULL);
7342       goto call_e74_arg;
7343     }
7344 
7345     shape_acl = NULL;
7346     if (SST_IDG(stkp) == S_ACONST) {
7347       shape_acl = SST_ACLG(stkp);
7348     }
7349 
7350     if (shape_acl && shape_acl->is_const) {
7351       shape_acl = SST_ACLG(stkp);
7352       count = get_int_cval(sym_of_ast(AD_NUMELM(AD_DPTR(dtype1))));
7353       if (count < 0 || count > 7) {
7354         E74_ARG(pdsym, 1, NULL);
7355         goto call_e74_arg;
7356       }
7357     } else
7358       shape_acl = NULL;
7359 
7360     stkp = ARG_STK(0);
7361     dtyper = SST_DTYPEG(stkp); /* source */
7362     if (DTY(dtyper) != TY_ARRAY) {
7363       E74_ARG(pdsym, 0, NULL);
7364       goto call_e74_arg;
7365     }
7366 
7367     if (SST_IDG(stkp) == S_IDENT) {
7368       int allo_sptr = SST_SYMG(stkp);
7369       if (ALLOCATTRG(allo_sptr)) {
7370         ALLOCDESCP(allo_sptr, TRUE);
7371       }
7372     }
7373     argt_count = 4;
7374 
7375     stkp = ARG_STK(1); /* shape */
7376 
7377     (void)mkexpr(ARG_STK(1));
7378     XFR_ARGAST(1);
7379     if (shape_acl == NULL) {
7380       ast = ARG_AST(1);
7381       if (sem.dinit_data && !SST_SHAPEG(stkp)) {
7382         if (ADD_NUMDIM(A_DTYPEG(ast)) != 1) {
7383           E74_ARG(pdsym, 1, NULL);
7384           goto call_e74_arg;
7385         }
7386         tmp = ADD_NUMELM(A_DTYPEG(ast));
7387       } else {
7388         shape1 = SST_SHAPEG(stkp);
7389         if (shape1 == 0 || SHD_NDIM(shape1) != 1) {
7390           E74_ARG(pdsym, 1, NULL);
7391           goto call_e74_arg;
7392         }
7393         tmp = size_of_ast(ast);
7394       }
7395 
7396       if (A_TYPEG(tmp) != A_CNST) {
7397         E74_ARG(pdsym, 1, NULL);
7398         goto call_e74_arg;
7399       }
7400       count = get_int_cval(A_SPTRG(tmp));
7401       if (count < 0 || count > 7) {
7402         E74_ARG(pdsym, 1, NULL);
7403         goto call_e74_arg;
7404       }
7405     }
7406 
7407     if ((stkp = ARG_STK(2))) { /* pad */
7408       (void)mkexpr(stkp);
7409       XFR_ARGAST(2);
7410       dtype2 = SST_DTYPEG(stkp);
7411       if (DTY(dtype2) != TY_ARRAY || DTY(dtype2 + 1) != DTY(dtyper + 1)) {
7412         E74_ARG(pdsym, 2, NULL);
7413         goto call_e74_arg;
7414       }
7415     }
7416     if ((stkp = ARG_STK(3))) { /* order */
7417       (void)mkexpr(stkp);
7418       XFR_ARGAST(3);
7419       dtype2 = SST_DTYPEG(stkp);
7420       if (!DT_ISINT(DTY(dtype2 + 1)) ||
7421           count != get_int_cval(sym_of_ast(AD_NUMELM(AD_DPTR(dtype2))))) {
7422         E74_ARG(pdsym, 3, NULL);
7423         goto call_e74_arg;
7424       }
7425     }
7426 
7427     sem.arrdim.ndim = 1;
7428     (void)mkexpr(ARG_STK(0));
7429 
7430     XFR_ARGAST(0);
7431 
7432     if (sem.dinit_data) {
7433       ACL *aclp = shape_acl;
7434 
7435       if (!DT_ISINT(DTY(SST_DTYPEG(ARG_STK(1)) + 1))) { /* shape */
7436         E74_ARG(pdsym, 1, NULL);
7437         goto call_e74_arg;
7438       }
7439 
7440       if ((stkp = ARG_STK(2))) { /* pad */
7441         if (DTY(SST_DTYPEG(stkp) + 1) != DTY(dtyper + 1)) {
7442           sem.dinit_error = TRUE;
7443           E74_ARG(pdsym, 2, NULL);
7444           goto call_e74_arg;
7445         }
7446       }
7447 
7448       if ((stkp = ARG_STK(3))) { /* order */
7449         dtype2 = SST_DTYPEG(ARG_STK(3));
7450         if (!DT_ISINT(DTY(dtype2 + 1)) ||
7451             count != get_int_cval(sym_of_ast(AD_NUMELM(AD_DPTR(dtype2))))) {
7452           sem.dinit_error = TRUE;
7453           E74_ARG(pdsym, 3, NULL);
7454           goto call_e74_arg;
7455         }
7456       }
7457 
7458       if (!aclp) {
7459         aclp = construct_acl_from_ast(SST_ASTG(ARG_STK(1)), 0, 0);
7460       }
7461       aclp = eval_init_expr(aclp);
7462 
7463       add_shape_rank(count);
7464       sem.arrdim.ndim = count;
7465       sem.arrdim.ndefer = 0;
7466       aclp = (aclp->id == AC_ACONST ? aclp->subc : aclp);
7467       if (!aclp) {
7468         return 0;
7469       }
7470       for (i = 0; i < count; i++) {
7471         int ubast = mk_bnd_int(aclp->u1.ast);
7472         add_shape_spec(astb.bnd.one, ubast, astb.bnd.one);
7473 
7474         sem.bounds[i].lowtype = S_CONST;
7475         sem.bounds[i].lowb = 1;
7476         sem.bounds[i].lwast = 0;
7477         sem.bounds[i].uptype = S_CONST;
7478         sem.bounds[i].upb = get_int_cval(A_SPTRG(aclp->u1.ast));
7479         sem.bounds[i].upast = ubast;
7480         sem.bounds[i].upast = ubast;
7481 
7482         aclp = aclp->next;
7483       }
7484       shaper = mk_shape();
7485       dtyper = mk_arrdsc();
7486       DTY(dtyper + 1) = DDTG(SST_DTYPEG(ARG_STK(0)));
7487 
7488       gen_init_intrin_call(stktop, pdsym, argt_count, dtyper, FALSE);
7489 
7490       A_SHAPEP(SST_ASTG(stktop), shaper);
7491 
7492       return 0;
7493     }
7494 
7495     if (shape_acl != NULL) {
7496       add_shape_rank(count);
7497       shape_acl = shape_acl->subc; /* go down to element list */
7498       for (i = 0; i < count; i++) {
7499         add_shape_spec(astb.bnd.one, mk_bnd_int(shape_acl->u1.ast),
7500                        astb.bnd.one);
7501         shape_acl = shape_acl->next;
7502       }
7503       shaper = mk_shape();
7504     } else {
7505       /*
7506        * compute the shape for the result of 'reshape':
7507        * o   count is the size of the shape argument and represents the
7508        *     rank of the result.
7509        * o   for each dimension in the result, its upper bound is the
7510        *     value of the corresponding element in the shape argument.
7511        * o   to access an element of the shape argument, a subscripted
7512        *     reference of the shape argument must be generated; the
7513        *     subscript will consist of any non-triple subscripts; the
7514        *     triple subscript will be replaced with the 'current' index.
7515        * o   the shape descriptor is used to generate a sequence of
7516        *     indices; e.g.,   lwb : upb : stride.
7517        */
7518       int arr;
7519       int subs[7];
7520       int asd;
7521       int dim = 0;
7522       int nsubs = 1;
7523       int ix;
7524       int shp[7];
7525       int eldtype;
7526 
7527       eldtype = DDTG(A_DTYPEG(ast));
7528       arr = ast;
7529       if (A_TYPEG(ast) == A_SUBSCR) {
7530         arr = A_LOPG(ast);
7531         asd = A_ASDG(ast);
7532         nsubs = ASD_NDIM(asd);
7533         for (i = 0; i < nsubs; i++) {
7534           tmp = ASD_SUBS(asd, i);
7535           if (A_TYPEG(tmp) == A_TRIPLE)
7536             dim = i;
7537           else
7538             subs[i] = tmp;
7539         }
7540       }
7541 
7542       ix = SHD_LWB(shape1, 0);
7543       for (i = 0; i < count; i++) {
7544         int src;
7545         int asn;
7546 
7547         subs[dim] = ix;
7548         ix = mk_binop(OP_ADD, ix, (int)SHD_STRIDE(shape1, 0), astb.bnd.dtype);
7549         shp[i] = mk_id(get_temp(astb.bnd.dtype));
7550         src = mk_subscr(arr, subs, nsubs, eldtype);
7551         asn = mk_assn_stmt(shp[i], src, astb.bnd.dtype);
7552         (void)add_stmt(asn);
7553       }
7554       add_shape_rank(count);
7555       for (i = 0; i < count; i++)
7556         add_shape_spec(astb.bnd.one, shp[i], astb.bnd.one);
7557       shaper = mk_shape();
7558     }
7559     break;
7560 
7561   case PD_merge:
7562     if (count != 3) {
7563       E74_CNT(pdsym, count, 3, 3);
7564       goto call_e74_cnt;
7565     }
7566     if (evl_kwd_args(list, 3, KWDARGSTR(pdsym)))
7567       goto exit_;
7568 
7569     stkp = ARG_STK(2);
7570     if (!DT_ISLOG(DDTG(SST_DTYPEG(stkp)))) { /* mask */
7571       E74_ARG(pdsym, 2, NULL);
7572       goto call_e74_arg;
7573     }
7574     dtype2 = SST_DTYPEG(stkp);
7575     shape2 = SST_SHAPEG(stkp);
7576 
7577     stkp = ARG_STK(0); /* tsource */
7578     dtyper = SST_DTYPEG(stkp);
7579     shaper = SST_SHAPEG(stkp);
7580 
7581     stkp = ARG_STK(1); /* fsource */
7582     dtype1 = SST_DTYPEG(stkp);
7583     shape1 = SST_SHAPEG(stkp);
7584     if (DDTG(dtyper) != DDTG(dtype1)) {
7585       if (DTYG(dtyper) == TY_CHAR || DTYG(dtyper) == TY_NCHAR) {
7586         if (DTYG(dtyper) != DTYG(dtype1)) {
7587           E74_ARG(pdsym, 1, NULL);
7588           goto call_e74_arg;
7589         }
7590       } else {
7591         E74_ARG(pdsym, 1, NULL);
7592         goto call_e74_arg;
7593       }
7594     }
7595     shaper = set_shape_result(shaper, shape1);
7596     if (shaper < 0) {
7597       E74_ARG(pdsym, 1, NULL);
7598       goto call_e74_arg;
7599     }
7600     sptr = (shaper == shape1 ? SST_SYMG(ARG_STK(1)) : SST_SYMG(ARG_STK(0)));
7601 
7602     shaper = set_shape_result(shaper, shape2);
7603     if (shaper < 0) {
7604       E74_ARG(pdsym, 2, NULL);
7605       goto call_e74_arg;
7606     }
7607     sptr = (shaper == shape2 ? SST_SYMG(ARG_STK(2)) : sptr);
7608 
7609     if (shaper && DTY(dtyper) != TY_ARRAY) {
7610       dtyper = get_array_dtype(SHD_NDIM(shaper), dtyper);
7611       ad = AD_DPTR(dtyper);
7612       for (i = 0; i < (int)SHD_NDIM(shaper); i++) {
7613         AD_LWBD(ad, i) = AD_LWAST(ad, i) = SHD_LWB(shaper, i);
7614         AD_UPBD(ad, i) = AD_UPAST(ad, i) = SHD_UPB(shaper, i);
7615         AD_EXTNTAST(ad, i) = mk_extent(AD_LWAST(ad, i), AD_UPAST(ad, i), i);
7616       }
7617     }
7618 
7619     ast = ARG_AST(2);
7620     hpf_sym = getMergeSym((int)DDTG(dtyper), IK_ELEMENTAL);
7621     switch (DTYG(dtyper)) {
7622     case TY_CHAR:
7623     case TY_NCHAR:
7624       dtype1 = DDTG(dtyper);
7625       if (dtype1 == DT_ASSCHAR || dtype1 == DT_DEFERCHAR) {
7626         tmp = ast_intr(I_LEN, DT_INT4, 1, ARG_AST(0));
7627         dtype1 = get_type(2, TY_CHAR, tmp);
7628         if (DTY(dtyper) != TY_ARRAY) {
7629           dtyper = dtype1;
7630         } else {
7631           dtyper = dup_array_dtype(dtyper);
7632           DTY(dtyper + 1) = dtype1;
7633         }
7634       } else if (dtype1 == DT_ASSNCHAR || dtype1 == DT_DEFERCHAR) {
7635         tmp = ast_intr(I_LEN, DT_INT4, 1, ARG_AST(0));
7636         dtype1 = get_type(2, TY_NCHAR, tmp);
7637         if (DTY(dtyper) != TY_ARRAY) {
7638           dtyper = dtype1;
7639         } else {
7640           dtyper = dup_array_dtype(dtyper);
7641           DTY(dtyper + 1) = dtype1;
7642         }
7643       }
7644       arrtmp_ast = mk_id(get_ch_temp(dtyper));
7645       func_ast = begin_call(A_ICALL, hpf_sym, 5);
7646       A_OPTYPEP(func_ast, INTASTG(pdsym));
7647       add_arg(arrtmp_ast);
7648       add_arg(ARG_AST(0));
7649       add_arg(ARG_AST(1));
7650       add_arg(ast);
7651       add_arg(mk_cval(size_of(DDTG(A_DTYPEG(ast))), DT_INT));
7652       (void)add_stmt(func_ast);
7653       ast = arrtmp_ast;
7654       break;
7655     case TY_DERIVED:
7656       if (shaper)
7657         arrtmp_ast = mk_id(get_arr_temp(dtyper, FALSE, FALSE, FALSE));
7658       else
7659         arrtmp_ast = mk_id(get_temp(dtyper));
7660       func_ast = begin_call(A_ICALL, hpf_sym, 6);
7661       A_OPTYPEP(func_ast, INTASTG(pdsym));
7662       add_arg(arrtmp_ast);
7663       add_arg(ARG_AST(0));
7664       add_arg(ARG_AST(1));
7665       add_arg(
7666           mk_cval(size_of(DDTG(dtyper)), DT_INT)); /* size of derived type */
7667       add_arg(ast);
7668       add_arg(mk_cval(size_of(DDTG(A_DTYPEG(ast))), DT_INT));
7669       (void)add_stmt(func_ast);
7670       ast = arrtmp_ast;
7671       break;
7672     default:
7673       argt = mk_argt(4); /* space for arguments */
7674       ARGT_ARG(argt, 0) = ARG_AST(0);
7675       ARGT_ARG(argt, 1) = ARG_AST(1);
7676       ARGT_ARG(argt, 2) = ast;
7677       ARGT_ARG(argt, 3) = mk_cval(size_of(DDTG(A_DTYPEG(ast))), DT_INT);
7678       func_ast = mk_id(hpf_sym);
7679       ast = mk_func_node(A_INTR, func_ast, 4, argt);
7680       A_DTYPEP(ast, dtyper);
7681       A_OPTYPEP(ast, INTASTG(pdsym));
7682       if (shaper == 0)
7683         shaper = mkshape(dtyper);
7684     }
7685     goto expr_val;
7686 
7687   case PD_dsize:
7688     if (!XBIT(49, 0x40)) /* if xbit set, CM fortran intrinsics allowed */
7689       goto bad_args;
7690   case PD_size:
7691     if (count == 0 || count > 3) {
7692       E74_CNT(pdsym, count, 1, 3);
7693       goto call_e74_cnt;
7694     }
7695     if (get_kwd_args(list, 3, KWDARGSTR(pdsym)))
7696       goto exit_;
7697 
7698     (void)mkarg(ARG_STK(0), &dum);
7699     XFR_ARGAST(0);
7700     argt_count = 2;
7701     shaper = 0;
7702     if ((stkp = ARG_STK(2))) { /* KIND */
7703       dtyper = set_kind_result(stkp, DT_INT, TY_INT);
7704       if (!dtyper) {
7705         E74_ARG(pdsym, 2, NULL);
7706         goto call_e74_arg;
7707       }
7708     } else {
7709       if (XBIT(68, 0x1) && XBIT(68, 0x2))
7710         dtyper = DT_INT8;
7711       else
7712         dtyper = stb.user.dt_int;
7713     }
7714 
7715     if (sem.dinit_data) {
7716       gen_init_intrin_call(stktop, pdsym, count, dtyper, FALSE);
7717       return 0;
7718     }
7719 
7720     dtype1 = SST_DTYPEG(ARG_STK(0));
7721     if (DTY(dtype1) != TY_ARRAY) {
7722       E74_ARG(pdsym, 0, NULL);
7723       goto call_e74_arg;
7724     }
7725     asumsz = 0;
7726     ast = ARG_AST(0);
7727     if (A_TYPEG(ast) == A_INTR) {
7728       switch (A_OPTYPEG(ast)) {
7729       case I_ADJUSTL: /* adjustl(string) */
7730       case I_ADJUSTR: /* adjustr(string) */
7731         /*  len is just len(string) */
7732         ast = ARGT_ARG(A_ARGSG(ast), 0);
7733         ARG_AST(0) = ast;
7734         break;
7735       }
7736     }
7737     switch (A_TYPEG(ast)) {
7738     case A_ID:
7739       asumsz = A_SPTRG(ast);
7740       if (SCG(asumsz) != SC_DUMMY || !ASUMSZG(asumsz))
7741         asumsz = 0;
7742       break;
7743     case A_MEM:
7744       /* elide any scalar members */
7745       while (TRUE) {
7746         sptr = A_SPTRG(A_MEMG(ast));
7747         if (DTY(DTYPEG(sptr)) == TY_ARRAY)
7748           break;
7749         ast = A_PARENTG(ast);
7750         if (A_TYPEG(ast) == A_ID)
7751           break;
7752         if (A_TYPEG(ast) == A_SUBSCR)
7753           break;
7754       }
7755       ARG_AST(0) = ast;
7756       break;
7757     default:
7758       break;
7759     }
7760     sptr = find_pointer_variable(ast);
7761     if (sptr && (POINTERG(sptr) || (ALLOCG(sptr) && SDSCG(sptr)))) {
7762       /* pghpf_size(dim, static_descriptor) */
7763       if ((stkp = ARG_STK(1))) { /* dim */
7764         (void)mkexpr(stkp);
7765         XFR_ARGAST(1);
7766         dtype2 = SST_DTYPEG(stkp);
7767         if (!DT_ISINT(dtype2)) {
7768           E74_ARG(pdsym, 1, NULL);
7769           goto call_e74_arg;
7770         }
7771         ARG_AST(1) = mk_bnd_int(ARG_AST(1));
7772       } else
7773         ARG_AST(1) = astb.ptr0;
7774 
7775       if (XBIT(68, 0x1))
7776         hpf_sym = sym_mkfunc_nodesc(mkRteRtnNm(RTE_sizeDsc), dtyper);
7777       else
7778         hpf_sym = sym_mkfunc_nodesc(mkRteRtnNm(RTE_sizeDsc), dtyper);
7779       ast = begin_call(A_FUNC, hpf_sym, 2);
7780       A_DTYPEP(ast, dtyper);
7781       add_arg(ARG_AST(1));
7782       add_arg(check_member(ARG_AST(0), mk_id(SDSCG(sptr)))); /* rank */
7783       goto expr_val;
7784     }
7785     shape1 = A_SHAPEG(ARG_AST(0));
7786     count = SHD_NDIM(shape1);  /* rank of array arg */
7787     if ((stkp = ARG_STK(1))) { /* dim */
7788       (void)mkexpr(stkp);
7789       XFR_ARGAST(1);
7790       dtype2 = SST_DTYPEG(stkp);
7791       if (!DT_ISINT(dtype2)) {
7792         E74_ARG(pdsym, 1, NULL);
7793         goto call_e74_arg;
7794       }
7795       if ((ast = A_ALIASG(ARG_AST(1)))) {
7796         /* dim is a constant */
7797         i = get_int_cval(A_SPTRG(ast));
7798         if (i < 1 || i > count) {
7799           error(423, 3, gbl.lineno, NULL, NULL);
7800           i = 1;
7801         }
7802         if (asumsz && i == count)
7803           error(84, 3, gbl.lineno, SYMNAME(asumsz),
7804                 "- size of assumed size array is unknown");
7805         /*
7806          * Before computing the extent, ensure that an upper bound
7807          * for this dimension exists.  The upper bound may be zero
7808          * if the array is an argument declared in an interface
7809          * within a module.
7810          */
7811         if (SHD_UPB(shape1, i - 1)) {
7812           ast = extent_of_shape(shape1, i - 1);
7813           if (A_ALIASG(ast)) {
7814             ast = A_ALIASG(ast);
7815             iszval = get_isz_cval(A_SPTRG(ast));
7816             goto const_isz_val;
7817           } else {
7818 
7819             (void)sym_mkfunc_nodesc(mkRteRtnNm(RTE_size), stb.user.dt_int);
7820 
7821             goto gen_call;
7822           }
7823         }
7824         if (sem.interface) {
7825           /*
7826            * if this expression is rewritten (i.e., when this
7827            * function specified by this interface is invoked),
7828            * ast_rewrite() will select the size based on the
7829            * constant dim value.
7830            */
7831 
7832           (void)sym_mkfunc_nodesc(mkRteRtnNm(RTE_size), stb.user.dt_int);
7833 
7834           goto gen_call;
7835         }
7836         goto expr_val;
7837       }
7838     } else {
7839       if (asumsz)
7840         error(84, 3, gbl.lineno, SYMNAME(asumsz),
7841               "- size of assumed size array is unknown");
7842       else {
7843         for (i = 0; i < count; i++) {
7844           if (SHD_LWB(shape1, i) == 0 || A_ALIASG(SHD_LWB(shape1, i)) == 0 ||
7845               SHD_UPB(shape1, i) == 0 || A_ALIASG(SHD_UPB(shape1, i)) == 0 ||
7846               (SHD_STRIDE(shape1, i) != 0 &&
7847                A_ALIASG(SHD_STRIDE(shape1, i)) == 0)) {
7848             goto PD_size_nonconstant;
7849           }
7850         }
7851         ast = extent_of_shape(shape1, 0);
7852         for (i = 1; i < count; i++) {
7853           int e;
7854           e = extent_of_shape(shape1, i);
7855           if (A_ALIASG(e)) { /* should be constant, but ... */
7856             if (get_isz_cval(A_SPTRG(e)) <= 0) {
7857               ast = astb.bnd.zero;
7858               break;
7859             }
7860           } else
7861             goto PD_size_nonconstant;
7862           ast = mk_binop(OP_MUL, ast, e, astb.bnd.dtype);
7863         }
7864         if (A_ALIASG(ast)) { /* should be constant, but ... */
7865           ast = A_ALIASG(ast);
7866           iszval = get_isz_cval(A_SPTRG(ast));
7867           goto const_isz_val;
7868         }
7869       }
7870     PD_size_nonconstant:
7871       ARG_AST(1) = astb.ptr0;
7872     }
7873 
7874     (void)sym_mkfunc_nodesc(mkRteRtnNm(RTE_size), dtyper);
7875     break;
7876 
7877   case PD_allocated:
7878     if (count != 1) {
7879       E74_CNT(pdsym, count, 1, 1);
7880       goto call_e74_cnt;
7881     }
7882     if (evl_kwd_args(list, 1, KWDARGSTR(pdsym)))
7883       goto exit_;
7884     argt_count = 1;
7885     ast = SST_ASTG(ARG_STK(0));
7886     if (A_TYPEG(ast) != A_ID && A_TYPEG(ast) != A_MEM) {
7887       E74_ARG(pdsym, 0, NULL);
7888       goto call_e74_arg;
7889     }
7890     i = memsym_of_ast(ast);
7891     dtype1 = DTYPEG(i);
7892     if (!ALLOCG(i) || TPALLOCG(i)) {
7893       E74_ARG(pdsym, 0, NULL);
7894       goto call_e74_arg;
7895     }
7896     ad = AD_DPTR(dtype1);
7897     if (DTY(dtype1) == TY_ARRAY) {
7898       ad = AD_DPTR(dtype1);
7899       if (AD_DEFER(ad) == 0) {
7900         E74_CNT(pdsym, count, 1, 1);
7901         goto call_e74_cnt;
7902       }
7903     }
7904     dtyper = stb.user.dt_log;
7905 
7906     break;
7907 
7908   case PD_present:
7909     if (count != 1) {
7910       E74_CNT(pdsym, count, 1, 1);
7911       goto call_e74_cnt;
7912     }
7913     dont_issue_assumedsize_error = 1;
7914     if (evl_kwd_args(list, 1, KWDARGSTR(pdsym)))
7915       goto exit_;
7916     dont_issue_assumedsize_error = 0;
7917     argt_count = 1;
7918     ast = SST_ASTG(ARG_STK(0));
7919     if (A_TYPEG(ast) != A_ID) {
7920       E74_ARG(pdsym, 0, NULL);
7921       goto call_e74_arg;
7922     }
7923     i = A_SPTRG(ast);
7924     if (gbl.internal > 1 && !INTERNALG(i) && NEWARGG(i)) {
7925       i = NEWARGG(i);
7926       ARG_AST(0) = mk_id(i);
7927     } else if (SCG(i) != SC_DUMMY) {
7928       E74_ARG(pdsym, 0, NULL);
7929       goto call_e74_arg;
7930     }
7931     if (!OPTARGG(i))
7932       error(84, 3, gbl.lineno, SYMNAME(i), "- must be an OPTIONAL argument");
7933     dtyper = stb.user.dt_log;
7934 
7935     if (DTYG(DTYPEG(i)) == TY_CHAR || DTYG(DTYPEG(i)) == TY_NCHAR)
7936       (void)sym_mkfunc_nodesc(mkRteRtnNm(RTE_presentc), stb.user.dt_log);
7937     else if (!XBIT(57, 0x80000) && POINTERG(i))
7938       (void)sym_mkfunc_nodesc(mkRteRtnNm(RTE_present_ptr), stb.user.dt_log);
7939     else
7940       (void)sym_mkfunc_nodesc(mkRteRtnNm(RTE_present), stb.user.dt_log);
7941     break;
7942 
7943   case PD_kind:
7944     if (count != 1) {
7945       E74_CNT(pdsym, count, 1, 1);
7946       goto call_e74_cnt;
7947     }
7948     if (get_kwd_args(list, 1, KWDARGSTR(pdsym)))
7949       goto exit_;
7950     dtype1 = DDTG(SST_DTYPEG(ARG_STK(0)));
7951     conval = kind_of(dtype1);
7952     if (conval <= 0) {
7953       E74_ARG(pdsym, 0, NULL);
7954       goto call_e74_arg;
7955     }
7956     goto const_default_int_val; /*return default integer*/
7957 
7958   case PD_selected_int_kind:
7959     if (count != 1) {
7960       E74_CNT(pdsym, count, 1, 1);
7961       goto call_e74_cnt;
7962     }
7963     if (evl_kwd_args(list, 1, KWDARGSTR(pdsym)))
7964       goto exit_;
7965     stkp = ARG_STK(0);
7966     dtype1 = SST_DTYPEG(stkp);
7967     if (!DT_ISINT(dtype1)) {
7968       E74_ARG(pdsym, 0, NULL);
7969       goto call_e74_arg;
7970     }
7971 
7972     if (sem.dinit_data) {
7973       gen_init_intrin_call(stktop, pdsym, count, stb.user.dt_int, FALSE);
7974       return 0;
7975     }
7976 
7977     ast = SST_ASTG(stkp);
7978     if (A_ALIASG(ast)) {
7979       ast = A_ALIASG(ast);
7980       con1 = A_SPTRG(ast);
7981       con1 = CONVAL2G(con1);
7982       conval = 4;
7983       if (con1 > 18 || (con1 > 9 && XBIT(57, 2)))
7984         conval = -1;
7985       else if (con1 > 9)
7986         conval = 8;
7987       else if (con1 > 4)
7988         conval = 4;
7989       else if (con1 > 2)
7990         conval = 2;
7991       else
7992         conval = 1;
7993       goto const_default_int_val; /*return default integer*/
7994     }
7995     /* nonconstant argument, call RTE_sel_int_kind(r,descr) */
7996     XFR_ARGAST(0);
7997     func_type = A_FUNC;
7998 
7999     hpf_sym = sym_mkfunc(mkRteRtnNm(RTE_sel_int_kind), stb.user.dt_int);
8000 
8001     dtyper = stb.user.dt_int;
8002     break;
8003 
8004   case PD_selected_real_kind:
8005 #ifdef PD_ieee_selected_real_kind
8006   case PD_ieee_selected_real_kind:
8007 #endif
8008     if (count > 2 || count == 0) {
8009       E74_CNT(pdsym, count, 0, 2);
8010       goto call_e74_cnt;
8011     }
8012     if (evl_kwd_args(list, 2, KWDARGSTR(pdsym)))
8013       goto exit_;
8014 
8015     if (sem.dinit_data) {
8016       gen_init_intrin_call(stktop, pdsym, 2, stb.user.dt_int, FALSE);
8017       return 0;
8018     }
8019 
8020     stkp = ARG_STK(0);
8021     is_constant = TRUE;
8022     conval = 4;
8023     if (!stkp) {
8024       ARG_AST(0) = astb.ptr0;
8025     } else {
8026       dtype1 = SST_DTYPEG(stkp);
8027       if (!DT_ISINT(dtype1)) {
8028         E74_ARG(pdsym, 0, NULL);
8029         goto call_e74_arg;
8030       }
8031       XFR_ARGAST(0);
8032       ast = SST_ASTG(stkp);
8033       if (!A_ALIASG(ast)) {
8034         is_constant = FALSE;
8035       } else {
8036         ast = A_ALIASG(ast);
8037         con1 = A_SPTRG(ast);
8038         con1 = CONVAL2G(con1);
8039         if (con1 <= 6)
8040           conval = 4;
8041         else if (con1 <= 15)
8042           conval = 8;
8043         else if (con1 <= 31 && !XBIT(57, 4))
8044           conval = 16;
8045         else
8046           conval = -1;
8047       }
8048     }
8049     stkp = ARG_STK(1);
8050     if (!stkp) {
8051       ARG_AST(1) = astb.ptr0;
8052     } else {
8053       dtype1 = SST_DTYPEG(stkp);
8054       if (!DT_ISINT(dtype1)) {
8055         E74_ARG(pdsym, 1, NULL);
8056         goto call_e74_arg;
8057       }
8058       XFR_ARGAST(1);
8059       ast = SST_ASTG(stkp);
8060       if (!A_ALIASG(ast)) {
8061         is_constant = FALSE;
8062       } else {
8063         ast = A_ALIASG(ast);
8064         con1 = A_SPTRG(ast);
8065         con1 = CONVAL2G(con1);
8066         if (XBIT(49, 0x40000)) {
8067           /* Cray C90 */
8068           if (con1 <= 37) {
8069             if (conval > 0 && conval < 4)
8070               conval = 4;
8071           } else if (con1 <= 2465) {
8072             if (conval > 0 && conval < 8)
8073               conval = 8;
8074           } else {
8075             if (conval > 0)
8076               conval = 0;
8077             conval -= 2;
8078           }
8079         } else {
8080           /* ANSI */
8081           if (con1 <= 37) {
8082             if (conval > 0 && conval < 4)
8083               conval = 4;
8084           } else if (con1 <= 307) {
8085             if (conval > 0 && conval < 8)
8086               conval = 8;
8087           } else if (con1 <= 4931 && !XBIT(57, 4)) {
8088             if (conval > 0 && conval < 16)
8089               conval = 16;
8090           } else {
8091             if (conval > 0)
8092               conval = 0;
8093             conval -= 2;
8094           }
8095         }
8096       }
8097     }
8098     if (is_constant) {
8099       goto const_default_int_val; /*return default integer*/
8100     }
8101     /* nonconstant argument, call RTE_sel_int_kind(r,descr) */
8102     func_type = A_FUNC;
8103 
8104     hpf_sym = sym_mkfunc(mkRteRtnNm(RTE_sel_real_kind), stb.user.dt_int);
8105     dtyper = stb.user.dt_int;
8106     argt_count = 2;
8107     break;
8108 
8109   case PD_selected_char_kind:
8110     if (count != 1) {
8111       E74_CNT(pdsym, count, 1, 1);
8112       goto call_e74_cnt;
8113     }
8114     if (evl_kwd_args(list, 1, KWDARGSTR(pdsym)))
8115       goto exit_;
8116     stkp = ARG_STK(0);
8117     dtype1 = SST_DTYPEG(stkp);
8118     if (DTY(dtype1) != TY_CHAR) {
8119       E74_ARG(pdsym, 0, NULL);
8120       goto call_e74_arg;
8121     }
8122     if (sem.dinit_data) {
8123       gen_init_intrin_call(stktop, pdsym, count, stb.user.dt_int, FALSE);
8124       return 0;
8125     }
8126     ast = SST_ASTG(stkp);
8127     if (A_ALIASG(ast)) {
8128       ast = A_ALIASG(ast);
8129       con1 = A_SPTRG(ast);
8130       conval = _selected_char_kind(con1);
8131       goto const_default_int_val; /*return default integer*/
8132     }
8133     /* nonconstant argument, call RTE_sel_char_kind(r,descr) */
8134     XFR_ARGAST(0);
8135     func_type = A_FUNC;
8136 
8137     hpf_sym = sym_mkfunc(mkRteRtnNm(RTE_sel_char_kinda), stb.user.dt_int);
8138 
8139     dtyper = stb.user.dt_int;
8140     break;
8141 
8142   case PD_new_line:
8143     if (count == 0 || count > 1) {
8144       E74_CNT(pdsym, count, 0, 1);
8145       goto call_e74_cnt;
8146     }
8147     if (evl_kwd_args(list, 1, KWDARGSTR(pdsym)))
8148       goto exit_;
8149     stkp = ARG_STK(0);
8150     dtype1 = DDTG(SST_DTYPEG(stkp));
8151     if (DTY(dtype1) != TY_CHAR && DTY(dtype1) != TY_NCHAR) {
8152       E74_ARG(pdsym, 0, NULL);
8153       goto call_e74_arg;
8154     }
8155     dtyper = dtype1;
8156     ch = 10;
8157     conval = getstring(&ch, 1);
8158     goto const_return;
8159     break;
8160   case PD_is_iostat_end:
8161   case PD_is_iostat_eor:
8162     if (count < 1 || count > 1) {
8163       E74_CNT(pdsym, count, 0, 1);
8164       goto call_e74_cnt;
8165     }
8166     if (evl_kwd_args(list, 1, KWDARGSTR(pdsym)))
8167       goto exit_;
8168     stkp = ARG_STK(0);
8169     dtype1 = SST_DTYPEG(stkp);
8170     if (!DT_ISINT(DDTG(dtype1))) {
8171       E74_ARG(pdsym, 0, NULL);
8172       goto call_e74_arg;
8173     }
8174     ast = ARG_AST(0);
8175     shaper = SST_SHAPEG(stkp);
8176     dtyper = stb.user.dt_log; /* default logical */
8177     if (shaper)
8178       dtyper = get_array_dtype(1, dtyper);
8179 
8180     if (pdtype == PD_is_iostat_end) {
8181       hpf_sym = sym_mkfunc_nodesc(mkRteRtnNm(RTE_is_iostat_end), dtyper);
8182     } else {
8183       hpf_sym = sym_mkfunc_nodesc(mkRteRtnNm(RTE_is_iostat_eor), dtyper);
8184     }
8185     ELEMENTALP(hpf_sym, 1);
8186     EXTSYMP(pdsym, hpf_sym);
8187     DTYPEP(hpf_sym, dtyper);
8188 
8189     argt_count = 1;
8190     ast = mk_convert(ast, DT_INT4);
8191     ast = mk_unop(OP_VAL, ast, DT_INT4);
8192     argt = mk_argt(1);
8193     ARGT_ARG(argt, 0) = ast;
8194     func_ast = mk_id(hpf_sym);
8195     A_DTYPEP(func_ast, dtyper);
8196     func_type = A_FUNC;
8197     ast = mk_func_node(func_type, func_ast, 1, argt);
8198     if (shaper)
8199       dtyper = dtype_with_shape(dtyper, shaper);
8200     A_DTYPEP(ast, dtyper);
8201     if (shaper == 0)
8202       shaper = mkshape(dtyper);
8203 
8204     goto expr_val;
8205 
8206     break;
8207   case PD_achar:
8208     if (count < 1 || count > 2) {
8209       E74_CNT(pdsym, count, 1, 2);
8210       goto call_e74_cnt;
8211     }
8212     if (evl_kwd_args(list, 2, KWDARGSTR(pdsym)))
8213       goto exit_;
8214     /* TBD - array argument */
8215     stkp = ARG_STK(0);
8216     dtype1 = SST_DTYPEG(stkp);
8217     if (!DT_ISINT(DDTG(dtype1))) {
8218       E74_ARG(pdsym, 0, NULL);
8219       goto call_e74_arg;
8220     }
8221     shaper = SST_SHAPEG(stkp);
8222     ast = ARG_AST(0);
8223     dtyper = DT_CHAR; /* default kind */
8224     if ((stkp = ARG_STK(1))) {
8225       dtyper = set_kind_result(stkp, DT_CHAR, TY_CHAR);
8226       if (!dtyper) {
8227         E74_ARG(pdsym, 1, NULL);
8228         goto call_e74_arg;
8229       }
8230     }
8231 
8232     if (shaper) {
8233       dtyper = get_array_dtype(SHD_NDIM(shaper), dtyper);
8234       ad = AD_DPTR(dtyper);
8235       for (i = 0; i < (int)SHD_NDIM(shaper); i++) {
8236         AD_LWBD(ad, i) = AD_LWAST(ad, i) = SHD_LWB(shaper, i);
8237         AD_UPBD(ad, i) = AD_UPAST(ad, i) = SHD_UPB(shaper, i);
8238         AD_EXTNTAST(ad, i) = mk_extent(AD_LWAST(ad, i), AD_UPAST(ad, i), i);
8239       }
8240     } else if (A_ALIASG(ast)) {
8241       ch = get_int_cval(A_SPTRG(A_ALIASG(ast)));
8242       conval = getstring(&ch, 1);
8243       goto const_return;
8244     }
8245     if (DTY(dtyper) == TY_NCHAR) {
8246       sptr = intast_sym[I_NCHAR];
8247       ast = begin_call(A_INTR, sptr, 1);
8248       add_arg(ARG_AST(0));
8249       A_DTYPEP(ast, dtyper);
8250       A_OPTYPEP(ast, I_NCHAR);
8251     } else
8252     {
8253       sptr = intast_sym[I_ACHAR];
8254       ast = begin_call(A_INTR, sptr, 1);
8255       add_arg(ARG_AST(0));
8256       A_DTYPEP(ast, dtyper);
8257       A_OPTYPEP(ast, I_ACHAR);
8258     }
8259     goto expr_val;
8260 
8261   case PD_adjustl:
8262   case PD_adjustr:
8263     if (count != 1) {
8264       E74_CNT(pdsym, count, 1, 1);
8265       goto call_e74_cnt;
8266     }
8267     if (evl_kwd_args(list, 1, KWDARGSTR(pdsym)))
8268       goto exit_;
8269     stkp = ARG_STK(0);
8270     dtype1 = SST_DTYPEG(stkp);
8271     dtyper = dtype1;
8272     shaper = SST_SHAPEG(stkp);
8273     if (DTYG(dtype1) != TY_CHAR && DTYG(dtype1) != TY_NCHAR) {
8274       E74_ARG(pdsym, 0, NULL);
8275       goto call_e74_arg;
8276     }
8277 
8278     ast = ARG_AST(0);
8279     if (A_ALIASG(ast)) {
8280       if (pdtype == PD_adjustl)
8281         sptr = _adjustl(A_SPTRG(A_ALIASG(ast)));
8282       else
8283         sptr = _adjustr(A_SPTRG(A_ALIASG(ast)));
8284       goto const_str_val;
8285     }
8286 
8287     if (sem.dinit_data) {
8288       gen_init_intrin_call(stktop, pdsym, count, DDTG(dtype1), TRUE);
8289       return 0;
8290     }
8291 
8292     /* check if the dtype warrants an allocatable temp; if so,
8293      * need indicate this so that if the context is a relational
8294      * expression, the expression will be evaluated an assigned
8295      * to a temp.
8296      */
8297     (void)need_alloc_ch_temp(dtyper);
8298     break;
8299 
8300   case PD_bit_size:
8301     if (count != 1) {
8302       E74_CNT(pdsym, count, 1, 1);
8303       goto call_e74_cnt;
8304     }
8305     if (get_kwd_args(list, 1, KWDARGSTR(pdsym)))
8306       goto exit_;
8307     dtyper = DDTG(SST_DTYPEG(ARG_STK(0)));
8308     switch (DTY(dtyper)) {
8309     case TY_BINT:
8310     case TY_SINT:
8311     case TY_INT:
8312     case TY_INT8:
8313       conval = bits_in(dtyper);
8314       break;
8315     default:
8316       E74_ARG(pdsym, 0, NULL);
8317       goto call_e74_arg;
8318     }
8319 
8320     goto const_kind_int_val;
8321 
8322   case PD_digits:
8323     if (count != 1) {
8324       E74_CNT(pdsym, count, 1, 1);
8325       goto call_e74_cnt;
8326     }
8327     if (get_kwd_args(list, 1, KWDARGSTR(pdsym)))
8328       goto exit_;
8329     dtype1 = DDTG(SST_DTYPEG(ARG_STK(0)));
8330     switch (DTY(dtype1)) {
8331     case TY_BINT:
8332       conval = 7;
8333       break;
8334     case TY_SINT:
8335       conval = 15;
8336       break;
8337     case TY_INT:
8338       conval = 31;
8339       break;
8340     case TY_INT8:
8341       conval = 63;
8342       break;
8343     /* values for real/double taken from float.h <type>_MANT_DIG */
8344     case TY_REAL:
8345       conval = 24;
8346       break;
8347     case TY_DBLE:
8348       if (XBIT(49, 0x40000)) /* C90 */
8349         conval = 47;
8350       else
8351         conval = 53;
8352       break;
8353     case TY_QUAD:
8354       if (XBIT(49, 0x40000)) /* C90 */
8355         conval = 95;
8356       else
8357         conval = 113;
8358       break;
8359     default:
8360       E74_ARG(pdsym, 0, NULL);
8361       goto call_e74_arg;
8362     }
8363     goto const_default_int_val; /*return default integer*/
8364 
8365   case PD_epsilon:
8366     if (count != 1) {
8367       E74_CNT(pdsym, count, 1, 1);
8368       goto call_e74_cnt;
8369     }
8370     if (get_kwd_args(list, 1, KWDARGSTR(pdsym)))
8371       goto exit_;
8372     dtype1 = DDTG(SST_DTYPEG(ARG_STK(0)));
8373     switch (DTY(dtype1)) {
8374     case TY_REAL:
8375       val[0] = 0x34000000;
8376       sname = "epsilon(1.0_4)";
8377       goto const_real_val;
8378     case TY_DBLE:
8379       if (XBIT(49, 0x40000)) { /* C90 */
8380 #define C90_EPSILON "0.1421085471520200e-13"
8381         atoxd(C90_EPSILON, &val[0], strlen(C90_EPSILON));
8382       } else {
8383         val[0] = 0x3cb00000;
8384         val[1] = 0;
8385       }
8386       sname = "epsilon(1.0_8)";
8387       goto const_dble_val;
8388     default:
8389       break;
8390     }
8391     E74_ARG(pdsym, 0, NULL);
8392     goto call_e74_arg;
8393 
8394   case PD_exponent:
8395     if (count != 1) {
8396       E74_CNT(pdsym, count, 1, 1);
8397       goto call_e74_cnt;
8398     }
8399     if (evl_kwd_args(list, 1, KWDARGSTR(pdsym)))
8400       goto exit_;
8401     stkp = ARG_STK(0);
8402     dtype1 = DDTG(SST_DTYPEG(stkp));
8403     if (!DT_ISREAL(dtype1)) {
8404       E74_ARG(pdsym, 0, NULL);
8405       goto call_e74_arg;
8406     }
8407     if (DTY(dtype1) == TY_REAL)
8408       rtlRtn = RTE_expon;
8409     else /* TY_DBLE */
8410       rtlRtn = RTE_expond;
8411 
8412     fsptr = sym_mkfunc_nodesc(mkRteRtnNm(rtlRtn), stb.user.dt_int);
8413     ELEMENTALP(fsptr, 1);
8414     shaper = SST_SHAPEG(stkp);
8415     if (shaper == 0)
8416       dtyper = stb.user.dt_int;
8417     else
8418       dtyper = aux.dt_iarray;
8419     break;
8420 
8421   case PD_fraction:
8422   case PD_rrspacing:
8423   case PD_spacing:
8424     if (count != 1) {
8425       E74_CNT(pdsym, count, 1, 1);
8426       goto call_e74_cnt;
8427     }
8428     if (evl_kwd_args(list, 1, KWDARGSTR(pdsym)))
8429       goto exit_;
8430     stkp = ARG_STK(0);
8431     dtyper = SST_DTYPEG(stkp);
8432     shaper = SST_SHAPEG(stkp);
8433     dtype1 = DDTG(dtyper);
8434     if (!DT_ISREAL(dtype1)) {
8435       E74_ARG(pdsym, 0, NULL);
8436       goto call_e74_arg;
8437     }
8438     if (DTY(dtype1) == TY_REAL) {
8439       switch (pdtype) {
8440       case PD_fraction:
8441         rtlRtn = RTE_frac;
8442         break;
8443       case PD_rrspacing:
8444         rtlRtn = RTE_rrspacing;
8445         break;
8446       case PD_spacing:
8447         rtlRtn = RTE_spacing;
8448         break;
8449       default:
8450         interr("PD_spacing, pdtype", pdtype, 3);
8451       }
8452     } else { /* TY_DBLE */
8453       switch (pdtype) {
8454       case PD_fraction:
8455         rtlRtn = RTE_fracd;
8456         break;
8457       case PD_rrspacing:
8458         rtlRtn = RTE_rrspacingd;
8459         break;
8460       case PD_spacing:
8461         rtlRtn = RTE_spacingd;
8462         break;
8463       default:
8464         interr("PD_spacingd, pdtype", pdtype, 3);
8465       }
8466     }
8467     (void)sym_mkfunc_nodesc(mkRteRtnNm(rtlRtn), dtype1);
8468     break;
8469 
8470   case PD_erf:
8471   case PD_erfc:
8472   case PD_erfc_scaled:
8473   case PD_gamma:
8474   case PD_log_gamma:
8475   case PD_acosh:
8476   case PD_asinh:
8477   case PD_atanh:
8478   case PD_bessel_j0:
8479   case PD_bessel_j1:
8480   case PD_bessel_y0:
8481   case PD_bessel_y1:
8482     /* TODO: where are the names for these set? */
8483     if (count != 1) {
8484       E74_CNT(pdsym, count, 1, 1);
8485       goto call_e74_cnt;
8486     }
8487     if (evl_kwd_args(list, 1, KWDARGSTR(pdsym)))
8488       goto exit_;
8489     stkp = ARG_STK(0);
8490     dtyper = SST_DTYPEG(stkp);
8491     shaper = SST_SHAPEG(stkp);
8492     dtype1 = DDTG(dtyper);
8493     if (!DT_ISREAL(dtype1)) {
8494       E74_ARG(pdsym, 0, NULL);
8495       goto call_e74_arg;
8496     }
8497     break;
8498   case PD_bessel_jn:
8499   case PD_bessel_yn:
8500     if (count < 2 || count > 3) {
8501       E74_CNT(pdsym, count, 2, 3);
8502       goto call_e74_cnt;
8503     }
8504     if (count == 2) {
8505       if (evl_kwd_args(list, 2, "n x"))
8506         goto exit_;
8507 
8508       dtype1 = DDTG(SST_DTYPEG(ARG_STK(0)));
8509       dtype2 = DDTG(SST_DTYPEG(ARG_STK(1)));
8510       if (!DT_ISINT(dtype1) || !DT_ISREAL(dtype2)) {
8511         E74_ARG(pdsym, 0, NULL);
8512         goto call_e74_arg;
8513       }
8514       shaper = A_SHAPEG(ARG_AST(1));
8515       if (shaper < 0) {
8516         E74_ARG(pdsym, 2, NULL);
8517         goto call_e74_arg;
8518       }
8519       if (shaper) {
8520         dtyper = get_array_dtype(SHD_NDIM(shaper), dtype2);
8521       } else {
8522         dtyper = dtype2;
8523       }
8524 
8525       if (DTY(dtype1) != TY_INT) {
8526         ast = ARG_AST(0);
8527         ast = mk_convert(ast, dtype1);
8528         ARG_AST(0) = ast;
8529       }
8530     } else if (count == 3) {
8531       if (evl_kwd_args(list, 3, KWDARGSTR(pdsym)))
8532         goto exit_;
8533 
8534       if (!DT_ISINT(DDTG(SST_DTYPEG(ARG_STK(0)))) ||
8535           !DT_ISINT(DDTG(SST_DTYPEG(ARG_STK(1)))) ||
8536           !DT_ISREAL(DDTG(SST_DTYPEG(ARG_STK(2))))) {
8537         E74_ARG(pdsym, 0, NULL);
8538         goto call_e74_arg;
8539       }
8540 
8541       dtype2 = DDTG(SST_DTYPEG(ARG_STK(2)));
8542 
8543       argt = mk_argt(4);
8544 
8545       sem.arrdim.ndim = 1;
8546       sem.arrdim.ndefer = 0;
8547       sem.bounds[0].lowtype = S_CONST;
8548       sem.bounds[0].lowb = 1;
8549       sem.bounds[0].lwast = 0;
8550       sem.bounds[0].uptype = S_EXPR;
8551       sem.bounds[0].upb = 0;
8552       sem.bounds[0].upast =
8553           mk_binop(OP_ADD, mk_binop(OP_SUB, ARG_AST(1), ARG_AST(0), DT_INT),
8554                    astb.bnd.one, DT_INT);
8555       dtyper = mk_arrdsc();
8556       DTY(dtyper + 1) = dtype2;
8557 
8558       shaper = mkshape(dtyper);
8559       arrtmp_ast = mk_id(get_arr_temp(dtyper, FALSE, FALSE, FALSE));
8560       ARGT_ARG(argt, 0) = arrtmp_ast;
8561 
8562       dtype1 = DDTG(SST_DTYPEG(ARG_STK(0)));
8563       ARGT_ARG(argt, 1) = SST_ASTG(ARG_STK(0));
8564       if (DTY(dtype1) != TY_INT) {
8565         ast = ARG_AST(0);
8566         ast = mk_convert(ast, dtype1);
8567         ARGT_ARG(argt, 1) = ast;
8568       }
8569       dtype1 = DDTG(SST_DTYPEG(ARG_STK(1)));
8570       ARGT_ARG(argt, 2) = SST_ASTG(ARG_STK(1));
8571       if (DTY(dtype1) != TY_INT) {
8572         ast = ARG_AST(1);
8573         ast = mk_convert(ast, dtype1);
8574         ARGT_ARG(argt, 2) = ast;
8575       }
8576 
8577       ARGT_ARG(argt, 3) = SST_ASTG(ARG_STK(2));
8578 
8579       if (DTY(dtype2) == TY_REAL) {
8580         switch (pdtype) {
8581         case PD_bessel_jn:
8582           name = "f90_bessel_jn";
8583           break;
8584         case PD_bessel_yn:
8585           name = "f90_bessel_yn";
8586           break;
8587         }
8588       } else { /* TY_DBLE */
8589         switch (pdtype) {
8590         case PD_bessel_jn:
8591           name = "f90_dbessel_jn";
8592           break;
8593         case PD_bessel_yn:
8594           name = "f90_dbessel_yn";
8595           break;
8596         }
8597       }
8598 
8599       hpf_sym = sym_mkfunc_nodesc(name, dtyper);
8600       func_ast = mk_id(hpf_sym);
8601       A_DTYPEP(func_ast, dtyper);
8602       ast = mk_func_node(A_CALL, func_ast, 4, argt);
8603       add_stmt(ast);
8604       dtyper = dtype1;
8605       A_DTYPEP(ast, dtyper);
8606       A_DTYPEP(func_ast, dtyper);
8607       A_SHAPEP(ast, shaper);
8608 
8609       SST_ASTP(stktop, arrtmp_ast);
8610       SST_SHAPEP(stktop, shaper);
8611       SST_DTYPEP(stktop, dtyper);
8612       SST_IDP(stktop, S_EXPR);
8613 
8614       EXPSTP(hpf_sym, 1);
8615       return 1;
8616     }
8617     break;
8618   case PD_hypot:
8619     if (count != 2) {
8620       E74_CNT(pdsym, count, 2, 2);
8621       goto call_e74_cnt;
8622     }
8623     if (evl_kwd_args(list, 2, KWDARGSTR(pdsym)))
8624       goto exit_;
8625     dtype1 = DDTG(SST_DTYPEG(ARG_STK(0)));
8626     dtype2 = DDTG(SST_DTYPEG(ARG_STK(1)));
8627     if (!DT_ISREAL(dtype1) || !DT_ISREAL(dtype2)) {
8628       E74_ARG(pdsym, 0, NULL);
8629       goto call_e74_arg;
8630     }
8631     shaper = SST_SHAPEG(ARG_STK(0));
8632     shape2 = SST_SHAPEG(ARG_STK(1));
8633     shaper = set_shape_result(shaper, shape2);
8634     if (shaper < 0) {
8635       E74_ARG(pdsym, 2, NULL);
8636       goto call_e74_arg;
8637     }
8638     if (shaper) {
8639       dtyper = get_array_dtype(SHD_NDIM(shaper), dtype1);
8640     } else {
8641       dtyper = dtype1;
8642     }
8643     if (DTY(dtype1) == TY_REAL) {
8644       rtlRtn = RTE_hypot;
8645     } else { /* TY_DBLE */
8646       rtlRtn = RTE_hypotd;
8647     }
8648     /* TODO: where is the call generated */
8649     break;
8650 
8651   case PD_huge:
8652     if (count != 1) {
8653       E74_CNT(pdsym, count, 1, 1);
8654       goto call_e74_cnt;
8655     }
8656     if (get_kwd_args(list, 1, KWDARGSTR(pdsym)))
8657       goto exit_;
8658     dtype1 = DDTG(SST_DTYPEG(ARG_STK(0)));
8659     ast = ast_intr(I_HUGE, dtype1, 0); /* returns a constant ast */
8660     switch (DTY(dtype1)) {
8661     case TY_BINT:
8662     case TY_SINT:
8663     case TY_INT:
8664       goto const_int_ast;
8665     case TY_INT8:
8666       goto const_int8_ast;
8667     case TY_REAL:
8668       goto const_real_ast;
8669     case TY_DBLE:
8670       goto const_dble_ast;
8671     case TY_QUAD:
8672       goto const_quad_ast;
8673     default:
8674       break;
8675     }
8676     E74_ARG(pdsym, 0, NULL);
8677     goto call_e74_arg;
8678 
8679   case PD_iachar:
8680     if (count == 0 || count > 2) {
8681       E74_CNT(pdsym, count, 1, 2);
8682       goto call_e74_cnt;
8683     }
8684     if (evl_kwd_args(list, 2, KWDARGSTR(pdsym)))
8685       goto exit_;
8686     stkp = ARG_STK(0);
8687     dtype1 = SST_DTYPEG(stkp);
8688     if (DTYG(dtype1) != TY_CHAR && DTYG(dtype1) != TY_NCHAR) {
8689       E74_ARG(pdsym, 0, NULL);
8690       goto call_e74_arg;
8691     }
8692     shaper = SST_SHAPEG(stkp);
8693     if ((stkp = ARG_STK(1))) { /* KIND */
8694       dtyper = set_kind_result(stkp, DT_INT, TY_INT);
8695       if (!dtyper) {
8696         E74_ARG(pdsym, 1, NULL);
8697         goto call_e74_arg;
8698       }
8699     } else {
8700       dtyper = stb.user.dt_int;
8701     }
8702     if (sem.dinit_data) {
8703       gen_init_intrin_call(stktop, pdsym, count, dtyper, TRUE);
8704       return 0;
8705     }
8706     if (shaper) {
8707       dtyper = get_array_dtype(SHD_NDIM(shaper), dtyper);
8708       ad = AD_DPTR(dtyper);
8709       for (i = 0; i < (int)SHD_NDIM(shaper); i++) {
8710         AD_LWBD(ad, i) = AD_LWAST(ad, i) = SHD_LWB(shaper, i);
8711         AD_UPBD(ad, i) = AD_UPAST(ad, i) = SHD_UPB(shaper, i);
8712         AD_EXTNTAST(ad, i) = mk_extent(AD_LWAST(ad, i), AD_UPAST(ad, i), i);
8713       }
8714     } else if (A_ALIASG(ARG_AST(0))) { /* constant character */
8715       conval = stb.n_base[CONVAL1G(A_SPTRG(A_ALIASG(ARG_AST(0))))] & 0xff;
8716       conval = cngcon(conval, DT_INT4, dtyper);
8717       goto const_return;
8718     }
8719 
8720     break;
8721 
8722   case PD_ceiling:
8723   case PD_floor:
8724     if (count < 1 || count > 2) {
8725         E74_CNT(pdsym, count, 0, 2);
8726         goto call_e74_cnt;
8727     }
8728     if (get_kwd_args(list, 2, KWDARGSTR(pdsym)))
8729       goto exit_;
8730 
8731     stkp = ARG_STK(0);
8732     dtype1 = DDTG(SST_DTYPEG(stkp));
8733     if (!DT_ISREAL(dtype1)) {
8734       E74_ARG(pdsym, 0, NULL);
8735       goto call_e74_arg;
8736     }
8737 
8738     dtyper = dtype1; /* initial result of call is type of argument */
8739 
8740     /* for this case dtype2 is used for conversion; the actual floor/ceiling
8741      * calls we use return real, but the Fortran declaration returns int.
8742      * We need to calculate final type for conversion to correct int kind.
8743      */
8744 
8745     if ((stkp = ARG_STK(1))) { /* kind */
8746       dtype2 = set_kind_result(stkp, DT_INT, TY_INT);
8747       if (!dtype2) {
8748         E74_ARG(pdsym, 1, NULL);
8749         goto call_e74_arg;
8750       }
8751     } else {
8752       dtype2 = stb.user.dt_int;  /* default return type for floor/ceiling */
8753     }
8754 
8755     if (sem.dinit_data) {
8756       gen_init_intrin_call(stktop, pdsym, count, dtype2, TRUE);
8757       return 0;
8758     }
8759 
8760     /* If this is f90, leave the kind argument in. Otherwise issue
8761      * a warning and leave it -- we'll get to it someday
8762      */
8763     (void)mkexpr(ARG_STK(0));
8764     shaper = SST_SHAPEG(ARG_STK(0));
8765     XFR_ARGAST(0);
8766     argt_count = 1;
8767     if (ARG_STK(1)) {
8768       (void)mkexpr(ARG_STK(1));
8769       argt_count = 2;
8770       ARG_AST(1) = mk_cval1(target_kind(dtyper), DT_INT4);
8771     }
8772     if (shaper)
8773       dtyper = get_array_dtype(1, dtyper);
8774     goto gen_call;
8775 
8776   case PD_aint:
8777   case PD_anint:
8778     if (count < 1 || count > 2) {
8779       E74_CNT(pdsym, count, 1, 2);
8780       goto call_e74_cnt;
8781     }
8782     if (get_kwd_args(list, 2, KWDARGSTR(pdsym)))
8783       goto exit_;
8784     stkp = ARG_STK(0);
8785     if (SST_ISNONDECC(stkp))
8786       cngtyp(stkp, DT_INT);
8787     dtype1 = DDTG(SST_DTYPEG(stkp));
8788     if (!DT_ISREAL(dtype1)) {
8789       E74_ARG(pdsym, 0, NULL);
8790       goto call_e74_arg;
8791     }
8792     if ((stkp = ARG_STK(1))) { /* kind */
8793       dtyper = set_kind_result(stkp, DT_REAL, TY_REAL);
8794       if (!dtyper) {
8795         E74_ARG(pdsym, 1, NULL);
8796         goto call_e74_arg;
8797       }
8798     } else
8799       dtyper = dtype1; /* result is type of argument */
8800     /* If this is f90, leave the kind argument in. Otherwise issue
8801      * a warning and leave it -- we'll get to it someday
8802      */
8803     (void)mkexpr(ARG_STK(0));
8804     shaper = SST_SHAPEG(ARG_STK(0));
8805     XFR_ARGAST(0);
8806     argt_count = 1;
8807     if (ARG_STK(1)) {
8808       (void)mkexpr(ARG_STK(1));
8809       argt_count = 2;
8810       ARG_AST(1) = mk_cval1(target_kind(dtyper), DT_INT4);
8811     }
8812     if (shaper)
8813       dtyper = get_array_dtype(1, dtyper);
8814     goto gen_call;
8815 
8816   case PD_int:
8817     if (count < 1 || count > 2) {
8818       E74_CNT(pdsym, count, 1, 2);
8819       goto call_e74_cnt;
8820     }
8821     if (get_kwd_args(list, 2, KWDARGSTR(pdsym)))
8822       goto exit_;
8823 
8824     stkp = ARG_STK(0);
8825     stkp1 = ARG_STK(1);
8826 
8827     if (stkp1) { /* kind */
8828       dtyper = set_kind_result(stkp1, DT_INT, TY_INT);
8829       if (!dtyper) {
8830         E74_ARG(pdsym, 1, NULL);
8831         goto call_e74_arg;
8832       }
8833     } else {
8834       dtyper = stb.user.dt_int; /* default integer*/
8835     }
8836 
8837     if (SST_ISNONDECC(stkp) || SST_DTYPEG(stkp) == DT_DWORD)
8838       cngtyp(stkp, dtyper);
8839     dtype1 = DDTG(SST_DTYPEG(stkp));
8840     if (!DT_ISNUMERIC(dtype1)) {
8841       E74_ARG(pdsym, 0, NULL);
8842       goto call_e74_arg;
8843     }
8844 
8845     /* If this is f90, leave the kind argument in. Otherwise issue
8846      * a warning and leave it -- we'll get to it someday
8847      */
8848     if (is_sst_const(stkp)) {
8849       con1 = get_sst_cval(stkp);
8850       conval = cngcon(con1, dtype1, dtyper);
8851       goto const_return;
8852     }
8853 
8854     if (sem.dinit_data) {
8855       gen_init_intrin_call(stktop, pdsym, count, dtyper, TRUE);
8856       return 0;
8857     }
8858 
8859     (void)mkexpr(stkp);
8860     shaper = SST_SHAPEG(stkp);
8861     XFR_ARGAST(0);
8862     argt_count = 1;
8863     if (stkp1) {
8864       (void)mkexpr(stkp1);
8865       argt_count = 2;
8866       ARG_AST(1) = mk_cval1(target_kind(dtyper), DT_INT4);
8867     }
8868     if (dtyper == dtype1) {
8869       ast = ARG_AST(0);
8870       if (shaper)
8871         dtyper = get_array_dtype(1, dtyper);
8872       goto expr_val;
8873     }
8874     if (shaper)
8875       dtyper = get_array_dtype(1, dtyper);
8876     goto gen_call;
8877 
8878   case PD_nint:
8879     if (count < 1 || count > 2) {
8880       E74_CNT(pdsym, count, 1, 2);
8881       goto call_e74_cnt;
8882     }
8883     if (get_kwd_args(list, 2, KWDARGSTR(pdsym)))
8884       goto exit_;
8885     stkp = ARG_STK(0);
8886     if (SST_ISNONDECC(stkp))
8887       cngtyp(stkp, DT_INT);
8888     dtype1 = DDTG(SST_DTYPEG(stkp));
8889     if (!DT_ISREAL(dtype1)) {
8890       E74_ARG(pdsym, 0, NULL);
8891       goto call_e74_arg;
8892     }
8893     dtyper = stb.user.dt_int;  /* default int */
8894     if ((stkp = ARG_STK(1))) { /* kind */
8895       dtyper = set_kind_result(stkp, DT_INT, TY_INT);
8896       if (!dtyper) {
8897         E74_ARG(pdsym, 1, NULL);
8898         goto call_e74_arg;
8899       }
8900     }
8901 
8902     if (sem.dinit_data) {
8903       gen_init_intrin_call(stktop, pdsym, count, dtyper, TRUE);
8904       return 0;
8905     }
8906 
8907     /* If this is f90, leave the kind argument in. Otherwise issue
8908      * a warning and leave it -- we'll get to it someday
8909      */
8910     stkp = ARG_STK(0);
8911     if (is_sst_const(stkp)) {
8912       con1 = get_sst_cval(stkp);
8913       switch (DTY(dtype1)) {
8914       case TY_REAL:
8915         num1[0] = CONVAL2G(stb.flt0);
8916         if (xfcmp(con1, num1[0]) >= 0) {
8917           INT fv2_23 = 0x4b000000;
8918           if (xfcmp(con1, fv2_23) >= 0)
8919             xfadd(con1, CONVAL2G(stb.flt0), &res[0]);
8920           else
8921             xfadd(con1, CONVAL2G(stb.flthalf), &res[0]);
8922         } else {
8923           INT fvm2_23 = 0xcb000000;
8924           if (xfcmp(con1, fvm2_23) <= 0)
8925             xfsub(con1, CONVAL2G(stb.flt0), &res[0]);
8926           else
8927             xfsub(con1, CONVAL2G(stb.flthalf), &res[0]);
8928         }
8929         break;
8930       case TY_DBLE:
8931         if (const_fold(OP_CMP, con1, stb.dbl0, DT_REAL8) >= 0) {
8932           INT dv2_52[2] = {0x43300000, 0x00000000};
8933           INT d2_52;
8934           d2_52 = getcon(dv2_52, DT_DBLE);
8935           if (const_fold(OP_CMP, con1, d2_52, DT_REAL8) >= 0)
8936             res[0] = const_fold(OP_ADD, con1, stb.dbl0, DT_REAL8);
8937           else
8938             res[0] = const_fold(OP_ADD, con1, stb.dblhalf, DT_REAL8);
8939         } else {
8940           INT dvm2_52[2] = {0xc3300000, 0x00000000};
8941           INT dm2_52;
8942           dm2_52 = getcon(dvm2_52, DT_DBLE);
8943           if (const_fold(OP_CMP, con1, dm2_52, DT_REAL8) >= 0)
8944             res[0] = const_fold(OP_SUB, con1, stb.dblhalf, DT_REAL8);
8945           else
8946             res[0] = const_fold(OP_SUB, con1, stb.dbl0, DT_REAL8);
8947         }
8948         break;
8949       }
8950       conval = cngcon(res[0], dtype1, dtyper);
8951       goto const_return;
8952     }
8953     (void)mkexpr(ARG_STK(0));
8954     shaper = SST_SHAPEG(ARG_STK(0));
8955     XFR_ARGAST(0);
8956     argt_count = 1;
8957     if (ARG_STK(1)) {
8958       (void)mkexpr(ARG_STK(1));
8959       argt_count = 2;
8960       ARG_AST(1) = mk_cval1(target_kind(dtyper), DT_INT4);
8961     }
8962     if (shaper)
8963       dtyper = get_array_dtype(1, dtyper);
8964     goto gen_call;
8965 
8966   case PD_cmplx:
8967     if (count < 1 || count > 3) {
8968       E74_CNT(pdsym, count, 1, 3);
8969       goto call_e74_cnt;
8970     }
8971     if (get_kwd_args(list, 3, KWDARGSTR(pdsym)))
8972       goto exit_;
8973 
8974     stkp = ARG_STK(0);
8975     stkp1 = ARG_STK(1);
8976     stkp2 = ARG_STK(2);
8977 
8978     if (stkp2) { /* kind */
8979       dtyper = set_kind_result(stkp2, DT_CMPLX, TY_CMPLX);
8980       dtype1 = dtyper == DT_CMPLX16 ? DT_REAL8 : DT_REAL4;
8981       if (!dtyper) {
8982         E74_ARG(pdsym, 1, NULL);
8983         goto call_e74_arg;
8984       }
8985     } else {
8986       dtyper = stb.user.dt_cmplx; /* default complex */
8987       dtype1 = stb.user.dt_real;  /* default real    */
8988     }
8989 
8990     /* f2003 says that a boz literal can appear as an argument to
8991      * the real, dble, cmplx, and dcmplx intrinsics and its value
8992      * is used as the respective internal respresentation
8993      */
8994     if (SST_ISNONDECC(stkp) || SST_DTYPEG(stkp) == DT_DWORD)
8995       cngtyp(stkp, dtype1);
8996     if (stkp1 && (SST_ISNONDECC(stkp1) || SST_DTYPEG(stkp1) == DT_DWORD))
8997       cngtyp(stkp1, dtype1);
8998 
8999     dtype1 = DDTG(SST_DTYPEG(stkp));
9000     if (!DT_ISNUMERIC(dtype1)) {
9001       E74_ARG(pdsym, 0, NULL);
9002       goto call_e74_arg;
9003     }
9004 
9005     /* If this is f90, leave the kind argument in. Otherwise issue
9006      * a warning and leave it -- we'll get to it someday
9007      */
9008     if (is_sst_const(stkp) && (!stkp1 || is_sst_const(stkp1))) {
9009       con1 = get_sst_cval(stkp);
9010       con1 = cngcon(con1, dtype1, dtyper);
9011       if (stkp1) {
9012         con2 = get_sst_cval(stkp1);
9013         con2 = cngcon(con2, DDTG(SST_DTYPEG(stkp1)), dtyper);
9014         num1[0] = CONVAL1G(con1);
9015         num1[1] = CONVAL1G(con2);
9016         conval = getcon(num1, dtyper);
9017       } else
9018         conval = con1;
9019       goto const_return;
9020     }
9021     (void)mkexpr(stkp);
9022     shaper = SST_SHAPEG(stkp);
9023     XFR_ARGAST(0);
9024     if (stkp1) {
9025       (void)mkexpr(stkp1);
9026       if (shaper == 0 && SST_SHAPEG(stkp1))
9027         shaper = SST_SHAPEG(stkp1);
9028       XFR_ARGAST(1);
9029     } else {
9030       ARG_AST(1) = 0;
9031     }
9032     argt_count = 3;
9033     ARG_AST(2) = 0;
9034     if (stkp2) { /* kind is present */
9035       (void)mkexpr(stkp2);
9036       ARG_AST(2) = mk_cval1(target_kind(dtyper), DT_INT4);
9037     }
9038     if (shaper)
9039       dtyper = get_array_dtype(1, dtyper);
9040     goto gen_call;
9041 
9042   case PD_real:
9043     if (count < 1 || count > 2) {
9044       E74_CNT(pdsym, count, 1, 2);
9045       goto call_e74_cnt;
9046     }
9047     if (get_kwd_args(list, 2, KWDARGSTR(pdsym)))
9048       goto exit_;
9049 
9050     stkp = ARG_STK(0);
9051     stkp1 = ARG_STK(1);
9052 
9053     if (stkp1) { /* kind */
9054       dtyper = set_kind_result(stkp1, DT_REAL, TY_REAL);
9055       if (!dtyper) {
9056         E74_ARG(pdsym, 1, NULL);
9057         goto call_e74_arg;
9058       }
9059     } else {
9060       switch (DTY(DDTG(SST_DTYPEG(stkp)))) {
9061       case TY_CMPLX:
9062         dtyper = stb.user.dt_real;
9063         break;
9064       case TY_DCMPLX:
9065         dtyper = DT_REAL8;
9066         (void)mk_coercion_func(dtyper);
9067         break;
9068       case TY_QCMPLX:
9069         dtyper = DT_QUAD;
9070         (void)mk_coercion_func(dtyper);
9071         break;
9072       default:
9073         dtyper = stb.user.dt_real; /* default real */
9074         break;
9075       }
9076     }
9077 
9078     /* f2003 says that a boz literal can appear as an argument to
9079      * the real, dble, cmplx, and dcmplx intrinsics and its value
9080      * is used as the respective internal respresentation
9081      */
9082     if (SST_ISNONDECC(stkp) || SST_DTYPEG(stkp) == DT_DWORD)
9083       cngtyp(stkp, dtyper);
9084     dtype1 = DDTG(SST_DTYPEG(stkp));
9085     if (!DT_ISNUMERIC(dtype1)) {
9086       E74_ARG(pdsym, 0, NULL);
9087       goto call_e74_arg;
9088     }
9089 
9090     /* If this is f90, leave the kind argument in. Otherwise issue
9091      * a warning and leave it -- we'll get to it someday
9092      */
9093     if (is_sst_const(stkp)) {
9094       con1 = get_sst_cval(stkp);
9095       conval = cngcon(con1, dtype1, dtyper);
9096       goto const_return;
9097     }
9098     (void)mkexpr(stkp);
9099     shaper = SST_SHAPEG(stkp);
9100     XFR_ARGAST(0);
9101     argt_count = 1;
9102     if (stkp1) {
9103       (void)mkexpr(stkp1);
9104       argt_count = 2;
9105       ARG_AST(1) = mk_cval1(target_kind(dtyper), DT_INT4);
9106     }
9107     if (shaper)
9108       dtyper = get_array_dtype(1, dtyper);
9109     goto gen_call;
9110 
9111   case PD_char:
9112     if (count < 1 || count > 2) {
9113       E74_CNT(pdsym, count, 1, 2);
9114       goto call_e74_cnt;
9115     }
9116     if (get_kwd_args(list, 2, KWDARGSTR(pdsym)))
9117       goto exit_;
9118     stkp = ARG_STK(0);
9119     if (SST_ISNONDECC(stkp))
9120       cngtyp(stkp, DT_INT);
9121     dtype1 = DDTG(SST_DTYPEG(stkp));
9122     if (!DT_ISINT(dtype1)) {
9123       E74_ARG(pdsym, 0, NULL);
9124       goto call_e74_arg;
9125     }
9126 
9127     dtyper = DT_CHAR;          /* default char */
9128     if ((stkp = ARG_STK(1))) { /* kind */
9129       dtyper = set_kind_result(stkp, DT_CHAR, TY_CHAR);
9130       if (!dtyper) {
9131         E74_ARG(pdsym, 1, NULL);
9132         goto call_e74_arg;
9133       }
9134     }
9135 
9136     /* If this is f90, leave the kind argument in. Otherwise issue
9137      * a warning and leave it -- we'll get to it someday
9138      */
9139     stkp = ARG_STK(0);
9140     if (is_sst_const(stkp)) {
9141       con1 = get_sst_cval(stkp);
9142       if (SST_DTYPEG(stkp) == DT_INT8)
9143         /* con1 is an sptr */
9144         con1 = get_int_cval(con1);
9145       ch = con1;
9146       conval = getstring(&ch, 1);
9147       goto const_return;
9148     }
9149 
9150     if (sem.dinit_data) {
9151       if (dtyper == DT_CHAR)
9152         dtyper = get_type(2, TY_CHAR, astb.i1);
9153       gen_init_intrin_call(stktop, pdsym, count, dtyper, TRUE);
9154       return 0;
9155     }
9156     (void)mkexpr(ARG_STK(0));
9157     shaper = SST_SHAPEG(ARG_STK(0));
9158     XFR_ARGAST(0);
9159     argt_count = 1;
9160     if (shaper)
9161       dtyper = get_array_dtype(1, dtyper);
9162     goto gen_call;
9163 
9164   const_return:
9165     SST_IDP(stktop, S_CONST);
9166     SST_DTYPEP(stktop, dtyper);
9167     SST_CVALP(stktop, conval);
9168     EXPSTP(pdsym, 1); /* freeze generic or specific name */
9169     SST_SHAPEP(stktop, 0);
9170     ast = mk_cval1(conval, dtyper);
9171     SST_ASTP(stktop, ast);
9172     return conval;
9173 
9174   const_default_int_return:
9175     SST_IDP(stktop, S_CONST);
9176     SST_DTYPEP(stktop, dtyper);
9177     /* call cngcon to convert the constant from type native integer to the
9178      * user defined integer type -- if the types are the same cngcon will
9179      * just return.
9180      */
9181     conval = cngcon(conval, DT_INT, dtyper);
9182     SST_CVALP(stktop, conval);
9183     EXPSTP(pdsym, 1); /* freeze generic or specific name */
9184     SST_SHAPEP(stktop, 0);
9185     ast = mk_cval1(conval, dtyper);
9186     SST_ASTP(stktop, ast);
9187     return conval;
9188 
9189   case PD_logical:
9190     if (count < 1 || count > 2) {
9191       E74_CNT(pdsym, count, 1, 2);
9192       goto call_e74_cnt;
9193     }
9194     if (get_kwd_args(list, 2, KWDARGSTR(pdsym)))
9195       goto exit_;
9196     stkp = ARG_STK(0);
9197     dtype1 = DDTG(SST_DTYPEG(stkp));
9198     if (!DT_ISLOG(dtype1)) {
9199       E74_ARG(pdsym, 0, NULL);
9200       goto call_e74_arg;
9201     }
9202     dtyper = stb.user.dt_log;  /* default logical */
9203     if ((stkp = ARG_STK(1))) { /* kind */
9204       dtyper = set_kind_result(stkp, DT_LOG, TY_LOG);
9205       if (!dtyper) {
9206         E74_ARG(pdsym, 1, NULL);
9207         goto call_e74_arg;
9208       }
9209     }
9210     (void)mkexpr(ARG_STK(0));
9211     cngtyp(ARG_STK(0), dtyper);
9212     XFR_ARGAST(0);
9213     stkp = ARG_STK(0);
9214     shaper = SST_SHAPEG(stkp);
9215     ast = ARG_AST(0);
9216     if (dtype1 != dtyper) {
9217       argt_count = 1;
9218       goto gen_call;
9219     }
9220     goto expr_val;
9221 
9222   case PD_maxexponent:
9223   case PD_minexponent:
9224     if (count != 1) {
9225       E74_CNT(pdsym, count, 1, 1);
9226       goto call_e74_cnt;
9227     }
9228     if (get_kwd_args(list, 1, KWDARGSTR(pdsym)))
9229       goto exit_;
9230     dtype1 = DDTG(SST_DTYPEG(ARG_STK(0)));
9231     switch (DTY(dtype1)) {
9232     case TY_REAL:
9233       conval = pdtype == PD_maxexponent ? 128 : -125;
9234       break;
9235     case TY_DBLE:
9236       if (XBIT(49, 0x40000)) /* C90 */
9237         conval = pdtype == PD_maxexponent ? 8189 : -8188;
9238       else
9239         conval = pdtype == PD_maxexponent ? 1024 : -1021;
9240       break;
9241     case TY_QUAD:
9242       if (XBIT(49, 0x40000)) /* C90 */
9243         conval = pdtype == PD_maxexponent ? 8189 : -8188;
9244       else
9245         conval = pdtype == PD_maxexponent ? 16384 : -16381;
9246     default:
9247       E74_ARG(pdsym, 0, NULL);
9248       goto call_e74_arg;
9249     }
9250     goto const_default_int_val; /*return default integer*/
9251 
9252   case PD_nearest:
9253     if (count != 2) {
9254       E74_CNT(pdsym, count, 2, 2);
9255       goto call_e74_cnt;
9256     }
9257     if (evl_kwd_args(list, 2, KWDARGSTR(pdsym)))
9258       goto exit_;
9259     stkp = ARG_STK(0);
9260     shaper = SST_SHAPEG(stkp);
9261     dtype1 = DDTG(SST_DTYPEG(stkp));
9262     dtype2 = DDTG(SST_DTYPEG(ARG_STK(1)));
9263     if (!DT_ISREAL(dtype1) || !DT_ISREAL(dtype2)) {
9264       E74_ARG(pdsym, 0, NULL);
9265       goto call_e74_arg;
9266     }
9267     shape2 = SST_SHAPEG(ARG_STK(1));
9268     shaper = set_shape_result(shaper, shape2);
9269     if (shaper < 0) {
9270       E74_ARG(pdsym, 2, NULL);
9271       goto call_e74_arg;
9272     }
9273     ast = ARG_AST(1);
9274     if (shape2)
9275       dtyper = get_array_dtype(1, DT_LOG);
9276     else
9277       dtyper = DT_LOG;
9278     if (DTY(dtype2) == TY_REAL)
9279       ast = mk_binop(OP_GE, ast, mk_cnst(stb.flt0), dtyper);
9280     else
9281       ast = mk_binop(OP_GE, ast, mk_cnst(stb.dbl0), dtyper);
9282     ARG_AST(1) = ast;
9283     if (DTY(dtype1) == TY_REAL)
9284       rtlRtn = RTE_nearest;
9285     else /* TY_DBLE */
9286       rtlRtn = RTE_nearestd;
9287     (void)sym_mkfunc_nodesc(mkRteRtnNm(rtlRtn), dtype1);
9288     dtyper = SST_DTYPEG(stkp);
9289     if (shaper && DTY(dtyper) != TY_ARRAY)
9290       dtyper = get_array_dtype(1, dtyper);
9291     break;
9292 
9293   case PD_precision:
9294     if (count != 1) {
9295       E74_CNT(pdsym, count, 1, 1);
9296       goto call_e74_cnt;
9297     }
9298     if (get_kwd_args(list, 1, KWDARGSTR(pdsym)))
9299       goto exit_;
9300     dtype1 = DDTG(SST_DTYPEG(ARG_STK(0)));
9301     switch (DTY(dtype1)) {
9302     /* values for real/double taken from float.h <type>_DIG */
9303     case TY_REAL:
9304     case TY_CMPLX:
9305       conval = 6;
9306       break;
9307     case TY_DBLE:
9308     case TY_DCMPLX:
9309       if (XBIT(49, 0x40000)) /* C90 */
9310         conval = 13;
9311       else
9312         conval = 15;
9313       break;
9314     case TY_QCMPLX:
9315     case TY_QUAD:
9316       if (XBIT(49, 0x40000)) /* C90 */
9317         conval = 28;
9318       else
9319         conval = 33;
9320       break;
9321     default:
9322       E74_ARG(pdsym, 0, NULL);
9323       goto call_e74_arg;
9324     }
9325     goto const_default_int_val; /*return default integer*/
9326 
9327   case PD_radix:
9328     if (count != 1) {
9329       E74_CNT(pdsym, count, 1, 1);
9330       goto call_e74_cnt;
9331     }
9332     if (get_kwd_args(list, 1, KWDARGSTR(pdsym)))
9333       goto exit_;
9334     dtype1 = DDTG(SST_DTYPEG(ARG_STK(0)));
9335     switch (DTY(dtype1)) {
9336     case TY_BINT:
9337     case TY_SINT:
9338     case TY_INT:
9339     case TY_INT8:
9340     case TY_REAL:
9341     case TY_DBLE:
9342       conval = 2;
9343       break;
9344     default:
9345       E74_ARG(pdsym, 0, NULL);
9346       goto call_e74_arg;
9347     }
9348     goto const_default_int_val; /*return default integer*/
9349 
9350   case PD_range:
9351     if (count != 1) {
9352       E74_CNT(pdsym, count, 1, 1);
9353       goto call_e74_cnt;
9354     }
9355     if (get_kwd_args(list, 1, KWDARGSTR(pdsym)))
9356       goto exit_;
9357     dtype1 = DDTG(SST_DTYPEG(ARG_STK(0)));
9358     switch (DTY(dtype1)) {
9359     case TY_BINT:
9360       conval = 2;
9361       break;
9362     case TY_SINT:
9363       conval = 4;
9364       break;
9365     case TY_INT:
9366       conval = 9;
9367       break;
9368     case TY_INT8:
9369       conval = 18;
9370       break;
9371     case TY_REAL:
9372     case TY_CMPLX:
9373       conval = 37;
9374       break;
9375     case TY_DBLE:
9376     case TY_DCMPLX:
9377       if (XBIT(49, 0x40000)) /* C90 */
9378         conval = 2465;
9379       else
9380         conval = 307;
9381       break;
9382     case TY_QUAD:
9383     case TY_QCMPLX:
9384       if (XBIT(49, 0x40000)) /* C90 */
9385         conval = 2465;
9386       else
9387         conval = 4931;
9388       break;
9389     default:
9390       E74_ARG(pdsym, 0, NULL);
9391       goto call_e74_arg;
9392     }
9393     goto const_default_int_val; /*return default integer*/
9394 
9395   case PD_scale:
9396   case PD_set_exponent:
9397     if (count != 2) {
9398       E74_CNT(pdsym, count, 2, 2);
9399       goto call_e74_cnt;
9400     }
9401     if (evl_kwd_args(list, 2, KWDARGSTR(pdsym)))
9402       goto exit_;
9403     stkp = ARG_STK(0);
9404     dtyper = SST_DTYPEG(stkp);
9405     shaper = SST_SHAPEG(stkp);
9406     dtype1 = DDTG(dtyper);
9407     if (!DT_ISREAL(dtype1)) {
9408       E74_ARG(pdsym, 0, NULL);
9409       goto call_e74_arg;
9410     }
9411     dtype2 = SST_DTYPEG(ARG_STK(1));
9412     if (!DT_ISINT(DDTG(dtype2))) {
9413       E74_ARG(pdsym, 1, NULL);
9414       goto call_e74_arg;
9415     }
9416     shape1 = SST_SHAPEG(ARG_STK(1));
9417     shaper = set_shape_result(shaper, shape1);
9418     if (shaper < 0) {
9419       E74_ARG(pdsym, 1, NULL);
9420       goto call_e74_arg;
9421     }
9422     if (shaper && DTY(dtyper) != TY_ARRAY)
9423       dtyper = get_array_dtype(1, dtyper);
9424     if (DTY(dtype1) == TY_REAL) {
9425       if (pdtype == PD_scale)
9426         rtlRtn = RTE_scale;
9427       else
9428         rtlRtn = RTE_setexp;
9429     } else { /* TY_DBLE */
9430       if (pdtype == PD_scale)
9431         rtlRtn = RTE_scaled;
9432       else
9433         rtlRtn = RTE_setexpd;
9434     }
9435     (void)sym_mkfunc_nodesc(mkRteRtnNm(rtlRtn), dtype1);
9436     break;
9437 
9438   case PD_tiny:
9439     if (count != 1) {
9440       E74_CNT(pdsym, count, 1, 1);
9441       goto call_e74_cnt;
9442     }
9443     if (get_kwd_args(list, 1, KWDARGSTR(pdsym)))
9444       goto exit_;
9445     dtype1 = DDTG(SST_DTYPEG(ARG_STK(0)));
9446     switch (DTY(dtype1)) {
9447     case TY_REAL:
9448       /* 1.175494351E-38 */
9449       val[0] = 0x00800000; /* was 0x00400000 */
9450       sname = "tiny(1.0_4)";
9451       goto const_real_val;
9452     case TY_DBLE:
9453       if (XBIT(49, 0x40000)) {            /* C90 */
9454 #define C90_TINY "0.73344154702194e-2465" /* 0200044000000000000000 */
9455         atoxd(C90_TINY, &val[0], strlen(C90_TINY));
9456       } else {
9457         /* 2.22507385850720138E-308 */
9458         val[0] = 0x00100000; /* was 0x00080000 */
9459         val[1] = 0x00000000;
9460       }
9461       sname = "tiny(1.0_8)";
9462       if (XBIT(51, 0x10))
9463         goto const_dword_val;
9464       goto const_dble_val;
9465     default:
9466       break;
9467     }
9468     E74_ARG(pdsym, 0, NULL);
9469     goto call_e74_arg;
9470 
9471   case PD_index:
9472 #ifdef PD_kindex
9473   case PD_kindex:
9474 #endif
9475     if (count < 2 || count > 4) {
9476       E74_CNT(pdsym, count, 2, 4);
9477       goto call_e74_cnt;
9478     }
9479     if (evl_kwd_args(list, 4, KWDARGSTR(pdsym)))
9480       goto exit_;
9481 
9482     stkp = ARG_STK(0); /* string */
9483     if (DTY(DDTG(SST_DTYPEG(stkp))) != TY_CHAR &&
9484         DTY(DDTG(SST_DTYPEG(stkp))) != TY_NCHAR) {
9485       E74_ARG(pdsym, 0, NULL);
9486       goto call_e74_arg;
9487     }
9488 
9489     shaper = SST_SHAPEG(stkp);
9490     stkp = ARG_STK(1); /* substring */
9491     if (DTY(DDTG(SST_DTYPEG(stkp))) != TY_CHAR &&
9492         DTY(DDTG(SST_DTYPEG(stkp))) != TY_NCHAR) {
9493       E74_ARG(pdsym, 1, NULL);
9494       goto call_e74_arg;
9495     }
9496     shape1 = SST_SHAPEG(stkp);
9497     shaper = set_shape_result(shaper, shape1);
9498     if (shaper < 0) {
9499       E74_ARG(pdsym, 0, NULL);
9500       goto call_e74_arg;
9501     }
9502 
9503     if ((stkp = ARG_STK(2))) { /* back */
9504       dtype2 = SST_DTYPEG(stkp);
9505       if (!DT_ISLOG(DDTG(dtype2))) {
9506         E74_ARG(pdsym, 2, NULL);
9507         goto call_e74_arg;
9508       }
9509       shape2 = SST_SHAPEG(stkp);
9510       shaper = set_shape_result(shaper, shape2);
9511       if (shaper < 0) {
9512         E74_ARG(pdsym, 2, NULL);
9513         goto call_e74_arg;
9514       }
9515     } else
9516       ARG_AST(2) = mk_cval((INT)SCFTN_FALSE, DT_LOG);
9517 
9518     dtyper = stb.user.dt_int;
9519     if ((stkp = ARG_STK(3))) { /* kind */
9520       dtyper = set_kind_result(stkp, DT_INT, TY_INT);
9521       if (!dtyper) {
9522         E74_ARG(pdsym, 3, NULL);
9523         goto call_e74_arg;
9524       }
9525     }
9526 
9527     if (A_ALIASG(ARG_AST(0)) && A_ALIASG(ARG_AST(1)) && A_ALIASG(ARG_AST(2))) {
9528       conval =
9529           _index(A_SPTRG(A_ALIASG(ARG_AST(0))), A_SPTRG(A_ALIASG(ARG_AST(1))),
9530                  A_SPTRG(A_ALIASG(ARG_AST(2))));
9531       goto const_kind_int_val; /*return kind,default integer*/
9532     }
9533 
9534     if (sem.dinit_data) {
9535       gen_init_intrin_call(stktop, pdsym, count, dtyper, TRUE);
9536       return 0;
9537     }
9538 
9539     hpf_sym = sym_mkfunc_nodesc(mkRteRtnNm(RTE_indexa), dtyper);
9540 
9541     argt_count = 4;
9542     /* pass the kind of the logical argument back */
9543     ARG_AST(3) = (mk_cval(size_of(DDTG(A_DTYPEG(ARG_AST(2)))), astb.bnd.dtype));
9544 
9545     if (shaper)
9546       dtyper = get_array_dtype(1, dtyper);
9547 
9548     break;
9549 
9550   case PD_repeat:
9551     if (count != 2) {
9552       E74_CNT(pdsym, count, 2, 2);
9553       goto call_e74_cnt;
9554     }
9555     if (evl_kwd_args(list, 2, KWDARGSTR(pdsym)))
9556       goto exit_;
9557     stkp = ARG_STK(0); /* string */
9558     dtype1 = SST_DTYPEG(stkp);
9559     if (DTY(dtype1) != TY_CHAR && DTY(dtype1) != TY_NCHAR) {
9560       E74_ARG(pdsym, 0, NULL);
9561       goto call_e74_arg;
9562     }
9563     stkp = ARG_STK(1); /* ncopies */
9564     dtype2 = SST_DTYPEG(stkp);
9565     if (!DT_ISINT(dtype2)) {
9566       E74_ARG(pdsym, 1, NULL);
9567       goto call_e74_arg;
9568     }
9569 
9570     ast = ARG_AST(1);
9571     if (A_ALIASG(ARG_AST(0)) && A_ALIASG(ast)) {
9572       sptr = _repeat(A_SPTRG(A_ALIASG(ARG_AST(0))), A_SPTRG(A_ALIASG(ast)));
9573       goto const_str_val;
9574     }
9575     if (sem.dinit_data) {
9576       int ncopies = get_int_cval(A_SPTRG(A_ALIASG(ast)));
9577       int cvlen = string_length(dtype1);
9578       int dtypeintr =
9579           get_type(2, DTYG(dtype1), mk_cval(ncopies * cvlen, stb.user.dt_int));
9580       gen_init_intrin_call(stktop, pdsym, count, dtypeintr, FALSE);
9581       return 0;
9582     }
9583     ARG_AST(2) = mk_cval(size_of(DDTG(A_DTYPEG(ast))), astb.bnd.dtype);
9584 
9585     ast = mk_id(get_temp(DT_INT));
9586     if (dtype1 != DT_ASSCHAR && dtype1 != DT_ASSNCHAR) {
9587       tmp = DTY(dtype1 + 1);
9588     } else {
9589       sptr = sym_mkfunc_nodesc(mkRteRtnNm(RTE_lena), DT_INT);
9590       tmp = begin_call(A_FUNC, sptr, 1);
9591       add_arg(ARG_AST(0));
9592     }
9593     tmp = mk_binop(OP_MUL, tmp, ARG_AST(1), DT_INT);
9594     tmp = mk_assn_stmt(ast, tmp, DT_INT);
9595     (void)add_stmt(tmp);
9596 
9597     if (DTY(dtype1) == TY_CHAR) {
9598       hpf_sym = sym_mkfunc_nodesc(mkRteRtnNm(RTE_repeata), astb.bnd.dtype);
9599       dtyper = get_type(2, TY_CHAR, ast);
9600     } else {
9601       hpf_sym = sym_mkfunc_nodesc(mkRteRtnNm(RTE_nrepeat), DT_INT);
9602       dtyper = get_type(2, TY_NCHAR, ast);
9603     }
9604     arrtmp_ast = mk_id(get_ch_temp(dtyper));
9605     func_ast = begin_call(A_CALL, hpf_sym, 4);
9606     add_arg(arrtmp_ast);
9607     add_arg(ARG_AST(0));
9608     add_arg(ARG_AST(1));
9609     add_arg(ARG_AST(2));
9610     (void)add_stmt(func_ast);
9611     ast = mk_substr(arrtmp_ast, 0, ast, dtype1);
9612     shaper = 0;
9613     goto expr_val;
9614 
9615   case PD_len:
9616     if (count == 0 || count > 2) {
9617       E74_CNT(pdsym, count, 1, 2);
9618       goto call_e74_cnt;
9619     }
9620     dont_issue_assumedsize_error = 1;
9621     if (evl_kwd_args(list, 2, KWDARGSTR(pdsym)))
9622       goto exit_;
9623     dont_issue_assumedsize_error = 0;
9624     if ((stkp = ARG_STK(1))) { /* KIND */
9625       dtyper = set_kind_result(stkp, DT_INT, TY_INT);
9626       if (!dtyper) {
9627         E74_ARG(pdsym, 1, NULL);
9628         goto call_e74_arg;
9629       }
9630     } else {
9631       dtyper = stb.user.dt_int;
9632     }
9633     goto len_shared;
9634 
9635 #ifdef PD_klen
9636   case PD_klen:
9637     if (count != 1) {
9638       E74_CNT(pdsym, count, 1, 1);
9639       goto call_e74_cnt;
9640     }
9641     dont_issue_assumedsize_error = 1;
9642     if (evl_kwd_args(list, 1, KWDARGSTR(pdsym)))
9643       goto exit_;
9644     dont_issue_assumedsize_error = 0;
9645     dtyper = DT_INT8;
9646 #endif
9647   len_shared:
9648     stkp = ARG_STK(0);
9649     dtype1 = DDTG(SST_DTYPEG(stkp));
9650     if (DTY(dtype1) != TY_CHAR && DTY(dtype1) != TY_NCHAR) {
9651       E74_ARG(pdsym, 0, NULL);
9652       goto call_e74_arg;
9653     }
9654     ast = ARG_AST(0);
9655     if (A_TYPEG(ast) == A_INTR) {
9656       switch (A_OPTYPEG(ast)) {
9657       case I_ADJUSTL: /* adjustl(string) */
9658       case I_ADJUSTR: /* adjustr(string) */
9659         /*  len is just len(string) */
9660         ast = ARGT_ARG(A_ARGSG(ast), 0);
9661         ARG_AST(0) = ast;
9662         break;
9663       }
9664     }
9665     if (A_ALIASG(ast)) {
9666       conval = string_length(dtype1);
9667       goto const_kind_int_val; /*return dtyper integer*/
9668     }
9669     switch (A_TYPEG(ast)) {
9670       int clen;
9671       int sym = 0;
9672     case A_ID:
9673     case A_MEM:
9674     case A_SUBSCR:
9675 #ifdef USELENG
9676       sym = memsym_of_ast(ast);
9677       if (A_TYPEG(ast) == A_MEM && LENG(sym) && USELENG(sym)) {
9678         if (SETKINDG(sym) && !USEKINDG(sym)) {
9679           clen = LENG(sym);
9680         } else {
9681           clen = get_len_parm_by_number(LENG(sym), ENCLDTYPEG(sym), 0);
9682         }
9683         if (clen) {
9684           clen = mk_member(A_PARENTG(ast), clen, ENCLDTYPEG(sym));
9685         } else {
9686           clen = DTY(dtype1 + 1);
9687         }
9688       } else
9689 #endif
9690       {
9691         if (!sym)
9692           sym = memsym_of_ast(ast);
9693         if (ADJLENG(sym)) {
9694           clen = mk_id(CVLENG(sym));
9695         } else {
9696           clen = DTY(dtype1 + 1);
9697         }
9698       }
9699       if (clen && A_ALIASG(clen)) {
9700         /* not assumed-size */
9701         conval = string_length(dtype1);
9702         goto const_kind_int_val; /*return dtyper integer*/
9703       } else if (clen) {
9704         ast = clen;
9705         goto expr_val;
9706       }
9707       break;
9708     }
9709     if (DTY(SST_DTYPEG(stkp)) == TY_ARRAY) {
9710       if (pdtype == PD_len) {
9711         hpf_sym =
9712             sym_mkfunc_nodesc_expst(mkRteRtnNm(RTE_lena), stb.user.dt_int);
9713         /*
9714          * need to generete the call here since gen_call assumes that
9715          * the type of result of the function is the type of the
9716          * intrinsic.
9717          */
9718         argt = mk_argt(1);
9719         ARGT_ARG(argt, 0) = ARG_AST(0);
9720         func_ast = mk_id(hpf_sym);
9721         ast = mk_func_node(A_FUNC, func_ast, 1, argt);
9722         A_DTYPEP(ast, stb.user.dt_int);
9723         A_DTYPEP(func_ast, stb.user.dt_int);
9724         if (dtyper != stb.user.dt_int)
9725           ast = mk_convert(ast, dtyper);
9726         goto expr_val;
9727       }
9728       hpf_sym = sym_mkfunc_nodesc_expst(mkRteRtnNm(RTE_lena), DT_INT8);
9729       func_type = A_FUNC;
9730     }
9731     argt_count = 1;
9732     break;
9733 
9734   case PD_len_trim:
9735     if (count < 1 || count > 2) {
9736       E74_CNT(pdsym, count, 1, 2);
9737       goto call_e74_cnt;
9738     }
9739     if (evl_kwd_args(list, 2, KWDARGSTR(pdsym)))
9740       goto exit_;
9741 
9742     stkp = ARG_STK(0);
9743     dtype1 = DDTG(SST_DTYPEG(stkp));
9744     shaper = SST_SHAPEG(stkp);
9745     if (DTY(dtype1) != TY_CHAR && DTY(dtype1) != TY_NCHAR) {
9746       E74_ARG(pdsym, 0, NULL);
9747       goto call_e74_arg;
9748     }
9749     dtyper = stb.user.dt_int;
9750     if ((stkp = ARG_STK(1))) {
9751       dtyper = set_kind_result(stkp, DT_INT, TY_INT);
9752       if (!dtyper) {
9753         E74_ARG(pdsym, 1, NULL);
9754         goto call_e74_arg;
9755       }
9756     }
9757     ast = ARG_AST(0);
9758     if (A_ALIASG(ast)) {
9759       conval = _len_trim(A_SPTRG(A_ALIASG(ast)));
9760       goto const_kind_int_val;
9761     }
9762     if (sem.dinit_data) {
9763       gen_init_intrin_call(stktop, pdsym, count, dtyper, FALSE);
9764       return 0;
9765     }
9766     argt_count = 1;
9767     if (shaper)
9768       dtyper = get_array_dtype(1, dtyper);
9769     break;
9770 
9771   case PD_trim:
9772     if (count != 1) {
9773       E74_CNT(pdsym, count, 1, 1);
9774       goto call_e74_cnt;
9775     }
9776     if (evl_kwd_args(list, 1, KWDARGSTR(pdsym)))
9777       goto exit_;
9778     stkp = ARG_STK(0);
9779     dtype1 = SST_DTYPEG(stkp);
9780     if (DTY(dtype1) != TY_CHAR && DTY(dtype1) != TY_NCHAR) {
9781       E74_ARG(pdsym, 0, NULL);
9782       goto call_e74_arg;
9783     }
9784     if (A_ALIASG(ARG_AST(0))) {
9785       sptr = _trim(A_SPTRG(A_ALIASG(ARG_AST(0))));
9786       goto const_str_val;
9787     }
9788     if (sem.dinit_data) {
9789       gen_init_intrin_call(stktop, pdsym, count, dtype1, FALSE);
9790       return 0;
9791     }
9792     if (DTY(dtype1) == TY_CHAR)
9793       dtyper = DT_ASSCHAR;
9794     else
9795       dtyper = DT_ASSNCHAR;
9796     /* check if the dtype warrants an allocatable temp; if so,
9797      * need indicate this so that if the context is a relational
9798      * expression, the expression will be evaluated an assigned
9799      * to a temp.
9800      */
9801     (void)need_alloc_ch_temp(dtyper);
9802     break;
9803 
9804   case PD_transfer:
9805     if (count < 2 || count > 3) {
9806       E74_CNT(pdsym, count, 2, 3);
9807       goto call_e74_cnt;
9808     }
9809     if (evl_kwd_args(list, 3, KWDARGSTR(pdsym)))
9810       goto exit_;
9811     argt_count = 3;
9812 
9813     stkp = ARG_STK(1); /* mold */
9814     dtyper = SST_DTYPEG(stkp);
9815     shaper = SST_SHAPEG(stkp);
9816 
9817     if ((stkp = ARG_STK(2))) { /* size */
9818       dtype2 = SST_DTYPEG(stkp);
9819       if (!DT_ISINT(dtype2)) {
9820         E74_ARG(pdsym, 2, NULL);
9821         goto call_e74_arg;
9822       }
9823     }
9824 
9825     if (sem.dinit_data) {
9826       /* If the result is array-valued, we need to determine its type. */
9827       if (shaper != 0 || stkp != NULL) {
9828         int size_ast;
9829         ISZ_T size;
9830 
9831         if (stkp != NULL)
9832           size_ast = ARG_AST(2); /* use size */
9833         else {
9834           /* No size specified.
9835            * Make result big enough to hold all of source.
9836            */
9837           size = size_of(DDTG(dtyper));
9838           size = (size_of(SST_DTYPEG(ARG_STK(0))) + size - 1) / size;
9839           size_ast = mk_isz_cval(size, astb.bnd.dtype);
9840         }
9841         add_shape_rank(1);
9842         add_shape_spec(astb.bnd.one, size_ast, astb.bnd.one);
9843         shaper = mk_shape();
9844         if (DTY(dtyper) != TY_ARRAY)
9845           dtyper = get_array_dtype(1, dtyper);
9846         dtyper = dtype_with_shape(dtyper, shaper);
9847         ADD_NUMELM(dtyper) = size_ast;
9848       }
9849       gen_init_intrin_call(stktop, pdsym, argt_count, dtyper, FALSE);
9850       return 0;
9851     }
9852 
9853     if (shaper == 0 && stkp == NULL) {
9854       /* result is the 'scalar' type of mold */
9855       shaper = 0;
9856       dtyper = DDTG(dtyper);
9857     } else {
9858       tmp = getcctmp_sc('d', sem.dtemps++, ST_VAR, astb.bnd.dtype, sem.sc);
9859       add_shape_rank(1);
9860       add_shape_spec(astb.bnd.one, mk_id(tmp), astb.bnd.one);
9861       shaper = mk_shape();
9862       if (DTY(dtyper) != TY_ARRAY)
9863         dtyper = get_array_dtype(1, dtyper);
9864       if (stkp != NULL)
9865         ast = ARG_AST(2); /* use size */
9866       else {
9867         /* else compute size by the expression
9868          *   (t1 + t2 - 1) / t2
9869          *
9870          * t1 = (#elements source) * size_of(element type of source)
9871          * t2 = size_of(element type of mold).
9872          */
9873         int t1, t2;
9874         t1 = size_of_ast(ARG_AST(0)); /* #elements in source */
9875         t1 = mk_binop(OP_MUL, t1, elem_size_of_ast(ARG_AST(0)), astb.bnd.dtype);
9876         t2 = elem_size_of_ast(ARG_AST(1));
9877         ast = mk_binop(OP_ADD, t1, t2, astb.bnd.dtype);
9878         ast = mk_binop(OP_SUB, ast, astb.bnd.one, astb.bnd.dtype);
9879         ast = mk_binop(OP_DIV, ast, t2, astb.bnd.dtype);
9880       }
9881       ast = mk_assn_stmt(mk_id(tmp), ast, astb.bnd.dtype);
9882       (void)add_stmt(ast);
9883     }
9884     break;
9885 
9886   case PD_scan:
9887   case PD_verify:
9888     if (count < 2 || count > 4) {
9889       E74_CNT(pdsym, count, 2, 4);
9890       goto call_e74_cnt;
9891     }
9892     if (evl_kwd_args(list, 4, KWDARGSTR(pdsym)))
9893       goto exit_;
9894     argt_count = 3;
9895 
9896     stkp = ARG_STK(0); /* string */
9897     dtype1 = DDTG(SST_DTYPEG(stkp));
9898     if (DTY(dtype1) != TY_CHAR && DTY(dtype1) != TY_NCHAR) {
9899       E74_ARG(pdsym, 0, NULL);
9900       goto call_e74_arg;
9901     }
9902     shaper = SST_SHAPEG(stkp);
9903 
9904     stkp = ARG_STK(1); /* set */
9905     if (DTY(DDTG(SST_DTYPEG(stkp))) != DTY(dtype1)) {
9906       E74_ARG(pdsym, 1, NULL);
9907       goto call_e74_arg;
9908     }
9909     shape1 = SST_SHAPEG(stkp);
9910     shaper = set_shape_result(shaper, shape1);
9911     if (shaper < 0) {
9912       E74_ARG(pdsym, 1, NULL);
9913       goto call_e74_arg;
9914     }
9915 
9916     dtype2 = DT_LOG;
9917     if ((stkp = ARG_STK(2))) { /* back */
9918       ast = ARG_AST(2);
9919       dtype2 = SST_DTYPEG(stkp);
9920       if (!DT_ISLOG(DDTG(dtype2))) {
9921         E74_ARG(pdsym, 2, NULL);
9922         goto call_e74_arg;
9923       }
9924       shape2 = SST_SHAPEG(stkp);
9925       shaper = set_shape_result(shaper, shape2);
9926       if (shaper < 0) {
9927         E74_ARG(pdsym, 2, NULL);
9928         goto call_e74_arg;
9929       }
9930     } else
9931       ast = mk_cval((INT)SCFTN_FALSE, DT_LOG);
9932 
9933     dtyper = stb.user.dt_int;
9934     if ((stkp = ARG_STK(3))) { /* kind */
9935       dtyper = set_kind_result(stkp, DT_INT, TY_INT);
9936       if (!dtyper) {
9937         E74_ARG(pdsym, 3, NULL);
9938         goto call_e74_arg;
9939       }
9940     }
9941 
9942     if (DTY(dtype1) == TY_CHAR && A_ALIASG(ARG_AST(0)) &&
9943         A_ALIASG(ARG_AST(1)) && A_ALIASG(ast)) {
9944       if (pdtype == PD_verify)
9945         conval = _verify(A_SPTRG(A_ALIASG(ARG_AST(0))),
9946                          A_SPTRG(A_ALIASG(ARG_AST(1))), A_SPTRG(A_ALIASG(ast)));
9947       else
9948         conval = _scan(A_SPTRG(A_ALIASG(ARG_AST(0))),
9949                        A_SPTRG(A_ALIASG(ARG_AST(1))), A_SPTRG(A_ALIASG(ast)));
9950       goto const_kind_int_val; /*return default integer*/
9951     }
9952 
9953     if (sem.dinit_data) {
9954       gen_init_intrin_call(stktop, pdsym, count, dtyper, TRUE);
9955       return 0;
9956     }
9957 
9958     ARG_AST(2) = ast;
9959     ARG_AST(3) = mk_cval(size_of(DDTG(dtype2)), astb.bnd.dtype);
9960     argt_count = 4;
9961     if (DTY(dtype1) == TY_CHAR) {
9962       if (pdtype == PD_verify)
9963         rtlRtn = RTE_verifya;
9964       else
9965         rtlRtn = RTE_scana;
9966     } else { /* TY_NCHAR */
9967       if (pdtype == PD_verify)
9968         rtlRtn = RTE_nverify;
9969       else
9970         rtlRtn = RTE_nscan;
9971     }
9972 
9973     hpf_sym = sym_mkfunc_nodesc(mkRteRtnNm(rtlRtn), dtyper);
9974 
9975     if (shaper)
9976       dtyper = get_array_dtype(1, dtyper);
9977     break;
9978 
9979   case PD_ilen:
9980     if (count != 1) {
9981       E74_CNT(pdsym, count, 1, 1);
9982       goto call_e74_cnt;
9983     }
9984     if (get_kwd_args(list, 1, KWDARGSTR(pdsym)))
9985       goto exit_;
9986     stkp = ARG_STK(0); /* i */
9987     dtyper = SST_DTYPEG(stkp);
9988     shaper = SST_SHAPEG(stkp);
9989     dtype1 = DDTG(dtyper);
9990     if (!DT_ISINT(dtype1)) {
9991       E74_ARG(pdsym, 0, NULL);
9992       goto call_e74_arg;
9993     }
9994     if (is_sst_const(stkp)) {
9995       /*
9996        * if i is nonnegative,
9997        *     ilen(i) = ceiling(log2(i+1))
9998        * if i is negative,
9999        *     ilen(i) = ceiling(log2(-i))
10000        */
10001       INT tmp[2];
10002       INT zero[2];
10003       INT vval[2];
10004       int len;
10005       int i;
10006 
10007       con1 = get_sst_cval(stkp);
10008       if (DTY(dtype1) == TY_INT8 || DTY(dtype1) == TY_LOG8) {
10009         val[0] = CONVAL1G(con1);
10010         val[1] = CONVAL2G(con1);
10011       } else {
10012         if (con1 < 0)
10013           val[0] = -1;
10014         else
10015           val[0] = 0;
10016         val[1] = con1;
10017       }
10018       zero[0] = zero[1] = 0;
10019       if (cmp64(val, zero) < 0)
10020         neg64(val, val);
10021       else {
10022         tmp[0] = 0;
10023         tmp[1] = 1;
10024         add64(val, tmp, val);
10025       }
10026       vval[0] = val[0];
10027       vval[1] = val[1];
10028       len = -1;
10029       while (cmp64(val, zero) != 0) {
10030         ushf64((UINT *)val, -1, (UINT *)val);
10031         ++len;
10032       }
10033       tmp[0] = 0;
10034       tmp[1] = 1;
10035       shf64(tmp, len, tmp);
10036       /* if number is larger than 2**(bit pos), increase by one */
10037       xor64(tmp, vval, tmp);
10038       if (cmp64(tmp, zero) != 0)
10039         ++len;
10040       conval = len;
10041       goto const_default_int_val; /*return default integer*/
10042     }
10043     (void)mkexpr(ARG_STK(0));
10044     XFR_ARGAST(0);
10045     ast = ARG_AST(0);
10046     ARG_AST(1) = mk_cval(size_of(DDTG(A_DTYPEG(ast))), astb.bnd.dtype);
10047     argt_count = 2;
10048     fsptr = sym_mkfunc_nodesc(mkRteRtnNm(RTE_ilen), astb.bnd.dtype);
10049     EXTSYMP(pdsym, fsptr);
10050     break;
10051 
10052   case PD_processors_shape:
10053     if (count) {
10054       E74_CNT(pdsym, count, 0, 0);
10055       goto call_e74_cnt;
10056     }
10057     tmp = getcctmp_sc('d', sem.dtemps++, ST_VAR, DT_INT, sem.sc);
10058     add_shape_rank(1);
10059     add_shape_spec(astb.i1, mk_id(tmp), astb.i1);
10060     shaper = mk_shape();
10061     dtyper = aux.dt_iarray;
10062 
10063     sptr = sym_mkfunc_nodesc(mkRteRtnNm(RTE_processors_rank), stb.user.dt_int);
10064     ast = mk_func_node(A_FUNC, mk_id(sptr), 0, 0);
10065     A_DTYPEP(ast, DT_INT);
10066 
10067     ast = mk_assn_stmt(mk_id(tmp), ast, DT_INT);
10068 
10069     (void)add_stmt(ast);
10070 
10071     argt_count = 0;
10072     break;
10073 
10074   case PD_same_type_as:
10075   case PD_extends_type_of: {
10076     int dt1, dt2, sptrsdsc, argsptr, argsptr2, fsptr, flag, mast1, mast2;
10077     int decl1, decl2, flag_con;
10078     static int tmp = 0;
10079 
10080     if (count != 2) {
10081       E74_CNT(pdsym, count, 1, 2);
10082       goto call_e74_cnt;
10083     }
10084     if (evl_kwd_args(list, 2, KWDARGSTR(pdsym)))
10085       goto exit_;
10086 
10087     dt1 = A_DTYPEG(ARG_AST(0));
10088     dt2 = A_DTYPEG(ARG_AST(1));
10089     if (DTY(dt1) == TY_ARRAY) {
10090       dt1 = DTY(dt1 + 1);
10091     }
10092 
10093     if (DTY(dt2) == TY_ARRAY) {
10094       dt2 = DTY(dt2 + 1);
10095     }
10096 
10097     if (DTY(dt1) != TY_DERIVED) {
10098       /* TBD - Probably need to fix this condition when we implement
10099        * unlimited polymorphic types.
10100        */
10101       E74_ARG(pdsym, 0, NULL);
10102       goto call_e74_arg;
10103     }
10104     if (DTY(dt2) != TY_DERIVED) {
10105       /* TBD - Probably need to fix this condition when we implement
10106        * unlimited polymorphic types.
10107        */
10108       E74_ARG(pdsym, 1, NULL);
10109       goto call_e74_arg;
10110     }
10111 
10112     mast1 = ARG_AST(0);
10113     if (A_TYPEG(mast1) == A_SUBSCR) {
10114       /* To avoid lower error - bad OP type */
10115       mast1 = A_LOPG(mast1);
10116     }
10117     argsptr = memsym_of_ast(mast1);
10118     mast2 = ARG_AST(1);
10119     if (A_TYPEG(mast2) == A_SUBSCR) {
10120       /* To avoid lower error - bad OP type */
10121       mast2 = A_LOPG(mast2);
10122     }
10123     argsptr2 = memsym_of_ast(mast2);
10124     if (!CLASSG(argsptr) && !CLASSG(argsptr2)) {
10125       /* we can statically compute the type comparison */
10126       flag = eq_dtype2(dt2, dt1, (pdtype == PD_extends_type_of));
10127       if (flag)
10128         flag = gbl.ftn_true;
10129       ast = mk_cval1(flag, DT_INT);
10130       goto finish_type_cmp;
10131     }
10132 
10133     argt = mk_argt(7);
10134     ARGT_ARG(argt, 0) = mast1;
10135     ARGT_ARG(argt, 2) = mast2;
10136 
10137     if (CLASSG(argsptr)) {
10138       if (POINTERG(argsptr)) {
10139         flag = 1;
10140       } else if (ALLOCATTRG(argsptr)) {
10141         flag = 2;
10142       } else {
10143         flag = 0;
10144       }
10145     } else {
10146       flag = 0;
10147     }
10148 
10149     if (flag & (1 | 2)) {
10150       /* get declared type of arg1 */
10151       decl1 = getccsym('D', tmp++, ST_VAR);
10152       DTYPEP(decl1, DTYPEG(argsptr));
10153       decl1 = get_static_type_descriptor(decl1);
10154     } else {
10155       decl1 = 0;
10156     }
10157 
10158     if (CLASSG(argsptr) && STYPEG(argsptr) == ST_MEMBER) {
10159       int newargt2, astnew, func;
10160       int src_ast, std;
10161       int sdsc_mem = get_member_descriptor(argsptr);
10162       if (CLASSG(argsptr)) {
10163         sptrsdsc = get_type_descr_arg(gbl.currsub, argsptr);
10164       } else {
10165         sptrsdsc = getccsym('D', tmp++, ST_VAR);
10166         DTYPEP(sptrsdsc, DTYPEG(argsptr));
10167         sptrsdsc = get_static_type_descriptor(sptrsdsc);
10168       }
10169       ARGT_ARG(argt, 1) = mk_id(sptrsdsc);
10170 
10171       src_ast = mk_member(A_PARENTG(mast1), mk_id(sdsc_mem), A_DTYPEG(mast1));
10172       std = add_stmt(mk_stmt(A_CONTINUE, 0));
10173       gen_set_type(mk_id(sptrsdsc), src_ast, std, FALSE, FALSE);
10174     } else {
10175       if (CLASSG(argsptr)) {
10176         sptrsdsc = get_type_descr_arg(gbl.currsub, argsptr);
10177       } else {
10178         sptrsdsc = getccsym('D', tmp++, ST_VAR);
10179         DTYPEP(sptrsdsc, DTYPEG(argsptr));
10180         sptrsdsc = get_static_type_descriptor(sptrsdsc);
10181       }
10182       ARGT_ARG(argt, 1) = mk_id(sptrsdsc);
10183     }
10184 
10185     if (CLASSG(argsptr2)) {
10186       if (POINTERG(argsptr2)) {
10187         flag |= 4;
10188       } else if (ALLOCATTRG(argsptr2)) {
10189         flag |= 8;
10190       }
10191     }
10192 
10193     if (flag & (4 | 8)) {
10194       /* get declared type of arg2 */
10195       decl2 = getccsym('D', tmp++, ST_VAR);
10196       DTYPEP(decl2, DTYPEG(argsptr2));
10197       decl2 = get_static_type_descriptor(decl2);
10198     } else {
10199       decl2 = 0;
10200     }
10201     if (CLASSG(argsptr2) && STYPEG(argsptr2) == ST_MEMBER) {
10202       int newargt2, func, astnew;
10203       int src_ast, std;
10204       int sdsc_mem = get_member_descriptor(argsptr2);
10205       if (CLASSG(argsptr2)) {
10206         sptrsdsc = get_type_descr_arg(gbl.currsub, argsptr2);
10207       } else {
10208         sptrsdsc = getccsym('D', tmp++, ST_VAR);
10209         DTYPEP(sptrsdsc, DTYPEG(argsptr2));
10210         sptrsdsc = get_static_type_descriptor(sptrsdsc);
10211       }
10212 
10213       ARGT_ARG(argt, 3) = mk_id(sptrsdsc);
10214       src_ast = mk_member(A_PARENTG(mast2), mk_id(sdsc_mem), A_DTYPEG(mast2));
10215       std = add_stmt(mk_stmt(A_CONTINUE, 0));
10216       gen_set_type(mk_id(sptrsdsc), src_ast, std, FALSE, FALSE);
10217 
10218     } else {
10219       if (CLASSG(argsptr2)) {
10220         sptrsdsc = get_type_descr_arg(gbl.currsub, argsptr2);
10221       } else {
10222         sptrsdsc = getccsym('D', tmp++, ST_VAR);
10223         DTYPEP(sptrsdsc, DTYPEG(argsptr2));
10224         sptrsdsc = get_static_type_descriptor(sptrsdsc);
10225       }
10226 
10227       ARGT_ARG(argt, 3) = mk_id(sptrsdsc);
10228     }
10229 
10230     flag_con = mk_cval1(flag, DT_INT);
10231     flag_con = mk_unop(OP_VAL, flag_con, DT_INT);
10232     ARGT_ARG(argt, 4) = flag_con;
10233     argt_count = 5;
10234     if (decl1) {
10235       ARGT_ARG(argt, 5) = mk_id(decl1);
10236       ++argt_count;
10237     }
10238     if (decl2) {
10239       ARGT_ARG(argt, argt_count) = mk_id(decl2);
10240       ++argt_count;
10241     }
10242     if (pdtype == PD_extends_type_of) {
10243       if (XBIT(68, 0x1)) {
10244         fsptr = sym_mkfunc_nodesc(mkRteRtnNm(RTE_extends_type_of), DT_LOG);
10245       } else
10246         fsptr = sym_mkfunc_nodesc(mkRteRtnNm(RTE_extends_type_of), DT_LOG);
10247     } else {
10248       if (XBIT(68, 0x1)) {
10249         fsptr = sym_mkfunc_nodesc(mkRteRtnNm(RTE_same_type_as), DT_LOG);
10250 
10251       } else
10252         fsptr = sym_mkfunc_nodesc(mkRteRtnNm(RTE_same_type_as), DT_LOG);
10253     }
10254     func_ast = mk_id(fsptr);
10255     ast = mk_func_node(A_FUNC, func_ast, argt_count, argt);
10256   finish_type_cmp:
10257     dtyper = stb.user.dt_log;
10258     A_DTYPEP(ast, dtyper);
10259     A_OPTYPEP(ast, INTASTG(pdsym));
10260     goto expr_val;
10261   }
10262   case PD_associated:
10263     if (count < 1 || count > 2) {
10264       E74_CNT(pdsym, count, 1, 2);
10265       goto call_e74_cnt;
10266     }
10267     if (evl_kwd_args(list, 2, KWDARGSTR(pdsym)))
10268       goto exit_;
10269     pvar = find_pointer_variable(ARG_AST(0));
10270     if (pvar == 0 || !POINTERG(pvar)) {
10271       E74_ARG(pdsym, 0, NULL);
10272       goto call_e74_arg;
10273     }
10274     if ((stkp = ARG_STK(1))) { /* target */
10275       find_pointer_target(ARG_AST(1), &baseptr, &sptr);
10276       /* target may be variable, subarray, or derived-type member;
10277        * if variable or subarray, it must be POINTER or TARGET.
10278        * if derived-type member, the base must be a TARGET,
10279        * or the base or member must be POINTER */
10280       if (baseptr == 0 || (!TARGETG(baseptr) && !POINTERG(sptr) &&
10281                            !any_pointer_source(ARG_AST(1)))) {
10282         if (STYPEG(sptr) != ST_PROC || !is_procedure_ptr(pvar)) {
10283           E74_ARG(pdsym, 1, NULL);
10284           goto call_e74_arg;
10285         }
10286       }
10287     }
10288     argt_count = 2;
10289 
10290     dtyper = stb.user.dt_log;
10291     break;
10292 
10293   case PD_is_contiguous:
10294     if (count != 1) {
10295       E74_CNT(pdsym, count, 1, 2);
10296       goto call_e74_cnt;
10297     }
10298     if (evl_kwd_args(list, 1, KWDARGSTR(pdsym)))
10299       goto exit_;
10300     ast = SST_ASTG(ARG_STK(0));
10301     if (A_TYPEG(ast) != A_ID && A_TYPEG(ast) != A_MEM) {
10302       E74_ARG(pdsym, 0, NULL);
10303       goto call_e74_arg;
10304     }
10305     i = memsym_of_ast(ast);
10306     dtype1 = DTYPEG(i);
10307     if (DTY(dtype1) != TY_ARRAY) {
10308       E74_CNT(pdsym, count, 1, 1);
10309       goto call_e74_cnt;
10310     }
10311     dtyper = stb.user.dt_log;
10312     if (CONTIGATTRG(i) || (!ASSUMSHPG(i) && !POINTERG(i))) {
10313       conval = TRUE;
10314       goto const_kind_int_val;
10315     }
10316     argt_count = 2;
10317     if (!SDSCG(i)) {
10318       get_static_descriptor(i);
10319     }
10320     ARG_AST(1) = mk_id(SDSCG(i));
10321     break;
10322 
10323   case PD_ranf:
10324     if (count > 1) {
10325       E74_CNT(pdsym, count, 0, 1);
10326       goto call_e74_cnt;
10327     }
10328     argt_count = 0; /* ignore argument if present */
10329     dtyper = stb.user.dt_real;
10330     break;
10331   case PD_ranget:
10332     if (count > 1) {
10333       E74_CNT(pdsym, count, 0, 1);
10334       goto call_e74_cnt;
10335     }
10336     if (REFG(pdsym) && !FUNCG(pdsym))
10337       goto ill_call; /* can be CALL'd, but must be consistent */
10338     if (get_kwd_args(list, 1, KWDARGSTR(pdsym)))
10339       goto exit_;
10340     if ((stkp = ARG_STK(0))) { /* i */
10341       if (!is_varref(stkp)) {
10342         E74_ARG(pdsym, 0, NULL);
10343         goto call_e74_arg;
10344       }
10345       (void)mkarg(stkp, &dum);
10346       XFR_ARGAST(0);
10347       dtype2 = SST_DTYPEG(stkp);
10348       if (dtype2 != DT_INT) {
10349         E74_ARG(pdsym, 0, NULL);
10350         goto call_e74_arg;
10351       }
10352     }
10353     dtyper = DT_DWORD;
10354     REFP(pdsym, 1);
10355     FUNCP(pdsym, 1);
10356     break;
10357   case PD_ranset:
10358     if (count > 1) {
10359       E74_CNT(pdsym, count, 0, 1);
10360       goto call_e74_cnt;
10361     }
10362     if (REFG(pdsym) && !FUNCG(pdsym))
10363       goto ill_call; /* can be CALL'd, but must be consistent */
10364     if (evl_kwd_args(list, 1, KWDARGSTR(pdsym)))
10365       goto exit_;
10366     if ((stkp = ARG_STK(0))) { /* i */
10367       (void)mkarg(stkp, &dum);
10368       XFR_ARGAST(0);
10369       dtype2 = SST_DTYPEG(stkp);
10370       if (!DT_ISINT(dtype2) && dtype2 != DT_REAL) {
10371         E74_ARG(pdsym, 0, NULL);
10372         goto call_e74_arg;
10373       }
10374     }
10375     dtyper = DT_DWORD;
10376     REFP(pdsym, 1);
10377     FUNCP(pdsym, 1);
10378     break;
10379   case PD_unit:
10380   case PD_length:
10381     if (count != 1) {
10382       E74_CNT(pdsym, count, 1, 1);
10383       goto call_e74_cnt;
10384     }
10385     if (get_kwd_args(list, 1, KWDARGSTR(pdsym)))
10386       goto exit_;
10387     stkp = ARG_STK(0); /* unit number */
10388     (void)mkarg(stkp, &dum);
10389     XFR_ARGAST(0);
10390     dtype2 = SST_DTYPEG(stkp);
10391     if (!DT_ISINT(dtype2)) {
10392       E74_ARG(pdsym, 0, NULL);
10393       goto call_e74_arg;
10394     }
10395     if (pdtype == PD_unit)
10396       dtyper = DT_REAL;
10397     else
10398       dtyper = DT_INT;
10399     break;
10400 
10401   case PD_int_mult_upper:
10402     if (count != 2) {
10403       E74_CNT(pdsym, count, 2, 2);
10404       goto call_e74_cnt;
10405     }
10406     if (evl_kwd_args(list, 2, KWDARGSTR(pdsym)))
10407       goto exit_;
10408     stkp = ARG_STK(0); /* i */
10409     shaper = SST_SHAPEG(stkp);
10410     dtyper = SST_DTYPEG(stkp);
10411     dtype1 = DDTG(dtyper);
10412     if (dtype1 != DT_INT) {
10413       E74_ARG(pdsym, 0, NULL);
10414       goto call_e74_arg;
10415     }
10416     stkp = ARG_STK(1); /* j */
10417     dtype2 = DDTG(SST_DTYPEG(stkp));
10418     if (dtype2 != DT_INT) {
10419       E74_ARG(pdsym, 1, NULL);
10420       goto call_e74_arg;
10421     }
10422     shape2 = SST_SHAPEG(stkp);
10423     if (shaper == 0) {
10424       /* i is scalar - assume the shape of j */
10425       shaper = shape2;
10426       dtyper = SST_DTYPEG(stkp);
10427     } else if (shape2 && !conform_shape(shaper, shape2)) {
10428       /* both i and j have shape */
10429       error(155, 3, gbl.lineno, "Nonconformable arrays passed to intrinsic",
10430             SYMNAME(pdsym));
10431       goto exit_;
10432     }
10433     break;
10434 
10435   case PD_cot:
10436     if (count != 1) {
10437       E74_CNT(pdsym, count, 1, 1);
10438       goto call_e74_cnt;
10439     }
10440     if (evl_kwd_args(list, 1, KWDARGSTR(pdsym)))
10441       goto exit_;
10442     stkp = ARG_STK(0); /* x */
10443     shaper = SST_SHAPEG(stkp);
10444     dtyper = SST_DTYPEG(stkp);
10445     dtype1 = DDTG(dtyper);
10446     if (!DT_ISREAL(dtype1)) {
10447       E74_ARG(pdsym, 0, NULL);
10448       goto call_e74_arg;
10449     }
10450     break;
10451 
10452   case PD_dcot:
10453     if (count != 1) {
10454       E74_CNT(pdsym, count, 1, 1);
10455       goto call_e74_cnt;
10456     }
10457     if (evl_kwd_args(list, 1, KWDARGSTR(pdsym)))
10458       goto exit_;
10459     stkp = ARG_STK(0); /* x */
10460     shaper = SST_SHAPEG(stkp);
10461     dtyper = SST_DTYPEG(stkp);
10462     dtype1 = DDTG(dtyper);
10463     if (dtype1 != DT_QUAD) {
10464       E74_ARG(pdsym, 0, NULL);
10465       goto call_e74_arg;
10466     }
10467     break;
10468 
10469   case PD_shiftl:
10470   case PD_shiftr:
10471     if (count != 2) {
10472       E74_CNT(pdsym, count, 2, 2);
10473       goto call_e74_cnt;
10474     }
10475     if (evl_kwd_args(list, 2, KWDARGSTR(pdsym)))
10476       goto exit_;
10477     stkp = ARG_STK(0); /* i */
10478     shaper = SST_SHAPEG(stkp);
10479     dtype1 = DDTG(SST_DTYPEG(stkp));
10480     if (!DT_ISINT(dtype1) && !DT_ISREAL(dtype1)) {
10481       E74_ARG(pdsym, 0, NULL);
10482       goto call_e74_arg;
10483     }
10484     stkp = ARG_STK(1); /* j */
10485     dtype1 = DDTG(SST_DTYPEG(stkp));
10486     if (!DT_ISINT(dtype1)) {
10487       E74_ARG(pdsym, 0, NULL);
10488       goto call_e74_arg;
10489     }
10490     if (shaper)
10491       dtyper = get_array_dtype(SHD_NDIM(shaper), DT_DWORD);
10492     else
10493       dtyper = DT_DWORD;
10494     break;
10495 
10496   case PD_dshiftl:
10497   case PD_dshiftr:
10498     if (count != 3) {
10499       E74_CNT(pdsym, count, 3, 3);
10500       goto call_e74_cnt;
10501     }
10502     if (evl_kwd_args(list, 3, KWDARGSTR(pdsym)))
10503       goto exit_;
10504     shaper = 0;
10505     for (i = 0; i < 3; i++) {
10506       stkp = ARG_STK(i); /* i, j, k */
10507       dtype1 = DDTG(SST_DTYPEG(stkp));
10508       if (!DT_ISINT(dtype1)) {
10509         E74_ARG(pdsym, i, NULL);
10510         goto call_e74_arg;
10511       }
10512       if (shaper) {
10513         if ((shape1 = SST_SHAPEG(stkp)) &&
10514             SHD_NDIM(shaper) != SHD_NDIM(shape1)) {
10515           E74_ARG(pdsym, i, NULL);
10516           goto call_e74_arg;
10517         }
10518       } else
10519         shaper = SST_SHAPEG(stkp);
10520     }
10521     if (shaper)
10522       dtyper = get_array_dtype(SHD_NDIM(shaper), DT_INT);
10523     else
10524       dtyper = DT_INT;
10525     break;
10526 
10527   case PD_mask:
10528   /* Mask is a cray intrinsic */
10529   like_cray_mask:
10530     if (count != 1) {
10531       E74_CNT(pdsym, count, 1, 1);
10532       goto call_e74_cnt;
10533     }
10534     if (evl_kwd_args(list, 1, KWDARGSTR(pdsym)))
10535       goto exit_;
10536     stkp = ARG_STK(0); /* i */
10537     dtyper = SST_DTYPEG(stkp);
10538     dtype1 = DDTG(dtyper);
10539     if (!DT_ISINT(dtype1)) {
10540       E74_ARG(pdsym, 0, NULL);
10541       goto call_e74_arg;
10542     }
10543     shaper = SST_SHAPEG(stkp);
10544     break;
10545 
10546   case PD_null:
10547     argt_count = 0;
10548     if (count > 1) {
10549       E74_CNT(pdsym, count, 1, 2);
10550       goto call_e74_cnt;
10551     }
10552     if (evl_kwd_args(list, 1, KWDARGSTR(pdsym)))
10553       goto exit_;
10554     if (count == 1) {
10555       if (SST_IDG(ARG_STK(0)) == S_IDENT) {
10556         sptr = SST_SYMG(ARG_STK(0));
10557       } else {
10558         sptr = memsym_of_ast(SST_ASTG(ARG_STK(0)));
10559       }
10560       if (!POINTERG(sptr)) {
10561         errsev(458);
10562         if (INSIDE_STRUCT) {
10563           sem.dinit_error = TRUE;
10564         }
10565         return (fix_term(stktop, stb.i0));
10566       }
10567       dtyper = SST_DTYPEG(ARG_STK(0));
10568       shaper = SST_SHAPEG(ARG_STK(0));
10569       argt_count = 1;
10570     } else {
10571       dtyper = DT_WORD;
10572     }
10573     if (sem.dinit_data || INSIDE_STRUCT) {
10574       gen_init_intrin_call(stktop, pdsym, count, dtyper, FALSE);
10575       return 0;
10576     }
10577     break;
10578 
10579   case PD_int_ptr_kind:
10580     if (count) {
10581       E74_CNT(pdsym, count, 0, 2);
10582       goto call_e74_cnt;
10583     }
10584     conval = size_of(DT_PTR);
10585     goto const_default_int_val; /*return default integer*/
10586 
10587   case PD_c_sizeof:
10588   case PD_sizeof:
10589     if (count != 1) {
10590       E74_CNT(pdsym, count, 1, 1);
10591       goto call_e74_cnt;
10592     }
10593     if (get_kwd_args(list, 1, KWDARGSTR(pdsym)))
10594       goto exit_;
10595 
10596     (void)mkarg(ARG_STK(0), &dum);
10597     XFR_ARGAST(0);
10598     ast = ARG_AST(0);
10599 
10600     if (pdtype == PD_c_sizeof) {
10601       sptr = 0;
10602       if (A_TYPEG(ast) == A_MEM) {
10603         sptr = A_SPTRG(A_MEMG(ast));
10604       } else if (A_TYPEG(ast) == A_ID) {
10605         sptr = A_SPTRG(ast);
10606       }
10607       if (sptr) {
10608         if (POINTERG(sptr) || ALLOCG(sptr) || CLASSG(sptr) || ASSUMSHPG(sptr) ||
10609             ASUMSZG(sptr) ||
10610             (DTY(DTYPEG(sptr)) == TY_DERIVED &&
10611              !(CFUNCG(DTY(DTYPEG(sptr) + 3)) || is_iso_cptr(DTYPEG(sptr)) ||
10612                is_iso_c_funptr(DTYPEG(sptr))))) {
10613           error(4, 3, gbl.lineno,
10614                 "Illegal argument: must be interoperable with a C type", NULL);
10615           goto exit_;
10616         }
10617       }
10618       dtyper = 0;
10619       sptr = refsym(getsymbol("c_size_t"), OC_OTHER);
10620       if (STYPEG(sptr) == ST_PARAM) {
10621         dtyper =
10622             select_kind(DT_INT, TY_INT, get_isz_cval(A_SPTRG(CONVAL2G(sptr))));
10623       } else {
10624         dtyper = select_kind(DT_INT, TY_INT, 8);
10625       }
10626     } else {
10627       if (XBIT(68, 0x1) && XBIT(68, 0x2))
10628         dtyper = DT_INT8;
10629       else
10630         dtyper = stb.user.dt_int;
10631     }
10632     asumsz = 0;
10633     shaper = 0;
10634     dtype1 = SST_DTYPEG(ARG_STK(0));
10635     if (DTY(dtype1) == TY_ARRAY) {
10636       eltype = DTY(dtype1 + 1);
10637       /* FIRST, compute SIZE(arg) */
10638       switch (A_TYPEG(ast)) {
10639       case A_ID:
10640         asumsz = A_SPTRG(ast);
10641         if (SCG(asumsz) != SC_DUMMY || !ASUMSZG(asumsz))
10642           asumsz = 0;
10643         break;
10644       default:
10645         break;
10646       }
10647       sptr = find_pointer_variable(ast);
10648       if (sptr && (POINTERG(sptr) || (ALLOCG(sptr) && SDSCG(sptr)))) {
10649         /* pghpf_size(dim, static_descriptor) */
10650         if (XBIT(68, 0x1))
10651           hpf_sym = sym_mkfunc_nodesc(mkRteRtnNm(RTE_sizeDsc), dtyper);
10652         else
10653           hpf_sym = sym_mkfunc_nodesc(mkRteRtnNm(RTE_sizeDsc), dtyper);
10654         nelems = begin_call(A_FUNC, hpf_sym, 2);
10655         A_DTYPEP(nelems, dtyper);
10656         add_arg(astb.ptr0);
10657         add_arg(check_member(ARG_AST(0), mk_id(SDSCG(sptr))));
10658         goto mul_by_eltype;
10659       }
10660       shape1 = A_SHAPEG(ARG_AST(0));
10661       count = SHD_NDIM(shape1); /* rank of array arg */
10662       if (asumsz)
10663         error(84, 3, gbl.lineno, SYMNAME(asumsz),
10664               "- size of assumed size array is unknown");
10665       else {
10666         for (i = 0; i < count; i++) {
10667           if (SHD_LWB(shape1, i) == 0 || A_ALIASG(SHD_LWB(shape1, i)) == 0 ||
10668               SHD_UPB(shape1, i) == 0 || A_ALIASG(SHD_UPB(shape1, i)) == 0 ||
10669               (SHD_STRIDE(shape1, i) != 0 &&
10670                A_ALIASG(SHD_STRIDE(shape1, i)) == 0)) {
10671             goto call_size_intr;
10672           }
10673         }
10674         nelems = extent_of_shape(shape1, 0);
10675         for (i = 1; i < count; i++) {
10676           int e;
10677           e = extent_of_shape(shape1, i);
10678           if (A_ALIASG(e)) { /* should be constant, but ... */
10679             if (get_isz_cval(A_SPTRG(e)) <= 0) {
10680               nelems = astb.bnd.zero;
10681               break;
10682             }
10683           } else
10684             goto call_size_intr;
10685           nelems = mk_binop(OP_MUL, nelems, e, astb.bnd.dtype);
10686         }
10687         goto mul_by_eltype;
10688       }
10689     call_size_intr:
10690       (void)sym_mkfunc_nodesc(mkRteRtnNm(RTE_size), dtyper);
10691       argt = mk_argt(2);
10692       ARGT_ARG(argt, 0) = ARG_AST(0);
10693       ARGT_ARG(argt, 1) = astb.ptr0;
10694       func_ast = mk_id(intast_sym[I_SIZE]);
10695       nelems = mk_func_node(A_INTR, func_ast, 2, argt);
10696       A_DTYPEP(nelems, dtyper);
10697       A_DTYPEP(func_ast, dtyper);
10698       A_OPTYPEP(nelems, I_SIZE);
10699     } else {
10700       nelems = mk_cval(1, dtyper);
10701       eltype = dtype1;
10702     }
10703 
10704   mul_by_eltype:
10705     if (eltype == DT_ASSCHAR || eltype == DT_ASSNCHAR ||
10706         eltype == DT_DEFERCHAR || eltype == DT_DEFERNCHAR) {
10707       ast = ast_intr(I_LEN, dtyper, 1, ast);
10708     } else
10709       ast = size_ast_of(ast, eltype);
10710     ast = mk_binop(OP_MUL, ast, nelems, dtyper);
10711     if (A_ALIASG(ast)) {
10712       ast = A_ALIASG(ast);
10713       iszval = get_isz_cval(A_SPTRG(ast));
10714       goto const_isz_val;
10715     }
10716     goto expr_val;
10717 
10718   case PD_storage_size:
10719     if (count == 0 || count > 2) {
10720       E74_CNT(pdsym, count, 1, 3);
10721       goto call_e74_cnt;
10722     }
10723     if (get_kwd_args(list, 2, KWDARGSTR(pdsym)))
10724       goto exit_;
10725 
10726     if ((stkp = ARG_STK(1))) { /* KIND */
10727       dtyper = set_kind_result(stkp, DT_INT, TY_INT);
10728       if (!dtyper) {
10729         E74_ARG(pdsym, 3, NULL);
10730         goto call_e74_arg;
10731       }
10732     } else {
10733       dtyper = stb.user.dt_int;
10734     }
10735 
10736     if (SST_IDG(ARG_STK(0)) == S_IDENT) {
10737       sptr = SST_SYMG(ARG_STK(0));
10738     } else {
10739       sptr = memsym_of_ast(SST_ASTG(ARG_STK(0)));
10740     }
10741 
10742     dtype1 = DTYPEG(sptr);
10743     eltype = DTY(dtype1) == TY_ARRAY ? DTY(dtype1 + 1) : dtype1;
10744     if (CLASSG(sptr)) {
10745       ast = gen_call_class_obj_size(sptr);
10746       ast = mk_binop(OP_MUL, ast, mk_cval(BITS_PER_BYTE, DT_INT8), DT_INT8);
10747       if (dtyper != DT_INT8)
10748         ast = mk_convert(ast, dtyper);
10749       goto expr_val;
10750     } else if (eltype == DT_ASSCHAR || eltype == DT_ASSNCHAR ||
10751                eltype == DT_DEFERCHAR || eltype == DT_DEFERNCHAR) {
10752       (void)mkarg(ARG_STK(0), &dum);
10753       XFR_ARGAST(0);
10754       ast = ast_intr(I_LEN, dtyper, 1, ARG_AST(0));
10755       ast = mk_binop(OP_MUL, ast, mk_cval(BITS_PER_BYTE, dtyper), dtyper);
10756       if (A_ALIASG(ast)) {
10757         ast = A_ALIASG(ast);
10758         iszval = get_isz_cval(A_SPTRG(ast));
10759         goto const_isz_val;
10760       }
10761       goto expr_val;
10762     } else {
10763       dtype1 = SST_DTYPEG(ARG_STK(0));
10764       if (DTY(dtype1) == TY_ARRAY) {
10765         conval = size_of(DTY(dtype1 + 1));
10766         conval = ALIGN(conval, alignment(dtype1));
10767       } else {
10768         conval = size_of(dtype1);
10769       }
10770       conval *= BITS_PER_BYTE;
10771       goto const_kind_int_val;
10772     }
10773     break;
10774   case PD_leadz:
10775   case PD_popcnt:
10776   case PD_poppar:
10777     if (count != 1) {
10778       E74_CNT(pdsym, count, 1, 1);
10779       goto call_e74_cnt;
10780     }
10781     if (evl_kwd_args(list, 1, KWDARGSTR(pdsym)))
10782       goto exit_;
10783     stkp = ARG_STK(0); /* i */
10784     dtyper = SST_DTYPEG(stkp);
10785     dtype1 = DDTG(dtyper);
10786     if (!DT_ISINT(dtype1)) {
10787       E74_ARG(pdsym, 0, NULL);
10788       goto call_e74_arg;
10789     }
10790     shaper = SST_SHAPEG(stkp);
10791     break;
10792 
10793   case PD_compiler_version:
10794     if (count != 0) {
10795       E74_CNT(pdsym, count, 0, 0);
10796       goto call_e74_cnt;
10797     }
10798 
10799     sprintf(verstr, "flang %s", get_version_string());
10800     sptr = getstring(verstr, strlen(verstr));
10801 
10802     goto const_str_val;
10803 
10804   case PD_compiler_options:
10805     if (count != 0) {
10806       E74_CNT(pdsym, count, 0, 0);
10807       goto call_e74_cnt;
10808     }
10809     sname = flg.cmdline;
10810     if (sname != NULL) {
10811       for (; !isspace(*sname); ++sname)
10812         ;
10813       for (; isspace(*sname); ++sname)
10814         ;
10815       sptr = getstring(sname, strlen(sname));
10816     } else {
10817       interr("compiler_options: command line not available", 0, 3);
10818     }
10819 
10820     goto const_str_val;
10821 
10822   case PD_command_argument_count:
10823     if (count != 0) {
10824       E74_CNT(pdsym, count, 0, 0);
10825       goto call_e74_cnt;
10826     }
10827     dtyper = stb.user.dt_int;
10828     func_type = A_FUNC;
10829     argt_count = 0;
10830     rtlRtn = RTE_cmd_arg_cnt;
10831     hpf_sym = sym_mkfunc_nodesc(mkRteRtnNm(rtlRtn), stb.user.dt_int);
10832     goto gen_call;
10833 
10834     /* cases where predeclared subroutines are called as functions */
10835 
10836   default:
10837     if ((pdsym = newsym(pdsym))) {
10838       SST_SYMP(stktop, pdsym);
10839       return mkvarref(stktop, list);
10840     }
10841     return fix_term(stktop, stb.i0);
10842 
10843   } /* End of switch */
10844 
10845   /* generate call where args stored in argpos */
10846 
10847 gen_call:
10848   argt = mk_argt(argt_count + argt_extra); /* space for arguments */
10849   for (i = 0; i < argt_count; i++)
10850     ARGT_ARG(argt, i) = ARG_AST(i);
10851   for (; i < argt_count + argt_extra; i++)
10852     ARGT_ARG(argt, i) = 0;
10853   if (hpf_sym)
10854     func_ast = mk_id(hpf_sym);
10855   else
10856     func_ast = mk_id(pdsym);
10857   ast = mk_func_node(func_type, func_ast, argt_count + argt_extra, argt);
10858   if (shaper)
10859     dtyper = dtype_with_shape(dtyper, shaper);
10860   A_DTYPEP(ast, dtyper);
10861   A_DTYPEP(func_ast, dtyper);
10862   if (func_type == A_INTR)
10863     A_OPTYPEP(ast, INTASTG(pdsym));
10864   if (shaper == 0)
10865     shaper = mkshape(dtyper);
10866 
10867 expr_val:
10868   /* dtyper, shaper, ast 'define' the result of the expression */
10869   A_SHAPEP(ast, shaper);
10870   EXPSTP(pdsym, 1); /* freeze predeclared */
10871   SST_IDP(stktop, S_EXPR);
10872   SST_DTYPEP(stktop, dtyper);
10873   SST_ASTP(stktop, ast);
10874   SST_SHAPEP(stktop, shaper);
10875   /* Fortran floor/ceiling take real arguments and return integer values.
10876    * But we want to use the same ILM/ILI as C/C++ (which return integral
10877    * values in real format), so as to have common optimization and
10878    * vectorization techniques and routines. Thus do an explicit convert here.
10879    */
10880   if(pdtype == PD_floor || pdtype == PD_ceiling)
10881     cngtyp(stktop, dtype2); /* dtype2 from PD_floor/PD_ceiling case above */
10882   return 1;
10883 
10884 /*
10885  * result is a 32-bit constant value, but the result is any
10886  * integer kind.
10887  */
10888 const_default_int_val:
10889   dtyper = stb.user.dt_int; /*return default integer*/
10890                             /*
10891                              *  FALL THRU !!!!
10892                              */
10893 const_kind_int_val:
10894   ast = mk_cval(conval, dtyper);
10895   EXPSTP(pdsym, 1); /* freeze predeclared */
10896   SST_IDP(stktop, S_CONST);
10897   SST_DTYPEP(stktop, dtyper);
10898   SST_SHAPEP(stktop, 0);
10899   SST_ASTP(stktop, ast);
10900   if (DTY(dtyper) != TY_INT8)
10901     SST_CVALP(stktop, conval);
10902   else
10903     SST_CVALP(stktop, A_SPTRG(ast));
10904   return SST_CVALG(stktop);
10905 
10906 const_isz_val:
10907   ast = mk_isz_cval(iszval, dtyper);
10908   EXPSTP(pdsym, 1);
10909   SST_IDP(stktop, S_CONST);
10910   SST_DTYPEP(stktop, dtyper);
10911   SST_ASTP(stktop, ast);
10912   SST_SHAPEP(stktop, 0);
10913   if (DTY(dtyper) == TY_INT)
10914     SST_CVALP(stktop, iszval);
10915   else
10916     SST_CVALP(stktop, A_SPTRG(ast));
10917   return iszval;
10918 const_real_val:
10919   EXPSTP(pdsym, 1); /* freeze predeclared */
10920   SST_IDP(stktop, S_CONST);
10921   SST_DTYPEP(stktop, DT_REAL4);
10922   SST_CVALP(stktop, val[0]);
10923   SST_SHAPEP(stktop, 0);
10924   ast = mk_cval1(val[0], DT_REAL4);
10925   SST_ASTP(stktop, ast);
10926   sptr = A_SPTRG(ast);
10927   return val[0];
10928 
10929 const_dble_val:
10930   tmp = getcon(val, DT_REAL8);
10931   EXPSTP(pdsym, 1); /* freeze predeclared */
10932   SST_IDP(stktop, S_CONST);
10933   SST_DTYPEP(stktop, DT_REAL8);
10934   SST_CVALP(stktop, tmp);
10935   SST_SHAPEP(stktop, 0);
10936   SST_ASTP(stktop, mk_cnst(tmp));
10937   return tmp;
10938 
10939 const_dword_val:
10940   tmp = getcon(val, DT_DWORD);
10941   EXPSTP(pdsym, 1); /* freeze predeclared */
10942   SST_IDP(stktop, S_CONST);
10943   SST_DTYPEP(stktop, DT_DWORD);
10944   SST_CVALP(stktop, tmp);
10945   SST_SHAPEP(stktop, 0);
10946   SST_ASTP(stktop, mk_cnst(tmp));
10947   return tmp;
10948 
10949 const_quad_val:
10950   tmp = getcon(val, DT_QUAD);
10951   EXPSTP(pdsym, 1); /* freeze predeclared */
10952   SST_IDP(stktop, S_CONST);
10953   SST_DTYPEP(stktop, DT_QUAD);
10954   SST_CVALP(stktop, tmp);
10955   SST_SHAPEP(stktop, 0);
10956   SST_ASTP(stktop, mk_cnst(tmp));
10957   return tmp;
10958 
10959 const_str_val:
10960   EXPSTP(pdsym, 1); /* freeze predeclared */
10961   SST_IDP(stktop, S_CONST);
10962   SST_DTYPEP(stktop, DTYPEG(sptr));
10963   SST_CVALP(stktop, sptr);
10964   SST_SHAPEP(stktop, 0);
10965   SST_ASTP(stktop, mk_cnst(sptr));
10966   return sptr;
10967 
10968 const_int_ast:
10969   val[0] = CONVAL2G(A_SPTRG(ast));
10970   EXPSTP(pdsym, 1); /* freeze predeclared */
10971   SST_IDP(stktop, S_CONST);
10972   SST_DTYPEP(stktop, DT_INT4);
10973   SST_CVALP(stktop, val[0]);
10974   SST_SHAPEP(stktop, 0);
10975   SST_ASTP(stktop, ast);
10976   return val[0];
10977 
10978 const_int8_ast:
10979   tmp = A_SPTRG(ast);
10980   EXPSTP(pdsym, 1); /* freeze predeclared */
10981   SST_IDP(stktop, S_CONST);
10982   SST_DTYPEP(stktop, DT_INT8);
10983   SST_CVALP(stktop, tmp);
10984   SST_SHAPEP(stktop, 0);
10985   SST_ASTP(stktop, ast);
10986   return tmp;
10987 
10988 const_real_ast:
10989   val[0] = CONVAL2G(A_SPTRG(ast));
10990   EXPSTP(pdsym, 1); /* freeze predeclared */
10991   SST_IDP(stktop, S_CONST);
10992   SST_DTYPEP(stktop, DT_REAL4);
10993   SST_CVALP(stktop, val[0]);
10994   SST_SHAPEP(stktop, 0);
10995   SST_ASTP(stktop, ast);
10996   return val[0];
10997 
10998 const_dble_ast:
10999   tmp = A_SPTRG(ast);
11000   EXPSTP(pdsym, 1); /* freeze predeclared */
11001   SST_IDP(stktop, S_CONST);
11002   SST_DTYPEP(stktop, DT_REAL8);
11003   SST_CVALP(stktop, tmp);
11004   SST_SHAPEP(stktop, 0);
11005   SST_ASTP(stktop, ast);
11006   return tmp;
11007 
11008 const_quad_ast:
11009   tmp = A_SPTRG(ast);
11010   EXPSTP(pdsym, 1); /* freeze predeclared */
11011   SST_IDP(stktop, S_CONST);
11012   SST_DTYPEP(stktop, DT_QUAD);
11013   SST_CVALP(stktop, tmp);
11014   SST_SHAPEP(stktop, 0);
11015   SST_ASTP(stktop, ast);
11016   return tmp;
11017 
11018 bad_args:
11019   if (EXPSTG(pdsym)) {
11020     /* Intrinsic frozen, therefore user misused intrinsic */
11021     error(74, 3, gbl.lineno, SYMNAME(pdsym), CNULL);
11022     return (fix_term(stktop, stb.i0));
11023   }
11024   /* Intrinsic not frozen, try to interpret as a function call */
11025   SST_SYMP(stktop, newsym(pdsym));
11026   return (mkvarref(stktop, list));
11027 
11028 call_e74_cnt:
11029   e74_cnt(_e74_sym, _e74_cnt, _e74_l, _e74_u);
11030   goto exit_;
11031 call_e74_arg:
11032   e74_arg(_e74_sym, _e74_pos, _e74_kwd);
11033 exit_:
11034   dont_issue_assumedsize_error = 0;
11035   EXPSTP(pdsym, 1); /* freeze predeclared */
11036   SST_IDP(stktop, S_EXPR);
11037   SST_DTYPEP(stktop, DT_INT);
11038   SST_ASTP(stktop, astb.i0);
11039   SST_SHAPEP(stktop, 0);
11040   return 1;
11041 ill_call:
11042   error(84, 3, gbl.lineno, SYMNAME(pdsym),
11043         "- attempt to use a subroutine intrinsic as a function");
11044   return (fix_term(stktop, stb.i0));
11045 }
11046 
11047 static int
getMergeSym(int dt,int ikind)11048 getMergeSym(int dt, int ikind)
11049 {
11050   int sym;
11051   FtnRtlEnum rtlRtn;
11052   int localDt = dt;
11053 
11054   switch (DTY(dt)) {
11055   case TY_BINT:
11056     rtlRtn = RTE_mergei1;
11057     break;
11058   case TY_SINT:
11059     rtlRtn = RTE_mergei2;
11060     break;
11061   case TY_INT:
11062     rtlRtn = RTE_mergei;
11063     break;
11064   case TY_INT8:
11065     rtlRtn = RTE_mergei8;
11066     break;
11067   case TY_REAL:
11068     rtlRtn = RTE_merger;
11069     break;
11070   case TY_DBLE:
11071     rtlRtn = RTE_merged;
11072     break;
11073   case TY_QUAD:
11074     rtlRtn = RTE_mergeq;
11075     break;
11076   case TY_CMPLX:
11077     rtlRtn = RTE_mergec;
11078     break;
11079   case TY_DCMPLX:
11080     rtlRtn = RTE_mergedc;
11081     break;
11082   case TY_BLOG:
11083     rtlRtn = RTE_mergel1;
11084     break;
11085   case TY_SLOG:
11086     rtlRtn = RTE_mergel2;
11087     break;
11088   case TY_LOG:
11089     rtlRtn = RTE_mergel;
11090     break;
11091   case TY_LOG8:
11092     rtlRtn = RTE_mergel8;
11093     break;
11094   case TY_CHAR:
11095     rtlRtn = RTE_mergecha;
11096     localDt = DT_NONE;
11097     break;
11098   case TY_DERIVED:
11099     rtlRtn = RTE_mergedt;
11100     localDt = DT_NONE;
11101     break;
11102   default:
11103     interr("getMergeSym:unexp.dt", DTY(dt), 3);
11104     break;
11105   }
11106   sym = sym_mkfunc_nodesc(mkRteRtnNm(rtlRtn), localDt);
11107   INKINDP(sym, ikind);
11108   return sym;
11109 }
11110 
11111 static void
ref_pd_subr(SST * stktop,ITEM * list)11112 ref_pd_subr(SST *stktop, ITEM *list)
11113 {
11114   int extsym, count, pdsym, dtype;
11115   int sptr, sptr2;
11116   int dtype1, dtype2;
11117   int shape, shape1;
11118   int i, dum;
11119   ITEM *ip1;
11120   int ast, lop;
11121   int argt;
11122   int argt_count;
11123   SST *sp;
11124   SST *stkp;
11125   int is_real2_arg_error = 0;
11126 
11127   /* Count the number of arguments to function */
11128   count = 0;
11129   pdsym = SST_SYMG(stktop);
11130   for (ip1 = list; ip1 != ITEM_END; ip1 = ip1->next) {
11131     count++;
11132   }
11133 
11134   argt_count = count;
11135   switch (PDNUMG(pdsym)) {
11136   case PD_exit:
11137     if (count > 1 || (count == 1 && evl_kwd_args(list, 1, KWDARGSTR(pdsym))))
11138       goto bad_args;
11139     EXPSTP(pdsym, 1); /* freeze predeclared */
11140     ast =
11141         begin_call(A_CALL, sym_mkfunc_nodesc(mkRteRtnNm(RTE_exit), DT_NONE), 1);
11142     if (count == 0)
11143       add_arg(astb.i0);
11144     else
11145       add_arg(ARG_AST(0));
11146     SST_ASTP(stktop, ast);
11147     return;
11148 
11149   case PD_date:
11150     if (count != 1 || get_kwd_args(list, 1, KWDARGSTR(pdsym)))
11151       goto bad_args;
11152     goto time_shared;
11153   case PD_time:
11154     if (count != 1 || get_kwd_args(list, 1, KWDARGSTR(pdsym)))
11155       goto bad_args;
11156   time_shared:
11157     if (!is_varref(ARG_STK(0)))
11158       goto bad_args;
11159     (void)mkarg(ARG_STK(0), &dum);
11160     XFR_ARGAST(0);
11161     break;
11162 
11163   case PD_idate:
11164     if (count != 3 || get_kwd_args(list, 3, KWDARGSTR(pdsym)))
11165       goto bad_args;
11166     dtype = SST_DTYPEG(ARG_STK(0));
11167     if ((dtype != DT_INT && dtype != DT_SINT) || !is_varref(ARG_STK(0)))
11168       goto bad_args;
11169     (void)mkarg(ARG_STK(0), &dum);
11170     XFR_ARGAST(0);
11171     for (i = 1; i <= 2; i++) {
11172       if (SST_DTYPEG(ARG_STK(i)) != dtype || !is_varref(ARG_STK(i)))
11173         goto bad_args;
11174       (void)mkarg(ARG_STK(i), &dum);
11175       XFR_ARGAST(i);
11176     }
11177     break;
11178 
11179   case PD_move_alloc:
11180     if (count != 2) {
11181       E74_CNT(pdsym, count, 2, 2);
11182       goto call_e74_cnt;
11183     }
11184     if (get_kwd_args(list, 2, KWDARGSTR(pdsym)))
11185       goto exit_;
11186     sp = ARG_STK(0);
11187     if (!is_varref(sp)) {
11188       E74_ARG(pdsym, 0, NULL);
11189       goto call_e74_arg;
11190     }
11191     (void)mkarg(sp, &dum);
11192     XFR_ARGAST(0);
11193     sptr = memsym_of_ast(ARG_AST(0));
11194     if (!ALLOCATTRG(sptr)) {
11195       E74_ARG(pdsym, 0, NULL);
11196       goto call_e74_arg;
11197     }
11198 
11199     sp = ARG_STK(1);
11200     if (!is_varref(sp)) {
11201       E74_ARG(pdsym, 1, NULL);
11202       goto call_e74_arg;
11203     }
11204     (void)mkarg(sp, &dum);
11205     XFR_ARGAST(1);
11206     sptr2 = memsym_of_ast(ARG_AST(1));
11207     if (!ALLOCATTRG(sptr2)) {
11208       E74_ARG(pdsym, 0, NULL);
11209       goto call_e74_arg;
11210     }
11211     if (CLASSG(sptr) && !CLASSG(sptr2)) {
11212       E74_ARG(pdsym, 0, NULL);
11213       goto call_e74_arg;
11214     }
11215     NOALLOOPTP(sptr2, 1);
11216     dtype1 = A_DTYPEG(ARG_AST(0));
11217     dtype2 = A_DTYPEG(ARG_AST(1));
11218     if (rank_of(dtype1) != rank_of(dtype2)) {
11219       E74_ARG(pdsym, 1, NULL);
11220       goto call_e74_arg;
11221     }
11222     dtype1 = DDTG(dtype1);
11223     dtype2 = DDTG(dtype2);
11224     /*
11225      * type compatible here means character of any length?
11226      */
11227     if (DTY(dtype1) == TY_CHAR && DTY(dtype2) == TY_CHAR)
11228       break;
11229     if (DTY(dtype1) == TY_NCHAR && DTY(dtype2) == TY_NCHAR)
11230       break;
11231     if (!eq_dtype2(dtype2, dtype1, CLASSG(sptr2))) {
11232       E74_ARG(pdsym, 1, NULL);
11233       goto call_e74_arg;
11234     }
11235     break;
11236 
11237   case PD_mvbits:
11238     /* call mvbits(from, frompos, len, to, topos) */
11239     if (count != 5) {
11240       E74_CNT(pdsym, count, 5, 5);
11241       goto call_e74_cnt;
11242     }
11243     if (get_kwd_args(list, 5, KWDARGSTR(pdsym)))
11244       goto exit_;
11245 
11246     for (i = 0; i <= 4; i++) {
11247       dtype = DDTG(SST_DTYPEG(ARG_STK(i)));
11248       if (!DT_ISINT(dtype)) {
11249         E74_ARG(pdsym, i, NULL);
11250         goto call_e74_arg;
11251       }
11252     }
11253 
11254     sp = ARG_STK(0); /* from */
11255     dtype = DDTG(SST_DTYPEG(sp));
11256 
11257     sp = ARG_STK(3); /* to */
11258     if (!is_varref(sp)) {
11259       E74_ARG(pdsym, 3, NULL);
11260       goto call_e74_arg;
11261     }
11262     dtype1 = DDTG(SST_DTYPEG(sp));
11263     if (dtype != dtype1) {
11264       E74_ARG(pdsym, 3, NULL);
11265       goto call_e74_arg;
11266     }
11267     (void)mkarg(sp, &dum);
11268     XFR_ARGAST(3);
11269     shape = SST_SHAPEG(sp);
11270 
11271     for (i = 0; i <= 4; i++) {
11272       sp = ARG_STK(i);
11273       (void)mkexpr(sp);
11274       XFR_ARGAST(i);
11275       shape1 = SST_SHAPEG(sp);
11276       if (shape) {
11277         if (shape1 && !conform_shape(shape, shape1)) {
11278           E74_ARG(pdsym, i, NULL);
11279           goto call_e74_arg;
11280         }
11281       } else
11282         shape = shape1;
11283     }
11284     break;
11285 
11286   case PD_date_and_time:
11287     if (count > 4) {
11288       E74_CNT(pdsym, count, 0, 4);
11289       goto call_e74_cnt;
11290     }
11291     if (get_kwd_args(list, 4, KWDARGSTR(pdsym)))
11292       goto exit_;
11293     argt_count = 4;
11294     for (i = 0; i <= 2; i++) /* date, time, zone */
11295       if ((sp = ARG_STK(i))) {
11296         if (!is_varref(sp) || DTY(SST_DTYPEG(sp)) != TY_CHAR) {
11297           E74_ARG(pdsym, i, NULL);
11298           goto call_e74_arg;
11299         }
11300         (void)mkarg(sp, &dum);
11301         XFR_ARGAST(i);
11302       } else
11303         ARG_AST(i) = astb.ptr0c;
11304     if ((sp = ARG_STK(3))) { /* values */
11305       if (!is_varref(sp)) {
11306         E74_ARG(pdsym, 3, NULL);
11307         goto call_e74_arg;
11308       }
11309       (void)mkarg(sp, &dum);
11310       XFR_ARGAST(3);
11311       dtype = SST_DTYPEG(sp);
11312       if (!DT_ISINT_ARR(dtype) || rank_of_ast(ARG_AST(3)) != 1) {
11313         E74_ARG(pdsym, 3, NULL);
11314         goto call_e74_arg;
11315       }
11316     }
11317     break;
11318 
11319   case PD_cpu_time:
11320     if (count != 1) {
11321       E74_CNT(pdsym, count, 1, 1);
11322       goto call_e74_cnt;
11323     }
11324     if (get_kwd_args(list, 1, KWDARGSTR(pdsym)))
11325       goto exit_;
11326     if ((sp = ARG_STK(0))) {
11327       if (!is_varref(sp)) {
11328         E74_ARG(pdsym, 0, NULL);
11329         goto call_e74_arg;
11330       }
11331       dtype = SST_DTYPEG(sp);
11332       if (!DT_ISREAL(dtype)) {
11333         E74_ARG(pdsym, 0, NULL);
11334         goto call_e74_arg;
11335       }
11336       (void)mkarg(sp, &dum);
11337       XFR_ARGAST(0);
11338     }
11339     break;
11340 
11341   case PD_random_number:
11342     if (count != 1) {
11343       E74_CNT(pdsym, count, 1, 1);
11344       goto call_e74_cnt;
11345     }
11346     if (get_kwd_args(list, 1, KWDARGSTR(pdsym)))
11347       goto exit_;
11348     if ((sp = ARG_STK(0))) {
11349       if (!is_varref(sp)) {
11350         E74_ARG(pdsym, 0, NULL);
11351         goto call_e74_arg;
11352       }
11353       dtype = SST_DTYPEG(sp);
11354       if (!DT_ISREAL(DDTG(dtype))) {
11355         E74_ARG(pdsym, 0, NULL);
11356         goto call_e74_arg;
11357       }
11358       (void)mkarg(sp, &dum);
11359       XFR_ARGAST(0);
11360       sptr = sym_of_ast(ARG_AST(0)); /* the HARVEST arg */
11361       ADDRTKNP(sptr, 1);
11362     }
11363     break;
11364   case PD_random_seed:
11365     if (count > 3) {
11366       E74_CNT(pdsym, count, 0, 3);
11367       goto call_e74_cnt;
11368     }
11369     if (get_kwd_args(list, 3, KWDARGSTR(pdsym)))
11370       goto exit_;
11371     argt_count = 3;
11372     for (i = 1; i <= 2; i++)
11373       if ((sp = ARG_STK(i))) {
11374         if (i == 2 && !is_varref(sp)) {
11375           /* get argument must be variable */
11376           E74_ARG(pdsym, i, NULL);
11377           goto call_e74_arg;
11378         }
11379         dtype = SST_DTYPEG(sp);
11380         (void)mkarg(sp, &dum);
11381         XFR_ARGAST(i);
11382         if (!DT_ISINT_ARR(dtype) || rank_of_ast(ARG_AST(i)) != 1) {
11383           E74_ARG(pdsym, i, NULL);
11384           goto call_e74_arg;
11385         }
11386         if (i == 2) {
11387           sptr = sym_of_ast(ARG_AST(2)); /* intent OUT arg */
11388           ADDRTKNP(sptr, 1);
11389         }
11390       }
11391     if ((sp = ARG_STK(0))) {
11392       if (!is_varref(sp)) {
11393         E74_ARG(pdsym, 0, NULL);
11394         goto call_e74_arg;
11395       }
11396       dtype = SST_DTYPEG(sp);
11397       if (!DT_ISINT(dtype)) {
11398         E74_ARG(pdsym, 0, NULL);
11399         goto call_e74_arg;
11400       }
11401       (void)mkarg(sp, &dum);
11402       XFR_ARGAST(0);
11403       sptr = sym_of_ast(ARG_AST(0)); /* intent OUT arg */
11404       ADDRTKNP(sptr, 1);
11405     }
11406     break;
11407   case PD_system_clock:
11408     if (count > 3) {
11409       E74_CNT(pdsym, count, 0, 3);
11410       goto call_e74_cnt;
11411     }
11412     if (get_kwd_args(list, 3, KWDARGSTR(pdsym)))
11413       goto exit_;
11414     argt_count = 3;
11415     for (i = 0; i <= 2; i++)
11416       if ((sp = ARG_STK(i))) {
11417         if (!is_varref(sp)) {
11418           E74_ARG(pdsym, i, NULL);
11419           goto call_e74_arg;
11420         }
11421         dtype = SST_DTYPEG(sp);
11422         if (!DT_ISINT(dtype)) {
11423           /* f2003 allows count_rate to be integer or real */
11424           if (i != 1 || !DT_ISREAL(dtype)) {
11425             E74_ARG(pdsym, i, NULL);
11426             goto call_e74_arg;
11427           }
11428         }
11429         (void)mkarg(sp, &dum);
11430         XFR_ARGAST(i);
11431       }
11432     break;
11433 
11434   case PD_ranget:
11435     if (count > 1) {
11436       E74_CNT(pdsym, count, 0, 1);
11437       goto call_e74_cnt;
11438     }
11439     if (REFG(pdsym) && FUNCG(pdsym))
11440       goto ill_call; /* can be CALL'd, but must be consistent */
11441     if (get_kwd_args(list, 1, KWDARGSTR(pdsym)))
11442       goto exit_;
11443     if ((stkp = ARG_STK(0))) { /* i */
11444       if (!is_varref(stkp)) {
11445         E74_ARG(pdsym, 0, NULL);
11446         goto call_e74_arg;
11447       }
11448       (void)mkarg(stkp, &dum);
11449       XFR_ARGAST(0);
11450       dtype2 = SST_DTYPEG(stkp);
11451       if (dtype2 != DT_INT) {
11452         E74_ARG(pdsym, 0, NULL);
11453         goto call_e74_arg;
11454       }
11455     }
11456     REFP(pdsym, 1);
11457     break;
11458   case PD_ranset:
11459     if (count > 1) {
11460       E74_CNT(pdsym, count, 0, 1);
11461       goto call_e74_cnt;
11462     }
11463     if (REFG(pdsym) && FUNCG(pdsym))
11464       goto ill_call; /* can be CALL'd, but must be consistent */
11465     if (evl_kwd_args(list, 1, KWDARGSTR(pdsym)))
11466       goto exit_;
11467     if ((stkp = ARG_STK(0))) { /* i */
11468       (void)mkarg(stkp, &dum);
11469       XFR_ARGAST(0);
11470       dtype2 = SST_DTYPEG(stkp);
11471       if (!DT_ISINT(dtype2) && dtype2 != DT_REAL) {
11472         E74_ARG(pdsym, 0, NULL);
11473         goto call_e74_arg;
11474       }
11475     }
11476     REFP(pdsym, 1);
11477     break;
11478 
11479   case PD_get_command_argument:
11480     if (count < 1 || count > 4) {
11481       E74_CNT(pdsym, count, 1, 4);
11482       goto call_e74_cnt;
11483     }
11484     if (get_kwd_args(list, 4, KWDARGSTR(pdsym)))
11485       goto exit_;
11486     sp = ARG_STK(0); /* number */
11487     (void)mkexpr(sp);
11488     XFR_ARGAST(0);
11489     dtype2 = SST_DTYPEG(sp);
11490     if (dtype2 != stb.user.dt_int) {
11491       E74_ARG(pdsym, 0, NULL);
11492       goto call_e74_arg;
11493     }
11494     if ((sp = ARG_STK(1))) { /* value */
11495       if (!is_varref(sp)) {
11496         E74_ARG(pdsym, 1, NULL);
11497         goto call_e74_arg;
11498       }
11499       (void)mkarg(sp, &dum);
11500       XFR_ARGAST(1);
11501       dtype2 = SST_DTYPEG(sp);
11502       if (DTY(dtype2) != TY_CHAR) {
11503         E74_ARG(pdsym, 1, NULL);
11504         goto call_e74_arg;
11505       }
11506     }
11507     if ((sp = ARG_STK(2))) { /* length */
11508       if (!is_varref(sp)) {
11509         E74_ARG(pdsym, 2, NULL);
11510         goto call_e74_arg;
11511       }
11512       (void)mkarg(sp, &dum);
11513       XFR_ARGAST(2);
11514       dtype2 = SST_DTYPEG(sp);
11515       if (dtype2 != stb.user.dt_int) {
11516         E74_ARG(pdsym, 2, NULL);
11517         goto call_e74_arg;
11518       }
11519     }
11520     if ((sp = ARG_STK(3))) { /* status */
11521       if (!is_varref(sp)) {
11522         E74_ARG(pdsym, 3, NULL);
11523         goto call_e74_arg;
11524       }
11525       (void)mkarg(sp, &dum);
11526       XFR_ARGAST(3);
11527       dtype2 = SST_DTYPEG(sp);
11528       if (dtype2 != stb.user.dt_int) {
11529         E74_ARG(pdsym, 3, NULL);
11530         goto call_e74_arg;
11531       }
11532     }
11533     argt_count = 4;
11534     break;
11535 
11536   case PD_get_command:
11537     if (count > 3) {
11538       E74_CNT(pdsym, count, 0, 3);
11539       goto call_e74_cnt;
11540     }
11541     if (get_kwd_args(list, 3, KWDARGSTR(pdsym)))
11542       goto exit_;
11543     if ((sp = ARG_STK(0))) { /* command */
11544       if (!is_varref(sp)) {
11545         E74_ARG(pdsym, 0, NULL);
11546         goto call_e74_arg;
11547       }
11548       (void)mkarg(sp, &dum);
11549       XFR_ARGAST(0);
11550       dtype2 = SST_DTYPEG(sp);
11551       if (DTY(dtype2) != TY_CHAR) {
11552         E74_ARG(pdsym, 0, NULL);
11553         goto call_e74_arg;
11554       }
11555     }
11556     if ((sp = ARG_STK(1))) { /* length */
11557       if (!is_varref(sp)) {
11558         E74_ARG(pdsym, 1, NULL);
11559         goto call_e74_arg;
11560       }
11561       (void)mkarg(sp, &dum);
11562       XFR_ARGAST(1);
11563       dtype2 = SST_DTYPEG(sp);
11564       if (dtype2 != stb.user.dt_int) {
11565         E74_ARG(pdsym, 1, NULL);
11566         goto call_e74_arg;
11567       }
11568     }
11569     if ((sp = ARG_STK(2))) { /* status */
11570       if (!is_varref(sp)) {
11571         E74_ARG(pdsym, 2, NULL);
11572         goto call_e74_arg;
11573       }
11574       (void)mkarg(sp, &dum);
11575       XFR_ARGAST(2);
11576       dtype2 = SST_DTYPEG(sp);
11577       if (dtype2 != stb.user.dt_int) {
11578         E74_ARG(pdsym, 2, NULL);
11579         goto call_e74_arg;
11580       }
11581     }
11582     argt_count = 3;
11583     break;
11584 
11585   case PD_get_environment_variable:
11586     if (count < 1 || count > 5) {
11587       E74_CNT(pdsym, count, 1, 5);
11588       goto call_e74_cnt;
11589     }
11590     if (get_kwd_args(list, 5, KWDARGSTR(pdsym)))
11591       goto exit_;
11592     sp = ARG_STK(0); /* name */
11593     (void)mkexpr(sp);
11594     XFR_ARGAST(0);
11595     dtype2 = SST_DTYPEG(sp);
11596     if (DTY(dtype2) != TY_CHAR) {
11597       E74_ARG(pdsym, 0, NULL);
11598       goto call_e74_arg;
11599     }
11600     if ((sp = ARG_STK(1))) { /* value */
11601       if (!is_varref(sp)) {
11602         E74_ARG(pdsym, 1, NULL);
11603         goto call_e74_arg;
11604       }
11605       (void)mkarg(sp, &dum);
11606       XFR_ARGAST(1);
11607       dtype2 = SST_DTYPEG(sp);
11608       if (DTY(dtype2) != TY_CHAR) {
11609         E74_ARG(pdsym, 1, NULL);
11610         goto call_e74_arg;
11611       }
11612     }
11613     if ((sp = ARG_STK(2))) { /* length */
11614       if (!is_varref(sp)) {
11615         E74_ARG(pdsym, 2, NULL);
11616         goto call_e74_arg;
11617       }
11618       (void)mkarg(sp, &dum);
11619       XFR_ARGAST(2);
11620       dtype2 = SST_DTYPEG(sp);
11621       if (dtype2 != stb.user.dt_int) {
11622         E74_ARG(pdsym, 2, NULL);
11623         goto call_e74_arg;
11624       }
11625     }
11626     if ((sp = ARG_STK(3))) { /* status */
11627       if (!is_varref(sp)) {
11628         E74_ARG(pdsym, 3, NULL);
11629         goto call_e74_arg;
11630       }
11631       (void)mkarg(sp, &dum);
11632       XFR_ARGAST(3);
11633       dtype2 = SST_DTYPEG(sp);
11634       if (dtype2 != stb.user.dt_int) {
11635         E74_ARG(pdsym, 3, NULL);
11636         goto call_e74_arg;
11637       }
11638     }
11639     if ((sp = ARG_STK(4))) { /* trim_name */
11640       (void)mkexpr(sp);
11641       XFR_ARGAST(4);
11642       dtype2 = SST_DTYPEG(sp);
11643       if (dtype2 != stb.user.dt_log) {
11644         E74_ARG(pdsym, 4, NULL);
11645         goto call_e74_arg;
11646       }
11647     }
11648     argt_count = 5;
11649     break;
11650 
11651     /* cases where predeclared functions are CALL'd */
11652 
11653   default:
11654     if ((pdsym = newsym(pdsym))) {
11655       SST_SYMP(stktop, pdsym);
11656       subr_call(stktop, list);
11657     }
11658     return;
11659 
11660   } /* End of switch */
11661 
11662   /*  generate call */
11663 
11664   EXPSTP(pdsym, 1);           /* freeze predeclared */
11665   argt = mk_argt(argt_count); /* space for arguments */
11666   for (i = 0; i < argt_count; i++)
11667     ARGT_ARG(argt, i) = ARG_AST(i);
11668   ast = mk_stmt(A_ICALL, 0);
11669   lop = mk_id(pdsym);
11670   A_LOPP(ast, lop);
11671   A_OPTYPEP(ast, INTASTG(pdsym));
11672   A_ARGCNTP(ast, argt_count);
11673   A_ARGSP(ast, argt);
11674   SST_ASTP(stktop, ast);
11675   return;
11676 
11677 bad_args:
11678   /*  if a non-stanrard intrinsic, attempt to override intrinsic property */
11679   if (EXPSTG(pdsym)) {
11680     error(74, 3, gbl.lineno, SYMNAME(pdsym), CNULL);
11681   } else {
11682     /* Intrinsic not frozen, interpret as a subroutine call */
11683     SST_SYMP(stktop, newsym(pdsym));
11684     subr_call(stktop, list);
11685   }
11686   return;
11687 call_e74_cnt:
11688   e74_cnt(_e74_sym, _e74_cnt, _e74_l, _e74_u);
11689   goto exit_;
11690 call_e74_arg:
11691   e74_arg(_e74_sym, _e74_pos, _e74_kwd);
11692 exit_:
11693   return;
11694 ill_call:
11695   error(84, 3, gbl.lineno, SYMNAME(pdsym),
11696         "- attempt to CALL a function intrinsic");
11697 }
11698 
11699 static void
ref_intrin_subr(SST * stktop,ITEM * list)11700 ref_intrin_subr(SST *stktop, ITEM *list)
11701 {
11702   int extsym, count, pdsym, dtype;
11703   int sptr;
11704   int dtype1, dtype2;
11705   int shape, shape1;
11706   int i, dum;
11707   ITEM *ip1;
11708   int ast, lop;
11709   int argt;
11710   int argt_count;
11711   SST *sp;
11712   SST *stkp;
11713 
11714   /* Count the number of arguments to function */
11715   count = 0;
11716   pdsym = SST_SYMG(stktop);
11717   for (ip1 = list; ip1 != ITEM_END; ip1 = ip1->next) {
11718     count++;
11719   }
11720 
11721   argt_count = count;
11722   switch (INTASTG(pdsym)) {
11723   case I_C_F_POINTER:
11724     if (count < 2 || count > 3) {
11725       E74_CNT(pdsym, count, 1, 3);
11726       goto call_e74_cnt;
11727     }
11728     if (get_kwd_args(list, count, KWDARGSTR(pdsym)))
11729       goto bad_args;
11730     sp = ARG_STK(0); /* CPTR */
11731     (void)mkarg(sp, &dum);
11732     XFR_ARGAST(0);
11733     dtype2 = SST_DTYPEG(sp);
11734     if (!is_iso_c_loc(ARG_AST(0))) {
11735       if (!is_iso_c_ptr(dtype2)) {
11736         E74_ARG(pdsym, 0, NULL);
11737         goto call_e74_arg;
11738       }
11739     }
11740     sp = ARG_STK(1); /* fptr */
11741     if (!is_varref(sp)) {
11742       E74_ARG(pdsym, 1, NULL);
11743       goto call_e74_arg;
11744     }
11745     (void)mkarg(sp, &dum);
11746     XFR_ARGAST(1);
11747     sptr = find_pointer_variable(ARG_AST(1));
11748     if (!sptr || !POINTERG(sptr)) {
11749       E74_ARG(pdsym, 1, NULL);
11750       goto call_e74_arg;
11751     }
11752   cfptr_shp:
11753     if ((sp = ARG_STK(2))) { /* shape */
11754       if (DTY(SST_DTYPEG(ARG_STK(1))) != TY_ARRAY) {
11755         E74_ARG(pdsym, 1, NULL);
11756         goto call_e74_arg;
11757       }
11758       (void)mkarg(sp, &dum);
11759       XFR_ARGAST(2);
11760       dtype2 = SST_DTYPEG(sp);
11761       if (DTY(dtype2) != TY_ARRAY || !DT_ISINT(DTY(dtype2 + 1))) {
11762         E74_ARG(pdsym, 2, NULL);
11763         goto call_e74_arg;
11764       }
11765     } else if (DTY(SST_DTYPEG(ARG_STK(1))) == TY_ARRAY) {
11766       E74_ARG(pdsym, 1, NULL);
11767       goto call_e74_arg;
11768     }
11769     break;
11770   case I_C_F_PROCPOINTER:
11771     if (count != 2) {
11772       E74_CNT(pdsym, count, 2, 2);
11773       goto call_e74_cnt;
11774     }
11775     if (get_kwd_args(list, count, KWDARGSTR(pdsym)))
11776       goto bad_args;
11777     sp = ARG_STK(0); /* CPTR */
11778     (void)mkarg(sp, &dum);
11779     XFR_ARGAST(0);
11780     dtype2 = SST_DTYPEG(sp);
11781     if (!is_iso_c_funloc(ARG_AST(0))) {
11782       if (!is_iso_c_funptr(dtype2)) {
11783         E74_ARG(pdsym, 0, NULL);
11784         goto call_e74_arg;
11785       }
11786     }
11787     sp = ARG_STK(1); /* fptr */
11788     if (!is_varref(sp)) {
11789       E74_ARG(pdsym, 1, NULL);
11790       goto call_e74_arg;
11791     }
11792     (void)mkarg(sp, &dum);
11793     XFR_ARGAST(1);
11794     sptr = find_pointer_variable(ARG_AST(1));
11795     if (!sptr || !is_procedure_ptr(sptr)) {
11796       E74_ARG(pdsym, 1, NULL);
11797       goto call_e74_arg;
11798     }
11799     break;
11800   /* cases where predeclared functions are CALL'd */
11801   default:
11802     if ((pdsym = newsym(pdsym))) {
11803       SST_SYMP(stktop, pdsym);
11804       subr_call(stktop, list);
11805     }
11806     return;
11807 
11808   } /* End of switch */
11809 
11810   /*  generate call */
11811 
11812   EXPSTP(pdsym, 1);           /* freeze predeclared */
11813   argt = mk_argt(argt_count); /* space for arguments */
11814   for (i = 0; i < argt_count; i++)
11815     ARGT_ARG(argt, i) = ARG_AST(i);
11816   ast = mk_stmt(A_ICALL, 0);
11817   lop = mk_id(pdsym);
11818   A_LOPP(ast, lop);
11819   A_OPTYPEP(ast, INTASTG(pdsym));
11820   A_ARGCNTP(ast, argt_count);
11821   A_ARGSP(ast, argt);
11822   SST_ASTP(stktop, ast);
11823   return;
11824 
11825 bad_args:
11826   /*  if a non-stanrard intrinsic, attempt to override intrinsic property */
11827   if (EXPSTG(pdsym)) {
11828     error(74, 3, gbl.lineno, SYMNAME(pdsym), CNULL);
11829   } else {
11830     /* Intrinsic not frozen, interpret as a subroutine call */
11831     SST_SYMP(stktop, newsym(pdsym));
11832     subr_call(stktop, list);
11833   }
11834   return;
11835 call_e74_cnt:
11836   e74_cnt(_e74_sym, _e74_cnt, _e74_l, _e74_u);
11837   goto exit_;
11838 call_e74_arg:
11839   e74_arg(_e74_sym, _e74_pos, _e74_kwd);
11840 exit_:
11841   return;
11842 ill_call:
11843   error(84, 3, gbl.lineno, SYMNAME(pdsym),
11844         "- attempt to CALL a function intrinsic");
11845 }
11846 
11847 /*
11848  * Compare the two shapes and check for conformance.  Return:
11849  * 1.  if one shape is scalar and the other is array, return the shape
11850  *     of the array;
11851  * 2.  if both are arrays and are not conformant, return -1 (error);
11852  * 3.  otherwise, return the first shape.
11853  */
11854 static int
set_shape_result(int shape1,int shape2)11855 set_shape_result(int shape1, int shape2)
11856 {
11857   if (shape1) {
11858     if (shape2 && !conform_shape(shape1, shape2))
11859       return -1;
11860   } else if (shape2)
11861     return shape2;
11862 
11863   return shape1;
11864 }
11865 
11866 /*
11867  * a kind argument is present in an intrinsic and is used to select
11868  * the result of the intrinsic
11869  */
11870 static int
set_kind_result(SST * stkp,int dt,int ty)11871 set_kind_result(SST *stkp, int dt, int ty)
11872 {
11873   int kind;
11874   int dtype2;
11875 
11876   dtype2 = SST_DTYPEG(stkp);
11877   if (!DT_ISINT(dtype2))
11878     return 0; /* ERROR */
11879   if (is_sst_const(stkp))
11880     kind = cngcon(get_sst_cval(stkp), dtype2, DT_INT4);
11881   else if (SST_IDG(stkp) == S_EXPR) {
11882     int ast;
11883     ast = SST_ASTG(stkp);
11884     if (A_ALIASG(ast))
11885       kind = get_int_cval(A_SPTRG(ast));
11886     else
11887       return 0;
11888   } else {
11889     return 0; /* ERROR */
11890   }
11891   dtype2 = select_kind(dt, ty, kind);
11892   return dtype2;
11893 }
11894 
11895 static int
mk_array_type(int arr_spec_dt,int base_dtype)11896 mk_array_type(int arr_spec_dt, int base_dtype)
11897 {
11898   int rdtype;
11899   int rank;
11900   ADSC *ad;
11901   int ubound;
11902   int lbound;
11903   int i;
11904 
11905   ad = AD_DPTR(arr_spec_dt);
11906   rank = AD_NUMDIM(ad);
11907 
11908   sem.arrdim.ndim = rank;
11909   sem.arrdim.ndefer = 0;
11910   for (i = 0; i < rank; i++) {
11911     ubound = AD_UPAST(ad, i);
11912     lbound = AD_LWAST(ad, i);
11913     if (A_TYPEG(ubound) != A_CNST || A_TYPEG(lbound) != A_CNST) {
11914       error(87, 3, gbl.lineno, NULL, NULL);
11915       sem.dinit_error = TRUE;
11916       return 0;
11917     }
11918 
11919     sem.bounds[i].lowtype = S_CONST;
11920     sem.bounds[i].lowb = get_int_cval(A_SPTRG(lbound));
11921     sem.bounds[i].lwast = 0;
11922     sem.bounds[i].uptype = S_CONST;
11923     sem.bounds[i].upb = get_int_cval(A_SPTRG(ubound));
11924     sem.bounds[i].upast = ubound;
11925   }
11926   rdtype = mk_arrdsc();
11927   DTY(rdtype + 1) = base_dtype;
11928 
11929   return rdtype;
11930 }
11931 
11932 static int
_adjustl(int string)11933 _adjustl(int string)
11934 {
11935   char *p, *cp, *str;
11936   char ch;
11937   int i, cvlen, origlen, result;
11938   int dtyper, dtype;
11939   INT val[2];
11940 
11941   dtyper = dtype = DTYPEG(string);
11942   if (DTY(dtyper) == TY_NCHAR) {
11943     string = CONVAL1G(string);
11944     dtype = DTYPEG(string);
11945   }
11946   p = stb.n_base + CONVAL1G(string);
11947   cvlen = string_length(dtype);
11948   origlen = cvlen;
11949   str = cp = getitem(0, cvlen + 1); /* +1 just in case cvlen is 0 */
11950   i = 0;
11951   /* left justify string - skip leading blanks */
11952   while (cvlen-- > 0) {
11953     ch = *p++;
11954     if (ch != ' ') {
11955       *cp++ = ch;
11956       break;
11957     }
11958     i++;
11959   }
11960   while (cvlen-- > 0)
11961     *cp++ = *p++;
11962   /* append blanks */
11963   while (i-- > 0)
11964     *cp++ = ' ';
11965   result = getstring(str, origlen);
11966   if (DTY(dtyper) == TY_NCHAR) {
11967     val[0] = result;
11968     val[1] = 0;
11969     result = getcon(val, dtyper);
11970   }
11971   return result;
11972 }
11973 
11974 static int
_adjustr(int string)11975 _adjustr(int string)
11976 {
11977   char *p, *cp, *str;
11978   char ch;
11979   int i, cvlen, origlen, result;
11980   int dtyper, dtype;
11981   INT val[2];
11982 
11983   dtyper = dtype = DTYPEG(string);
11984   if (DTY(dtyper) == TY_NCHAR) {
11985     string = CONVAL1G(string);
11986     dtype = DTYPEG(string);
11987   }
11988   p = stb.n_base + CONVAL1G(string);
11989   origlen = cvlen = string_length(dtype);
11990   str = cp = getitem(0, cvlen + 1); /* +1 just in case cvlen is 0 */
11991   i = 0;
11992   p += cvlen - 1;
11993   cp += cvlen - 1;
11994   /* right justify string - skip trailing blanks */
11995   while (cvlen-- > 0) {
11996     ch = *p--;
11997     if (ch != ' ') {
11998       *cp-- = ch;
11999       break;
12000     }
12001     i++;
12002   }
12003   while (cvlen-- > 0)
12004     *cp-- = *p--;
12005   /* insert blanks */
12006   while (i-- > 0)
12007     *cp-- = ' ';
12008   result = getstring(str, origlen);
12009   if (DTY(dtyper) == TY_NCHAR) {
12010     val[0] = result;
12011     val[1] = 0;
12012     result = getcon(val, dtyper);
12013   }
12014   return result;
12015 }
12016 
12017 static int
_index(int string,int substring,int back)12018 _index(int string, int substring, int back)
12019 {
12020   int i, n;
12021   int l_string, l_substring;
12022   char *p_string, *p_substring;
12023 
12024   p_string = stb.n_base + CONVAL1G(string);
12025   l_string = string_length(DTYPEG(string));
12026   p_substring = stb.n_base + CONVAL1G(substring);
12027   l_substring = string_length(DTYPEG(substring));
12028   n = l_string - l_substring;
12029   if (n < 0)
12030     return 0;
12031   if (get_int_cval(back) == 0) {
12032     if (l_substring == 0)
12033       return 1;
12034     for (i = 0; i <= n; ++i) {
12035       if (p_string[i] == p_substring[0] &&
12036           strncmp(p_string + i, p_substring, l_substring) == 0)
12037         return i + 1;
12038     }
12039   } else {
12040     if (l_substring == 0)
12041       return l_string + 1;
12042     for (i = n; i >= 0; --i) {
12043       if (p_string[i] == p_substring[0] &&
12044           strncmp(p_string + i, p_substring, l_substring) == 0)
12045         return i + 1;
12046     }
12047   }
12048   return 0;
12049 }
12050 
12051 static int
_len_trim(int string)12052 _len_trim(int string)
12053 {
12054   char *p;
12055   int i, cvlen, result;
12056   int dtype;
12057 
12058   dtype = DTYPEG(string);
12059   if (DTY(dtype) == TY_NCHAR) {
12060     string = CONVAL1G(string);
12061     dtype = DTYPEG(string);
12062   }
12063   p = stb.n_base + CONVAL1G(string);
12064   result = cvlen = string_length(dtype);
12065   i = 0;
12066   p += cvlen - 1;
12067   /* skip trailing blanks */
12068   while (cvlen-- > 0) {
12069     if (*p-- != ' ')
12070       break;
12071     result--;
12072   }
12073   return result;
12074 }
12075 
12076 static int
_repeat(int string,int ncopies)12077 _repeat(int string, int ncopies)
12078 {
12079   char *p, *cp, *str;
12080   char ch;
12081   int i, j, cvlen, newlen, result;
12082   int dtyper, dtype;
12083   INT val[2];
12084 
12085   ncopies = get_int_cval(ncopies);
12086   dtyper = dtype = DTYPEG(string);
12087   if (DTY(dtyper) == TY_NCHAR) {
12088     string = CONVAL1G(string);
12089     dtype = DTYPEG(string);
12090   }
12091   cvlen = string_length(dtype);
12092   newlen = cvlen * ncopies;
12093   if (newlen == 0) {
12094     str = "";
12095     result = getstring(str, strlen(str));
12096     if (DTY(dtyper) == TY_NCHAR) {
12097       dtype = get_type(2, TY_NCHAR, strlen(str));
12098       val[0] = result;
12099       val[1] = 0;
12100       result = getcon(val, dtype);
12101     }
12102     return result;
12103   }
12104   str = cp = getitem(0, newlen);
12105   j = ncopies;
12106   while (j-- > 0) {
12107     p = stb.n_base + CONVAL1G(string);
12108     i = cvlen;
12109     while (i-- > 0)
12110       *cp++ = *p++;
12111   }
12112   result = getstring(str, newlen);
12113   if (DTY(dtyper) == TY_NCHAR) {
12114     val[0] = result;
12115     val[1] = 0;
12116     dtyper = get_type(2, TY_NCHAR,
12117                       mk_cval(ncopies * string_length(dtyper), DT_INT4));
12118     result = getcon(val, dtyper);
12119   }
12120   return result;
12121 }
12122 
12123 static int
_scan(int string,int set,int back)12124 _scan(int string, int set, int back)
12125 {
12126   int i, j;
12127   int l_string, l_set;
12128   char *p_string, *p_set;
12129 
12130   p_string = stb.n_base + CONVAL1G(string);
12131   l_string = string_length(DTYPEG(string));
12132   p_set = stb.n_base + CONVAL1G(set);
12133   l_set = string_length(DTYPEG(set));
12134   if (get_int_cval(back) == 0) {
12135     for (i = 0; i < l_string; ++i)
12136       for (j = 0; j < l_set; ++j)
12137         if (p_set[j] == p_string[i])
12138           return i + 1;
12139   } else {
12140     for (i = l_string - 1; i >= 0; --i)
12141       for (j = 0; j < l_set; ++j)
12142         if (p_set[j] == p_string[i])
12143           return i + 1;
12144   }
12145   return 0;
12146 }
12147 
12148 static int
_trim(int string)12149 _trim(int string)
12150 {
12151   char *p, *cp, *str;
12152   int i, cvlen, newlen, result;
12153   int dtyper, dtype;
12154   INT val[2];
12155 
12156   dtyper = dtype = DTYPEG(string);
12157   if (DTY(dtyper) == TY_NCHAR) {
12158     string = CONVAL1G(string);
12159     dtype = DTYPEG(string);
12160   }
12161   p = stb.n_base + CONVAL1G(string);
12162   newlen = cvlen = string_length(dtype);
12163   i = 0;
12164   p += cvlen - 1;
12165   /* skip trailing blanks */
12166   while (cvlen-- > 0) {
12167     if (*p-- != ' ')
12168       break;
12169     newlen--;
12170   }
12171   if (newlen == 0) {
12172     str = "";
12173     result = getstring(str, strlen(str));
12174     if (DTY(dtyper) == TY_NCHAR) {
12175       dtype = get_type(2, TY_NCHAR, strlen(str));
12176       val[0] = result;
12177       val[1] = 0;
12178       result = getcon(val, dtype);
12179     }
12180     return result;
12181   }
12182   str = cp = getitem(0, newlen);
12183   i = newlen;
12184   cp += newlen - 1;
12185   p++;
12186   while (i-- > 0) {
12187     *cp-- = *p--;
12188   }
12189   result = getstring(str, newlen);
12190   if (DTY(dtyper) == TY_NCHAR) {
12191     i = kanji_len((unsigned char *)str, newlen);
12192     dtype = get_type(2, TY_NCHAR, i);
12193     val[0] = result;
12194     val[1] = 0;
12195     result = getcon(val, dtype);
12196   }
12197   return result;
12198 }
12199 
12200 static int
_verify(int string,int set,int back)12201 _verify(int string, int set, int back)
12202 {
12203   int i, j;
12204   int l_string, l_set;
12205   char *p_string, *p_set;
12206 
12207   p_string = stb.n_base + CONVAL1G(string);
12208   l_string = string_length(DTYPEG(string));
12209   p_set = stb.n_base + CONVAL1G(set);
12210   l_set = string_length(DTYPEG(set));
12211   if (get_int_cval(back) == 0) {
12212     for (i = 0; i < l_string; ++i) {
12213       for (j = 0; j < l_set; ++j)
12214         if (p_set[j] == p_string[i])
12215           goto contf;
12216       return i + 1;
12217     contf:;
12218     }
12219   } else {
12220     for (i = l_string - 1; i >= 0; --i) {
12221       for (j = 0; j < l_set; ++j)
12222         if (p_set[j] == p_string[i])
12223           goto contb;
12224       return i + 1;
12225     contb:;
12226     }
12227   }
12228   return 0;
12229 }
12230 
12231 /** \brief Check charset
12232  *
12233  * Make sure this routine is consistent with
12234  * - f90:         dinit.c:_selected_char_kind()
12235  * - runtime/f90: miscsup_com.c:_selected_char_kind()
12236  */
12237 int
_selected_char_kind(int con)12238 _selected_char_kind(int con)
12239 {
12240   if (sem_eq_str(con, "ASCII"))
12241     return 1;
12242   else if (sem_eq_str(con, "DEFAULT"))
12243     return 1;
12244   return -1;
12245 }
12246 
12247 /*if astdim is constant and out of range, give error messages */
12248 static void
check_dim_error(int shape,int astdim)12249 check_dim_error(int shape, int astdim)
12250 {
12251   int dim;
12252   int ndim;
12253 
12254   /* dim is a constant */
12255   if (A_ALIASG(astdim)) {
12256     ndim = 0;
12257     if (shape)
12258       ndim = SHD_NDIM(shape);
12259     dim = get_int_cval(A_SPTRG(A_ALIASG(astdim)));
12260     if (dim < 1 || dim > ndim) {
12261       error(423, 3, gbl.lineno, NULL, NULL);
12262     }
12263   }
12264 }
12265