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: 2026-02-28 14:20:25 Functions: 92.3 % 13 12
Legend: Lines:     hit not hit

            Line data    Source code
       1              : /* Handling of fnspec attribute specifiers
       2              :    Copyright (C) 2008-2026 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    971274823 :   unsigned int arg_idx (int i) const
      78              :   {
      79    391187573 :     return return_desc_size + arg_desc_size * i;
      80              :   }
      81              : 
      82              : public:
      83      2740122 :   attr_fnspec (const char *str, unsigned len)
      84      2740122 :   : str (str), len (len)
      85              :   {
      86      2740122 :     if (flag_checking)
      87      2740122 :       verify ();
      88              :   }
      89    380485125 :   attr_fnspec (const char *str)
      90    380485125 :   : str (str), len (strlen (str))
      91              :   {
      92    380485125 :     if (flag_checking)
      93    380484104 :       verify ();
      94    380485125 :   }
      95     60451086 :   attr_fnspec (const_tree identifier)
      96     60451086 :   : str (TREE_STRING_POINTER (identifier)),
      97     60451086 :     len (TREE_STRING_LENGTH (identifier))
      98              :   {
      99     60451086 :     if (flag_checking)
     100     60451086 :       verify ();
     101     60451086 :   }
     102              :   attr_fnspec ()
     103              :   : str (NULL), len (0)
     104              :   {
     105              :   }
     106              : 
     107              :   /* Return true if fn spec is known.  */
     108              :   bool
     109    355109990 :   known_p () const
     110              :   {
     111    355109990 :     return len;
     112              :   }
     113              : 
     114              :   /* Return true if arg I is specified.  */
     115              :   bool
     116    685319566 :   arg_specified_p (unsigned int i) const
     117              :   {
     118    633474748 :     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     15594369 :   arg_direct_p (unsigned int i) const
     125              :   {
     126     15594369 :     unsigned int idx = arg_idx (i);
     127     15594369 :     gcc_checking_assert (arg_specified_p (i));
     128     15594369 :     return str[idx] == 'R' || str[idx] == 'O'
     129     15594369 :            || str[idx] == 'W' || (str[idx] >= '1' && str[idx] <= '9');
     130              :   }
     131              : 
     132              :   /* True if argument is used.  */
     133              :   bool
     134     15723611 :   arg_used_p (unsigned int i) const
     135              :   {
     136     15723611 :     unsigned int idx = arg_idx (i);
     137     15723611 :     gcc_checking_assert (arg_specified_p (i));
     138     15723611 :     return str[idx] != 'x' && str[idx] != 'X';
     139              :   }
     140              : 
     141              :   /* True if memory reached by the argument is readonly (not clobbered).  */
     142              :   bool
     143     15699786 :   arg_readonly_p (unsigned int i) const
     144              :   {
     145     15699786 :     unsigned int idx = arg_idx (i);
     146     15699786 :     gcc_checking_assert (arg_specified_p (i));
     147     15699786 :     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      8737830 :   arg_maybe_read_p (unsigned int i) const
     153              :   {
     154      8737830 :     unsigned int idx = arg_idx (i);
     155      8737830 :     gcc_checking_assert (arg_specified_p (i));
     156      8737830 :     return str[idx] != 'o' && str[idx] != 'O'
     157      8737830 :            && 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     34535628 :   arg_maybe_written_p (unsigned int i) const
     164              :   {
     165     34535628 :     unsigned int idx = arg_idx (i);
     166     34535628 :     gcc_checking_assert (arg_specified_p (i));
     167     34535628 :     return str[idx] != 'r' && str[idx] != 'R'
     168     34527610 :            && (str[idx] < '1' || str[idx] > '9')
     169     56925615 :            && 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     23809221 :   arg_max_access_size_given_by_arg_p (unsigned int i, unsigned int *arg) const
     176              :   {
     177     23809221 :     unsigned int idx = arg_idx (i);
     178     23809221 :     gcc_checking_assert (arg_specified_p (i));
     179     23809221 :     if (str[idx + 1] >= '1' && str[idx + 1] <= '9')
     180              :       {
     181     15890375 :         *arg = str[idx + 1] - '1';
     182     15890375 :         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      7918846 :   arg_access_size_given_by_type_p (unsigned int i) const
     192              :   {
     193      7918846 :     unsigned int idx = arg_idx (i);
     194      7918846 :     gcc_checking_assert (arg_specified_p (i));
     195      7918846 :     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) const
     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     15594369 :   arg_noescape_p (unsigned int i) const
     216              :   {
     217     15594369 :     unsigned int idx = arg_idx (i);
     218     15594369 :     gcc_checking_assert (arg_specified_p (i));
     219     15594369 :     return str[idx] == 'w' || str[idx] == 'W'
     220              :            || str[idx] == 'r' || str[idx] == 'R'
     221     15594369 :            || 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     81527018 :   returns_arg (unsigned int *arg_no) const
     228              :   {
     229     81527018 :     if (str[0] >= '1' && str[0] <= '4')
     230              :       {
     231      2719053 :         if (arg_no)
     232      2719053 :           *arg_no = str[0] - '1';
     233      2719053 :         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 () const
     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     20424704 :   global_memory_read_p () const
     249              :   {
     250     20424704 :     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     72158586 :   global_memory_written_p () const
     257              :   {
     258     72158586 :     return str[1] != 'c' && str[1] != 'C' && str[1] != 'p' && str[1] != 'P';
     259              :   }
     260              : 
     261              :   bool
     262     26072440 :   errno_maybe_written_p () const
     263              :   {
     264     26072440 :     return str[1] == 'C' || str[1] == 'P';
     265              :   }
     266              : 
     267              :   /* Return EAF flags for arg I.  */
     268              :   int
     269     29839427 :   arg_eaf_flags (unsigned int i) const
     270              :   {
     271     29839427 :     int flags = 0;
     272              : 
     273     29839427 :     if (!arg_specified_p (i))
     274              :       ;
     275     15723611 :     else if (!arg_used_p (i))
     276              :       flags = EAF_UNUSED;
     277              :     else
     278              :       {
     279     15594369 :         if (arg_direct_p (i))
     280      7797694 :           flags |= EAF_NO_INDIRECT_READ | EAF_NO_INDIRECT_ESCAPE
     281              :                    | EAF_NOT_RETURNED_INDIRECTLY | EAF_NO_INDIRECT_CLOBBER;
     282     15594369 :         if (arg_noescape_p (i))
     283     12237506 :           flags |= EAF_NO_DIRECT_ESCAPE | EAF_NO_INDIRECT_ESCAPE;
     284     15594369 :         if (arg_readonly_p (i))
     285      7288840 :           flags |= EAF_NO_DIRECT_CLOBBER | EAF_NO_INDIRECT_CLOBBER;
     286              :       }
     287     29839427 :     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 () const
     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.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.