1 /* Supporting functions for resolving DATA statement.
2 Copyright (C) 2002-2021 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
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
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.c.
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.c and
37 #include "coretypes.h"
40 #include "constructor.h"
42 static void formalize_init_expr (gfc_expr
*);
44 /* Calculate the array element offset. */
47 get_array_index (gfc_array_ref
*ar
, mpz_t
*offset
)
55 mpz_set_si (*offset
, 0);
56 mpz_init_set_si (delta
, 1);
57 for (i
= 0; i
< ar
->dimen
; i
++)
59 e
= gfc_copy_expr (ar
->start
[i
]);
60 gfc_simplify_expr (e
, 1);
62 if ((gfc_is_constant_expr (ar
->as
->lower
[i
]) == 0)
63 || (gfc_is_constant_expr (ar
->as
->upper
[i
]) == 0)
64 || (gfc_is_constant_expr (e
) == 0))
65 gfc_error ("non-constant array in DATA statement %L", &ar
->where
);
67 mpz_set (tmp
, e
->value
.integer
);
69 mpz_sub (tmp
, tmp
, ar
->as
->lower
[i
]->value
.integer
);
70 mpz_mul (tmp
, tmp
, delta
);
71 mpz_add (*offset
, tmp
, *offset
);
73 mpz_sub (tmp
, ar
->as
->upper
[i
]->value
.integer
,
74 ar
->as
->lower
[i
]->value
.integer
);
75 mpz_add_ui (tmp
, tmp
, 1);
76 mpz_mul (delta
, tmp
, delta
);
82 /* Find if there is a constructor which component is equal to COM.
83 TODO: remove this, use symbol.c(gfc_find_component) instead. */
85 static gfc_constructor
*
86 find_con_by_component (gfc_component
*com
, gfc_constructor_base base
)
90 for (c
= gfc_constructor_first (base
); c
; c
= gfc_constructor_next (c
))
91 if (com
== c
->n
.component
)
98 /* Create a character type initialization expression from RVALUE.
99 TS [and REF] describe [the substring of] the variable being initialized.
100 INIT is the existing initializer, not NULL. Initialization is performed
101 according to normal assignment rules. */
104 create_character_initializer (gfc_expr
*init
, gfc_typespec
*ts
,
105 gfc_ref
*ref
, gfc_expr
*rvalue
)
107 HOST_WIDE_INT len
, start
, end
, tlen
;
109 bool alloced_init
= false;
111 if (init
&& init
->ts
.type
!= BT_CHARACTER
)
114 gfc_extract_hwi (ts
->u
.cl
->length
, &len
);
118 /* Create a new initializer. */
119 init
= gfc_get_character_expr (ts
->kind
, NULL
, NULL
, len
);
124 dest
= init
->value
.character
.string
;
128 gfc_expr
*start_expr
, *end_expr
;
130 gcc_assert (ref
->type
== REF_SUBSTRING
);
132 /* Only set a substring of the destination. Fortran substring bounds
133 are one-based [start, end], we want zero based [start, end). */
134 start_expr
= gfc_copy_expr (ref
->u
.ss
.start
);
135 end_expr
= gfc_copy_expr (ref
->u
.ss
.end
);
137 if ((!gfc_simplify_expr(start_expr
, 1))
138 || !(gfc_simplify_expr(end_expr
, 1)))
140 gfc_error ("failure to simplify substring reference in DATA "
141 "statement at %L", &ref
->u
.ss
.start
->where
);
142 gfc_free_expr (start_expr
);
143 gfc_free_expr (end_expr
);
145 gfc_free_expr (init
);
149 gfc_extract_hwi (start_expr
, &start
);
150 gfc_free_expr (start_expr
);
152 gfc_extract_hwi (end_expr
, &end
);
153 gfc_free_expr (end_expr
);
157 /* Set the whole string. */
162 /* Copy the initial value. */
163 if (rvalue
->ts
.type
== BT_HOLLERITH
)
164 len
= rvalue
->representation
.length
- rvalue
->ts
.u
.pad
;
166 len
= rvalue
->value
.character
.length
;
173 gfc_warning_now (0, "Unused initialization string at %L because "
174 "variable has zero length", &rvalue
->where
);
179 gfc_warning_now (0, "Initialization string at %L was truncated to "
180 "fit the variable (%ld/%ld)", &rvalue
->where
,
181 (long) tlen
, (long) len
);
188 gfc_error ("Substring start index at %L is less than one",
189 &ref
->u
.ss
.start
->where
);
192 if (end
> init
->value
.character
.length
)
194 gfc_error ("Substring end index at %L exceeds the string length",
195 &ref
->u
.ss
.end
->where
);
199 if (rvalue
->ts
.type
== BT_HOLLERITH
)
201 for (size_t i
= 0; i
< (size_t) len
; i
++)
202 dest
[start
+i
] = rvalue
->representation
.string
[i
];
205 memcpy (&dest
[start
], rvalue
->value
.character
.string
,
206 len
* sizeof (gfc_char_t
));
208 /* Pad with spaces. Substrings will already be blanked. */
209 if (len
< tlen
&& ref
== NULL
)
210 gfc_wide_memset (&dest
[start
+ len
], ' ', end
- (start
+ len
));
212 if (rvalue
->ts
.type
== BT_HOLLERITH
)
214 init
->representation
.length
= init
->value
.character
.length
;
215 init
->representation
.string
216 = gfc_widechar_to_char (init
->value
.character
.string
,
217 init
->value
.character
.length
);
224 /* Assign the initial value RVALUE to LVALUE's symbol->value. If the
225 LVALUE already has an initialization, we extend this, otherwise we
226 create a new one. If REPEAT is non-NULL, initialize *REPEAT
227 consecutive values in LVALUE the same value in RVALUE. In that case,
228 LVALUE must refer to a full array, not an array section. */
231 gfc_assign_data_value (gfc_expr
*lvalue
, gfc_expr
*rvalue
, mpz_t index
,
236 gfc_expr
*expr
= NULL
;
238 gfc_constructor
*con
;
239 gfc_constructor
*last_con
;
241 gfc_typespec
*last_ts
;
243 const char *msg
= "F18(R841): data-implied-do object at %L is neither an "
244 "array-element nor a scalar-structure-component";
246 symbol
= lvalue
->symtree
->n
.sym
;
247 if (symbol
->attr
.flavor
== FL_PARAMETER
)
249 gfc_error ("PARAMETER %qs shall not appear in a DATA statement at %L",
250 symbol
->name
, &lvalue
->where
);
254 init
= symbol
->value
;
255 last_ts
= &symbol
->ts
;
257 mpz_init_set_si (offset
, 0);
259 /* Find/create the parent expressions for subobject references. */
260 for (ref
= lvalue
->ref
; ref
; ref
= ref
->next
)
262 /* Break out of the loop if we find a substring. */
263 if (ref
->type
== REF_SUBSTRING
)
265 /* A substring should always be the last subobject reference. */
266 gcc_assert (ref
->next
== NULL
);
270 /* Use the existing initializer expression if it exists. Otherwise
273 expr
= gfc_get_expr ();
277 /* Find or create this element. */
281 if (ref
->u
.ar
.as
->rank
== 0)
283 gcc_assert (ref
->u
.ar
.as
->corank
> 0);
289 if (init
&& expr
->expr_type
!= EXPR_ARRAY
)
291 gfc_error ("%qs at %L already is initialized at %L",
292 lvalue
->symtree
->n
.sym
->name
, &lvalue
->where
,
299 /* The element typespec will be the same as the array
302 /* Setup the expression to hold the constructor. */
303 expr
->expr_type
= EXPR_ARRAY
;
304 expr
->rank
= ref
->u
.ar
.as
->rank
;
307 if (ref
->u
.ar
.type
== AR_ELEMENT
)
308 get_array_index (&ref
->u
.ar
, &offset
);
310 mpz_set (offset
, index
);
312 /* Check the bounds. */
313 if (mpz_cmp_si (offset
, 0) < 0)
315 gfc_error ("Data element below array lower bound at %L",
319 else if (repeat
!= NULL
320 && ref
->u
.ar
.type
!= AR_ELEMENT
)
323 gcc_assert (ref
->u
.ar
.type
== AR_FULL
324 && ref
->next
== NULL
);
325 mpz_init_set (end
, offset
);
326 mpz_add (end
, end
, *repeat
);
327 if (spec_size (ref
->u
.ar
.as
, &size
))
329 if (mpz_cmp (end
, size
) > 0)
332 gfc_error ("Data element above array upper bound at %L",
339 con
= gfc_constructor_lookup (expr
->value
.constructor
,
340 mpz_get_si (offset
));
343 con
= gfc_constructor_lookup_next (expr
->value
.constructor
,
344 mpz_get_si (offset
));
345 if (con
!= NULL
&& mpz_cmp (con
->offset
, end
) >= 0)
349 /* Overwriting an existing initializer is non-standard but
350 usually only provokes a warning from other compilers. */
351 if (con
!= NULL
&& con
->expr
!= NULL
)
353 /* Order in which the expressions arrive here depends on
354 whether they are from data statements or F95 style
355 declarations. Therefore, check which is the most
358 exprd
= (LOCATION_LINE (con
->expr
->where
.lb
->location
)
359 > LOCATION_LINE (rvalue
->where
.lb
->location
))
360 ? con
->expr
: rvalue
;
361 if (gfc_notify_std (GFC_STD_GNU
,
362 "re-initialization of %qs at %L",
363 symbol
->name
, &exprd
->where
) == false)
369 gfc_constructor
*next_con
= gfc_constructor_next (con
);
371 if (mpz_cmp (con
->offset
, end
) >= 0)
373 if (mpz_cmp (con
->offset
, offset
) < 0)
375 gcc_assert (mpz_cmp_si (con
->repeat
, 1) > 0);
376 mpz_sub (con
->repeat
, offset
, con
->offset
);
378 else if (mpz_cmp_si (con
->repeat
, 1) > 0
379 && mpz_get_si (con
->offset
)
380 + mpz_get_si (con
->repeat
) > mpz_get_si (end
))
384 = splay_tree_lookup (con
->base
,
385 mpz_get_si (con
->offset
));
387 && con
== (gfc_constructor
*) node
->value
388 && node
->key
== (splay_tree_key
)
389 mpz_get_si (con
->offset
));
390 endi
= mpz_get_si (con
->offset
)
391 + mpz_get_si (con
->repeat
);
392 if (endi
> mpz_get_si (end
) + 1)
393 mpz_set_si (con
->repeat
, endi
- mpz_get_si (end
));
395 mpz_set_si (con
->repeat
, 1);
396 mpz_set (con
->offset
, end
);
397 node
->key
= (splay_tree_key
) mpz_get_si (end
);
401 gfc_constructor_remove (con
);
405 con
= gfc_constructor_insert_expr (&expr
->value
.constructor
,
406 NULL
, &rvalue
->where
,
407 mpz_get_si (offset
));
408 mpz_set (con
->repeat
, *repeat
);
416 if (spec_size (ref
->u
.ar
.as
, &size
))
418 if (mpz_cmp (offset
, size
) >= 0)
421 gfc_error ("Data element above array upper bound at %L",
429 con
= gfc_constructor_lookup (expr
->value
.constructor
,
430 mpz_get_si (offset
));
433 con
= gfc_constructor_insert_expr (&expr
->value
.constructor
,
434 NULL
, &rvalue
->where
,
435 mpz_get_si (offset
));
437 else if (mpz_cmp_si (con
->repeat
, 1) > 0)
439 /* Need to split a range. */
440 if (mpz_cmp (con
->offset
, offset
) < 0)
442 gfc_constructor
*pred_con
= con
;
443 con
= gfc_constructor_insert_expr (&expr
->value
.constructor
,
445 mpz_get_si (offset
));
446 con
->expr
= gfc_copy_expr (pred_con
->expr
);
447 mpz_add (con
->repeat
, pred_con
->offset
, pred_con
->repeat
);
448 mpz_sub (con
->repeat
, con
->repeat
, offset
);
449 mpz_sub (pred_con
->repeat
, offset
, pred_con
->offset
);
451 if (mpz_cmp_si (con
->repeat
, 1) > 0)
453 gfc_constructor
*succ_con
;
455 = gfc_constructor_insert_expr (&expr
->value
.constructor
,
457 mpz_get_si (offset
) + 1);
458 succ_con
->expr
= gfc_copy_expr (con
->expr
);
459 mpz_sub_ui (succ_con
->repeat
, con
->repeat
, 1);
460 mpz_set_si (con
->repeat
, 1);
468 /* Setup the expression to hold the constructor. */
469 expr
->expr_type
= EXPR_STRUCTURE
;
470 expr
->ts
.type
= BT_DERIVED
;
471 expr
->ts
.u
.derived
= ref
->u
.c
.sym
;
474 gcc_assert (expr
->expr_type
== EXPR_STRUCTURE
);
475 last_ts
= &ref
->u
.c
.component
->ts
;
477 /* Find the same element in the existing constructor. */
478 con
= find_con_by_component (ref
->u
.c
.component
,
479 expr
->value
.constructor
);
483 /* Create a new constructor. */
484 con
= gfc_constructor_append_expr (&expr
->value
.constructor
,
486 con
->n
.component
= ref
->u
.c
.component
;
492 /* After some discussion on clf it was determined that the following
493 violates F18(R841). If the error is removed, the expected result
494 is obtained. Leaving the code in place ensures a clean error
496 gfc_error (msg
, &lvalue
->where
);
498 /* This breaks with the other reference types in that the output
499 constructor has to be of type COMPLEX, whereas the lvalue is
500 of type REAL. The rvalue is copied to the real or imaginary
501 part as appropriate. In addition, for all except scalar
502 complex variables, a complex expression has to provided, where
503 the constructor does not have it, and the expression modified
504 with a new value for the real or imaginary part. */
505 gcc_assert (ref
->next
== NULL
&& last_ts
->type
== BT_COMPLEX
);
506 rexpr
= gfc_copy_expr (rvalue
);
507 if (!gfc_compare_types (&lvalue
->ts
, &rexpr
->ts
))
508 gfc_convert_type (rexpr
, &lvalue
->ts
, 0);
510 /* This is the scalar, complex case, where an initializer exists. */
511 if (init
&& ref
== lvalue
->ref
)
512 expr
= symbol
->value
;
513 /* Then all cases, where a complex expression does not exist. */
514 else if (!last_con
|| !last_con
->expr
)
516 expr
= gfc_get_constant_expr (BT_COMPLEX
, lvalue
->ts
.kind
,
519 last_con
->expr
= expr
;
522 /* Finally, and existing constructor expression to be modified. */
523 expr
= last_con
->expr
;
525 /* Rejection of LEN and KIND inquiry references is handled
526 elsewhere. The error here is added as backup. The assertion
527 of F2008 for RE and IM is also done elsewhere. */
532 gfc_error ("LEN or KIND inquiry ref in DATA statement at %L",
536 mpfr_set (mpc_realref (expr
->value
.complex),
541 mpfr_set (mpc_imagref (expr
->value
.complex),
547 /* Only the scalar, complex expression needs to be saved as the
548 symbol value since the last constructor expression is already
549 provided as the initializer in the code after the reference
551 if (ref
== lvalue
->ref
)
552 symbol
->value
= expr
;
554 gfc_free_expr (rexpr
);
564 /* Point the container at the new expression. */
565 if (last_con
== NULL
)
566 symbol
->value
= expr
;
568 last_con
->expr
= expr
;
575 gcc_assert (repeat
== NULL
);
577 /* Overwriting an existing initializer is non-standard but usually only
578 provokes a warning from other compilers. */
579 if (init
!= NULL
&& init
->where
.lb
&& rvalue
->where
.lb
)
581 /* Order in which the expressions arrive here depends on whether
582 they are from data statements or F95 style declarations.
583 Therefore, check which is the most recent. */
584 expr
= (LOCATION_LINE (init
->where
.lb
->location
)
585 > LOCATION_LINE (rvalue
->where
.lb
->location
))
587 if (gfc_notify_std (GFC_STD_GNU
, "re-initialization of %qs at %L",
588 symbol
->name
, &expr
->where
) == false)
592 if (ref
|| (last_ts
->type
== BT_CHARACTER
593 && rvalue
->expr_type
== EXPR_CONSTANT
))
595 /* An initializer has to be constant. */
596 if (lvalue
->ts
.u
.cl
->length
== NULL
&& !(ref
&& ref
->u
.ss
.length
!= NULL
))
598 if (lvalue
->ts
.u
.cl
->length
599 && lvalue
->ts
.u
.cl
->length
->expr_type
!= EXPR_CONSTANT
)
601 expr
= create_character_initializer (init
, last_ts
, ref
, rvalue
);
607 if (lvalue
->ts
.type
== BT_DERIVED
608 && gfc_has_default_initializer (lvalue
->ts
.u
.derived
))
610 gfc_error ("Nonpointer object %qs with default initialization "
611 "shall not appear in a DATA statement at %L",
612 symbol
->name
, &lvalue
->where
);
616 expr
= gfc_copy_expr (rvalue
);
617 if (!gfc_compare_types (&lvalue
->ts
, &expr
->ts
))
618 gfc_convert_type (expr
, &lvalue
->ts
, 0);
621 if (last_con
== NULL
)
622 symbol
->value
= expr
;
624 last_con
->expr
= expr
;
630 gfc_free_expr (expr
);
636 /* Modify the index of array section and re-calculate the array offset. */
639 gfc_advance_section (mpz_t
*section_index
, gfc_array_ref
*ar
,
647 gfc_expr
*start
, *end
, *stride
;
649 for (i
= 0; i
< ar
->dimen
; i
++)
651 if (ar
->dimen_type
[i
] != DIMEN_RANGE
)
656 stride
= gfc_copy_expr(ar
->stride
[i
]);
657 if(!gfc_simplify_expr(stride
, 1))
658 gfc_internal_error("Simplification error");
659 mpz_add (section_index
[i
], section_index
[i
],
660 stride
->value
.integer
);
661 if (mpz_cmp_si (stride
->value
.integer
, 0) >= 0)
665 gfc_free_expr(stride
);
669 mpz_add_ui (section_index
[i
], section_index
[i
], 1);
675 end
= gfc_copy_expr(ar
->end
[i
]);
676 if(!gfc_simplify_expr(end
, 1))
677 gfc_internal_error("Simplification error");
678 cmp
= mpz_cmp (section_index
[i
], end
->value
.integer
);
682 cmp
= mpz_cmp (section_index
[i
], ar
->as
->upper
[i
]->value
.integer
);
684 if ((cmp
> 0 && forwards
) || (cmp
< 0 && !forwards
))
686 /* Reset index to start, then loop to advance the next index. */
689 start
= gfc_copy_expr(ar
->start
[i
]);
690 if(!gfc_simplify_expr(start
, 1))
691 gfc_internal_error("Simplification error");
692 mpz_set (section_index
[i
], start
->value
.integer
);
693 gfc_free_expr(start
);
696 mpz_set (section_index
[i
], ar
->as
->lower
[i
]->value
.integer
);
702 mpz_set_si (*offset_ret
, 0);
703 mpz_init_set_si (delta
, 1);
705 for (i
= 0; i
< ar
->dimen
; i
++)
707 mpz_sub (tmp
, section_index
[i
], ar
->as
->lower
[i
]->value
.integer
);
708 mpz_mul (tmp
, tmp
, delta
);
709 mpz_add (*offset_ret
, tmp
, *offset_ret
);
711 mpz_sub (tmp
, ar
->as
->upper
[i
]->value
.integer
,
712 ar
->as
->lower
[i
]->value
.integer
);
713 mpz_add_ui (tmp
, tmp
, 1);
714 mpz_mul (delta
, tmp
, delta
);
721 /* Rearrange a structure constructor so the elements are in the specified
722 order. Also insert NULL entries if necessary. */
725 formalize_structure_cons (gfc_expr
*expr
)
727 gfc_constructor_base base
= NULL
;
728 gfc_constructor
*cur
;
729 gfc_component
*order
;
731 /* Constructor is already formalized. */
732 cur
= gfc_constructor_first (expr
->value
.constructor
);
733 if (!cur
|| cur
->n
.component
== NULL
)
736 for (order
= expr
->ts
.u
.derived
->components
; order
; order
= order
->next
)
738 cur
= find_con_by_component (order
, expr
->value
.constructor
);
740 gfc_constructor_append_expr (&base
, cur
->expr
, &cur
->expr
->where
);
742 gfc_constructor_append_expr (&base
, NULL
, NULL
);
745 /* For all what it's worth, one would expect
746 gfc_constructor_free (expr->value.constructor);
747 here. However, if the constructor is actually free'd,
748 hell breaks loose in the testsuite?! */
750 expr
->value
.constructor
= base
;
754 /* Make sure an initialization expression is in normalized form, i.e., all
755 elements of the constructors are in the correct order. */
758 formalize_init_expr (gfc_expr
*expr
)
766 type
= expr
->expr_type
;
770 for (c
= gfc_constructor_first (expr
->value
.constructor
);
771 c
; c
= gfc_constructor_next (c
))
772 formalize_init_expr (c
->expr
);
777 formalize_structure_cons (expr
);
786 /* Resolve symbol's initial value after all data statement. */
789 gfc_formalize_init_value (gfc_symbol
*sym
)
791 formalize_init_expr (sym
->value
);
795 /* Get the integer value into RET_AS and SECTION from AS and AR, and return
799 gfc_get_section_index (gfc_array_ref
*ar
, mpz_t
*section_index
, mpz_t
*offset
)
806 mpz_set_si (*offset
, 0);
808 mpz_init_set_si (delta
, 1);
809 for (i
= 0; i
< ar
->dimen
; i
++)
811 mpz_init (section_index
[i
]);
812 switch (ar
->dimen_type
[i
])
818 start
= gfc_copy_expr(ar
->start
[i
]);
819 if(!gfc_simplify_expr(start
, 1))
820 gfc_internal_error("Simplification error");
821 mpz_sub (tmp
, start
->value
.integer
,
822 ar
->as
->lower
[i
]->value
.integer
);
823 mpz_mul (tmp
, tmp
, delta
);
824 mpz_add (*offset
, tmp
, *offset
);
825 mpz_set (section_index
[i
], start
->value
.integer
);
826 gfc_free_expr(start
);
829 mpz_set (section_index
[i
], ar
->as
->lower
[i
]->value
.integer
);
833 gfc_internal_error ("TODO: Vector sections in data statements");
839 mpz_sub (tmp
, ar
->as
->upper
[i
]->value
.integer
,
840 ar
->as
->lower
[i
]->value
.integer
);
841 mpz_add_ui (tmp
, tmp
, 1);
842 mpz_mul (delta
, tmp
, delta
);