LCOV - code coverage report
Current view: top level - gcc/diagnostics - paths.h (source / functions) Coverage Total Hit
Test: gcc.info Lines: 100.0 % 13 13
Test Date: 2026-02-28 14:20:25 Functions: 100.0 % 1 1
Legend: Lines:     hit not hit

            Line data    Source code
       1              : /* Paths through the code associated with a diagnostic.
       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              : #ifndef GCC_DIAGNOSTICS_PATHS_H
      22              : #define GCC_DIAGNOSTICS_PATHS_H
      23              : 
      24              : #include "diagnostic.h" /* for ATTRIBUTE_GCC_DIAG.  */
      25              : #include "diagnostics/event-id.h"
      26              : #include "diagnostics/logical-locations.h"
      27              : 
      28              : namespace diagnostics {
      29              :   namespace digraphs {
      30              :     class digraph;
      31              :   } // namespace digraphs
      32              :   namespace logical_locations {
      33              :     class manager;
      34              :   } // logical_locations
      35              :   class sarif_builder;
      36              :   class sarif_object;
      37              : } //namespace diagnostics
      38              : 
      39              : namespace diagnostics {
      40              : namespace paths {
      41              : 
      42              : /* A diagnostics::paths::path is an optional additional piece of metadata associated
      43              :    with a diagnostic (via its rich_location).
      44              : 
      45              :    It describes a sequence of events predicted by the compiler that
      46              :    lead to the problem occurring, with their locations in the user's source,
      47              :    and text descriptions.
      48              : 
      49              :    For example, the following error has a 3-event path:
      50              : 
      51              :      test.c: In function 'demo':
      52              :      test.c:29:5: error: passing NULL as argument 1 to 'PyList_Append' which
      53              :        requires a non-NULL parameter
      54              :         29 |     PyList_Append(list, item);
      55              :            |     ^~~~~~~~~~~~~~~~~~~~~~~~~
      56              :        'demo': events 1-3
      57              :         25 |   list = PyList_New(0);
      58              :            |          ^~~~~~~~~~~~~
      59              :            |          |
      60              :            |          (1) when 'PyList_New' fails, returning NULL
      61              :         26 |
      62              :         27 |   for (i = 0; i < count; i++) {
      63              :            |   ~~~
      64              :            |   |
      65              :            |   (2) when 'i < count'
      66              :         28 |     item = PyLong_FromLong(random());
      67              :         29 |     PyList_Append(list, item);
      68              :            |     ~~~~~~~~~~~~~~~~~~~~~~~~~
      69              :            |     |
      70              :            |     (3) when calling 'PyList_Append', passing NULL from (1) as argument 1
      71              : 
      72              :     The diagnostic-printing code has consolidated the path into a single
      73              :     run of events, since all the events are near each other and within the same
      74              :     function; more complicated examples (such as interprocedural paths)
      75              :     might be printed as multiple runs of events.  */
      76              : 
      77              : /* Abstract base classes, describing events within a path, and the paths
      78              :    themselves.  */
      79              : 
      80              : /* One event within a path.  */
      81              : 
      82        41408 : class event
      83              : {
      84              :  public:
      85              :   /* Enums for giving a sense of what this event means.
      86              :      Roughly corresponds to SARIF v2.1.0 section 3.38.8.  */
      87              :   enum class verb
      88              :   {
      89              :     unknown,
      90              : 
      91              :     acquire,
      92              :     release,
      93              :     enter,
      94              :     exit,
      95              :     call,
      96              :     return_,
      97              :     branch,
      98              : 
      99              :     danger,
     100              : 
     101              :     // Special control flow operations:
     102              :     throw_,
     103              :     catch_,
     104              :     unwind_, // unwinding stack frame(s) during exception-handling
     105              :     setjmp_,
     106              :     longjmp_
     107              :   };
     108              :   enum class noun
     109              :   {
     110              :     unknown,
     111              : 
     112              :     taint,
     113              :     sensitive, // this one isn't in SARIF v2.1.0; filed as https://github.com/oasis-tcs/sarif-spec/issues/530
     114              :     function,
     115              :     lock,
     116              :     memory,
     117              :     resource
     118              :   };
     119              :   enum class property
     120              :   {
     121              :     unknown,
     122              : 
     123              :     true_,
     124              :     false_
     125              :   };
     126              :   /* A bundle of such enums, allowing for descriptions of the meaning of
     127              :      an event, such as
     128              :      - "acquire memory": meaning (verb::acquire, noun::memory)
     129              :      - "take true branch"": meaning (verb::branch, property::true)
     130              :      - "return from function": meaning (verb::return, noun::function)
     131              :      etc, as per SARIF's threadFlowLocation "kinds" property
     132              :      (SARIF v2.1.0 section 3.38.8).  */
     133              :   struct meaning
     134              :   {
     135         3612 :     meaning ()
     136              :     : m_verb (verb::unknown),
     137              :       m_noun (noun::unknown),
     138              :       m_property (property::unknown)
     139              :     {
     140              :     }
     141           58 :     meaning (enum verb verb)
     142              :     : m_verb (verb), m_noun (noun::unknown), m_property (property::unknown)
     143              :     {
     144              :     }
     145          997 :     meaning (enum verb verb, enum noun noun)
     146              :     : m_verb (verb), m_noun (noun), m_property (property::unknown)
     147              :     {
     148              :     }
     149          252 :     meaning (enum verb verb, enum property property)
     150              :     : m_verb (verb), m_noun (noun::unknown), m_property (property)
     151              :     {
     152              :     }
     153              : 
     154              :     void dump_to_pp (pretty_printer *pp) const;
     155              : 
     156              :     static const char *maybe_get_verb_str (enum verb);
     157              :     static const char *maybe_get_noun_str (enum noun);
     158              :     static const char *maybe_get_property_str (enum property);
     159              : 
     160              :     enum verb m_verb;
     161              :     enum noun m_noun;
     162              :     enum property m_property;
     163              :   };
     164              : 
     165         4862 :   virtual ~event () {}
     166              : 
     167              :   virtual location_t get_location () const = 0;
     168              : 
     169              :   /* Stack depth, so that consumers can visualize the interprocedural
     170              :      calls, returns, and frame nesting.  */
     171              :   virtual int get_stack_depth () const = 0;
     172              : 
     173              :   /* Print a localized (and possibly colorized) description of this event.  */
     174              :   virtual void print_desc (pretty_printer &pp) const = 0;
     175              : 
     176              :   /* Get a logical location for this event, or null if there is none.  */
     177              :   virtual logical_locations::key get_logical_location () const = 0;
     178              : 
     179              :   virtual meaning get_meaning () const = 0;
     180              : 
     181              :   /* True iff we should draw a line connecting this event to the
     182              :      next event (e.g. to highlight control flow).  */
     183              :   virtual bool connect_to_next_event_p () const = 0;
     184              : 
     185              :   virtual thread_id_t get_thread_id () const = 0;
     186              : 
     187              :   /* Hook for SARIF output to allow for adding diagnostic-specific
     188              :      properties to the threadFlowLocation object's property bag.  */
     189              :   virtual void
     190            9 :   maybe_add_sarif_properties (sarif_builder &,
     191              :                               sarif_object &/*thread_flow_loc_obj*/) const
     192              :   {
     193            9 :   }
     194              : 
     195              :   /* Hook for capturing state at this event, potentially for visualizing
     196              :      in HTML output, or for adding to SARIF.  */
     197              :   virtual std::unique_ptr<digraphs::digraph>
     198              :   maybe_make_diagnostic_state_graph (bool debug) const;
     199              : 
     200              :   label_text get_desc (pretty_printer &ref_pp) const;
     201              : };
     202              : 
     203              : /* Abstract base class representing a thread of execution within
     204              :    a diagnostics::paths::path.
     205              :    Each event is associated with one thread.
     206              :    Typically there is just one thread per diagnostics::paths::path. */
     207              : 
     208        11424 : class thread
     209              : {
     210              : public:
     211              :   virtual ~thread () {}
     212              :   virtual label_text get_name (bool can_colorize) const = 0;
     213              : };
     214              : 
     215              : /* Abstract base class for getting at a sequence of events.  */
     216              : 
     217              : class path
     218              : {
     219              :  public:
     220              :   virtual ~path () {}
     221              :   virtual unsigned num_events () const = 0;
     222              :   virtual const event & get_event (int idx) const = 0;
     223              :   virtual unsigned num_threads () const = 0;
     224              :   virtual const thread &
     225              :   get_thread (thread_id_t) const = 0;
     226              : 
     227              :   /* Return true iff the two events are both within the same function,
     228              :      or both outside of any function.  */
     229              :   virtual bool
     230              :   same_function_p (int event_idx_a,
     231              :                    int event_idx_b) const = 0;
     232              : 
     233              :   bool interprocedural_p () const;
     234              :   bool multithreaded_p () const;
     235              : 
     236        10953 :   const logical_locations::manager &get_logical_location_manager () const
     237              :   {
     238        10953 :     return m_logical_loc_mgr;
     239              :   }
     240              : 
     241              : protected:
     242       901708 :   path (const logical_locations::manager &logical_loc_mgr)
     243       901708 :   : m_logical_loc_mgr (logical_loc_mgr)
     244              :   {
     245              :   }
     246              : 
     247              : private:
     248              :   bool get_first_event_in_a_function (unsigned *out_idx) const;
     249              : 
     250              :   const logical_locations::manager &m_logical_loc_mgr;
     251              : };
     252              : 
     253              : } // namespace paths
     254              : } // namespace diagnostics
     255              : 
     256              : /* Concrete subclasses of the above can be found in
     257              :    simple-diagnostic-path.h.  */
     258              : 
     259              : extern void debug (diagnostics::paths::path *path);
     260              : 
     261              : #endif /* ! GCC_DIAGNOSTICS_PATHS_H */
        

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.