LCOV - code coverage report
Current view: top level - gcc/fortran - target-memory.cc (source / functions) Coverage Total Hit
Test: gcc.info Lines: 95.3 % 401 382
Test Date: 2026-02-28 14:20:25 Functions: 100.0 % 27 27
Legend: Lines:     hit not hit

            Line data    Source code
       1              : /* Simulate storage of variables into target memory.
       2              :    Copyright (C) 2007-2026 Free Software Foundation, Inc.
       3              :    Contributed by Paul Thomas and Brooks Moses
       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              : #include "config.h"
      22              : #include "system.h"
      23              : #include "coretypes.h"
      24              : #include "tree.h"
      25              : #include "gfortran.h"
      26              : #include "trans.h"
      27              : #include "fold-const.h"
      28              : #include "stor-layout.h"
      29              : #include "arith.h"
      30              : #include "constructor.h"
      31              : #include "trans-const.h"
      32              : #include "trans-types.h"
      33              : #include "target-memory.h"
      34              : 
      35              : /* --------------------------------------------------------------- */
      36              : /* Calculate the size of an expression.  */
      37              : 
      38              : 
      39              : static size_t
      40         4110 : size_integer (int kind)
      41              : {
      42         4110 :   return GET_MODE_SIZE (SCALAR_INT_TYPE_MODE (gfc_get_int_type (kind)));
      43              : }
      44              : 
      45              : static size_t
      46            6 : size_unsigned (int kind)
      47              : {
      48            6 :   return GET_MODE_SIZE (SCALAR_INT_TYPE_MODE (gfc_get_unsigned_type (kind)));
      49              : }
      50              : 
      51              : static size_t
      52         3899 : size_float (int kind)
      53              : {
      54         3899 :   return GET_MODE_SIZE (SCALAR_FLOAT_TYPE_MODE (gfc_get_real_type (kind)));
      55              : }
      56              : 
      57              : 
      58              : static size_t
      59          725 : size_complex (int kind)
      60              : {
      61            0 :   return 2 * size_float (kind);
      62              : }
      63              : 
      64              : 
      65              : static size_t
      66          953 : size_logical (int kind)
      67              : {
      68          953 :   return GET_MODE_SIZE (SCALAR_INT_TYPE_MODE (gfc_get_logical_type (kind)));
      69              : }
      70              : 
      71              : 
      72              : static size_t
      73       293779 : size_character (gfc_charlen_t length, int kind)
      74              : {
      75       293779 :   int i = gfc_validate_kind (BT_CHARACTER, kind, false);
      76       293779 :   return length * gfc_character_kinds[i].bit_size / 8;
      77              : }
      78              : 
      79              : 
      80              : /* Return the size of a single element of the given expression.
      81              :    Equivalent to gfc_target_expr_size for scalars.  */
      82              : 
      83              : bool
      84         6388 : gfc_element_size (gfc_expr *e, size_t *siz)
      85              : {
      86         6388 :   tree type;
      87              : 
      88         6388 :   switch (e->ts.type)
      89              :     {
      90         2542 :     case BT_INTEGER:
      91         2542 :       *siz = size_integer (e->ts.kind);
      92         2542 :       return true;
      93            6 :     case BT_UNSIGNED:
      94            6 :       *siz = size_unsigned (e->ts.kind);
      95            6 :       return true;
      96         1064 :     case BT_REAL:
      97         1064 :       *siz = size_float (e->ts.kind);
      98         1064 :       return true;
      99          725 :     case BT_COMPLEX:
     100          725 :       *siz = size_complex (e->ts.kind);
     101          725 :       return true;
     102          512 :     case BT_LOGICAL:
     103          512 :       *siz = size_logical (e->ts.kind);
     104          512 :       return true;
     105         1248 :     case BT_CHARACTER:
     106         1248 :       if (e->expr_type == EXPR_CONSTANT)
     107          706 :         *siz = size_character (e->value.character.length, e->ts.kind);
     108          542 :       else if (e->ts.u.cl != NULL && e->ts.u.cl->length != NULL
     109          515 :                && e->ts.u.cl->length->expr_type == EXPR_CONSTANT
     110          515 :                && e->ts.u.cl->length->ts.type == BT_INTEGER)
     111              :         {
     112          515 :           HOST_WIDE_INT length;
     113              : 
     114          515 :           gfc_extract_hwi (e->ts.u.cl->length, &length);
     115          515 :           *siz = size_character (length, e->ts.kind);
     116          515 :         }
     117              :       else
     118              :         {
     119           27 :           *siz = 0;
     120           27 :           return false;
     121              :         }
     122              :       return true;
     123              : 
     124            7 :     case BT_HOLLERITH:
     125            7 :       *siz = e->representation.length;
     126            7 :       return true;
     127          284 :     case BT_DERIVED:
     128          284 :     case BT_CLASS:
     129          284 :     case BT_VOID:
     130          284 :     case BT_ASSUMED:
     131          284 :     case BT_PROCEDURE:
     132          284 :       {
     133              :         /* Determine type size without clobbering the typespec for ISO C
     134              :            binding types.  */
     135          284 :         gfc_typespec ts;
     136          284 :         HOST_WIDE_INT size;
     137          284 :         ts = e->ts;
     138          284 :         type = gfc_typenode_for_spec (&ts);
     139          284 :         size = int_size_in_bytes (type);
     140          284 :         gcc_assert (size >= 0);
     141          284 :         *siz = size;
     142              :       }
     143          284 :       return true;
     144            0 :     default:
     145            0 :       gfc_internal_error ("Invalid expression in gfc_element_size.");
     146              :       *siz = 0;
     147              :       return false;
     148              :     }
     149              : }
     150              : 
     151              : 
     152              : /* Return the size of an expression in its target representation.  */
     153              : 
     154              : bool
     155         4141 : gfc_target_expr_size (gfc_expr *e, size_t *size)
     156              : {
     157         4141 :   mpz_t tmp;
     158         4141 :   size_t asz, el_size;
     159              : 
     160         4141 :   gcc_assert (e != NULL);
     161              : 
     162         4141 :   *size = 0;
     163         4141 :   if (e->rank)
     164              :     {
     165          409 :       if (gfc_array_size (e, &tmp))
     166          409 :         asz = mpz_get_ui (tmp);
     167              :       else
     168              :         return false;
     169              : 
     170          409 :       mpz_clear (tmp);
     171              :     }
     172              :   else
     173              :     asz = 1;
     174              : 
     175         4141 :   if (!gfc_element_size (e, &el_size))
     176              :     return false;
     177         4140 :   *size = asz * el_size;
     178         4140 :   return true;
     179              : }
     180              : 
     181              : 
     182              : /* The encode_* functions export a value into a buffer, and
     183              :    return the number of bytes of the buffer that have been
     184              :    used.  */
     185              : 
     186              : static unsigned HOST_WIDE_INT
     187          222 : encode_array (gfc_expr *expr, unsigned char *buffer, size_t buffer_size)
     188              : {
     189          222 :   mpz_t array_size;
     190          222 :   int i;
     191          222 :   int ptr = 0;
     192              : 
     193          222 :   gfc_constructor_base ctor = expr->value.constructor;
     194              : 
     195          222 :   gfc_array_size (expr, &array_size);
     196          909 :   for (i = 0; i < (int)mpz_get_ui (array_size); i++)
     197              :     {
     198          453 :       ptr += gfc_target_encode_expr (gfc_constructor_lookup_expr (ctor, i),
     199          453 :                                      &buffer[ptr], buffer_size - ptr);
     200              :     }
     201              : 
     202          222 :   mpz_clear (array_size);
     203          222 :   return ptr;
     204              : }
     205              : 
     206              : 
     207              : static int
     208          670 : encode_integer (int kind, mpz_t integer, unsigned char *buffer,
     209              :                 size_t buffer_size)
     210              : {
     211          670 :   return native_encode_expr (gfc_conv_mpz_to_tree (integer, kind),
     212          670 :                              buffer, buffer_size);
     213              : }
     214              : 
     215              : 
     216              : static int
     217           92 : encode_float (int kind, mpfr_t real, unsigned char *buffer, size_t buffer_size)
     218              : {
     219           92 :   return native_encode_expr (gfc_conv_mpfr_to_tree (real, kind, 0), buffer,
     220           92 :                              buffer_size);
     221              : }
     222              : 
     223              : 
     224              : static int
     225           18 : encode_complex (int kind, mpc_t cmplx,
     226              :                 unsigned char *buffer, size_t buffer_size)
     227              : {
     228           18 :   int size;
     229           18 :   size = encode_float (kind, mpc_realref (cmplx), &buffer[0], buffer_size);
     230           36 :   size += encode_float (kind, mpc_imagref (cmplx),
     231           18 :                         &buffer[size], buffer_size - size);
     232           18 :   return size;
     233              : }
     234              : 
     235              : 
     236              : static int
     237           23 : encode_logical (int kind, int logical, unsigned char *buffer, size_t buffer_size)
     238              : {
     239           23 :   return native_encode_expr (build_int_cst (gfc_get_logical_type (kind),
     240           23 :                                             logical),
     241           23 :                              buffer, buffer_size);
     242              : }
     243              : 
     244              : 
     245              : size_t
     246       145369 : gfc_encode_character (int kind, size_t length, const gfc_char_t *string,
     247              :                       unsigned char *buffer, size_t buffer_size)
     248              : {
     249       145369 :   size_t elsize = size_character (1, kind);
     250       145369 :   tree type = gfc_get_char_type (kind);
     251              : 
     252       145369 :   gcc_assert (buffer_size >= size_character (length, kind));
     253              : 
     254      2094986 :   for (size_t i = 0; i < length; i++)
     255      1949617 :     native_encode_expr (build_int_cst (type, string[i]), &buffer[i*elsize],
     256              :                         elsize);
     257              : 
     258       145369 :   return length;
     259              : }
     260              : 
     261              : 
     262              : static unsigned HOST_WIDE_INT
     263            4 : encode_derived (gfc_expr *source, unsigned char *buffer, size_t buffer_size)
     264              : {
     265            4 :   gfc_constructor *c;
     266            4 :   gfc_component *cmp;
     267            4 :   int ptr;
     268            4 :   tree type;
     269            4 :   HOST_WIDE_INT size;
     270              : 
     271            4 :   type = gfc_typenode_for_spec (&source->ts);
     272              : 
     273            4 :   for (c = gfc_constructor_first (source->value.constructor),
     274            4 :        cmp = source->ts.u.derived->components;
     275            9 :        c;
     276            5 :        c = gfc_constructor_next (c), cmp = cmp->next)
     277              :     {
     278            5 :       gcc_assert (cmp);
     279            5 :       if (!c->expr)
     280            0 :         continue;
     281            5 :       ptr = TREE_INT_CST_LOW(DECL_FIELD_OFFSET(cmp->backend_decl))
     282            5 :             + TREE_INT_CST_LOW(DECL_FIELD_BIT_OFFSET(cmp->backend_decl))/8;
     283              : 
     284            5 :       if (c->expr->expr_type == EXPR_NULL)
     285              :         {
     286            1 :           size = int_size_in_bytes (TREE_TYPE (cmp->backend_decl));
     287            1 :           gcc_assert (size >= 0);
     288            1 :           memset (&buffer[ptr], 0, size);
     289              :         }
     290              :       else
     291            4 :         gfc_target_encode_expr (c->expr, &buffer[ptr],
     292            4 :                                 buffer_size - ptr);
     293              :     }
     294              : 
     295            4 :   size = int_size_in_bytes (type);
     296            4 :   gcc_assert (size >= 0);
     297            4 :   return size;
     298              : }
     299              : 
     300              : 
     301              : /* Write a constant expression in binary form to a buffer.  */
     302              : unsigned HOST_WIDE_INT
     303         1507 : gfc_target_encode_expr (gfc_expr *source, unsigned char *buffer,
     304              :                         size_t buffer_size)
     305              : {
     306         1507 :   if (source == NULL)
     307              :     return 0;
     308              : 
     309         1507 :   if (source->expr_type == EXPR_ARRAY)
     310          222 :     return encode_array (source, buffer, buffer_size);
     311              : 
     312         1285 :   gcc_assert (source->expr_type == EXPR_CONSTANT
     313              :               || source->expr_type == EXPR_STRUCTURE
     314              :               || source->expr_type == EXPR_SUBSTRING);
     315              : 
     316              :   /* If we already have a target-memory representation, we use that rather
     317              :      than recreating one.  */
     318         1285 :   if (source->representation.string)
     319              :     {
     320          114 :       memcpy (buffer, source->representation.string,
     321          114 :               source->representation.length);
     322          114 :       return source->representation.length;
     323              :     }
     324              : 
     325         1171 :   switch (source->ts.type)
     326              :     {
     327          413 :     case BT_INTEGER:
     328          413 :       return encode_integer (source->ts.kind, source->value.integer, buffer,
     329          413 :                              buffer_size);
     330           56 :     case BT_REAL:
     331           56 :       return encode_float (source->ts.kind, source->value.real, buffer,
     332           56 :                            buffer_size);
     333           18 :     case BT_COMPLEX:
     334           18 :       return encode_complex (source->ts.kind, source->value.complex,
     335           18 :                              buffer, buffer_size);
     336           23 :     case BT_LOGICAL:
     337           23 :       return encode_logical (source->ts.kind, source->value.logical, buffer,
     338           23 :                              buffer_size);
     339          654 :     case BT_CHARACTER:
     340          654 :       if (source->expr_type == EXPR_CONSTANT || source->ref == NULL)
     341          624 :         return gfc_encode_character (source->ts.kind,
     342          624 :                                      source->value.character.length,
     343          624 :                                      source->value.character.string,
     344          624 :                                      buffer, buffer_size);
     345              :       else
     346              :         {
     347           30 :           HOST_WIDE_INT start, end;
     348              : 
     349           30 :           gcc_assert (source->expr_type == EXPR_SUBSTRING);
     350           30 :           gfc_extract_hwi (source->ref->u.ss.start, &start);
     351           30 :           gfc_extract_hwi (source->ref->u.ss.end, &end);
     352           30 :           return gfc_encode_character (source->ts.kind, MAX(end - start + 1, 0),
     353           30 :                                        &source->value.character.string[start-1],
     354              :                                        buffer, buffer_size);
     355              :         }
     356              : 
     357            7 :     case BT_DERIVED:
     358            7 :       if (source->ts.u.derived->ts.f90_type == BT_VOID)
     359              :         {
     360            3 :           gfc_constructor *c;
     361            3 :           gcc_assert (source->expr_type == EXPR_STRUCTURE);
     362            3 :           c = gfc_constructor_first (source->value.constructor);
     363            3 :           gcc_assert (c->expr->expr_type == EXPR_CONSTANT
     364              :                       && c->expr->ts.type == BT_INTEGER);
     365            3 :           return encode_integer (gfc_index_integer_kind, c->expr->value.integer,
     366            3 :                                  buffer, buffer_size);
     367              :         }
     368              : 
     369            4 :       return encode_derived (source, buffer, buffer_size);
     370            0 :     default:
     371            0 :       gfc_internal_error ("Invalid expression in gfc_target_encode_expr.");
     372              :       return 0;
     373              :     }
     374              : }
     375              : 
     376              : 
     377              : static size_t
     378          275 : interpret_array (unsigned char *buffer, size_t buffer_size, gfc_expr *result,
     379              :                  bool convert_widechar)
     380              : {
     381          275 :   gfc_constructor_base base = NULL;
     382          275 :   size_t array_size = 1;
     383          275 :   size_t ptr = 0;
     384              : 
     385              :   /* Calculate array size from its shape and rank.  */
     386          275 :   gcc_assert (result->rank > 0 && result->shape);
     387              : 
     388          550 :   for (int i = 0; i < result->rank; i++)
     389          310 :     array_size *= mpz_get_ui (result->shape[i]);
     390              : 
     391              :   /* Iterate over array elements, producing constructors.  */
     392         1036 :   for (size_t i = 0; i < array_size; i++)
     393              :     {
     394          761 :       gfc_expr *e = gfc_get_constant_expr (result->ts.type, result->ts.kind,
     395              :                                            &result->where);
     396          761 :       e->ts = result->ts;
     397              : 
     398          761 :       if (e->ts.type == BT_CHARACTER)
     399          464 :         e->value.character.length = result->value.character.length;
     400              : 
     401          761 :       gfc_constructor_append_expr (&base, e, &result->where);
     402              : 
     403          761 :       ptr += gfc_target_interpret_expr (&buffer[ptr], buffer_size - ptr, e,
     404              :                                         convert_widechar);
     405              :     }
     406              : 
     407          275 :   result->value.constructor = base;
     408          275 :   return ptr;
     409              : }
     410              : 
     411              : 
     412              : int
     413         1060 : gfc_interpret_integer (int kind, unsigned char *buffer, size_t buffer_size,
     414              :                    mpz_t integer)
     415              : {
     416         1060 :   mpz_init (integer);
     417         1060 :   gfc_conv_tree_to_mpz (integer,
     418              :                         native_interpret_expr (gfc_get_int_type (kind),
     419              :                                                buffer, buffer_size));
     420         1060 :   return size_integer (kind);
     421              : }
     422              : 
     423              : 
     424              : int
     425         1856 : gfc_interpret_float (int kind, unsigned char *buffer, size_t buffer_size,
     426              :                      mpfr_t real)
     427              : {
     428         1856 :   gfc_set_model_kind (kind);
     429              : 
     430         1856 :   tree source = native_interpret_expr (gfc_get_real_type (kind), buffer,
     431              :                                        buffer_size);
     432         1856 :   if (!source)
     433              :     return 0;
     434              : 
     435         1856 :   mpfr_init (real);
     436         1856 :   gfc_conv_tree_to_mpfr (real, source);
     437         1856 :   return size_float (kind);
     438              : }
     439              : 
     440              : 
     441              : int
     442          492 : gfc_interpret_complex (int kind, unsigned char *buffer, size_t buffer_size,
     443              :                        mpc_t complex)
     444              : {
     445          492 :   int size;
     446          984 :   size = gfc_interpret_float (kind, &buffer[0], buffer_size,
     447          492 :                               mpc_realref (complex));
     448          984 :   size += gfc_interpret_float (kind, &buffer[size], buffer_size - size,
     449          492 :                                mpc_imagref (complex));
     450          492 :   return size;
     451              : }
     452              : 
     453              : 
     454              : int
     455          441 : gfc_interpret_logical (int kind, unsigned char *buffer, size_t buffer_size,
     456              :                    int *logical)
     457              : {
     458          441 :   tree t = native_interpret_expr (gfc_get_logical_type (kind), buffer,
     459              :                                   buffer_size);
     460          441 :   *logical = wi::to_wide (t) == 0 ? 0 : 1;
     461          441 :   return size_logical (kind);
     462              : }
     463              : 
     464              : 
     465              : size_t
     466          688 : gfc_interpret_character (unsigned char *buffer, size_t buffer_size,
     467              :                          gfc_expr *result)
     468              : {
     469          688 :   if (result->ts.u.cl && result->ts.u.cl->length)
     470          688 :     result->value.character.length =
     471          688 :       gfc_mpz_get_hwi (result->ts.u.cl->length->value.integer);
     472              : 
     473          688 :   gcc_assert (buffer_size >= size_character (result->value.character.length,
     474              :                                              result->ts.kind));
     475         1376 :   result->value.character.string =
     476          688 :     gfc_get_wide_string (result->value.character.length + 1);
     477              : 
     478          688 :   if (result->ts.kind == gfc_default_character_kind)
     479          789 :     for (size_t i = 0; i < (size_t) result->value.character.length; i++)
     480          545 :       result->value.character.string[i] = (gfc_char_t) buffer[i];
     481              :   else
     482              :     {
     483          444 :       mpz_t integer;
     484          444 :       size_t bytes = size_character (1, result->ts.kind);
     485          444 :       mpz_init (integer);
     486          444 :       gcc_assert (bytes <= sizeof (unsigned long));
     487              : 
     488         1346 :       for (size_t i = 0; i < (size_t) result->value.character.length; i++)
     489              :         {
     490          902 :           gfc_conv_tree_to_mpz (integer,
     491              :             native_interpret_expr (gfc_get_char_type (result->ts.kind),
     492          902 :                                    &buffer[bytes*i], buffer_size-bytes*i));
     493          902 :           result->value.character.string[i]
     494          902 :             = (gfc_char_t) mpz_get_ui (integer);
     495              :         }
     496              : 
     497          444 :       mpz_clear (integer);
     498              :     }
     499              : 
     500          688 :   result->value.character.string[result->value.character.length] = '\0';
     501              : 
     502          688 :   return size_character (result->value.character.length, result->ts.kind);
     503              : }
     504              : 
     505              : 
     506              : int
     507           31 : gfc_interpret_derived (unsigned char *buffer, size_t buffer_size, gfc_expr *result)
     508              : {
     509           31 :   gfc_component *cmp;
     510           31 :   int ptr;
     511           31 :   tree type;
     512              : 
     513              :   /* The attributes of the derived type need to be bolted to the floor.  */
     514           31 :   result->expr_type = EXPR_STRUCTURE;
     515              : 
     516           31 :   cmp = result->ts.u.derived->components;
     517              : 
     518           31 :   if (result->ts.u.derived->from_intmod == INTMOD_ISO_C_BINDING
     519           15 :       && (result->ts.u.derived->intmod_sym_id == ISOCBINDING_PTR
     520            1 :           || result->ts.u.derived->intmod_sym_id == ISOCBINDING_FUNPTR))
     521              :     {
     522           15 :       gfc_constructor *c;
     523           15 :       gfc_expr *e;
     524              :       /* Needed as gfc_typenode_for_spec as gfc_typenode_for_spec
     525              :          sets this to BT_INTEGER.  */
     526           15 :       result->ts.type = BT_DERIVED;
     527           15 :       e = gfc_get_constant_expr (cmp->ts.type, cmp->ts.kind, &result->where);
     528           15 :       c = gfc_constructor_append_expr (&result->value.constructor, e, NULL);
     529           15 :       c->n.component = cmp;
     530           15 :       gfc_target_interpret_expr (buffer, buffer_size, e, true);
     531           15 :       e->ts.is_iso_c = 1;
     532           15 :       return int_size_in_bytes (ptr_type_node);
     533              :     }
     534              : 
     535           16 :   type = gfc_typenode_for_spec (&result->ts);
     536              : 
     537              :   /* Run through the derived type components.  */
     538           52 :   for (;cmp; cmp = cmp->next)
     539              :     {
     540           42 :       gfc_constructor *c;
     541           42 :       gfc_expr *e = gfc_get_constant_expr (cmp->ts.type, cmp->ts.kind,
     542              :                                            &result->where);
     543           42 :       e->ts = cmp->ts;
     544              : 
     545              :       /* Copy shape, if needed.  */
     546           42 :       if (cmp->as && cmp->as->rank)
     547              :         {
     548            8 :           int n;
     549              : 
     550            8 :           if (cmp->as->type != AS_EXPLICIT)
     551              :             return 0;
     552              : 
     553            2 :           e->expr_type = EXPR_ARRAY;
     554            2 :           e->rank = cmp->as->rank;
     555              : 
     556            2 :           e->shape = gfc_get_shape (e->rank);
     557            4 :           for (n = 0; n < e->rank; n++)
     558              :              {
     559            2 :                mpz_init_set_ui (e->shape[n], 1);
     560            2 :                mpz_add (e->shape[n], e->shape[n],
     561            2 :                         cmp->as->upper[n]->value.integer);
     562            2 :                mpz_sub (e->shape[n], e->shape[n],
     563            2 :                         cmp->as->lower[n]->value.integer);
     564              :              }
     565              :         }
     566              : 
     567           36 :       c = gfc_constructor_append_expr (&result->value.constructor, e, NULL);
     568              : 
     569              :       /* The constructor points to the component.  */
     570           36 :       c->n.component = cmp;
     571              : 
     572              :       /* Calculate the offset, which consists of the FIELD_OFFSET in
     573              :          bytes, which appears in multiples of DECL_OFFSET_ALIGN-bit-sized,
     574              :          and additional bits of FIELD_BIT_OFFSET. The code assumes that all
     575              :          sizes of the components are multiples of BITS_PER_UNIT,
     576              :          i.e. there are, e.g., no bit fields.  */
     577              : 
     578           36 :       gcc_assert (cmp->backend_decl);
     579           36 :       ptr = TREE_INT_CST_LOW (DECL_FIELD_BIT_OFFSET (cmp->backend_decl));
     580           36 :       gcc_assert (ptr % 8 == 0);
     581           36 :       ptr = ptr/8 + TREE_INT_CST_LOW (DECL_FIELD_OFFSET (cmp->backend_decl));
     582              : 
     583           36 :       gcc_assert (e->ts.type != BT_VOID || cmp->attr.caf_token);
     584           36 :       gfc_target_interpret_expr (&buffer[ptr], buffer_size - ptr, e, true);
     585              :     }
     586              : 
     587           10 :   return int_size_in_bytes (type);
     588              : }
     589              : 
     590              : 
     591              : /* Read a binary buffer to a constant expression.  */
     592              : size_t
     593         1671 : gfc_target_interpret_expr (unsigned char *buffer, size_t buffer_size,
     594              :                            gfc_expr *result, bool convert_widechar)
     595              : {
     596         1671 :   if (result->expr_type == EXPR_ARRAY)
     597          275 :     return interpret_array (buffer, buffer_size, result, convert_widechar);
     598              : 
     599         1396 :   switch (result->ts.type)
     600              :     {
     601          496 :     case BT_INTEGER:
     602          992 :       result->representation.length =
     603          992 :         gfc_interpret_integer (result->ts.kind, buffer, buffer_size,
     604          496 :                                result->value.integer);
     605          496 :       break;
     606              : 
     607          104 :     case BT_REAL:
     608          208 :       result->representation.length =
     609          208 :         gfc_interpret_float (result->ts.kind, buffer, buffer_size,
     610          104 :                              result->value.real);
     611          104 :       break;
     612              : 
     613           17 :     case BT_COMPLEX:
     614           34 :       result->representation.length =
     615           34 :         gfc_interpret_complex (result->ts.kind, buffer, buffer_size,
     616           17 :                                result->value.complex);
     617           17 :       break;
     618              : 
     619           60 :     case BT_LOGICAL:
     620          120 :       result->representation.length =
     621           60 :         gfc_interpret_logical (result->ts.kind, buffer, buffer_size,
     622              :                                &result->value.logical);
     623           60 :       break;
     624              : 
     625          688 :     case BT_CHARACTER:
     626         1376 :       result->representation.length =
     627          688 :         gfc_interpret_character (buffer, buffer_size, result);
     628          688 :       break;
     629              : 
     630            0 :     case BT_CLASS:
     631            0 :       result->ts = CLASS_DATA (result)->ts;
     632              :       /* Fall through.  */
     633           31 :     case BT_DERIVED:
     634           62 :       result->representation.length =
     635           31 :         gfc_interpret_derived (buffer, buffer_size, result);
     636           31 :       gcc_assert (result->representation.length >= 0);
     637              :       break;
     638              : 
     639            0 :     case BT_VOID:
     640              :       /* This deals with caf_tokens.  */
     641            0 :       result->representation.length =
     642            0 :         gfc_interpret_integer (result->ts.kind, buffer, buffer_size,
     643            0 :                                result->value.integer);
     644            0 :       break;
     645              : 
     646            0 :     default:
     647            0 :       gfc_internal_error ("Invalid expression in gfc_target_interpret_expr.");
     648         1396 :       break;
     649              :     }
     650              : 
     651         1396 :   if (result->ts.type == BT_CHARACTER && convert_widechar)
     652            0 :     result->representation.string
     653            0 :       = gfc_widechar_to_char (result->value.character.string,
     654            0 :                               result->value.character.length);
     655              :   else
     656              :     {
     657         2792 :       result->representation.string =
     658         1396 :         XCNEWVEC (char, result->representation.length + 1);
     659         1396 :       memcpy (result->representation.string, buffer,
     660         1396 :               result->representation.length);
     661         1396 :       result->representation.string[result->representation.length] = '\0';
     662              :     }
     663              : 
     664         1396 :   return result->representation.length;
     665              : }
     666              : 
     667              : 
     668              : /* --------------------------------------------------------------- */
     669              : /* Two functions used by trans-common.cc to write overlapping
     670              :    equivalence initializers to a buffer.  This is added to the union
     671              :    and the original initializers freed.  */
     672              : 
     673              : 
     674              : /* Writes the values of a constant expression to a char buffer. If another
     675              :    unequal initializer has already been written to the buffer, this is an
     676              :    error.  */
     677              : 
     678              : static size_t
     679          206 : expr_to_char (gfc_expr *e, locus *loc,
     680              :               unsigned char *data, unsigned char *chk, size_t len)
     681              : {
     682          206 :   int i;
     683          206 :   int ptr;
     684          206 :   gfc_constructor *c;
     685          206 :   gfc_component *cmp;
     686          206 :   unsigned char *buffer;
     687              : 
     688          206 :   if (e == NULL)
     689              :     return 0;
     690              : 
     691              :   /* Take a derived type, one component at a time, using the offsets from the backend
     692              :      declaration.  */
     693          206 :   if (e->ts.type == BT_DERIVED)
     694              :     {
     695           15 :       for (c = gfc_constructor_first (e->value.constructor),
     696           15 :            cmp = e->ts.u.derived->components;
     697           54 :            c; c = gfc_constructor_next (c), cmp = cmp->next)
     698              :         {
     699           39 :           gcc_assert (cmp && cmp->backend_decl);
     700           39 :           if (!c->expr)
     701           12 :             continue;
     702           27 :           ptr = TREE_INT_CST_LOW(DECL_FIELD_OFFSET(cmp->backend_decl))
     703           27 :             + TREE_INT_CST_LOW(DECL_FIELD_BIT_OFFSET(cmp->backend_decl))/8;
     704           27 :           expr_to_char (c->expr, loc, &data[ptr], &chk[ptr], len);
     705              :         }
     706           15 :       return len;
     707              :     }
     708              : 
     709              :   /* Otherwise, use the target-memory machinery to write a bitwise image, appropriate
     710              :      to the target, in a buffer and check off the initialized part of the buffer.  */
     711          191 :   gfc_target_expr_size (e, &len);
     712          191 :   buffer = (unsigned char*)alloca (len);
     713          191 :   len = gfc_target_encode_expr (e, buffer, len);
     714              : 
     715         1009 :   for (i = 0; i < (int)len; i++)
     716              :     {
     717          821 :       if (chk[i] && (buffer[i] != data[i]))
     718              :         {
     719            3 :           if (loc)
     720            3 :             gfc_error ("Overlapping unequal initializers in EQUIVALENCE "
     721              :                         "at %L", loc);
     722              :           else
     723            0 :             gfc_error ("Overlapping unequal initializers in EQUIVALENCE "
     724              :                         "at %C");
     725            3 :           return 0;
     726              :         }
     727          818 :       chk[i] = 0xFF;
     728              :     }
     729              : 
     730          188 :   memcpy (data, buffer, len);
     731          188 :   return len;
     732              : }
     733              : 
     734              : 
     735              : /* Writes the values from the equivalence initializers to a char* array
     736              :    that will be written to the constructor to make the initializer for
     737              :    the union declaration.  */
     738              : 
     739              : size_t
     740          239 : gfc_merge_initializers (gfc_typespec ts, gfc_expr *e, locus *loc,
     741              :                         unsigned char *data,
     742              :                         unsigned char *chk, size_t length)
     743              : {
     744          239 :   size_t len = 0;
     745          239 :   gfc_constructor * c;
     746              : 
     747          239 :   switch (e->expr_type)
     748              :     {
     749          179 :     case EXPR_CONSTANT:
     750          179 :     case EXPR_STRUCTURE:
     751          179 :       len = expr_to_char (e, loc, &data[0], &chk[0], length);
     752          179 :       break;
     753              : 
     754           60 :     case EXPR_ARRAY:
     755           60 :       for (c = gfc_constructor_first (e->value.constructor);
     756          203 :            c; c = gfc_constructor_next (c))
     757              :         {
     758          143 :           size_t elt_size;
     759              : 
     760          143 :           gfc_target_expr_size (c->expr, &elt_size);
     761              : 
     762          143 :           if (mpz_cmp_si (c->offset, 0) != 0)
     763           83 :             len = elt_size * (size_t)mpz_get_si (c->offset);
     764              : 
     765          143 :           len = len + gfc_merge_initializers (ts, c->expr, loc, &data[len],
     766              :                                               &chk[len], length - len);
     767              :         }
     768              :       break;
     769              : 
     770              :     default:
     771              :       return 0;
     772              :     }
     773              : 
     774              :   return len;
     775              : }
     776              : 
     777              : 
     778              : /* Transfer the bitpattern of a (integer) BOZ to real or complex variables.
     779              :    When successful, no BOZ or nothing to do, true is returned.  */
     780              : 
     781              : bool
     782          254 : gfc_convert_boz (gfc_expr *expr, gfc_typespec *ts)
     783              : {
     784          254 :   size_t buffer_size, boz_bit_size, ts_bit_size;
     785          254 :   int index;
     786          254 :   unsigned char *buffer;
     787              : 
     788          254 :   if (expr->ts.type != BT_INTEGER)
     789              :     return true;
     790              : 
     791              :   /* Don't convert BOZ to logical, character, derived etc.  */
     792          254 :   gcc_assert (ts->type == BT_REAL);
     793              : 
     794          254 :   buffer_size = size_float (ts->kind);
     795          254 :   ts_bit_size = buffer_size * 8;
     796              : 
     797              :   /* Convert BOZ to the smallest possible integer kind.  */
     798          254 :   boz_bit_size = mpz_sizeinbase (expr->value.integer, 2);
     799              : 
     800          254 :   gcc_assert (boz_bit_size <= ts_bit_size);
     801              : 
     802          880 :   for (index = 0; gfc_integer_kinds[index].kind != 0; ++index)
     803          880 :     if ((unsigned) gfc_integer_kinds[index].bit_size >= ts_bit_size)
     804              :       break;
     805              : 
     806          254 :   expr->ts.kind = gfc_integer_kinds[index].kind;
     807          254 :   buffer_size = MAX (buffer_size, size_integer (expr->ts.kind));
     808              : 
     809          254 :   buffer = (unsigned char*)alloca (buffer_size);
     810          254 :   encode_integer (expr->ts.kind, expr->value.integer, buffer, buffer_size);
     811          254 :   mpz_clear (expr->value.integer);
     812              : 
     813          254 :   mpfr_init (expr->value.real);
     814          254 :   gfc_interpret_float (ts->kind, buffer, buffer_size, expr->value.real);
     815              : 
     816          254 :   expr->ts.type = ts->type;
     817          254 :   expr->ts.kind = ts->kind;
     818              : 
     819          254 :   return true;
     820              : }
        

Generated by: LCOV version 2.4-beta

LCOV profile is generated on x86_64 machine using following configure options: configure --disable-bootstrap --enable-coverage=opt --enable-languages=c,c++,fortran,go,jit,lto,rust,m2 --enable-host-shared. GCC test suite is run with the built compiler.