1 /* Supporting functions for resolving DATA statement. 2 Copyright (C) 2002-2020 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.c. 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.c and 33 trans-array.c. */ 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 void 47 get_array_index (gfc_array_ref *ar, mpz_t *offset) 48 { 49 gfc_expr *e; 50 int i; 51 mpz_t delta; 52 mpz_t tmp; 53 54 mpz_init (tmp); 55 mpz_set_si (*offset, 0); 56 mpz_init_set_si (delta, 1); 57 for (i = 0; i < ar->dimen; i++) 58 { 59 e = gfc_copy_expr (ar->start[i]); 60 gfc_simplify_expr (e, 1); 61 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); 66 67 mpz_set (tmp, e->value.integer); 68 gfc_free_expr (e); 69 mpz_sub (tmp, tmp, ar->as->lower[i]->value.integer); 70 mpz_mul (tmp, tmp, delta); 71 mpz_add (*offset, tmp, *offset); 72 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); 77 } 78 mpz_clear (delta); 79 mpz_clear (tmp); 80 } 81 82 /* Find if there is a constructor which component is equal to COM. 83 TODO: remove this, use symbol.c(gfc_find_component) instead. */ 84 85 static gfc_constructor * 86 find_con_by_component (gfc_component *com, gfc_constructor_base base) 87 { 88 gfc_constructor *c; 89 90 for (c = gfc_constructor_first (base); c; c = gfc_constructor_next (c)) 91 if (com == c->n.component) 92 return c; 93 94 return NULL; 95 } 96 97 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. */ 102 103 static gfc_expr * 104 create_character_initializer (gfc_expr *init, gfc_typespec *ts, 105 gfc_ref *ref, gfc_expr *rvalue) 106 { 107 HOST_WIDE_INT len, start, end, tlen; 108 gfc_char_t *dest; 109 bool alloced_init = false; 110 111 if (init && init->ts.type != BT_CHARACTER) 112 return NULL; 113 114 gfc_extract_hwi (ts->u.cl->length, &len); 115 116 if (init == NULL) 117 { 118 /* Create a new initializer. */ 119 init = gfc_get_character_expr (ts->kind, NULL, NULL, len); 120 init->ts = *ts; 121 alloced_init = true; 122 } 123 124 dest = init->value.character.string; 125 126 if (ref) 127 { 128 gfc_expr *start_expr, *end_expr; 129 130 gcc_assert (ref->type == REF_SUBSTRING); 131 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); 136 137 if ((!gfc_simplify_expr(start_expr, 1)) 138 || !(gfc_simplify_expr(end_expr, 1))) 139 { 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); 144 if (alloced_init) 145 gfc_free_expr (init); 146 return NULL; 147 } 148 149 gfc_extract_hwi (start_expr, &start); 150 gfc_free_expr (start_expr); 151 start--; 152 gfc_extract_hwi (end_expr, &end); 153 gfc_free_expr (end_expr); 154 } 155 else 156 { 157 /* Set the whole string. */ 158 start = 0; 159 end = len; 160 } 161 162 /* Copy the initial value. */ 163 if (rvalue->ts.type == BT_HOLLERITH) 164 len = rvalue->representation.length - rvalue->ts.u.pad; 165 else 166 len = rvalue->value.character.length; 167 168 tlen = end - start; 169 if (len > tlen) 170 { 171 if (tlen < 0) 172 { 173 gfc_warning_now (0, "Unused initialization string at %L because " 174 "variable has zero length", &rvalue->where); 175 len = 0; 176 } 177 else 178 { 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); 182 len = tlen; 183 } 184 } 185 186 if (rvalue->ts.type == BT_HOLLERITH) 187 { 188 for (size_t i = 0; i < (size_t) len; i++) 189 dest[start+i] = rvalue->representation.string[i]; 190 } 191 else 192 memcpy (&dest[start], rvalue->value.character.string, 193 len * sizeof (gfc_char_t)); 194 195 /* Pad with spaces. Substrings will already be blanked. */ 196 if (len < tlen && ref == NULL) 197 gfc_wide_memset (&dest[start + len], ' ', end - (start + len)); 198 199 if (rvalue->ts.type == BT_HOLLERITH) 200 { 201 init->representation.length = init->value.character.length; 202 init->representation.string 203 = gfc_widechar_to_char (init->value.character.string, 204 init->value.character.length); 205 } 206 207 return init; 208 } 209 210 211 /* Assign the initial value RVALUE to LVALUE's symbol->value. If the 212 LVALUE already has an initialization, we extend this, otherwise we 213 create a new one. If REPEAT is non-NULL, initialize *REPEAT 214 consecutive values in LVALUE the same value in RVALUE. In that case, 215 LVALUE must refer to a full array, not an array section. */ 216 217 bool 218 gfc_assign_data_value (gfc_expr *lvalue, gfc_expr *rvalue, mpz_t index, 219 mpz_t *repeat) 220 { 221 gfc_ref *ref; 222 gfc_expr *init; 223 gfc_expr *expr = NULL; 224 gfc_expr *rexpr; 225 gfc_constructor *con; 226 gfc_constructor *last_con; 227 gfc_symbol *symbol; 228 gfc_typespec *last_ts; 229 mpz_t offset; 230 const char *msg = "F18(R841): data-implied-do object at %L is neither an " 231 "array-element nor a scalar-structure-component"; 232 233 symbol = lvalue->symtree->n.sym; 234 init = symbol->value; 235 last_ts = &symbol->ts; 236 last_con = NULL; 237 mpz_init_set_si (offset, 0); 238 239 /* Find/create the parent expressions for subobject references. */ 240 for (ref = lvalue->ref; ref; ref = ref->next) 241 { 242 /* Break out of the loop if we find a substring. */ 243 if (ref->type == REF_SUBSTRING) 244 { 245 /* A substring should always be the last subobject reference. */ 246 gcc_assert (ref->next == NULL); 247 break; 248 } 249 250 /* Use the existing initializer expression if it exists. Otherwise 251 create a new one. */ 252 if (init == NULL) 253 expr = gfc_get_expr (); 254 else 255 expr = init; 256 257 /* Find or create this element. */ 258 switch (ref->type) 259 { 260 case REF_ARRAY: 261 if (ref->u.ar.as->rank == 0) 262 { 263 gcc_assert (ref->u.ar.as->corank > 0); 264 if (init == NULL) 265 free (expr); 266 continue; 267 } 268 269 if (init && expr->expr_type != EXPR_ARRAY) 270 { 271 gfc_error ("%qs at %L already is initialized at %L", 272 lvalue->symtree->n.sym->name, &lvalue->where, 273 &init->where); 274 goto abort; 275 } 276 277 if (init == NULL) 278 { 279 /* The element typespec will be the same as the array 280 typespec. */ 281 expr->ts = *last_ts; 282 /* Setup the expression to hold the constructor. */ 283 expr->expr_type = EXPR_ARRAY; 284 expr->rank = ref->u.ar.as->rank; 285 } 286 287 if (ref->u.ar.type == AR_ELEMENT) 288 get_array_index (&ref->u.ar, &offset); 289 else 290 mpz_set (offset, index); 291 292 /* Check the bounds. */ 293 if (mpz_cmp_si (offset, 0) < 0) 294 { 295 gfc_error ("Data element below array lower bound at %L", 296 &lvalue->where); 297 goto abort; 298 } 299 else if (repeat != NULL 300 && ref->u.ar.type != AR_ELEMENT) 301 { 302 mpz_t size, end; 303 gcc_assert (ref->u.ar.type == AR_FULL 304 && ref->next == NULL); 305 mpz_init_set (end, offset); 306 mpz_add (end, end, *repeat); 307 if (spec_size (ref->u.ar.as, &size)) 308 { 309 if (mpz_cmp (end, size) > 0) 310 { 311 mpz_clear (size); 312 gfc_error ("Data element above array upper bound at %L", 313 &lvalue->where); 314 goto abort; 315 } 316 mpz_clear (size); 317 } 318 319 con = gfc_constructor_lookup (expr->value.constructor, 320 mpz_get_si (offset)); 321 if (!con) 322 { 323 con = gfc_constructor_lookup_next (expr->value.constructor, 324 mpz_get_si (offset)); 325 if (con != NULL && mpz_cmp (con->offset, end) >= 0) 326 con = NULL; 327 } 328 329 /* Overwriting an existing initializer is non-standard but 330 usually only provokes a warning from other compilers. */ 331 if (con != NULL && con->expr != NULL) 332 { 333 /* Order in which the expressions arrive here depends on 334 whether they are from data statements or F95 style 335 declarations. Therefore, check which is the most 336 recent. */ 337 gfc_expr *exprd; 338 exprd = (LOCATION_LINE (con->expr->where.lb->location) 339 > LOCATION_LINE (rvalue->where.lb->location)) 340 ? con->expr : rvalue; 341 if (gfc_notify_std (GFC_STD_GNU, 342 "re-initialization of %qs at %L", 343 symbol->name, &exprd->where) == false) 344 return false; 345 } 346 347 while (con != NULL) 348 { 349 gfc_constructor *next_con = gfc_constructor_next (con); 350 351 if (mpz_cmp (con->offset, end) >= 0) 352 break; 353 if (mpz_cmp (con->offset, offset) < 0) 354 { 355 gcc_assert (mpz_cmp_si (con->repeat, 1) > 0); 356 mpz_sub (con->repeat, offset, con->offset); 357 } 358 else if (mpz_cmp_si (con->repeat, 1) > 0 359 && mpz_get_si (con->offset) 360 + mpz_get_si (con->repeat) > mpz_get_si (end)) 361 { 362 int endi; 363 splay_tree_node node 364 = splay_tree_lookup (con->base, 365 mpz_get_si (con->offset)); 366 gcc_assert (node 367 && con == (gfc_constructor *) node->value 368 && node->key == (splay_tree_key) 369 mpz_get_si (con->offset)); 370 endi = mpz_get_si (con->offset) 371 + mpz_get_si (con->repeat); 372 if (endi > mpz_get_si (end) + 1) 373 mpz_set_si (con->repeat, endi - mpz_get_si (end)); 374 else 375 mpz_set_si (con->repeat, 1); 376 mpz_set (con->offset, end); 377 node->key = (splay_tree_key) mpz_get_si (end); 378 break; 379 } 380 else 381 gfc_constructor_remove (con); 382 con = next_con; 383 } 384 385 con = gfc_constructor_insert_expr (&expr->value.constructor, 386 NULL, &rvalue->where, 387 mpz_get_si (offset)); 388 mpz_set (con->repeat, *repeat); 389 repeat = NULL; 390 mpz_clear (end); 391 break; 392 } 393 else 394 { 395 mpz_t size; 396 if (spec_size (ref->u.ar.as, &size)) 397 { 398 if (mpz_cmp (offset, size) >= 0) 399 { 400 mpz_clear (size); 401 gfc_error ("Data element above array upper bound at %L", 402 &lvalue->where); 403 goto abort; 404 } 405 mpz_clear (size); 406 } 407 } 408 409 con = gfc_constructor_lookup (expr->value.constructor, 410 mpz_get_si (offset)); 411 if (!con) 412 { 413 con = gfc_constructor_insert_expr (&expr->value.constructor, 414 NULL, &rvalue->where, 415 mpz_get_si (offset)); 416 } 417 else if (mpz_cmp_si (con->repeat, 1) > 0) 418 { 419 /* Need to split a range. */ 420 if (mpz_cmp (con->offset, offset) < 0) 421 { 422 gfc_constructor *pred_con = con; 423 con = gfc_constructor_insert_expr (&expr->value.constructor, 424 NULL, &con->where, 425 mpz_get_si (offset)); 426 con->expr = gfc_copy_expr (pred_con->expr); 427 mpz_add (con->repeat, pred_con->offset, pred_con->repeat); 428 mpz_sub (con->repeat, con->repeat, offset); 429 mpz_sub (pred_con->repeat, offset, pred_con->offset); 430 } 431 if (mpz_cmp_si (con->repeat, 1) > 0) 432 { 433 gfc_constructor *succ_con; 434 succ_con 435 = gfc_constructor_insert_expr (&expr->value.constructor, 436 NULL, &con->where, 437 mpz_get_si (offset) + 1); 438 succ_con->expr = gfc_copy_expr (con->expr); 439 mpz_sub_ui (succ_con->repeat, con->repeat, 1); 440 mpz_set_si (con->repeat, 1); 441 } 442 } 443 break; 444 445 case REF_COMPONENT: 446 if (init == NULL) 447 { 448 /* Setup the expression to hold the constructor. */ 449 expr->expr_type = EXPR_STRUCTURE; 450 expr->ts.type = BT_DERIVED; 451 expr->ts.u.derived = ref->u.c.sym; 452 } 453 else 454 gcc_assert (expr->expr_type == EXPR_STRUCTURE); 455 last_ts = &ref->u.c.component->ts; 456 457 /* Find the same element in the existing constructor. */ 458 con = find_con_by_component (ref->u.c.component, 459 expr->value.constructor); 460 461 if (con == NULL) 462 { 463 /* Create a new constructor. */ 464 con = gfc_constructor_append_expr (&expr->value.constructor, 465 NULL, NULL); 466 con->n.component = ref->u.c.component; 467 } 468 break; 469 470 case REF_INQUIRY: 471 472 /* After some discussion on clf it was determined that the following 473 violates F18(R841). If the error is removed, the expected result 474 is obtained. Leaving the code in place ensures a clean error 475 recovery. */ 476 gfc_error (msg, &lvalue->where); 477 478 /* This breaks with the other reference types in that the output 479 constructor has to be of type COMPLEX, whereas the lvalue is 480 of type REAL. The rvalue is copied to the real or imaginary 481 part as appropriate. In addition, for all except scalar 482 complex variables, a complex expression has to provided, where 483 the constructor does not have it, and the expression modified 484 with a new value for the real or imaginary part. */ 485 gcc_assert (ref->next == NULL && last_ts->type == BT_COMPLEX); 486 rexpr = gfc_copy_expr (rvalue); 487 if (!gfc_compare_types (&lvalue->ts, &rexpr->ts)) 488 gfc_convert_type (rexpr, &lvalue->ts, 0); 489 490 /* This is the scalar, complex case, where an initializer exists. */ 491 if (init && ref == lvalue->ref) 492 expr = symbol->value; 493 /* Then all cases, where a complex expression does not exist. */ 494 else if (!last_con || !last_con->expr) 495 { 496 expr = gfc_get_constant_expr (BT_COMPLEX, lvalue->ts.kind, 497 &lvalue->where); 498 if (last_con) 499 last_con->expr = expr; 500 } 501 else 502 /* Finally, and existing constructor expression to be modified. */ 503 expr = last_con->expr; 504 505 /* Rejection of LEN and KIND inquiry references is handled 506 elsewhere. The error here is added as backup. The assertion 507 of F2008 for RE and IM is also done elsewhere. */ 508 switch (ref->u.i) 509 { 510 case INQUIRY_LEN: 511 case INQUIRY_KIND: 512 gfc_error ("LEN or KIND inquiry ref in DATA statement at %L", 513 &lvalue->where); 514 goto abort; 515 case INQUIRY_RE: 516 mpfr_set (mpc_realref (expr->value.complex), 517 rexpr->value.real, 518 GFC_RND_MODE); 519 break; 520 case INQUIRY_IM: 521 mpfr_set (mpc_imagref (expr->value.complex), 522 rexpr->value.real, 523 GFC_RND_MODE); 524 break; 525 } 526 527 /* Only the scalar, complex expression needs to be saved as the 528 symbol value since the last constructor expression is already 529 provided as the initializer in the code after the reference 530 cases. */ 531 if (ref == lvalue->ref) 532 symbol->value = expr; 533 534 gfc_free_expr (rexpr); 535 mpz_clear (offset); 536 return true; 537 538 default: 539 gcc_unreachable (); 540 } 541 542 if (init == NULL) 543 { 544 /* Point the container at the new expression. */ 545 if (last_con == NULL) 546 symbol->value = expr; 547 else 548 last_con->expr = expr; 549 } 550 init = con->expr; 551 last_con = con; 552 } 553 554 mpz_clear (offset); 555 gcc_assert (repeat == NULL); 556 557 /* Overwriting an existing initializer is non-standard but usually only 558 provokes a warning from other compilers. */ 559 if (init != NULL && init->where.lb && rvalue->where.lb) 560 { 561 /* Order in which the expressions arrive here depends on whether 562 they are from data statements or F95 style declarations. 563 Therefore, check which is the most recent. */ 564 expr = (LOCATION_LINE (init->where.lb->location) 565 > LOCATION_LINE (rvalue->where.lb->location)) 566 ? init : rvalue; 567 if (gfc_notify_std (GFC_STD_GNU, "re-initialization of %qs at %L", 568 symbol->name, &expr->where) == false) 569 return false; 570 } 571 572 if (ref || (last_ts->type == BT_CHARACTER 573 && rvalue->expr_type == EXPR_CONSTANT)) 574 { 575 /* An initializer has to be constant. */ 576 if (lvalue->ts.u.cl->length == NULL && !(ref && ref->u.ss.length != NULL)) 577 return false; 578 if (lvalue->ts.u.cl->length 579 && lvalue->ts.u.cl->length->expr_type != EXPR_CONSTANT) 580 return false; 581 expr = create_character_initializer (init, last_ts, ref, rvalue); 582 } 583 else 584 { 585 if (lvalue->ts.type == BT_DERIVED 586 && gfc_has_default_initializer (lvalue->ts.u.derived)) 587 { 588 gfc_error ("Nonpointer object %qs with default initialization " 589 "shall not appear in a DATA statement at %L", 590 symbol->name, &lvalue->where); 591 return false; 592 } 593 594 expr = gfc_copy_expr (rvalue); 595 if (!gfc_compare_types (&lvalue->ts, &expr->ts)) 596 gfc_convert_type (expr, &lvalue->ts, 0); 597 } 598 599 if (last_con == NULL) 600 symbol->value = expr; 601 else 602 last_con->expr = expr; 603 604 return true; 605 606 abort: 607 if (!init) 608 gfc_free_expr (expr); 609 mpz_clear (offset); 610 return false; 611 } 612 613 614 /* Modify the index of array section and re-calculate the array offset. */ 615 616 void 617 gfc_advance_section (mpz_t *section_index, gfc_array_ref *ar, 618 mpz_t *offset_ret) 619 { 620 int i; 621 mpz_t delta; 622 mpz_t tmp; 623 bool forwards; 624 int cmp; 625 gfc_expr *start, *end, *stride; 626 627 for (i = 0; i < ar->dimen; i++) 628 { 629 if (ar->dimen_type[i] != DIMEN_RANGE) 630 continue; 631 632 if (ar->stride[i]) 633 { 634 stride = gfc_copy_expr(ar->stride[i]); 635 if(!gfc_simplify_expr(stride, 1)) 636 gfc_internal_error("Simplification error"); 637 mpz_add (section_index[i], section_index[i], 638 stride->value.integer); 639 if (mpz_cmp_si (stride->value.integer, 0) >= 0) 640 forwards = true; 641 else 642 forwards = false; 643 gfc_free_expr(stride); 644 } 645 else 646 { 647 mpz_add_ui (section_index[i], section_index[i], 1); 648 forwards = true; 649 } 650 651 if (ar->end[i]) 652 { 653 end = gfc_copy_expr(ar->end[i]); 654 if(!gfc_simplify_expr(end, 1)) 655 gfc_internal_error("Simplification error"); 656 cmp = mpz_cmp (section_index[i], end->value.integer); 657 gfc_free_expr(end); 658 } 659 else 660 cmp = mpz_cmp (section_index[i], ar->as->upper[i]->value.integer); 661 662 if ((cmp > 0 && forwards) || (cmp < 0 && !forwards)) 663 { 664 /* Reset index to start, then loop to advance the next index. */ 665 if (ar->start[i]) 666 { 667 start = gfc_copy_expr(ar->start[i]); 668 if(!gfc_simplify_expr(start, 1)) 669 gfc_internal_error("Simplification error"); 670 mpz_set (section_index[i], start->value.integer); 671 gfc_free_expr(start); 672 } 673 else 674 mpz_set (section_index[i], ar->as->lower[i]->value.integer); 675 } 676 else 677 break; 678 } 679 680 mpz_set_si (*offset_ret, 0); 681 mpz_init_set_si (delta, 1); 682 mpz_init (tmp); 683 for (i = 0; i < ar->dimen; i++) 684 { 685 mpz_sub (tmp, section_index[i], ar->as->lower[i]->value.integer); 686 mpz_mul (tmp, tmp, delta); 687 mpz_add (*offset_ret, tmp, *offset_ret); 688 689 mpz_sub (tmp, ar->as->upper[i]->value.integer, 690 ar->as->lower[i]->value.integer); 691 mpz_add_ui (tmp, tmp, 1); 692 mpz_mul (delta, tmp, delta); 693 } 694 mpz_clear (tmp); 695 mpz_clear (delta); 696 } 697 698 699 /* Rearrange a structure constructor so the elements are in the specified 700 order. Also insert NULL entries if necessary. */ 701 702 static void 703 formalize_structure_cons (gfc_expr *expr) 704 { 705 gfc_constructor_base base = NULL; 706 gfc_constructor *cur; 707 gfc_component *order; 708 709 /* Constructor is already formalized. */ 710 cur = gfc_constructor_first (expr->value.constructor); 711 if (!cur || cur->n.component == NULL) 712 return; 713 714 for (order = expr->ts.u.derived->components; order; order = order->next) 715 { 716 cur = find_con_by_component (order, expr->value.constructor); 717 if (cur) 718 gfc_constructor_append_expr (&base, cur->expr, &cur->expr->where); 719 else 720 gfc_constructor_append_expr (&base, NULL, NULL); 721 } 722 723 /* For all what it's worth, one would expect 724 gfc_constructor_free (expr->value.constructor); 725 here. However, if the constructor is actually free'd, 726 hell breaks loose in the testsuite?! */ 727 728 expr->value.constructor = base; 729 } 730 731 732 /* Make sure an initialization expression is in normalized form, i.e., all 733 elements of the constructors are in the correct order. */ 734 735 static void 736 formalize_init_expr (gfc_expr *expr) 737 { 738 expr_t type; 739 gfc_constructor *c; 740 741 if (expr == NULL) 742 return; 743 744 type = expr->expr_type; 745 switch (type) 746 { 747 case EXPR_ARRAY: 748 for (c = gfc_constructor_first (expr->value.constructor); 749 c; c = gfc_constructor_next (c)) 750 formalize_init_expr (c->expr); 751 752 break; 753 754 case EXPR_STRUCTURE: 755 formalize_structure_cons (expr); 756 break; 757 758 default: 759 break; 760 } 761 } 762 763 764 /* Resolve symbol's initial value after all data statement. */ 765 766 void 767 gfc_formalize_init_value (gfc_symbol *sym) 768 { 769 formalize_init_expr (sym->value); 770 } 771 772 773 /* Get the integer value into RET_AS and SECTION from AS and AR, and return 774 offset. */ 775 776 void 777 gfc_get_section_index (gfc_array_ref *ar, mpz_t *section_index, mpz_t *offset) 778 { 779 int i; 780 mpz_t delta; 781 mpz_t tmp; 782 gfc_expr *start; 783 784 mpz_set_si (*offset, 0); 785 mpz_init (tmp); 786 mpz_init_set_si (delta, 1); 787 for (i = 0; i < ar->dimen; i++) 788 { 789 mpz_init (section_index[i]); 790 switch (ar->dimen_type[i]) 791 { 792 case DIMEN_ELEMENT: 793 case DIMEN_RANGE: 794 if (ar->start[i]) 795 { 796 start = gfc_copy_expr(ar->start[i]); 797 if(!gfc_simplify_expr(start, 1)) 798 gfc_internal_error("Simplification error"); 799 mpz_sub (tmp, start->value.integer, 800 ar->as->lower[i]->value.integer); 801 mpz_mul (tmp, tmp, delta); 802 mpz_add (*offset, tmp, *offset); 803 mpz_set (section_index[i], start->value.integer); 804 gfc_free_expr(start); 805 } 806 else 807 mpz_set (section_index[i], ar->as->lower[i]->value.integer); 808 break; 809 810 case DIMEN_VECTOR: 811 gfc_internal_error ("TODO: Vector sections in data statements"); 812 813 default: 814 gcc_unreachable (); 815 } 816 817 mpz_sub (tmp, ar->as->upper[i]->value.integer, 818 ar->as->lower[i]->value.integer); 819 mpz_add_ui (tmp, tmp, 1); 820 mpz_mul (delta, tmp, delta); 821 } 822 823 mpz_clear (tmp); 824 mpz_clear (delta); 825 } 826 827