File: | build/gcc/fortran/expr.cc |
Warning: | line 2801, column 4 Forming reference to null pointer |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
1 | /* Routines for manipulation of expression nodes. | |||
2 | Copyright (C) 2000-2023 Free Software Foundation, Inc. | |||
3 | Contributed by Andy Vaught | |||
4 | ||||
5 | This file is part of GCC. | |||
6 | ||||
7 | GCC is free software; you can redistribute it and/or modify it under | |||
8 | the terms of the GNU General Public License as published by the Free | |||
9 | Software Foundation; either version 3, or (at your option) any later | |||
10 | version. | |||
11 | ||||
12 | GCC is distributed in the hope that it will be useful, but WITHOUT ANY | |||
13 | WARRANTY; without even the implied warranty of MERCHANTABILITY or | |||
14 | FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |||
15 | for more details. | |||
16 | ||||
17 | You should have received a copy of the GNU General Public License | |||
18 | along with GCC; see the file COPYING3. If not see | |||
19 | <http://www.gnu.org/licenses/>. */ | |||
20 | ||||
21 | #include "config.h" | |||
22 | #include "system.h" | |||
23 | #include "coretypes.h" | |||
24 | #include "options.h" | |||
25 | #include "gfortran.h" | |||
26 | #include "arith.h" | |||
27 | #include "match.h" | |||
28 | #include "target-memory.h" /* for gfc_convert_boz */ | |||
29 | #include "constructor.h" | |||
30 | #include "tree.h" | |||
31 | ||||
32 | ||||
33 | /* The following set of functions provide access to gfc_expr* of | |||
34 | various types - actual all but EXPR_FUNCTION and EXPR_VARIABLE. | |||
35 | ||||
36 | There are two functions available elsewhere that provide | |||
37 | slightly different flavours of variables. Namely: | |||
38 | expr.cc (gfc_get_variable_expr) | |||
39 | symbol.cc (gfc_lval_expr_from_sym) | |||
40 | TODO: Merge these functions, if possible. */ | |||
41 | ||||
42 | /* Get a new expression node. */ | |||
43 | ||||
44 | gfc_expr * | |||
45 | gfc_get_expr (void) | |||
46 | { | |||
47 | gfc_expr *e; | |||
48 | ||||
49 | e = XCNEW (gfc_expr)((gfc_expr *) xcalloc (1, sizeof (gfc_expr))); | |||
50 | gfc_clear_ts (&e->ts); | |||
51 | e->shape = NULL__null; | |||
52 | e->ref = NULL__null; | |||
53 | e->symtree = NULL__null; | |||
54 | return e; | |||
55 | } | |||
56 | ||||
57 | ||||
58 | /* Get a new expression node that is an array constructor | |||
59 | of given type and kind. */ | |||
60 | ||||
61 | gfc_expr * | |||
62 | gfc_get_array_expr (bt type, int kind, locus *where) | |||
63 | { | |||
64 | gfc_expr *e; | |||
65 | ||||
66 | e = gfc_get_expr (); | |||
67 | e->expr_type = EXPR_ARRAY; | |||
68 | e->value.constructor = NULL__null; | |||
69 | e->rank = 1; | |||
70 | e->shape = NULL__null; | |||
71 | ||||
72 | e->ts.type = type; | |||
73 | e->ts.kind = kind; | |||
74 | if (where) | |||
75 | e->where = *where; | |||
76 | ||||
77 | return e; | |||
78 | } | |||
79 | ||||
80 | ||||
81 | /* Get a new expression node that is the NULL expression. */ | |||
82 | ||||
83 | gfc_expr * | |||
84 | gfc_get_null_expr (locus *where) | |||
85 | { | |||
86 | gfc_expr *e; | |||
87 | ||||
88 | e = gfc_get_expr (); | |||
89 | e->expr_type = EXPR_NULL; | |||
90 | e->ts.type = BT_UNKNOWN; | |||
91 | ||||
92 | if (where) | |||
93 | e->where = *where; | |||
94 | ||||
95 | return e; | |||
96 | } | |||
97 | ||||
98 | ||||
99 | /* Get a new expression node that is an operator expression node. */ | |||
100 | ||||
101 | gfc_expr * | |||
102 | gfc_get_operator_expr (locus *where, gfc_intrinsic_op op, | |||
103 | gfc_expr *op1, gfc_expr *op2) | |||
104 | { | |||
105 | gfc_expr *e; | |||
106 | ||||
107 | e = gfc_get_expr (); | |||
108 | e->expr_type = EXPR_OP; | |||
109 | e->value.op.op = op; | |||
110 | e->value.op.op1 = op1; | |||
111 | e->value.op.op2 = op2; | |||
112 | ||||
113 | if (where) | |||
114 | e->where = *where; | |||
115 | ||||
116 | return e; | |||
117 | } | |||
118 | ||||
119 | ||||
120 | /* Get a new expression node that is an structure constructor | |||
121 | of given type and kind. */ | |||
122 | ||||
123 | gfc_expr * | |||
124 | gfc_get_structure_constructor_expr (bt type, int kind, locus *where) | |||
125 | { | |||
126 | gfc_expr *e; | |||
127 | ||||
128 | e = gfc_get_expr (); | |||
129 | e->expr_type = EXPR_STRUCTURE; | |||
130 | e->value.constructor = NULL__null; | |||
131 | ||||
132 | e->ts.type = type; | |||
133 | e->ts.kind = kind; | |||
134 | if (where) | |||
135 | e->where = *where; | |||
136 | ||||
137 | return e; | |||
138 | } | |||
139 | ||||
140 | ||||
141 | /* Get a new expression node that is an constant of given type and kind. */ | |||
142 | ||||
143 | gfc_expr * | |||
144 | gfc_get_constant_expr (bt type, int kind, locus *where) | |||
145 | { | |||
146 | gfc_expr *e; | |||
147 | ||||
148 | if (!where) | |||
149 | gfc_internal_error ("gfc_get_constant_expr(): locus %<where%> cannot be " | |||
150 | "NULL"); | |||
151 | ||||
152 | e = gfc_get_expr (); | |||
153 | ||||
154 | e->expr_type = EXPR_CONSTANT; | |||
155 | e->ts.type = type; | |||
156 | e->ts.kind = kind; | |||
157 | e->where = *where; | |||
158 | ||||
159 | switch (type) | |||
160 | { | |||
161 | case BT_INTEGER: | |||
162 | mpz_init__gmpz_init (e->value.integer); | |||
163 | break; | |||
164 | ||||
165 | case BT_REAL: | |||
166 | gfc_set_model_kind (kind); | |||
167 | mpfr_init (e->value.real); | |||
168 | break; | |||
169 | ||||
170 | case BT_COMPLEX: | |||
171 | gfc_set_model_kind (kind); | |||
172 | mpc_init2 (e->value.complex, mpfr_get_default_prec()); | |||
173 | break; | |||
174 | ||||
175 | default: | |||
176 | break; | |||
177 | } | |||
178 | ||||
179 | return e; | |||
180 | } | |||
181 | ||||
182 | ||||
183 | /* Get a new expression node that is an string constant. | |||
184 | If no string is passed, a string of len is allocated, | |||
185 | blanked and null-terminated. */ | |||
186 | ||||
187 | gfc_expr * | |||
188 | gfc_get_character_expr (int kind, locus *where, const char *src, gfc_charlen_t len) | |||
189 | { | |||
190 | gfc_expr *e; | |||
191 | gfc_char_t *dest; | |||
192 | ||||
193 | if (!src) | |||
194 | { | |||
195 | dest = gfc_get_wide_string (len + 1)((gfc_char_t *) xcalloc ((len + 1), sizeof (gfc_char_t))); | |||
196 | gfc_wide_memset (dest, ' ', len); | |||
197 | dest[len] = '\0'; | |||
198 | } | |||
199 | else | |||
200 | dest = gfc_char_to_widechar (src); | |||
201 | ||||
202 | e = gfc_get_constant_expr (BT_CHARACTER, kind, | |||
203 | where ? where : &gfc_current_locus); | |||
204 | e->value.character.string = dest; | |||
205 | e->value.character.length = len; | |||
206 | ||||
207 | return e; | |||
208 | } | |||
209 | ||||
210 | ||||
211 | /* Get a new expression node that is an integer constant. */ | |||
212 | ||||
213 | gfc_expr * | |||
214 | gfc_get_int_expr (int kind, locus *where, HOST_WIDE_INTlong value) | |||
215 | { | |||
216 | gfc_expr *p; | |||
217 | p = gfc_get_constant_expr (BT_INTEGER, kind, | |||
218 | where ? where : &gfc_current_locus); | |||
219 | ||||
220 | const wide_int w = wi::shwi (value, kind * BITS_PER_UNIT(8)); | |||
221 | wi::to_mpz (w, p->value.integer, SIGNED); | |||
222 | ||||
223 | return p; | |||
224 | } | |||
225 | ||||
226 | ||||
227 | /* Get a new expression node that is a logical constant. */ | |||
228 | ||||
229 | gfc_expr * | |||
230 | gfc_get_logical_expr (int kind, locus *where, bool value) | |||
231 | { | |||
232 | gfc_expr *p; | |||
233 | p = gfc_get_constant_expr (BT_LOGICAL, kind, | |||
234 | where ? where : &gfc_current_locus); | |||
235 | ||||
236 | p->value.logical = value; | |||
237 | ||||
238 | return p; | |||
239 | } | |||
240 | ||||
241 | ||||
242 | gfc_expr * | |||
243 | gfc_get_iokind_expr (locus *where, io_kind k) | |||
244 | { | |||
245 | gfc_expr *e; | |||
246 | ||||
247 | /* Set the types to something compatible with iokind. This is needed to | |||
248 | get through gfc_free_expr later since iokind really has no Basic Type, | |||
249 | BT, of its own. */ | |||
250 | ||||
251 | e = gfc_get_expr (); | |||
252 | e->expr_type = EXPR_CONSTANT; | |||
253 | e->ts.type = BT_LOGICAL; | |||
254 | e->value.iokind = k; | |||
255 | e->where = *where; | |||
256 | ||||
257 | return e; | |||
258 | } | |||
259 | ||||
260 | ||||
261 | /* Given an expression pointer, return a copy of the expression. This | |||
262 | subroutine is recursive. */ | |||
263 | ||||
264 | gfc_expr * | |||
265 | gfc_copy_expr (gfc_expr *p) | |||
266 | { | |||
267 | gfc_expr *q; | |||
268 | gfc_char_t *s; | |||
269 | char *c; | |||
270 | ||||
271 | if (p == NULL__null) | |||
272 | return NULL__null; | |||
273 | ||||
274 | q = gfc_get_expr (); | |||
275 | *q = *p; | |||
276 | ||||
277 | switch (q->expr_type) | |||
278 | { | |||
279 | case EXPR_SUBSTRING: | |||
280 | s = gfc_get_wide_string (p->value.character.length + 1)((gfc_char_t *) xcalloc ((p->value.character.length + 1), sizeof (gfc_char_t))); | |||
281 | q->value.character.string = s; | |||
282 | memcpy (s, p->value.character.string, | |||
283 | (p->value.character.length + 1) * sizeof (gfc_char_t)); | |||
284 | break; | |||
285 | ||||
286 | case EXPR_CONSTANT: | |||
287 | /* Copy target representation, if it exists. */ | |||
288 | if (p->representation.string) | |||
289 | { | |||
290 | c = XCNEWVEC (char, p->representation.length + 1)((char *) xcalloc ((p->representation.length + 1), sizeof ( char))); | |||
291 | q->representation.string = c; | |||
292 | memcpy (c, p->representation.string, (p->representation.length + 1)); | |||
293 | } | |||
294 | ||||
295 | /* Copy the values of any pointer components of p->value. */ | |||
296 | switch (q->ts.type) | |||
297 | { | |||
298 | case BT_INTEGER: | |||
299 | mpz_init_set__gmpz_init_set (q->value.integer, p->value.integer); | |||
300 | break; | |||
301 | ||||
302 | case BT_REAL: | |||
303 | gfc_set_model_kind (q->ts.kind); | |||
304 | mpfr_init (q->value.real); | |||
305 | mpfr_set (q->value.real, p->value.real, GFC_RND_MODE)__extension__ ({ mpfr_srcptr _p = (p->value.real); mpfr_set4 (q->value.real,_p,MPFR_RNDN,((_p)->_mpfr_sign)); }); | |||
306 | break; | |||
307 | ||||
308 | case BT_COMPLEX: | |||
309 | gfc_set_model_kind (q->ts.kind); | |||
310 | mpc_init2 (q->value.complex, mpfr_get_default_prec()); | |||
311 | mpc_set (q->value.complex, p->value.complex, GFC_MPC_RND_MODE(((int)(MPFR_RNDN)) + ((int)(MPFR_RNDN) << 4))); | |||
312 | break; | |||
313 | ||||
314 | case BT_CHARACTER: | |||
315 | if (p->representation.string | |||
316 | && p->ts.kind == gfc_default_character_kind) | |||
317 | q->value.character.string | |||
318 | = gfc_char_to_widechar (q->representation.string); | |||
319 | else | |||
320 | { | |||
321 | s = gfc_get_wide_string (p->value.character.length + 1)((gfc_char_t *) xcalloc ((p->value.character.length + 1), sizeof (gfc_char_t))); | |||
322 | q->value.character.string = s; | |||
323 | ||||
324 | /* This is the case for the C_NULL_CHAR named constant. */ | |||
325 | if (p->value.character.length == 0 | |||
326 | && (p->ts.is_c_interop || p->ts.is_iso_c)) | |||
327 | { | |||
328 | *s = '\0'; | |||
329 | /* Need to set the length to 1 to make sure the NUL | |||
330 | terminator is copied. */ | |||
331 | q->value.character.length = 1; | |||
332 | } | |||
333 | else | |||
334 | memcpy (s, p->value.character.string, | |||
335 | (p->value.character.length + 1) * sizeof (gfc_char_t)); | |||
336 | } | |||
337 | break; | |||
338 | ||||
339 | case BT_HOLLERITH: | |||
340 | case BT_LOGICAL: | |||
341 | case_bt_structcase BT_DERIVED: case BT_UNION: | |||
342 | case BT_CLASS: | |||
343 | case BT_ASSUMED: | |||
344 | break; /* Already done. */ | |||
345 | ||||
346 | case BT_BOZ: | |||
347 | q->boz.len = p->boz.len; | |||
348 | q->boz.rdx = p->boz.rdx; | |||
349 | q->boz.str = XCNEWVEC (char, q->boz.len + 1)((char *) xcalloc ((q->boz.len + 1), sizeof (char))); | |||
350 | strncpy (q->boz.str, p->boz.str, p->boz.len); | |||
351 | break; | |||
352 | ||||
353 | case BT_PROCEDURE: | |||
354 | case BT_VOID: | |||
355 | /* Should never be reached. */ | |||
356 | case BT_UNKNOWN: | |||
357 | gfc_internal_error ("gfc_copy_expr(): Bad expr node"); | |||
358 | /* Not reached. */ | |||
359 | } | |||
360 | ||||
361 | break; | |||
362 | ||||
363 | case EXPR_OP: | |||
364 | switch (q->value.op.op) | |||
365 | { | |||
366 | case INTRINSIC_NOT: | |||
367 | case INTRINSIC_PARENTHESES: | |||
368 | case INTRINSIC_UPLUS: | |||
369 | case INTRINSIC_UMINUS: | |||
370 | q->value.op.op1 = gfc_copy_expr (p->value.op.op1); | |||
371 | break; | |||
372 | ||||
373 | default: /* Binary operators. */ | |||
374 | q->value.op.op1 = gfc_copy_expr (p->value.op.op1); | |||
375 | q->value.op.op2 = gfc_copy_expr (p->value.op.op2); | |||
376 | break; | |||
377 | } | |||
378 | ||||
379 | break; | |||
380 | ||||
381 | case EXPR_FUNCTION: | |||
382 | q->value.function.actual = | |||
383 | gfc_copy_actual_arglist (p->value.function.actual); | |||
384 | break; | |||
385 | ||||
386 | case EXPR_COMPCALL: | |||
387 | case EXPR_PPC: | |||
388 | q->value.compcall.actual = | |||
389 | gfc_copy_actual_arglist (p->value.compcall.actual); | |||
390 | q->value.compcall.tbp = p->value.compcall.tbp; | |||
391 | break; | |||
392 | ||||
393 | case EXPR_STRUCTURE: | |||
394 | case EXPR_ARRAY: | |||
395 | q->value.constructor = gfc_constructor_copy (p->value.constructor); | |||
396 | break; | |||
397 | ||||
398 | case EXPR_VARIABLE: | |||
399 | case EXPR_NULL: | |||
400 | break; | |||
401 | ||||
402 | case EXPR_UNKNOWN: | |||
403 | gcc_unreachable ()(fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/fortran/expr.cc" , 403, __FUNCTION__)); | |||
404 | } | |||
405 | ||||
406 | q->shape = gfc_copy_shape (p->shape, p->rank); | |||
407 | ||||
408 | q->ref = gfc_copy_ref (p->ref); | |||
409 | ||||
410 | if (p->param_list) | |||
411 | q->param_list = gfc_copy_actual_arglist (p->param_list); | |||
412 | ||||
413 | return q; | |||
414 | } | |||
415 | ||||
416 | ||||
417 | void | |||
418 | gfc_clear_shape (mpz_t *shape, int rank) | |||
419 | { | |||
420 | int i; | |||
421 | ||||
422 | for (i = 0; i < rank; i++) | |||
423 | mpz_clear__gmpz_clear (shape[i]); | |||
424 | } | |||
425 | ||||
426 | ||||
427 | void | |||
428 | gfc_free_shape (mpz_t **shape, int rank) | |||
429 | { | |||
430 | if (*shape == NULL__null) | |||
431 | return; | |||
432 | ||||
433 | gfc_clear_shape (*shape, rank); | |||
434 | free (*shape); | |||
435 | *shape = NULL__null; | |||
436 | } | |||
437 | ||||
438 | ||||
439 | /* Workhorse function for gfc_free_expr() that frees everything | |||
440 | beneath an expression node, but not the node itself. This is | |||
441 | useful when we want to simplify a node and replace it with | |||
442 | something else or the expression node belongs to another structure. */ | |||
443 | ||||
444 | static void | |||
445 | free_expr0 (gfc_expr *e) | |||
446 | { | |||
447 | switch (e->expr_type) | |||
448 | { | |||
449 | case EXPR_CONSTANT: | |||
450 | /* Free any parts of the value that need freeing. */ | |||
451 | switch (e->ts.type) | |||
452 | { | |||
453 | case BT_INTEGER: | |||
454 | mpz_clear__gmpz_clear (e->value.integer); | |||
455 | break; | |||
456 | ||||
457 | case BT_REAL: | |||
458 | mpfr_clear (e->value.real); | |||
459 | break; | |||
460 | ||||
461 | case BT_CHARACTER: | |||
462 | free (e->value.character.string); | |||
463 | break; | |||
464 | ||||
465 | case BT_COMPLEX: | |||
466 | mpc_clear (e->value.complex); | |||
467 | break; | |||
468 | ||||
469 | case BT_BOZ: | |||
470 | free (e->boz.str); | |||
471 | break; | |||
472 | ||||
473 | default: | |||
474 | break; | |||
475 | } | |||
476 | ||||
477 | /* Free the representation. */ | |||
478 | free (e->representation.string); | |||
479 | ||||
480 | break; | |||
481 | ||||
482 | case EXPR_OP: | |||
483 | if (e->value.op.op1 != NULL__null) | |||
484 | gfc_free_expr (e->value.op.op1); | |||
485 | if (e->value.op.op2 != NULL__null) | |||
486 | gfc_free_expr (e->value.op.op2); | |||
487 | break; | |||
488 | ||||
489 | case EXPR_FUNCTION: | |||
490 | gfc_free_actual_arglist (e->value.function.actual); | |||
491 | break; | |||
492 | ||||
493 | case EXPR_COMPCALL: | |||
494 | case EXPR_PPC: | |||
495 | gfc_free_actual_arglist (e->value.compcall.actual); | |||
496 | break; | |||
497 | ||||
498 | case EXPR_VARIABLE: | |||
499 | break; | |||
500 | ||||
501 | case EXPR_ARRAY: | |||
502 | case EXPR_STRUCTURE: | |||
503 | gfc_constructor_free (e->value.constructor); | |||
504 | break; | |||
505 | ||||
506 | case EXPR_SUBSTRING: | |||
507 | free (e->value.character.string); | |||
508 | break; | |||
509 | ||||
510 | case EXPR_NULL: | |||
511 | break; | |||
512 | ||||
513 | default: | |||
514 | gfc_internal_error ("free_expr0(): Bad expr type"); | |||
515 | } | |||
516 | ||||
517 | /* Free a shape array. */ | |||
518 | gfc_free_shape (&e->shape, e->rank); | |||
519 | ||||
520 | gfc_free_ref_list (e->ref); | |||
521 | ||||
522 | gfc_free_actual_arglist (e->param_list); | |||
523 | ||||
524 | memset (e, '\0', sizeof (gfc_expr)); | |||
525 | } | |||
526 | ||||
527 | ||||
528 | /* Free an expression node and everything beneath it. */ | |||
529 | ||||
530 | void | |||
531 | gfc_free_expr (gfc_expr *e) | |||
532 | { | |||
533 | if (e == NULL__null) | |||
534 | return; | |||
535 | free_expr0 (e); | |||
536 | free (e); | |||
537 | } | |||
538 | ||||
539 | ||||
540 | /* Free an argument list and everything below it. */ | |||
541 | ||||
542 | void | |||
543 | gfc_free_actual_arglist (gfc_actual_arglist *a1) | |||
544 | { | |||
545 | gfc_actual_arglist *a2; | |||
546 | ||||
547 | while (a1) | |||
548 | { | |||
549 | a2 = a1->next; | |||
550 | if (a1->expr) | |||
551 | gfc_free_expr (a1->expr); | |||
552 | free (a1->associated_dummy); | |||
553 | free (a1); | |||
554 | a1 = a2; | |||
555 | } | |||
556 | } | |||
557 | ||||
558 | ||||
559 | /* Copy an arglist structure and all of the arguments. */ | |||
560 | ||||
561 | gfc_actual_arglist * | |||
562 | gfc_copy_actual_arglist (gfc_actual_arglist *p) | |||
563 | { | |||
564 | gfc_actual_arglist *head, *tail, *new_arg; | |||
565 | ||||
566 | head = tail = NULL__null; | |||
567 | ||||
568 | for (; p; p = p->next) | |||
569 | { | |||
570 | new_arg = gfc_get_actual_arglist ()((gfc_actual_arglist *) xcalloc (1, sizeof (gfc_actual_arglist ))); | |||
571 | *new_arg = *p; | |||
572 | ||||
573 | if (p->associated_dummy != NULL__null) | |||
574 | { | |||
575 | new_arg->associated_dummy = gfc_get_dummy_arg ()((gfc_dummy_arg *) xcalloc (1, sizeof (gfc_dummy_arg))); | |||
576 | *new_arg->associated_dummy = *p->associated_dummy; | |||
577 | } | |||
578 | ||||
579 | new_arg->expr = gfc_copy_expr (p->expr); | |||
580 | new_arg->next = NULL__null; | |||
581 | ||||
582 | if (head == NULL__null) | |||
583 | head = new_arg; | |||
584 | else | |||
585 | tail->next = new_arg; | |||
586 | ||||
587 | tail = new_arg; | |||
588 | } | |||
589 | ||||
590 | return head; | |||
591 | } | |||
592 | ||||
593 | ||||
594 | /* Free a list of reference structures. */ | |||
595 | ||||
596 | void | |||
597 | gfc_free_ref_list (gfc_ref *p) | |||
598 | { | |||
599 | gfc_ref *q; | |||
600 | int i; | |||
601 | ||||
602 | for (; p; p = q) | |||
603 | { | |||
604 | q = p->next; | |||
605 | ||||
606 | switch (p->type) | |||
607 | { | |||
608 | case REF_ARRAY: | |||
609 | for (i = 0; i < GFC_MAX_DIMENSIONS15; i++) | |||
610 | { | |||
611 | gfc_free_expr (p->u.ar.start[i]); | |||
612 | gfc_free_expr (p->u.ar.end[i]); | |||
613 | gfc_free_expr (p->u.ar.stride[i]); | |||
614 | } | |||
615 | ||||
616 | break; | |||
617 | ||||
618 | case REF_SUBSTRING: | |||
619 | gfc_free_expr (p->u.ss.start); | |||
620 | gfc_free_expr (p->u.ss.end); | |||
621 | break; | |||
622 | ||||
623 | case REF_COMPONENT: | |||
624 | case REF_INQUIRY: | |||
625 | break; | |||
626 | } | |||
627 | ||||
628 | free (p); | |||
629 | } | |||
630 | } | |||
631 | ||||
632 | ||||
633 | /* Graft the *src expression onto the *dest subexpression. */ | |||
634 | ||||
635 | void | |||
636 | gfc_replace_expr (gfc_expr *dest, gfc_expr *src) | |||
637 | { | |||
638 | free_expr0 (dest); | |||
639 | *dest = *src; | |||
640 | free (src); | |||
641 | } | |||
642 | ||||
643 | ||||
644 | /* Try to extract an integer constant from the passed expression node. | |||
645 | Return true if some error occurred, false on success. If REPORT_ERROR | |||
646 | is non-zero, emit error, for positive REPORT_ERROR using gfc_error, | |||
647 | for negative using gfc_error_now. */ | |||
648 | ||||
649 | bool | |||
650 | gfc_extract_int (gfc_expr *expr, int *result, int report_error) | |||
651 | { | |||
652 | gfc_ref *ref; | |||
653 | ||||
654 | /* A KIND component is a parameter too. The expression for it | |||
655 | is stored in the initializer and should be consistent with | |||
656 | the tests below. */ | |||
657 | if (gfc_expr_attr(expr).pdt_kind) | |||
658 | { | |||
659 | for (ref = expr->ref; ref; ref = ref->next) | |||
660 | { | |||
661 | if (ref->u.c.component->attr.pdt_kind) | |||
662 | expr = ref->u.c.component->initializer; | |||
663 | } | |||
664 | } | |||
665 | ||||
666 | if (expr->expr_type != EXPR_CONSTANT) | |||
667 | { | |||
668 | if (report_error > 0) | |||
669 | gfc_error ("Constant expression required at %C"); | |||
670 | else if (report_error < 0) | |||
671 | gfc_error_now ("Constant expression required at %C"); | |||
672 | return true; | |||
673 | } | |||
674 | ||||
675 | if (expr->ts.type != BT_INTEGER) | |||
676 | { | |||
677 | if (report_error > 0) | |||
678 | gfc_error ("Integer expression required at %C"); | |||
679 | else if (report_error < 0) | |||
680 | gfc_error_now ("Integer expression required at %C"); | |||
681 | return true; | |||
682 | } | |||
683 | ||||
684 | if ((mpz_cmp_si (expr->value.integer, INT_MAX)(__builtin_constant_p ((2147483647) >= 0) && (2147483647 ) >= 0 ? (__builtin_constant_p ((static_cast<unsigned long > (2147483647))) && ((static_cast<unsigned long > (2147483647))) == 0 ? ((expr->value.integer)->_mp_size < 0 ? -1 : (expr->value.integer)->_mp_size > 0) : __gmpz_cmp_ui (expr->value.integer,(static_cast<unsigned long> (2147483647)))) : __gmpz_cmp_si (expr->value.integer ,2147483647)) > 0) | |||
685 | || (mpz_cmp_si (expr->value.integer, INT_MIN)(__builtin_constant_p (((-2147483647 -1)) >= 0) && ((-2147483647 -1)) >= 0 ? (__builtin_constant_p ((static_cast <unsigned long> ((-2147483647 -1)))) && ((static_cast <unsigned long> ((-2147483647 -1)))) == 0 ? ((expr-> value.integer)->_mp_size < 0 ? -1 : (expr->value.integer )->_mp_size > 0) : __gmpz_cmp_ui (expr->value.integer ,(static_cast<unsigned long> ((-2147483647 -1))))) : __gmpz_cmp_si (expr->value.integer,(-2147483647 -1))) < 0)) | |||
686 | { | |||
687 | if (report_error > 0) | |||
688 | gfc_error ("Integer value too large in expression at %C"); | |||
689 | else if (report_error < 0) | |||
690 | gfc_error_now ("Integer value too large in expression at %C"); | |||
691 | return true; | |||
692 | } | |||
693 | ||||
694 | *result = (int) mpz_get_si__gmpz_get_si (expr->value.integer); | |||
695 | ||||
696 | return false; | |||
697 | } | |||
698 | ||||
699 | ||||
700 | /* Same as gfc_extract_int, but use a HWI. */ | |||
701 | ||||
702 | bool | |||
703 | gfc_extract_hwi (gfc_expr *expr, HOST_WIDE_INTlong *result, int report_error) | |||
704 | { | |||
705 | gfc_ref *ref; | |||
706 | ||||
707 | /* A KIND component is a parameter too. The expression for it is | |||
708 | stored in the initializer and should be consistent with the tests | |||
709 | below. */ | |||
710 | if (gfc_expr_attr(expr).pdt_kind) | |||
711 | { | |||
712 | for (ref = expr->ref; ref; ref = ref->next) | |||
713 | { | |||
714 | if (ref->u.c.component->attr.pdt_kind) | |||
715 | expr = ref->u.c.component->initializer; | |||
716 | } | |||
717 | } | |||
718 | ||||
719 | if (expr->expr_type != EXPR_CONSTANT) | |||
720 | { | |||
721 | if (report_error > 0) | |||
722 | gfc_error ("Constant expression required at %C"); | |||
723 | else if (report_error < 0) | |||
724 | gfc_error_now ("Constant expression required at %C"); | |||
725 | return true; | |||
726 | } | |||
727 | ||||
728 | if (expr->ts.type != BT_INTEGER) | |||
729 | { | |||
730 | if (report_error > 0) | |||
731 | gfc_error ("Integer expression required at %C"); | |||
732 | else if (report_error < 0) | |||
733 | gfc_error_now ("Integer expression required at %C"); | |||
734 | return true; | |||
735 | } | |||
736 | ||||
737 | /* Use long_long_integer_type_node to determine when to saturate. */ | |||
738 | const wide_int val = wi::from_mpz (long_long_integer_type_nodeinteger_types[itk_long_long], | |||
739 | expr->value.integer, false); | |||
740 | ||||
741 | if (!wi::fits_shwi_p (val)) | |||
742 | { | |||
743 | if (report_error > 0) | |||
744 | gfc_error ("Integer value too large in expression at %C"); | |||
745 | else if (report_error < 0) | |||
746 | gfc_error_now ("Integer value too large in expression at %C"); | |||
747 | return true; | |||
748 | } | |||
749 | ||||
750 | *result = val.to_shwi (); | |||
751 | ||||
752 | return false; | |||
753 | } | |||
754 | ||||
755 | ||||
756 | /* Recursively copy a list of reference structures. */ | |||
757 | ||||
758 | gfc_ref * | |||
759 | gfc_copy_ref (gfc_ref *src) | |||
760 | { | |||
761 | gfc_array_ref *ar; | |||
762 | gfc_ref *dest; | |||
763 | ||||
764 | if (src == NULL__null) | |||
765 | return NULL__null; | |||
766 | ||||
767 | dest = gfc_get_ref ()((gfc_ref *) xcalloc (1, sizeof (gfc_ref))); | |||
768 | dest->type = src->type; | |||
769 | ||||
770 | switch (src->type) | |||
771 | { | |||
772 | case REF_ARRAY: | |||
773 | ar = gfc_copy_array_ref (&src->u.ar); | |||
774 | dest->u.ar = *ar; | |||
775 | free (ar); | |||
776 | break; | |||
777 | ||||
778 | case REF_COMPONENT: | |||
779 | dest->u.c = src->u.c; | |||
780 | break; | |||
781 | ||||
782 | case REF_INQUIRY: | |||
783 | dest->u.i = src->u.i; | |||
784 | break; | |||
785 | ||||
786 | case REF_SUBSTRING: | |||
787 | dest->u.ss = src->u.ss; | |||
788 | dest->u.ss.start = gfc_copy_expr (src->u.ss.start); | |||
789 | dest->u.ss.end = gfc_copy_expr (src->u.ss.end); | |||
790 | break; | |||
791 | } | |||
792 | ||||
793 | dest->next = gfc_copy_ref (src->next); | |||
794 | ||||
795 | return dest; | |||
796 | } | |||
797 | ||||
798 | ||||
799 | /* Detect whether an expression has any vector index array references. */ | |||
800 | ||||
801 | int | |||
802 | gfc_has_vector_index (gfc_expr *e) | |||
803 | { | |||
804 | gfc_ref *ref; | |||
805 | int i; | |||
806 | for (ref = e->ref; ref; ref = ref->next) | |||
807 | if (ref->type == REF_ARRAY) | |||
808 | for (i = 0; i < ref->u.ar.dimen; i++) | |||
809 | if (ref->u.ar.dimen_type[i] == DIMEN_VECTOR) | |||
810 | return 1; | |||
811 | return 0; | |||
812 | } | |||
813 | ||||
814 | ||||
815 | /* Copy a shape array. */ | |||
816 | ||||
817 | mpz_t * | |||
818 | gfc_copy_shape (mpz_t *shape, int rank) | |||
819 | { | |||
820 | mpz_t *new_shape; | |||
821 | int n; | |||
822 | ||||
823 | if (shape == NULL__null) | |||
824 | return NULL__null; | |||
825 | ||||
826 | new_shape = gfc_get_shape (rank)(((mpz_t *) xcalloc (((rank)), sizeof (mpz_t)))); | |||
827 | ||||
828 | for (n = 0; n < rank; n++) | |||
829 | mpz_init_set__gmpz_init_set (new_shape[n], shape[n]); | |||
830 | ||||
831 | return new_shape; | |||
832 | } | |||
833 | ||||
834 | ||||
835 | /* Copy a shape array excluding dimension N, where N is an integer | |||
836 | constant expression. Dimensions are numbered in Fortran style -- | |||
837 | starting with ONE. | |||
838 | ||||
839 | So, if the original shape array contains R elements | |||
840 | { s1 ... sN-1 sN sN+1 ... sR-1 sR} | |||
841 | the result contains R-1 elements: | |||
842 | { s1 ... sN-1 sN+1 ... sR-1} | |||
843 | ||||
844 | If anything goes wrong -- N is not a constant, its value is out | |||
845 | of range -- or anything else, just returns NULL. */ | |||
846 | ||||
847 | mpz_t * | |||
848 | gfc_copy_shape_excluding (mpz_t *shape, int rank, gfc_expr *dim) | |||
849 | { | |||
850 | mpz_t *new_shape, *s; | |||
851 | int i, n; | |||
852 | ||||
853 | if (shape == NULL__null | |||
854 | || rank <= 1 | |||
855 | || dim == NULL__null | |||
856 | || dim->expr_type != EXPR_CONSTANT | |||
857 | || dim->ts.type != BT_INTEGER) | |||
858 | return NULL__null; | |||
859 | ||||
860 | n = mpz_get_si__gmpz_get_si (dim->value.integer); | |||
861 | n--; /* Convert to zero based index. */ | |||
862 | if (n < 0 || n >= rank) | |||
863 | return NULL__null; | |||
864 | ||||
865 | s = new_shape = gfc_get_shape (rank - 1)(((mpz_t *) xcalloc (((rank - 1)), sizeof (mpz_t)))); | |||
866 | ||||
867 | for (i = 0; i < rank; i++) | |||
868 | { | |||
869 | if (i == n) | |||
870 | continue; | |||
871 | mpz_init_set__gmpz_init_set (*s, shape[i]); | |||
872 | s++; | |||
873 | } | |||
874 | ||||
875 | return new_shape; | |||
876 | } | |||
877 | ||||
878 | ||||
879 | /* Return the maximum kind of two expressions. In general, higher | |||
880 | kind numbers mean more precision for numeric types. */ | |||
881 | ||||
882 | int | |||
883 | gfc_kind_max (gfc_expr *e1, gfc_expr *e2) | |||
884 | { | |||
885 | return (e1->ts.kind > e2->ts.kind) ? e1->ts.kind : e2->ts.kind; | |||
886 | } | |||
887 | ||||
888 | ||||
889 | /* Returns nonzero if the type is numeric, zero otherwise. */ | |||
890 | ||||
891 | static int | |||
892 | numeric_type (bt type) | |||
893 | { | |||
894 | return type == BT_COMPLEX || type == BT_REAL || type == BT_INTEGER; | |||
895 | } | |||
896 | ||||
897 | ||||
898 | /* Returns nonzero if the typespec is a numeric type, zero otherwise. */ | |||
899 | ||||
900 | int | |||
901 | gfc_numeric_ts (gfc_typespec *ts) | |||
902 | { | |||
903 | return numeric_type (ts->type); | |||
904 | } | |||
905 | ||||
906 | ||||
907 | /* Return an expression node with an optional argument list attached. | |||
908 | A variable number of gfc_expr pointers are strung together in an | |||
909 | argument list with a NULL pointer terminating the list. */ | |||
910 | ||||
911 | gfc_expr * | |||
912 | gfc_build_conversion (gfc_expr *e) | |||
913 | { | |||
914 | gfc_expr *p; | |||
915 | ||||
916 | p = gfc_get_expr (); | |||
917 | p->expr_type = EXPR_FUNCTION; | |||
918 | p->symtree = NULL__null; | |||
919 | p->value.function.actual = gfc_get_actual_arglist ()((gfc_actual_arglist *) xcalloc (1, sizeof (gfc_actual_arglist ))); | |||
920 | p->value.function.actual->expr = e; | |||
921 | ||||
922 | return p; | |||
923 | } | |||
924 | ||||
925 | ||||
926 | /* Given an expression node with some sort of numeric binary | |||
927 | expression, insert type conversions required to make the operands | |||
928 | have the same type. Conversion warnings are disabled if wconversion | |||
929 | is set to 0. | |||
930 | ||||
931 | The exception is that the operands of an exponential don't have to | |||
932 | have the same type. If possible, the base is promoted to the type | |||
933 | of the exponent. For example, 1**2.3 becomes 1.0**2.3, but | |||
934 | 1.0**2 stays as it is. */ | |||
935 | ||||
936 | void | |||
937 | gfc_type_convert_binary (gfc_expr *e, int wconversion) | |||
938 | { | |||
939 | gfc_expr *op1, *op2; | |||
940 | ||||
941 | op1 = e->value.op.op1; | |||
942 | op2 = e->value.op.op2; | |||
943 | ||||
944 | if (op1->ts.type == BT_UNKNOWN || op2->ts.type == BT_UNKNOWN) | |||
945 | { | |||
946 | gfc_clear_ts (&e->ts); | |||
947 | return; | |||
948 | } | |||
949 | ||||
950 | /* Kind conversions of same type. */ | |||
951 | if (op1->ts.type == op2->ts.type) | |||
952 | { | |||
953 | if (op1->ts.kind == op2->ts.kind) | |||
954 | { | |||
955 | /* No type conversions. */ | |||
956 | e->ts = op1->ts; | |||
957 | goto done; | |||
958 | } | |||
959 | ||||
960 | if (op1->ts.kind > op2->ts.kind) | |||
961 | gfc_convert_type_warn (op2, &op1->ts, 2, wconversion); | |||
962 | else | |||
963 | gfc_convert_type_warn (op1, &op2->ts, 2, wconversion); | |||
964 | ||||
965 | e->ts = op1->ts; | |||
966 | goto done; | |||
967 | } | |||
968 | ||||
969 | /* Integer combined with real or complex. */ | |||
970 | if (op2->ts.type == BT_INTEGER) | |||
971 | { | |||
972 | e->ts = op1->ts; | |||
973 | ||||
974 | /* Special case for ** operator. */ | |||
975 | if (e->value.op.op == INTRINSIC_POWER) | |||
976 | goto done; | |||
977 | ||||
978 | gfc_convert_type_warn (e->value.op.op2, &e->ts, 2, wconversion); | |||
979 | goto done; | |||
980 | } | |||
981 | ||||
982 | if (op1->ts.type == BT_INTEGER) | |||
983 | { | |||
984 | e->ts = op2->ts; | |||
985 | gfc_convert_type_warn (e->value.op.op1, &e->ts, 2, wconversion); | |||
986 | goto done; | |||
987 | } | |||
988 | ||||
989 | /* Real combined with complex. */ | |||
990 | e->ts.type = BT_COMPLEX; | |||
991 | if (op1->ts.kind > op2->ts.kind) | |||
992 | e->ts.kind = op1->ts.kind; | |||
993 | else | |||
994 | e->ts.kind = op2->ts.kind; | |||
995 | if (op1->ts.type != BT_COMPLEX || op1->ts.kind != e->ts.kind) | |||
996 | gfc_convert_type_warn (e->value.op.op1, &e->ts, 2, wconversion); | |||
997 | if (op2->ts.type != BT_COMPLEX || op2->ts.kind != e->ts.kind) | |||
998 | gfc_convert_type_warn (e->value.op.op2, &e->ts, 2, wconversion); | |||
999 | ||||
1000 | done: | |||
1001 | return; | |||
1002 | } | |||
1003 | ||||
1004 | ||||
1005 | /* Standard intrinsics listed under F2018:10.1.12 (6), which are excluded in | |||
1006 | constant expressions, except TRANSFER (c.f. item (8)), which would need | |||
1007 | separate treatment. */ | |||
1008 | ||||
1009 | static bool | |||
1010 | is_non_constant_intrinsic (gfc_expr *e) | |||
1011 | { | |||
1012 | if (e->expr_type == EXPR_FUNCTION | |||
1013 | && e->value.function.isym) | |||
1014 | { | |||
1015 | switch (e->value.function.isym->id) | |||
1016 | { | |||
1017 | case GFC_ISYM_COMMAND_ARGUMENT_COUNT: | |||
1018 | case GFC_ISYM_GET_TEAM: | |||
1019 | case GFC_ISYM_NULL: | |||
1020 | case GFC_ISYM_NUM_IMAGES: | |||
1021 | case GFC_ISYM_TEAM_NUMBER: | |||
1022 | case GFC_ISYM_THIS_IMAGE: | |||
1023 | return true; | |||
1024 | ||||
1025 | default: | |||
1026 | return false; | |||
1027 | } | |||
1028 | } | |||
1029 | return false; | |||
1030 | } | |||
1031 | ||||
1032 | ||||
1033 | /* Determine if an expression is constant in the sense of F08:7.1.12. | |||
1034 | * This function expects that the expression has already been simplified. */ | |||
1035 | ||||
1036 | bool | |||
1037 | gfc_is_constant_expr (gfc_expr *e) | |||
1038 | { | |||
1039 | gfc_constructor *c; | |||
1040 | gfc_actual_arglist *arg; | |||
1041 | ||||
1042 | if (e == NULL__null) | |||
1043 | return true; | |||
1044 | ||||
1045 | switch (e->expr_type) | |||
1046 | { | |||
1047 | case EXPR_OP: | |||
1048 | return (gfc_is_constant_expr (e->value.op.op1) | |||
1049 | && (e->value.op.op2 == NULL__null | |||
1050 | || gfc_is_constant_expr (e->value.op.op2))); | |||
1051 | ||||
1052 | case EXPR_VARIABLE: | |||
1053 | /* The only context in which this can occur is in a parameterized | |||
1054 | derived type declaration, so returning true is OK. */ | |||
1055 | if (e->symtree->n.sym->attr.pdt_len | |||
1056 | || e->symtree->n.sym->attr.pdt_kind) | |||
1057 | return true; | |||
1058 | return false; | |||
1059 | ||||
1060 | case EXPR_FUNCTION: | |||
1061 | case EXPR_PPC: | |||
1062 | case EXPR_COMPCALL: | |||
1063 | gcc_assert (e->symtree || e->value.function.esym((void)(!(e->symtree || e->value.function.esym || e-> value.function.isym) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/fortran/expr.cc" , 1064, __FUNCTION__), 0 : 0)) | |||
1064 | || e->value.function.isym)((void)(!(e->symtree || e->value.function.esym || e-> value.function.isym) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/fortran/expr.cc" , 1064, __FUNCTION__), 0 : 0)); | |||
1065 | ||||
1066 | /* Check for intrinsics excluded in constant expressions. */ | |||
1067 | if (e->value.function.isym && is_non_constant_intrinsic (e)) | |||
1068 | return false; | |||
1069 | ||||
1070 | /* Call to intrinsic with at least one argument. */ | |||
1071 | if (e->value.function.isym && e->value.function.actual) | |||
1072 | { | |||
1073 | for (arg = e->value.function.actual; arg; arg = arg->next) | |||
1074 | if (!gfc_is_constant_expr (arg->expr)) | |||
1075 | return false; | |||
1076 | } | |||
1077 | ||||
1078 | if (e->value.function.isym | |||
1079 | && (e->value.function.isym->elemental | |||
1080 | || e->value.function.isym->pure | |||
1081 | || e->value.function.isym->inquiry | |||
1082 | || e->value.function.isym->transformational)) | |||
1083 | return true; | |||
1084 | ||||
1085 | return false; | |||
1086 | ||||
1087 | case EXPR_CONSTANT: | |||
1088 | case EXPR_NULL: | |||
1089 | return true; | |||
1090 | ||||
1091 | case EXPR_SUBSTRING: | |||
1092 | return e->ref == NULL__null || (gfc_is_constant_expr (e->ref->u.ss.start) | |||
1093 | && gfc_is_constant_expr (e->ref->u.ss.end)); | |||
1094 | ||||
1095 | case EXPR_ARRAY: | |||
1096 | case EXPR_STRUCTURE: | |||
1097 | c = gfc_constructor_first (e->value.constructor); | |||
1098 | if ((e->expr_type == EXPR_ARRAY) && c && c->iterator) | |||
1099 | return gfc_constant_ac (e); | |||
1100 | ||||
1101 | for (; c; c = gfc_constructor_next (c)) | |||
1102 | if (!gfc_is_constant_expr (c->expr)) | |||
1103 | return false; | |||
1104 | ||||
1105 | return true; | |||
1106 | ||||
1107 | ||||
1108 | default: | |||
1109 | gfc_internal_error ("gfc_is_constant_expr(): Unknown expression type"); | |||
1110 | return false; | |||
1111 | } | |||
1112 | } | |||
1113 | ||||
1114 | ||||
1115 | /* Is true if the expression or symbol is a passed CFI descriptor. */ | |||
1116 | bool | |||
1117 | is_CFI_desc (gfc_symbol *sym, gfc_expr *e) | |||
1118 | { | |||
1119 | if (sym == NULL__null | |||
1120 | && e && e->expr_type == EXPR_VARIABLE) | |||
1121 | sym = e->symtree->n.sym; | |||
1122 | ||||
1123 | if (sym && sym->attr.dummy | |||
1124 | && sym->ns->proc_name->attr.is_bind_c | |||
1125 | && (sym->attr.pointer | |||
1126 | || sym->attr.allocatable | |||
1127 | || (sym->attr.dimension | |||
1128 | && (sym->as->type == AS_ASSUMED_SHAPE | |||
1129 | || sym->as->type == AS_ASSUMED_RANK)) | |||
1130 | || (sym->ts.type == BT_CHARACTER | |||
1131 | && (!sym->ts.u.cl || !sym->ts.u.cl->length)))) | |||
1132 | return true; | |||
1133 | ||||
1134 | return false; | |||
1135 | } | |||
1136 | ||||
1137 | ||||
1138 | /* Is true if an array reference is followed by a component or substring | |||
1139 | reference. */ | |||
1140 | bool | |||
1141 | is_subref_array (gfc_expr * e) | |||
1142 | { | |||
1143 | gfc_ref * ref; | |||
1144 | bool seen_array; | |||
1145 | gfc_symbol *sym; | |||
1146 | ||||
1147 | if (e->expr_type != EXPR_VARIABLE) | |||
1148 | return false; | |||
1149 | ||||
1150 | sym = e->symtree->n.sym; | |||
1151 | ||||
1152 | if (sym->attr.subref_array_pointer) | |||
1153 | return true; | |||
1154 | ||||
1155 | seen_array = false; | |||
1156 | ||||
1157 | for (ref = e->ref; ref; ref = ref->next) | |||
1158 | { | |||
1159 | /* If we haven't seen the array reference and this is an intrinsic, | |||
1160 | what follows cannot be a subreference array, unless there is a | |||
1161 | substring reference. */ | |||
1162 | if (!seen_array && ref->type == REF_COMPONENT | |||
1163 | && ref->u.c.component->ts.type != BT_CHARACTER | |||
1164 | && ref->u.c.component->ts.type != BT_CLASS | |||
1165 | && !gfc_bt_struct (ref->u.c.component->ts.type)((ref->u.c.component->ts.type) == BT_DERIVED || (ref-> u.c.component->ts.type) == BT_UNION)) | |||
1166 | return false; | |||
1167 | ||||
1168 | if (ref->type == REF_ARRAY | |||
1169 | && ref->u.ar.type != AR_ELEMENT) | |||
1170 | seen_array = true; | |||
1171 | ||||
1172 | if (seen_array | |||
1173 | && ref->type != REF_ARRAY) | |||
1174 | return seen_array; | |||
1175 | } | |||
1176 | ||||
1177 | if (sym->ts.type == BT_CLASS | |||
1178 | && sym->attr.dummy | |||
1179 | && CLASS_DATA (sym)sym->ts.u.derived->components->attr.dimension | |||
1180 | && CLASS_DATA (sym)sym->ts.u.derived->components->attr.class_pointer) | |||
1181 | return true; | |||
1182 | ||||
1183 | return false; | |||
1184 | } | |||
1185 | ||||
1186 | ||||
1187 | /* Try to collapse intrinsic expressions. */ | |||
1188 | ||||
1189 | static bool | |||
1190 | simplify_intrinsic_op (gfc_expr *p, int type) | |||
1191 | { | |||
1192 | gfc_intrinsic_op op; | |||
1193 | gfc_expr *op1, *op2, *result; | |||
1194 | ||||
1195 | if (p->value.op.op == INTRINSIC_USER) | |||
1196 | return true; | |||
1197 | ||||
1198 | op1 = p->value.op.op1; | |||
1199 | op2 = p->value.op.op2; | |||
1200 | op = p->value.op.op; | |||
1201 | ||||
1202 | if (!gfc_simplify_expr (op1, type)) | |||
1203 | return false; | |||
1204 | if (!gfc_simplify_expr (op2, type)) | |||
1205 | return false; | |||
1206 | ||||
1207 | if (!gfc_is_constant_expr (op1) | |||
1208 | || (op2 != NULL__null && !gfc_is_constant_expr (op2))) | |||
1209 | return true; | |||
1210 | ||||
1211 | /* Rip p apart. */ | |||
1212 | p->value.op.op1 = NULL__null; | |||
1213 | p->value.op.op2 = NULL__null; | |||
1214 | ||||
1215 | switch (op) | |||
1216 | { | |||
1217 | case INTRINSIC_PARENTHESES: | |||
1218 | result = gfc_parentheses (op1); | |||
1219 | break; | |||
1220 | ||||
1221 | case INTRINSIC_UPLUS: | |||
1222 | result = gfc_uplus (op1); | |||
1223 | break; | |||
1224 | ||||
1225 | case INTRINSIC_UMINUS: | |||
1226 | result = gfc_uminus (op1); | |||
1227 | break; | |||
1228 | ||||
1229 | case INTRINSIC_PLUS: | |||
1230 | result = gfc_add (op1, op2); | |||
1231 | break; | |||
1232 | ||||
1233 | case INTRINSIC_MINUS: | |||
1234 | result = gfc_subtract (op1, op2); | |||
1235 | break; | |||
1236 | ||||
1237 | case INTRINSIC_TIMES: | |||
1238 | result = gfc_multiply (op1, op2); | |||
1239 | break; | |||
1240 | ||||
1241 | case INTRINSIC_DIVIDE: | |||
1242 | result = gfc_divide (op1, op2); | |||
1243 | break; | |||
1244 | ||||
1245 | case INTRINSIC_POWER: | |||
1246 | result = gfc_power (op1, op2); | |||
1247 | break; | |||
1248 | ||||
1249 | case INTRINSIC_CONCAT: | |||
1250 | result = gfc_concat (op1, op2); | |||
1251 | break; | |||
1252 | ||||
1253 | case INTRINSIC_EQ: | |||
1254 | case INTRINSIC_EQ_OS: | |||
1255 | result = gfc_eq (op1, op2, op); | |||
1256 | break; | |||
1257 | ||||
1258 | case INTRINSIC_NE: | |||
1259 | case INTRINSIC_NE_OS: | |||
1260 | result = gfc_ne (op1, op2, op); | |||
1261 | break; | |||
1262 | ||||
1263 | case INTRINSIC_GT: | |||
1264 | case INTRINSIC_GT_OS: | |||
1265 | result = gfc_gt (op1, op2, op); | |||
1266 | break; | |||
1267 | ||||
1268 | case INTRINSIC_GE: | |||
1269 | case INTRINSIC_GE_OS: | |||
1270 | result = gfc_ge (op1, op2, op); | |||
1271 | break; | |||
1272 | ||||
1273 | case INTRINSIC_LT: | |||
1274 | case INTRINSIC_LT_OS: | |||
1275 | result = gfc_lt (op1, op2, op); | |||
1276 | break; | |||
1277 | ||||
1278 | case INTRINSIC_LE: | |||
1279 | case INTRINSIC_LE_OS: | |||
1280 | result = gfc_le (op1, op2, op); | |||
1281 | break; | |||
1282 | ||||
1283 | case INTRINSIC_NOT: | |||
1284 | result = gfc_not (op1); | |||
1285 | break; | |||
1286 | ||||
1287 | case INTRINSIC_AND: | |||
1288 | result = gfc_and (op1, op2); | |||
1289 | break; | |||
1290 | ||||
1291 | case INTRINSIC_OR: | |||
1292 | result = gfc_or (op1, op2); | |||
1293 | break; | |||
1294 | ||||
1295 | case INTRINSIC_EQV: | |||
1296 | result = gfc_eqv (op1, op2); | |||
1297 | break; | |||
1298 | ||||
1299 | case INTRINSIC_NEQV: | |||
1300 | result = gfc_neqv (op1, op2); | |||
1301 | break; | |||
1302 | ||||
1303 | default: | |||
1304 | gfc_internal_error ("simplify_intrinsic_op(): Bad operator"); | |||
1305 | } | |||
1306 | ||||
1307 | if (result == NULL__null) | |||
1308 | { | |||
1309 | gfc_free_expr (op1); | |||
1310 | gfc_free_expr (op2); | |||
1311 | return false; | |||
1312 | } | |||
1313 | ||||
1314 | result->rank = p->rank; | |||
1315 | result->where = p->where; | |||
1316 | gfc_replace_expr (p, result); | |||
1317 | ||||
1318 | return true; | |||
1319 | } | |||
1320 | ||||
1321 | ||||
1322 | /* Subroutine to simplify constructor expressions. Mutually recursive | |||
1323 | with gfc_simplify_expr(). */ | |||
1324 | ||||
1325 | static bool | |||
1326 | simplify_constructor (gfc_constructor_base base, int type) | |||
1327 | { | |||
1328 | gfc_constructor *c; | |||
1329 | gfc_expr *p; | |||
1330 | ||||
1331 | for (c = gfc_constructor_first (base); c; c = gfc_constructor_next (c)) | |||
1332 | { | |||
1333 | if (c->iterator | |||
1334 | && (!gfc_simplify_expr(c->iterator->start, type) | |||
1335 | || !gfc_simplify_expr (c->iterator->end, type) | |||
1336 | || !gfc_simplify_expr (c->iterator->step, type))) | |||
1337 | return false; | |||
1338 | ||||
1339 | if (c->expr) | |||
1340 | { | |||
1341 | /* Try and simplify a copy. Replace the original if successful | |||
1342 | but keep going through the constructor at all costs. Not | |||
1343 | doing so can make a dog's dinner of complicated things. */ | |||
1344 | p = gfc_copy_expr (c->expr); | |||
1345 | ||||
1346 | if (!gfc_simplify_expr (p, type)) | |||
1347 | { | |||
1348 | gfc_free_expr (p); | |||
1349 | continue; | |||
1350 | } | |||
1351 | ||||
1352 | gfc_replace_expr (c->expr, p); | |||
1353 | } | |||
1354 | } | |||
1355 | ||||
1356 | return true; | |||
1357 | } | |||
1358 | ||||
1359 | ||||
1360 | /* Pull a single array element out of an array constructor. */ | |||
1361 | ||||
1362 | static bool | |||
1363 | find_array_element (gfc_constructor_base base, gfc_array_ref *ar, | |||
1364 | gfc_constructor **rval) | |||
1365 | { | |||
1366 | unsigned long nelemen; | |||
1367 | int i; | |||
1368 | mpz_t delta; | |||
1369 | mpz_t offset; | |||
1370 | mpz_t span; | |||
1371 | mpz_t tmp; | |||
1372 | gfc_constructor *cons; | |||
1373 | gfc_expr *e; | |||
1374 | bool t; | |||
1375 | ||||
1376 | t = true; | |||
1377 | e = NULL__null; | |||
1378 | ||||
1379 | mpz_init_set_ui__gmpz_init_set_ui (offset, 0); | |||
1380 | mpz_init__gmpz_init (delta); | |||
1381 | mpz_init__gmpz_init (tmp); | |||
1382 | mpz_init_set_ui__gmpz_init_set_ui (span, 1); | |||
1383 | for (i = 0; i < ar->dimen; i++) | |||
1384 | { | |||
1385 | if (!gfc_reduce_init_expr (ar->as->lower[i]) | |||
1386 | || !gfc_reduce_init_expr (ar->as->upper[i]) | |||
1387 | || ar->as->upper[i]->expr_type != EXPR_CONSTANT | |||
1388 | || ar->as->lower[i]->expr_type != EXPR_CONSTANT) | |||
1389 | { | |||
1390 | t = false; | |||
1391 | cons = NULL__null; | |||
1392 | goto depart; | |||
1393 | } | |||
1394 | ||||
1395 | e = ar->start[i]; | |||
1396 | if (e->expr_type != EXPR_CONSTANT) | |||
1397 | { | |||
1398 | cons = NULL__null; | |||
1399 | goto depart; | |||
1400 | } | |||
1401 | ||||
1402 | /* Check the bounds. */ | |||
1403 | if ((ar->as->upper[i] | |||
1404 | && mpz_cmp__gmpz_cmp (e->value.integer, | |||
1405 | ar->as->upper[i]->value.integer) > 0) | |||
1406 | || (mpz_cmp__gmpz_cmp (e->value.integer, | |||
1407 | ar->as->lower[i]->value.integer) < 0)) | |||
1408 | { | |||
1409 | gfc_error ("Index in dimension %d is out of bounds " | |||
1410 | "at %L", i + 1, &ar->c_where[i]); | |||
1411 | cons = NULL__null; | |||
1412 | t = false; | |||
1413 | goto depart; | |||
1414 | } | |||
1415 | ||||
1416 | mpz_sub__gmpz_sub (delta, e->value.integer, ar->as->lower[i]->value.integer); | |||
1417 | mpz_mul__gmpz_mul (delta, delta, span); | |||
1418 | mpz_add__gmpz_add (offset, offset, delta); | |||
1419 | ||||
1420 | mpz_set_ui__gmpz_set_ui (tmp, 1); | |||
1421 | mpz_add__gmpz_add (tmp, tmp, ar->as->upper[i]->value.integer); | |||
1422 | mpz_sub__gmpz_sub (tmp, tmp, ar->as->lower[i]->value.integer); | |||
1423 | mpz_mul__gmpz_mul (span, span, tmp); | |||
1424 | } | |||
1425 | ||||
1426 | for (cons = gfc_constructor_first (base), nelemen = mpz_get_ui__gmpz_get_ui (offset); | |||
1427 | cons && nelemen > 0; cons = gfc_constructor_next (cons), nelemen--) | |||
1428 | { | |||
1429 | if (cons->iterator) | |||
1430 | { | |||
1431 | cons = NULL__null; | |||
1432 | goto depart; | |||
1433 | } | |||
1434 | } | |||
1435 | ||||
1436 | depart: | |||
1437 | mpz_clear__gmpz_clear (delta); | |||
1438 | mpz_clear__gmpz_clear (offset); | |||
1439 | mpz_clear__gmpz_clear (span); | |||
1440 | mpz_clear__gmpz_clear (tmp); | |||
1441 | *rval = cons; | |||
1442 | return t; | |||
1443 | } | |||
1444 | ||||
1445 | ||||
1446 | /* Find a component of a structure constructor. */ | |||
1447 | ||||
1448 | static gfc_constructor * | |||
1449 | find_component_ref (gfc_constructor_base base, gfc_ref *ref) | |||
1450 | { | |||
1451 | gfc_component *pick = ref->u.c.component; | |||
1452 | gfc_constructor *c = gfc_constructor_first (base); | |||
1453 | ||||
1454 | gfc_symbol *dt = ref->u.c.sym; | |||
1455 | int ext = dt->attr.extension; | |||
1456 | ||||
1457 | /* For extended types, check if the desired component is in one of the | |||
1458 | * parent types. */ | |||
1459 | while (ext > 0 && gfc_find_component (dt->components->ts.u.derived, | |||
1460 | pick->name, true, true, NULL__null)) | |||
1461 | { | |||
1462 | dt = dt->components->ts.u.derived; | |||
1463 | c = gfc_constructor_first (c->expr->value.constructor); | |||
1464 | ext--; | |||
1465 | } | |||
1466 | ||||
1467 | gfc_component *comp = dt->components; | |||
1468 | while (comp != pick) | |||
1469 | { | |||
1470 | comp = comp->next; | |||
1471 | c = gfc_constructor_next (c); | |||
1472 | } | |||
1473 | ||||
1474 | return c; | |||
1475 | } | |||
1476 | ||||
1477 | ||||
1478 | /* Replace an expression with the contents of a constructor, removing | |||
1479 | the subobject reference in the process. */ | |||
1480 | ||||
1481 | static void | |||
1482 | remove_subobject_ref (gfc_expr *p, gfc_constructor *cons) | |||
1483 | { | |||
1484 | gfc_expr *e; | |||
1485 | ||||
1486 | if (cons) | |||
1487 | { | |||
1488 | e = cons->expr; | |||
1489 | cons->expr = NULL__null; | |||
1490 | } | |||
1491 | else | |||
1492 | e = gfc_copy_expr (p); | |||
1493 | e->ref = p->ref->next; | |||
1494 | p->ref->next = NULL__null; | |||
1495 | gfc_replace_expr (p, e); | |||
1496 | } | |||
1497 | ||||
1498 | ||||
1499 | /* Pull an array section out of an array constructor. */ | |||
1500 | ||||
1501 | static bool | |||
1502 | find_array_section (gfc_expr *expr, gfc_ref *ref) | |||
1503 | { | |||
1504 | int idx; | |||
1505 | int rank; | |||
1506 | int d; | |||
1507 | int shape_i; | |||
1508 | int limit; | |||
1509 | long unsigned one = 1; | |||
1510 | bool incr_ctr; | |||
1511 | mpz_t start[GFC_MAX_DIMENSIONS15]; | |||
1512 | mpz_t end[GFC_MAX_DIMENSIONS15]; | |||
1513 | mpz_t stride[GFC_MAX_DIMENSIONS15]; | |||
1514 | mpz_t delta[GFC_MAX_DIMENSIONS15]; | |||
1515 | mpz_t ctr[GFC_MAX_DIMENSIONS15]; | |||
1516 | mpz_t delta_mpz; | |||
1517 | mpz_t tmp_mpz; | |||
1518 | mpz_t nelts; | |||
1519 | mpz_t ptr; | |||
1520 | gfc_constructor_base base; | |||
1521 | gfc_constructor *cons, *vecsub[GFC_MAX_DIMENSIONS15]; | |||
1522 | gfc_expr *begin; | |||
1523 | gfc_expr *finish; | |||
1524 | gfc_expr *step; | |||
1525 | gfc_expr *upper; | |||
1526 | gfc_expr *lower; | |||
1527 | bool t; | |||
1528 | ||||
1529 | t = true; | |||
1530 | ||||
1531 | base = expr->value.constructor; | |||
1532 | expr->value.constructor = NULL__null; | |||
1533 | ||||
1534 | rank = ref->u.ar.as->rank; | |||
1535 | ||||
1536 | if (expr->shape == NULL__null) | |||
1537 | expr->shape = gfc_get_shape (rank)(((mpz_t *) xcalloc (((rank)), sizeof (mpz_t)))); | |||
1538 | ||||
1539 | mpz_init_set_ui__gmpz_init_set_ui (delta_mpz, one); | |||
1540 | mpz_init_set_ui__gmpz_init_set_ui (nelts, one); | |||
1541 | mpz_init__gmpz_init (tmp_mpz); | |||
1542 | ||||
1543 | /* Do the initialization now, so that we can cleanup without | |||
1544 | keeping track of where we were. */ | |||
1545 | for (d = 0; d < rank; d++) | |||
1546 | { | |||
1547 | mpz_init__gmpz_init (delta[d]); | |||
1548 | mpz_init__gmpz_init (start[d]); | |||
1549 | mpz_init__gmpz_init (end[d]); | |||
1550 | mpz_init__gmpz_init (ctr[d]); | |||
1551 | mpz_init__gmpz_init (stride[d]); | |||
1552 | vecsub[d] = NULL__null; | |||
1553 | } | |||
1554 | ||||
1555 | /* Build the counters to clock through the array reference. */ | |||
1556 | shape_i = 0; | |||
1557 | for (d = 0; d < rank; d++) | |||
1558 | { | |||
1559 | /* Make this stretch of code easier on the eye! */ | |||
1560 | begin = ref->u.ar.start[d]; | |||
1561 | finish = ref->u.ar.end[d]; | |||
1562 | step = ref->u.ar.stride[d]; | |||
1563 | lower = ref->u.ar.as->lower[d]; | |||
1564 | upper = ref->u.ar.as->upper[d]; | |||
1565 | ||||
1566 | if (!lower || !upper | |||
1567 | || lower->expr_type != EXPR_CONSTANT | |||
1568 | || upper->expr_type != EXPR_CONSTANT | |||
1569 | || lower->ts.type != BT_INTEGER | |||
1570 | || upper->ts.type != BT_INTEGER) | |||
1571 | { | |||
1572 | t = false; | |||
1573 | goto cleanup; | |||
1574 | } | |||
1575 | ||||
1576 | if (ref->u.ar.dimen_type[d] == DIMEN_VECTOR) /* Vector subscript. */ | |||
1577 | { | |||
1578 | gfc_constructor *ci; | |||
1579 | gcc_assert (begin)((void)(!(begin) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/fortran/expr.cc" , 1579, __FUNCTION__), 0 : 0)); | |||
1580 | ||||
1581 | if (begin->expr_type != EXPR_ARRAY || !gfc_is_constant_expr (begin)) | |||
1582 | { | |||
1583 | t = false; | |||
1584 | goto cleanup; | |||
1585 | } | |||
1586 | ||||
1587 | gcc_assert (begin->rank == 1)((void)(!(begin->rank == 1) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/fortran/expr.cc" , 1587, __FUNCTION__), 0 : 0)); | |||
1588 | /* Zero-sized arrays have no shape and no elements, stop early. */ | |||
1589 | if (!begin->shape) | |||
1590 | { | |||
1591 | mpz_init_set_ui__gmpz_init_set_ui (nelts, 0); | |||
1592 | break; | |||
1593 | } | |||
1594 | ||||
1595 | vecsub[d] = gfc_constructor_first (begin->value.constructor); | |||
1596 | mpz_set__gmpz_set (ctr[d], vecsub[d]->expr->value.integer); | |||
1597 | mpz_mul__gmpz_mul (nelts, nelts, begin->shape[0]); | |||
1598 | mpz_set__gmpz_set (expr->shape[shape_i++], begin->shape[0]); | |||
1599 | ||||
1600 | /* Check bounds. */ | |||
1601 | for (ci = vecsub[d]; ci; ci = gfc_constructor_next (ci)) | |||
1602 | { | |||
1603 | if (mpz_cmp__gmpz_cmp (ci->expr->value.integer, upper->value.integer) > 0 | |||
1604 | || mpz_cmp__gmpz_cmp (ci->expr->value.integer, | |||
1605 | lower->value.integer) < 0) | |||
1606 | { | |||
1607 | gfc_error ("index in dimension %d is out of bounds " | |||
1608 | "at %L", d + 1, &ref->u.ar.c_where[d]); | |||
1609 | t = false; | |||
1610 | goto cleanup; | |||
1611 | } | |||
1612 | } | |||
1613 | } | |||
1614 | else | |||
1615 | { | |||
1616 | if ((begin && begin->expr_type != EXPR_CONSTANT) | |||
1617 | || (finish && finish->expr_type != EXPR_CONSTANT) | |||
1618 | || (step && step->expr_type != EXPR_CONSTANT)) | |||
1619 | { | |||
1620 | t = false; | |||
1621 | goto cleanup; | |||
1622 | } | |||
1623 | ||||
1624 | /* Obtain the stride. */ | |||
1625 | if (step) | |||
1626 | mpz_set__gmpz_set (stride[d], step->value.integer); | |||
1627 | else | |||
1628 | mpz_set_ui__gmpz_set_ui (stride[d], one); | |||
1629 | ||||
1630 | if (mpz_cmp_ui (stride[d], 0)(__builtin_constant_p (0) && (0) == 0 ? ((stride[d])-> _mp_size < 0 ? -1 : (stride[d])->_mp_size > 0) : __gmpz_cmp_ui (stride[d],0)) == 0) | |||
1631 | mpz_set_ui__gmpz_set_ui (stride[d], one); | |||
1632 | ||||
1633 | /* Obtain the start value for the index. */ | |||
1634 | if (begin) | |||
1635 | mpz_set__gmpz_set (start[d], begin->value.integer); | |||
1636 | else | |||
1637 | mpz_set__gmpz_set (start[d], lower->value.integer); | |||
1638 | ||||
1639 | mpz_set__gmpz_set (ctr[d], start[d]); | |||
1640 | ||||
1641 | /* Obtain the end value for the index. */ | |||
1642 | if (finish) | |||
1643 | mpz_set__gmpz_set (end[d], finish->value.integer); | |||
1644 | else | |||
1645 | mpz_set__gmpz_set (end[d], upper->value.integer); | |||
1646 | ||||
1647 | /* Separate 'if' because elements sometimes arrive with | |||
1648 | non-null end. */ | |||
1649 | if (ref->u.ar.dimen_type[d] == DIMEN_ELEMENT) | |||
1650 | mpz_set__gmpz_set (end [d], begin->value.integer); | |||
1651 | ||||
1652 | /* Check the bounds. */ | |||
1653 | if (mpz_cmp__gmpz_cmp (ctr[d], upper->value.integer) > 0 | |||
1654 | || mpz_cmp__gmpz_cmp (end[d], upper->value.integer) > 0 | |||
1655 | || mpz_cmp__gmpz_cmp (ctr[d], lower->value.integer) < 0 | |||
1656 | || mpz_cmp__gmpz_cmp (end[d], lower->value.integer) < 0) | |||
1657 | { | |||
1658 | gfc_error ("index in dimension %d is out of bounds " | |||
1659 | "at %L", d + 1, &ref->u.ar.c_where[d]); | |||
1660 | t = false; | |||
1661 | goto cleanup; | |||
1662 | } | |||
1663 | ||||
1664 | /* Calculate the number of elements and the shape. */ | |||
1665 | mpz_set__gmpz_set (tmp_mpz, stride[d]); | |||
1666 | mpz_add__gmpz_add (tmp_mpz, end[d], tmp_mpz); | |||
1667 | mpz_sub__gmpz_sub (tmp_mpz, tmp_mpz, ctr[d]); | |||
1668 | mpz_div__gmpz_fdiv_q (tmp_mpz, tmp_mpz, stride[d]); | |||
1669 | mpz_mul__gmpz_mul (nelts, nelts, tmp_mpz); | |||
1670 | ||||
1671 | /* An element reference reduces the rank of the expression; don't | |||
1672 | add anything to the shape array. */ | |||
1673 | if (ref->u.ar.dimen_type[d] != DIMEN_ELEMENT) | |||
1674 | mpz_set__gmpz_set (expr->shape[shape_i++], tmp_mpz); | |||
1675 | } | |||
1676 | ||||
1677 | /* Calculate the 'stride' (=delta) for conversion of the | |||
1678 | counter values into the index along the constructor. */ | |||
1679 | mpz_set__gmpz_set (delta[d], delta_mpz); | |||
1680 | mpz_sub__gmpz_sub (tmp_mpz, upper->value.integer, lower->value.integer); | |||
1681 | mpz_add_ui__gmpz_add_ui (tmp_mpz, tmp_mpz, one); | |||
1682 | mpz_mul__gmpz_mul (delta_mpz, delta_mpz, tmp_mpz); | |||
1683 | } | |||
1684 | ||||
1685 | mpz_init__gmpz_init (ptr); | |||
1686 | cons = gfc_constructor_first (base); | |||
1687 | ||||
1688 | /* Now clock through the array reference, calculating the index in | |||
1689 | the source constructor and transferring the elements to the new | |||
1690 | constructor. */ | |||
1691 | for (idx = 0; idx < (int) mpz_get_si__gmpz_get_si (nelts); idx++) | |||
1692 | { | |||
1693 | mpz_init_set_ui__gmpz_init_set_ui (ptr, 0); | |||
1694 | ||||
1695 | incr_ctr = true; | |||
1696 | for (d = 0; d < rank; d++) | |||
1697 | { | |||
1698 | mpz_set__gmpz_set (tmp_mpz, ctr[d]); | |||
1699 | mpz_sub__gmpz_sub (tmp_mpz, tmp_mpz, ref->u.ar.as->lower[d]->value.integer); | |||
1700 | mpz_mul__gmpz_mul (tmp_mpz, tmp_mpz, delta[d]); | |||
1701 | mpz_add__gmpz_add (ptr, ptr, tmp_mpz); | |||
1702 | ||||
1703 | if (!incr_ctr) continue; | |||
1704 | ||||
1705 | if (ref->u.ar.dimen_type[d] == DIMEN_VECTOR) /* Vector subscript. */ | |||
1706 | { | |||
1707 | gcc_assert(vecsub[d])((void)(!(vecsub[d]) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/fortran/expr.cc" , 1707, __FUNCTION__), 0 : 0)); | |||
1708 | ||||
1709 | if (!gfc_constructor_next (vecsub[d])) | |||
1710 | vecsub[d] = gfc_constructor_first (ref->u.ar.start[d]->value.constructor); | |||
1711 | else | |||
1712 | { | |||
1713 | vecsub[d] = gfc_constructor_next (vecsub[d]); | |||
1714 | incr_ctr = false; | |||
1715 | } | |||
1716 | mpz_set__gmpz_set (ctr[d], vecsub[d]->expr->value.integer); | |||
1717 | } | |||
1718 | else | |||
1719 | { | |||
1720 | mpz_add__gmpz_add (ctr[d], ctr[d], stride[d]); | |||
1721 | ||||
1722 | if (mpz_cmp_ui (stride[d], 0)(__builtin_constant_p (0) && (0) == 0 ? ((stride[d])-> _mp_size < 0 ? -1 : (stride[d])->_mp_size > 0) : __gmpz_cmp_ui (stride[d],0)) > 0 | |||
1723 | ? mpz_cmp__gmpz_cmp (ctr[d], end[d]) > 0 | |||
1724 | : mpz_cmp__gmpz_cmp (ctr[d], end[d]) < 0) | |||
1725 | mpz_set__gmpz_set (ctr[d], start[d]); | |||
1726 | else | |||
1727 | incr_ctr = false; | |||
1728 | } | |||
1729 | } | |||
1730 | ||||
1731 | limit = mpz_get_ui__gmpz_get_ui (ptr); | |||
1732 | if (limit >= flag_max_array_constructorglobal_options.x_flag_max_array_constructor) | |||
1733 | { | |||
1734 | gfc_error ("The number of elements in the array constructor " | |||
1735 | "at %L requires an increase of the allowed %d " | |||
1736 | "upper limit. See %<-fmax-array-constructor%> " | |||
1737 | "option", &expr->where, flag_max_array_constructorglobal_options.x_flag_max_array_constructor); | |||
1738 | return false; | |||
1739 | } | |||
1740 | ||||
1741 | cons = gfc_constructor_lookup (base, limit); | |||
1742 | if (cons == NULL__null) | |||
1743 | { | |||
1744 | gfc_error ("Error in array constructor referenced at %L", | |||
1745 | &ref->u.ar.where); | |||
1746 | t = false; | |||
1747 | goto cleanup; | |||
1748 | } | |||
1749 | gfc_constructor_append_expr (&expr->value.constructor, | |||
1750 | gfc_copy_expr (cons->expr), NULL__null); | |||
1751 | } | |||
1752 | ||||
1753 | mpz_clear__gmpz_clear (ptr); | |||
1754 | ||||
1755 | cleanup: | |||
1756 | ||||
1757 | mpz_clear__gmpz_clear (delta_mpz); | |||
1758 | mpz_clear__gmpz_clear (tmp_mpz); | |||
1759 | mpz_clear__gmpz_clear (nelts); | |||
1760 | for (d = 0; d < rank; d++) | |||
1761 | { | |||
1762 | mpz_clear__gmpz_clear (delta[d]); | |||
1763 | mpz_clear__gmpz_clear (start[d]); | |||
1764 | mpz_clear__gmpz_clear (end[d]); | |||
1765 | mpz_clear__gmpz_clear (ctr[d]); | |||
1766 | mpz_clear__gmpz_clear (stride[d]); | |||
1767 | } | |||
1768 | gfc_constructor_free (base); | |||
1769 | return t; | |||
1770 | } | |||
1771 | ||||
1772 | /* Pull a substring out of an expression. */ | |||
1773 | ||||
1774 | static bool | |||
1775 | find_substring_ref (gfc_expr *p, gfc_expr **newp) | |||
1776 | { | |||
1777 | gfc_charlen_t end; | |||
1778 | gfc_charlen_t start; | |||
1779 | gfc_charlen_t length; | |||
1780 | gfc_char_t *chr; | |||
1781 | ||||
1782 | if (p->ref->u.ss.start->expr_type != EXPR_CONSTANT | |||
1783 | || p->ref->u.ss.end->expr_type != EXPR_CONSTANT) | |||
1784 | return false; | |||
1785 | ||||
1786 | *newp = gfc_copy_expr (p); | |||
1787 | free ((*newp)->value.character.string); | |||
1788 | ||||
1789 | end = (gfc_charlen_t) mpz_get_si__gmpz_get_si (p->ref->u.ss.end->value.integer); | |||
1790 | start = (gfc_charlen_t) mpz_get_si__gmpz_get_si (p->ref->u.ss.start->value.integer); | |||
1791 | if (end >= start) | |||
1792 | length = end - start + 1; | |||
1793 | else | |||
1794 | length = 0; | |||
1795 | ||||
1796 | chr = (*newp)->value.character.string = gfc_get_wide_string (length + 1)((gfc_char_t *) xcalloc ((length + 1), sizeof (gfc_char_t))); | |||
1797 | (*newp)->value.character.length = length; | |||
1798 | memcpy (chr, &p->value.character.string[start - 1], | |||
1799 | length * sizeof (gfc_char_t)); | |||
1800 | chr[length] = '\0'; | |||
1801 | return true; | |||
1802 | } | |||
1803 | ||||
1804 | ||||
1805 | /* Pull an inquiry result out of an expression. */ | |||
1806 | ||||
1807 | static bool | |||
1808 | find_inquiry_ref (gfc_expr *p, gfc_expr **newp) | |||
1809 | { | |||
1810 | gfc_ref *ref; | |||
1811 | gfc_ref *inquiry = NULL__null; | |||
1812 | gfc_expr *tmp; | |||
1813 | ||||
1814 | tmp = gfc_copy_expr (p); | |||
1815 | ||||
1816 | if (tmp->ref && tmp->ref->type == REF_INQUIRY) | |||
1817 | { | |||
1818 | inquiry = tmp->ref; | |||
1819 | tmp->ref = NULL__null; | |||
1820 | } | |||
1821 | else | |||
1822 | { | |||
1823 | for (ref = tmp->ref; ref; ref = ref->next) | |||
1824 | if (ref->next && ref->next->type == REF_INQUIRY) | |||
1825 | { | |||
1826 | inquiry = ref->next; | |||
1827 | ref->next = NULL__null; | |||
1828 | } | |||
1829 | } | |||
1830 | ||||
1831 | if (!inquiry) | |||
1832 | { | |||
1833 | gfc_free_expr (tmp); | |||
1834 | return false; | |||
1835 | } | |||
1836 | ||||
1837 | gfc_resolve_expr (tmp); | |||
1838 | ||||
1839 | /* In principle there can be more than one inquiry reference. */ | |||
1840 | for (; inquiry; inquiry = inquiry->next) | |||
1841 | { | |||
1842 | switch (inquiry->u.i) | |||
1843 | { | |||
1844 | case INQUIRY_LEN: | |||
1845 | if (tmp->ts.type != BT_CHARACTER) | |||
1846 | goto cleanup; | |||
1847 | ||||
1848 | if (!gfc_notify_std (GFC_STD_F2003(1<<4), "LEN part_ref at %C")) | |||
1849 | goto cleanup; | |||
1850 | ||||
1851 | if (tmp->ts.u.cl->length | |||
1852 | && tmp->ts.u.cl->length->expr_type == EXPR_CONSTANT) | |||
1853 | *newp = gfc_copy_expr (tmp->ts.u.cl->length); | |||
1854 | else if (tmp->expr_type == EXPR_CONSTANT) | |||
1855 | *newp = gfc_get_int_expr (gfc_default_integer_kind, | |||
1856 | NULL__null, tmp->value.character.length); | |||
1857 | else | |||
1858 | goto cleanup; | |||
1859 | ||||
1860 | break; | |||
1861 | ||||
1862 | case INQUIRY_KIND: | |||
1863 | if (tmp->ts.type == BT_DERIVED || tmp->ts.type == BT_CLASS) | |||
1864 | goto cleanup; | |||
1865 | ||||
1866 | if (!gfc_notify_std (GFC_STD_F2003(1<<4), "KIND part_ref at %C")) | |||
1867 | goto cleanup; | |||
1868 | ||||
1869 | *newp = gfc_get_int_expr (gfc_default_integer_kind, | |||
1870 | NULL__null, tmp->ts.kind); | |||
1871 | break; | |||
1872 | ||||
1873 | case INQUIRY_RE: | |||
1874 | if (tmp->ts.type != BT_COMPLEX || tmp->expr_type != EXPR_CONSTANT) | |||
1875 | goto cleanup; | |||
1876 | ||||
1877 | if (!gfc_notify_std (GFC_STD_F2008(1<<7), "RE part_ref at %C")) | |||
1878 | goto cleanup; | |||
1879 | ||||
1880 | *newp = gfc_get_constant_expr (BT_REAL, tmp->ts.kind, &tmp->where); | |||
1881 | mpfr_set ((*newp)->value.real,__extension__ ({ mpfr_srcptr _p = (((tmp->value.complex)-> re)); mpfr_set4((*newp)->value.real,_p,MPFR_RNDN,((_p)-> _mpfr_sign)); }) | |||
1882 | mpc_realref (tmp->value.complex), GFC_RND_MODE)__extension__ ({ mpfr_srcptr _p = (((tmp->value.complex)-> re)); mpfr_set4((*newp)->value.real,_p,MPFR_RNDN,((_p)-> _mpfr_sign)); }); | |||
1883 | break; | |||
1884 | ||||
1885 | case INQUIRY_IM: | |||
1886 | if (tmp->ts.type != BT_COMPLEX || tmp->expr_type != EXPR_CONSTANT) | |||
1887 | goto cleanup; | |||
1888 | ||||
1889 | if (!gfc_notify_std (GFC_STD_F2008(1<<7), "IM part_ref at %C")) | |||
1890 | goto cleanup; | |||
1891 | ||||
1892 | *newp = gfc_get_constant_expr (BT_REAL, tmp->ts.kind, &tmp->where); | |||
1893 | mpfr_set ((*newp)->value.real,__extension__ ({ mpfr_srcptr _p = (((tmp->value.complex)-> im)); mpfr_set4((*newp)->value.real,_p,MPFR_RNDN,((_p)-> _mpfr_sign)); }) | |||
1894 | mpc_imagref (tmp->value.complex), GFC_RND_MODE)__extension__ ({ mpfr_srcptr _p = (((tmp->value.complex)-> im)); mpfr_set4((*newp)->value.real,_p,MPFR_RNDN,((_p)-> _mpfr_sign)); }); | |||
1895 | break; | |||
1896 | } | |||
1897 | tmp = gfc_copy_expr (*newp); | |||
1898 | } | |||
1899 | ||||
1900 | if (!(*newp)) | |||
1901 | goto cleanup; | |||
1902 | else if ((*newp)->expr_type != EXPR_CONSTANT) | |||
1903 | { | |||
1904 | gfc_free_expr (*newp); | |||
1905 | goto cleanup; | |||
1906 | } | |||
1907 | ||||
1908 | gfc_free_expr (tmp); | |||
1909 | return true; | |||
1910 | ||||
1911 | cleanup: | |||
1912 | gfc_free_expr (tmp); | |||
1913 | return false; | |||
1914 | } | |||
1915 | ||||
1916 | ||||
1917 | ||||
1918 | /* Simplify a subobject reference of a constructor. This occurs when | |||
1919 | parameter variable values are substituted. */ | |||
1920 | ||||
1921 | static bool | |||
1922 | simplify_const_ref (gfc_expr *p) | |||
1923 | { | |||
1924 | gfc_constructor *cons, *c; | |||
1925 | gfc_expr *newp = NULL__null; | |||
1926 | gfc_ref *last_ref; | |||
1927 | ||||
1928 | while (p->ref) | |||
1929 | { | |||
1930 | switch (p->ref->type) | |||
1931 | { | |||
1932 | case REF_ARRAY: | |||
1933 | switch (p->ref->u.ar.type) | |||
1934 | { | |||
1935 | case AR_ELEMENT: | |||
1936 | /* <type/kind spec>, parameter :: x(<int>) = scalar_expr | |||
1937 | will generate this. */ | |||
1938 | if (p->expr_type != EXPR_ARRAY) | |||
1939 | { | |||
1940 | remove_subobject_ref (p, NULL__null); | |||
1941 | break; | |||
1942 | } | |||
1943 | if (!find_array_element (p->value.constructor, &p->ref->u.ar, &cons)) | |||
1944 | return false; | |||
1945 | ||||
1946 | if (!cons) | |||
1947 | return true; | |||
1948 | ||||
1949 | remove_subobject_ref (p, cons); | |||
1950 | break; | |||
1951 | ||||
1952 | case AR_SECTION: | |||
1953 | if (!find_array_section (p, p->ref)) | |||
1954 | return false; | |||
1955 | p->ref->u.ar.type = AR_FULL; | |||
1956 | ||||
1957 | /* Fall through. */ | |||
1958 | ||||
1959 | case AR_FULL: | |||
1960 | if (p->ref->next != NULL__null | |||
1961 | && (p->ts.type == BT_CHARACTER || gfc_bt_struct (p->ts.type)((p->ts.type) == BT_DERIVED || (p->ts.type) == BT_UNION ))) | |||
1962 | { | |||
1963 | for (c = gfc_constructor_first (p->value.constructor); | |||
1964 | c; c = gfc_constructor_next (c)) | |||
1965 | { | |||
1966 | c->expr->ref = gfc_copy_ref (p->ref->next); | |||
1967 | if (!simplify_const_ref (c->expr)) | |||
1968 | return false; | |||
1969 | } | |||
1970 | ||||
1971 | if (gfc_bt_struct (p->ts.type)((p->ts.type) == BT_DERIVED || (p->ts.type) == BT_UNION ) | |||
1972 | && p->ref->next | |||
1973 | && (c = gfc_constructor_first (p->value.constructor))) | |||
1974 | { | |||
1975 | /* There may have been component references. */ | |||
1976 | p->ts = c->expr->ts; | |||
1977 | } | |||
1978 | ||||
1979 | last_ref = p->ref; | |||
1980 | for (; last_ref->next; last_ref = last_ref->next) {}; | |||
1981 | ||||
1982 | if (p->ts.type == BT_CHARACTER | |||
1983 | && last_ref->type == REF_SUBSTRING) | |||
1984 | { | |||
1985 | /* If this is a CHARACTER array and we possibly took | |||
1986 | a substring out of it, update the type-spec's | |||
1987 | character length according to the first element | |||
1988 | (as all should have the same length). */ | |||
1989 | gfc_charlen_t string_len; | |||
1990 | if ((c = gfc_constructor_first (p->value.constructor))) | |||
1991 | { | |||
1992 | const gfc_expr* first = c->expr; | |||
1993 | gcc_assert (first->expr_type == EXPR_CONSTANT)((void)(!(first->expr_type == EXPR_CONSTANT) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/fortran/expr.cc" , 1993, __FUNCTION__), 0 : 0)); | |||
1994 | gcc_assert (first->ts.type == BT_CHARACTER)((void)(!(first->ts.type == BT_CHARACTER) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/fortran/expr.cc" , 1994, __FUNCTION__), 0 : 0)); | |||
1995 | string_len = first->value.character.length; | |||
1996 | } | |||
1997 | else | |||
1998 | string_len = 0; | |||
1999 | ||||
2000 | if (!p->ts.u.cl) | |||
2001 | { | |||
2002 | if (p->symtree) | |||
2003 | p->ts.u.cl = gfc_new_charlen (p->symtree->n.sym->ns, | |||
2004 | NULL__null); | |||
2005 | else | |||
2006 | p->ts.u.cl = gfc_new_charlen (gfc_current_ns, | |||
2007 | NULL__null); | |||
2008 | } | |||
2009 | else | |||
2010 | gfc_free_expr (p->ts.u.cl->length); | |||
2011 | ||||
2012 | p->ts.u.cl->length | |||
2013 | = gfc_get_int_expr (gfc_charlen_int_kind, | |||
2014 | NULL__null, string_len); | |||
2015 | } | |||
2016 | } | |||
2017 | gfc_free_ref_list (p->ref); | |||
2018 | p->ref = NULL__null; | |||
2019 | break; | |||
2020 | ||||
2021 | default: | |||
2022 | return true; | |||
2023 | } | |||
2024 | ||||
2025 | break; | |||
2026 | ||||
2027 | case REF_COMPONENT: | |||
2028 | cons = find_component_ref (p->value.constructor, p->ref); | |||
2029 | remove_subobject_ref (p, cons); | |||
2030 | break; | |||
2031 | ||||
2032 | case REF_INQUIRY: | |||
2033 | if (!find_inquiry_ref (p, &newp)) | |||
2034 | return false; | |||
2035 | ||||
2036 | gfc_replace_expr (p, newp); | |||
2037 | gfc_free_ref_list (p->ref); | |||
2038 | p->ref = NULL__null; | |||
2039 | break; | |||
2040 | ||||
2041 | case REF_SUBSTRING: | |||
2042 | if (!find_substring_ref (p, &newp)) | |||
2043 | return false; | |||
2044 | ||||
2045 | gfc_replace_expr (p, newp); | |||
2046 | gfc_free_ref_list (p->ref); | |||
2047 | p->ref = NULL__null; | |||
2048 | break; | |||
2049 | } | |||
2050 | } | |||
2051 | ||||
2052 | return true; | |||
2053 | } | |||
2054 | ||||
2055 | ||||
2056 | /* Simplify a chain of references. */ | |||
2057 | ||||
2058 | static bool | |||
2059 | simplify_ref_chain (gfc_ref *ref, int type, gfc_expr **p) | |||
2060 | { | |||
2061 | int n; | |||
2062 | gfc_expr *newp; | |||
2063 | ||||
2064 | for (; ref; ref = ref->next) | |||
2065 | { | |||
2066 | switch (ref->type) | |||
2067 | { | |||
2068 | case REF_ARRAY: | |||
2069 | for (n = 0; n < ref->u.ar.dimen; n++) | |||
2070 | { | |||
2071 | if (!gfc_simplify_expr (ref->u.ar.start[n], type)) | |||
2072 | return false; | |||
2073 | if (!gfc_simplify_expr (ref->u.ar.end[n], type)) | |||
2074 | return false; | |||
2075 | if (!gfc_simplify_expr (ref->u.ar.stride[n], type)) | |||
2076 | return false; | |||
2077 | } | |||
2078 | break; | |||
2079 | ||||
2080 | case REF_SUBSTRING: | |||
2081 | if (!gfc_simplify_expr (ref->u.ss.start, type)) | |||
2082 | return false; | |||
2083 | if (!gfc_simplify_expr (ref->u.ss.end, type)) | |||
2084 | return false; | |||
2085 | break; | |||
2086 | ||||
2087 | case REF_INQUIRY: | |||
2088 | if (!find_inquiry_ref (*p, &newp)) | |||
2089 | return false; | |||
2090 | ||||
2091 | gfc_replace_expr (*p, newp); | |||
2092 | gfc_free_ref_list ((*p)->ref); | |||
2093 | (*p)->ref = NULL__null; | |||
2094 | return true; | |||
2095 | ||||
2096 | default: | |||
2097 | break; | |||
2098 | } | |||
2099 | } | |||
2100 | return true; | |||
2101 | } | |||
2102 | ||||
2103 | ||||
2104 | /* Try to substitute the value of a parameter variable. */ | |||
2105 | ||||
2106 | static bool | |||
2107 | simplify_parameter_variable (gfc_expr *p, int type) | |||
2108 | { | |||
2109 | gfc_expr *e; | |||
2110 | bool t; | |||
2111 | ||||
2112 | /* Set rank and check array ref; as resolve_variable calls | |||
2113 | gfc_simplify_expr, call gfc_resolve_ref + gfc_expression_rank instead. */ | |||
2114 | if (!gfc_resolve_ref (p)) | |||
2115 | { | |||
2116 | gfc_error_check (); | |||
2117 | return false; | |||
2118 | } | |||
2119 | gfc_expression_rank (p); | |||
2120 | ||||
2121 | /* Is this an inquiry? */ | |||
2122 | bool inquiry = false; | |||
2123 | gfc_ref* ref = p->ref; | |||
2124 | while (ref) | |||
2125 | { | |||
2126 | if (ref->type == REF_INQUIRY) | |||
2127 | break; | |||
2128 | ref = ref->next; | |||
2129 | } | |||
2130 | if (ref && ref->type == REF_INQUIRY) | |||
2131 | inquiry = ref->u.i == INQUIRY_LEN || ref->u.i == INQUIRY_KIND; | |||
2132 | ||||
2133 | if (gfc_is_size_zero_array (p)) | |||
2134 | { | |||
2135 | if (p->expr_type == EXPR_ARRAY) | |||
2136 | return true; | |||
2137 | ||||
2138 | e = gfc_get_expr (); | |||
2139 | e->expr_type = EXPR_ARRAY; | |||
2140 | e->ts = p->ts; | |||
2141 | e->rank = p->rank; | |||
2142 | e->value.constructor = NULL__null; | |||
2143 | e->shape = gfc_copy_shape (p->shape, p->rank); | |||
2144 | e->where = p->where; | |||
2145 | /* If %kind and %len are not used then we're done, otherwise | |||
2146 | drop through for simplification. */ | |||
2147 | if (!inquiry) | |||
2148 | { | |||
2149 | gfc_replace_expr (p, e); | |||
2150 | return true; | |||
2151 | } | |||
2152 | } | |||
2153 | else | |||
2154 | { | |||
2155 | e = gfc_copy_expr (p->symtree->n.sym->value); | |||
2156 | if (e == NULL__null) | |||
2157 | return false; | |||
2158 | ||||
2159 | gfc_free_shape (&e->shape, e->rank); | |||
2160 | e->shape = gfc_copy_shape (p->shape, p->rank); | |||
2161 | e->rank = p->rank; | |||
2162 | ||||
2163 | if (e->ts.type == BT_CHARACTER && p->ts.u.cl) | |||
2164 | e->ts = p->ts; | |||
2165 | } | |||
2166 | ||||
2167 | if (e->ts.type == BT_CHARACTER && e->ts.u.cl == NULL__null) | |||
2168 | e->ts.u.cl = gfc_new_charlen (gfc_current_ns, p->ts.u.cl); | |||
2169 | ||||
2170 | /* Do not copy subobject refs for constant. */ | |||
2171 | if (e->expr_type != EXPR_CONSTANT && p->ref != NULL__null) | |||
2172 | e->ref = gfc_copy_ref (p->ref); | |||
2173 | t = gfc_simplify_expr (e, type); | |||
2174 | e->where = p->where; | |||
2175 | ||||
2176 | /* Only use the simplification if it eliminated all subobject references. */ | |||
2177 | if (t && !e->ref) | |||
2178 | gfc_replace_expr (p, e); | |||
2179 | else | |||
2180 | gfc_free_expr (e); | |||
2181 | ||||
2182 | return t; | |||
2183 | } | |||
2184 | ||||
2185 | ||||
2186 | static bool | |||
2187 | scalarize_intrinsic_call (gfc_expr *, bool init_flag); | |||
2188 | ||||
2189 | /* Given an expression, simplify it by collapsing constant | |||
2190 | expressions. Most simplification takes place when the expression | |||
2191 | tree is being constructed. If an intrinsic function is simplified | |||
2192 | at some point, we get called again to collapse the result against | |||
2193 | other constants. | |||
2194 | ||||
2195 | We work by recursively simplifying expression nodes, simplifying | |||
2196 | intrinsic functions where possible, which can lead to further | |||
2197 | constant collapsing. If an operator has constant operand(s), we | |||
2198 | rip the expression apart, and rebuild it, hoping that it becomes | |||
2199 | something simpler. | |||
2200 | ||||
2201 | The expression type is defined for: | |||
2202 | 0 Basic expression parsing | |||
2203 | 1 Simplifying array constructors -- will substitute | |||
2204 | iterator values. | |||
2205 | Returns false on error, true otherwise. | |||
2206 | NOTE: Will return true even if the expression cannot be simplified. */ | |||
2207 | ||||
2208 | bool | |||
2209 | gfc_simplify_expr (gfc_expr *p, int type) | |||
2210 | { | |||
2211 | gfc_actual_arglist *ap; | |||
2212 | gfc_intrinsic_sym* isym = NULL__null; | |||
2213 | ||||
2214 | ||||
2215 | if (p == NULL__null) | |||
2216 | return true; | |||
2217 | ||||
2218 | switch (p->expr_type) | |||
2219 | { | |||
2220 | case EXPR_CONSTANT: | |||
2221 | if (p->ref && p->ref->type == REF_INQUIRY) | |||
2222 | simplify_ref_chain (p->ref, type, &p); | |||
2223 | break; | |||
2224 | case EXPR_NULL: | |||
2225 | break; | |||
2226 | ||||
2227 | case EXPR_FUNCTION: | |||
2228 | // For array-bound functions, we don't need to optimize | |||
2229 | // the 'array' argument. In particular, if the argument | |||
2230 | // is a PARAMETER, simplifying might convert an EXPR_VARIABLE | |||
2231 | // into an EXPR_ARRAY; the latter has lbound = 1, the former | |||
2232 | // can have any lbound. | |||
2233 | ap = p->value.function.actual; | |||
2234 | if (p->value.function.isym && | |||
2235 | (p->value.function.isym->id == GFC_ISYM_LBOUND | |||
2236 | || p->value.function.isym->id == GFC_ISYM_UBOUND | |||
2237 | || p->value.function.isym->id == GFC_ISYM_LCOBOUND | |||
2238 | || p->value.function.isym->id == GFC_ISYM_UCOBOUND | |||
2239 | || p->value.function.isym->id == GFC_ISYM_SHAPE)) | |||
2240 | ap = ap->next; | |||
2241 | ||||
2242 | for ( ; ap; ap = ap->next) | |||
2243 | if (!gfc_simplify_expr (ap->expr, type)) | |||
2244 | return false; | |||
2245 | ||||
2246 | if (p->value.function.isym != NULL__null | |||
2247 | && gfc_intrinsic_func_interface (p, 1) == MATCH_ERROR) | |||
2248 | return false; | |||
2249 | ||||
2250 | if (p->symtree && (p->value.function.isym || p->ts.type == BT_UNKNOWN)) | |||
2251 | { | |||
2252 | isym = gfc_find_function (p->symtree->n.sym->name); | |||
2253 | if (isym && isym->elemental) | |||
2254 | scalarize_intrinsic_call (p, false); | |||
2255 | } | |||
2256 | ||||
2257 | break; | |||
2258 | ||||
2259 | case EXPR_SUBSTRING: | |||
2260 | if (!simplify_ref_chain (p->ref, type, &p)) | |||
2261 | return false; | |||
2262 | ||||
2263 | if (gfc_is_constant_expr (p)) | |||
2264 | { | |||
2265 | gfc_char_t *s; | |||
2266 | HOST_WIDE_INTlong start, end; | |||
2267 | ||||
2268 | start = 0; | |||
2269 | if (p->ref && p->ref->u.ss.start) | |||
2270 | { | |||
2271 | gfc_extract_hwi (p->ref->u.ss.start, &start); | |||
2272 | start--; /* Convert from one-based to zero-based. */ | |||
2273 | } | |||
2274 | ||||
2275 | end = p->value.character.length; | |||
2276 | if (p->ref && p->ref->u.ss.end) | |||
2277 | gfc_extract_hwi (p->ref->u.ss.end, &end); | |||
2278 | ||||
2279 | if (end < start) | |||
2280 | end = start; | |||
2281 | ||||
2282 | s = gfc_get_wide_string (end - start + 2)((gfc_char_t *) xcalloc ((end - start + 2), sizeof (gfc_char_t ))); | |||
2283 | memcpy (s, p->value.character.string + start, | |||
2284 | (end - start) * sizeof (gfc_char_t)); | |||
2285 | s[end - start + 1] = '\0'; /* TODO: C-style string. */ | |||
2286 | free (p->value.character.string); | |||
2287 | p->value.character.string = s; | |||
2288 | p->value.character.length = end - start; | |||
2289 | p->ts.u.cl = gfc_new_charlen (gfc_current_ns, NULL__null); | |||
2290 | p->ts.u.cl->length = gfc_get_int_expr (gfc_charlen_int_kind, | |||
2291 | NULL__null, | |||
2292 | p->value.character.length); | |||
2293 | gfc_free_ref_list (p->ref); | |||
2294 | p->ref = NULL__null; | |||
2295 | p->expr_type = EXPR_CONSTANT; | |||
2296 | } | |||
2297 | break; | |||
2298 | ||||
2299 | case EXPR_OP: | |||
2300 | if (!simplify_intrinsic_op (p, type)) | |||
2301 | return false; | |||
2302 | break; | |||
2303 | ||||
2304 | case EXPR_VARIABLE: | |||
2305 | /* Only substitute array parameter variables if we are in an | |||
2306 | initialization expression, or we want a subsection. */ | |||
2307 | if (p->symtree->n.sym->attr.flavor == FL_PARAMETER | |||
2308 | && (gfc_init_expr_flag || p->ref | |||
2309 | || (p->symtree->n.sym->value | |||
2310 | && p->symtree->n.sym->value->expr_type != EXPR_ARRAY))) | |||
2311 | { | |||
2312 | if (!simplify_parameter_variable (p, type)) | |||
2313 | return false; | |||
2314 | break; | |||
2315 | } | |||
2316 | ||||
2317 | if (type == 1) | |||
2318 | { | |||
2319 | gfc_simplify_iterator_var (p); | |||
2320 | } | |||
2321 | ||||
2322 | /* Simplify subcomponent references. */ | |||
2323 | if (!simplify_ref_chain (p->ref, type, &p)) | |||
2324 | return false; | |||
2325 | ||||
2326 | break; | |||
2327 | ||||
2328 | case EXPR_STRUCTURE: | |||
2329 | case EXPR_ARRAY: | |||
2330 | if (!simplify_ref_chain (p->ref, type, &p)) | |||
2331 | return false; | |||
2332 | ||||
2333 | /* If the following conditions hold, we found something like kind type | |||
2334 | inquiry of the form a(2)%kind while simplify the ref chain. */ | |||
2335 | if (p->expr_type == EXPR_CONSTANT && !p->ref && !p->rank && !p->shape) | |||
2336 | return true; | |||
2337 | ||||
2338 | if (!simplify_constructor (p->value.constructor, type)) | |||
2339 | return false; | |||
2340 | ||||
2341 | if (p->expr_type == EXPR_ARRAY && p->ref && p->ref->type == REF_ARRAY | |||
2342 | && p->ref->u.ar.type == AR_FULL) | |||
2343 | gfc_expand_constructor (p, false); | |||
2344 | ||||
2345 | if (!simplify_const_ref (p)) | |||
2346 | return false; | |||
2347 | ||||
2348 | break; | |||
2349 | ||||
2350 | case EXPR_COMPCALL: | |||
2351 | case EXPR_PPC: | |||
2352 | break; | |||
2353 | ||||
2354 | case EXPR_UNKNOWN: | |||
2355 | gcc_unreachable ()(fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/fortran/expr.cc" , 2355, __FUNCTION__)); | |||
2356 | } | |||
2357 | ||||
2358 | return true; | |||
2359 | } | |||
2360 | ||||
2361 | ||||
2362 | /* Try simplification of an expression via gfc_simplify_expr. | |||
2363 | When an error occurs (arithmetic or otherwise), roll back. */ | |||
2364 | ||||
2365 | bool | |||
2366 | gfc_try_simplify_expr (gfc_expr *e, int type) | |||
2367 | { | |||
2368 | gfc_expr *n; | |||
2369 | bool t, saved_div0; | |||
2370 | ||||
2371 | if (e == NULL__null || e->expr_type == EXPR_CONSTANT) | |||
2372 | return true; | |||
2373 | ||||
2374 | saved_div0 = gfc_seen_div0; | |||
2375 | gfc_seen_div0 = false; | |||
2376 | n = gfc_copy_expr (e); | |||
2377 | t = gfc_simplify_expr (n, type) && !gfc_seen_div0; | |||
2378 | if (t) | |||
2379 | gfc_replace_expr (e, n); | |||
2380 | else | |||
2381 | gfc_free_expr (n); | |||
2382 | gfc_seen_div0 = saved_div0; | |||
2383 | return t; | |||
2384 | } | |||
2385 | ||||
2386 | ||||
2387 | /* Returns the type of an expression with the exception that iterator | |||
2388 | variables are automatically integers no matter what else they may | |||
2389 | be declared as. */ | |||
2390 | ||||
2391 | static bt | |||
2392 | et0 (gfc_expr *e) | |||
2393 | { | |||
2394 | if (e->expr_type == EXPR_VARIABLE && gfc_check_iter_variable (e)) | |||
2395 | return BT_INTEGER; | |||
2396 | ||||
2397 | return e->ts.type; | |||
2398 | } | |||
2399 | ||||
2400 | ||||
2401 | /* Scalarize an expression for an elemental intrinsic call. */ | |||
2402 | ||||
2403 | static bool | |||
2404 | scalarize_intrinsic_call (gfc_expr *e, bool init_flag) | |||
2405 | { | |||
2406 | gfc_actual_arglist *a, *b; | |||
2407 | gfc_constructor_base ctor; | |||
2408 | gfc_constructor *args[5] = {}; /* Avoid uninitialized warnings. */ | |||
2409 | gfc_constructor *ci, *new_ctor; | |||
2410 | gfc_expr *expr, *old, *p; | |||
2411 | int n, i, rank[5], array_arg; | |||
2412 | ||||
2413 | if (e == NULL__null) | |||
2414 | return false; | |||
2415 | ||||
2416 | a = e->value.function.actual; | |||
2417 | for (; a; a = a->next) | |||
2418 | if (a->expr && !gfc_is_constant_expr (a->expr)) | |||
2419 | return false; | |||
2420 | ||||
2421 | /* Find which, if any, arguments are arrays. Assume that the old | |||
2422 | expression carries the type information and that the first arg | |||
2423 | that is an array expression carries all the shape information.*/ | |||
2424 | n = array_arg = 0; | |||
2425 | a = e->value.function.actual; | |||
2426 | for (; a; a = a->next) | |||
2427 | { | |||
2428 | n++; | |||
2429 | if (!a->expr || a->expr->expr_type != EXPR_ARRAY) | |||
2430 | continue; | |||
2431 | array_arg = n; | |||
2432 | expr = gfc_copy_expr (a->expr); | |||
2433 | break; | |||
2434 | } | |||
2435 | ||||
2436 | if (!array_arg) | |||
2437 | return false; | |||
2438 | ||||
2439 | old = gfc_copy_expr (e); | |||
2440 | ||||
2441 | gfc_constructor_free (expr->value.constructor); | |||
2442 | expr->value.constructor = NULL__null; | |||
2443 | expr->ts = old->ts; | |||
2444 | expr->where = old->where; | |||
2445 | expr->expr_type = EXPR_ARRAY; | |||
2446 | ||||
2447 | /* Copy the array argument constructors into an array, with nulls | |||
2448 | for the scalars. */ | |||
2449 | n = 0; | |||
2450 | a = old->value.function.actual; | |||
2451 | for (; a; a = a->next) | |||
2452 | { | |||
2453 | /* Check that this is OK for an initialization expression. */ | |||
2454 | if (a->expr && init_flag && !gfc_check_init_expr (a->expr)) | |||
2455 | goto cleanup; | |||
2456 | ||||
2457 | rank[n] = 0; | |||
2458 | if (a->expr && a->expr->rank && a->expr->expr_type == EXPR_VARIABLE) | |||
2459 | { | |||
2460 | rank[n] = a->expr->rank; | |||
2461 | ctor = a->expr->symtree->n.sym->value->value.constructor; | |||
2462 | args[n] = gfc_constructor_first (ctor); | |||
2463 | } | |||
2464 | else if (a->expr && a->expr->expr_type == EXPR_ARRAY) | |||
2465 | { | |||
2466 | if (a->expr->rank) | |||
2467 | rank[n] = a->expr->rank; | |||
2468 | else | |||
2469 | rank[n] = 1; | |||
2470 | ctor = gfc_constructor_copy (a->expr->value.constructor); | |||
2471 | args[n] = gfc_constructor_first (ctor); | |||
2472 | } | |||
2473 | else | |||
2474 | args[n] = NULL__null; | |||
2475 | ||||
2476 | n++; | |||
2477 | } | |||
2478 | ||||
2479 | /* Using the array argument as the master, step through the array | |||
2480 | calling the function for each element and advancing the array | |||
2481 | constructors together. */ | |||
2482 | for (ci = args[array_arg - 1]; ci; ci = gfc_constructor_next (ci)) | |||
2483 | { | |||
2484 | new_ctor = gfc_constructor_append_expr (&expr->value.constructor, | |||
2485 | gfc_copy_expr (old), NULL__null); | |||
2486 | ||||
2487 | gfc_free_actual_arglist (new_ctor->expr->value.function.actual); | |||
2488 | a = NULL__null; | |||
2489 | b = old->value.function.actual; | |||
2490 | for (i = 0; i < n; i++) | |||
2491 | { | |||
2492 | if (a == NULL__null) | |||
2493 | new_ctor->expr->value.function.actual | |||
2494 | = a = gfc_get_actual_arglist ()((gfc_actual_arglist *) xcalloc (1, sizeof (gfc_actual_arglist ))); | |||
2495 | else | |||
2496 | { | |||
2497 | a->next = gfc_get_actual_arglist ()((gfc_actual_arglist *) xcalloc (1, sizeof (gfc_actual_arglist ))); | |||
2498 | a = a->next; | |||
2499 | } | |||
2500 | ||||
2501 | if (args[i]) | |||
2502 | a->expr = gfc_copy_expr (args[i]->expr); | |||
2503 | else | |||
2504 | a->expr = gfc_copy_expr (b->expr); | |||
2505 | ||||
2506 | b = b->next; | |||
2507 | } | |||
2508 | ||||
2509 | /* Simplify the function calls. If the simplification fails, the | |||
2510 | error will be flagged up down-stream or the library will deal | |||
2511 | with it. */ | |||
2512 | p = gfc_copy_expr (new_ctor->expr); | |||
2513 | ||||
2514 | if (!gfc_simplify_expr (p, init_flag)) | |||
2515 | gfc_free_expr (p); | |||
2516 | else | |||
2517 | gfc_replace_expr (new_ctor->expr, p); | |||
2518 | ||||
2519 | for (i = 0; i < n; i++) | |||
2520 | if (args[i]) | |||
2521 | args[i] = gfc_constructor_next (args[i]); | |||
2522 | ||||
2523 | for (i = 1; i < n; i++) | |||
2524 | if (rank[i] && ((args[i] != NULL__null && args[array_arg - 1] == NULL__null) | |||
2525 | || (args[i] == NULL__null && args[array_arg - 1] != NULL__null))) | |||
2526 | goto compliance; | |||
2527 | } | |||
2528 | ||||
2529 | free_expr0 (e); | |||
2530 | *e = *expr; | |||
2531 | /* Free "expr" but not the pointers it contains. */ | |||
2532 | free (expr); | |||
2533 | gfc_free_expr (old); | |||
2534 | return true; | |||
2535 | ||||
2536 | compliance: | |||
2537 | gfc_error_now ("elemental function arguments at %C are not compliant"); | |||
2538 | ||||
2539 | cleanup: | |||
2540 | gfc_free_expr (expr); | |||
2541 | gfc_free_expr (old); | |||
2542 | return false; | |||
2543 | } | |||
2544 | ||||
2545 | ||||
2546 | static bool | |||
2547 | check_intrinsic_op (gfc_expr *e, bool (*check_function) (gfc_expr *)) | |||
2548 | { | |||
2549 | gfc_expr *op1 = e->value.op.op1; | |||
2550 | gfc_expr *op2 = e->value.op.op2; | |||
2551 | ||||
2552 | if (!(*check_function)(op1)) | |||
2553 | return false; | |||
2554 | ||||
2555 | switch (e->value.op.op) | |||
2556 | { | |||
2557 | case INTRINSIC_UPLUS: | |||
2558 | case INTRINSIC_UMINUS: | |||
2559 | if (!numeric_type (et0 (op1))) | |||
2560 | goto not_numeric; | |||
2561 | break; | |||
2562 | ||||
2563 | case INTRINSIC_EQ: | |||
2564 | case INTRINSIC_EQ_OS: | |||
2565 | case INTRINSIC_NE: | |||
2566 | case INTRINSIC_NE_OS: | |||
2567 | case INTRINSIC_GT: | |||
2568 | case INTRINSIC_GT_OS: | |||
2569 | case INTRINSIC_GE: | |||
2570 | case INTRINSIC_GE_OS: | |||
2571 | case INTRINSIC_LT: | |||
2572 | case INTRINSIC_LT_OS: | |||
2573 | case INTRINSIC_LE: | |||
2574 | case INTRINSIC_LE_OS: | |||
2575 | if (!(*check_function)(op2)) | |||
2576 | return false; | |||
2577 | ||||
2578 | if (!(et0 (op1) == BT_CHARACTER && et0 (op2) == BT_CHARACTER) | |||
2579 | && !(numeric_type (et0 (op1)) && numeric_type (et0 (op2)))) | |||
2580 | { | |||
2581 | gfc_error ("Numeric or CHARACTER operands are required in " | |||
2582 | "expression at %L", &e->where); | |||
2583 | return false; | |||
2584 | } | |||
2585 | break; | |||
2586 | ||||
2587 | case INTRINSIC_PLUS: | |||
2588 | case INTRINSIC_MINUS: | |||
2589 | case INTRINSIC_TIMES: | |||
2590 | case INTRINSIC_DIVIDE: | |||
2591 | case INTRINSIC_POWER: | |||
2592 | if (!(*check_function)(op2)) | |||
2593 | return false; | |||
2594 | ||||
2595 | if (!numeric_type (et0 (op1)) || !numeric_type (et0 (op2))) | |||
2596 | goto not_numeric; | |||
2597 | ||||
2598 | break; | |||
2599 | ||||
2600 | case INTRINSIC_CONCAT: | |||
2601 | if (!(*check_function)(op2)) | |||
2602 | return false; | |||
2603 | ||||
2604 | if (et0 (op1) != BT_CHARACTER || et0 (op2) != BT_CHARACTER) | |||
2605 | { | |||
2606 | gfc_error ("Concatenation operator in expression at %L " | |||
2607 | "must have two CHARACTER operands", &op1->where); | |||
2608 | return false; | |||
2609 | } | |||
2610 | ||||
2611 | if (op1->ts.kind != op2->ts.kind) | |||
2612 | { | |||
2613 | gfc_error ("Concat operator at %L must concatenate strings of the " | |||
2614 | "same kind", &e->where); | |||
2615 | return false; | |||
2616 | } | |||
2617 | ||||
2618 | break; | |||
2619 | ||||
2620 | case INTRINSIC_NOT: | |||
2621 | if (et0 (op1) != BT_LOGICAL) | |||
2622 | { | |||
2623 | gfc_error (".NOT. operator in expression at %L must have a LOGICAL " | |||
2624 | "operand", &op1->where); | |||
2625 | return false; | |||
2626 | } | |||
2627 | ||||
2628 | break; | |||
2629 | ||||
2630 | case INTRINSIC_AND: | |||
2631 | case INTRINSIC_OR: | |||
2632 | case INTRINSIC_EQV: | |||
2633 | case INTRINSIC_NEQV: | |||
2634 | if (!(*check_function)(op2)) | |||
2635 | return false; | |||
2636 | ||||
2637 | if (et0 (op1) != BT_LOGICAL || et0 (op2) != BT_LOGICAL) | |||
2638 | { | |||
2639 | gfc_error ("LOGICAL operands are required in expression at %L", | |||
2640 | &e->where); | |||
2641 | return false; | |||
2642 | } | |||
2643 | ||||
2644 | break; | |||
2645 | ||||
2646 | case INTRINSIC_PARENTHESES: | |||
2647 | break; | |||
2648 | ||||
2649 | default: | |||
2650 | gfc_error ("Only intrinsic operators can be used in expression at %L", | |||
2651 | &e->where); | |||
2652 | return false; | |||
2653 | } | |||
2654 | ||||
2655 | return true; | |||
2656 | ||||
2657 | not_numeric: | |||
2658 | gfc_error ("Numeric operands are required in expression at %L", &e->where); | |||
2659 | ||||
2660 | return false; | |||
2661 | } | |||
2662 | ||||
2663 | /* F2003, 7.1.7 (3): In init expression, allocatable components | |||
2664 | must not be data-initialized. */ | |||
2665 | static bool | |||
2666 | check_alloc_comp_init (gfc_expr *e) | |||
2667 | { | |||
2668 | gfc_component *comp; | |||
2669 | gfc_constructor *ctor; | |||
2670 | ||||
2671 | gcc_assert (e->expr_type == EXPR_STRUCTURE)((void)(!(e->expr_type == EXPR_STRUCTURE) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/fortran/expr.cc" , 2671, __FUNCTION__), 0 : 0)); | |||
2672 | gcc_assert (e->ts.type == BT_DERIVED || e->ts.type == BT_CLASS)((void)(!(e->ts.type == BT_DERIVED || e->ts.type == BT_CLASS ) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/fortran/expr.cc" , 2672, __FUNCTION__), 0 : 0)); | |||
2673 | ||||
2674 | for (comp = e->ts.u.derived->components, | |||
2675 | ctor = gfc_constructor_first (e->value.constructor); | |||
2676 | comp; comp = comp->next, ctor = gfc_constructor_next (ctor)) | |||
2677 | { | |||
2678 | if (comp->attr.allocatable && ctor->expr | |||
2679 | && ctor->expr->expr_type != EXPR_NULL) | |||
2680 | { | |||
2681 | gfc_error ("Invalid initialization expression for ALLOCATABLE " | |||
2682 | "component %qs in structure constructor at %L", | |||
2683 | comp->name, &ctor->expr->where); | |||
2684 | return false; | |||
2685 | } | |||
2686 | } | |||
2687 | ||||
2688 | return true; | |||
2689 | } | |||
2690 | ||||
2691 | static match | |||
2692 | check_init_expr_arguments (gfc_expr *e) | |||
2693 | { | |||
2694 | gfc_actual_arglist *ap; | |||
2695 | ||||
2696 | for (ap = e->value.function.actual; ap; ap = ap->next) | |||
2697 | if (!gfc_check_init_expr (ap->expr)) | |||
2698 | return MATCH_ERROR; | |||
2699 | ||||
2700 | return MATCH_YES; | |||
2701 | } | |||
2702 | ||||
2703 | static bool check_restricted (gfc_expr *); | |||
2704 | ||||
2705 | /* F95, 7.1.6.1, Initialization expressions, (7) | |||
2706 | F2003, 7.1.7 Initialization expression, (8) | |||
2707 | F2008, 7.1.12 Constant expression, (4) */ | |||
2708 | ||||
2709 | static match | |||
2710 | check_inquiry (gfc_expr *e, int not_restricted) | |||
2711 | { | |||
2712 | const char *name; | |||
2713 | const char *const *functions; | |||
2714 | ||||
2715 | static const char *const inquiry_func_f95[] = { | |||
2716 | "lbound", "shape", "size", "ubound", | |||
2717 | "bit_size", "len", "kind", | |||
2718 | "digits", "epsilon", "huge", "maxexponent", "minexponent", | |||
2719 | "precision", "radix", "range", "tiny", | |||
2720 | NULL__null | |||
2721 | }; | |||
2722 | ||||
2723 | static const char *const inquiry_func_f2003[] = { | |||
2724 | "lbound", "shape", "size", "ubound", | |||
2725 | "bit_size", "len", "kind", | |||
2726 | "digits", "epsilon", "huge", "maxexponent", "minexponent", | |||
2727 | "precision", "radix", "range", "tiny", | |||
2728 | "new_line", NULL__null | |||
2729 | }; | |||
2730 | ||||
2731 | /* std=f2008+ or -std=gnu */ | |||
2732 | static const char *const inquiry_func_gnu[] = { | |||
2733 | "lbound", "shape", "size", "ubound", | |||
2734 | "bit_size", "len", "kind", | |||
2735 | "digits", "epsilon", "huge", "maxexponent", "minexponent", | |||
2736 | "precision", "radix", "range", "tiny", | |||
2737 | "new_line", "storage_size", NULL__null | |||
2738 | }; | |||
2739 | ||||
2740 | int i = 0; | |||
2741 | gfc_actual_arglist *ap; | |||
2742 | gfc_symbol *sym; | |||
2743 | gfc_symbol *asym; | |||
2744 | ||||
2745 | if (!e->value.function.isym |
29.1 | Field 'isym' is non-null |
50.1 | 'asym' is null |
51 | Forming reference to null pointer |
11.1 | 'e' is not equal to NULL |
19.1 | 'conversion' is false |
1 | Assuming field 'as' is null |