1 /* Supporting functions for resolving DATA statement.
2 Copyright (C) 2002-2015 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 int len
, start
, end
, tlen
;
109 bool alloced_init
= false;
111 gfc_extract_int (ts
->u
.cl
->length
, &len
);
115 /* Create a new initializer. */
116 init
= gfc_get_character_expr (ts
->kind
, NULL
, NULL
, len
);
121 dest
= init
->value
.character
.string
;
125 gfc_expr
*start_expr
, *end_expr
;
127 gcc_assert (ref
->type
== REF_SUBSTRING
);
129 /* Only set a substring of the destination. Fortran substring bounds
130 are one-based [start, end], we want zero based [start, end). */
131 start_expr
= gfc_copy_expr (ref
->u
.ss
.start
);
132 end_expr
= gfc_copy_expr (ref
->u
.ss
.end
);
134 if ((!gfc_simplify_expr(start_expr
, 1))
135 || !(gfc_simplify_expr(end_expr
, 1)))
137 gfc_error ("failure to simplify substring reference in DATA "
138 "statement at %L", &ref
->u
.ss
.start
->where
);
139 gfc_free_expr (start_expr
);
140 gfc_free_expr (end_expr
);
142 gfc_free_expr (init
);
146 gfc_extract_int (start_expr
, &start
);
147 gfc_free_expr (start_expr
);
149 gfc_extract_int (end_expr
, &end
);
150 gfc_free_expr (end_expr
);
154 /* Set the whole string. */
159 /* Copy the initial value. */
160 if (rvalue
->ts
.type
== BT_HOLLERITH
)
161 len
= rvalue
->representation
.length
- rvalue
->ts
.u
.pad
;
163 len
= rvalue
->value
.character
.length
;
170 gfc_warning_now (0, "Unused initialization string at %L because "
171 "variable has zero length", &rvalue
->where
);
176 gfc_warning_now (0, "Initialization string at %L was truncated to "
177 "fit the variable (%d/%d)", &rvalue
->where
,
183 if (rvalue
->ts
.type
== BT_HOLLERITH
)
186 for (i
= 0; i
< len
; i
++)
187 dest
[start
+i
] = rvalue
->representation
.string
[i
];
190 memcpy (&dest
[start
], rvalue
->value
.character
.string
,
191 len
* sizeof (gfc_char_t
));
193 /* Pad with spaces. Substrings will already be blanked. */
194 if (len
< tlen
&& ref
== NULL
)
195 gfc_wide_memset (&dest
[start
+ len
], ' ', end
- (start
+ len
));
197 if (rvalue
->ts
.type
== BT_HOLLERITH
)
199 init
->representation
.length
= init
->value
.character
.length
;
200 init
->representation
.string
201 = gfc_widechar_to_char (init
->value
.character
.string
,
202 init
->value
.character
.length
);
209 /* Assign the initial value RVALUE to LVALUE's symbol->value. If the
210 LVALUE already has an initialization, we extend this, otherwise we
211 create a new one. If REPEAT is non-NULL, initialize *REPEAT
212 consecutive values in LVALUE the same value in RVALUE. In that case,
213 LVALUE must refer to a full array, not an array section. */
216 gfc_assign_data_value (gfc_expr
*lvalue
, gfc_expr
*rvalue
, mpz_t index
,
221 gfc_expr
*expr
= NULL
;
222 gfc_constructor
*con
;
223 gfc_constructor
*last_con
;
225 gfc_typespec
*last_ts
;
228 symbol
= lvalue
->symtree
->n
.sym
;
229 init
= symbol
->value
;
230 last_ts
= &symbol
->ts
;
232 mpz_init_set_si (offset
, 0);
234 /* Find/create the parent expressions for subobject references. */
235 for (ref
= lvalue
->ref
; ref
; ref
= ref
->next
)
237 /* Break out of the loop if we find a substring. */
238 if (ref
->type
== REF_SUBSTRING
)
240 /* A substring should always be the last subobject reference. */
241 gcc_assert (ref
->next
== NULL
);
245 /* Use the existing initializer expression if it exists. Otherwise
248 expr
= gfc_get_expr ();
252 /* Find or create this element. */
256 if (ref
->u
.ar
.as
->rank
== 0)
258 gcc_assert (ref
->u
.ar
.as
->corank
> 0);
264 if (init
&& expr
->expr_type
!= EXPR_ARRAY
)
266 gfc_error ("%qs at %L already is initialized at %L",
267 lvalue
->symtree
->n
.sym
->name
, &lvalue
->where
,
274 /* The element typespec will be the same as the array
277 /* Setup the expression to hold the constructor. */
278 expr
->expr_type
= EXPR_ARRAY
;
279 expr
->rank
= ref
->u
.ar
.as
->rank
;
282 if (ref
->u
.ar
.type
== AR_ELEMENT
)
283 get_array_index (&ref
->u
.ar
, &offset
);
285 mpz_set (offset
, index
);
287 /* Check the bounds. */
288 if (mpz_cmp_si (offset
, 0) < 0)
290 gfc_error ("Data element below array lower bound at %L",
294 else if (repeat
!= NULL
295 && ref
->u
.ar
.type
!= AR_ELEMENT
)
298 gcc_assert (ref
->u
.ar
.type
== AR_FULL
299 && ref
->next
== NULL
);
300 mpz_init_set (end
, offset
);
301 mpz_add (end
, end
, *repeat
);
302 if (spec_size (ref
->u
.ar
.as
, &size
))
304 if (mpz_cmp (end
, size
) > 0)
307 gfc_error ("Data element above array upper bound at %L",
314 con
= gfc_constructor_lookup (expr
->value
.constructor
,
315 mpz_get_si (offset
));
318 con
= gfc_constructor_lookup_next (expr
->value
.constructor
,
319 mpz_get_si (offset
));
320 if (con
!= NULL
&& mpz_cmp (con
->offset
, end
) >= 0)
324 /* Overwriting an existing initializer is non-standard but
325 usually only provokes a warning from other compilers. */
326 if (con
!= NULL
&& con
->expr
!= NULL
)
328 /* Order in which the expressions arrive here depends on
329 whether they are from data statements or F95 style
330 declarations. Therefore, check which is the most
333 exprd
= (LOCATION_LINE (con
->expr
->where
.lb
->location
)
334 > LOCATION_LINE (rvalue
->where
.lb
->location
))
335 ? con
->expr
: rvalue
;
336 if (gfc_notify_std (GFC_STD_GNU
,
337 "re-initialization of %qs at %L",
338 symbol
->name
, &exprd
->where
) == false)
344 gfc_constructor
*next_con
= gfc_constructor_next (con
);
346 if (mpz_cmp (con
->offset
, end
) >= 0)
348 if (mpz_cmp (con
->offset
, offset
) < 0)
350 gcc_assert (mpz_cmp_si (con
->repeat
, 1) > 0);
351 mpz_sub (con
->repeat
, offset
, con
->offset
);
353 else if (mpz_cmp_si (con
->repeat
, 1) > 0
354 && mpz_get_si (con
->offset
)
355 + mpz_get_si (con
->repeat
) > mpz_get_si (end
))
359 = splay_tree_lookup (con
->base
,
360 mpz_get_si (con
->offset
));
362 && con
== (gfc_constructor
*) node
->value
363 && node
->key
== (splay_tree_key
)
364 mpz_get_si (con
->offset
));
365 endi
= mpz_get_si (con
->offset
)
366 + mpz_get_si (con
->repeat
);
367 if (endi
> mpz_get_si (end
) + 1)
368 mpz_set_si (con
->repeat
, endi
- mpz_get_si (end
));
370 mpz_set_si (con
->repeat
, 1);
371 mpz_set (con
->offset
, end
);
372 node
->key
= (splay_tree_key
) mpz_get_si (end
);
376 gfc_constructor_remove (con
);
380 con
= gfc_constructor_insert_expr (&expr
->value
.constructor
,
381 NULL
, &rvalue
->where
,
382 mpz_get_si (offset
));
383 mpz_set (con
->repeat
, *repeat
);
391 if (spec_size (ref
->u
.ar
.as
, &size
))
393 if (mpz_cmp (offset
, size
) >= 0)
396 gfc_error ("Data element above array upper bound at %L",
404 con
= gfc_constructor_lookup (expr
->value
.constructor
,
405 mpz_get_si (offset
));
408 con
= gfc_constructor_insert_expr (&expr
->value
.constructor
,
409 NULL
, &rvalue
->where
,
410 mpz_get_si (offset
));
412 else if (mpz_cmp_si (con
->repeat
, 1) > 0)
414 /* Need to split a range. */
415 if (mpz_cmp (con
->offset
, offset
) < 0)
417 gfc_constructor
*pred_con
= con
;
418 con
= gfc_constructor_insert_expr (&expr
->value
.constructor
,
420 mpz_get_si (offset
));
421 con
->expr
= gfc_copy_expr (pred_con
->expr
);
422 mpz_add (con
->repeat
, pred_con
->offset
, pred_con
->repeat
);
423 mpz_sub (con
->repeat
, con
->repeat
, offset
);
424 mpz_sub (pred_con
->repeat
, offset
, pred_con
->offset
);
426 if (mpz_cmp_si (con
->repeat
, 1) > 0)
428 gfc_constructor
*succ_con
;
430 = gfc_constructor_insert_expr (&expr
->value
.constructor
,
432 mpz_get_si (offset
) + 1);
433 succ_con
->expr
= gfc_copy_expr (con
->expr
);
434 mpz_sub_ui (succ_con
->repeat
, con
->repeat
, 1);
435 mpz_set_si (con
->repeat
, 1);
443 /* Setup the expression to hold the constructor. */
444 expr
->expr_type
= EXPR_STRUCTURE
;
445 expr
->ts
.type
= BT_DERIVED
;
446 expr
->ts
.u
.derived
= ref
->u
.c
.sym
;
449 gcc_assert (expr
->expr_type
== EXPR_STRUCTURE
);
450 last_ts
= &ref
->u
.c
.component
->ts
;
452 /* Find the same element in the existing constructor. */
453 con
= find_con_by_component (ref
->u
.c
.component
,
454 expr
->value
.constructor
);
458 /* Create a new constructor. */
459 con
= gfc_constructor_append_expr (&expr
->value
.constructor
,
461 con
->n
.component
= ref
->u
.c
.component
;
471 /* Point the container at the new expression. */
472 if (last_con
== NULL
)
473 symbol
->value
= expr
;
475 last_con
->expr
= expr
;
482 gcc_assert (repeat
== NULL
);
484 if (ref
|| last_ts
->type
== BT_CHARACTER
)
486 if (lvalue
->ts
.u
.cl
->length
== NULL
&& !(ref
&& ref
->u
.ss
.length
!= NULL
))
488 expr
= create_character_initializer (init
, last_ts
, ref
, rvalue
);
492 /* Overwriting an existing initializer is non-standard but usually only
493 provokes a warning from other compilers. */
496 /* Order in which the expressions arrive here depends on whether
497 they are from data statements or F95 style declarations.
498 Therefore, check which is the most recent. */
499 expr
= (LOCATION_LINE (init
->where
.lb
->location
)
500 > LOCATION_LINE (rvalue
->where
.lb
->location
))
502 if (gfc_notify_std (GFC_STD_GNU
,
503 "re-initialization of %qs at %L",
504 symbol
->name
, &expr
->where
) == false)
508 expr
= gfc_copy_expr (rvalue
);
509 if (!gfc_compare_types (&lvalue
->ts
, &expr
->ts
))
510 gfc_convert_type (expr
, &lvalue
->ts
, 0);
513 if (last_con
== NULL
)
514 symbol
->value
= expr
;
516 last_con
->expr
= expr
;
522 gfc_free_expr (expr
);
528 /* Modify the index of array section and re-calculate the array offset. */
531 gfc_advance_section (mpz_t
*section_index
, gfc_array_ref
*ar
,
540 for (i
= 0; i
< ar
->dimen
; i
++)
542 if (ar
->dimen_type
[i
] != DIMEN_RANGE
)
547 mpz_add (section_index
[i
], section_index
[i
],
548 ar
->stride
[i
]->value
.integer
);
549 if (mpz_cmp_si (ar
->stride
[i
]->value
.integer
, 0) >= 0)
556 mpz_add_ui (section_index
[i
], section_index
[i
], 1);
561 cmp
= mpz_cmp (section_index
[i
], ar
->end
[i
]->value
.integer
);
563 cmp
= mpz_cmp (section_index
[i
], ar
->as
->upper
[i
]->value
.integer
);
565 if ((cmp
> 0 && forwards
) || (cmp
< 0 && !forwards
))
567 /* Reset index to start, then loop to advance the next index. */
569 mpz_set (section_index
[i
], ar
->start
[i
]->value
.integer
);
571 mpz_set (section_index
[i
], ar
->as
->lower
[i
]->value
.integer
);
577 mpz_set_si (*offset_ret
, 0);
578 mpz_init_set_si (delta
, 1);
580 for (i
= 0; i
< ar
->dimen
; i
++)
582 mpz_sub (tmp
, section_index
[i
], ar
->as
->lower
[i
]->value
.integer
);
583 mpz_mul (tmp
, tmp
, delta
);
584 mpz_add (*offset_ret
, tmp
, *offset_ret
);
586 mpz_sub (tmp
, ar
->as
->upper
[i
]->value
.integer
,
587 ar
->as
->lower
[i
]->value
.integer
);
588 mpz_add_ui (tmp
, tmp
, 1);
589 mpz_mul (delta
, tmp
, delta
);
596 /* Rearrange a structure constructor so the elements are in the specified
597 order. Also insert NULL entries if necessary. */
600 formalize_structure_cons (gfc_expr
*expr
)
602 gfc_constructor_base base
= NULL
;
603 gfc_constructor
*cur
;
604 gfc_component
*order
;
606 /* Constructor is already formalized. */
607 cur
= gfc_constructor_first (expr
->value
.constructor
);
608 if (!cur
|| cur
->n
.component
== NULL
)
611 for (order
= expr
->ts
.u
.derived
->components
; order
; order
= order
->next
)
613 cur
= find_con_by_component (order
, expr
->value
.constructor
);
615 gfc_constructor_append_expr (&base
, cur
->expr
, &cur
->expr
->where
);
617 gfc_constructor_append_expr (&base
, NULL
, NULL
);
620 /* For all what it's worth, one would expect
621 gfc_constructor_free (expr->value.constructor);
622 here. However, if the constructor is actually free'd,
623 hell breaks loose in the testsuite?! */
625 expr
->value
.constructor
= base
;
629 /* Make sure an initialization expression is in normalized form, i.e., all
630 elements of the constructors are in the correct order. */
633 formalize_init_expr (gfc_expr
*expr
)
641 type
= expr
->expr_type
;
645 for (c
= gfc_constructor_first (expr
->value
.constructor
);
646 c
; c
= gfc_constructor_next (c
))
647 formalize_init_expr (c
->expr
);
652 formalize_structure_cons (expr
);
661 /* Resolve symbol's initial value after all data statement. */
664 gfc_formalize_init_value (gfc_symbol
*sym
)
666 formalize_init_expr (sym
->value
);
670 /* Get the integer value into RET_AS and SECTION from AS and AR, and return
674 gfc_get_section_index (gfc_array_ref
*ar
, mpz_t
*section_index
, mpz_t
*offset
)
680 mpz_set_si (*offset
, 0);
682 mpz_init_set_si (delta
, 1);
683 for (i
= 0; i
< ar
->dimen
; i
++)
685 mpz_init (section_index
[i
]);
686 switch (ar
->dimen_type
[i
])
692 mpz_sub (tmp
, ar
->start
[i
]->value
.integer
,
693 ar
->as
->lower
[i
]->value
.integer
);
694 mpz_mul (tmp
, tmp
, delta
);
695 mpz_add (*offset
, tmp
, *offset
);
696 mpz_set (section_index
[i
], ar
->start
[i
]->value
.integer
);
699 mpz_set (section_index
[i
], ar
->as
->lower
[i
]->value
.integer
);
703 gfc_internal_error ("TODO: Vector sections in data statements");
709 mpz_sub (tmp
, ar
->as
->upper
[i
]->value
.integer
,
710 ar
->as
->lower
[i
]->value
.integer
);
711 mpz_add_ui (tmp
, tmp
, 1);
712 mpz_mul (delta
, tmp
, delta
);