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