Branch data Line data Source code
1 : : /* Supporting functions for resolving DATA statement.
2 : : Copyright (C) 2002-2025 Free Software Foundation, Inc.
3 : : Contributed by Lifang Zeng <zlf605@hotmail.com>
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 : :
22 : : /* Notes for DATA statement implementation:
23 : :
24 : : We first assign initial value to each symbol by gfc_assign_data_value
25 : : during resolving DATA statement. Refer to check_data_variable and
26 : : traverse_data_list in resolve.cc.
27 : :
28 : : The complexity exists in the handling of array section, implied do
29 : : and array of struct appeared in DATA statement.
30 : :
31 : : We call gfc_conv_structure, gfc_con_array_array_initializer,
32 : : etc., to convert the initial value. Refer to trans-expr.cc and
33 : : trans-array.cc. */
34 : :
35 : : #include "config.h"
36 : : #include "system.h"
37 : : #include "coretypes.h"
38 : : #include "gfortran.h"
39 : : #include "data.h"
40 : : #include "constructor.h"
41 : :
42 : : static void formalize_init_expr (gfc_expr *);
43 : :
44 : : /* Calculate the array element offset. */
45 : :
46 : : static bool
47 : 1436 : get_array_index (gfc_array_ref *ar, mpz_t *offset)
48 : : {
49 : 1436 : gfc_expr *e;
50 : 1436 : int i;
51 : 1436 : mpz_t delta;
52 : 1436 : mpz_t tmp;
53 : 1436 : bool ok = true;
54 : :
55 : 1436 : mpz_init (tmp);
56 : 1436 : mpz_set_si (*offset, 0);
57 : 1436 : mpz_init_set_si (delta, 1);
58 : 5055 : for (i = 0; i < ar->dimen; i++)
59 : : {
60 : 2188 : e = gfc_copy_expr (ar->start[i]);
61 : 2188 : gfc_simplify_expr (e, 1);
62 : :
63 : 2188 : if (!gfc_is_constant_expr (ar->as->lower[i])
64 : 2188 : || !gfc_is_constant_expr (ar->as->upper[i])
65 : 4375 : || !gfc_is_constant_expr (e))
66 : : {
67 : 1 : gfc_error ("non-constant array in DATA statement %L", &ar->where);
68 : 1 : ok = false;
69 : 1 : break;
70 : : }
71 : :
72 : 2187 : mpz_set (tmp, e->value.integer);
73 : 2187 : gfc_free_expr (e);
74 : :
75 : : /* Overindexing is only allowed as a legacy extension. */
76 : 2187 : if (mpz_cmp (tmp, ar->as->lower[i]->value.integer) < 0
77 : 2187 : && !gfc_notify_std (GFC_STD_LEGACY,
78 : : "Subscript at %L below array lower bound "
79 : : "(%ld < %ld) in dimension %d", &ar->c_where[i],
80 : : mpz_get_si (tmp),
81 : : mpz_get_si (ar->as->lower[i]->value.integer),
82 : : i+1))
83 : : {
84 : : ok = false;
85 : : break;
86 : : }
87 : 2185 : if (mpz_cmp (tmp, ar->as->upper[i]->value.integer) > 0
88 : 2185 : && !gfc_notify_std (GFC_STD_LEGACY,
89 : : "Subscript at %L above array upper bound "
90 : : "(%ld > %ld) in dimension %d", &ar->c_where[i],
91 : : mpz_get_si (tmp),
92 : : mpz_get_si (ar->as->upper[i]->value.integer),
93 : : i+1))
94 : : {
95 : : ok = false;
96 : : break;
97 : : }
98 : :
99 : 2183 : mpz_sub (tmp, tmp, ar->as->lower[i]->value.integer);
100 : 2183 : mpz_mul (tmp, tmp, delta);
101 : 2183 : mpz_add (*offset, tmp, *offset);
102 : :
103 : 2183 : mpz_sub (tmp, ar->as->upper[i]->value.integer,
104 : 2183 : ar->as->lower[i]->value.integer);
105 : 2183 : mpz_add_ui (tmp, tmp, 1);
106 : 2183 : mpz_mul (delta, tmp, delta);
107 : : }
108 : 1436 : mpz_clear (delta);
109 : 1436 : mpz_clear (tmp);
110 : :
111 : 1436 : return ok;
112 : : }
113 : :
114 : : /* Find if there is a constructor which component is equal to COM.
115 : : TODO: remove this, use symbol.cc(gfc_find_component) instead. */
116 : :
117 : : static gfc_constructor *
118 : 844 : find_con_by_component (gfc_component *com, gfc_constructor_base base)
119 : : {
120 : 844 : gfc_constructor *c;
121 : :
122 : 1996 : for (c = gfc_constructor_first (base); c; c = gfc_constructor_next (c))
123 : 1814 : if (com == c->n.component)
124 : : return c;
125 : :
126 : : return NULL;
127 : : }
128 : :
129 : :
130 : : /* Create a character type initialization expression from RVALUE.
131 : : TS [and REF] describe [the substring of] the variable being initialized.
132 : : INIT is the existing initializer, not NULL. Initialization is performed
133 : : according to normal assignment rules. */
134 : :
135 : : static gfc_expr *
136 : 720 : create_character_initializer (gfc_expr *init, gfc_typespec *ts,
137 : : gfc_ref *ref, gfc_expr *rvalue)
138 : : {
139 : 720 : HOST_WIDE_INT len, start, end, tlen;
140 : 720 : gfc_char_t *dest;
141 : 720 : bool alloced_init = false;
142 : :
143 : 720 : if (init && init->ts.type != BT_CHARACTER)
144 : : return NULL;
145 : :
146 : 719 : gfc_extract_hwi (ts->u.cl->length, &len);
147 : :
148 : 719 : if (init == NULL)
149 : : {
150 : : /* Create a new initializer. */
151 : 673 : init = gfc_get_character_expr (ts->kind, NULL, NULL, len);
152 : 673 : init->ts = *ts;
153 : 673 : alloced_init = true;
154 : : }
155 : :
156 : 719 : dest = init->value.character.string;
157 : :
158 : 719 : if (ref)
159 : : {
160 : 98 : gfc_expr *start_expr, *end_expr;
161 : :
162 : 98 : gcc_assert (ref->type == REF_SUBSTRING);
163 : :
164 : : /* Only set a substring of the destination. Fortran substring bounds
165 : : are one-based [start, end], we want zero based [start, end). */
166 : 98 : start_expr = gfc_copy_expr (ref->u.ss.start);
167 : 98 : end_expr = gfc_copy_expr (ref->u.ss.end);
168 : :
169 : 98 : if ((!gfc_simplify_expr(start_expr, 1))
170 : 98 : || !(gfc_simplify_expr(end_expr, 1)))
171 : : {
172 : 0 : gfc_error ("failure to simplify substring reference in DATA "
173 : 0 : "statement at %L", &ref->u.ss.start->where);
174 : 0 : gfc_free_expr (start_expr);
175 : 0 : gfc_free_expr (end_expr);
176 : 0 : if (alloced_init)
177 : 0 : gfc_free_expr (init);
178 : 0 : return NULL;
179 : : }
180 : :
181 : 98 : gfc_extract_hwi (start_expr, &start);
182 : 98 : gfc_free_expr (start_expr);
183 : 98 : start--;
184 : 98 : gfc_extract_hwi (end_expr, &end);
185 : 98 : gfc_free_expr (end_expr);
186 : : }
187 : : else
188 : : {
189 : : /* Set the whole string. */
190 : 621 : start = 0;
191 : 621 : end = len;
192 : : }
193 : :
194 : : /* Copy the initial value. */
195 : 719 : if (rvalue->ts.type == BT_HOLLERITH)
196 : 42 : len = rvalue->representation.length - rvalue->ts.u.pad;
197 : : else
198 : 677 : len = rvalue->value.character.length;
199 : :
200 : 719 : tlen = end - start;
201 : 719 : if (len > tlen)
202 : : {
203 : 44 : if (tlen < 0)
204 : : {
205 : 3 : gfc_warning_now (0, "Unused initialization string at %L because "
206 : : "variable has zero length", &rvalue->where);
207 : 3 : len = 0;
208 : : }
209 : : else
210 : : {
211 : 41 : gfc_warning_now (0, "Initialization string at %L was truncated to "
212 : : "fit the variable (%wd/%wd)", &rvalue->where,
213 : : tlen, len);
214 : 41 : len = tlen;
215 : : }
216 : : }
217 : :
218 : 719 : if (start < 0)
219 : : {
220 : 1 : gfc_error ("Substring start index at %L is less than one",
221 : 1 : &ref->u.ss.start->where);
222 : 1 : return NULL;
223 : : }
224 : 718 : if (end > init->value.character.length)
225 : : {
226 : 1 : gfc_error ("Substring end index at %L exceeds the string length",
227 : 1 : &ref->u.ss.end->where);
228 : 1 : return NULL;
229 : : }
230 : :
231 : 717 : if (rvalue->ts.type == BT_HOLLERITH)
232 : : {
233 : 126 : for (size_t i = 0; i < (size_t) len; i++)
234 : 84 : dest[start+i] = rvalue->representation.string[i];
235 : : }
236 : : else
237 : 675 : memcpy (&dest[start], rvalue->value.character.string,
238 : 675 : len * sizeof (gfc_char_t));
239 : :
240 : : /* Pad with spaces. Substrings will already be blanked. */
241 : 717 : if (len < tlen && ref == NULL)
242 : 206 : gfc_wide_memset (&dest[start + len], ' ', end - (start + len));
243 : :
244 : 717 : if (rvalue->ts.type == BT_HOLLERITH)
245 : : {
246 : 42 : init->representation.length = init->value.character.length;
247 : 42 : init->representation.string
248 : 42 : = gfc_widechar_to_char (init->value.character.string,
249 : : init->value.character.length);
250 : : }
251 : :
252 : : return init;
253 : : }
254 : :
255 : :
256 : : /* Assign the initial value RVALUE to LVALUE's symbol->value. If the
257 : : LVALUE already has an initialization, we extend this, otherwise we
258 : : create a new one. If REPEAT is non-NULL, initialize *REPEAT
259 : : consecutive values in LVALUE the same value in RVALUE. In that case,
260 : : LVALUE must refer to a full array, not an array section. */
261 : :
262 : : bool
263 : 9199 : gfc_assign_data_value (gfc_expr *lvalue, gfc_expr *rvalue, mpz_t index,
264 : : mpz_t *repeat)
265 : : {
266 : 9199 : gfc_ref *ref;
267 : 9199 : gfc_expr *init;
268 : 9199 : gfc_expr *expr = NULL;
269 : 9199 : gfc_expr *rexpr;
270 : 9199 : gfc_constructor *con;
271 : 9199 : gfc_constructor *last_con;
272 : 9199 : gfc_symbol *symbol;
273 : 9199 : gfc_typespec *last_ts;
274 : 9199 : mpz_t offset;
275 : :
276 : 9199 : symbol = lvalue->symtree->n.sym;
277 : 9199 : init = symbol->value;
278 : 9199 : last_ts = &symbol->ts;
279 : 9199 : last_con = NULL;
280 : 9199 : mpz_init_set_si (offset, 0);
281 : :
282 : : /* Find/create the parent expressions for subobject references. */
283 : 17639 : for (ref = lvalue->ref; ref; ref = ref->next)
284 : : {
285 : : /* Break out of the loop if we find a substring. */
286 : 8572 : if (ref->type == REF_SUBSTRING)
287 : : {
288 : : /* A substring should always be the last subobject reference. */
289 : 98 : gcc_assert (ref->next == NULL);
290 : : break;
291 : : }
292 : :
293 : : /* Use the existing initializer expression if it exists. Otherwise
294 : : create a new one. */
295 : 8474 : if (init == NULL)
296 : 1234 : expr = gfc_get_expr ();
297 : : else
298 : : expr = init;
299 : :
300 : : /* Find or create this element. */
301 : 8474 : switch (ref->type)
302 : : {
303 : 7963 : case REF_ARRAY:
304 : 7963 : if (ref->u.ar.as->rank == 0)
305 : : {
306 : 2 : gcc_assert (ref->u.ar.as->corank > 0);
307 : 2 : if (init == NULL)
308 : 2 : free (expr);
309 : 2 : continue;
310 : : }
311 : :
312 : 7961 : if (init && expr->expr_type != EXPR_ARRAY)
313 : : {
314 : 7 : gfc_error ("%qs at %L already is initialized at %L",
315 : 7 : lvalue->symtree->n.sym->name, &lvalue->where,
316 : : &init->where);
317 : 7 : goto abort;
318 : : }
319 : :
320 : : if (init == NULL)
321 : : {
322 : : /* The element typespec will be the same as the array
323 : : typespec. */
324 : 1075 : expr->ts = *last_ts;
325 : : /* Setup the expression to hold the constructor. */
326 : 1075 : expr->expr_type = EXPR_ARRAY;
327 : 1075 : expr->rank = ref->u.ar.as->rank;
328 : 1075 : expr->corank = ref->u.ar.as->corank;
329 : : }
330 : :
331 : 7954 : if (ref->u.ar.type == AR_ELEMENT)
332 : : {
333 : 1436 : if (!get_array_index (&ref->u.ar, &offset))
334 : 5 : goto abort;
335 : : }
336 : : else
337 : 6518 : mpz_set (offset, index);
338 : :
339 : : /* Check the bounds. */
340 : 7949 : if (mpz_cmp_si (offset, 0) < 0)
341 : : {
342 : 2 : gfc_error ("Data element below array lower bound at %L",
343 : : &lvalue->where);
344 : 2 : goto abort;
345 : : }
346 : 7947 : else if (repeat != NULL
347 : 196 : && ref->u.ar.type != AR_ELEMENT)
348 : : {
349 : 160 : mpz_t size, end;
350 : 160 : gcc_assert (ref->u.ar.type == AR_FULL
351 : : && ref->next == NULL);
352 : 160 : mpz_init_set (end, offset);
353 : 160 : mpz_add (end, end, *repeat);
354 : 160 : if (spec_size (ref->u.ar.as, &size))
355 : : {
356 : 160 : if (mpz_cmp (end, size) > 0)
357 : : {
358 : 0 : mpz_clear (size);
359 : 0 : gfc_error ("Data element above array upper bound at %L",
360 : : &lvalue->where);
361 : 0 : goto abort;
362 : : }
363 : 160 : mpz_clear (size);
364 : : }
365 : :
366 : 320 : con = gfc_constructor_lookup (expr->value.constructor,
367 : 160 : mpz_get_si (offset));
368 : 160 : if (!con)
369 : : {
370 : 312 : con = gfc_constructor_lookup_next (expr->value.constructor,
371 : 156 : mpz_get_si (offset));
372 : 156 : if (con != NULL && mpz_cmp (con->offset, end) >= 0)
373 : : con = NULL;
374 : : }
375 : :
376 : : /* Overwriting an existing initializer is non-standard but
377 : : usually only provokes a warning from other compilers. */
378 : 8 : if (con != NULL && con->expr != NULL)
379 : : {
380 : : /* Order in which the expressions arrive here depends on
381 : : whether they are from data statements or F95 style
382 : : declarations. Therefore, check which is the most
383 : : recent. */
384 : 8 : gfc_expr *exprd;
385 : 16 : exprd = (linemap_location_before_p (line_table,
386 : 8 : gfc_get_location (&con->expr->where),
387 : : gfc_get_location (&rvalue->where))
388 : 8 : ? rvalue : con->expr);
389 : 8 : if (gfc_notify_std (GFC_STD_GNU,
390 : : "re-initialization of %qs at %L",
391 : : symbol->name, &exprd->where) == false)
392 : 6 : return false;
393 : : }
394 : :
395 : 164 : while (con != NULL)
396 : : {
397 : 10 : gfc_constructor *next_con = gfc_constructor_next (con);
398 : :
399 : 10 : if (mpz_cmp (con->offset, end) >= 0)
400 : : break;
401 : 10 : if (mpz_cmp (con->offset, offset) < 0)
402 : : {
403 : 0 : gcc_assert (mpz_cmp_si (con->repeat, 1) > 0);
404 : 0 : mpz_sub (con->repeat, offset, con->offset);
405 : : }
406 : 10 : else if (mpz_cmp_si (con->repeat, 1) > 0
407 : 0 : && mpz_get_si (con->offset)
408 : 0 : + mpz_get_si (con->repeat) > mpz_get_si (end))
409 : : {
410 : 0 : int endi;
411 : 0 : splay_tree_node node
412 : 0 : = splay_tree_lookup (con->base,
413 : : mpz_get_si (con->offset));
414 : 0 : gcc_assert (node
415 : : && con == (gfc_constructor *) node->value
416 : : && node->key == (splay_tree_key)
417 : : mpz_get_si (con->offset));
418 : 0 : endi = mpz_get_si (con->offset)
419 : 0 : + mpz_get_si (con->repeat);
420 : 0 : if (endi > mpz_get_si (end) + 1)
421 : 0 : mpz_set_si (con->repeat, endi - mpz_get_si (end));
422 : : else
423 : 0 : mpz_set_si (con->repeat, 1);
424 : 0 : mpz_set (con->offset, end);
425 : 0 : node->key = (splay_tree_key) mpz_get_si (end);
426 : 0 : break;
427 : : }
428 : : else
429 : 10 : gfc_constructor_remove (con);
430 : : con = next_con;
431 : : }
432 : :
433 : 308 : con = gfc_constructor_insert_expr (&expr->value.constructor,
434 : : NULL, &rvalue->where,
435 : 154 : mpz_get_si (offset));
436 : 154 : mpz_set (con->repeat, *repeat);
437 : 154 : repeat = NULL;
438 : 154 : mpz_clear (end);
439 : 154 : break;
440 : : }
441 : : else
442 : : {
443 : 7787 : mpz_t size;
444 : 7787 : if (spec_size (ref->u.ar.as, &size))
445 : : {
446 : 7785 : if (mpz_cmp (offset, size) >= 0)
447 : : {
448 : 2 : mpz_clear (size);
449 : 2 : gfc_error ("Data element above array upper bound at %L",
450 : : &lvalue->where);
451 : 2 : goto abort;
452 : : }
453 : 7783 : mpz_clear (size);
454 : : }
455 : : }
456 : :
457 : 15570 : con = gfc_constructor_lookup (expr->value.constructor,
458 : 7785 : mpz_get_si (offset));
459 : 7785 : if (!con)
460 : : {
461 : 7391 : con = gfc_constructor_insert_expr (&expr->value.constructor,
462 : : NULL, &rvalue->where,
463 : 7391 : mpz_get_si (offset));
464 : : }
465 : 394 : else if (mpz_cmp_si (con->repeat, 1) > 0)
466 : : {
467 : : /* Need to split a range. */
468 : 14 : if (mpz_cmp (con->offset, offset) < 0)
469 : : {
470 : 9 : gfc_constructor *pred_con = con;
471 : 18 : con = gfc_constructor_insert_expr (&expr->value.constructor,
472 : : NULL, &con->where,
473 : 9 : mpz_get_si (offset));
474 : 9 : con->expr = gfc_copy_expr (pred_con->expr);
475 : 9 : mpz_add (con->repeat, pred_con->offset, pred_con->repeat);
476 : 9 : mpz_sub (con->repeat, con->repeat, offset);
477 : 9 : mpz_sub (pred_con->repeat, offset, pred_con->offset);
478 : : }
479 : 14 : if (mpz_cmp_si (con->repeat, 1) > 0)
480 : : {
481 : 13 : gfc_constructor *succ_con;
482 : 13 : succ_con
483 : 26 : = gfc_constructor_insert_expr (&expr->value.constructor,
484 : : NULL, &con->where,
485 : 13 : mpz_get_si (offset) + 1);
486 : 13 : succ_con->expr = gfc_copy_expr (con->expr);
487 : 13 : mpz_sub_ui (succ_con->repeat, con->repeat, 1);
488 : 13 : mpz_set_si (con->repeat, 1);
489 : : }
490 : : }
491 : : break;
492 : :
493 : 499 : case REF_COMPONENT:
494 : 499 : if (init == NULL)
495 : : {
496 : : /* Setup the expression to hold the constructor. */
497 : 151 : expr->expr_type = EXPR_STRUCTURE;
498 : 151 : expr->ts.type = BT_DERIVED;
499 : 151 : expr->ts.u.derived = ref->u.c.sym;
500 : : }
501 : : else
502 : 348 : gcc_assert (expr->expr_type == EXPR_STRUCTURE);
503 : 499 : last_ts = &ref->u.c.component->ts;
504 : :
505 : : /* Find the same element in the existing constructor. */
506 : 499 : con = find_con_by_component (ref->u.c.component,
507 : : expr->value.constructor);
508 : :
509 : 499 : if (con == NULL)
510 : : {
511 : : /* Create a new constructor. */
512 : 172 : con = gfc_constructor_append_expr (&expr->value.constructor,
513 : : NULL, NULL);
514 : 172 : con->n.component = ref->u.c.component;
515 : : }
516 : : break;
517 : :
518 : 12 : case REF_INQUIRY:
519 : :
520 : : /* After some discussion on clf it was determined that the following
521 : : violates F18(R841). If the error is removed, the expected result
522 : : is obtained. Leaving the code in place ensures a clean error
523 : : recovery. */
524 : 12 : gfc_error ("data-implied-do object at %L is neither an array-element "
525 : : "nor a scalar-structure-component (F2018: R841)",
526 : : &lvalue->where);
527 : :
528 : : /* This breaks with the other reference types in that the output
529 : : constructor has to be of type COMPLEX, whereas the lvalue is
530 : : of type REAL. The rvalue is copied to the real or imaginary
531 : : part as appropriate. In addition, for all except scalar
532 : : complex variables, a complex expression has to provided, where
533 : : the constructor does not have it, and the expression modified
534 : : with a new value for the real or imaginary part. */
535 : 12 : gcc_assert (ref->next == NULL && last_ts->type == BT_COMPLEX);
536 : 12 : rexpr = gfc_copy_expr (rvalue);
537 : 12 : if (!gfc_compare_types (&lvalue->ts, &rexpr->ts))
538 : 0 : gfc_convert_type (rexpr, &lvalue->ts, 0);
539 : :
540 : : /* This is the scalar, complex case, where an initializer exists. */
541 : 12 : if (init && ref == lvalue->ref)
542 : 1 : expr = symbol->value;
543 : : /* Then all cases, where a complex expression does not exist. */
544 : 11 : else if (!last_con || !last_con->expr)
545 : : {
546 : 6 : expr = gfc_get_constant_expr (BT_COMPLEX, lvalue->ts.kind,
547 : : &lvalue->where);
548 : 6 : if (last_con)
549 : 5 : last_con->expr = expr;
550 : : }
551 : : else
552 : : /* Finally, and existing constructor expression to be modified. */
553 : : expr = last_con->expr;
554 : :
555 : : /* Rejection of LEN and KIND inquiry references is handled
556 : : elsewhere. The error here is added as backup. The assertion
557 : : of F2008 for RE and IM is also done elsewhere. */
558 : 12 : switch (ref->u.i)
559 : : {
560 : 0 : case INQUIRY_LEN:
561 : 0 : case INQUIRY_KIND:
562 : 0 : gfc_error ("LEN or KIND inquiry ref in DATA statement at %L",
563 : : &lvalue->where);
564 : 0 : goto abort;
565 : 6 : case INQUIRY_RE:
566 : 6 : mpfr_set (mpc_realref (expr->value.complex),
567 : : rexpr->value.real,
568 : : GFC_RND_MODE);
569 : 6 : break;
570 : 6 : case INQUIRY_IM:
571 : 6 : mpfr_set (mpc_imagref (expr->value.complex),
572 : : rexpr->value.real,
573 : : GFC_RND_MODE);
574 : 6 : break;
575 : : }
576 : :
577 : : /* Only the scalar, complex expression needs to be saved as the
578 : : symbol value since the last constructor expression is already
579 : : provided as the initializer in the code after the reference
580 : : cases. */
581 : 12 : if (ref == lvalue->ref)
582 : 2 : symbol->value = expr;
583 : :
584 : 12 : gfc_free_expr (rexpr);
585 : 12 : mpz_clear (offset);
586 : 12 : return true;
587 : :
588 : 0 : default:
589 : 0 : gcc_unreachable ();
590 : : }
591 : :
592 : 8438 : if (init == NULL)
593 : : {
594 : : /* Point the container at the new expression. */
595 : 1223 : if (last_con == NULL)
596 : 1020 : symbol->value = expr;
597 : : else
598 : 203 : last_con->expr = expr;
599 : : }
600 : 8438 : init = con->expr;
601 : 8438 : last_con = con;
602 : : }
603 : :
604 : 9165 : mpz_clear (offset);
605 : 9165 : gcc_assert (repeat == NULL);
606 : :
607 : : /* Overwriting an existing initializer is non-standard but usually only
608 : : provokes a warning from other compilers. */
609 : 9165 : if (init != NULL
610 : 73 : && GFC_LOCUS_IS_SET (init->where)
611 : 73 : && GFC_LOCUS_IS_SET (rvalue->where))
612 : : {
613 : : /* Order in which the expressions arrive here depends on whether
614 : : they are from data statements or F95 style declarations.
615 : : Therefore, check which is the most recent. */
616 : 73 : expr = (linemap_location_before_p (line_table,
617 : : gfc_get_location (&init->where),
618 : : gfc_get_location (&rvalue->where))
619 : 73 : ? rvalue : init);
620 : 73 : if (gfc_notify_std (GFC_STD_GNU, "re-initialization of %qs at %L",
621 : : symbol->name, &expr->where) == false)
622 : : return false;
623 : : }
624 : :
625 : 9150 : if (ref || (last_ts->type == BT_CHARACTER
626 : 631 : && rvalue->expr_type == EXPR_CONSTANT))
627 : : {
628 : : /* An initializer has to be constant. */
629 : 721 : if (lvalue->ts.u.cl->length == NULL && !(ref && ref->u.ss.length != NULL))
630 : : return false;
631 : 720 : if (lvalue->ts.u.cl->length
632 : 670 : && lvalue->ts.u.cl->length->expr_type != EXPR_CONSTANT)
633 : : return false;
634 : 720 : expr = create_character_initializer (init, last_ts, ref, rvalue);
635 : 720 : if (!expr)
636 : : return false;
637 : : }
638 : : else
639 : : {
640 : 8429 : if (lvalue->ts.type == BT_DERIVED
641 : 8429 : && gfc_has_default_initializer (lvalue->ts.u.derived))
642 : : {
643 : 1 : gfc_error ("Nonpointer object %qs with default initialization "
644 : : "shall not appear in a DATA statement at %L",
645 : : symbol->name, &lvalue->where);
646 : 1 : return false;
647 : : }
648 : :
649 : 8428 : expr = gfc_copy_expr (rvalue);
650 : 8428 : if (!gfc_compare_types (&lvalue->ts, &expr->ts))
651 : 1469 : gfc_convert_type (expr, &lvalue->ts, 0);
652 : : }
653 : :
654 : 9145 : if (IS_POINTER (symbol)
655 : 9145 : && !gfc_check_pointer_assign (lvalue, rvalue, false, true))
656 : : return false;
657 : :
658 : 9144 : if (last_con == NULL)
659 : 1597 : symbol->value = expr;
660 : : else
661 : 7547 : last_con->expr = expr;
662 : :
663 : : return true;
664 : :
665 : 16 : abort:
666 : 16 : if (!init)
667 : 3 : gfc_free_expr (expr);
668 : 16 : mpz_clear (offset);
669 : 16 : return false;
670 : : }
671 : :
672 : :
673 : : /* Modify the index of array section and re-calculate the array offset. */
674 : :
675 : : void
676 : 363 : gfc_advance_section (mpz_t *section_index, gfc_array_ref *ar,
677 : : mpz_t *offset_ret, int *vector_offset)
678 : : {
679 : 363 : int i;
680 : 363 : mpz_t delta;
681 : 363 : mpz_t tmp;
682 : 363 : bool forwards;
683 : 363 : int cmp;
684 : 363 : gfc_expr *start, *end, *stride, *elem;
685 : 363 : gfc_constructor_base base;
686 : :
687 : 609 : for (i = 0; i < ar->dimen; i++)
688 : : {
689 : 467 : bool advance = false;
690 : :
691 : 467 : switch (ar->dimen_type[i])
692 : : {
693 : : case DIMEN_ELEMENT:
694 : : /* Loop to advance the next index. */
695 : : advance = true;
696 : : break;
697 : :
698 : 320 : case DIMEN_RANGE:
699 : 320 : if (ar->stride[i])
700 : : {
701 : 120 : stride = gfc_copy_expr(ar->stride[i]);
702 : 120 : if(!gfc_simplify_expr(stride, 1))
703 : 0 : gfc_internal_error("Simplification error");
704 : 120 : mpz_add (section_index[i], section_index[i],
705 : 120 : stride->value.integer);
706 : 120 : if (mpz_cmp_si (stride->value.integer, 0) >= 0)
707 : : forwards = true;
708 : : else
709 : 36 : forwards = false;
710 : 120 : gfc_free_expr(stride);
711 : : }
712 : : else
713 : : {
714 : 200 : mpz_add_ui (section_index[i], section_index[i], 1);
715 : 200 : forwards = true;
716 : : }
717 : :
718 : 320 : if (ar->end[i])
719 : : {
720 : 193 : end = gfc_copy_expr(ar->end[i]);
721 : 193 : if(!gfc_simplify_expr(end, 1))
722 : 0 : gfc_internal_error("Simplification error");
723 : 193 : cmp = mpz_cmp (section_index[i], end->value.integer);
724 : 193 : gfc_free_expr(end);
725 : : }
726 : : else
727 : 127 : cmp = mpz_cmp (section_index[i], ar->as->upper[i]->value.integer);
728 : :
729 : 320 : if ((cmp > 0 && forwards) || (cmp < 0 && !forwards))
730 : : {
731 : : /* Reset index to start, then loop to advance the next index. */
732 : 129 : if (ar->start[i])
733 : : {
734 : 76 : start = gfc_copy_expr(ar->start[i]);
735 : 76 : if(!gfc_simplify_expr(start, 1))
736 : 0 : gfc_internal_error("Simplification error");
737 : 76 : mpz_set (section_index[i], start->value.integer);
738 : 76 : gfc_free_expr(start);
739 : : }
740 : : else
741 : 53 : mpz_set (section_index[i], ar->as->lower[i]->value.integer);
742 : : advance = true;
743 : : }
744 : : break;
745 : :
746 : 72 : case DIMEN_VECTOR:
747 : 72 : vector_offset[i]++;
748 : 72 : base = ar->start[i]->value.constructor;
749 : 72 : elem = gfc_constructor_lookup_expr (base, vector_offset[i]);
750 : :
751 : 72 : if (elem == NULL)
752 : : {
753 : : /* Reset to first vector element and advance the next index. */
754 : 42 : vector_offset[i] = 0;
755 : 42 : elem = gfc_constructor_lookup_expr (base, 0);
756 : 42 : advance = true;
757 : : }
758 : 42 : if (elem)
759 : : {
760 : 72 : start = gfc_copy_expr (elem);
761 : 72 : if (!gfc_simplify_expr (start, 1))
762 : 0 : gfc_internal_error ("Simplification error");
763 : 72 : mpz_set (section_index[i], start->value.integer);
764 : 72 : gfc_free_expr (start);
765 : : }
766 : : break;
767 : :
768 : 0 : default:
769 : 0 : gcc_unreachable ();
770 : : }
771 : :
772 : 72 : if (!advance)
773 : : break;
774 : : }
775 : :
776 : 363 : mpz_set_si (*offset_ret, 0);
777 : 363 : mpz_init_set_si (delta, 1);
778 : 363 : mpz_init (tmp);
779 : 1247 : for (i = 0; i < ar->dimen; i++)
780 : : {
781 : 521 : mpz_sub (tmp, section_index[i], ar->as->lower[i]->value.integer);
782 : 521 : mpz_mul (tmp, tmp, delta);
783 : 521 : mpz_add (*offset_ret, tmp, *offset_ret);
784 : :
785 : 521 : mpz_sub (tmp, ar->as->upper[i]->value.integer,
786 : 521 : ar->as->lower[i]->value.integer);
787 : 521 : mpz_add_ui (tmp, tmp, 1);
788 : 521 : mpz_mul (delta, tmp, delta);
789 : : }
790 : 363 : mpz_clear (tmp);
791 : 363 : mpz_clear (delta);
792 : 363 : }
793 : :
794 : :
795 : : /* Rearrange a structure constructor so the elements are in the specified
796 : : order. Also insert NULL entries if necessary. */
797 : :
798 : : static void
799 : 55043 : formalize_structure_cons (gfc_expr *expr)
800 : : {
801 : 55043 : gfc_constructor_base base = NULL;
802 : 55043 : gfc_constructor *cur;
803 : 55043 : gfc_component *order;
804 : :
805 : : /* Constructor is already formalized. */
806 : 55043 : cur = gfc_constructor_first (expr->value.constructor);
807 : 55043 : if (!cur || cur->n.component == NULL)
808 : 54895 : return;
809 : :
810 : 493 : for (order = expr->ts.u.derived->components; order; order = order->next)
811 : : {
812 : 345 : cur = find_con_by_component (order, expr->value.constructor);
813 : 345 : if (cur)
814 : 335 : gfc_constructor_append_expr (&base, cur->expr, &cur->expr->where);
815 : : else
816 : 10 : gfc_constructor_append_expr (&base, NULL, NULL);
817 : : }
818 : :
819 : : /* For all what it's worth, one would expect
820 : : gfc_constructor_free (expr->value.constructor);
821 : : here. However, if the constructor is actually free'd,
822 : : hell breaks loose in the testsuite?! */
823 : :
824 : 148 : expr->value.constructor = base;
825 : : }
826 : :
827 : :
828 : : /* Make sure an initialization expression is in normalized form, i.e., all
829 : : elements of the constructors are in the correct order. */
830 : :
831 : : static void
832 : 1964192 : formalize_init_expr (gfc_expr *expr)
833 : : {
834 : 1964192 : expr_t type;
835 : 1964192 : gfc_constructor *c;
836 : :
837 : 1964192 : if (expr == NULL)
838 : : return;
839 : :
840 : 643768 : type = expr->expr_type;
841 : 643768 : switch (type)
842 : : {
843 : 8510 : case EXPR_ARRAY:
844 : 8510 : for (c = gfc_constructor_first (expr->value.constructor);
845 : 242883 : c; c = gfc_constructor_next (c))
846 : 234373 : formalize_init_expr (c->expr);
847 : :
848 : : break;
849 : :
850 : 55043 : case EXPR_STRUCTURE:
851 : 55043 : formalize_structure_cons (expr);
852 : 55043 : break;
853 : :
854 : : default:
855 : : break;
856 : : }
857 : : }
858 : :
859 : :
860 : : /* Resolve symbol's initial value after all data statement. */
861 : :
862 : : void
863 : 1729819 : gfc_formalize_init_value (gfc_symbol *sym)
864 : : {
865 : 1729819 : formalize_init_expr (sym->value);
866 : 1729819 : }
867 : :
868 : :
869 : : /* Get the integer value into RET_AS and SECTION from AS and AR, and return
870 : : offset. */
871 : :
872 : : void
873 : 149 : gfc_get_section_index (gfc_array_ref *ar, mpz_t *section_index, mpz_t *offset,
874 : : int *vector_offset)
875 : : {
876 : 149 : int i;
877 : 149 : mpz_t delta;
878 : 149 : mpz_t tmp;
879 : 149 : gfc_expr *start, *elem;
880 : 149 : gfc_constructor_base base;
881 : :
882 : 149 : mpz_set_si (*offset, 0);
883 : 149 : mpz_init (tmp);
884 : 149 : mpz_init_set_si (delta, 1);
885 : 491 : for (i = 0; i < ar->dimen; i++)
886 : : {
887 : 193 : mpz_init (section_index[i]);
888 : 193 : switch (ar->dimen_type[i])
889 : : {
890 : 157 : case DIMEN_ELEMENT:
891 : 157 : case DIMEN_RANGE:
892 : 157 : elem = ar->start[i];
893 : 157 : break;
894 : :
895 : 36 : case DIMEN_VECTOR:
896 : 36 : vector_offset[i] = 0;
897 : 36 : base = ar->start[i]->value.constructor;
898 : 36 : elem = gfc_constructor_lookup_expr (base, vector_offset[i]);
899 : 36 : break;
900 : :
901 : 0 : default:
902 : 0 : gcc_unreachable ();
903 : : }
904 : :
905 : 193 : if (elem)
906 : : {
907 : 142 : start = gfc_copy_expr (elem);
908 : 142 : if (!gfc_simplify_expr (start, 1))
909 : 0 : gfc_internal_error ("Simplification error");
910 : 142 : mpz_sub (tmp, start->value.integer,
911 : 142 : ar->as->lower[i]->value.integer);
912 : 142 : mpz_mul (tmp, tmp, delta);
913 : 142 : mpz_add (*offset, tmp, *offset);
914 : 142 : mpz_set (section_index[i], start->value.integer);
915 : 142 : gfc_free_expr (start);
916 : : }
917 : : else
918 : : /* Fallback for empty section or constructor. */
919 : 51 : mpz_set (section_index[i], ar->as->lower[i]->value.integer);
920 : :
921 : 193 : mpz_sub (tmp, ar->as->upper[i]->value.integer,
922 : 193 : ar->as->lower[i]->value.integer);
923 : 193 : mpz_add_ui (tmp, tmp, 1);
924 : 193 : mpz_mul (delta, tmp, delta);
925 : : }
926 : :
927 : 149 : mpz_clear (tmp);
928 : 149 : mpz_clear (delta);
929 : 149 : }
930 : :
|