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: 2026-02-28 14:20:25 Functions: 92.9 % 14 13
Legend: Lines:     hit not hit

            Line data    Source code
       1              : /* Concrete classes for implementing diagnostic paths, using tree.
       2              :    Copyright (C) 2019-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 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         5767 : simple_diagnostic_path::
      40              : simple_diagnostic_path (const tree_logical_location_manager &logical_loc_mgr,
      41         5767 :                         pretty_printer *event_pp)
      42              : : path (logical_loc_mgr),
      43         5767 :   m_event_pp (event_pp),
      44         5767 :   m_localize_events (true)
      45              : {
      46         5767 :   add_thread ("main");
      47         5767 : }
      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         5773 : simple_diagnostic_path::add_thread (const char *name)
      74              : {
      75         5773 :   m_threads.safe_push (new simple_diagnostic_thread (name));
      76         5773 :   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.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.