LCOV - code coverage report
Current view: top level - gcc - simple-diagnostic-path.cc (source / functions) Coverage Total Hit
Test: gcc.info Lines: 95.7 % 92 88
Test Date: 2024-12-21 13:15:12 Functions: 93.8 % 16 15
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.
       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 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                 :             : /* class simple_diagnostic_path : public diagnostic_path.  */
      36                 :             : 
      37                 :          26 : simple_diagnostic_path::simple_diagnostic_path (pretty_printer *event_pp)
      38                 :          26 : : m_event_pp (event_pp),
      39                 :          26 :   m_localize_events (true)
      40                 :             : {
      41                 :          26 :   add_thread ("main");
      42                 :          26 : }
      43                 :             : 
      44                 :             : /* Implementation of diagnostic_path::num_events vfunc for
      45                 :             :    simple_diagnostic_path: simply get the number of events in the vec.  */
      46                 :             : 
      47                 :             : unsigned
      48                 :          79 : simple_diagnostic_path::num_events () const
      49                 :             : {
      50                 :          79 :   return m_events.length ();
      51                 :             : }
      52                 :             : 
      53                 :             : /* Implementation of diagnostic_path::get_event vfunc for
      54                 :             :    simple_diagnostic_path: simply return the event in the vec.  */
      55                 :             : 
      56                 :             : const diagnostic_event &
      57                 :         405 : simple_diagnostic_path::get_event (int idx) const
      58                 :             : {
      59                 :         405 :   return *m_events[idx];
      60                 :             : }
      61                 :             : 
      62                 :             : unsigned
      63                 :           8 : simple_diagnostic_path::num_threads () const
      64                 :             : {
      65                 :           8 :   return m_threads.length ();
      66                 :             : }
      67                 :             : 
      68                 :             : const diagnostic_thread &
      69                 :          20 : simple_diagnostic_path::get_thread (diagnostic_thread_id_t idx) const
      70                 :             : {
      71                 :          20 :   return *m_threads[idx];
      72                 :             : }
      73                 :             : 
      74                 :             : bool
      75                 :         168 : simple_diagnostic_path::same_function_p (int event_idx_a,
      76                 :             :                                          int event_idx_b) const
      77                 :             : {
      78                 :         168 :   return (m_events[event_idx_a]->get_fndecl ()
      79                 :         168 :           == m_events[event_idx_b]->get_fndecl ());
      80                 :             : }
      81                 :             : 
      82                 :             : diagnostic_thread_id_t
      83                 :          32 : simple_diagnostic_path::add_thread (const char *name)
      84                 :             : {
      85                 :          32 :   m_threads.safe_push (new simple_diagnostic_thread (name));
      86                 :          32 :   return m_threads.length () - 1;
      87                 :             : }
      88                 :             : 
      89                 :             : /* Add an event to this path at LOC within function FNDECL at
      90                 :             :    stack depth DEPTH.
      91                 :             : 
      92                 :             :    Use m_context's printer to format FMT, as the text of the new
      93                 :             :    event.  Localize FMT iff m_localize_events is set.
      94                 :             : 
      95                 :             :    Return the id of the new event.  */
      96                 :             : 
      97                 :             : diagnostic_event_id_t
      98                 :          97 : simple_diagnostic_path::add_event (location_t loc, tree fndecl, int depth,
      99                 :             :                                    const char *fmt, ...)
     100                 :             : {
     101                 :          97 :   pretty_printer *pp = m_event_pp;
     102                 :          97 :   pp_clear_output_area (pp);
     103                 :             : 
     104                 :          97 :   rich_location rich_loc (line_table, UNKNOWN_LOCATION);
     105                 :             : 
     106                 :          97 :   va_list ap;
     107                 :             : 
     108                 :          97 :   va_start (ap, fmt);
     109                 :             : 
     110                 :          97 :   text_info ti (m_localize_events ? _(fmt) : fmt,
     111                 :          97 :                 &ap, 0, nullptr, &rich_loc);
     112                 :          97 :   pp_format (pp, &ti);
     113                 :          97 :   pp_output_formatted_text (pp);
     114                 :             : 
     115                 :          97 :   va_end (ap);
     116                 :             : 
     117                 :          97 :   simple_diagnostic_event *new_event
     118                 :          97 :     = new simple_diagnostic_event (loc, fndecl, depth, pp_formatted_text (pp));
     119                 :          97 :   m_events.safe_push (new_event);
     120                 :             : 
     121                 :          97 :   pp_clear_output_area (pp);
     122                 :             : 
     123                 :         194 :   return diagnostic_event_id_t (m_events.length () - 1);
     124                 :          97 : }
     125                 :             : 
     126                 :             : diagnostic_event_id_t
     127                 :          64 : simple_diagnostic_path::add_thread_event (diagnostic_thread_id_t thread_id,
     128                 :             :                                           location_t loc,
     129                 :             :                                           tree fndecl,
     130                 :             :                                           int depth,
     131                 :             :                                           const char *fmt, ...)
     132                 :             : {
     133                 :          64 :   pretty_printer *pp = m_event_pp;
     134                 :          64 :   pp_clear_output_area (pp);
     135                 :             : 
     136                 :          64 :   rich_location rich_loc (line_table, UNKNOWN_LOCATION);
     137                 :             : 
     138                 :          64 :   va_list ap;
     139                 :             : 
     140                 :          64 :   va_start (ap, fmt);
     141                 :             : 
     142                 :          64 :   text_info ti (_(fmt), &ap, 0, nullptr, &rich_loc);
     143                 :             : 
     144                 :          64 :   pp_format (pp, &ti);
     145                 :          64 :   pp_output_formatted_text (pp);
     146                 :             : 
     147                 :          64 :   va_end (ap);
     148                 :             : 
     149                 :          64 :   simple_diagnostic_event *new_event
     150                 :             :     = new simple_diagnostic_event (loc, fndecl, depth, pp_formatted_text (pp),
     151                 :          64 :                                    thread_id);
     152                 :          64 :   m_events.safe_push (new_event);
     153                 :             : 
     154                 :          64 :   pp_clear_output_area (pp);
     155                 :             : 
     156                 :         128 :   return diagnostic_event_id_t (m_events.length () - 1);
     157                 :          64 : }
     158                 :             : 
     159                 :             : /* Mark the most recent event on this path (which must exist) as being
     160                 :             :    connected to the next one to be added.  */
     161                 :             : 
     162                 :             : void
     163                 :           0 : simple_diagnostic_path::connect_to_next_event ()
     164                 :             : {
     165                 :           0 :   gcc_assert (m_events.length () > 0);
     166                 :           0 :   m_events[m_events.length () - 1]->connect_to_next_event ();
     167                 :           0 : }
     168                 :             : 
     169                 :             : /* struct simple_diagnostic_event.  */
     170                 :             : 
     171                 :             : /* simple_diagnostic_event's ctor.  */
     172                 :             : 
     173                 :         161 : simple_diagnostic_event::
     174                 :             : simple_diagnostic_event (location_t loc,
     175                 :             :                          tree fndecl,
     176                 :             :                          int depth,
     177                 :             :                          const char *desc,
     178                 :         161 :                          diagnostic_thread_id_t thread_id)
     179                 :         161 : : m_loc (loc), m_fndecl (fndecl), m_logical_loc (fndecl),
     180                 :         161 :   m_depth (depth), m_desc (xstrdup (desc)),
     181                 :         161 :   m_connected_to_next_event (false),
     182                 :         161 :   m_thread_id (thread_id)
     183                 :             : {
     184                 :         161 : }
     185                 :             : 
     186                 :             : /* simple_diagnostic_event's dtor.  */
     187                 :             : 
     188                 :         322 : simple_diagnostic_event::~simple_diagnostic_event ()
     189                 :             : {
     190                 :         161 :   free (m_desc);
     191                 :         322 : }
     192                 :             : 
     193                 :             : void
     194                 :         145 : simple_diagnostic_event::print_desc (pretty_printer &pp) const
     195                 :             : {
     196                 :         145 :   pp_string (&pp, m_desc);
     197                 :         145 : }
     198                 :             : 
     199                 :             : #if CHECKING_P
     200                 :             : 
     201                 :             : namespace selftest {
     202                 :             : 
     203                 :             : static void
     204                 :           4 : test_intraprocedural_path (pretty_printer *event_pp)
     205                 :             : {
     206                 :           4 :   tree fntype_void_void
     207                 :           4 :     = build_function_type_array (void_type_node, 0, NULL);
     208                 :           4 :   tree fndecl_foo = build_fn_decl ("foo", fntype_void_void);
     209                 :             : 
     210                 :           4 :   simple_diagnostic_path path (event_pp);
     211                 :           4 :   path.add_event (UNKNOWN_LOCATION, fndecl_foo, 0, "first %qs", "free");
     212                 :           4 :   path.add_event (UNKNOWN_LOCATION, fndecl_foo, 0, "double %qs", "free");
     213                 :             : 
     214                 :           4 :   ASSERT_EQ (path.num_events (), 2);
     215                 :           4 :   ASSERT_EQ (path.num_threads (), 1);
     216                 :           4 :   ASSERT_FALSE (path.interprocedural_p ());
     217                 :           4 :   ASSERT_STREQ (path.get_event (0).get_desc (*event_pp).get (),
     218                 :             :                 "first `free'");
     219                 :           4 :   ASSERT_STREQ (path.get_event (1).get_desc (*event_pp).get (),
     220                 :             :                 "double `free'");
     221                 :           4 : }
     222                 :             : 
     223                 :             : /* Run all of the selftests within this file.  */
     224                 :             : 
     225                 :             : void
     226                 :           4 : simple_diagnostic_path_cc_tests ()
     227                 :             : {
     228                 :             :   /* In a few places we use the global dc's printer to determine
     229                 :             :      colorization so ensure this off during the tests.  */
     230                 :           4 :   pretty_printer *global_pp = global_dc->get_reference_printer ();
     231                 :           4 :   const bool saved_show_color = pp_show_color (global_pp);
     232                 :           4 :   pp_show_color (global_pp) = false;
     233                 :             : 
     234                 :           4 :   auto_fix_quotes fix_quotes;
     235                 :           4 :   std::unique_ptr<pretty_printer> event_pp
     236                 :           4 :     = std::unique_ptr<pretty_printer> (global_pp->clone ());
     237                 :             : 
     238                 :           4 :   test_intraprocedural_path (event_pp.get ());
     239                 :             : 
     240                 :           4 :   pp_show_color (global_pp) = saved_show_color;
     241                 :           4 : }
     242                 :             : 
     243                 :             : } // namespace selftest
     244                 :             : 
     245                 :             : #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.