target-memory.c 18.8 KB
Newer Older
Paul Thomas committed
1
/* Simulate storage of variables into target memory.
2
   Copyright (C) 2007, 2008, 2009
Paul Thomas committed
3 4 5 6 7 8 9
   Free Software Foundation, Inc.
   Contributed by Paul Thomas and Brooks Moses

This file is part of GCC.

GCC is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free
10
Software Foundation; either version 3, or (at your option) any later
Paul Thomas committed
11 12 13 14 15 16 17 18
version.

GCC is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
for more details.

You should have received a copy of the GNU General Public License
19 20
along with GCC; see the file COPYING3.  If not see
<http://www.gnu.org/licenses/>.  */
Paul Thomas committed
21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75

#include "config.h"
#include "system.h"
#include "flags.h"
#include "machmode.h"
#include "tree.h"
#include "gfortran.h"
#include "arith.h"
#include "trans.h"
#include "trans-const.h"
#include "trans-types.h"
#include "target-memory.h"

/* --------------------------------------------------------------- */ 
/* Calculate the size of an expression.  */

static size_t
size_array (gfc_expr *e)
{
  mpz_t array_size;
  size_t elt_size = gfc_target_expr_size (e->value.constructor->expr);

  gfc_array_size (e, &array_size);
  return (size_t)mpz_get_ui (array_size) * elt_size;
}

static size_t
size_integer (int kind)
{
  return GET_MODE_SIZE (TYPE_MODE (gfc_get_int_type (kind)));;
}


static size_t
size_float (int kind)
{
  return GET_MODE_SIZE (TYPE_MODE (gfc_get_real_type (kind)));;
}


static size_t
size_complex (int kind)
{
  return 2 * size_float (kind);
}


static size_t
size_logical (int kind)
{
  return GET_MODE_SIZE (TYPE_MODE (gfc_get_logical_type (kind)));;
}


static size_t
76
size_character (int length, int kind)
Paul Thomas committed
77
{
78 79
  int i = gfc_validate_kind (BT_CHARACTER, kind, false);
  return length * gfc_character_kinds[i].bit_size / 8;
Paul Thomas committed
80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103
}


size_t
gfc_target_expr_size (gfc_expr *e)
{
  tree type;

  gcc_assert (e != NULL);

  if (e->expr_type == EXPR_ARRAY)
    return size_array (e);

  switch (e->ts.type)
    {
    case BT_INTEGER:
      return size_integer (e->ts.kind);
    case BT_REAL:
      return size_float (e->ts.kind);
    case BT_COMPLEX:
      return size_complex (e->ts.kind);
    case BT_LOGICAL:
      return size_logical (e->ts.kind);
    case BT_CHARACTER:
104 105 106 107 108 109 110 111 112 113
      if (e->expr_type == EXPR_SUBSTRING && e->ref)
        {
          int start, end;

          gfc_extract_int (e->ref->u.ss.start, &start);
          gfc_extract_int (e->ref->u.ss.end, &end);
          return size_character (MAX(end - start + 1, 0), e->ts.kind);
        }
      else
        return size_character (e->value.character.length, e->ts.kind);
Brooks Moses committed
114 115
    case BT_HOLLERITH:
      return e->representation.length;
Paul Thomas committed
116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160
    case BT_DERIVED:
      type = gfc_typenode_for_spec (&e->ts);
      return int_size_in_bytes (type);
    default:
      gfc_internal_error ("Invalid expression in gfc_target_expr_size.");
      return 0;
    }
}


/* The encode_* functions export a value into a buffer, and 
   return the number of bytes of the buffer that have been
   used.  */

static int
encode_array (gfc_expr *expr, unsigned char *buffer, size_t buffer_size)
{
  mpz_t array_size;
  int i;
  int ptr = 0;

  gfc_array_size (expr, &array_size);
  for (i = 0; i < (int)mpz_get_ui (array_size); i++)
    {
      ptr += gfc_target_encode_expr (gfc_get_array_element (expr, i),
				     &buffer[ptr], buffer_size - ptr);
    }

  mpz_clear (array_size);
  return ptr;
}


static int
encode_integer (int kind, mpz_t integer, unsigned char *buffer,
		size_t buffer_size)
{
  return native_encode_expr (gfc_conv_mpz_to_tree (integer, kind),
			     buffer, buffer_size);
}


static int
encode_float (int kind, mpfr_t real, unsigned char *buffer, size_t buffer_size)
{
161
  return native_encode_expr (gfc_conv_mpfr_to_tree (real, kind, 0), buffer,
Paul Thomas committed
162 163 164 165 166
			     buffer_size);
}


static int
167
encode_complex (int kind, mpc_t cmplx,
168
		unsigned char *buffer, size_t buffer_size)
Paul Thomas committed
169 170
{
  int size;
171 172
  size = encode_float (kind, mpc_realref (cmplx), &buffer[0], buffer_size);
  size += encode_float (kind, mpc_imagref (cmplx),
173
			&buffer[size], buffer_size - size);
Paul Thomas committed
174 175 176 177 178 179 180 181 182 183 184 185 186
  return size;
}


static int
encode_logical (int kind, int logical, unsigned char *buffer, size_t buffer_size)
{
  return native_encode_expr (build_int_cst (gfc_get_logical_type (kind),
					    logical),
			     buffer, buffer_size);
}


187 188 189
int
gfc_encode_character (int kind, int length, const gfc_char_t *string,
		      unsigned char *buffer, size_t buffer_size)
Paul Thomas committed
190
{
191 192 193
  size_t elsize = size_character (1, kind);
  tree type = gfc_get_char_type (kind);
  int i;
194 195 196

  gcc_assert (buffer_size >= size_character (length, kind));

197 198 199
  for (i = 0; i < length; i++)
    native_encode_expr (build_int_cst (type, string[i]), &buffer[i*elsize],
			elsize);
200

Paul Thomas committed
201 202 203 204 205 206 207 208 209 210 211 212 213 214 215
  return length;
}


static int
encode_derived (gfc_expr *source, unsigned char *buffer, size_t buffer_size)
{
  gfc_constructor *ctr;
  gfc_component *cmp;
  int ptr;
  tree type;

  type = gfc_typenode_for_spec (&source->ts);

  ctr = source->value.constructor;
216
  cmp = source->ts.u.derived->components;
Paul Thomas committed
217 218
  for (;ctr; ctr = ctr->next, cmp = cmp->next)
    {
219 220 221 222 223
      gcc_assert (cmp);
      if (!ctr->expr)
	continue;
      ptr = TREE_INT_CST_LOW(DECL_FIELD_OFFSET(cmp->backend_decl))
	    + TREE_INT_CST_LOW(DECL_FIELD_BIT_OFFSET(cmp->backend_decl))/8;
224 225 226 227 228 229 230

      if (ctr->expr->expr_type == EXPR_NULL)
 	memset (&buffer[ptr], 0,
		int_size_in_bytes (TREE_TYPE (cmp->backend_decl)));
      else
	gfc_target_encode_expr (ctr->expr, &buffer[ptr],
				buffer_size - ptr);
Paul Thomas committed
231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248
    }

  return int_size_in_bytes (type);
}


/* Write a constant expression in binary form to a buffer.  */
int
gfc_target_encode_expr (gfc_expr *source, unsigned char *buffer,
			size_t buffer_size)
{
  if (source == NULL)
    return 0;

  if (source->expr_type == EXPR_ARRAY)
    return encode_array (source, buffer, buffer_size);

  gcc_assert (source->expr_type == EXPR_CONSTANT
249 250
	      || source->expr_type == EXPR_STRUCTURE
	      || source->expr_type == EXPR_SUBSTRING);
Paul Thomas committed
251

252 253 254 255 256 257 258 259 260
  /* If we already have a target-memory representation, we use that rather 
     than recreating one.  */
  if (source->representation.string)
    {
      memcpy (buffer, source->representation.string,
	      source->representation.length);
      return source->representation.length;
    }

Paul Thomas committed
261 262 263 264 265 266 267 268 269
  switch (source->ts.type)
    {
    case BT_INTEGER:
      return encode_integer (source->ts.kind, source->value.integer, buffer,
			     buffer_size);
    case BT_REAL:
      return encode_float (source->ts.kind, source->value.real, buffer,
			   buffer_size);
    case BT_COMPLEX:
270
      return encode_complex (source->ts.kind, source->value.complex,
271
			     buffer, buffer_size);
Paul Thomas committed
272 273 274 275
    case BT_LOGICAL:
      return encode_logical (source->ts.kind, source->value.logical, buffer,
			     buffer_size);
    case BT_CHARACTER:
276
      if (source->expr_type == EXPR_CONSTANT || source->ref == NULL)
277 278 279 280
	return gfc_encode_character (source->ts.kind,
				     source->value.character.length,
				     source->value.character.string,
				     buffer, buffer_size);
281 282 283 284 285 286 287
      else
	{
	  int start, end;

	  gcc_assert (source->expr_type == EXPR_SUBSTRING);
	  gfc_extract_int (source->ref->u.ss.start, &start);
	  gfc_extract_int (source->ref->u.ss.end, &end);
288 289 290
	  return gfc_encode_character (source->ts.kind, MAX(end - start + 1, 0),
				       &source->value.character.string[start-1],
				       buffer, buffer_size);
291 292
	}

Paul Thomas committed
293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343
    case BT_DERIVED:
      return encode_derived (source, buffer, buffer_size);
    default:
      gfc_internal_error ("Invalid expression in gfc_target_encode_expr.");
      return 0;
    }
}


static int
interpret_array (unsigned char *buffer, size_t buffer_size, gfc_expr *result)
{
  int array_size = 1;
  int i;
  int ptr = 0;
  gfc_constructor *head = NULL, *tail = NULL;

  /* Calculate array size from its shape and rank.  */
  gcc_assert (result->rank > 0 && result->shape);

  for (i = 0; i < result->rank; i++)
    array_size *= (int)mpz_get_ui (result->shape[i]);

  /* Iterate over array elements, producing constructors.  */
  for (i = 0; i < array_size; i++)
    {
      if (head == NULL)
	head = tail = gfc_get_constructor ();
      else
	{
	  tail->next = gfc_get_constructor ();
	  tail = tail->next;
	}

      tail->where = result->where;
      tail->expr = gfc_constant_result (result->ts.type,
					  result->ts.kind, &result->where);
      tail->expr->ts = result->ts;

      if (tail->expr->ts.type == BT_CHARACTER)
	tail->expr->value.character.length = result->value.character.length;

      ptr += gfc_target_interpret_expr (&buffer[ptr], buffer_size - ptr,
					tail->expr);
    }
  result->value.constructor = head;

  return ptr;
}


344 345
int
gfc_interpret_integer (int kind, unsigned char *buffer, size_t buffer_size,
Paul Thomas committed
346 347 348 349 350 351 352 353 354 355
		   mpz_t integer)
{
  mpz_init (integer);
  gfc_conv_tree_to_mpz (integer,
			native_interpret_expr (gfc_get_int_type (kind),
					       buffer, buffer_size));
  return size_integer (kind);
}


356 357
int
gfc_interpret_float (int kind, unsigned char *buffer, size_t buffer_size,
358
		     mpfr_t real)
Paul Thomas committed
359
{
360
  gfc_set_model_kind (kind);
Paul Thomas committed
361 362 363 364 365 366 367 368 369
  mpfr_init (real);
  gfc_conv_tree_to_mpfr (real,
			 native_interpret_expr (gfc_get_real_type (kind),
						buffer, buffer_size));

  return size_float (kind);
}


370 371
int
gfc_interpret_complex (int kind, unsigned char *buffer, size_t buffer_size,
372
		       mpc_t complex)
Paul Thomas committed
373 374
{
  int size;
375
  size = gfc_interpret_float (kind, &buffer[0], buffer_size,
376
			      mpc_realref (complex));
377
  size += gfc_interpret_float (kind, &buffer[size], buffer_size - size,
378
			       mpc_imagref (complex));
Paul Thomas committed
379 380 381 382
  return size;
}


383 384
int
gfc_interpret_logical (int kind, unsigned char *buffer, size_t buffer_size,
Paul Thomas committed
385 386 387 388 389 390 391 392 393 394
		   int *logical)
{
  tree t = native_interpret_expr (gfc_get_logical_type (kind), buffer,
				  buffer_size);
  *logical = double_int_zero_p (tree_to_double_int (t))
	     ? 0 : 1;
  return size_logical (kind);
}


395
int
396 397
gfc_interpret_character (unsigned char *buffer, size_t buffer_size,
			 gfc_expr *result)
Paul Thomas committed
398
{
399 400
  int i;

401
  if (result->ts.u.cl && result->ts.u.cl->length)
Paul Thomas committed
402
    result->value.character.length =
403
      (int) mpz_get_ui (result->ts.u.cl->length->value.integer);
Paul Thomas committed
404

405 406
  gcc_assert (buffer_size >= size_character (result->value.character.length,
					     result->ts.kind));
Paul Thomas committed
407
  result->value.character.string =
408 409
    gfc_get_wide_string (result->value.character.length + 1);

410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431
  if (result->ts.kind == gfc_default_character_kind)
    for (i = 0; i < result->value.character.length; i++)
      result->value.character.string[i] = (gfc_char_t) buffer[i];
  else
    {
      mpz_t integer;
      unsigned bytes = size_character (1, result->ts.kind);
      mpz_init (integer);
      gcc_assert (bytes <= sizeof (unsigned long));

      for (i = 0; i < result->value.character.length; i++)
	{
	  gfc_conv_tree_to_mpz (integer,
	    native_interpret_expr (gfc_get_char_type (result->ts.kind),
				   &buffer[bytes*i], buffer_size-bytes*i));
	  result->value.character.string[i]
	    = (gfc_char_t) mpz_get_ui (integer);
	}

      mpz_clear (integer);
    }

432
  result->value.character.string[result->value.character.length] = '\0';
Paul Thomas committed
433 434 435 436 437

  return result->value.character.length;
}


438 439
int
gfc_interpret_derived (unsigned char *buffer, size_t buffer_size, gfc_expr *result)
Paul Thomas committed
440 441 442 443 444 445 446 447 448 449
{
  gfc_component *cmp;
  gfc_constructor *head = NULL, *tail = NULL;
  int ptr;
  tree type;

  /* The attributes of the derived type need to be bolted to the floor.  */
  result->expr_type = EXPR_STRUCTURE;

  type = gfc_typenode_for_spec (&result->ts);
450
  cmp = result->ts.u.derived->components;
Paul Thomas committed
451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510

  /* Run through the derived type components.  */
  for (;cmp; cmp = cmp->next)
    {
      if (head == NULL)
	head = tail = gfc_get_constructor ();
      else
	{
	  tail->next = gfc_get_constructor ();
	  tail = tail->next;
	}

      /* The constructor points to the component.  */
      tail->n.component = cmp;

      tail->expr = gfc_constant_result (cmp->ts.type, cmp->ts.kind,
					&result->where);
      tail->expr->ts = cmp->ts;

      /* Copy shape, if needed.  */
      if (cmp->as && cmp->as->rank)
	{
	  int n;

	  tail->expr->expr_type = EXPR_ARRAY;
	  tail->expr->rank = cmp->as->rank;

	  tail->expr->shape = gfc_get_shape (tail->expr->rank);
	  for (n = 0; n < tail->expr->rank; n++)
	     {
	       mpz_init_set_ui (tail->expr->shape[n], 1);
	       mpz_add (tail->expr->shape[n], tail->expr->shape[n],
			cmp->as->upper[n]->value.integer);
	       mpz_sub (tail->expr->shape[n], tail->expr->shape[n],
			cmp->as->lower[n]->value.integer);
	     }
	}

      ptr = TREE_INT_CST_LOW (DECL_FIELD_OFFSET (cmp->backend_decl));
      gfc_target_interpret_expr (&buffer[ptr], buffer_size - ptr,
				 tail->expr);

      result->value.constructor = head;
    }
    
  return int_size_in_bytes (type);
}


/* Read a binary buffer to a constant expression.  */
int
gfc_target_interpret_expr (unsigned char *buffer, size_t buffer_size,
			   gfc_expr *result)
{
  if (result->expr_type == EXPR_ARRAY)
    return interpret_array (buffer, buffer_size, result);

  switch (result->ts.type)
    {
    case BT_INTEGER:
511 512 513 514 515
      result->representation.length = 
        gfc_interpret_integer (result->ts.kind, buffer, buffer_size,
			       result->value.integer);
      break;

Paul Thomas committed
516
    case BT_REAL:
517 518 519 520 521
      result->representation.length = 
        gfc_interpret_float (result->ts.kind, buffer, buffer_size,
    			     result->value.real);
      break;

Paul Thomas committed
522
    case BT_COMPLEX:
523 524
      result->representation.length = 
        gfc_interpret_complex (result->ts.kind, buffer, buffer_size,
525
			       result->value.complex);
526 527
      break;

Paul Thomas committed
528
    case BT_LOGICAL:
529 530 531 532 533
      result->representation.length = 
        gfc_interpret_logical (result->ts.kind, buffer, buffer_size,
			       &result->value.logical);
      break;

Paul Thomas committed
534
    case BT_CHARACTER:
535 536 537 538
      result->representation.length = 
        gfc_interpret_character (buffer, buffer_size, result);
      break;

Paul Thomas committed
539
    case BT_DERIVED:
540 541 542 543
      result->representation.length = 
        gfc_interpret_derived (buffer, buffer_size, result);
      break;

Paul Thomas committed
544 545
    default:
      gfc_internal_error ("Invalid expression in gfc_target_interpret_expr.");
546 547 548 549
      break;
    }

  if (result->ts.type == BT_CHARACTER)
550 551 552
    result->representation.string
      = gfc_widechar_to_char (result->value.character.string,
			      result->value.character.length);
553 554 555
  else
    {
      result->representation.string =
556
        (char *) gfc_getmem (result->representation.length + 1);
557 558 559
      memcpy (result->representation.string, buffer,
	      result->representation.length);
      result->representation.string[result->representation.length] = '\0';
Paul Thomas committed
560
    }
561 562

  return result->representation.length;
Paul Thomas committed
563
}
564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592


/* --------------------------------------------------------------- */ 
/* Two functions used by trans-common.c to write overlapping
   equivalence initializers to a buffer.  This is added to the union
   and the original initializers freed.  */


/* Writes the values of a constant expression to a char buffer. If another
   unequal initializer has already been written to the buffer, this is an
   error.  */

static size_t
expr_to_char (gfc_expr *e, unsigned char *data, unsigned char *chk, size_t len)
{
  int i;
  int ptr;
  gfc_constructor *ctr;
  gfc_component *cmp;
  unsigned char *buffer;

  if (e == NULL)
    return 0;

  /* Take a derived type, one component at a time, using the offsets from the backend
     declaration.  */
  if (e->ts.type == BT_DERIVED)
    {
      ctr = e->value.constructor;
593
      cmp = e->ts.u.derived->components;
594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665
      for (;ctr; ctr = ctr->next, cmp = cmp->next)
	{
	  gcc_assert (cmp && cmp->backend_decl);
	  if (!ctr->expr)
	    continue;
	    ptr = TREE_INT_CST_LOW(DECL_FIELD_OFFSET(cmp->backend_decl))
			+ TREE_INT_CST_LOW(DECL_FIELD_BIT_OFFSET(cmp->backend_decl))/8;
	  expr_to_char (ctr->expr, &data[ptr], &chk[ptr], len);
	}
      return len;
    }

  /* Otherwise, use the target-memory machinery to write a bitwise image, appropriate
     to the target, in a buffer and check off the initialized part of the buffer.  */
  len = gfc_target_expr_size (e);
  buffer = (unsigned char*)alloca (len);
  len = gfc_target_encode_expr (e, buffer, len);

    for (i = 0; i < (int)len; i++)
    {
      if (chk[i] && (buffer[i] != data[i]))
	{
	  gfc_error ("Overlapping unequal initializers in EQUIVALENCE "
		     "at %L", &e->where);
	  return 0;
	}
      chk[i] = 0xFF;
    }

  memcpy (data, buffer, len);
  return len;
}


/* Writes the values from the equivalence initializers to a char* array
   that will be written to the constructor to make the initializer for
   the union declaration.  */

size_t
gfc_merge_initializers (gfc_typespec ts, gfc_expr *e, unsigned char *data,
			unsigned char *chk, size_t length)
{
  size_t len = 0;
  gfc_constructor * c;

  switch (e->expr_type)
    {
    case EXPR_CONSTANT:
    case EXPR_STRUCTURE:
      len = expr_to_char (e, &data[0], &chk[0], length);

      break;

    case EXPR_ARRAY:
      for (c = e->value.constructor; c; c = c->next)
	{
	  size_t elt_size = gfc_target_expr_size (c->expr);

	  if (c->n.offset)
	    len = elt_size * (size_t)mpz_get_si (c->n.offset);

	  len = len + gfc_merge_initializers (ts, c->expr, &data[len],
					      &chk[len], length - len);
	}
      break;

    default:
      return 0;
    }

  return len;
}
666

667 668 669 670 671

/* Transfer the bitpattern of a (integer) BOZ to real or complex variables.
   When successful, no BOZ or nothing to do, true is returned.  */

bool
672 673
gfc_convert_boz (gfc_expr *expr, gfc_typespec *ts)
{
674 675
  size_t buffer_size, boz_bit_size, ts_bit_size;
  int index;
676 677 678
  unsigned char *buffer;

  if (!expr->is_boz)
679
    return true;
680 681 682 683 684 685

  gcc_assert (expr->expr_type == EXPR_CONSTANT
	      && expr->ts.type == BT_INTEGER);

  /* Don't convert BOZ to logical, character, derived etc.  */
  if (ts->type == BT_REAL)
686 687 688 689
    {
      buffer_size = size_float (ts->kind);
      ts_bit_size = buffer_size * 8;
    }
690
  else if (ts->type == BT_COMPLEX)
691 692 693 694
    {
      buffer_size = size_complex (ts->kind);
      ts_bit_size = buffer_size * 8 / 2;
    }
695
  else
696 697 698 699
    return true;

  /* Convert BOZ to the smallest possible integer kind.  */
  boz_bit_size = mpz_sizeinbase (expr->value.integer, 2);
700

701 702 703 704 705 706 707 708
  if (boz_bit_size > ts_bit_size)
    {
      gfc_error_now ("BOZ constant at %L is too large (%ld vs %ld bits)",
		     &expr->where, (long) boz_bit_size, (long) ts_bit_size);
      return false;
    }

  for (index = 0; gfc_integer_kinds[index].kind != 0; ++index)
709 710
    if ((unsigned) gfc_integer_kinds[index].bit_size >= ts_bit_size)
      break;
711 712

  expr->ts.kind = gfc_integer_kinds[index].kind;
713 714 715 716 717 718 719 720 721 722 723 724 725
  buffer_size = MAX (buffer_size, size_integer (expr->ts.kind));

  buffer = (unsigned char*)alloca (buffer_size);
  encode_integer (expr->ts.kind, expr->value.integer, buffer, buffer_size);
  mpz_clear (expr->value.integer);

  if (ts->type == BT_REAL)
    {
      mpfr_init (expr->value.real);
      gfc_interpret_float (ts->kind, buffer, buffer_size, expr->value.real);
    }
  else
    {
726
      mpc_init2 (expr->value.complex, mpfr_get_default_prec());
727
      gfc_interpret_complex (ts->kind, buffer, buffer_size,
728
			     expr->value.complex);
729 730 731 732
    }
  expr->is_boz = 0;  
  expr->ts.type = ts->type;
  expr->ts.kind = ts->kind;
733 734

  return true;
735
}