aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Malcolm <dmalcolm@redhat.com>2024-08-06 18:24:45 -0400
committerDavid Malcolm <dmalcolm@redhat.com>2024-08-06 18:24:45 -0400
commit77f36e8016e11c051aa8264f3c43ab2c27aece55 (patch)
treebe6883ae4e6cb54137256cc9a8ba7b2553f36214
parenta50916a6c0a6c73c1537d033509d4f7034341f75 (diff)
downloadgcc-77f36e8016e11c051aa8264f3c43ab2c27aece55.zip
gcc-77f36e8016e11c051aa8264f3c43ab2c27aece55.tar.gz
gcc-77f36e8016e11c051aa8264f3c43ab2c27aece55.tar.bz2
diagnostics: SARIF output: fix "executionSuccessful" §3.20.14 [PR116177]
Previously the invocation's "executionSuccessful" property (§3.20.14) was only false if there was an ICE. Update it so that it will also be false if we will exit with a non-zero exit code (due to errors, Werror, and "sorry"). gcc/ChangeLog: PR other/116177 * diagnostic-format-sarif.cc (sarif_invocation::prepare_to_flush): If the diagnostics would lead to us exiting with a failure code, then emit "executionSuccessful": False (SARIF v2.1.0 section §3.20.14). * diagnostic.cc (diagnostic_context::execution_failed_p): New. * diagnostic.h (diagnostic_context::execution_failed_p): New decl. * toplev.cc (toplev::main): Use it for determining returned value. gcc/testsuite/ChangeLog: PR other/116177 * gcc.dg/sarif-output/include-chain-2.c: Remove pruning of "exit status is 1", as we expect this to exit with 0. * gcc.dg/sarif-output/no-diagnostics.c: New test. * gcc.dg/sarif-output/test-include-chain-1.py (test_execution_unsuccessful): Add. * gcc.dg/sarif-output/test-include-chain-2.py (test_execution_successful): Add. * gcc.dg/sarif-output/test-missing-semicolon.py (test_execution_unsuccessful): Add. * gcc.dg/sarif-output/test-no-diagnostics.py: New test. * gcc.dg/sarif-output/test-werror.py: New test. * gcc.dg/sarif-output/werror.c: New test. Signed-off-by: David Malcolm <dmalcolm@redhat.com>
-rw-r--r--gcc/diagnostic-format-sarif.cc2
-rw-r--r--gcc/diagnostic.cc13
-rw-r--r--gcc/diagnostic.h2
-rw-r--r--gcc/testsuite/gcc.dg/sarif-output/include-chain-2.c5
-rw-r--r--gcc/testsuite/gcc.dg/sarif-output/no-diagnostics.c13
-rw-r--r--gcc/testsuite/gcc.dg/sarif-output/test-include-chain-1.py11
-rw-r--r--gcc/testsuite/gcc.dg/sarif-output/test-include-chain-2.py11
-rw-r--r--gcc/testsuite/gcc.dg/sarif-output/test-missing-semicolon.py11
-rw-r--r--gcc/testsuite/gcc.dg/sarif-output/test-no-diagnostics.py31
-rw-r--r--gcc/testsuite/gcc.dg/sarif-output/test-werror.py39
-rw-r--r--gcc/testsuite/gcc.dg/sarif-output/werror.c18
-rw-r--r--gcc/toplev.cc2
12 files changed, 152 insertions, 6 deletions
diff --git a/gcc/diagnostic-format-sarif.cc b/gcc/diagnostic-format-sarif.cc
index 7c2e96f..963a185 100644
--- a/gcc/diagnostic-format-sarif.cc
+++ b/gcc/diagnostic-format-sarif.cc
@@ -811,6 +811,8 @@ void
sarif_invocation::prepare_to_flush (diagnostic_context &context)
{
/* "executionSuccessful" property (SARIF v2.1.0 section 3.20.14). */
+ if (context.execution_failed_p ())
+ m_success = false;
set_bool ("executionSuccessful", m_success);
/* "toolExecutionNotifications" property (SARIF v2.1.0 section 3.20.21). */
diff --git a/gcc/diagnostic.cc b/gcc/diagnostic.cc
index 71d2f44..3fc81ad 100644
--- a/gcc/diagnostic.cc
+++ b/gcc/diagnostic.cc
@@ -399,6 +399,19 @@ diagnostic_context::finish ()
m_original_argv = nullptr;
}
+/* Return true if sufficiently severe diagnostics have been seen that
+ we ought to exit with a non-zero exit code. */
+
+bool
+diagnostic_context::execution_failed_p () const
+{
+ /* Equivalent to (seen_error () || werrorcount), but on
+ this context, rather than global_dc. */
+ return (m_diagnostic_count [DK_ERROR]
+ || m_diagnostic_count [DK_SORRY]
+ || m_diagnostic_count [DK_WERROR]);
+}
+
void
diagnostic_context::set_output_format (diagnostic_output_format *output_format)
{
diff --git a/gcc/diagnostic.h b/gcc/diagnostic.h
index 79386cc..83180de 100644
--- a/gcc/diagnostic.h
+++ b/gcc/diagnostic.h
@@ -392,6 +392,8 @@ public:
void finish ();
+ bool execution_failed_p () const;
+
void set_original_argv (unique_argv original_argv);
const char * const *get_original_argv ()
{
diff --git a/gcc/testsuite/gcc.dg/sarif-output/include-chain-2.c b/gcc/testsuite/gcc.dg/sarif-output/include-chain-2.c
index 3f984f4..a04b647 100644
--- a/gcc/testsuite/gcc.dg/sarif-output/include-chain-2.c
+++ b/gcc/testsuite/gcc.dg/sarif-output/include-chain-2.c
@@ -27,11 +27,6 @@ PATH/include-chain-2.h:6:3: warning: double-'free' of 'ptr' [CWE-415] [-Wanalyze
#include "include-chain-2.h"
-/* We expect a failing compile due to the errors, but the use of
- -fdiagnostics-format=sarif-file means there should be no output to stderr.
- DejaGnu injects this message; ignore it:
- { dg-prune-output "exit status is 1" } */
-
/* Verify that some JSON was written to a file with the expected name:
{ dg-final { verify-sarif-file } } */
diff --git a/gcc/testsuite/gcc.dg/sarif-output/no-diagnostics.c b/gcc/testsuite/gcc.dg/sarif-output/no-diagnostics.c
new file mode 100644
index 0000000..2536e2e
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/sarif-output/no-diagnostics.c
@@ -0,0 +1,13 @@
+/* { dg-do compile } */
+/* { dg-options "-fdiagnostics-format=sarif-file" } */
+
+/* Verify our SARIF output for a translation unit with no diagnostics. */
+
+int nonempty;
+
+/* Verify that some JSON was written to a file with the expected name:
+ { dg-final { verify-sarif-file } } */
+
+/* Use a Python script to verify various properties about the generated
+ .sarif file:
+ { dg-final { run-sarif-pytest no-diagnostics.c "test-no-diagnostics.py" } } */
diff --git a/gcc/testsuite/gcc.dg/sarif-output/test-include-chain-1.py b/gcc/testsuite/gcc.dg/sarif-output/test-include-chain-1.py
index 16cd6a6..4bb2ebf 100644
--- a/gcc/testsuite/gcc.dg/sarif-output/test-include-chain-1.py
+++ b/gcc/testsuite/gcc.dg/sarif-output/test-include-chain-1.py
@@ -13,6 +13,17 @@ def test_basics(sarif):
version = sarif['version']
assert version == "2.1.0"
+def test_execution_unsuccessful(sarif):
+ runs = sarif['runs']
+ run = runs[0]
+
+ invocations = run['invocations']
+ assert len(invocations) == 1
+ invocation = invocations[0]
+
+ # We expect the errors to make executionSuccessful be false
+ assert invocation['executionSuccessful'] == False
+
def test_location_relationships(sarif):
runs = sarif['runs']
run = runs[0]
diff --git a/gcc/testsuite/gcc.dg/sarif-output/test-include-chain-2.py b/gcc/testsuite/gcc.dg/sarif-output/test-include-chain-2.py
index aea9aab..761fe1b 100644
--- a/gcc/testsuite/gcc.dg/sarif-output/test-include-chain-2.py
+++ b/gcc/testsuite/gcc.dg/sarif-output/test-include-chain-2.py
@@ -31,6 +31,17 @@ def test_basics(sarif):
version = sarif['version']
assert version == "2.1.0"
+def test_execution_successful(sarif):
+ runs = sarif['runs']
+ run = runs[0]
+
+ invocations = run['invocations']
+ assert len(invocations) == 1
+ invocation = invocations[0]
+
+ # We expect a mere 'warning' to allow executionSuccessful be true
+ assert invocation['executionSuccessful'] == True
+
def test_result(sarif):
runs = sarif['runs']
run = runs[0]
diff --git a/gcc/testsuite/gcc.dg/sarif-output/test-missing-semicolon.py b/gcc/testsuite/gcc.dg/sarif-output/test-missing-semicolon.py
index 795980d..17759d3 100644
--- a/gcc/testsuite/gcc.dg/sarif-output/test-missing-semicolon.py
+++ b/gcc/testsuite/gcc.dg/sarif-output/test-missing-semicolon.py
@@ -13,6 +13,17 @@ def test_basics(sarif):
version = sarif['version']
assert version == "2.1.0"
+def test_execution_unsuccessful(sarif):
+ runs = sarif['runs']
+ run = runs[0]
+
+ invocations = run['invocations']
+ assert len(invocations) == 1
+ invocation = invocations[0]
+
+ # We expect the 'error' to make executionSuccessful be false
+ assert invocation['executionSuccessful'] == False
+
def test_location_relationships(sarif):
runs = sarif['runs']
run = runs[0]
diff --git a/gcc/testsuite/gcc.dg/sarif-output/test-no-diagnostics.py b/gcc/testsuite/gcc.dg/sarif-output/test-no-diagnostics.py
new file mode 100644
index 0000000..f5812df
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/sarif-output/test-no-diagnostics.py
@@ -0,0 +1,31 @@
+from sarif import *
+
+import pytest
+
+@pytest.fixture(scope='function', autouse=True)
+def sarif():
+ return sarif_from_env()
+
+def test_basics(sarif):
+ schema = sarif['$schema']
+ assert schema == "https://raw.githubusercontent.com/oasis-tcs/sarif-spec/master/Schemata/sarif-schema-2.1.0.json"
+
+ version = sarif['version']
+ assert version == "2.1.0"
+
+def test_execution_successful(sarif):
+ runs = sarif['runs']
+ run = runs[0]
+
+ invocations = run['invocations']
+ assert len(invocations) == 1
+ invocation = invocations[0]
+
+ assert invocation['executionSuccessful'] == True
+ assert invocation['toolExecutionNotifications'] == []
+
+def test_empty_results(sarif):
+ runs = sarif['runs']
+ run = runs[0]
+ results = run['results']
+ assert len(results) == 0
diff --git a/gcc/testsuite/gcc.dg/sarif-output/test-werror.py b/gcc/testsuite/gcc.dg/sarif-output/test-werror.py
new file mode 100644
index 0000000..99c2c2c
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/sarif-output/test-werror.py
@@ -0,0 +1,39 @@
+from sarif import *
+
+import pytest
+
+@pytest.fixture(scope='function', autouse=True)
+def sarif():
+ return sarif_from_env()
+
+def test_basics(sarif):
+ schema = sarif['$schema']
+ assert schema == "https://raw.githubusercontent.com/oasis-tcs/sarif-spec/master/Schemata/sarif-schema-2.1.0.json"
+
+ version = sarif['version']
+ assert version == "2.1.0"
+
+def test_execution_unsuccessful(sarif):
+ runs = sarif['runs']
+ run = runs[0]
+
+ invocations = run['invocations']
+ assert len(invocations) == 1
+ invocation = invocations[0]
+
+ assert '-Werror=unused-variable' in invocation['arguments']
+
+ # We expect the 'Werror' to make executionSuccessful be false
+ assert invocation['executionSuccessful'] == False
+
+def test_result(sarif):
+ runs = sarif['runs']
+ run = runs[0]
+ results = run['results']
+
+ assert len(results) == 1
+
+ result = results[0]
+ assert result['ruleId'] == '-Werror=unused-variable'
+ assert result['level'] == 'error'
+ assert result['message']['text'] == "'ununsed' defined but not used"
diff --git a/gcc/testsuite/gcc.dg/sarif-output/werror.c b/gcc/testsuite/gcc.dg/sarif-output/werror.c
new file mode 100644
index 0000000..fa9eb9a
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/sarif-output/werror.c
@@ -0,0 +1,18 @@
+/* { dg-do compile } */
+/* { dg-options "-Werror=unused-variable -fdiagnostics-format=sarif-file" } */
+
+/* Verify our SARIF output for a translation unit with -Werror. */
+
+static int ununsed;
+
+/* We expect a failing compile due to the Werror, but the use of
+ -fdiagnostics-format=sarif-file means there should be no output to stderr.
+ DejaGnu injects this message; ignore it:
+ { dg-prune-output "exit status is 1" } */
+
+/* Verify that some JSON was written to a file with the expected name:
+ { dg-final { verify-sarif-file } } */
+
+/* Use a Python script to verify various properties about the generated
+ .sarif file:
+ { dg-final { run-sarif-pytest werror.c "test-werror.py" } } */
diff --git a/gcc/toplev.cc b/gcc/toplev.cc
index 7f19d5c..eee4805 100644
--- a/gcc/toplev.cc
+++ b/gcc/toplev.cc
@@ -2355,7 +2355,7 @@ toplev::main (int argc, char **argv)
after_memory_report = true;
- if (seen_error () || werrorcount)
+ if (global_dc->execution_failed_p ())
return (FATAL_EXIT_CODE);
return (SUCCESS_EXIT_CODE);