aboutsummaryrefslogtreecommitdiff
path: root/gcc/testsuite/gcc.dg/plugin
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/testsuite/gcc.dg/plugin')
-rw-r--r--gcc/testsuite/gcc.dg/plugin/analyzer_cpython_plugin.cc1
-rw-r--r--gcc/testsuite/gcc.dg/plugin/analyzer_gil_plugin.cc9
-rw-r--r--gcc/testsuite/gcc.dg/plugin/analyzer_kernel_plugin.cc1
-rw-r--r--gcc/testsuite/gcc.dg/plugin/analyzer_known_fns_plugin.cc1
-rw-r--r--gcc/testsuite/gcc.dg/plugin/diagnostic-test-metadata-html.c15
-rw-r--r--gcc/testsuite/gcc.dg/plugin/diagnostic-test-metadata-html.py73
-rw-r--r--gcc/testsuite/gcc.dg/plugin/diagnostic-test-paths-2.c6
-rw-r--r--gcc/testsuite/gcc.dg/plugin/diagnostic-test-paths-2.py48
-rw-r--r--gcc/testsuite/gcc.dg/plugin/diagnostic-test-paths-3.c75
-rw-r--r--gcc/testsuite/gcc.dg/plugin/diagnostic-test-paths-4.c6
-rw-r--r--gcc/testsuite/gcc.dg/plugin/diagnostic-test-paths-4.py49
-rw-r--r--gcc/testsuite/gcc.dg/plugin/diagnostic-test-show-locus-bw-line-numbers.c6
-rw-r--r--gcc/testsuite/gcc.dg/plugin/diagnostic-test-show-locus.py115
-rw-r--r--gcc/testsuite/gcc.dg/plugin/diagnostic-test-xhtml-1.c19
-rw-r--r--gcc/testsuite/gcc.dg/plugin/diagnostic_group_plugin.cc3
-rw-r--r--gcc/testsuite/gcc.dg/plugin/diagnostic_plugin_test_paths.cc10
-rw-r--r--gcc/testsuite/gcc.dg/plugin/diagnostic_plugin_xhtml_format.cc985
-rw-r--r--gcc/testsuite/gcc.dg/plugin/location-overflow-test-pr116047-1.h6
-rw-r--r--gcc/testsuite/gcc.dg/plugin/location-overflow-test-pr116047-2.h1
-rw-r--r--gcc/testsuite/gcc.dg/plugin/location-overflow-test-pr116047.c5
-rw-r--r--gcc/testsuite/gcc.dg/plugin/location-overflow-test-pr120061-1.h6
-rw-r--r--gcc/testsuite/gcc.dg/plugin/location-overflow-test-pr120061-2.h1
-rw-r--r--gcc/testsuite/gcc.dg/plugin/location-overflow-test-pr120061.c6
-rw-r--r--gcc/testsuite/gcc.dg/plugin/location_overflow_plugin.cc15
-rw-r--r--gcc/testsuite/gcc.dg/plugin/plugin.exp8
25 files changed, 374 insertions, 1096 deletions
diff --git a/gcc/testsuite/gcc.dg/plugin/analyzer_cpython_plugin.cc b/gcc/testsuite/gcc.dg/plugin/analyzer_cpython_plugin.cc
index 0f1f864..1fe5b5c 100644
--- a/gcc/testsuite/gcc.dg/plugin/analyzer_cpython_plugin.cc
+++ b/gcc/testsuite/gcc.dg/plugin/analyzer_cpython_plugin.cc
@@ -2,6 +2,7 @@
/* { dg-options "-g" } */
#define INCLUDE_MEMORY
+#define INCLUDE_STRING
#define INCLUDE_VECTOR
#include "gcc-plugin.h"
#include "config.h"
diff --git a/gcc/testsuite/gcc.dg/plugin/analyzer_gil_plugin.cc b/gcc/testsuite/gcc.dg/plugin/analyzer_gil_plugin.cc
index 3cac3f8f..fa2f2fa 100644
--- a/gcc/testsuite/gcc.dg/plugin/analyzer_gil_plugin.cc
+++ b/gcc/testsuite/gcc.dg/plugin/analyzer_gil_plugin.cc
@@ -5,6 +5,7 @@
/* { dg-options "-g" } */
#define INCLUDE_MEMORY
+#define INCLUDE_STRING
#define INCLUDE_VECTOR
#include "gcc-plugin.h"
#include "config.h"
@@ -126,11 +127,11 @@ public:
if (change.is_global_p ())
{
if (change.m_new_state == m_sm.m_released_gil)
- return diagnostic_event::meaning (diagnostic_event::VERB_release,
- diagnostic_event::NOUN_lock);
+ return diagnostic_event::meaning (diagnostic_event::verb::release,
+ diagnostic_event::noun::lock);
else if (change.m_new_state == m_sm.get_start_state ())
- return diagnostic_event::meaning (diagnostic_event::VERB_acquire,
- diagnostic_event::NOUN_lock);
+ return diagnostic_event::meaning (diagnostic_event::verb::acquire,
+ diagnostic_event::noun::lock);
}
return diagnostic_event::meaning ();
}
diff --git a/gcc/testsuite/gcc.dg/plugin/analyzer_kernel_plugin.cc b/gcc/testsuite/gcc.dg/plugin/analyzer_kernel_plugin.cc
index 771ff75..18e054b 100644
--- a/gcc/testsuite/gcc.dg/plugin/analyzer_kernel_plugin.cc
+++ b/gcc/testsuite/gcc.dg/plugin/analyzer_kernel_plugin.cc
@@ -2,6 +2,7 @@
/* { dg-options "-g" } */
#define INCLUDE_MEMORY
+#define INCLUDE_STRING
#define INCLUDE_VECTOR
#include "gcc-plugin.h"
#include "config.h"
diff --git a/gcc/testsuite/gcc.dg/plugin/analyzer_known_fns_plugin.cc b/gcc/testsuite/gcc.dg/plugin/analyzer_known_fns_plugin.cc
index c7087f0..5a6e075 100644
--- a/gcc/testsuite/gcc.dg/plugin/analyzer_known_fns_plugin.cc
+++ b/gcc/testsuite/gcc.dg/plugin/analyzer_known_fns_plugin.cc
@@ -2,6 +2,7 @@
/* { dg-options "-g" } */
#define INCLUDE_MEMORY
+#define INCLUDE_STRING
#define INCLUDE_VECTOR
#include "gcc-plugin.h"
#include "config.h"
diff --git a/gcc/testsuite/gcc.dg/plugin/diagnostic-test-metadata-html.c b/gcc/testsuite/gcc.dg/plugin/diagnostic-test-metadata-html.c
new file mode 100644
index 0000000..df57b25
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/plugin/diagnostic-test-metadata-html.c
@@ -0,0 +1,15 @@
+/* { dg-do compile } */
+/* { dg-options "-fdiagnostics-set-output=experimental-html:javascript=no" } */
+/* { dg-additional-options "-fdiagnostics-show-caret -fdiagnostics-show-line-numbers" } */
+
+extern char *gets (char *s);
+
+void test_cwe (void)
+{
+ char buf[1024];
+ gets (buf);
+}
+
+/* Use a Python script to verify various properties about the generated
+ HTML file:
+ { dg-final { run-html-pytest diagnostic-test-metadata-html.c "diagnostic-test-metadata-html.py" } } */
diff --git a/gcc/testsuite/gcc.dg/plugin/diagnostic-test-metadata-html.py b/gcc/testsuite/gcc.dg/plugin/diagnostic-test-metadata-html.py
new file mode 100644
index 0000000..67fb241
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/plugin/diagnostic-test-metadata-html.py
@@ -0,0 +1,73 @@
+# Verify that metadata works in HTML output.
+
+from htmltest import *
+
+import pytest
+
+@pytest.fixture(scope='function', autouse=True)
+def html_tree():
+ return html_tree_from_env()
+
+def test_metadata(html_tree):
+ root = html_tree.getroot ()
+ assert root.tag == make_tag('html')
+
+ body = root.find('xhtml:body', ns)
+ assert body is not None
+
+ diag_list = body.find('xhtml:div', ns)
+ assert diag_list is not None
+ assert diag_list.attrib['class'] == 'gcc-diagnostic-list'
+
+ diag = diag_list.find('xhtml:div', ns)
+ assert diag is not None
+ assert diag.attrib['class'] == 'alert alert-warning'
+
+ icon = diag.find('xhtml:span', ns)
+ assert icon.attrib['class'] == 'pficon pficon-warning-triangle-o'
+
+ message = diag.find("./xhtml:div[@class='gcc-message']", ns)
+ assert message.attrib['id'] == 'gcc-diag-0-message'
+
+ assert message[0].tag == make_tag('strong')
+ assert message[0].text == 'warning: '
+ assert message[0].tail == " never use '"
+
+ assert message[1].tag == make_tag('span')
+ assert message[1].attrib['class'] == 'gcc-quoted-text'
+ assert message[1].text == 'gets'
+ assert message[1].tail == "' "
+
+ metadata = message[2]
+ assert metadata.attrib['class'] == 'gcc-metadata'
+ assert metadata[0].tag == make_tag('span')
+ assert metadata[0].attrib['class'] == 'gcc-metadata-item'
+ assert metadata[0].text == '['
+ assert metadata[0][0].tag == make_tag('a')
+ assert metadata[0][0].attrib['href'] == 'https://cwe.mitre.org/data/definitions/242.html'
+ assert metadata[0][0].text == 'CWE-242'
+ assert metadata[0][0].tail == ']'
+
+ assert metadata[1].tag == make_tag('span')
+ assert metadata[1].attrib['class'] == 'gcc-metadata-item'
+ assert metadata[1].text == '['
+ assert metadata[1][0].tag == make_tag('a')
+ assert metadata[1][0].attrib['href'] == 'https://example.com/'
+ assert metadata[1][0].text == 'STR34-C'
+ assert metadata[1][0].tail == ']'
+
+ src = diag.find('xhtml:table', ns)
+ assert src.attrib['class'] == 'locus'
+
+ tbody = src.find('xhtml:tbody', ns)
+ assert tbody.attrib['class'] == 'line-span'
+
+ rows = tbody.findall('xhtml:tr', ns)
+
+ quoted_src_tr = rows[0]
+ assert_quoted_line(quoted_src_tr,
+ ' 10', ' gets (buf);')
+
+ annotation_tr = rows[1]
+ assert_annotation_line(annotation_tr,
+ ' ^~~~~~~~~~')
diff --git a/gcc/testsuite/gcc.dg/plugin/diagnostic-test-paths-2.c b/gcc/testsuite/gcc.dg/plugin/diagnostic-test-paths-2.c
index b8134ae..dab9c38 100644
--- a/gcc/testsuite/gcc.dg/plugin/diagnostic-test-paths-2.c
+++ b/gcc/testsuite/gcc.dg/plugin/diagnostic-test-paths-2.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-options "-fdiagnostics-show-caret -fdiagnostics-show-line-numbers -fdiagnostics-path-format=inline-events" } */
+/* { dg-options "-fdiagnostics-show-caret -fdiagnostics-show-line-numbers -fdiagnostics-path-format=inline-events -fdiagnostics-add-output=experimental-html:javascript=no" } */
#include <stddef.h>
#include <stdlib.h>
@@ -52,3 +52,7 @@ make_a_list_of_random_ints_badly(PyObject *self,
| (3) when calling 'PyList_Append', passing NULL from (1) as argument 1
{ dg-end-multiline-output "" } */
}
+
+/* Use a Python script to verify various properties about the generated
+ HTML file:
+ { dg-final { run-html-pytest diagnostic-test-paths-2.c "diagnostic-test-paths-2.py" } } */
diff --git a/gcc/testsuite/gcc.dg/plugin/diagnostic-test-paths-2.py b/gcc/testsuite/gcc.dg/plugin/diagnostic-test-paths-2.py
new file mode 100644
index 0000000..f0fed45
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/plugin/diagnostic-test-paths-2.py
@@ -0,0 +1,48 @@
+# Verify that execution paths work in HTML output.
+
+from htmltest import *
+
+import pytest
+
+@pytest.fixture(scope='function', autouse=True)
+def html_tree():
+ return html_tree_from_env()
+
+def test_paths(html_tree):
+ root = html_tree.getroot ()
+ assert root.tag == make_tag('html')
+
+ body = root.find('xhtml:body', ns)
+ assert body is not None
+
+ diag_list = body.find('xhtml:div', ns)
+ assert diag_list is not None
+ assert diag_list.attrib['class'] == 'gcc-diagnostic-list'
+
+ diag = diag_list.find('xhtml:div', ns)
+ assert diag is not None
+ assert diag.attrib['class'] == 'alert alert-danger'
+ assert diag.attrib['id'] == 'gcc-diag-0'
+
+ exec_path = diag.find("./xhtml:div[@id='execution-path']", ns)
+ assert exec_path is not None
+
+ label = exec_path.find('xhtml:label', ns)
+ assert label.text == 'Execution path with 3 events'
+
+ event_ranges = exec_path.find('xhtml:div', ns)
+ assert_class(event_ranges, 'event-ranges')
+
+ frame_margin = event_ranges.find('xhtml:table', ns)
+ assert_class(frame_margin, 'stack-frame-with-margin')
+
+ tr = frame_margin.find('xhtml:tr', ns)
+ assert tr is not None
+ tds = tr.findall('xhtml:td', ns)
+ assert len(tds) == 2
+
+ assert_class(tds[0], 'interprocmargin')
+
+ test_frame = tds[1]
+ assert_frame(test_frame, 'make_a_list_of_random_ints_badly')
+ assert_event_range_with_margin(test_frame[1])
diff --git a/gcc/testsuite/gcc.dg/plugin/diagnostic-test-paths-3.c b/gcc/testsuite/gcc.dg/plugin/diagnostic-test-paths-3.c
deleted file mode 100644
index a315d20..0000000
--- a/gcc/testsuite/gcc.dg/plugin/diagnostic-test-paths-3.c
+++ /dev/null
@@ -1,75 +0,0 @@
-/* { dg-do compile } */
-/* { dg-options "-fdiagnostics-format=json" } */
-
-#include <stddef.h>
-#include <stdlib.h>
-
-/* Minimal reimplementation of cpython API. */
-typedef struct PyObject {} PyObject;
-extern int PyArg_ParseTuple (PyObject *args, const char *fmt, ...);
-extern PyObject *PyList_New (int);
-extern PyObject *PyLong_FromLong(long);
-extern void PyList_Append(PyObject *list, PyObject *item);
-
-PyObject *
-make_a_list_of_random_ints_badly(PyObject *self,
- PyObject *args)
-{
- PyObject *list, *item;
- long count, i;
-
- if (!PyArg_ParseTuple(args, "i", &count)) {
- return NULL;
- }
-
- list = PyList_New(0);
-
- for (i = 0; i < count; i++) {
- item = PyLong_FromLong(random());
- PyList_Append(list, item);
- }
-
- return list;
-}
-
-/* { dg-begin-multiline-output "" }
-[{"kind": "error",
- "message": "passing NULL as argument 1 to 'PyList_Append' which requires a non-NULL parameter",
- "children": [],
- "column-origin": 1,
- "locations": [{"caret": {"file": "
- "line": 29,
- "display-column": 5,
- "byte-column": 5,
- "column": 5},
- "finish": {"file": "
- "line": 29,
- "display-column": 29,
- "byte-column": 29,
- "column": 29}}],
- "path": [{"location": {"file": "
- "line": 25,
- "display-column": 10,
- "byte-column": 10,
- "column": 10},
- "description": "when 'PyList_New' fails, returning NULL",
- "function": "make_a_list_of_random_ints_badly",
- "depth": 0},
- {"location": {"file": "
- "line": 27,
- "display-column": 17,
- "byte-column": 17,
- "column": 17},
- "description": "when 'i < count'",
- "function": "make_a_list_of_random_ints_badly",
- "depth": 0},
- {"location": {"file": "
- "line": 29,
- "display-column": 5,
- "byte-column": 5,
- "column": 5},
- "description": "when calling 'PyList_Append', passing NULL from (1) as argument 1",
- "function": "make_a_list_of_random_ints_badly",
- "depth": 0}],
- "escape-source": false}]
-{ dg-end-multiline-output "" } */
diff --git a/gcc/testsuite/gcc.dg/plugin/diagnostic-test-paths-4.c b/gcc/testsuite/gcc.dg/plugin/diagnostic-test-paths-4.c
index 847b6d4..7eb0c50 100644
--- a/gcc/testsuite/gcc.dg/plugin/diagnostic-test-paths-4.c
+++ b/gcc/testsuite/gcc.dg/plugin/diagnostic-test-paths-4.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-options "-fdiagnostics-path-format=inline-events -fdiagnostics-show-caret -fdiagnostics-show-line-numbers" } */
+/* { dg-options "-fdiagnostics-path-format=inline-events -fdiagnostics-show-caret -fdiagnostics-show-line-numbers -fdiagnostics-add-output=experimental-html:javascript=no" } */
/* { dg-enable-nn-line-numbers "" } */
#include <stdio.h>
@@ -82,3 +82,7 @@ void test (void)
| | (9) calling 'fprintf'
|
{ dg-end-multiline-output "" } */
+
+/* Use a Python script to verify various properties about the generated
+ HTML file:
+ { dg-final { run-html-pytest diagnostic-test-paths-4.c "diagnostic-test-paths-4.py" } } */
diff --git a/gcc/testsuite/gcc.dg/plugin/diagnostic-test-paths-4.py b/gcc/testsuite/gcc.dg/plugin/diagnostic-test-paths-4.py
new file mode 100644
index 0000000..d2bc67c
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/plugin/diagnostic-test-paths-4.py
@@ -0,0 +1,49 @@
+# Verify that interprocedural execution paths work in HTML output.
+
+from htmltest import *
+
+import pytest
+
+@pytest.fixture(scope='function', autouse=True)
+def html_tree():
+ return html_tree_from_env()
+
+def test_paths(html_tree):
+ diag = get_diag_by_index(html_tree, 0)
+ src = get_locus_within_diag (diag)
+
+ tbody = src.find('xhtml:tbody', ns)
+ assert_class(tbody, 'line-span')
+
+ rows = tbody.findall('xhtml:tr', ns)
+
+ quoted_src_tr = rows[0]
+ assert_quoted_line(quoted_src_tr,
+ ' 13', ' fprintf(stderr, "LOG: %s", msg); /* { dg-warning "call to \'fprintf\' from within signal handler" } */')
+
+ annotation_tr = rows[1]
+ assert_annotation_line(annotation_tr,
+ ' ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~')
+
+ exec_path = diag.find("./xhtml:div[@id='execution-path']", ns)
+ assert exec_path is not None
+
+ label = exec_path.find('xhtml:label', ns)
+ assert label.text == 'Execution path with 9 events'
+
+ event_ranges = exec_path.find('xhtml:div', ns)
+ assert_class(event_ranges, 'event-ranges')
+
+ test_frame_margin = event_ranges.find('xhtml:table', ns)
+ assert_class(test_frame_margin, 'stack-frame-with-margin')
+
+ tr = test_frame_margin.find('xhtml:tr', ns)
+ assert tr is not None
+ tds = tr.findall('xhtml:td', ns)
+ assert len(tds) == 2
+
+ assert_class(tds[0], 'interprocmargin')
+
+ test_frame = tds[1]
+ assert_frame(test_frame, 'test')
+ assert_event_range_with_margin(test_frame[1])
diff --git a/gcc/testsuite/gcc.dg/plugin/diagnostic-test-show-locus-bw-line-numbers.c b/gcc/testsuite/gcc.dg/plugin/diagnostic-test-show-locus-bw-line-numbers.c
index 1e8f73b..e81856a 100644
--- a/gcc/testsuite/gcc.dg/plugin/diagnostic-test-show-locus-bw-line-numbers.c
+++ b/gcc/testsuite/gcc.dg/plugin/diagnostic-test-show-locus-bw-line-numbers.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-options "-O -fdiagnostics-show-caret -fdiagnostics-show-line-numbers" } */
+/* { dg-options "-O -fdiagnostics-show-caret -fdiagnostics-show-line-numbers -fdiagnostics-add-output=experimental-html:javascript=no" } */
/* This is a collection of unittests for diagnostic_show_locus;
see the overview in diagnostic_plugin_test_show_locus.c.
@@ -118,3 +118,7 @@ void test_fixit_insert_newline (void)
{ dg-end-multiline-output "" } */
#endif
}
+
+/* Use a Python script to verify various properties about the generated
+ HTML file:
+ { dg-final { run-html-pytest diagnostic-test-show-locus-bw-line-numbers.c "diagnostic-test-show-locus.py" } } */
diff --git a/gcc/testsuite/gcc.dg/plugin/diagnostic-test-show-locus.py b/gcc/testsuite/gcc.dg/plugin/diagnostic-test-show-locus.py
new file mode 100644
index 0000000..aca1b6c
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/plugin/diagnostic-test-show-locus.py
@@ -0,0 +1,115 @@
+# Verify that diagnostic-show-locus.cc works with HTML output.
+
+from htmltest import *
+
+import pytest
+
+@pytest.fixture(scope='function', autouse=True)
+def html_tree():
+ return html_tree_from_env()
+
+#def get_tr_within_thead(thead, idx)
+
+def get_ruler_text(thead, idx):
+ trs = thead.findall('xhtml:tr', ns)
+ tr = trs[idx]
+ tds = tr.findall('xhtml:td', ns)
+ assert len(tds) == 3
+ assert_class(tds[2], 'ruler')
+ return tds[2].text
+
+def test_very_wide_line(html_tree):
+ diag = get_diag_by_index(html_tree, 2)
+ src = get_locus_within_diag(diag)
+
+ # Check ruler
+ thead = src.find('xhtml:thead', ns)
+ assert_class(thead, 'ruler')
+ trs = thead.findall('xhtml:tr', ns)
+ assert len(trs) == 3
+
+ assert get_ruler_text(thead, 0) == ' 0 0 0 0 0 1 1 '
+ assert get_ruler_text(thead, 1) == ' 5 6 7 8 9 0 1 '
+ assert get_ruler_text(thead, 2) == '34567890123456789012345678901234567890123456789012345678901234567890123'
+
+ # Check quoted source
+ tbody = src.find('xhtml:tbody', ns)
+ assert_class(tbody, 'line-span')
+ trs = tbody.findall('xhtml:tr', ns)
+ assert len(trs) == 5
+ assert_quoted_line(trs[0], ' 43', ' float f = foo * bar; /* { dg-warning "95: test" } */')
+ assert_annotation_line(trs[1], ' ~~~~^~~~~')
+ assert_annotation_line(trs[2], ' |')
+ assert_annotation_line(trs[3], ' label 0')
+ assert_annotation_line(trs[4], ' bar * foo')
+
+def test_fixit_insert(html_tree):
+ diag = get_diag_by_index(html_tree, 3)
+ msg = get_message_within_diag(diag)
+ assert msg[0].text == 'warning: '
+ assert msg[0].tail == ' example of insertion hints'
+
+ src = get_locus_within_diag(diag)
+
+ # Check quoted source
+ tbody = src.find('xhtml:tbody', ns)
+ assert_class(tbody, 'line-span')
+ trs = tbody.findall('xhtml:tr', ns)
+ assert len(trs) == 3
+ assert_quoted_line(trs[0], ' 63', ' int a[2][2] = { 0, 1 , 2, 3 }; /* { dg-warning "insertion hints" } */')
+ assert_annotation_line(trs[1], ' ^~~~')
+ assert_annotation_line(trs[2], ' { }')
+
+def test_fixit_remove(html_tree):
+ diag = get_diag_by_index(html_tree, 4)
+ msg = get_message_within_diag(diag)
+ assert msg[0].text == 'warning: '
+ assert msg[0].tail == ' example of a removal hint'
+
+ src = get_locus_within_diag(diag)
+
+ # Check quoted source
+ tbody = src.find('xhtml:tbody', ns)
+ assert_class(tbody, 'line-span')
+ trs = tbody.findall('xhtml:tr', ns)
+ assert len(trs) == 3
+ assert_quoted_line(trs[0], ' 77', ' int a;; /* { dg-warning "example of a removal hint" } */')
+ assert_annotation_line(trs[1], ' ^')
+ assert_annotation_line(trs[2], ' -')
+
+def test_fixit_replace(html_tree):
+ diag = get_diag_by_index(html_tree, 5)
+ msg = get_message_within_diag(diag)
+ assert msg[0].text == 'warning: '
+ assert msg[0].tail == ' example of a replacement hint'
+
+ src = get_locus_within_diag(diag)
+
+ # Check quoted source
+ tbody = src.find('xhtml:tbody', ns)
+ assert_class(tbody, 'line-span')
+ trs = tbody.findall('xhtml:tr', ns)
+ assert len(trs) == 3
+ assert_quoted_line(trs[0], ' 91', ' gtk_widget_showall (dlg); /* { dg-warning "example of a replacement hint" } */')
+ assert_annotation_line(trs[1], ' ^~~~~~~~~~~~~~~~~~')
+ assert_annotation_line(trs[2], ' gtk_widget_show_all')
+
+def test_fixit_insert_newline(html_tree):
+ diag = get_diag_by_index(html_tree, 6)
+ msg = get_message_within_diag(diag)
+ assert msg[0].text == 'warning: '
+ assert msg[0].tail == ' example of newline insertion hint'
+
+ src = get_locus_within_diag(diag)
+
+ # Check quoted source
+ tbody = src.find('xhtml:tbody', ns)
+ assert_class(tbody, 'line-span')
+ trs = tbody.findall('xhtml:tr', ns)
+ assert len(trs) == 4
+ assert_quoted_line(trs[0], ' 109', ' x = a;')
+ assert_annotation_line(trs[1], ' break;',
+ expected_line_num=' +++',
+ expected_left_margin='+')
+ assert_quoted_line(trs[2], ' 110', " case 'b': /* { dg-warning \"newline insertion\" } */")
+ assert_annotation_line(trs[3], ' ^~~~~~~~')
diff --git a/gcc/testsuite/gcc.dg/plugin/diagnostic-test-xhtml-1.c b/gcc/testsuite/gcc.dg/plugin/diagnostic-test-xhtml-1.c
deleted file mode 100644
index da069ff..0000000
--- a/gcc/testsuite/gcc.dg/plugin/diagnostic-test-xhtml-1.c
+++ /dev/null
@@ -1,19 +0,0 @@
-/* { dg-do compile } */
-
-int missing_semicolon (void)
-{
- return 42
-}
-
-/* Verify some properties of the generated HTML. */
-
-/* { dg-begin-multiline-output "" }
-<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE html
- PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
- "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
-<html xmlns="http://www.w3.org/1999/xhtml">
- <head>
- { dg-end-multiline-output "" } */
-
-/* { dg-excess-errors "" } */
diff --git a/gcc/testsuite/gcc.dg/plugin/diagnostic_group_plugin.cc b/gcc/testsuite/gcc.dg/plugin/diagnostic_group_plugin.cc
index 5ec3418..4ade232 100644
--- a/gcc/testsuite/gcc.dg/plugin/diagnostic_group_plugin.cc
+++ b/gcc/testsuite/gcc.dg/plugin/diagnostic_group_plugin.cc
@@ -176,9 +176,10 @@ test_diagnostic_text_starter (diagnostic_text_output_format &text_output,
void
test_diagnostic_start_span_fn (const diagnostic_location_print_policy &,
- pretty_printer *pp,
+ to_text &sink,
expanded_location)
{
+ pretty_printer *pp = get_printer (sink);
pp_string (pp, "START_SPAN_FN: ");
pp_newline (pp);
}
diff --git a/gcc/testsuite/gcc.dg/plugin/diagnostic_plugin_test_paths.cc b/gcc/testsuite/gcc.dg/plugin/diagnostic_plugin_test_paths.cc
index 954538f..a7963fa 100644
--- a/gcc/testsuite/gcc.dg/plugin/diagnostic_plugin_test_paths.cc
+++ b/gcc/testsuite/gcc.dg/plugin/diagnostic_plugin_test_paths.cc
@@ -147,7 +147,9 @@ example_1 ()
{
auto_diagnostic_group d;
gcc_rich_location richloc (gimple_location (call_to_PyList_Append));
- simple_diagnostic_path path (global_dc->get_reference_printer ());
+ tree_logical_location_manager logical_loc_mgr;
+ simple_diagnostic_path path (logical_loc_mgr,
+ global_dc->get_reference_printer ());
diagnostic_event_id_t alloc_event_id
= path.add_event (gimple_location (call_to_PyList_New),
example_a_fun->decl, 0,
@@ -214,7 +216,8 @@ class test_diagnostic_path : public simple_diagnostic_path
{
public:
test_diagnostic_path (pretty_printer *event_pp)
- : simple_diagnostic_path (event_pp)
+ : simple_diagnostic_path (m_logical_loc_mgr,
+ event_pp)
{
}
diagnostic_event_id_t
@@ -262,6 +265,9 @@ class test_diagnostic_path : public simple_diagnostic_path
add_event (call_evloc.m_loc, call_evloc.m_fun->decl, caller_stack_depth,
"calling %qs", callee);
}
+
+private:
+ tree_logical_location_manager m_logical_loc_mgr;
};
static void
diff --git a/gcc/testsuite/gcc.dg/plugin/diagnostic_plugin_xhtml_format.cc b/gcc/testsuite/gcc.dg/plugin/diagnostic_plugin_xhtml_format.cc
deleted file mode 100644
index 24c6f8c..0000000
--- a/gcc/testsuite/gcc.dg/plugin/diagnostic_plugin_xhtml_format.cc
+++ /dev/null
@@ -1,985 +0,0 @@
-/* Verify that we can write a non-trivial diagnostic output format
- as a plugin (XHTML).
- Copyright (C) 2018-2024 Free Software Foundation, Inc.
- Contributed by David Malcolm <dmalcolm@redhat.com>.
-
-This file is part of GCC.
-
-GCC 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, or (at your option) any later
-version.
-
-GCC 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 GCC; see the file COPYING3. If not see
-<http://www.gnu.org/licenses/>. */
-
-
-#include "config.h"
-#define INCLUDE_LIST
-#define INCLUDE_MAP
-#define INCLUDE_MEMORY
-#define INCLUDE_VECTOR
-#include "system.h"
-#include "coretypes.h"
-#include "diagnostic.h"
-#include "diagnostic-metadata.h"
-#include "diagnostic-path.h"
-#include "cpplib.h"
-#include "logical-location.h"
-#include "diagnostic-client-data-hooks.h"
-#include "diagnostic-diagram.h"
-#include "text-art/canvas.h"
-#include "diagnostic-format.h"
-#include "diagnostic-buffer.h"
-#include "ordered-hash-map.h"
-#include "sbitmap.h"
-#include "selftest.h"
-#include "selftest-diagnostic.h"
-#include "selftest-diagnostic-show-locus.h"
-#include "text-range-label.h"
-#include "pretty-print-format-impl.h"
-#include "pretty-print-urlifier.h"
-#include "intl.h"
-#include "gcc-plugin.h"
-#include "plugin-version.h"
-
-namespace xml {
-
-/* Disable warnings about quoting issues in the pp_xxx calls below
- that (intentionally) don't follow GCC diagnostic conventions. */
-#if __GNUC__ >= 10
-# pragma GCC diagnostic push
-# pragma GCC diagnostic ignored "-Wformat-diag"
-#endif
-
-static void write_escaped_text (const char *text);
-
-struct node
-{
- virtual ~node () {}
- virtual void write_as_xml (pretty_printer *pp,
- int depth, bool indent) const = 0;
- void dump (FILE *out) const;
- void DEBUG_FUNCTION dump () const { dump (stderr); }
-};
-
-struct text : public node
-{
- text (label_text str)
- : m_str (std::move (str))
- {}
-
- void write_as_xml (pretty_printer *pp,
- int depth, bool indent) const final override;
-
- label_text m_str;
-};
-
-struct node_with_children : public node
-{
- void add_child (std::unique_ptr<node> node);
- void add_text (label_text str);
-
- std::vector<std::unique_ptr<node>> m_children;
-};
-
-struct document : public node_with_children
-{
- void write_as_xml (pretty_printer *pp,
- int depth, bool indent) const final override;
-};
-
-struct element : public node_with_children
-{
- element (const char *kind, bool preserve_whitespace)
- : m_kind (kind),
- m_preserve_whitespace (preserve_whitespace)
- {}
-
- void write_as_xml (pretty_printer *pp,
- int depth, bool indent) const final override;
-
- void set_attr (const char *name, label_text value);
-
- const char *m_kind;
- bool m_preserve_whitespace;
- std::map<const char *, label_text> m_attributes;
-};
-
-/* Implementation. */
-
-static void
-write_escaped_text (pretty_printer *pp, const char *text)
-{
- gcc_assert (text);
-
- for (const char *p = text; *p; ++p)
- {
- char ch = *p;
- switch (ch)
- {
- default:
- pp_character (pp, ch);
- break;
- case '\'':
- pp_string (pp, "&apos;");
- break;
- case '"':
- pp_string (pp, "&quot;");
- break;
- case '&':
- pp_string (pp, "&amp;");
- break;
- case '<':
- pp_string (pp, "&lt;");
- break;
- case '>':
- pp_string (pp, "&gt;");
- break;
- }
- }
-}
-
-/* struct node. */
-
-void
-node::dump (FILE *out) const
-{
- pretty_printer pp;
- pp.set_output_stream (out);
- write_as_xml (&pp, 0, true);
- pp_flush (&pp);
-}
-
-/* struct text : public node. */
-
-void
-text::write_as_xml (pretty_printer *pp, int /*depth*/, bool /*indent*/) const
-{
- write_escaped_text (pp, m_str.get ());
-}
-
-/* struct node_with_children : public node. */
-
-void
-node_with_children::add_child (std::unique_ptr<node> node)
-{
- gcc_assert (node.get ());
- m_children.push_back (std::move (node));
-}
-
-void
-node_with_children::add_text (label_text str)
-{
- gcc_assert (str.get ());
- add_child (std::make_unique <text> (std::move (str)));
-}
-
-
-/* struct document : public node_with_children. */
-
-void
-document::write_as_xml (pretty_printer *pp, int depth, bool indent) const
-{
- pp_string (pp, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
- pp_string (pp, "<!DOCTYPE html\n"
- " PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\"\n"
- " \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">");
- for (auto &iter : m_children)
- iter->write_as_xml (pp, depth, indent);
-}
-
-/* struct element : public node_with_children. */
-
-void
-element::write_as_xml (pretty_printer *pp, int depth, bool indent) const
-{
- if (indent)
- {
- pp_newline (pp);
- for (int i = 0; i < depth; ++i)
- pp_string (pp, " ");
- }
-
- if (m_preserve_whitespace)
- indent = false;
-
- pp_printf (pp, "<%s", m_kind);
- for (auto &attr : m_attributes)
- {
- pp_printf (pp, " %s=\"", attr.first);
- write_escaped_text (pp, attr.second.get ());
- pp_string (pp, "\"");
- }
- if (m_children.empty ())
- pp_string (pp, " />");
- else
- {
- pp_string (pp, ">");
- for (auto &child : m_children)
- child->write_as_xml (pp, depth + 1, indent);
- if (indent)
- {
- pp_newline (pp);
- for (int i = 0; i < depth; ++i)
- pp_string (pp, " ");
- }
- pp_printf (pp, "</%s>", m_kind);
- }
-}
-
-void
-element::set_attr (const char *name, label_text value)
-{
- m_attributes[name] = std::move (value);
-}
-
-#if __GNUC__ >= 10
-# pragma GCC diagnostic pop
-#endif
-
-} // namespace xml
-
-class xhtml_builder;
-
-/* Concrete buffering implementation subclass for HTML output. */
-
-class diagnostic_xhtml_format_buffer : public diagnostic_per_format_buffer
-{
-public:
- friend class xhtml_builder;
- friend class xhtml_output_format;
-
- diagnostic_xhtml_format_buffer (xhtml_builder &builder)
- : m_builder (builder)
- {}
-
- void dump (FILE *out, int indent) const final override;
- bool empty_p () const final override;
- void move_to (diagnostic_per_format_buffer &dest) final override;
- void clear () final override;
- void flush () final override;
-
- void add_result (std::unique_ptr<xml::element> result)
- {
- m_results.push_back (std::move (result));
- }
-
-private:
- xhtml_builder &m_builder;
- std::vector<std::unique_ptr<xml::element>> m_results;
-};
-
-/* A class for managing XHTML output of diagnostics.
-
- Implemented:
- - message text
-
- Known limitations/missing functionality:
- - title for page
- - file/line/column
- - error vs warning
- - CWEs
- - rules
- - fix-it hints
- - paths
-*/
-
-class xhtml_builder
-{
-public:
- friend class diagnostic_xhtml_format_buffer;
-
- xhtml_builder (diagnostic_context &context,
- pretty_printer &pp,
- const line_maps *line_maps);
-
- void on_report_diagnostic (const diagnostic_info &diagnostic,
- diagnostic_t orig_diag_kind,
- diagnostic_xhtml_format_buffer *buffer);
- void emit_diagram (const diagnostic_diagram &diagram);
- void end_group ();
-
- std::unique_ptr<xml::element> take_current_diagnostic ()
- {
- return std::move (m_cur_diagnostic_element);
- }
-
- void flush_to_file (FILE *outf);
-
- const xml::document &get_document () const { return *m_document; }
-
- void set_printer (pretty_printer &pp)
- {
- m_printer = &pp;
- }
-
-private:
- std::unique_ptr<xml::element>
- make_element_for_diagnostic (const diagnostic_info &diagnostic,
- diagnostic_t orig_diag_kind);
-
- diagnostic_context &m_context;
- pretty_printer *m_printer;
- const line_maps *m_line_maps;
-
- std::unique_ptr<xml::document> m_document;
- xml::element *m_diagnostics_element;
- std::unique_ptr<xml::element> m_cur_diagnostic_element;
-};
-
-static std::unique_ptr<xml::element>
-make_div (label_text class_)
-{
- auto div = std::make_unique<xml::element> ("div", false);
- div->set_attr ("class", std::move (class_));
- return div;
-}
-
-static std::unique_ptr<xml::element>
-make_span (label_text class_)
-{
- auto span = std::make_unique<xml::element> ("span", true);
- span->set_attr ("class", std::move (class_));
- return span;
-}
-
-/* class diagnostic_xhtml_format_buffer : public diagnostic_per_format_buffer. */
-
-void
-diagnostic_xhtml_format_buffer::dump (FILE *out, int indent) const
-{
- fprintf (out, "%*sdiagnostic_xhtml_format_buffer:\n", indent, "");
- int idx = 0;
- for (auto &result : m_results)
- {
- fprintf (out, "%*sresult[%i]:\n", indent + 2, "", idx);
- result->dump (out);
- fprintf (out, "\n");
- ++idx;
- }
-}
-
-bool
-diagnostic_xhtml_format_buffer::empty_p () const
-{
- return m_results.empty ();
-}
-
-void
-diagnostic_xhtml_format_buffer::move_to (diagnostic_per_format_buffer &base)
-{
- diagnostic_xhtml_format_buffer &dest
- = static_cast<diagnostic_xhtml_format_buffer &> (base);
- for (auto &&result : m_results)
- dest.m_results.push_back (std::move (result));
- m_results.clear ();
-}
-
-void
-diagnostic_xhtml_format_buffer::clear ()
-{
- m_results.clear ();
-}
-
-void
-diagnostic_xhtml_format_buffer::flush ()
-{
- for (auto &&result : m_results)
- m_builder.m_diagnostics_element->add_child (std::move (result));
- m_results.clear ();
-}
-
-/* class xhtml_builder. */
-
-/* xhtml_builder's ctor. */
-
-xhtml_builder::xhtml_builder (diagnostic_context &context,
- pretty_printer &pp,
- const line_maps *line_maps)
-: m_context (context),
- m_printer (&pp),
- m_line_maps (line_maps)
-{
- gcc_assert (m_line_maps);
-
- m_document = std::make_unique<xml::document> ();
- {
- auto html_element = std::make_unique<xml::element> ("html", false);
- html_element->set_attr
- ("xmlns",
- label_text::borrow ("http://www.w3.org/1999/xhtml"));
- {
- {
- auto head_element = std::make_unique<xml::element> ("head", false);
- {
- auto title_element = std::make_unique<xml::element> ("title", true);
- label_text title (label_text::borrow ("Title goes here")); // TODO
- title_element->add_text (std::move (title));
- head_element->add_child (std::move (title_element));
- }
- html_element->add_child (std::move (head_element));
-
- auto body_element = std::make_unique<xml::element> ("body", false);
- {
- auto diagnostics_element
- = make_div (label_text::borrow ("gcc-diagnostic-list"));
- m_diagnostics_element = diagnostics_element.get ();
- body_element->add_child (std::move (diagnostics_element));
- }
- html_element->add_child (std::move (body_element));
- }
- }
- m_document->add_child (std::move (html_element));
- }
-}
-
-/* Implementation of "on_report_diagnostic" for XHTML output. */
-
-void
-xhtml_builder::on_report_diagnostic (const diagnostic_info &diagnostic,
- diagnostic_t orig_diag_kind,
- diagnostic_xhtml_format_buffer *buffer)
-{
- if (diagnostic.kind == DK_ICE || diagnostic.kind == DK_ICE_NOBT)
- {
- /* Print a header for the remaining output to stderr, and
- return, attempting to print the usual ICE messages to
- stderr. Hopefully this will be helpful to the user in
- indicating what's gone wrong (also for DejaGnu, for pruning
- those messages). */
- fnotice (stderr, "Internal compiler error:\n");
- }
-
- auto diag_element
- = make_element_for_diagnostic (diagnostic, orig_diag_kind);
- if (buffer)
- {
- gcc_assert (!m_cur_diagnostic_element);
- buffer->m_results.push_back (std::move (diag_element));
- }
- else
- {
- if (m_cur_diagnostic_element)
- /* Nested diagnostic. */
- m_cur_diagnostic_element->add_child (std::move (diag_element));
- else
- /* Top-level diagnostic. */
- m_cur_diagnostic_element = std::move (diag_element);
- }
-}
-
-std::unique_ptr<xml::element>
-xhtml_builder::make_element_for_diagnostic (const diagnostic_info &diagnostic,
- diagnostic_t orig_diag_kind)
-{
- class xhtml_token_printer : public token_printer
- {
- public:
- xhtml_token_printer (xhtml_builder &builder,
- xml::element &parent_element)
- : m_builder (builder)
- {
- m_open_elements.push_back (&parent_element);
- }
- void print_tokens (pretty_printer */*pp*/,
- const pp_token_list &tokens) final override
- {
- /* Implement print_tokens by adding child elements to
- m_parent_element. */
- for (auto iter = tokens.m_first; iter; iter = iter->m_next)
- switch (iter->m_kind)
- {
- default:
- gcc_unreachable ();
-
- case pp_token::kind::text:
- {
- pp_token_text *sub = as_a <pp_token_text *> (iter);
- /* The value might be in the obstack, so we may need to
- copy it. */
- insertion_element ().add_text
- (label_text::take (xstrdup (sub->m_value.get ())));
- }
- break;
-
- case pp_token::kind::begin_color:
- case pp_token::kind::end_color:
- /* These are no-ops. */
- break;
-
- case pp_token::kind::begin_quote:
- {
- insertion_element ().add_text (label_text::borrow (open_quote));
- push_element (make_span (label_text::borrow ("gcc-quoted-text")));
- }
- break;
- case pp_token::kind::end_quote:
- {
- pop_element ();
- insertion_element ().add_text (label_text::borrow (close_quote));
- }
- break;
-
- case pp_token::kind::begin_url:
- {
- pp_token_begin_url *sub = as_a <pp_token_begin_url *> (iter);
- auto anchor = std::make_unique<xml::element> ("a", true);
- anchor->set_attr ("href", std::move (sub->m_value));
- push_element (std::move (anchor));
- }
- break;
- case pp_token::kind::end_url:
- pop_element ();
- break;
- }
- }
-
- private:
- xml::element &insertion_element () const
- {
- return *m_open_elements.back ();
- }
- void push_element (std::unique_ptr<xml::element> new_element)
- {
- xml::element &current_top = insertion_element ();
- m_open_elements.push_back (new_element.get ());
- current_top.add_child (std::move (new_element));
- }
- void pop_element ()
- {
- m_open_elements.pop_back ();
- }
-
- xhtml_builder &m_builder;
- /* We maintain a stack of currently "open" elements.
- Children are added to the topmost open element. */
- std::vector<xml::element *> m_open_elements;
- };
-
- auto diag_element = make_div (label_text::borrow ("gcc-diagnostic"));
-
- // TODO: might be nice to emulate the text output format, but colorize it
-
- auto message_span = make_span (label_text::borrow ("gcc-message"));
- xhtml_token_printer tok_printer (*this, *message_span.get ());
- m_printer->set_token_printer (&tok_printer);
- pp_output_formatted_text (m_printer, m_context.get_urlifier ());
- m_printer->set_token_printer (nullptr);
- pp_clear_output_area (m_printer);
- diag_element->add_child (std::move (message_span));
-
- if (diagnostic.metadata)
- {
- int cwe = diagnostic.metadata->get_cwe ();
- if (cwe)
- {
- diag_element->add_text (label_text::borrow (" "));
- auto cwe_span = make_span (label_text::borrow ("gcc-cwe-metadata"));
- cwe_span->add_text (label_text::borrow ("["));
- {
- auto anchor = std::make_unique<xml::element> ("a", true);
- anchor->set_attr ("href", label_text::take (get_cwe_url (cwe)));
- pretty_printer pp;
- pp_printf (&pp, "CWE-%i", cwe);
- anchor->add_text
- (label_text::take (xstrdup (pp_formatted_text (&pp))));
- cwe_span->add_child (std::move (anchor));
- }
- cwe_span->add_text (label_text::borrow ("]"));
- diag_element->add_child (std::move (cwe_span));
- }
- }
-
- // TODO: show any rules
-
- label_text option_text = label_text::take
- (m_context.make_option_name (diagnostic.option_id,
- orig_diag_kind, diagnostic.kind));
- if (option_text.get ())
- {
- label_text option_url = label_text::take
- (m_context.make_option_url (diagnostic.option_id));
-
- diag_element->add_text (label_text::borrow (" "));
- auto option_span = make_span (label_text::borrow ("gcc-option"));
- option_span->add_text (label_text::borrow ("["));
- {
- if (option_url.get ())
- {
- auto anchor = std::make_unique<xml::element> ("a", true);
- anchor->set_attr ("href", std::move (option_url));
- anchor->add_text (std::move (option_text));
- option_span->add_child (std::move (anchor));
- }
- else
- option_span->add_text (std::move (option_text));
- option_span->add_text (label_text::borrow ("]"));
- }
- diag_element->add_child (std::move (option_span));
- }
-
- {
- auto pre = std::make_unique<xml::element> ("pre", true);
- pre->set_attr ("class", label_text::borrow ("gcc-annotated-source"));
- // TODO: ideally we'd like to capture elements within the following:
- diagnostic_show_locus (&m_context, m_context.m_source_printing,
- diagnostic.richloc, diagnostic.kind,
- m_printer);
- pre->add_text
- (label_text::take (xstrdup (pp_formatted_text (m_printer))));
- pp_clear_output_area (m_printer);
- diag_element->add_child (std::move (pre));
- }
-
- return diag_element;
-}
-
-/* Implementation of diagnostic_context::m_diagrams.m_emission_cb
- for XHTML output. */
-
-void
-xhtml_builder::emit_diagram (const diagnostic_diagram &/*diagram*/)
-{
- /* We must be within the emission of a top-level diagnostic. */
- gcc_assert (m_cur_diagnostic_element);
-
- // TODO
-}
-
-/* Implementation of "end_group_cb" for XHTML output. */
-
-void
-xhtml_builder::end_group ()
-{
- if (m_cur_diagnostic_element)
- m_diagnostics_element->add_child (std::move (m_cur_diagnostic_element));
-}
-
-/* Create a top-level object, and add it to all the results
- (and other entities) we've seen so far.
-
- Flush it all to OUTF. */
-
-void
-xhtml_builder::flush_to_file (FILE *outf)
-{
- auto top = m_document.get ();
- top->dump (outf);
- fprintf (outf, "\n");
-}
-
-class xhtml_output_format : public diagnostic_output_format
-{
-public:
- ~xhtml_output_format ()
- {
- /* Any diagnostics should have been handled by now.
- If not, then something's gone wrong with diagnostic
- groupings. */
- std::unique_ptr<xml::element> pending_diag
- = m_builder.take_current_diagnostic ();
- gcc_assert (!pending_diag);
- }
-
- void dump (FILE *out, int indent) const override
- {
- fprintf (out, "%*sxhtml_output_format\n", indent, "");
- diagnostic_output_format::dump (out, indent);
- }
-
- std::unique_ptr<diagnostic_per_format_buffer>
- make_per_format_buffer () final override
- {
- return std::make_unique<diagnostic_xhtml_format_buffer> (m_builder);
- }
- void set_buffer (diagnostic_per_format_buffer *base_buffer) final override
- {
- diagnostic_xhtml_format_buffer *buffer
- = static_cast<diagnostic_xhtml_format_buffer *> (base_buffer);
- m_buffer = buffer;
- }
-
- void on_begin_group () final override
- {
- /* No-op, */
- }
- void on_end_group () final override
- {
- m_builder.end_group ();
- }
- void
- on_report_diagnostic (const diagnostic_info &diagnostic,
- diagnostic_t orig_diag_kind) final override
- {
- m_builder.on_report_diagnostic (diagnostic, orig_diag_kind, m_buffer);
- }
- void on_diagram (const diagnostic_diagram &diagram) final override
- {
- m_builder.emit_diagram (diagram);
- }
- void after_diagnostic (const diagnostic_info &)
- {
- /* No-op, but perhaps could show paths here. */
- }
- bool follows_reference_printer_p () const final override
- {
- return false;
- }
- void update_printer () final override
- {
- m_printer = m_context.clone_printer ();
-
- /* Don't colorize the text. */
- pp_show_color (m_printer.get ()) = false;
-
- /* No textual URLs. */
- m_printer->set_url_format (URL_FORMAT_NONE);
-
- /* Update the builder to use the new printer. */
- m_builder.set_printer (*get_printer ());
- }
-
- const xml::document &get_document () const
- {
- return m_builder.get_document ();
- }
-
-protected:
- xhtml_output_format (diagnostic_context &context,
- const line_maps *line_maps)
- : diagnostic_output_format (context),
- m_builder (context, *get_printer (), line_maps),
- m_buffer (nullptr)
- {}
-
- xhtml_builder m_builder;
- diagnostic_xhtml_format_buffer *m_buffer;
-};
-
-class xhtml_stream_output_format : public xhtml_output_format
-{
-public:
- xhtml_stream_output_format (diagnostic_context &context,
- const line_maps *line_maps,
- FILE *stream)
- : xhtml_output_format (context, line_maps),
- m_stream (stream)
- {
- }
- ~xhtml_stream_output_format ()
- {
- m_builder.flush_to_file (m_stream);
- }
- bool machine_readable_stderr_p () const final override
- {
- return m_stream == stderr;
- }
-private:
- FILE *m_stream;
-};
-
-class xhtml_file_output_format : public xhtml_output_format
-{
-public:
- xhtml_file_output_format (diagnostic_context &context,
- const line_maps *line_maps,
- const char *base_file_name)
- : xhtml_output_format (context, line_maps),
- m_base_file_name (xstrdup (base_file_name))
- {
- }
- ~xhtml_file_output_format ()
- {
- char *filename = concat (m_base_file_name, ".xhtml", nullptr);
- free (m_base_file_name);
- m_base_file_name = nullptr;
- FILE *outf = fopen (filename, "w");
- if (!outf)
- {
- const char *errstr = xstrerror (errno);
- fnotice (stderr, "error: unable to open '%s' for writing: %s\n",
- filename, errstr);
- free (filename);
- return;
- }
- m_builder.flush_to_file (outf);
- fclose (outf);
- free (filename);
- }
- bool machine_readable_stderr_p () const final override
- {
- return false;
- }
-
-private:
- char *m_base_file_name;
-};
-
-/* Populate CONTEXT in preparation for XHTML output (either to stderr, or
- to a file). */
-
-static void
-diagnostic_output_format_init_xhtml (diagnostic_context &context,
- std::unique_ptr<xhtml_output_format> fmt)
-{
- /* Don't colorize the text. */
- pp_show_color (fmt->get_printer ()) = false;
- context.set_show_highlight_colors (false);
-
- context.set_output_format (std::move (fmt));
-}
-
-/* Populate CONTEXT in preparation for XHTML output to stderr. */
-
-void
-diagnostic_output_format_init_xhtml_stderr (diagnostic_context &context,
- const line_maps *line_maps)
-{
- gcc_assert (line_maps);
- auto format = std::make_unique<xhtml_stream_output_format> (context,
- line_maps,
- stderr);
- diagnostic_output_format_init_xhtml (context, std::move (format));
-}
-
-/* Populate CONTEXT in preparation for XHTML output to a file named
- BASE_FILE_NAME.xhtml. */
-
-void
-diagnostic_output_format_init_xhtml_file (diagnostic_context &context,
- const line_maps *line_maps,
- const char *base_file_name)
-{
- gcc_assert (line_maps);
- auto format = std::make_unique<xhtml_file_output_format> (context,
- line_maps,
- base_file_name);
- diagnostic_output_format_init_xhtml (context, std::move (format));
-}
-
-#if CHECKING_P
-
-namespace selftest {
-
-/* A subclass of xhtml_output_format for writing selftests.
- The XML output is cached internally, rather than written
- out to a file. */
-
-class test_xhtml_diagnostic_context : public test_diagnostic_context
-{
-public:
- test_xhtml_diagnostic_context ()
- {
- auto format = std::make_unique<xhtml_buffered_output_format> (*this,
- line_table);
- m_format = format.get (); // borrowed
- diagnostic_output_format_init_xhtml (*this, std::move (format));
- }
-
- const xml::document &get_document () const
- {
- return m_format->get_document ();
- }
-
-private:
- class xhtml_buffered_output_format : public xhtml_output_format
- {
- public:
- xhtml_buffered_output_format (diagnostic_context &context,
- const line_maps *line_maps)
- : xhtml_output_format (context, line_maps)
- {
- }
- bool machine_readable_stderr_p () const final override
- {
- return true;
- }
- };
-
- xhtml_output_format *m_format; // borrowed
-};
-
- /* Test of reporting a diagnostic at UNKNOWN_LOCATION to a
- diagnostic_context and examining the generated XML document.
- Verify various basic properties. */
-
-static void
-test_simple_log ()
-{
- test_xhtml_diagnostic_context dc;
-
- rich_location richloc (line_table, UNKNOWN_LOCATION);
- dc.report (DK_ERROR, richloc, nullptr, 0, "this is a test: %i", 42);
-
- const xml::document &doc = dc.get_document ();
-
- pretty_printer pp;
- doc.write_as_xml (&pp, 0, true);
- ASSERT_STREQ
- (pp_formatted_text (&pp),
- ("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
- "<!DOCTYPE html\n"
- " PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\"\n"
- " \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">\n"
- "<html xmlns=\"http://www.w3.org/1999/xhtml\">\n"
- " <head>\n"
- " <title>Title goes here</title>\n"
- " </head>\n"
- " <body>\n"
- " <div class=\"gcc-diagnostic-list\">\n"
- " <div class=\"gcc-diagnostic\">\n"
- " <span class=\"gcc-message\">this is a test: 42</span>\n"
- " <pre class=\"gcc-annotated-source\"></pre>\n"
- " </div>\n"
- " </div>\n"
- " </body>\n"
- "</html>"));
-}
-
-/* Run all of the selftests within this file. */
-
-static void
-xhtml_format_selftests ()
-{
- test_simple_log ();
-}
-
-} // namespace selftest
-
-#endif /* CHECKING_P */
-
-/* Plugin hooks. */
-
-int plugin_is_GPL_compatible;
-
-/* Entrypoint for the plugin. */
-
-int
-plugin_init (struct plugin_name_args *plugin_info,
- struct plugin_gcc_version *version)
-{
- const char *plugin_name = plugin_info->base_name;
- int argc = plugin_info->argc;
- struct plugin_argument *argv = plugin_info->argv;
-
- if (!plugin_default_version_check (version, &gcc_version))
- return 1;
-
- global_dc->set_output_format
- (std::make_unique<xhtml_stream_output_format> (*global_dc,
- line_table,
- stderr));
-
-#if CHECKING_P
- selftest::xhtml_format_selftests ();
-#endif
-
- return 0;
-}
diff --git a/gcc/testsuite/gcc.dg/plugin/location-overflow-test-pr116047-1.h b/gcc/testsuite/gcc.dg/plugin/location-overflow-test-pr116047-1.h
new file mode 100644
index 0000000..3dd6434
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/plugin/location-overflow-test-pr116047-1.h
@@ -0,0 +1,6 @@
+
+
+
+
+#include "location-overflow-test-pr116047-2.h"
+static_assert (__LINE__ == 6, "");
diff --git a/gcc/testsuite/gcc.dg/plugin/location-overflow-test-pr116047-2.h b/gcc/testsuite/gcc.dg/plugin/location-overflow-test-pr116047-2.h
new file mode 100644
index 0000000..048f715
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/plugin/location-overflow-test-pr116047-2.h
@@ -0,0 +1 @@
+int i;
diff --git a/gcc/testsuite/gcc.dg/plugin/location-overflow-test-pr116047.c b/gcc/testsuite/gcc.dg/plugin/location-overflow-test-pr116047.c
new file mode 100644
index 0000000..75161fa
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/plugin/location-overflow-test-pr116047.c
@@ -0,0 +1,5 @@
+/* PR preprocessor/116047 */
+/* { dg-do preprocess } */
+/* { dg-options "-nostdinc -std=c23 -fplugin-arg-location_overflow_plugin-value=0x4ffe0180" } */
+#include "location-overflow-test-pr116047-1.h"
+/* { dg-final { scan-file location-overflow-test-pr116047.i "static_assert\[^\n\r]\*6\[^\n\r]\*== 6" } } */
diff --git a/gcc/testsuite/gcc.dg/plugin/location-overflow-test-pr120061-1.h b/gcc/testsuite/gcc.dg/plugin/location-overflow-test-pr120061-1.h
new file mode 100644
index 0000000..ebf7704
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/plugin/location-overflow-test-pr120061-1.h
@@ -0,0 +1,6 @@
+
+
+
+
+#include "location-overflow-test-pr120061-2.h"
+
diff --git a/gcc/testsuite/gcc.dg/plugin/location-overflow-test-pr120061-2.h b/gcc/testsuite/gcc.dg/plugin/location-overflow-test-pr120061-2.h
new file mode 100644
index 0000000..048f715
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/plugin/location-overflow-test-pr120061-2.h
@@ -0,0 +1 @@
+int i;
diff --git a/gcc/testsuite/gcc.dg/plugin/location-overflow-test-pr120061.c b/gcc/testsuite/gcc.dg/plugin/location-overflow-test-pr120061.c
new file mode 100644
index 0000000..e8e8038
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/plugin/location-overflow-test-pr120061.c
@@ -0,0 +1,6 @@
+/* PR preprocessor/120061 */
+/* { dg-do preprocess } */
+/* { dg-options "-nostdinc -std=c23 -fplugin-arg-location_overflow_plugin-value=0x61000000" } */
+#include "location-overflow-test-pr120061-1.h"
+static_assert (__LINE__ == 5, "");
+/* { dg-final { scan-file location-overflow-test-pr120061.i "static_assert\[^\n\r]\*5\[^\n\r]\*== 5" } } */
diff --git a/gcc/testsuite/gcc.dg/plugin/location_overflow_plugin.cc b/gcc/testsuite/gcc.dg/plugin/location_overflow_plugin.cc
index f731b14..f770d35 100644
--- a/gcc/testsuite/gcc.dg/plugin/location_overflow_plugin.cc
+++ b/gcc/testsuite/gcc.dg/plugin/location_overflow_plugin.cc
@@ -85,9 +85,18 @@ plugin_init (struct plugin_name_args *plugin_info,
error_at (UNKNOWN_LOCATION, "missing plugin argument");
/* With 64-bit locations, the thresholds are larger, so shift the base
- location argument accordingly. */
+ location argument accordingly, basically remap the GCC 14 32-bit
+ location_t argument values to 64-bit location_t counterparts. There
+ is one exception for values slightly before the 32-bit location_t
+ LINE_MAP_MAX_LOCATION_WITH_PACKED_RANGES (0x50000000). In that case
+ remap them to the same amount before the 64-bit location_t
+ LINE_MAP_MAX_LOCATION_WITH_PACKED_RANGES -
+ ((location_t) 0x50000000) << 31. */
gcc_assert (sizeof (location_t) == sizeof (uint64_t));
- base_location = 1 + ((base_location - 1) << 31);
+ if (base_location >= 0x4f000000 && base_location <= 0x4fffffff)
+ base_location += (((location_t) 0x50000000) << 31) - 0x50000000;
+ else
+ base_location = 1 + ((base_location - 1) << 31);
register_callback (plugin_info->base_name,
PLUGIN_PRAGMAS,
@@ -107,7 +116,7 @@ plugin_init (struct plugin_name_args *plugin_info,
break;
default:
- error_at (UNKNOWN_LOCATION, "unrecognized value for plugin argument");
+ break;
}
return 0;
diff --git a/gcc/testsuite/gcc.dg/plugin/plugin.exp b/gcc/testsuite/gcc.dg/plugin/plugin.exp
index 90c9162..d1d7f5d 100644
--- a/gcc/testsuite/gcc.dg/plugin/plugin.exp
+++ b/gcc/testsuite/gcc.dg/plugin/plugin.exp
@@ -76,8 +76,6 @@ set plugin_test_list [list \
crash-test-ice-in-header-sarif-2.1.c \
crash-test-ice-in-header-sarif-2.2.c \
crash-test-write-though-null-sarif.c } \
- { diagnostic_plugin_xhtml_format.cc \
- diagnostic-test-xhtml-1.c } \
{ diagnostic_group_plugin.cc \
diagnostic-group-test-1.c } \
{ diagnostic_plugin_test_show_locus.cc \
@@ -107,6 +105,7 @@ set plugin_test_list [list \
diagnostic-test-inlining-4.c } \
{ diagnostic_plugin_test_metadata.cc
diagnostic-test-metadata.c \
+ diagnostic-test-metadata-html.c \
diagnostic-test-metadata-sarif.c } \
{ diagnostic_plugin_test_nesting.cc \
diagnostic-test-nesting-text-plain.c \
@@ -117,7 +116,6 @@ set plugin_test_list [list \
{ diagnostic_plugin_test_paths.cc \
diagnostic-test-paths-1.c \
diagnostic-test-paths-2.c \
- diagnostic-test-paths-3.c \
diagnostic-test-paths-4.c \
diagnostic-test-paths-5.c \
diagnostic-test-paths-multithreaded-inline-events.c \
@@ -138,7 +136,9 @@ set plugin_test_list [list \
{ location_overflow_plugin.cc \
location-overflow-test-1.c \
location-overflow-test-2.c \
- location-overflow-test-pr83173.c } \
+ location-overflow-test-pr83173.c \
+ location-overflow-test-pr116047.c \
+ location-overflow-test-pr120061.c } \
{ must_tail_call_plugin.cc \
must-tail-call-1.c \
must-tail-call-2.c } \