LCOV - code coverage report
Current view: top level - gcc/fortran - target-memory.cc (source / functions) Coverage Total Hit
Test: gcc.info Lines: 96.4 % 394 380
Test Date: 2024-04-20 14:03:02 Functions: 96.2 % 26 25
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: - 0 0

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

Generated by: LCOV version 2.1-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.