libcpp, c, middle-end: Optimize initializers using #embed in C
[official-gcc.git] / gcc / fortran / data.cc
blobd80ba66d358dbdb9859695fa96dabb5a78914824
1 /* Supporting functions for resolving DATA statement.
2 Copyright (C) 2002-2024 Free Software Foundation, Inc.
3 Contributed by Lifang Zeng <zlf605@hotmail.com>
5 This file is part of GCC.
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.
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.
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/>. */
22 /* Notes for DATA statement implementation:
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.
28 The complexity exists in the handling of array section, implied do
29 and array of struct appeared in DATA statement.
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. */
35 #include "config.h"
36 #include "system.h"
37 #include "coretypes.h"
38 #include "gfortran.h"
39 #include "data.h"
40 #include "constructor.h"
42 static void formalize_init_expr (gfc_expr *);
44 /* Calculate the array element offset. */
46 static bool
47 get_array_index (gfc_array_ref *ar, mpz_t *offset)
49 gfc_expr *e;
50 int i;
51 mpz_t delta;
52 mpz_t tmp;
53 bool ok = true;
55 mpz_init (tmp);
56 mpz_set_si (*offset, 0);
57 mpz_init_set_si (delta, 1);
58 for (i = 0; i < ar->dimen; i++)
60 e = gfc_copy_expr (ar->start[i]);
61 gfc_simplify_expr (e, 1);
63 if (!gfc_is_constant_expr (ar->as->lower[i])
64 || !gfc_is_constant_expr (ar->as->upper[i])
65 || !gfc_is_constant_expr (e))
67 gfc_error ("non-constant array in DATA statement %L", &ar->where);
68 ok = false;
69 break;
72 mpz_set (tmp, e->value.integer);
73 gfc_free_expr (e);
75 /* Overindexing is only allowed as a legacy extension. */
76 if (mpz_cmp (tmp, ar->as->lower[i]->value.integer) < 0
77 && !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))
84 ok = false;
85 break;
87 if (mpz_cmp (tmp, ar->as->upper[i]->value.integer) > 0
88 && !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))
95 ok = false;
96 break;
99 mpz_sub (tmp, tmp, ar->as->lower[i]->value.integer);
100 mpz_mul (tmp, tmp, delta);
101 mpz_add (*offset, tmp, *offset);
103 mpz_sub (tmp, ar->as->upper[i]->value.integer,
104 ar->as->lower[i]->value.integer);
105 mpz_add_ui (tmp, tmp, 1);
106 mpz_mul (delta, tmp, delta);
108 mpz_clear (delta);
109 mpz_clear (tmp);
111 return ok;
114 /* Find if there is a constructor which component is equal to COM.
115 TODO: remove this, use symbol.cc(gfc_find_component) instead. */
117 static gfc_constructor *
118 find_con_by_component (gfc_component *com, gfc_constructor_base base)
120 gfc_constructor *c;
122 for (c = gfc_constructor_first (base); c; c = gfc_constructor_next (c))
123 if (com == c->n.component)
124 return c;
126 return NULL;
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. */
135 static gfc_expr *
136 create_character_initializer (gfc_expr *init, gfc_typespec *ts,
137 gfc_ref *ref, gfc_expr *rvalue)
139 HOST_WIDE_INT len, start, end, tlen;
140 gfc_char_t *dest;
141 bool alloced_init = false;
143 if (init && init->ts.type != BT_CHARACTER)
144 return NULL;
146 gfc_extract_hwi (ts->u.cl->length, &len);
148 if (init == NULL)
150 /* Create a new initializer. */
151 init = gfc_get_character_expr (ts->kind, NULL, NULL, len);
152 init->ts = *ts;
153 alloced_init = true;
156 dest = init->value.character.string;
158 if (ref)
160 gfc_expr *start_expr, *end_expr;
162 gcc_assert (ref->type == REF_SUBSTRING);
164 /* Only set a substring of the destination. Fortran substring bounds
165 are one-based [start, end], we want zero based [start, end). */
166 start_expr = gfc_copy_expr (ref->u.ss.start);
167 end_expr = gfc_copy_expr (ref->u.ss.end);
169 if ((!gfc_simplify_expr(start_expr, 1))
170 || !(gfc_simplify_expr(end_expr, 1)))
172 gfc_error ("failure to simplify substring reference in DATA "
173 "statement at %L", &ref->u.ss.start->where);
174 gfc_free_expr (start_expr);
175 gfc_free_expr (end_expr);
176 if (alloced_init)
177 gfc_free_expr (init);
178 return NULL;
181 gfc_extract_hwi (start_expr, &start);
182 gfc_free_expr (start_expr);
183 start--;
184 gfc_extract_hwi (end_expr, &end);
185 gfc_free_expr (end_expr);
187 else
189 /* Set the whole string. */
190 start = 0;
191 end = len;
194 /* Copy the initial value. */
195 if (rvalue->ts.type == BT_HOLLERITH)
196 len = rvalue->representation.length - rvalue->ts.u.pad;
197 else
198 len = rvalue->value.character.length;
200 tlen = end - start;
201 if (len > tlen)
203 if (tlen < 0)
205 gfc_warning_now (0, "Unused initialization string at %L because "
206 "variable has zero length", &rvalue->where);
207 len = 0;
209 else
211 gfc_warning_now (0, "Initialization string at %L was truncated to "
212 "fit the variable (%wd/%wd)", &rvalue->where,
213 tlen, len);
214 len = tlen;
218 if (start < 0)
220 gfc_error ("Substring start index at %L is less than one",
221 &ref->u.ss.start->where);
222 return NULL;
224 if (end > init->value.character.length)
226 gfc_error ("Substring end index at %L exceeds the string length",
227 &ref->u.ss.end->where);
228 return NULL;
231 if (rvalue->ts.type == BT_HOLLERITH)
233 for (size_t i = 0; i < (size_t) len; i++)
234 dest[start+i] = rvalue->representation.string[i];
236 else
237 memcpy (&dest[start], rvalue->value.character.string,
238 len * sizeof (gfc_char_t));
240 /* Pad with spaces. Substrings will already be blanked. */
241 if (len < tlen && ref == NULL)
242 gfc_wide_memset (&dest[start + len], ' ', end - (start + len));
244 if (rvalue->ts.type == BT_HOLLERITH)
246 init->representation.length = init->value.character.length;
247 init->representation.string
248 = gfc_widechar_to_char (init->value.character.string,
249 init->value.character.length);
252 return init;
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. */
262 bool
263 gfc_assign_data_value (gfc_expr *lvalue, gfc_expr *rvalue, mpz_t index,
264 mpz_t *repeat)
266 gfc_ref *ref;
267 gfc_expr *init;
268 gfc_expr *expr = NULL;
269 gfc_expr *rexpr;
270 gfc_constructor *con;
271 gfc_constructor *last_con;
272 gfc_symbol *symbol;
273 gfc_typespec *last_ts;
274 mpz_t offset;
275 const char *msg = "F18(R841): data-implied-do object at %L is neither an "
276 "array-element nor a scalar-structure-component";
278 symbol = lvalue->symtree->n.sym;
279 init = symbol->value;
280 last_ts = &symbol->ts;
281 last_con = NULL;
282 mpz_init_set_si (offset, 0);
284 /* Find/create the parent expressions for subobject references. */
285 for (ref = lvalue->ref; ref; ref = ref->next)
287 /* Break out of the loop if we find a substring. */
288 if (ref->type == REF_SUBSTRING)
290 /* A substring should always be the last subobject reference. */
291 gcc_assert (ref->next == NULL);
292 break;
295 /* Use the existing initializer expression if it exists. Otherwise
296 create a new one. */
297 if (init == NULL)
298 expr = gfc_get_expr ();
299 else
300 expr = init;
302 /* Find or create this element. */
303 switch (ref->type)
305 case REF_ARRAY:
306 if (ref->u.ar.as->rank == 0)
308 gcc_assert (ref->u.ar.as->corank > 0);
309 if (init == NULL)
310 free (expr);
311 continue;
314 if (init && expr->expr_type != EXPR_ARRAY)
316 gfc_error ("%qs at %L already is initialized at %L",
317 lvalue->symtree->n.sym->name, &lvalue->where,
318 &init->where);
319 goto abort;
322 if (init == NULL)
324 /* The element typespec will be the same as the array
325 typespec. */
326 expr->ts = *last_ts;
327 /* Setup the expression to hold the constructor. */
328 expr->expr_type = EXPR_ARRAY;
329 expr->rank = ref->u.ar.as->rank;
330 expr->corank = ref->u.ar.as->corank;
333 if (ref->u.ar.type == AR_ELEMENT)
335 if (!get_array_index (&ref->u.ar, &offset))
336 goto abort;
338 else
339 mpz_set (offset, index);
341 /* Check the bounds. */
342 if (mpz_cmp_si (offset, 0) < 0)
344 gfc_error ("Data element below array lower bound at %L",
345 &lvalue->where);
346 goto abort;
348 else if (repeat != NULL
349 && ref->u.ar.type != AR_ELEMENT)
351 mpz_t size, end;
352 gcc_assert (ref->u.ar.type == AR_FULL
353 && ref->next == NULL);
354 mpz_init_set (end, offset);
355 mpz_add (end, end, *repeat);
356 if (spec_size (ref->u.ar.as, &size))
358 if (mpz_cmp (end, size) > 0)
360 mpz_clear (size);
361 gfc_error ("Data element above array upper bound at %L",
362 &lvalue->where);
363 goto abort;
365 mpz_clear (size);
368 con = gfc_constructor_lookup (expr->value.constructor,
369 mpz_get_si (offset));
370 if (!con)
372 con = gfc_constructor_lookup_next (expr->value.constructor,
373 mpz_get_si (offset));
374 if (con != NULL && mpz_cmp (con->offset, end) >= 0)
375 con = NULL;
378 /* Overwriting an existing initializer is non-standard but
379 usually only provokes a warning from other compilers. */
380 if (con != NULL && con->expr != NULL)
382 /* Order in which the expressions arrive here depends on
383 whether they are from data statements or F95 style
384 declarations. Therefore, check which is the most
385 recent. */
386 gfc_expr *exprd;
387 exprd = (LOCATION_LINE (con->expr->where.lb->location)
388 > LOCATION_LINE (rvalue->where.lb->location))
389 ? con->expr : rvalue;
390 if (gfc_notify_std (GFC_STD_GNU,
391 "re-initialization of %qs at %L",
392 symbol->name, &exprd->where) == false)
393 return false;
396 while (con != NULL)
398 gfc_constructor *next_con = gfc_constructor_next (con);
400 if (mpz_cmp (con->offset, end) >= 0)
401 break;
402 if (mpz_cmp (con->offset, offset) < 0)
404 gcc_assert (mpz_cmp_si (con->repeat, 1) > 0);
405 mpz_sub (con->repeat, offset, con->offset);
407 else if (mpz_cmp_si (con->repeat, 1) > 0
408 && mpz_get_si (con->offset)
409 + mpz_get_si (con->repeat) > mpz_get_si (end))
411 int endi;
412 splay_tree_node node
413 = splay_tree_lookup (con->base,
414 mpz_get_si (con->offset));
415 gcc_assert (node
416 && con == (gfc_constructor *) node->value
417 && node->key == (splay_tree_key)
418 mpz_get_si (con->offset));
419 endi = mpz_get_si (con->offset)
420 + mpz_get_si (con->repeat);
421 if (endi > mpz_get_si (end) + 1)
422 mpz_set_si (con->repeat, endi - mpz_get_si (end));
423 else
424 mpz_set_si (con->repeat, 1);
425 mpz_set (con->offset, end);
426 node->key = (splay_tree_key) mpz_get_si (end);
427 break;
429 else
430 gfc_constructor_remove (con);
431 con = next_con;
434 con = gfc_constructor_insert_expr (&expr->value.constructor,
435 NULL, &rvalue->where,
436 mpz_get_si (offset));
437 mpz_set (con->repeat, *repeat);
438 repeat = NULL;
439 mpz_clear (end);
440 break;
442 else
444 mpz_t size;
445 if (spec_size (ref->u.ar.as, &size))
447 if (mpz_cmp (offset, size) >= 0)
449 mpz_clear (size);
450 gfc_error ("Data element above array upper bound at %L",
451 &lvalue->where);
452 goto abort;
454 mpz_clear (size);
458 con = gfc_constructor_lookup (expr->value.constructor,
459 mpz_get_si (offset));
460 if (!con)
462 con = gfc_constructor_insert_expr (&expr->value.constructor,
463 NULL, &rvalue->where,
464 mpz_get_si (offset));
466 else if (mpz_cmp_si (con->repeat, 1) > 0)
468 /* Need to split a range. */
469 if (mpz_cmp (con->offset, offset) < 0)
471 gfc_constructor *pred_con = con;
472 con = gfc_constructor_insert_expr (&expr->value.constructor,
473 NULL, &con->where,
474 mpz_get_si (offset));
475 con->expr = gfc_copy_expr (pred_con->expr);
476 mpz_add (con->repeat, pred_con->offset, pred_con->repeat);
477 mpz_sub (con->repeat, con->repeat, offset);
478 mpz_sub (pred_con->repeat, offset, pred_con->offset);
480 if (mpz_cmp_si (con->repeat, 1) > 0)
482 gfc_constructor *succ_con;
483 succ_con
484 = gfc_constructor_insert_expr (&expr->value.constructor,
485 NULL, &con->where,
486 mpz_get_si (offset) + 1);
487 succ_con->expr = gfc_copy_expr (con->expr);
488 mpz_sub_ui (succ_con->repeat, con->repeat, 1);
489 mpz_set_si (con->repeat, 1);
492 break;
494 case REF_COMPONENT:
495 if (init == NULL)
497 /* Setup the expression to hold the constructor. */
498 expr->expr_type = EXPR_STRUCTURE;
499 expr->ts.type = BT_DERIVED;
500 expr->ts.u.derived = ref->u.c.sym;
502 else
503 gcc_assert (expr->expr_type == EXPR_STRUCTURE);
504 last_ts = &ref->u.c.component->ts;
506 /* Find the same element in the existing constructor. */
507 con = find_con_by_component (ref->u.c.component,
508 expr->value.constructor);
510 if (con == NULL)
512 /* Create a new constructor. */
513 con = gfc_constructor_append_expr (&expr->value.constructor,
514 NULL, NULL);
515 con->n.component = ref->u.c.component;
517 break;
519 case REF_INQUIRY:
521 /* After some discussion on clf it was determined that the following
522 violates F18(R841). If the error is removed, the expected result
523 is obtained. Leaving the code in place ensures a clean error
524 recovery. */
525 gfc_error (msg, &lvalue->where);
527 /* This breaks with the other reference types in that the output
528 constructor has to be of type COMPLEX, whereas the lvalue is
529 of type REAL. The rvalue is copied to the real or imaginary
530 part as appropriate. In addition, for all except scalar
531 complex variables, a complex expression has to provided, where
532 the constructor does not have it, and the expression modified
533 with a new value for the real or imaginary part. */
534 gcc_assert (ref->next == NULL && last_ts->type == BT_COMPLEX);
535 rexpr = gfc_copy_expr (rvalue);
536 if (!gfc_compare_types (&lvalue->ts, &rexpr->ts))
537 gfc_convert_type (rexpr, &lvalue->ts, 0);
539 /* This is the scalar, complex case, where an initializer exists. */
540 if (init && ref == lvalue->ref)
541 expr = symbol->value;
542 /* Then all cases, where a complex expression does not exist. */
543 else if (!last_con || !last_con->expr)
545 expr = gfc_get_constant_expr (BT_COMPLEX, lvalue->ts.kind,
546 &lvalue->where);
547 if (last_con)
548 last_con->expr = expr;
550 else
551 /* Finally, and existing constructor expression to be modified. */
552 expr = last_con->expr;
554 /* Rejection of LEN and KIND inquiry references is handled
555 elsewhere. The error here is added as backup. The assertion
556 of F2008 for RE and IM is also done elsewhere. */
557 switch (ref->u.i)
559 case INQUIRY_LEN:
560 case INQUIRY_KIND:
561 gfc_error ("LEN or KIND inquiry ref in DATA statement at %L",
562 &lvalue->where);
563 goto abort;
564 case INQUIRY_RE:
565 mpfr_set (mpc_realref (expr->value.complex),
566 rexpr->value.real,
567 GFC_RND_MODE);
568 break;
569 case INQUIRY_IM:
570 mpfr_set (mpc_imagref (expr->value.complex),
571 rexpr->value.real,
572 GFC_RND_MODE);
573 break;
576 /* Only the scalar, complex expression needs to be saved as the
577 symbol value since the last constructor expression is already
578 provided as the initializer in the code after the reference
579 cases. */
580 if (ref == lvalue->ref)
581 symbol->value = expr;
583 gfc_free_expr (rexpr);
584 mpz_clear (offset);
585 return true;
587 default:
588 gcc_unreachable ();
591 if (init == NULL)
593 /* Point the container at the new expression. */
594 if (last_con == NULL)
595 symbol->value = expr;
596 else
597 last_con->expr = expr;
599 init = con->expr;
600 last_con = con;
603 mpz_clear (offset);
604 gcc_assert (repeat == NULL);
606 /* Overwriting an existing initializer is non-standard but usually only
607 provokes a warning from other compilers. */
608 if (init != NULL && init->where.lb && rvalue->where.lb)
610 /* Order in which the expressions arrive here depends on whether
611 they are from data statements or F95 style declarations.
612 Therefore, check which is the most recent. */
613 expr = (LOCATION_LINE (init->where.lb->location)
614 > LOCATION_LINE (rvalue->where.lb->location))
615 ? init : rvalue;
616 if (gfc_notify_std (GFC_STD_GNU, "re-initialization of %qs at %L",
617 symbol->name, &expr->where) == false)
618 return false;
621 if (ref || (last_ts->type == BT_CHARACTER
622 && rvalue->expr_type == EXPR_CONSTANT))
624 /* An initializer has to be constant. */
625 if (lvalue->ts.u.cl->length == NULL && !(ref && ref->u.ss.length != NULL))
626 return false;
627 if (lvalue->ts.u.cl->length
628 && lvalue->ts.u.cl->length->expr_type != EXPR_CONSTANT)
629 return false;
630 expr = create_character_initializer (init, last_ts, ref, rvalue);
631 if (!expr)
632 return false;
634 else
636 if (lvalue->ts.type == BT_DERIVED
637 && gfc_has_default_initializer (lvalue->ts.u.derived))
639 gfc_error ("Nonpointer object %qs with default initialization "
640 "shall not appear in a DATA statement at %L",
641 symbol->name, &lvalue->where);
642 return false;
645 expr = gfc_copy_expr (rvalue);
646 if (!gfc_compare_types (&lvalue->ts, &expr->ts))
647 gfc_convert_type (expr, &lvalue->ts, 0);
650 if (IS_POINTER (symbol)
651 && !gfc_check_pointer_assign (lvalue, rvalue, false, true))
652 return false;
654 if (last_con == NULL)
655 symbol->value = expr;
656 else
657 last_con->expr = expr;
659 return true;
661 abort:
662 if (!init)
663 gfc_free_expr (expr);
664 mpz_clear (offset);
665 return false;
669 /* Modify the index of array section and re-calculate the array offset. */
671 void
672 gfc_advance_section (mpz_t *section_index, gfc_array_ref *ar,
673 mpz_t *offset_ret, int *vector_offset)
675 int i;
676 mpz_t delta;
677 mpz_t tmp;
678 bool forwards;
679 int cmp;
680 gfc_expr *start, *end, *stride, *elem;
681 gfc_constructor_base base;
683 for (i = 0; i < ar->dimen; i++)
685 bool advance = false;
687 switch (ar->dimen_type[i])
689 case DIMEN_ELEMENT:
690 /* Loop to advance the next index. */
691 advance = true;
692 break;
694 case DIMEN_RANGE:
695 if (ar->stride[i])
697 stride = gfc_copy_expr(ar->stride[i]);
698 if(!gfc_simplify_expr(stride, 1))
699 gfc_internal_error("Simplification error");
700 mpz_add (section_index[i], section_index[i],
701 stride->value.integer);
702 if (mpz_cmp_si (stride->value.integer, 0) >= 0)
703 forwards = true;
704 else
705 forwards = false;
706 gfc_free_expr(stride);
708 else
710 mpz_add_ui (section_index[i], section_index[i], 1);
711 forwards = true;
714 if (ar->end[i])
716 end = gfc_copy_expr(ar->end[i]);
717 if(!gfc_simplify_expr(end, 1))
718 gfc_internal_error("Simplification error");
719 cmp = mpz_cmp (section_index[i], end->value.integer);
720 gfc_free_expr(end);
722 else
723 cmp = mpz_cmp (section_index[i], ar->as->upper[i]->value.integer);
725 if ((cmp > 0 && forwards) || (cmp < 0 && !forwards))
727 /* Reset index to start, then loop to advance the next index. */
728 if (ar->start[i])
730 start = gfc_copy_expr(ar->start[i]);
731 if(!gfc_simplify_expr(start, 1))
732 gfc_internal_error("Simplification error");
733 mpz_set (section_index[i], start->value.integer);
734 gfc_free_expr(start);
736 else
737 mpz_set (section_index[i], ar->as->lower[i]->value.integer);
738 advance = true;
740 break;
742 case DIMEN_VECTOR:
743 vector_offset[i]++;
744 base = ar->start[i]->value.constructor;
745 elem = gfc_constructor_lookup_expr (base, vector_offset[i]);
747 if (elem == NULL)
749 /* Reset to first vector element and advance the next index. */
750 vector_offset[i] = 0;
751 elem = gfc_constructor_lookup_expr (base, 0);
752 advance = true;
754 if (elem)
756 start = gfc_copy_expr (elem);
757 if (!gfc_simplify_expr (start, 1))
758 gfc_internal_error ("Simplification error");
759 mpz_set (section_index[i], start->value.integer);
760 gfc_free_expr (start);
762 break;
764 default:
765 gcc_unreachable ();
768 if (!advance)
769 break;
772 mpz_set_si (*offset_ret, 0);
773 mpz_init_set_si (delta, 1);
774 mpz_init (tmp);
775 for (i = 0; i < ar->dimen; i++)
777 mpz_sub (tmp, section_index[i], ar->as->lower[i]->value.integer);
778 mpz_mul (tmp, tmp, delta);
779 mpz_add (*offset_ret, tmp, *offset_ret);
781 mpz_sub (tmp, ar->as->upper[i]->value.integer,
782 ar->as->lower[i]->value.integer);
783 mpz_add_ui (tmp, tmp, 1);
784 mpz_mul (delta, tmp, delta);
786 mpz_clear (tmp);
787 mpz_clear (delta);
791 /* Rearrange a structure constructor so the elements are in the specified
792 order. Also insert NULL entries if necessary. */
794 static void
795 formalize_structure_cons (gfc_expr *expr)
797 gfc_constructor_base base = NULL;
798 gfc_constructor *cur;
799 gfc_component *order;
801 /* Constructor is already formalized. */
802 cur = gfc_constructor_first (expr->value.constructor);
803 if (!cur || cur->n.component == NULL)
804 return;
806 for (order = expr->ts.u.derived->components; order; order = order->next)
808 cur = find_con_by_component (order, expr->value.constructor);
809 if (cur)
810 gfc_constructor_append_expr (&base, cur->expr, &cur->expr->where);
811 else
812 gfc_constructor_append_expr (&base, NULL, NULL);
815 /* For all what it's worth, one would expect
816 gfc_constructor_free (expr->value.constructor);
817 here. However, if the constructor is actually free'd,
818 hell breaks loose in the testsuite?! */
820 expr->value.constructor = base;
824 /* Make sure an initialization expression is in normalized form, i.e., all
825 elements of the constructors are in the correct order. */
827 static void
828 formalize_init_expr (gfc_expr *expr)
830 expr_t type;
831 gfc_constructor *c;
833 if (expr == NULL)
834 return;
836 type = expr->expr_type;
837 switch (type)
839 case EXPR_ARRAY:
840 for (c = gfc_constructor_first (expr->value.constructor);
841 c; c = gfc_constructor_next (c))
842 formalize_init_expr (c->expr);
844 break;
846 case EXPR_STRUCTURE:
847 formalize_structure_cons (expr);
848 break;
850 default:
851 break;
856 /* Resolve symbol's initial value after all data statement. */
858 void
859 gfc_formalize_init_value (gfc_symbol *sym)
861 formalize_init_expr (sym->value);
865 /* Get the integer value into RET_AS and SECTION from AS and AR, and return
866 offset. */
868 void
869 gfc_get_section_index (gfc_array_ref *ar, mpz_t *section_index, mpz_t *offset,
870 int *vector_offset)
872 int i;
873 mpz_t delta;
874 mpz_t tmp;
875 gfc_expr *start, *elem;
876 gfc_constructor_base base;
878 mpz_set_si (*offset, 0);
879 mpz_init (tmp);
880 mpz_init_set_si (delta, 1);
881 for (i = 0; i < ar->dimen; i++)
883 mpz_init (section_index[i]);
884 switch (ar->dimen_type[i])
886 case DIMEN_ELEMENT:
887 case DIMEN_RANGE:
888 elem = ar->start[i];
889 break;
891 case DIMEN_VECTOR:
892 vector_offset[i] = 0;
893 base = ar->start[i]->value.constructor;
894 elem = gfc_constructor_lookup_expr (base, vector_offset[i]);
895 break;
897 default:
898 gcc_unreachable ();
901 if (elem)
903 start = gfc_copy_expr (elem);
904 if (!gfc_simplify_expr (start, 1))
905 gfc_internal_error ("Simplification error");
906 mpz_sub (tmp, start->value.integer,
907 ar->as->lower[i]->value.integer);
908 mpz_mul (tmp, tmp, delta);
909 mpz_add (*offset, tmp, *offset);
910 mpz_set (section_index[i], start->value.integer);
911 gfc_free_expr (start);
913 else
914 /* Fallback for empty section or constructor. */
915 mpz_set (section_index[i], ar->as->lower[i]->value.integer);
917 mpz_sub (tmp, ar->as->upper[i]->value.integer,
918 ar->as->lower[i]->value.integer);
919 mpz_add_ui (tmp, tmp, 1);
920 mpz_mul (delta, tmp, delta);
923 mpz_clear (tmp);
924 mpz_clear (delta);