.. Copyright (C) 2024-2025 Free Software Foundation, Inc.
   Originally contributed by David Malcolm <dmalcolm@redhat.com>

   This is free software: you can redistribute it and/or modify it
   under the terms of the GNU General Public License as published by
   the Free Software Foundation, either version 3 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful, but
   WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program.  If not, see
   <https://www.gnu.org/licenses/>.

.. default-domain:: c

Tutorial part 7: execution paths
================================

A :type:`diagnostic` can optionally have a :type:`diagnostic_execution_path`
describing a path of execution through code.

For example, let's pretend we're writing a static analyis tool for finding
bugs in `CPython extension code <https://docs.python.org/3/c-api/index.html>`_.

Let's say we're analyzing this code:

.. literalinclude:: ../../../testsuite/libgdiagnostics.dg/test-warning-with-path.c
   :language: c
   :start-after: begin fake source
   :end-before:  end fake source

This code attempts to take an Python integer parameter and then build a
list of that length, containing random integers.  However, there are
**numerous bugs** in this code: a type mismatch, mistakes in
reference-counting, and an almost total lack of error-handling.

For example, ``PyList_Append`` requires a non-NULL first parameter (``list``),
but ``PyList_New`` can fail, returning NULL, and this isn't checked for,
which would lead to a segfault if ``PyList_New`` fails.

We can add a :type:`diagnostic_execution_path` to the :type:`diagnostic`
via :func:`diagnostic_add_execution_path`, and then add events to it
using :func:`diagnostic_execution_path_add_event`.

For example, with::

  diagnostic_event_id alloc_event_id
    = diagnostic_execution_path_add_event (path,
					   loc_call_to_PyList_New,
					   logical_loc, 0,
					   "when %qs fails, returning NULL",
					   "PyList_New");

we create an event that will be worded as::

  (1) when `PyList_New' fails, returning NULL

Note that :func:`diagnostic_execution_path_add_event` returns a
:type:`diagnostic_event_id`.  We can use this to refer to this event
in another event using the ``%@`` format code in its message, which
takes the address of a :type:`diagnostic_event_id`::

  diagnostic_execution_path_add_event (path,
				       loc_call_to_PyList_Append,
				       logical_loc, 0,
				       "when calling %qs, passing NULL from %@ as argument %i",
				       "PyList_Append", &alloc_event_id, 1);

where the latter event will be worded as::

  (2) when calling `PyList_Append', passing NULL from (1) as argument 1

where the ``%@`` reference to the other event has been printed as ``(1)``.
In SARIF output the text "(1)" will have a embedded link referring within the sarif
log to the ``threadFlowLocation`` object for the other event, via JSON
pointer (see `§3.10.3 "URIs that use the sarif scheme" <https://docs.oasis-open.org/sarif/sarif/v2.1.0/errata01/os/sarif-v2.1.0-errata01-os-complete.html#_Toc141790707>`_).

Let's add an event between these describing control flow, creating three
events in all:

.. literalinclude:: ../../../testsuite/libgdiagnostics.dg/test-warning-with-path.c
   :language: c
   :start-after: begin path creation
   :end-before:  end path creation

Assuming we also gave it :type:`diagnostic_logical_location` with:

.. literalinclude:: ../../../testsuite/libgdiagnostics.dg/test-warning-with-path.c
   :language: c
   :start-after: begin create logical locs
   :end-before:  end create logical locs

and finish the :type:`diagnostic` with :func:`diagnostic_finish` like this::

  diagnostic_finish (d,
		     "passing NULL as argument %i to %qs"
		     " which requires a non-NULL parameter",
		     1, "PyList_Append");

then we should get output to text sinks similar to the following::

   In function 'make_a_list_of_random_ints_badly':
   test-warning-with-path.c:30:5: warning: passing NULL as argument 1 to 'PyList_Append' which requires a non-NULL parameter"
      30 |     PyList_Append(list, item);
         |     ^~~~~~~~~~~~~~~~~~~~~~~~~
   make_a_list_of_random_ints_badly': events 1-3
      26 |   list = PyList_New(0);
         |          ^~~~~~~~~~~~~
         |          |
         |          (1) when 'PyList_New' fails, returning NULL
      27 | 
      28 |   for (i = 0; i < count; i++) {
         |               ~~~~~~~~~
         |               |
         |               (2) when 'i < count'
      29 |     item = PyLong_FromLong(random());
      30 |     PyList_Append(list, item);
         |     ~~~~~~~~~~~~~~~~~~~~~~~~~
         |     |
         |     (3) when calling 'PyList_Append', passing NULL from (1) as argument 1

and for SARIF sinks the path will be added as a ``codeFlow`` object
(see SARIF 2.1.0 `§3.36 codeFlow object <https://docs.oasis-open.org/sarif/sarif/v2.1.0/errata01/os/sarif-v2.1.0-errata01-os-complete.html#_Toc141790990>`_).

Here's the above example in full:

.. literalinclude:: ../../../testsuite/libgdiagnostics.dg/test-warning-with-path.c
   :language: c
   :start-after: begin full example
   :end-before:  end full example


See the :doc:`guide to execution paths <../topics/execution-paths>`
for more information, or go on to
:doc:`the next section of the tutorial <08-message-buffers>`.
