LCOV - code coverage report
Current view: top level - gcc/rust/checks/errors - rust-readonly-check.cc (source / functions) Coverage Total Hit
Test: gcc.info Lines: 76.9 % 39 30
Test Date: 2024-04-27 14:03:13 Functions: 100.0 % 4 4
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: - 0 0

             Branch data     Line data    Source code
       1                 :             : // Copyright (C) 2021-2024 Free Software Foundation, Inc.
       2                 :             : 
       3                 :             : // This file is part of GCC.
       4                 :             : 
       5                 :             : // GCC is free software; you can redistribute it and/or modify it under
       6                 :             : // the terms of the GNU General Public License as published by the Free
       7                 :             : // Software Foundation; either version 3, or (at your option) any later
       8                 :             : // version.
       9                 :             : 
      10                 :             : // GCC is distributed in the hope that it will be useful, but WITHOUT ANY
      11                 :             : // WARRANTY; without even the implied warranty of MERCHANTABILITY or
      12                 :             : // FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
      13                 :             : // for more details.
      14                 :             : 
      15                 :             : // You should have received a copy of the GNU General Public License
      16                 :             : // along with GCC; see the file COPYING3.  If not see
      17                 :             : // <http://www.gnu.org/licenses/>.
      18                 :             : 
      19                 :             : #include "rust-readonly-check.h"
      20                 :             : #include "rust-tree.h"
      21                 :             : #include "rust-gcc.h"
      22                 :             : 
      23                 :             : namespace Rust {
      24                 :             : namespace Analysis {
      25                 :             : 
      26                 :             : // ported over from c-family/c-warn.cc
      27                 :             : void
      28                 :           2 : readonly_error (location_t loc, tree arg, enum lvalue_use use)
      29                 :             : {
      30                 :           2 :   gcc_assert (use == lv_assign || use == lv_increment || use == lv_decrement
      31                 :             :               || use == lv_asm);
      32                 :           2 :   STRIP_ANY_LOCATION_WRAPPER (arg);
      33                 :             :   /* Using this macro rather than (for example) arrays of messages
      34                 :             :      ensures that all the format strings are checked at compile
      35                 :             :      time.  */
      36                 :             : #define READONLY_MSG(A, I, D, AS)                                              \
      37                 :             :   (use == lv_assign                                                            \
      38                 :             :      ? (A)                                                                     \
      39                 :             :      : (use == lv_increment ? (I) : (use == lv_decrement ? (D) : (AS))))
      40                 :           2 :   if (TREE_CODE (arg) == COMPONENT_REF)
      41                 :             :     {
      42                 :           0 :       if (TYPE_READONLY (TREE_TYPE (TREE_OPERAND (arg, 0))))
      43                 :           0 :         error_at (loc,
      44                 :             :                   READONLY_MSG (G_ ("assignment of member "
      45                 :             :                                     "%qD in read-only object"),
      46                 :             :                                 G_ ("increment of member "
      47                 :             :                                     "%qD in read-only object"),
      48                 :             :                                 G_ ("decrement of member "
      49                 :             :                                     "%qD in read-only object"),
      50                 :             :                                 G_ ("member %qD in read-only object "
      51                 :             :                                     "used as %<asm%> output")),
      52                 :           0 :                   TREE_OPERAND (arg, 1));
      53                 :             :       else
      54                 :           0 :         error_at (
      55                 :             :           loc,
      56                 :             :           READONLY_MSG (G_ ("assignment of read-only member %qD"),
      57                 :             :                         G_ ("increment of read-only member %qD"),
      58                 :             :                         G_ ("decrement of read-only member %qD"),
      59                 :             :                         G_ ("read-only member %qD used as %<asm%> output")),
      60                 :           0 :           TREE_OPERAND (arg, 1));
      61                 :             :     }
      62                 :             :   else if (VAR_P (arg))
      63                 :           0 :     error_at (loc,
      64                 :             :               READONLY_MSG (G_ ("assignment of read-only variable %qD"),
      65                 :             :                             G_ ("increment of read-only variable %qD"),
      66                 :             :                             G_ ("decrement of read-only variable %qD"),
      67                 :             :                             G_ (
      68                 :             :                               "read-only variable %qD used as %<asm%> output")),
      69                 :             :               arg);
      70                 :             :   else if (TREE_CODE (arg) == PARM_DECL)
      71                 :           0 :     error_at (loc,
      72                 :             :               READONLY_MSG (G_ ("assignment of read-only parameter %qD"),
      73                 :             :                             G_ ("increment of read-only parameter %qD"),
      74                 :             :                             G_ ("decrement of read-only parameter %qD"),
      75                 :             :                             G_ (
      76                 :             :                               "read-only parameter %qD use as %<asm%> output")),
      77                 :             :               arg);
      78                 :             :   else if (TREE_CODE (arg) == RESULT_DECL)
      79                 :             :     {
      80                 :           0 :       error_at (loc,
      81                 :             :                 READONLY_MSG (G_ ("assignment of "
      82                 :             :                                   "read-only named return value %qD"),
      83                 :             :                               G_ ("increment of "
      84                 :             :                                   "read-only named return value %qD"),
      85                 :             :                               G_ ("decrement of "
      86                 :             :                                   "read-only named return value %qD"),
      87                 :             :                               G_ ("read-only named return value %qD "
      88                 :             :                                   "used as %<asm%>output")),
      89                 :             :                 arg);
      90                 :             :     }
      91                 :             :   else if (TREE_CODE (arg) == FUNCTION_DECL)
      92                 :           0 :     error_at (loc,
      93                 :             :               READONLY_MSG (G_ ("assignment of function %qD"),
      94                 :             :                             G_ ("increment of function %qD"),
      95                 :             :                             G_ ("decrement of function %qD"),
      96                 :             :                             G_ ("function %qD used as %<asm%> output")),
      97                 :             :               arg);
      98                 :             :   else
      99                 :           4 :     error_at (loc,
     100                 :             :               READONLY_MSG (G_ ("assignment of read-only location %qE"),
     101                 :             :                             G_ ("increment of read-only location %qE"),
     102                 :             :                             G_ ("decrement of read-only location %qE"),
     103                 :             :                             G_ (
     104                 :             :                               "read-only location %qE used as %<asm%> output")),
     105                 :             :               arg);
     106                 :           2 : }
     107                 :             : 
     108                 :             : static void
     109                 :       22489 : check_decl (tree *t)
     110                 :             : {
     111                 :       22489 :   if (TREE_CODE (*t) == MODIFY_EXPR)
     112                 :             :     {
     113                 :       15401 :       tree lhs = TREE_OPERAND (*t, 0);
     114                 :       15401 :       if (TREE_READONLY (lhs) || TREE_CONSTANT (lhs))
     115                 :             :         {
     116                 :           2 :           readonly_error (EXPR_LOCATION (*t), lhs, lv_assign);
     117                 :           2 :           TREE_OPERAND (*t, 0) = error_mark_node;
     118                 :             :         }
     119                 :             :     }
     120                 :       22489 : }
     121                 :             : 
     122                 :             : static tree
     123                 :      217521 : readonly_walk_fn (tree *t, int *, void *)
     124                 :             : {
     125                 :      217521 :   switch (TREE_CODE (*t))
     126                 :             :     {
     127                 :       15401 :     case MODIFY_EXPR:
     128                 :       15401 :       check_decl (t);
     129                 :       15401 :       break;
     130                 :             : 
     131                 :             :     default:
     132                 :             :       break;
     133                 :             :     }
     134                 :      217521 :   return NULL_TREE;
     135                 :             : }
     136                 :             : 
     137                 :             : void
     138                 :        3279 : ReadonlyCheck::Lint (Compile::Context &ctx)
     139                 :             : {
     140                 :       12761 :   for (auto &fndecl : ctx.get_func_decls ())
     141                 :             :     {
     142                 :       16084 :       for (tree p = DECL_ARGUMENTS (fndecl); p != NULL_TREE; p = DECL_CHAIN (p))
     143                 :             :         {
     144                 :        6602 :           check_decl (&p);
     145                 :             :         }
     146                 :             : 
     147                 :        9482 :       walk_tree_without_duplicates (&DECL_SAVED_TREE (fndecl),
     148                 :             :                                     &readonly_walk_fn, &ctx);
     149                 :             :     }
     150                 :             : 
     151                 :        3317 :   for (auto &var : ctx.get_var_decls ())
     152                 :             :     {
     153                 :          38 :       tree decl = var->get_decl ();
     154                 :          38 :       check_decl (&decl);
     155                 :             :     }
     156                 :             : 
     157                 :        3727 :   for (auto &const_decl : ctx.get_const_decls ())
     158                 :             :     {
     159                 :         448 :       check_decl (&const_decl);
     160                 :             :     }
     161                 :        3279 : }
     162                 :             : 
     163                 :             : } // namespace Analysis
     164                 :             : } // namespace Rust
        

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.