diff options
Diffstat (limited to 'gcc/testsuite/gcc.dg/plugin')
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, "'"); - break; - case '"': - pp_string (pp, """); - break; - case '&': - pp_string (pp, "&"); - break; - case '<': - pp_string (pp, "<"); - break; - case '>': - pp_string (pp, ">"); - 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 ¤t_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 } \ |