https://gcc.gnu.org/g:2af541920787e333a25b6524e6b94200f128ba13

commit r15-6285-g2af541920787e333a25b6524e6b94200f128ba13
Author: David Malcolm <dmalc...@redhat.com>
Date:   Mon Dec 16 11:22:50 2024 -0500

    libgdiagnostics: consolidate logical locations
    
    This patch updates diagnostic_manager_new_logical_location so
    that repeated calls with the same input values yield the same
    instance of diagnostic_logical_location.
    
    Doing so allows the path-printing logic to properly consolidate runs of
    events, whereas previously it could treat each event as having a
    distinct logical location, and thus require them to be printed
    separately; this greatly improves the output of sarif-replay when
    displaying execution paths.
    
    gcc/ChangeLog:
            * doc/libgdiagnostics/topics/logical-locations.rst
            (diagnostic_manager_new_logical_location): Add note about repeated
            calls.
            * libgdiagnostics.cc: Define INCLUDE_MAP.
            (class owned_nullable_string): Add copy ctor and move ctor.
            (owned_nullable_string::operator<): New.
            (diagnostic_logical_location::operator<): New.
            (diagnostic_manager::new_logical_location): Use m_logical_locs to
            "uniquify" instances, converting it to a std::map.
            (diagnostic_manager::logical_locs_map_t): New typedef.
            (diagnostic_manager::t m_logical_locs): Convert from a std::vector
            to a std::map.
            (diagnostic_execution_path::same_function_p): Update comment.
    
    gcc/testsuite/ChangeLog:
            * libgdiagnostics.dg/test-logical-location.c: Include <assert.h>.
            Verify that creating a diagnostic_logical_location with equal
            values yields the same instance.
            * sarif-replay.dg/2.1.0-valid/malloc-vs-local-4.c.sarif: New test.
            * sarif-replay.dg/2.1.0-valid/signal-1.c.moved.sarif: Update
            expected output to show logical location and for consolidation of
            events into runs.
            * sarif-replay.dg/2.1.0-valid/signal-1.c.sarif: Likewise.
            * sarif-replay.dg/2.1.0-valid/spec-example-4.sarif: Likewise.
    
    Signed-off-by: David Malcolm <dmalc...@redhat.com>

Diff:
---
 .../libgdiagnostics/topics/logical-locations.rst   |   6 +
 gcc/libgdiagnostics.cc                             |  58 ++-
 .../libgdiagnostics.dg/test-logical-location.c     |  13 +
 .../2.1.0-valid/malloc-vs-local-4.c.sarif          | 402 +++++++++++++++++++++
 .../2.1.0-valid/signal-1.c.moved.sarif             |  25 +-
 .../sarif-replay.dg/2.1.0-valid/signal-1.c.sarif   |  25 +-
 .../2.1.0-valid/spec-example-4.sarif               |  11 +-
 7 files changed, 497 insertions(+), 43 deletions(-)

diff --git a/gcc/doc/libgdiagnostics/topics/logical-locations.rst 
b/gcc/doc/libgdiagnostics/topics/logical-locations.rst
index 85900b6344f2..70bbb00c486d 100644
--- a/gcc/doc/libgdiagnostics/topics/logical-locations.rst
+++ b/gcc/doc/libgdiagnostics/topics/logical-locations.rst
@@ -88,6 +88,12 @@ source location
    the SARIF logicalLocation ``decoratedName`` property
    (SARIF v2.1.0 `§3.33.6 
<https://docs.oasis-open.org/sarif/sarif/v2.1.0/errata01/os/sarif-v2.1.0-errata01-os-complete.html#_Toc141790975>`_).
 
+   Repeated calls to :func:`diagnostic_manager_new_logical_location` with
+   "equal" input values on the same :type:`diagnostic_manager` will return
+   the same instance of :type:`diagnostic_logical_location`.  "Equal" here
+   includes different string buffers that compare as equal with
+   :func:``strcmp`.
+
 .. function:: void diagnostic_manager_debug_dump_logical_location (const 
diagnostic_manager *diag_mgr, \
                                                                    const 
diagnostic_logical_location *loc, \
                                                                    FILE *out)
diff --git a/gcc/libgdiagnostics.cc b/gcc/libgdiagnostics.cc
index 00f8fefe838e..126ba747f796 100644
--- a/gcc/libgdiagnostics.cc
+++ b/gcc/libgdiagnostics.cc
@@ -18,6 +18,7 @@ along with GCC; see the file COPYING3.  If not see
 <http://www.gnu.org/licenses/>.  */
 
 #include "config.h"
+#define INCLUDE_MAP
 #define INCLUDE_VECTOR
 #include "system.h"
 #include "coretypes.h"
@@ -43,6 +44,15 @@ public:
   : m_str (str ? ::xstrdup (str) : nullptr)
   {
   }
+  owned_nullable_string (const owned_nullable_string &other)
+  : m_str (other.xstrdup ())
+  {
+  }
+  owned_nullable_string (owned_nullable_string &&other)
+  {
+    m_str = other.m_str;
+    other.m_str = nullptr;
+  }
 
   ~owned_nullable_string ()
   {
@@ -62,6 +72,16 @@ public:
     return m_str ? ::xstrdup (m_str) : nullptr;
   }
 
+  bool
+  operator< (const owned_nullable_string &other) const
+  {
+    if (m_str && other.m_str)
+      return strcmp (m_str, other.m_str) < 0;
+    if (m_str == nullptr && other.m_str != nullptr)
+      return true;
+    return false;
+  }
+
 private:
   char *m_str;
 };
@@ -205,6 +225,23 @@ struct diagnostic_logical_location : public 
logical_location
     return label_text::borrow (m_short_name.get_str ());
   }
 
+  bool
+  operator< (const diagnostic_logical_location &other) const
+  {
+    if (m_kind < other.m_kind)
+      return true;
+    if (m_parent < other.m_parent)
+      return true;
+    if (m_short_name < other.m_short_name)
+      return true;
+    if (m_fully_qualified_name < other.m_fully_qualified_name)
+      return true;
+    if (m_decorated_name < other.m_decorated_name)
+      return true;
+
+    return false;
+  }
+
 private:
   enum diagnostic_logical_location_kind_t m_kind;
   const diagnostic_logical_location *m_parent;
@@ -445,6 +482,16 @@ public:
                        const char *fully_qualified_name,
                        const char *decorated_name)
   {
+    /* Use m_logical_locs to "uniquify" instances.  */
+    diagnostic_logical_location key (kind,
+                                    parent,
+                                    short_name,
+                                    fully_qualified_name,
+                                    decorated_name);
+    auto iter = m_logical_locs.find (key);
+    if (iter != m_logical_locs.end ())
+      return (*iter).second.get ();
+
     std::unique_ptr<diagnostic_logical_location> logical_loc
       = ::make_unique<diagnostic_logical_location> (kind,
                                                    parent,
@@ -452,7 +499,9 @@ public:
                                                    fully_qualified_name,
                                                    decorated_name);
     const diagnostic_logical_location *result = logical_loc.get ();
-    m_logical_locs.push_back (std::move (logical_loc));
+    m_logical_locs.insert
+      (logical_locs_map_t::value_type (std::move (key),
+                                      std::move (logical_loc)));
     return result;
   }
 
@@ -552,7 +601,9 @@ private:
   hash_map<nofree_string_hash, diagnostic_file *> m_str_to_file_map;
   hash_map<int_hash<location_t, UNKNOWN_LOCATION, location_t (-1)>,
           diagnostic_physical_location *> m_location_t_map;
-  std::vector<std::unique_ptr<diagnostic_logical_location>> m_logical_locs;
+  typedef std::map<diagnostic_logical_location,
+                  std::unique_ptr<diagnostic_logical_location>> 
logical_locs_map_t;
+  logical_locs_map_t m_logical_locs;
   const diagnostic *m_current_diag;
   const diagnostic_logical_location *m_prev_diag_logical_loc;
   std::unique_ptr<edit_context> m_edit_context;
@@ -758,8 +809,7 @@ struct diagnostic_execution_path : public diagnostic_path
     const logical_location *logical_loc_b
       = m_events[event_idx_b]->get_logical_location ();
 
-    // TODO:
-    /* Pointer equality, so we may want to uniqify logical loc ptrs.  */
+    /* Pointer equality, as we uniqify logical location instances.  */
     return logical_loc_a == logical_loc_b;
   }
 
diff --git a/gcc/testsuite/libgdiagnostics.dg/test-logical-location.c 
b/gcc/testsuite/libgdiagnostics.dg/test-logical-location.c
index d853983b2bcf..140891938970 100644
--- a/gcc/testsuite/libgdiagnostics.dg/test-logical-location.c
+++ b/gcc/testsuite/libgdiagnostics.dg/test-logical-location.c
@@ -19,6 +19,8 @@ PRINT "hello world!";
 */
 const int line_num = __LINE__ - 2;
 
+#include <assert.h>
+
 int
 main ()
 {
@@ -60,6 +62,17 @@ main ()
   diagnostic_finish (d, "can't find %qs", "foo");
   /* end quoted source */
 
+  /* Verify that creating a diagnostic_logical_location with equal values 
+     yields the same instance.  */
+  const diagnostic_logical_location *dup
+    = diagnostic_manager_new_logical_location (diag_mgr,
+                                              
DIAGNOSTIC_LOGICAL_LOCATION_KIND_FUNCTION,
+                                              NULL, /* parent */
+                                              "test_short_name",
+                                              "test_qualified_name",
+                                              "test_decorated_name");
+  assert (dup == logical_loc); 
+
   return end_test ();
 }
 
diff --git 
a/gcc/testsuite/sarif-replay.dg/2.1.0-valid/malloc-vs-local-4.c.sarif 
b/gcc/testsuite/sarif-replay.dg/2.1.0-valid/malloc-vs-local-4.c.sarif
new file mode 100644
index 000000000000..5fd8e628b47d
--- /dev/null
+++ b/gcc/testsuite/sarif-replay.dg/2.1.0-valid/malloc-vs-local-4.c.sarif
@@ -0,0 +1,402 @@
+/* Test a replay of a .sarif file generated from GCC testsuite.
+
+   The dg directives were stripped out from the generated .sarif
+   to avoid confusing DejaGnu for this test.   */
+
+{"$schema": 
"https://docs.oasis-open.org/sarif/sarif/v2.1.0/errata01/os/schemas/sarif-schema-2.1.0.json";,
+ "version": "2.1.0",
+ "runs": [{"tool": {"driver": {"name": "GNU C23",
+                               "fullName": "GNU C23 (GCC) version 15.0.0 
20241211 (experimental) (x86_64-pc-linux-gnu)",
+                               "version": "15.0.0 20241211 (experimental)",
+                               "informationUri": "https://gcc.gnu.org/gcc-15/";,
+                               "rules": [{"id": 
"-Wanalyzer-possible-null-dereference",
+                                          "helpUri": 
"https://gcc.gnu.org/onlinedocs/gcc/Static-Analyzer-Options.html#index-Wanalyzer-possible-null-dereference"},
+                                         {"id": "-Wanalyzer-double-free",
+                                          "helpUri": 
"https://gcc.gnu.org/onlinedocs/gcc/Static-Analyzer-Options.html#index-Wanalyzer-double-free"}]}},
+           "taxonomies": [{"name": "CWE",
+                           "version": "4.7",
+                           "organization": "MITRE",
+                           "shortDescription": {"text": "The MITRE Common 
Weakness Enumeration"},
+                           "taxa": [{"id": "690",
+                                     "helpUri": 
"https://cwe.mitre.org/data/definitions/690.html"},
+                                    {"id": "415",
+                                     "helpUri": 
"https://cwe.mitre.org/data/definitions/415.html"}]}],
+           "invocations": [{"arguments": ["./cc1",
+                                          "-quiet",
+                                          "-iprefix",
+                                          
"/home/david/coding/gcc-newgit-more-taint/build-with-libgdiagnostics/gcc/../lib/gcc/x86_64-pc-linux-gnu/15.0.0/",
+                                          "-isystem",
+                                          "./include",
+                                          "-isystem",
+                                          "./include-fixed",
+                                          
"/not/a/real/path/malloc-vs-local-4.c",
+                                          "-quiet",
+                                          "-dumpbase",
+                                          "malloc-vs-local-4.c",
+                                          "-dumpbase-ext",
+                                          ".c",
+                                          "-mtune=generic",
+                                          "-march=x86-64",
+                                          "-fanalyzer",
+                                          "-fdiagnostics-add-output=sarif",
+                                          "-o",
+                                          "malloc-vs-local-4.s"],
+                            "workingDirectory": {"uri": 
"/home/david/coding/gcc-newgit-more-taint/build-with-libgdiagnostics/gcc"},
+                            "startTimeUtc": "2024-12-12T22:09:12Z",
+                            "executionSuccessful": true,
+                            "toolExecutionNotifications": [],
+                            "endTimeUtc": "2024-12-12T22:09:12Z"}],
+           "originalUriBaseIds": {"PWD": {"uri": 
"file:///home/david/coding/gcc-newgit-more-taint/build-with-libgdiagnostics/gcc/"}},
+           "artifacts": [{"location": {"uri": 
"/not/a/real/path/malloc-vs-local-4.c",
+                                       "uriBaseId": "PWD"},
+                          "sourceLanguage": "c",
+                          "contents": {"text": "#include <stdlib.h>\n\nvoid 
__attribute__((noinline)) callee_1 (int *ptr)\n{\n  *ptr = 42; \n}\n\nint 
test_1 (int i, int flag)\n{\n  /* Double diamond CFG; either use &i, or a 
malloc-ed buffer.  */\n  int *ptr = &i;\n  if (flag)\n    ptr = (int *)malloc 
(sizeof (int));\n  callee_1 (ptr);\n  if (flag)\n    free (ptr);\n  return 
i;\n}\n\nvoid __attribute__((noinline)) callee_2 (int *ptr)\n{\n  *ptr = 
42;\n}\n\nint test_2 (int flag)\n{\n  int i;\n\n  if (flag)\n    callee_2 
(&i);\n\n  callee_2 (&i);\n\n  if (!flag)\n    {\n      void *ptr = malloc 
(16);\n      free (ptr);\n      free (ptr);\n    }\n}\n"},
+                          "roles": ["analysisTarget",
+                                    "tracedFile"]}],
+           "results": [{"ruleId": "-Wanalyzer-possible-null-dereference",
+                        "taxa": [{"id": "690",
+                                  "toolComponent": {"name": "cwe"}}],
+                        "properties": {"gcc/analyzer/saved_diagnostic/sm": 
"malloc",
+                                       "gcc/analyzer/saved_diagnostic/enode": 
78,
+                                       "gcc/analyzer/saved_diagnostic/snode": 
22,
+                                       "gcc/analyzer/saved_diagnostic/sval": 
"&HEAP_ALLOCATED_REGION(46)",
+                                       "gcc/analyzer/saved_diagnostic/state": 
"unchecked ({free})",
+                                       "gcc/analyzer/saved_diagnostic/idx": 1},
+                        "level": "warning",
+                        "message": {"text": "dereference of possibly-NULL 
‘ptr’"},
+                        "locations": [{"physicalLocation": 
{"artifactLocation": {"uri": "/not/a/real/path/malloc-vs-local-4.c",
+                                                                               
  "uriBaseId": "PWD"},
+                                                            "region": 
{"startLine": 5,
+                                                                       
"startColumn": 3,
+                                                                       
"endColumn": 12},
+                                                            "contextRegion": 
{"startLine": 5,
+                                                                              
"snippet": {"text": "  *ptr = 42;\n"}}},
+                                       "logicalLocations": [{"name": 
"callee_1",
+                                                             
"fullyQualifiedName": "callee_1",
+                                                             "decoratedName": 
"callee_1",
+                                                             "kind": 
"function"}]}],
+                        "codeFlows": [{"threadFlows": [{"id": "main",
+                                                        "locations": 
[{"properties": {"gcc/analyzer/checker_event/emission_id": "(1)",
+                                                                               
       "gcc/analyzer/checker_event/kind": "EK_FUNCTION_ENTRY"},
+                                                                       
"location": {"physicalLocation": {"artifactLocation": {"uri": 
"/not/a/real/path/malloc-vs-local-4.c",
+                                                                               
                                               "uriBaseId": "PWD"},
+                                                                               
                          "region": {"startLine": 8,
+                                                                               
                                     "startColumn": 5,
+                                                                               
                                     "endColumn": 11},
+                                                                               
                          "contextRegion": {"startLine": 8,
+                                                                               
                                            "snippet": {"text": "int test_1 
(int i, int flag)\n"}}},
+                                                                               
     "logicalLocations": [{"name": "test_1",
+                                                                               
                           "fullyQualifiedName": "test_1",
+                                                                               
                           "decoratedName": "test_1",
+                                                                               
                           "kind": "function"}],
+                                                                               
     "message": {"text": "entry to ‘test_1’"}},
+                                                                       
"kinds": ["enter",
+                                                                               
  "function"],
+                                                                       
"nestingLevel": 1,
+                                                                       
"executionOrder": 1},
+                                                                      
{"properties": {"gcc/analyzer/checker_event/emission_id": "(2)",
+                                                                               
       "gcc/analyzer/checker_event/kind": "EK_START_CFG_EDGE",
+                                                                               
       "gcc/analyzer/superedge_event/superedge": {"kind": "SUPEREDGE_CFG_EDGE",
+                                                                               
                                                  "src_idx": 13,
+                                                                               
                                                  "dst_idx": 14,
+                                                                               
                                                  "desc": "true (flags 
TRUE_VALUE) (has goto_locus)"}},
+                                                                       
"location": {"physicalLocation": {"artifactLocation": {"uri": 
"/not/a/real/path/malloc-vs-local-4.c",
+                                                                               
                                               "uriBaseId": "PWD"},
+                                                                               
                          "region": {"startLine": 12,
+                                                                               
                                     "startColumn": 6,
+                                                                               
                                     "endColumn": 7},
+                                                                               
                          "contextRegion": {"startLine": 12,
+                                                                               
                                            "snippet": {"text": "  if 
(flag)\n"}}},
+                                                                               
     "logicalLocations": [{"name": "test_1",
+                                                                               
                           "fullyQualifiedName": "test_1",
+                                                                               
                           "decoratedName": "test_1",
+                                                                               
                           "kind": "function"}],
+                                                                               
     "message": {"text": "following ‘true’ branch (when ‘flag != 0’)..."}},
+                                                                       
"kinds": ["branch",
+                                                                               
  "true"],
+                                                                       
"nestingLevel": 1,
+                                                                       
"executionOrder": 2},
+                                                                      
{"properties": {"gcc/analyzer/checker_event/emission_id": "(3)",
+                                                                               
       "gcc/analyzer/checker_event/kind": "EK_END_CFG_EDGE",
+                                                                               
       "gcc/analyzer/superedge_event/superedge": {"kind": "SUPEREDGE_CFG_EDGE",
+                                                                               
                                                  "src_idx": 13,
+                                                                               
                                                  "dst_idx": 14,
+                                                                               
                                                  "desc": "true (flags 
TRUE_VALUE) (has goto_locus)"}},
+                                                                       
"location": {"physicalLocation": {"artifactLocation": {"uri": 
"/not/a/real/path/malloc-vs-local-4.c",
+                                                                               
                                               "uriBaseId": "PWD"},
+                                                                               
                          "region": {"startLine": 13,
+                                                                               
                                     "startColumn": 18,
+                                                                               
                                     "endColumn": 39},
+                                                                               
                          "contextRegion": {"startLine": 13,
+                                                                               
                                            "snippet": {"text": "    ptr = (int 
*)malloc (sizeof (int));\n"}}},
+                                                                               
     "logicalLocations": [{"name": "test_1",
+                                                                               
                           "fullyQualifiedName": "test_1",
+                                                                               
                           "decoratedName": "test_1",
+                                                                               
                           "kind": "function"}],
+                                                                               
     "message": {"text": "...to here"}},
+                                                                       
"kinds": ["branch",
+                                                                               
  "true"],
+                                                                       
"nestingLevel": 1,
+                                                                       
"executionOrder": 3},
+                                                                      
{"properties": {"gcc/analyzer/checker_event/emission_id": "(4)",
+                                                                               
       "gcc/analyzer/checker_event/kind": "EK_STATE_CHANGE"},
+                                                                       
"location": {"physicalLocation": {"artifactLocation": {"uri": 
"/not/a/real/path/malloc-vs-local-4.c",
+                                                                               
                                               "uriBaseId": "PWD"},
+                                                                               
                          "region": {"startLine": 13,
+                                                                               
                                     "startColumn": 18,
+                                                                               
                                     "endColumn": 39},
+                                                                               
                          "contextRegion": {"startLine": 13,
+                                                                               
                                            "snippet": {"text": "    ptr = (int 
*)malloc (sizeof (int));\n"}}},
+                                                                               
     "logicalLocations": [{"name": "test_1",
+                                                                               
                           "fullyQualifiedName": "test_1",
+                                                                               
                           "decoratedName": "test_1",
+                                                                               
                           "kind": "function"}],
+                                                                               
     "message": {"text": "this call could return NULL"}},
+                                                                       
"kinds": ["acquire",
+                                                                               
  "memory"],
+                                                                       
"nestingLevel": 1,
+                                                                       
"executionOrder": 4},
+                                                                      
{"properties": {"gcc/analyzer/checker_event/emission_id": "(5)",
+                                                                               
       "gcc/analyzer/checker_event/kind": "EK_CALL_EDGE",
+                                                                               
       "gcc/analyzer/superedge_event/superedge": {"kind": "SUPEREDGE_CALL",
+                                                                               
                                                  "src_idx": 15,
+                                                                               
                                                  "dst_idx": 21,
+                                                                               
                                                  "desc": "call"}},
+                                                                       
"location": {"physicalLocation": {"artifactLocation": {"uri": 
"/not/a/real/path/malloc-vs-local-4.c",
+                                                                               
                                               "uriBaseId": "PWD"},
+                                                                               
                          "region": {"startLine": 14,
+                                                                               
                                     "startColumn": 3,
+                                                                               
                                     "endColumn": 17},
+                                                                               
                          "contextRegion": {"startLine": 14,
+                                                                               
                                            "snippet": {"text": "  callee_1 
(ptr);\n"}}},
+                                                                               
     "logicalLocations": [{"name": "test_1",
+                                                                               
                           "fullyQualifiedName": "test_1",
+                                                                               
                           "decoratedName": "test_1",
+                                                                               
                           "kind": "function"}],
+                                                                               
     "message": {"text": "calling ‘callee_1’ from ‘test_1’"}},
+                                                                       
"kinds": ["call",
+                                                                               
  "function"],
+                                                                       
"nestingLevel": 1,
+                                                                       
"executionOrder": 5},
+                                                                      
{"properties": {"gcc/analyzer/checker_event/emission_id": "(6)",
+                                                                               
       "gcc/analyzer/checker_event/kind": "EK_FUNCTION_ENTRY"},
+                                                                       
"location": {"physicalLocation": {"artifactLocation": {"uri": 
"/not/a/real/path/malloc-vs-local-4.c",
+                                                                               
                                               "uriBaseId": "PWD"},
+                                                                               
                          "region": {"startLine": 3,
+                                                                               
                                     "startColumn": 32,
+                                                                               
                                     "endColumn": 40},
+                                                                               
                          "contextRegion": {"startLine": 3,
+                                                                               
                                            "snippet": {"text": "void 
__attribute__((noinline)) callee_1 (int *ptr)\n"}}},
+                                                                               
     "logicalLocations": [{"name": "callee_1",
+                                                                               
                           "fullyQualifiedName": "callee_1",
+                                                                               
                           "decoratedName": "callee_1",
+                                                                               
                           "kind": "function"}],
+                                                                               
     "message": {"text": "entry to ‘callee_1’"}},
+                                                                       
"kinds": ["enter",
+                                                                               
  "function"],
+                                                                       
"nestingLevel": 2,
+                                                                       
"executionOrder": 6},
+                                                                      
{"properties": {"gcc/analyzer/checker_event/emission_id": "(7)",
+                                                                               
       "gcc/analyzer/checker_event/kind": "EK_WARNING"},
+                                                                       
"location": {"physicalLocation": {"artifactLocation": {"uri": 
"/not/a/real/path/malloc-vs-local-4.c",
+                                                                               
                                               "uriBaseId": "PWD"},
+                                                                               
                          "region": {"startLine": 5,
+                                                                               
                                     "startColumn": 3,
+                                                                               
                                     "endColumn": 12},
+                                                                               
                          "contextRegion": {"startLine": 5,
+                                                                               
                                            "snippet": {"text": "  *ptr = 
42;\n"}}},
+                                                                               
     "logicalLocations": [{"name": "callee_1",
+                                                                               
                           "fullyQualifiedName": "callee_1",
+                                                                               
                           "decoratedName": "callee_1",
+                                                                               
                           "kind": "function"}],
+                                                                               
     "message": {"text": "‘ptr’ could be NULL: unchecked value from 
[(4)](sarif:/runs/0/results/0/codeFlows/0/threadFlows/0/locations/3)"}},
+                                                                       
"kinds": ["danger"],
+                                                                       
"nestingLevel": 2,
+                                                                       
"executionOrder": 7}]}]}]},
+                       {"ruleId": "-Wanalyzer-double-free",
+                        "taxa": [{"id": "415",
+                                  "toolComponent": {"name": "cwe"}}],
+                        "properties": {"gcc/analyzer/saved_diagnostic/sm": 
"malloc",
+                                       "gcc/analyzer/saved_diagnostic/enode": 
39,
+                                       "gcc/analyzer/saved_diagnostic/snode": 
6,
+                                       "gcc/analyzer/saved_diagnostic/sval": 
"&HEAP_ALLOCATED_REGION(46)",
+                                       "gcc/analyzer/saved_diagnostic/state": 
"freed",
+                                       "gcc/analyzer/saved_diagnostic/idx": 0},
+                        "level": "warning",
+                        "message": {"text": "double-‘free’ of ‘ptr’"},
+                        "locations": [{"physicalLocation": 
{"artifactLocation": {"uri": "/not/a/real/path/malloc-vs-local-4.c",
+                                                                               
  "uriBaseId": "PWD"},
+                                                            "region": 
{"startLine": 38,
+                                                                       
"startColumn": 7,
+                                                                       
"endColumn": 17},
+                                                            "contextRegion": 
{"startLine": 38,
+                                                                              
"snippet": {"text": "      free (ptr);\n"}}},
+                                       "logicalLocations": [{"name": "test_2",
+                                                             
"fullyQualifiedName": "test_2",
+                                                             "decoratedName": 
"test_2",
+                                                             "kind": 
"function"}]}],
+                        "codeFlows": [{"threadFlows": [{"id": "main",
+                                                        "locations": 
[{"properties": {"gcc/analyzer/checker_event/emission_id": "(1)",
+                                                                               
       "gcc/analyzer/checker_event/kind": "EK_START_CFG_EDGE",
+                                                                               
       "gcc/analyzer/superedge_event/superedge": {"kind": "SUPEREDGE_CFG_EDGE",
+                                                                               
                                                  "src_idx": 5,
+                                                                               
                                                  "dst_idx": 6,
+                                                                               
                                                  "desc": "true (flags 
TRUE_VALUE) (has goto_locus)"}},
+                                                                       
"location": {"physicalLocation": {"artifactLocation": {"uri": 
"/not/a/real/path/malloc-vs-local-4.c",
+                                                                               
                                               "uriBaseId": "PWD"},
+                                                                               
                          "region": {"startLine": 34,
+                                                                               
                                     "startColumn": 6,
+                                                                               
                                     "endColumn": 7},
+                                                                               
                          "contextRegion": {"startLine": 34,
+                                                                               
                                            "snippet": {"text": "  if 
(!flag)\n"}}},
+                                                                               
     "logicalLocations": [{"name": "test_2",
+                                                                               
                           "fullyQualifiedName": "test_2",
+                                                                               
                           "decoratedName": "test_2",
+                                                                               
                           "kind": "function"}],
+                                                                               
     "message": {"text": "following ‘true’ branch (when ‘flag == 0’)..."}},
+                                                                       
"kinds": ["branch",
+                                                                               
  "true"],
+                                                                       
"nestingLevel": 1,
+                                                                       
"executionOrder": 1},
+                                                                      
{"properties": {"gcc/analyzer/checker_event/emission_id": "(2)",
+                                                                               
       "gcc/analyzer/checker_event/kind": "EK_END_CFG_EDGE",
+                                                                               
       "gcc/analyzer/superedge_event/superedge": {"kind": "SUPEREDGE_CFG_EDGE",
+                                                                               
                                                  "src_idx": 5,
+                                                                               
                                                  "dst_idx": 6,
+                                                                               
                                                  "desc": "true (flags 
TRUE_VALUE) (has goto_locus)"}},
+                                                                       
"location": {"physicalLocation": {"artifactLocation": {"uri": 
"/not/a/real/path/malloc-vs-local-4.c",
+                                                                               
                                               "uriBaseId": "PWD"},
+                                                                               
                          "region": {"startLine": 36,
+                                                                               
                                     "startColumn": 19,
+                                                                               
                                     "endColumn": 30},
+                                                                               
                          "contextRegion": {"startLine": 36,
+                                                                               
                                            "snippet": {"text": "      void 
*ptr = malloc (16);\n"}}},
+                                                                               
     "logicalLocations": [{"name": "test_2",
+                                                                               
                           "fullyQualifiedName": "test_2",
+                                                                               
                           "decoratedName": "test_2",
+                                                                               
                           "kind": "function"}],
+                                                                               
     "message": {"text": "...to here"}},
+                                                                       
"kinds": ["branch",
+                                                                               
  "true"],
+                                                                       
"nestingLevel": 1,
+                                                                       
"executionOrder": 2},
+                                                                      
{"properties": {"gcc/analyzer/checker_event/emission_id": "(3)",
+                                                                               
       "gcc/analyzer/checker_event/kind": "EK_STATE_CHANGE"},
+                                                                       
"location": {"physicalLocation": {"artifactLocation": {"uri": 
"/not/a/real/path/malloc-vs-local-4.c",
+                                                                               
                                               "uriBaseId": "PWD"},
+                                                                               
                          "region": {"startLine": 36,
+                                                                               
                                     "startColumn": 19,
+                                                                               
                                     "endColumn": 30},
+                                                                               
                          "contextRegion": {"startLine": 36,
+                                                                               
                                            "snippet": {"text": "      void 
*ptr = malloc (16);\n"}}},
+                                                                               
     "logicalLocations": [{"name": "test_2",
+                                                                               
                           "fullyQualifiedName": "test_2",
+                                                                               
                           "decoratedName": "test_2",
+                                                                               
                           "kind": "function"}],
+                                                                               
     "message": {"text": "allocated here"}},
+                                                                       
"kinds": ["acquire",
+                                                                               
  "memory"],
+                                                                       
"nestingLevel": 1,
+                                                                       
"executionOrder": 3},
+                                                                      
{"properties": {"gcc/analyzer/checker_event/emission_id": "(4)",
+                                                                               
       "gcc/analyzer/checker_event/kind": "EK_STATE_CHANGE"},
+                                                                       
"location": {"physicalLocation": {"artifactLocation": {"uri": 
"/not/a/real/path/malloc-vs-local-4.c",
+                                                                               
                                               "uriBaseId": "PWD"},
+                                                                               
                          "region": {"startLine": 37,
+                                                                               
                                     "startColumn": 7,
+                                                                               
                                     "endColumn": 17},
+                                                                               
                          "contextRegion": {"startLine": 37,
+                                                                               
                                            "snippet": {"text": "      free 
(ptr);\n"}}},
+                                                                               
     "logicalLocations": [{"name": "test_2",
+                                                                               
                           "fullyQualifiedName": "test_2",
+                                                                               
                           "decoratedName": "test_2",
+                                                                               
                           "kind": "function"}],
+                                                                               
     "message": {"text": "first ‘free’ here"}},
+                                                                       
"kinds": ["release",
+                                                                               
  "memory"],
+                                                                       
"nestingLevel": 1,
+                                                                       
"executionOrder": 4},
+                                                                      
{"properties": {"gcc/analyzer/checker_event/emission_id": "(5)",
+                                                                               
       "gcc/analyzer/checker_event/kind": "EK_WARNING"},
+                                                                       
"location": {"physicalLocation": {"artifactLocation": {"uri": 
"/not/a/real/path/malloc-vs-local-4.c",
+                                                                               
                                               "uriBaseId": "PWD"},
+                                                                               
                          "region": {"startLine": 38,
+                                                                               
                                     "startColumn": 7,
+                                                                               
                                     "endColumn": 17},
+                                                                               
                          "contextRegion": {"startLine": 38,
+                                                                               
                                            "snippet": {"text": "      free 
(ptr);\n"}}},
+                                                                               
     "logicalLocations": [{"name": "test_2",
+                                                                               
                           "fullyQualifiedName": "test_2",
+                                                                               
                           "decoratedName": "test_2",
+                                                                               
                           "kind": "function"}],
+                                                                               
     "message": {"text": "second ‘free’ here; first ‘free’ was at 
[(4)](sarif:/runs/0/results/1/codeFlows/0/threadFlows/0/locations/3)"}},
+                                                                       
"kinds": ["danger"],
+                                                                       
"nestingLevel": 1,
+                                                                       
"executionOrder": 5}]}]}]}]}]}
+// TODO: show the CWEs
+// TODO: fix URL in message
+
+/* { dg-begin-multiline-output "" }
+In function 'callee_1':
+/not/a/real/path/malloc-vs-local-4.c:5:3: warning: dereference of 
possibly-NULL ‘ptr’ [-Wanalyzer-possible-null-dereference]
+    5 |   *ptr = 42;
+      |   ^~~~~~~~~~
+  'test_1': events 1-5
+    |
+    |    8 | int test_1 (int i, int flag)
+    |      |     ^~~~~~~
+    |      |     |
+    |      |     (1) entry to ‘test_1’
+    |......
+    |   12 |   if (flag)
+    |      |      ~~
+    |      |      |
+    |      |      (2) following ‘true’ branch (when ‘flag != 0’)...
+    |   13 |     ptr = (int *)malloc (sizeof (int));
+    |      |                  ~~~~~~~~~~~~~~~~~~~~~~
+    |      |                  |
+    |      |                  (3) ...to here
+    |      |                  (4) this call could return NULL
+    |   14 |   callee_1 (ptr);
+    |      |   ~~~~~~~~~~~~~~~
+    |      |   |
+    |      |   (5) calling ‘callee_1’ from ‘test_1’
+    |
+    +--> 'callee_1': events 6-7
+           |
+           |    3 | void __attribute__((noinline)) callee_1 (int *ptr)
+           |      |                                ^~~~~~~~~
+           |      |                                |
+           |      |                                (6) entry to ‘callee_1’
+           |    4 | {
+           |    5 |   *ptr = 42;
+           |      |   ~~~~~~~~~~                    
+           |      |   |
+           |      |   (7) ‘ptr’ could be NULL: unchecked value from 
[(4)](sarif:/runs/0/results/0/codeFlows/0/threadFlows/0/locations/3)
+           |
+   { dg-end-multiline-output "" } */
+/* { dg-begin-multiline-output "" }
+In function 'test_2':
+/not/a/real/path/malloc-vs-local-4.c:38:7: warning: double-‘free’ of ‘ptr’ 
[-Wanalyzer-double-free]
+   38 |       free (ptr);
+      |       ^~~~~~~~~~~
+  'test_2': events 1-5
+   34 |   if (!flag)
+      |      ^~
+      |      |
+      |      (1) following ‘true’ branch (when ‘flag == 0’)...
+   35 |     {
+   36 |       void *ptr = malloc (16);
+      |                   ~~~~~~~~~~~~
+      |                   |
+      |                   (2) ...to here
+      |                   (3) allocated here
+   37 |       free (ptr);
+      |       ~~~~~~~~~~~
+      |       |
+      |       (4) first ‘free’ here
+   38 |       free (ptr);
+      |       ~~~~~~~~~~~
+      |       |
+      |       (5) second ‘free’ here; first ‘free’ was at 
[(4)](sarif:/runs/0/results/1/codeFlows/0/threadFlows/0/locations/3)
+   { dg-end-multiline-output "" } */
diff --git a/gcc/testsuite/sarif-replay.dg/2.1.0-valid/signal-1.c.moved.sarif 
b/gcc/testsuite/sarif-replay.dg/2.1.0-valid/signal-1.c.moved.sarif
index eabab5a68cd3..f0026de12da4 100644
--- a/gcc/testsuite/sarif-replay.dg/2.1.0-valid/signal-1.c.moved.sarif
+++ b/gcc/testsuite/sarif-replay.dg/2.1.0-valid/signal-1.c.moved.sarif
@@ -167,20 +167,19 @@
 
 // TODO: show the CWE
 /* { dg-begin-multiline-output "" }
+In function 'custom_logger':
 signal-1.c:13:3: warning: call to ‘fprintf’ from within signal handler 
[-Wanalyzer-unsafe-call-within-signal-handler]
    13 |   fprintf(stderr, "LOG: %s", msg);
       |   ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-  'main': event 1
+  'main': events 1-2
     |
     |   21 | int main(int argc, const char *argv)
     |      |     ^~~~~
     |      |     |
     |      |     (1) entry to ‘main’
-    |
-  'main': event 2
-    |
+    |......
     |   25 |   signal(SIGINT, handler);
-    |      |   ^~~~~~~~~~~~~~~~~~~~~~~~
+    |      |   ~~~~~~~~~~~~~~~~~~~~~~~~
     |      |   |
     |      |   (2) registering ‘handler’ as signal handler
     |
@@ -189,31 +188,27 @@ signal-1.c:13:3: warning: call to ‘fprintf’ from within 
signal handler [-Wan
     |GNU C17:
     | (3): later on, when the signal is delivered to the process
     |
-    +--> 'handler': event 4
+    +--> 'handler': events 4-5
            |
            |   16 | static void handler(int signum)
            |      |             ^~~~~~~~
            |      |             |
            |      |             (4) entry to ‘handler’
-           |
-         'handler': event 5
-           |
+           |   17 | {
            |   18 |   custom_logger("got signal");
-           |      |   ^~~~~~~~~~~~~~~~~~~~~~~~~~~~
+           |      |   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
            |      |   |
            |      |   (5) calling ‘custom_logger’ from ‘handler’
            |
-           +--> 'custom_logger': event 6
+           +--> 'custom_logger': events 6-7
                   |
                   |   11 | void custom_logger(const char *msg)
                   |      |      ^~~~~~~~~~~~~~
                   |      |      |
                   |      |      (6) entry to ‘custom_logger’
-                  |
-                'custom_logger': event 7
-                  |
+                  |   12 | {
                   |   13 |   fprintf(stderr, "LOG: %s", msg);
-                  |      |   ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+                  |      |   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
                   |      |   |
                   |      |   (7) call to ‘fprintf’ from within signal handler
                   |
diff --git a/gcc/testsuite/sarif-replay.dg/2.1.0-valid/signal-1.c.sarif 
b/gcc/testsuite/sarif-replay.dg/2.1.0-valid/signal-1.c.sarif
index 81ac149e1253..e2f316b972e9 100644
--- a/gcc/testsuite/sarif-replay.dg/2.1.0-valid/signal-1.c.sarif
+++ b/gcc/testsuite/sarif-replay.dg/2.1.0-valid/signal-1.c.sarif
@@ -165,20 +165,19 @@
 
 // TODO: show the CWE
 /* { dg-begin-multiline-output "" }
+In function 'custom_logger':
 ../../src/gcc/testsuite/gcc.dg/analyzer/signal-1.c:13:3: warning: call to 
‘fprintf’ from within signal handler 
[-Wanalyzer-unsafe-call-within-signal-handler]
    13 |   fprintf(stderr, "LOG: %s", msg);
       |   ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-  'main': event 1
+  'main': events 1-2
     |
     |   21 | int main(int argc, const char *argv)
     |      |     ^~~~~
     |      |     |
     |      |     (1) entry to ‘main’
-    |
-  'main': event 2
-    |
+    |......
     |   25 |   signal(SIGINT, handler);
-    |      |   ^~~~~~~~~~~~~~~~~~~~~~~~
+    |      |   ~~~~~~~~~~~~~~~~~~~~~~~~
     |      |   |
     |      |   (2) registering ‘handler’ as signal handler
     |
@@ -187,31 +186,27 @@
     |GNU C17:
     | (3): later on, when the signal is delivered to the process
     |
-    +--> 'handler': event 4
+    +--> 'handler': events 4-5
            |
            |   16 | static void handler(int signum)
            |      |             ^~~~~~~~
            |      |             |
            |      |             (4) entry to ‘handler’
-           |
-         'handler': event 5
-           |
+           |   17 | {
            |   18 |   custom_logger("got signal");
-           |      |   ^~~~~~~~~~~~~~~~~~~~~~~~~~~~
+           |      |   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
            |      |   |
            |      |   (5) calling ‘custom_logger’ from ‘handler’
            |
-           +--> 'custom_logger': event 6
+           +--> 'custom_logger': events 6-7
                   |
                   |   11 | void custom_logger(const char *msg)
                   |      |      ^~~~~~~~~~~~~~
                   |      |      |
                   |      |      (6) entry to ‘custom_logger’
-                  |
-                'custom_logger': event 7
-                  |
+                  |   12 | {
                   |   13 |   fprintf(stderr, "LOG: %s", msg);
-                  |      |   ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+                  |      |   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
                   |      |   |
                   |      |   (7) call to ‘fprintf’ from within signal handler
                   |
diff --git a/gcc/testsuite/sarif-replay.dg/2.1.0-valid/spec-example-4.sarif 
b/gcc/testsuite/sarif-replay.dg/2.1.0-valid/spec-example-4.sarif
index 84d3f887cefd..60c87314e1c8 100644
--- a/gcc/testsuite/sarif-replay.dg/2.1.0-valid/spec-example-4.sarif
+++ b/gcc/testsuite/sarif-replay.dg/2.1.0-valid/spec-example-4.sarif
@@ -749,15 +749,8 @@
 /* { dg-begin-multiline-output "" }
 In function 'collections::list::add':
 collections/list.h:15:9: error: Variable "ptr" was used without being 
initialized. It was declared [here](0). [C2001]
-  event 1
-    |
-    |
-  event 2
-    |
-    |
-  event 3
-    |
-    |
+  events 1-3
+......
    { dg-end-multiline-output "" } */
 /* { dg-begin-multiline-output "" }
 collections/list.h:8:5: note: Variable "ptr" was declared here.

Reply via email to