--- /dev/null
+/* 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 "" } */