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

            Line data    Source code
       1              : /* Diagnostics for complaining about shift operations.
       2              :    Copyright (C) 2020-2026 Free Software Foundation, Inc.
       3              :    Contributed by David Malcolm <dmalcolm@redhat.com>.
       4              : 
       5              : This file is part of GCC.
       6              : 
       7              : GCC is free software; you can redistribute it and/or modify it
       8              : under the terms of the GNU General Public License as published by
       9              : the Free Software Foundation; either version 3, or (at your option)
      10              : any later version.
      11              : 
      12              : GCC is distributed in the hope that it will be useful, but
      13              : WITHOUT ANY WARRANTY; without even the implied warranty of
      14              : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      15              : 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              : #include "analyzer/common.h"
      22              : 
      23              : #include "analyzer/region-model.h"
      24              : #include "analyzer/feasible-graph.h"
      25              : #include "diagnostics/sarif-sink.h"
      26              : 
      27              : #if ENABLE_ANALYZER
      28              : 
      29              : namespace ana {
      30              : 
      31              : /* A subclass of pending_diagnostic for complaining about shifts
      32              :    by negative counts.  */
      33              : 
      34              : class shift_count_negative_diagnostic
      35              : : public pending_diagnostic_subclass<shift_count_negative_diagnostic>
      36              : {
      37              : public:
      38           24 :   shift_count_negative_diagnostic (const gassign *assign, tree count_cst,
      39              :                                    const region *src_region)
      40           24 :   : m_assign (assign), m_count_cst (count_cst), m_src_region (src_region)
      41              :   {}
      42              : 
      43          156 :   const char *get_kind () const final override
      44              :   {
      45          156 :     return "shift_count_negative_diagnostic";
      46              :   }
      47              : 
      48           24 :   bool operator== (const shift_count_negative_diagnostic &other) const
      49              :   {
      50           24 :     return (m_assign == other.m_assign
      51           24 :             && same_tree_p (m_count_cst, other.m_count_cst));
      52              :   }
      53              : 
      54           36 :   int get_controlling_option () const final override
      55              :   {
      56           36 :     return OPT_Wanalyzer_shift_count_negative;
      57              :   }
      58              : 
      59           12 :   bool emit (diagnostic_emission_context &ctxt) final override
      60              :   {
      61           12 :     return ctxt.warn ("shift by negative count (%qE)", m_count_cst);
      62              :   }
      63              : 
      64              :   bool
      65           24 :   describe_final_event (pretty_printer &pp,
      66              :                         const evdesc::final_event &) final override
      67              :   {
      68           24 :     pp_printf (&pp,
      69              :                "shift by negative amount here (%qE)",
      70              :                m_count_cst);
      71           24 :     return true;
      72              :   }
      73              : 
      74              :   void
      75           24 :   mark_interesting_stuff (interesting_t *interest)
      76              :   {
      77           24 :     interest->add_read_region (m_src_region, "shift count value");
      78           24 :   }
      79              : 
      80              : private:
      81              :   const gassign *m_assign;
      82              :   tree m_count_cst;
      83              :   const region *m_src_region;
      84              : };
      85              : 
      86              : std::unique_ptr<pending_diagnostic>
      87           24 : make_shift_count_negative_diagnostic (const gassign *assign, tree count_cst,
      88              :                                       const region *src_region)
      89              : {
      90           24 :   return std::make_unique<shift_count_negative_diagnostic>
      91           24 :     (assign, count_cst, src_region);
      92              : }
      93              : 
      94              : /* A subclass of pending_diagnostic for complaining about shifts
      95              :    by counts >= the width of the operand type.  */
      96              : 
      97              : class shift_count_overflow_diagnostic
      98              : : public pending_diagnostic_subclass<shift_count_overflow_diagnostic>
      99              : {
     100              : public:
     101           24 :   shift_count_overflow_diagnostic (const gassign *assign,
     102              :                                    int operand_precision,
     103              :                                    tree count_cst,
     104              :                                    const region *src_region)
     105           24 :   : m_assign (assign), m_operand_precision (operand_precision),
     106           24 :     m_count_cst (count_cst),
     107           24 :     m_src_region (src_region)
     108              :   {}
     109              : 
     110          108 :   const char *get_kind () const final override
     111              :   {
     112          108 :     return "shift_count_overflow_diagnostic";
     113              :   }
     114              : 
     115           24 :   bool operator== (const shift_count_overflow_diagnostic &other) const
     116              :   {
     117           24 :     return (m_assign == other.m_assign
     118           24 :             && m_operand_precision == other.m_operand_precision
     119           48 :             && same_tree_p (m_count_cst, other.m_count_cst));
     120              :   }
     121              : 
     122           36 :   int get_controlling_option () const final override
     123              :   {
     124           36 :     return OPT_Wanalyzer_shift_count_overflow;
     125              :   }
     126              : 
     127           12 :   bool emit (diagnostic_emission_context &ctxt) final override
     128              :   {
     129           12 :     return ctxt.warn ("shift by count (%qE) >= precision of type (%qi)",
     130           12 :                       m_count_cst, m_operand_precision);
     131              :   }
     132              : 
     133              :   bool
     134           24 :   describe_final_event (pretty_printer &pp,
     135              :                         const evdesc::final_event &) final override
     136              :   {
     137           24 :     pp_printf (&pp,
     138              :                "shift by count %qE here",
     139              :                m_count_cst);
     140           24 :     return true;
     141              :   }
     142              : 
     143              :   void
     144           24 :   mark_interesting_stuff (interesting_t *interest)
     145              :   {
     146           24 :     interest->add_read_region (m_src_region, "shift count value");
     147           24 :   }
     148              : 
     149              : private:
     150              :   const gassign *m_assign;
     151              :   int m_operand_precision;
     152              :   tree m_count_cst;
     153              :   const region *m_src_region;
     154              : };
     155              : 
     156              : std::unique_ptr<pending_diagnostic>
     157           24 : make_shift_count_overflow_diagnostic (const gassign *assign,
     158              :                                       int operand_precision,
     159              :                                       tree count_cst,
     160              :                                       const region *src_region)
     161              : {
     162           24 :   return std::make_unique<shift_count_overflow_diagnostic>
     163           24 :     (assign, operand_precision, count_cst, src_region);
     164              : }
     165              : 
     166              : } // namespace ana
     167              : 
     168              : #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.