LCOV - code coverage report
Current view: top level - gcc - attr-fnspec.h (source / functions) Coverage Total Hit
Test: gcc.info Lines: 93.2 % 88 82
Test Date: 2024-03-23 14:05:01 Functions: 92.3 % 13 12
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: - 0 0

             Branch data     Line data    Source code
       1                 :             : /* Handling of fnspec attribute specifiers
       2                 :             :    Copyright (C) 2008-2024 Free Software Foundation, Inc.
       3                 :             :    Contributed by Richard Guenther  <rguenther@suse.de>
       4                 :             : 
       5                 :             :    This file is part of GCC.
       6                 :             : 
       7                 :             :    GCC is free software; you can redistribute it and/or modify
       8                 :             :    under the terms of the GNU General Public License as published by
       9                 :             :    the Free Software Foundation; either version 3 of the License, or
      10                 :             :    (at your option) any later version.
      11                 :             : 
      12                 :             :    GCC is distributed in the hope that it will be useful,
      13                 :             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
      14                 :             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      15                 :             :    GNU General Public License 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                 :             : /* Parse string of attribute "fn spec".  This is an internal attribute
      22                 :             :    describing side effects of a function as follows:
      23                 :             : 
      24                 :             :    character 0  specifies properties of return values as follows:
      25                 :             :      '1'...'4'  specifies number of argument function returns (as in memset)
      26                 :             :      'm'        specifies that returned value is noalias (as in malloc)
      27                 :             :      '.'        specifies that nothing is known.
      28                 :             :    character 1  specifies additional function properties
      29                 :             :      ' '        specifies that nothing is known
      30                 :             :      'p' or 'P' specifies that function is pure except for described side
      31                 :             :                 effects.
      32                 :             :      'c' or 'C' specifies that function is const except for described side
      33                 :             :                 effects.
      34                 :             :    The uppercase letter in addition specifies that function clobbers errno.
      35                 :             : 
      36                 :             :    character 2+2i specifies properties of argument number i as follows:
      37                 :             :      'x' or 'X' specifies that parameter is unused.
      38                 :             :      'r' or 'R' specifies that the memory pointed to by the parameter is only
      39                 :             :                 read and does not escape
      40                 :             :      'o' or 'O' specifies that the memory pointed to by the parameter is only
      41                 :             :                 written and does not escape
      42                 :             :      'w' or 'W' specifies that the memory pointed to by the parameter does not
      43                 :             :                 escape
      44                 :             :      '1'....'9' specifies that the memory pointed to by the parameter is
      45                 :             :                 copied to memory pointed to by different parameter
      46                 :             :                 (as in memcpy).
      47                 :             :      '.'        specifies that nothing is known.
      48                 :             :    The uppercase letter in addition specifies that the memory pointed to
      49                 :             :    by the parameter is not dereferenced.  For 'r' only read applies
      50                 :             :    transitively to pointers read from the pointed-to memory.
      51                 :             : 
      52                 :             :    character 3+2i specifies additional properties of argument number i
      53                 :             :    as follows:
      54                 :             :      ' '        nothing is known
      55                 :             :      't'        the size of value written/read corresponds to the size of
      56                 :             :                 of the pointed-to type of the argument type
      57                 :             :      '1'...'9'  specifies the size of value written/read is bound by the
      58                 :             :                 specified argument
      59                 :             :  */
      60                 :             : 
      61                 :             : #ifndef ATTR_FNSPEC_H
      62                 :             : #define ATTR_FNSPEC_H
      63                 :             : 
      64                 :             : class attr_fnspec
      65                 :             : {
      66                 :             : private:
      67                 :             :   /* fn spec attribute string.  */
      68                 :             :   const char *str;
      69                 :             :   /* length of the fn spec string.  */
      70                 :             :   const unsigned len;
      71                 :             :   /* Number of characters specifying return value.  */
      72                 :             :   const unsigned int return_desc_size = 2;
      73                 :             :   /* Number of characters specifying size.  */
      74                 :             :   const unsigned int arg_desc_size = 2;
      75                 :             : 
      76                 :             :   /* Return start of specifier of arg i.  */
      77                 :   701178391 :   unsigned int arg_idx (int i)
      78                 :             :   {
      79                 :   279806929 :     return return_desc_size + arg_desc_size * i;
      80                 :             :   }
      81                 :             : 
      82                 :             : public:
      83                 :     2338785 :   attr_fnspec (const char *str, unsigned len)
      84                 :     2338785 :   : str (str), len (len)
      85                 :             :   {
      86                 :     2338785 :     if (flag_checking)
      87                 :     2338785 :       verify ();
      88                 :             :   }
      89                 :   280764834 :   attr_fnspec (const char *str)
      90                 :   280764834 :   : str (str), len (strlen (str))
      91                 :             :   {
      92                 :   280764834 :     if (flag_checking)
      93                 :   280763767 :       verify ();
      94                 :   280764834 :   }
      95                 :    49044335 :   attr_fnspec (const_tree identifier)
      96                 :    49044335 :   : str (TREE_STRING_POINTER (identifier)),
      97                 :    49044335 :     len (TREE_STRING_LENGTH (identifier))
      98                 :             :   {
      99                 :    49044335 :     if (flag_checking)
     100                 :    49044335 :       verify ();
     101                 :    49044335 :   }
     102                 :             :   attr_fnspec ()
     103                 :             :   : str (NULL), len (0)
     104                 :             :   {
     105                 :             :   }
     106                 :             : 
     107                 :             :   /* Return true if fn spec is known.  */
     108                 :             :   bool
     109                 :   252579096 :   known_p ()
     110                 :             :   {
     111                 :   252579096 :     return len;
     112                 :             :   }
     113                 :             : 
     114                 :             :   /* Return true if arg I is specified.  */
     115                 :             :   bool
     116                 :   484233391 :   arg_specified_p (unsigned int i)
     117                 :             :   {
     118                 :   453835489 :     return len >= arg_idx (i + 1);
     119                 :             :   }
     120                 :             : 
     121                 :             :   /* True if the argument is not dereferenced recursively, thus only
     122                 :             :      directly reachable memory is read or written.  */
     123                 :             :   bool
     124                 :     9463433 :   arg_direct_p (unsigned int i)
     125                 :             :   {
     126                 :     9463433 :     unsigned int idx = arg_idx (i);
     127                 :     9463433 :     gcc_checking_assert (arg_specified_p (i));
     128                 :     9463433 :     return str[idx] == 'R' || str[idx] == 'O'
     129                 :     9463433 :            || str[idx] == 'W' || (str[idx] >= '1' && str[idx] <= '9');
     130                 :             :   }
     131                 :             : 
     132                 :             :   /* True if argument is used.  */
     133                 :             :   bool
     134                 :     9576114 :   arg_used_p (unsigned int i)
     135                 :             :   {
     136                 :     9576114 :     unsigned int idx = arg_idx (i);
     137                 :     9576114 :     gcc_checking_assert (arg_specified_p (i));
     138                 :     9576114 :     return str[idx] != 'x' && str[idx] != 'X';
     139                 :             :   }
     140                 :             : 
     141                 :             :   /* True if memory reached by the argument is readonly (not clobbered).  */
     142                 :             :   bool
     143                 :     9552369 :   arg_readonly_p (unsigned int i)
     144                 :             :   {
     145                 :     9552369 :     unsigned int idx = arg_idx (i);
     146                 :     9552369 :     gcc_checking_assert (arg_specified_p (i));
     147                 :     9552369 :     return str[idx] == 'r' || str[idx] == 'R' || (str[idx] >= '1' && str[idx] <= '9');
     148                 :             :   }
     149                 :             : 
     150                 :             :   /* True if memory reached by the argument is read (directly or indirectly)  */
     151                 :             :   bool
     152                 :     3227024 :   arg_maybe_read_p (unsigned int i)
     153                 :             :   {
     154                 :     3227024 :     unsigned int idx = arg_idx (i);
     155                 :     3227024 :     gcc_checking_assert (arg_specified_p (i));
     156                 :     3227024 :     return str[idx] != 'o' && str[idx] != 'O'
     157                 :     3227024 :            && str[idx] != 'x' && str[idx] != 'X';
     158                 :             :   }
     159                 :             : 
     160                 :             :   /* True if memory reached by the argument is written.
     161                 :             :      (directly or indirectly)  */
     162                 :             :   bool
     163                 :    22106049 :   arg_maybe_written_p (unsigned int i)
     164                 :             :   {
     165                 :    22106049 :     unsigned int idx = arg_idx (i);
     166                 :    22106049 :     gcc_checking_assert (arg_specified_p (i));
     167                 :    22106049 :     return str[idx] != 'r' && str[idx] != 'R'
     168                 :    22098411 :            && (str[idx] < '1' || str[idx] > '9')
     169                 :    36079016 :            && str[idx] != 'x' && str[idx] != 'X';
     170                 :             :   }
     171                 :             : 
     172                 :             :   /* Return true if load of memory pointed to by argument I is bound
     173                 :             :      by another argument.  In this case set ARG.  */
     174                 :             :   bool
     175                 :    15069758 :   arg_max_access_size_given_by_arg_p (unsigned int i, unsigned int *arg)
     176                 :             :   {
     177                 :    15069758 :     unsigned int idx = arg_idx (i);
     178                 :    15069758 :     gcc_checking_assert (arg_specified_p (i));
     179                 :    15069758 :     if (str[idx + 1] >= '1' && str[idx + 1] <= '9')
     180                 :             :       {
     181                 :    10665431 :         *arg = str[idx + 1] - '1';
     182                 :    10665431 :         return true;
     183                 :             :       }
     184                 :             :     else
     185                 :             :       return false;
     186                 :             :   }
     187                 :             : 
     188                 :             :   /* Return true if the pointed-to type of the argument correspond to the
     189                 :             :      size of the memory acccess.  */
     190                 :             :   bool
     191                 :     4404327 :   arg_access_size_given_by_type_p (unsigned int i)
     192                 :             :   {
     193                 :     4404327 :     unsigned int idx = arg_idx (i);
     194                 :     4404327 :     gcc_checking_assert (arg_specified_p (i));
     195                 :     4404327 :     return str[idx + 1] == 't';
     196                 :             :   }
     197                 :             : 
     198                 :             :   /* Return true if memory pointer to by argument is copied to a memory
     199                 :             :      pointed to by a different argument (as in memcpy).
     200                 :             :      In this case set ARG.  */
     201                 :             :   bool
     202                 :           0 :   arg_copied_to_arg_p (unsigned int i, unsigned int *arg)
     203                 :             :   {
     204                 :           0 :     unsigned int idx = arg_idx (i);
     205                 :           0 :     gcc_checking_assert (arg_specified_p (i));
     206                 :           0 :     if (str[idx] < '1' || str[idx] > '9')
     207                 :             :       return false;
     208                 :           0 :     *arg = str[idx] - '1';
     209                 :           0 :     return true;
     210                 :             :   }
     211                 :             : 
     212                 :             : 
     213                 :             :   /* True if the argument does not escape.  */
     214                 :             :   bool
     215                 :     9463433 :   arg_noescape_p (unsigned int i)
     216                 :             :   {
     217                 :     9463433 :     unsigned int idx = arg_idx (i);
     218                 :     9463433 :     gcc_checking_assert (arg_specified_p (i));
     219                 :     9463433 :     return str[idx] == 'w' || str[idx] == 'W'
     220                 :             :            || str[idx] == 'r' || str[idx] == 'R'
     221                 :     9463433 :            || str[idx] == 'o' || str[idx] == 'O';
     222                 :             :   }
     223                 :             : 
     224                 :             :   /* Return true if function returns value of its parameter.  If ARG_NO is
     225                 :             :      non-NULL return initialize it to the argument returned.  */
     226                 :             :   bool
     227                 :    73364383 :   returns_arg (unsigned int *arg_no)
     228                 :             :   {
     229                 :    73364383 :     if (str[0] >= '1' && str[0] <= '4')
     230                 :             :       {
     231                 :     2233828 :         if (arg_no)
     232                 :     2233828 :           *arg_no = str[0] - '1';
     233                 :     2233828 :         return true;
     234                 :             :       }
     235                 :             :     return false;
     236                 :             :   }
     237                 :             : 
     238                 :             :   /* Nonzero if the return value does not alias with anything.  Functions
     239                 :             :      with the malloc attribute have this set on their return value.  */
     240                 :             :   bool
     241                 :             :   returns_noalias_p ()
     242                 :             :   {
     243                 :             :     return str[0] == 'm';
     244                 :             :   }
     245                 :             : 
     246                 :             :   /* Return true if all memory read by the function is specified by fnspec.  */
     247                 :             :   bool
     248                 :    10646194 :   global_memory_read_p ()
     249                 :             :   {
     250                 :    10646194 :     return str[1] != 'c' && str[1] != 'C';
     251                 :             :   }
     252                 :             : 
     253                 :             :   /* Return true if all memory written by the function
     254                 :             :      is specified by fnspec.  */
     255                 :             :   bool
     256                 :    56179871 :   global_memory_written_p ()
     257                 :             :   {
     258                 :    56179871 :     return str[1] != 'c' && str[1] != 'C' && str[1] != 'p' && str[1] != 'P';
     259                 :             :   }
     260                 :             : 
     261                 :             :   bool
     262                 :    17641348 :   errno_maybe_written_p ()
     263                 :             :   {
     264                 :    17641348 :     return str[1] == 'C' || str[1] == 'P';
     265                 :             :   }
     266                 :             : 
     267                 :             :   /* Return EAF flags for arg I.  */
     268                 :             :   int
     269                 :    19548209 :   arg_eaf_flags (unsigned int i)
     270                 :             :   {
     271                 :    19548209 :     int flags = 0;
     272                 :             : 
     273                 :    19548209 :     if (!arg_specified_p (i))
     274                 :             :       ;
     275                 :     9576114 :     else if (!arg_used_p (i))
     276                 :             :       flags = EAF_UNUSED;
     277                 :             :     else
     278                 :             :       {
     279                 :     9463433 :         if (arg_direct_p (i))
     280                 :     4988431 :           flags |= EAF_NO_INDIRECT_READ | EAF_NO_INDIRECT_ESCAPE
     281                 :             :                    | EAF_NOT_RETURNED_INDIRECTLY | EAF_NO_INDIRECT_CLOBBER;
     282                 :     9463433 :         if (arg_noescape_p (i))
     283                 :     7392959 :           flags |= EAF_NO_DIRECT_ESCAPE | EAF_NO_INDIRECT_ESCAPE;
     284                 :     9463433 :         if (arg_readonly_p (i))
     285                 :     4685570 :           flags |= EAF_NO_DIRECT_CLOBBER | EAF_NO_INDIRECT_CLOBBER;
     286                 :             :       }
     287                 :    19548209 :     return flags;
     288                 :             :   }
     289                 :             : 
     290                 :             :   /* Check validity of the string.  */
     291                 :             :   void verify ();
     292                 :             : 
     293                 :             :   /* Return the fnspec string.  */
     294                 :             :   const char *
     295                 :             :   get_str ()
     296                 :             :   {
     297                 :             :     return str;
     298                 :             :   }
     299                 :             : };
     300                 :             : 
     301                 :             : extern attr_fnspec gimple_call_fnspec (const gcall *stmt);
     302                 :             : extern attr_fnspec builtin_fnspec (tree);
     303                 :             : 
     304                 :             : #endif /* ATTR_FNSPEC_H  */
        

Generated by: LCOV version 2.0-1

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.