LCOV - code coverage report
Current view: top level - gcc - simple-diagnostic-path.cc (source / functions) Coverage Total Hit
Test: gcc.info Lines: 95.6 % 91 87
Test Date: 2025-08-30 13:27:53 Functions: 92.9 % 14 13
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: - 0 0

             Branch data     Line data    Source code
       1                 :             : /* Concrete classes for implementing diagnostic paths, using tree.
       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 under
       8                 :             : the terms of the GNU General Public License as published by the Free
       9                 :             : Software Foundation; either version 3, or (at your option) any later
      10                 :             : version.
      11                 :             : 
      12                 :             : GCC is distributed in the hope that it will be useful, but WITHOUT ANY
      13                 :             : WARRANTY; without even the implied warranty of MERCHANTABILITY or
      14                 :             : FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
      15                 :             : 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                 :             : 
      22                 :             : #include "config.h"
      23                 :             : #define INCLUDE_VECTOR
      24                 :             : #include "system.h"
      25                 :             : #include "coretypes.h"
      26                 :             : #include "tree.h"
      27                 :             : #include "version.h"
      28                 :             : #include "demangle.h"
      29                 :             : #include "intl.h"
      30                 :             : #include "backtrace.h"
      31                 :             : #include "diagnostic.h"
      32                 :             : #include "simple-diagnostic-path.h"
      33                 :             : #include "selftest.h"
      34                 :             : 
      35                 :             : using namespace diagnostics::paths;
      36                 :             : 
      37                 :             : /* class simple_diagnostic_path : public diagnostics::paths::path.  */
      38                 :             : 
      39                 :        5743 : simple_diagnostic_path::
      40                 :             : simple_diagnostic_path (const tree_logical_location_manager &logical_loc_mgr,
      41                 :        5743 :                         pretty_printer *event_pp)
      42                 :             : : path (logical_loc_mgr),
      43                 :        5743 :   m_event_pp (event_pp),
      44                 :        5743 :   m_localize_events (true)
      45                 :             : {
      46                 :        5743 :   add_thread ("main");
      47                 :        5743 : }
      48                 :             : 
      49                 :             : /* Implementation of path::get_event vfunc for
      50                 :             :    simple_diagnostic_path: simply return the event in the vec.  */
      51                 :             : 
      52                 :             : const event &
      53                 :         558 : simple_diagnostic_path::get_event (int idx) const
      54                 :             : {
      55                 :         558 :   return *m_events[idx];
      56                 :             : }
      57                 :             : 
      58                 :             : const thread &
      59                 :          33 : simple_diagnostic_path::get_thread (thread_id_t idx) const
      60                 :             : {
      61                 :          33 :   return *m_threads[idx];
      62                 :             : }
      63                 :             : 
      64                 :             : bool
      65                 :         186 : simple_diagnostic_path::same_function_p (int event_idx_a,
      66                 :             :                                          int event_idx_b) const
      67                 :             : {
      68                 :         186 :   return (m_events[event_idx_a]->get_fndecl ()
      69                 :         186 :           == m_events[event_idx_b]->get_fndecl ());
      70                 :             : }
      71                 :             : 
      72                 :             : thread_id_t
      73                 :        5749 : simple_diagnostic_path::add_thread (const char *name)
      74                 :             : {
      75                 :        5749 :   m_threads.safe_push (new simple_diagnostic_thread (name));
      76                 :        5749 :   return m_threads.length () - 1;
      77                 :             : }
      78                 :             : 
      79                 :             : /* Add an event to this path at LOC within function FNDECL at
      80                 :             :    stack depth DEPTH.
      81                 :             : 
      82                 :             :    Use m_context's printer to format FMT, as the text of the new
      83                 :             :    event.  Localize FMT iff m_localize_events is set.
      84                 :             : 
      85                 :             :    Return the id of the new event.  */
      86                 :             : 
      87                 :             : event_id_t
      88                 :         110 : simple_diagnostic_path::add_event (location_t loc, tree fndecl, int depth,
      89                 :             :                                    const char *fmt, ...)
      90                 :             : {
      91                 :         110 :   pretty_printer *pp = m_event_pp;
      92                 :         110 :   pp_clear_output_area (pp);
      93                 :             : 
      94                 :         110 :   rich_location rich_loc (line_table, UNKNOWN_LOCATION);
      95                 :             : 
      96                 :         110 :   va_list ap;
      97                 :             : 
      98                 :         110 :   va_start (ap, fmt);
      99                 :             : 
     100                 :         110 :   text_info ti (m_localize_events ? _(fmt) : fmt,
     101                 :         110 :                 &ap, 0, nullptr, &rich_loc);
     102                 :         110 :   pp_format (pp, &ti);
     103                 :         110 :   pp_output_formatted_text (pp);
     104                 :             : 
     105                 :         110 :   va_end (ap);
     106                 :             : 
     107                 :         110 :   simple_diagnostic_event *new_event
     108                 :         110 :     = new simple_diagnostic_event (loc, fndecl, depth, pp_formatted_text (pp));
     109                 :         110 :   m_events.safe_push (new_event);
     110                 :             : 
     111                 :         110 :   pp_clear_output_area (pp);
     112                 :             : 
     113                 :         220 :   return event_id_t (m_events.length () - 1);
     114                 :         110 : }
     115                 :             : 
     116                 :             : event_id_t
     117                 :          64 : simple_diagnostic_path::add_thread_event (thread_id_t thread_id,
     118                 :             :                                           location_t loc,
     119                 :             :                                           tree fndecl,
     120                 :             :                                           int depth,
     121                 :             :                                           const char *fmt, ...)
     122                 :             : {
     123                 :          64 :   pretty_printer *pp = m_event_pp;
     124                 :          64 :   pp_clear_output_area (pp);
     125                 :             : 
     126                 :          64 :   rich_location rich_loc (line_table, UNKNOWN_LOCATION);
     127                 :             : 
     128                 :          64 :   va_list ap;
     129                 :             : 
     130                 :          64 :   va_start (ap, fmt);
     131                 :             : 
     132                 :          64 :   text_info ti (_(fmt), &ap, 0, nullptr, &rich_loc);
     133                 :             : 
     134                 :          64 :   pp_format (pp, &ti);
     135                 :          64 :   pp_output_formatted_text (pp);
     136                 :             : 
     137                 :          64 :   va_end (ap);
     138                 :             : 
     139                 :          64 :   simple_diagnostic_event *new_event
     140                 :             :     = new simple_diagnostic_event (loc, fndecl, depth, pp_formatted_text (pp),
     141                 :          64 :                                    thread_id);
     142                 :          64 :   m_events.safe_push (new_event);
     143                 :             : 
     144                 :          64 :   pp_clear_output_area (pp);
     145                 :             : 
     146                 :         128 :   return event_id_t (m_events.length () - 1);
     147                 :          64 : }
     148                 :             : 
     149                 :             : /* Mark the most recent event on this path (which must exist) as being
     150                 :             :    connected to the next one to be added.  */
     151                 :             : 
     152                 :             : void
     153                 :           0 : simple_diagnostic_path::connect_to_next_event ()
     154                 :             : {
     155                 :           0 :   gcc_assert (m_events.length () > 0);
     156                 :           0 :   m_events[m_events.length () - 1]->connect_to_next_event ();
     157                 :           0 : }
     158                 :             : 
     159                 :             : /* struct simple_diagnostic_event.  */
     160                 :             : 
     161                 :             : /* simple_diagnostic_event's ctor.  */
     162                 :             : 
     163                 :         174 : simple_diagnostic_event::
     164                 :             : simple_diagnostic_event (location_t loc,
     165                 :             :                          tree fndecl,
     166                 :             :                          int depth,
     167                 :             :                          const char *desc,
     168                 :         174 :                          thread_id_t thread_id)
     169                 :         174 : : m_loc (loc), m_fndecl (fndecl),
     170                 :         174 :   m_logical_loc (tree_logical_location_manager::key_from_tree (fndecl)),
     171                 :         174 :   m_depth (depth), m_desc (xstrdup (desc)),
     172                 :         174 :   m_connected_to_next_event (false),
     173                 :         174 :   m_thread_id (thread_id)
     174                 :             : {
     175                 :         174 : }
     176                 :             : 
     177                 :             : /* simple_diagnostic_event's dtor.  */
     178                 :             : 
     179                 :         348 : simple_diagnostic_event::~simple_diagnostic_event ()
     180                 :             : {
     181                 :         174 :   free (m_desc);
     182                 :         348 : }
     183                 :             : 
     184                 :             : void
     185                 :         170 : simple_diagnostic_event::print_desc (pretty_printer &pp) const
     186                 :             : {
     187                 :         170 :   pp_string (&pp, m_desc);
     188                 :         170 : }
     189                 :             : 
     190                 :             : #if CHECKING_P
     191                 :             : 
     192                 :             : namespace selftest {
     193                 :             : 
     194                 :             : static void
     195                 :           4 : test_intraprocedural_path (pretty_printer *event_pp)
     196                 :             : {
     197                 :           4 :   tree_logical_location_manager mgr;
     198                 :           4 :   tree fntype_void_void
     199                 :           4 :     = build_function_type_array (void_type_node, 0, nullptr);
     200                 :           4 :   tree fndecl_foo = build_fn_decl ("foo", fntype_void_void);
     201                 :             : 
     202                 :           4 :   simple_diagnostic_path path (mgr, event_pp);
     203                 :           4 :   path.add_event (UNKNOWN_LOCATION, fndecl_foo, 0, "first %qs", "free");
     204                 :           4 :   path.add_event (UNKNOWN_LOCATION, fndecl_foo, 0, "double %qs", "free");
     205                 :             : 
     206                 :           4 :   ASSERT_EQ (path.num_events (), 2);
     207                 :           4 :   ASSERT_EQ (path.num_threads (), 1);
     208                 :           4 :   ASSERT_FALSE (path.interprocedural_p ());
     209                 :           4 :   ASSERT_STREQ (path.get_event (0).get_desc (*event_pp).get (),
     210                 :             :                 "first `free'");
     211                 :           4 :   ASSERT_STREQ (path.get_event (1).get_desc (*event_pp).get (),
     212                 :             :                 "double `free'");
     213                 :           4 : }
     214                 :             : 
     215                 :             : /* Run all of the selftests within this file.  */
     216                 :             : 
     217                 :             : void
     218                 :           4 : simple_diagnostic_path_cc_tests ()
     219                 :             : {
     220                 :             :   /* In a few places we use the global dc's printer to determine
     221                 :             :      colorization so ensure this off during the tests.  */
     222                 :           4 :   pretty_printer *global_pp = global_dc->get_reference_printer ();
     223                 :           4 :   const bool saved_show_color = pp_show_color (global_pp);
     224                 :           4 :   pp_show_color (global_pp) = false;
     225                 :             : 
     226                 :           4 :   auto_fix_quotes fix_quotes;
     227                 :           4 :   std::unique_ptr<pretty_printer> event_pp
     228                 :           4 :     = std::unique_ptr<pretty_printer> (global_pp->clone ());
     229                 :             : 
     230                 :           4 :   test_intraprocedural_path (event_pp.get ());
     231                 :             : 
     232                 :           4 :   pp_show_color (global_pp) = saved_show_color;
     233                 :           4 : }
     234                 :             : 
     235                 :             : } // namespace selftest
     236                 :             : 
     237                 :             : #endif /* #if CHECKING_P */
        

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.