LCOV - code coverage report
Current view: top level - gcc/analyzer - write-to-const-diagnostics.cc (source / functions) Coverage Total Hit
Test: gcc.info Lines: 100.0 % 57 57
Test Date: 2026-05-11 19:44:49 Functions: 100.0 % 10 10
Legend: Lines:     hit not hit

            Line data    Source code
       1              : /* Implementation of write_to_const_diagnostic and
       2              :    write_to_string_literal_diagnostic.
       3              :    Copyright (C) 2020-2026 Free Software Foundation, Inc.
       4              :    Contributed by David Malcolm <dmalcolm@redhat.com>.
       5              : 
       6              : This file is part of GCC.
       7              : 
       8              : GCC is free software; you can redistribute it and/or modify it
       9              : under the terms of the GNU General Public License as published by
      10              : the Free Software Foundation; either version 3, or (at your option)
      11              : any later version.
      12              : 
      13              : GCC is distributed in the hope that it will be useful, but
      14              : WITHOUT ANY WARRANTY; without even the implied warranty of
      15              : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      16              : General Public License for more details.
      17              : 
      18              : You should have received a copy of the GNU General Public License
      19              : along with GCC; see the file COPYING3.  If not see
      20              : <http://www.gnu.org/licenses/>.  */
      21              : 
      22              : #include "analyzer/common.h"
      23              : 
      24              : #include "analyzer/region-model.h"
      25              : 
      26              : #if ENABLE_ANALYZER
      27              : 
      28              : namespace ana {
      29              : 
      30              : /* A subclass of pending_diagnostic for complaining about writes to
      31              :    constant regions of memory.  */
      32              : 
      33              : class write_to_const_diagnostic
      34              : : public pending_diagnostic_subclass<write_to_const_diagnostic>
      35              : {
      36              : public:
      37           33 :   write_to_const_diagnostic (const region *reg, tree decl)
      38           33 :   : m_reg (reg), m_decl (decl)
      39              :   {}
      40              : 
      41          421 :   const char *get_kind () const final override
      42              :   {
      43          421 :     return "write_to_const_diagnostic";
      44              :   }
      45              : 
      46           33 :   bool operator== (const write_to_const_diagnostic &other) const
      47              :   {
      48           33 :     return (m_reg == other.m_reg
      49           33 :             && m_decl == other.m_decl);
      50              :   }
      51              : 
      52           66 :   int get_controlling_option () const final override
      53              :   {
      54           66 :     return OPT_Wanalyzer_write_to_const;
      55              :   }
      56              : 
      57           33 :   bool emit (diagnostic_emission_context &ctxt) final override
      58              :   {
      59           33 :     auto_diagnostic_group d;
      60           33 :     bool warned;
      61           33 :     switch (m_reg->get_kind ())
      62              :       {
      63           20 :       default:
      64           20 :         warned = ctxt.warn ("write to %<const%> object %qE", m_decl);
      65           20 :         break;
      66            9 :       case RK_FUNCTION:
      67            9 :         warned = ctxt.warn ("write to function %qE", m_decl);
      68            9 :         break;
      69            4 :       case RK_LABEL:
      70            4 :         warned = ctxt.warn ("write to label %qE", m_decl);
      71            4 :         break;
      72              :       }
      73           33 :     if (warned)
      74           33 :       inform (DECL_SOURCE_LOCATION (m_decl), "declared here");
      75           66 :     return warned;
      76           33 :   }
      77              : 
      78              :   bool
      79           66 :   describe_final_event (pretty_printer &pp,
      80              :                         const evdesc::final_event &) final override
      81              :   {
      82           66 :     switch (m_reg->get_kind ())
      83              :       {
      84           40 :       default:
      85           40 :         {
      86           40 :           pp_printf (&pp,
      87              :                      "write to %<const%> object %qE here", m_decl);
      88           40 :           return true;
      89              :         }
      90           18 :       case RK_FUNCTION:
      91           18 :         {
      92           18 :           pp_printf (&pp,
      93              :                      "write to function %qE here", m_decl);
      94           18 :           return true;
      95              :         }
      96            8 :       case RK_LABEL:
      97            8 :         {
      98            8 :           pp_printf (&pp,
      99              :                      "write to label %qE here", m_decl);
     100            8 :           return true;
     101              :         }
     102              :       }
     103              :   }
     104              : 
     105              : private:
     106              :   const region *m_reg;
     107              :   tree m_decl;
     108              : };
     109              : 
     110              : std::unique_ptr<pending_diagnostic>
     111           33 : make_write_to_const_diagnostic (const region *dest_reg, tree decl)
     112              : {
     113           33 :   return std::make_unique<write_to_const_diagnostic> (dest_reg, decl);
     114              : }
     115              : 
     116              : /* A subclass of pending_diagnostic for complaining about writes to
     117              :    string literals.  */
     118              : 
     119              : class write_to_string_literal_diagnostic
     120              : : public pending_diagnostic_subclass<write_to_string_literal_diagnostic>
     121              : {
     122              : public:
     123           51 :   write_to_string_literal_diagnostic (const region *reg)
     124           51 :   : m_reg (reg)
     125              :   {}
     126              : 
     127          337 :   const char *get_kind () const final override
     128              :   {
     129          337 :     return "write_to_string_literal_diagnostic";
     130              :   }
     131              : 
     132           47 :   bool operator== (const write_to_string_literal_diagnostic &other) const
     133              :   {
     134           47 :     return m_reg == other.m_reg;
     135              :   }
     136              : 
     137           94 :   int get_controlling_option () const final override
     138              :   {
     139           94 :     return OPT_Wanalyzer_write_to_string_literal;
     140              :   }
     141              : 
     142           43 :   bool emit (diagnostic_emission_context &ctxt) final override
     143              :   {
     144           43 :     return ctxt.warn ("write to string literal");
     145              :     /* Ideally we would show the location of the STRING_CST as well,
     146              :        but it is not available at this point.  */
     147              :   }
     148              : 
     149              :   bool
     150           86 :   describe_final_event (pretty_printer &pp,
     151              :                         const evdesc::final_event &) final override
     152              :   {
     153           86 :     pp_string (&pp, "write to string literal here");
     154           86 :     return true;
     155              :   }
     156              : 
     157              : private:
     158              :   const region *m_reg;
     159              : };
     160              : 
     161              : std::unique_ptr<pending_diagnostic>
     162           51 : make_write_to_string_literal_diagnostic (const region *reg)
     163              : {
     164           51 :   return std::make_unique<write_to_string_literal_diagnostic> (reg);
     165              : }
     166              : 
     167              : } // namespace ana
     168              : 
     169              : #endif /* #if ENABLE_ANALYZER */
        

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.