LCOV - code coverage report
Current view: top level - gcc/analyzer - pending-diagnostic.cc (source / functions) Coverage Total Hit
Test: gcc.info Lines: 88.1 % 84 74
Test Date: 2024-11-30 13:30:02 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                 :             : /* Classes for analyzer diagnostics.
       2                 :             :    Copyright (C) 2019-2024 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 "config.h"
      22                 :             : #define INCLUDE_VECTOR
      23                 :             : #include "system.h"
      24                 :             : #include "coretypes.h"
      25                 :             : #include "tree.h"
      26                 :             : #include "intl.h"
      27                 :             : #include "diagnostic.h"
      28                 :             : #include "analyzer/analyzer.h"
      29                 :             : #include "diagnostic-event-id.h"
      30                 :             : #include "analyzer/analyzer-logging.h"
      31                 :             : #include "analyzer/sm.h"
      32                 :             : #include "diagnostic-event-id.h"
      33                 :             : #include "analyzer/sm.h"
      34                 :             : #include "analyzer/pending-diagnostic.h"
      35                 :             : #include "analyzer/diagnostic-manager.h"
      36                 :             : #include "analyzer/call-string.h"
      37                 :             : #include "analyzer/program-point.h"
      38                 :             : #include "analyzer/store.h"
      39                 :             : #include "analyzer/region-model.h"
      40                 :             : #include "cpplib.h"
      41                 :             : #include "digraph.h"
      42                 :             : #include "ordered-hash-map.h"
      43                 :             : #include "cfg.h"
      44                 :             : #include "basic-block.h"
      45                 :             : #include "gimple.h"
      46                 :             : #include "gimple-iterator.h"
      47                 :             : #include "cgraph.h"
      48                 :             : #include "analyzer/supergraph.h"
      49                 :             : #include "analyzer/program-state.h"
      50                 :             : #include "analyzer/exploded-graph.h"
      51                 :             : #include "diagnostic-path.h"
      52                 :             : #include "analyzer/checker-path.h"
      53                 :             : #include "make-unique.h"
      54                 :             : 
      55                 :             : #if ENABLE_ANALYZER
      56                 :             : 
      57                 :             : namespace ana {
      58                 :             : 
      59                 :             : /* struct interesting_t.  */
      60                 :             : 
      61                 :             : /* Mark the creation of REG as being interesting.  */
      62                 :             : 
      63                 :             : void
      64                 :        1320 : interesting_t::add_region_creation (const region *reg)
      65                 :             : {
      66                 :        1320 :   gcc_assert (reg);
      67                 :        1320 :   m_region_creation.safe_push (reg);
      68                 :        1320 : }
      69                 :             : 
      70                 :             : void
      71                 :           0 : interesting_t::dump_to_pp (pretty_printer *pp, bool simple) const
      72                 :             : {
      73                 :           0 :   pp_string (pp, "{ region creation: [");
      74                 :           0 :   unsigned i;
      75                 :           0 :   const region *reg;
      76                 :           0 :   FOR_EACH_VEC_ELT (m_region_creation, i, reg)
      77                 :             :     {
      78                 :           0 :       if (i > 0)
      79                 :           0 :         pp_string (pp, ", ");
      80                 :           0 :       reg->dump_to_pp (pp, simple);
      81                 :             :     }
      82                 :           0 :   pp_string (pp, "]}");
      83                 :           0 : }
      84                 :             : 
      85                 :             : /* class diagnostic_emission_context.  */
      86                 :             : 
      87                 :             : /* Get the pending_diagnostic being emitted.  */
      88                 :             : 
      89                 :             : const pending_diagnostic &
      90                 :        3793 : diagnostic_emission_context::get_pending_diagnostic () const
      91                 :             : {
      92                 :        3793 :   return *m_sd.m_d.get ();
      93                 :             : }
      94                 :             : 
      95                 :             : /* Emit a warning, using the rich_location, metadata, and the
      96                 :             :    pending_diagnostic's option.  */
      97                 :             : 
      98                 :             : bool
      99                 :        3634 : diagnostic_emission_context::warn (const char *gmsgid, ...)
     100                 :             : {
     101                 :        3634 :   const pending_diagnostic &pd = get_pending_diagnostic ();
     102                 :        3634 :   auto_diagnostic_group d;
     103                 :        3634 :   va_list ap;
     104                 :        3634 :   va_start (ap, gmsgid);
     105                 :        3634 :   const bool result = emit_diagnostic_valist_meta (DK_WARNING,
     106                 :        3634 :                                                    &m_rich_loc, &m_metadata,
     107                 :        3634 :                                                    pd.get_controlling_option (),
     108                 :             :                                                    gmsgid, &ap);
     109                 :        3634 :   va_end (ap);
     110                 :        7268 :   return result;
     111                 :        3634 : }
     112                 :             : 
     113                 :             : /* Emit a note, using the rich_location and metadata (and the
     114                 :             :    pending_diagnostic's option).  */
     115                 :             : 
     116                 :             : void
     117                 :         159 : diagnostic_emission_context::inform (const char *gmsgid, ...)
     118                 :             : {
     119                 :         159 :   const pending_diagnostic &pd = get_pending_diagnostic ();
     120                 :         159 :   auto_diagnostic_group d;
     121                 :         159 :   va_list ap;
     122                 :         159 :   va_start (ap, gmsgid);
     123                 :         159 :   emit_diagnostic_valist_meta (DK_NOTE,
     124                 :         159 :                                &m_rich_loc, &m_metadata,
     125                 :         159 :                                pd.get_controlling_option (),
     126                 :             :                                gmsgid, &ap);
     127                 :         159 :   va_end (ap);
     128                 :         159 : }
     129                 :             : 
     130                 :             : /* Return true if T1 and T2 are "the same" for the purposes of
     131                 :             :    diagnostic deduplication.  */
     132                 :             : 
     133                 :             : bool
     134                 :      149089 : pending_diagnostic::same_tree_p (tree t1, tree t2)
     135                 :             : {
     136                 :      149089 :   return simple_cst_equal (t1, t2) == 1;
     137                 :             : }
     138                 :             : 
     139                 :             : /* Return true iff IDENT is STR.  */
     140                 :             : 
     141                 :             : static bool
     142                 :       21356 : ht_ident_eq (ht_identifier ident, const char *str)
     143                 :             : {
     144                 :       21356 :   return (strlen (str) == ident.len
     145                 :       21356 :           && 0 == strcmp (str, (const char *)ident.str));
     146                 :             : }
     147                 :             : 
     148                 :             : /* Return true if we should show the expansion location rather than unwind
     149                 :             :    within MACRO.  */
     150                 :             : 
     151                 :             : static bool
     152                 :        4308 : fixup_location_in_macro_p (cpp_hashnode *macro)
     153                 :             : {
     154                 :        4308 :   ht_identifier ident = macro->ident;
     155                 :             : 
     156                 :             :   /* Don't unwind inside "alloca" macro, so that we don't suppress warnings
     157                 :             :      from it (due to being in system headers).  */
     158                 :        4308 :   if (ht_ident_eq (ident, "alloca"))
     159                 :             :     return true;
     160                 :             : 
     161                 :             :   /* Don't unwind inside <stdarg.h> macros, so that we don't suppress warnings
     162                 :             :      from them (due to being in system headers).  */
     163                 :        4276 :   if (ht_ident_eq (ident, "va_start")
     164                 :        4266 :       || ht_ident_eq (ident, "va_copy")
     165                 :        4259 :       || ht_ident_eq (ident, "va_arg")
     166                 :        8523 :       || ht_ident_eq (ident, "va_end"))
     167                 :             :     return true;
     168                 :             :   return false;
     169                 :             : }
     170                 :             : 
     171                 :             : /* Base implementation of pending_diagnostic::fixup_location.
     172                 :             :    Don't unwind inside macros for which fixup_location_in_macro_p is true.  */
     173                 :             : 
     174                 :             : location_t
     175                 :       29977 : pending_diagnostic::fixup_location (location_t loc, bool) const
     176                 :             : {
     177                 :       29977 :   if (linemap_location_from_macro_expansion_p (line_table, loc))
     178                 :             :     {
     179                 :        4308 :       line_map *map
     180                 :        4308 :         = const_cast <line_map *> (linemap_lookup (line_table, loc));
     181                 :        4308 :       const line_map_macro *macro_map = linemap_check_macro (map);
     182                 :        4308 :       if (fixup_location_in_macro_p (macro_map->macro))
     183                 :          67 :         loc = linemap_resolve_location (line_table, loc,
     184                 :             :                                         LRK_MACRO_EXPANSION_POINT, NULL);
     185                 :             :     }
     186                 :       29977 :   return loc;
     187                 :             : }
     188                 :             : 
     189                 :             : /* Base implementation of pending_diagnostic::add_function_entry_event.
     190                 :             :    Add a function_entry_event to EMISSION_PATH.  */
     191                 :             : 
     192                 :             : void
     193                 :        4736 : pending_diagnostic::add_function_entry_event (const exploded_edge &eedge,
     194                 :             :                                               checker_path *emission_path)
     195                 :             : {
     196                 :        4736 :   const exploded_node *dst_node = eedge.m_dest;
     197                 :        4736 :   const program_point &dst_point = dst_node->get_point ();
     198                 :        4736 :   emission_path->add_event (make_unique<function_entry_event> (dst_point));
     199                 :        4736 : }
     200                 :             : 
     201                 :             : /* Base implementation of pending_diagnostic::add_call_event.
     202                 :             :    Add a call_event to EMISSION_PATH.  */
     203                 :             : 
     204                 :             : void
     205                 :        1086 : pending_diagnostic::add_call_event (const exploded_edge &eedge,
     206                 :             :                                     checker_path *emission_path)
     207                 :             : {
     208                 :        1086 :   const exploded_node *src_node = eedge.m_src;
     209                 :        1086 :   const program_point &src_point = src_node->get_point ();
     210                 :        1086 :   const int src_stack_depth = src_point.get_stack_depth ();
     211                 :        1086 :   const gimple *last_stmt = src_point.get_supernode ()->get_last_stmt ();
     212                 :        1086 :   emission_path->add_event
     213                 :        1086 :     (make_unique<call_event> (eedge,
     214                 :        1086 :                               event_loc_info (last_stmt
     215                 :             :                                               ? last_stmt->location
     216                 :             :                                               : UNKNOWN_LOCATION,
     217                 :             :                                               src_point.get_fndecl (),
     218                 :        1086 :                                               src_stack_depth)));
     219                 :        1086 : }
     220                 :             : 
     221                 :             : /* Base implementation of pending_diagnostic::add_region_creation_events.
     222                 :             :    See the comment for class region_creation_event.  */
     223                 :             : 
     224                 :             : void
     225                 :         591 : pending_diagnostic::add_region_creation_events (const region *reg,
     226                 :             :                                                 tree capacity,
     227                 :             :                                                 const event_loc_info &loc_info,
     228                 :             :                                                 checker_path &emission_path)
     229                 :             : {
     230                 :         591 :   emission_path.add_event
     231                 :         591 :     (make_unique<region_creation_event_memory_space> (reg->get_memory_space (),
     232                 :             :                                                       loc_info));
     233                 :             : 
     234                 :         591 :   if (capacity)
     235                 :         359 :     emission_path.add_event
     236                 :         359 :       (make_unique<region_creation_event_capacity> (capacity, loc_info));
     237                 :         591 : }
     238                 :             : 
     239                 :             : /* Base implementation of pending_diagnostic::add_final_event.
     240                 :             :    Add a warning_event to the end of EMISSION_PATH.  */
     241                 :             : 
     242                 :             : void
     243                 :        3630 : pending_diagnostic::add_final_event (const state_machine *sm,
     244                 :             :                                      const exploded_node *enode,
     245                 :             :                                      const event_loc_info &loc_info,
     246                 :             :                                      tree var, state_machine::state_t state,
     247                 :             :                                      checker_path *emission_path)
     248                 :             : {
     249                 :        3630 :   emission_path->add_event
     250                 :        3630 :     (make_unique<warning_event>
     251                 :        7260 :      (loc_info,
     252                 :             :       enode,
     253                 :             :       sm, var, state));
     254                 :        3630 : }
     255                 :             : 
     256                 :             : } // namespace ana
     257                 :             : 
     258                 :             : #endif /* #if ENABLE_ANALYZER */
        

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.