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, ¶mct, &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, ¶mct, &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, ¶mct, &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, ¶mct, &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, ¶mct, &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, ¶mct, &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