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.cc41
-rw-r--r--gcc/testsuite/gcc.dg/plugin/analyzer_gil_plugin.cc57
-rw-r--r--gcc/testsuite/gcc.dg/plugin/analyzer_kernel_plugin.cc22
-rw-r--r--gcc/testsuite/gcc.dg/plugin/analyzer_known_fns_plugin.cc17
-rw-r--r--gcc/testsuite/gcc.dg/plugin/diagnostic-test-graphs-html.c13
-rw-r--r--gcc/testsuite/gcc.dg/plugin/diagnostic-test-graphs-html.py48
-rw-r--r--gcc/testsuite/gcc.dg/plugin/diagnostic-test-graphs-sarif.c16
-rw-r--r--gcc/testsuite/gcc.dg/plugin/diagnostic-test-graphs-sarif.py55
-rw-r--r--gcc/testsuite/gcc.dg/plugin/diagnostic-test-graphs.c8
-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-nesting-html.c13
-rw-r--r--gcc/testsuite/gcc.dg/plugin/diagnostic-test-nesting-html.py69
-rw-r--r--gcc/testsuite/gcc.dg/plugin/diagnostic-test-nesting-no-show-nesting.c9
-rw-r--r--gcc/testsuite/gcc.dg/plugin/diagnostic-test-nesting-show-nesting.c24
-rw-r--r--gcc/testsuite/gcc.dg/plugin/diagnostic-test-nesting-text-indented-show-levels.c2
-rw-r--r--gcc/testsuite/gcc.dg/plugin/diagnostic-test-nesting-text-indented-unicode.c2
-rw-r--r--gcc/testsuite/gcc.dg/plugin/diagnostic-test-nesting-text-indented.c2
-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.cc26
-rw-r--r--gcc/testsuite/gcc.dg/plugin/diagnostic_plugin_show_trees.cc2
-rw-r--r--gcc/testsuite/gcc.dg/plugin/diagnostic_plugin_test_graphs.cc283
-rw-r--r--gcc/testsuite/gcc.dg/plugin/diagnostic_plugin_test_inlining.cc2
-rw-r--r--gcc/testsuite/gcc.dg/plugin/diagnostic_plugin_test_metadata.cc13
-rw-r--r--gcc/testsuite/gcc.dg/plugin/diagnostic_plugin_test_paths.cc32
-rw-r--r--gcc/testsuite/gcc.dg/plugin/diagnostic_plugin_test_show_locus.cc48
-rw-r--r--gcc/testsuite/gcc.dg/plugin/diagnostic_plugin_test_string_literals.cc2
-rw-r--r--gcc/testsuite/gcc.dg/plugin/diagnostic_plugin_test_text_art.cc4
-rw-r--r--gcc/testsuite/gcc.dg/plugin/diagnostic_plugin_test_tree_expression_range.cc2
-rw-r--r--gcc/testsuite/gcc.dg/plugin/diagnostic_plugin_xhtml_format.cc986
-rw-r--r--gcc/testsuite/gcc.dg/plugin/expensive_selftests_plugin.cc17
-rw-r--r--gcc/testsuite/gcc.dg/plugin/infoleak-net-ethtool-ioctl.c3
-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.cc37
-rw-r--r--gcc/testsuite/gcc.dg/plugin/must-tail-call-2.c2
-rw-r--r--gcc/testsuite/gcc.dg/plugin/plugin.exp15
48 files changed, 1068 insertions, 1241 deletions
diff --git a/gcc/testsuite/gcc.dg/plugin/analyzer_cpython_plugin.cc b/gcc/testsuite/gcc.dg/plugin/analyzer_cpython_plugin.cc
index 467af16..01ab766 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"
@@ -22,14 +23,14 @@
#include "target.h"
#include "fold-const.h"
#include "tree-pretty-print.h"
-#include "diagnostic-color.h"
-#include "diagnostic-metadata.h"
+#include "diagnostics/color.h"
+#include "diagnostics/metadata.h"
#include "tristate.h"
#include "bitmap.h"
#include "selftest.h"
#include "function.h"
#include "json.h"
-#include "analyzer/analyzer.h"
+#include "analyzer/common.h"
#include "analyzer/analyzer-language.h"
#include "analyzer/analyzer-logging.h"
#include "ordered-hash-map.h"
@@ -46,7 +47,6 @@
#include "analyzer/call-details.h"
#include "analyzer/call-info.h"
#include "analyzer/exploded-graph.h"
-#include "make-unique.h"
int plugin_is_GPL_compatible;
@@ -207,7 +207,7 @@ public:
std::unique_ptr<stmt_finder>
clone () const final override
{
- return make_unique<refcnt_stmt_finder> (m_eg, m_var);
+ return std::make_unique<refcnt_stmt_finder> (m_eg, m_var);
}
const gimple *
@@ -451,8 +451,9 @@ check_refcnt (const region_model *model,
const auto &eg = ctxt->get_eg ();
refcnt_stmt_finder finder (*eg, reg_tree);
- auto pd = make_unique<refcnt_mismatch> (curr_region, ob_refcnt_sval,
- actual_refcnt_sval, reg_tree);
+ auto pd = std::make_unique<refcnt_mismatch> (curr_region, ob_refcnt_sval,
+ actual_refcnt_sval,
+ reg_tree);
if (pd && eg)
ctxt->warn (std::move (pd), &finder);
}
@@ -680,7 +681,7 @@ kf_PyList_Append::impl_call_post (const call_details &cd) const
= old_ptr_sval->dyn_cast_region_svalue ())
{
const region *freed_reg = old_reg->get_pointee ();
- model->unbind_region_and_descendents (freed_reg, POISON_KIND_FREED);
+ model->unbind_region_and_descendents (freed_reg, poison_kind::freed);
model->unset_dynamic_extents (freed_reg);
}
@@ -885,7 +886,7 @@ kf_PyList_Append::impl_call_post (const call_details &cd) const
model->mark_region_as_unknown (freed_reg, cd.get_uncertainty ());
}
- model->unbind_region_and_descendents (freed_reg, POISON_KIND_FREED);
+ model->unbind_region_and_descendents (freed_reg, poison_kind::freed);
model->unset_dynamic_extents (freed_reg);
}
@@ -943,9 +944,9 @@ kf_PyList_Append::impl_call_post (const call_details &cd) const
/* Body of kf_PyList_Append::impl_call_post. */
if (cd.get_ctxt ())
{
- cd.get_ctxt ()->bifurcate (make_unique<realloc_failure> (cd));
- cd.get_ctxt ()->bifurcate (make_unique<realloc_success_no_move> (cd));
- cd.get_ctxt ()->bifurcate (make_unique<realloc_success_move> (cd));
+ cd.get_ctxt ()->bifurcate (std::make_unique<realloc_failure> (cd));
+ cd.get_ctxt ()->bifurcate (std::make_unique<realloc_success_no_move> (cd));
+ cd.get_ctxt ()->bifurcate (std::make_unique<realloc_success_move> (cd));
cd.get_ctxt ()->terminate_path ();
}
}
@@ -1078,8 +1079,8 @@ kf_PyList_New::impl_call_post (const call_details &cd) const
if (cd.get_ctxt ())
{
- cd.get_ctxt ()->bifurcate (make_unique<pyobj_init_fail> (cd));
- cd.get_ctxt ()->bifurcate (make_unique<success> (cd));
+ cd.get_ctxt ()->bifurcate (std::make_unique<pyobj_init_fail> (cd));
+ cd.get_ctxt ()->bifurcate (std::make_unique<success> (cd));
cd.get_ctxt ()->terminate_path ();
}
}
@@ -1147,8 +1148,8 @@ kf_PyLong_FromLong::impl_call_post (const call_details &cd) const
if (cd.get_ctxt ())
{
- cd.get_ctxt ()->bifurcate (make_unique<pyobj_init_fail> (cd));
- cd.get_ctxt ()->bifurcate (make_unique<success> (cd));
+ cd.get_ctxt ()->bifurcate (std::make_unique<pyobj_init_fail> (cd));
+ cd.get_ctxt ()->bifurcate (std::make_unique<success> (cd));
cd.get_ctxt ()->terminate_path ();
}
}
@@ -1290,14 +1291,14 @@ cpython_analyzer_init_cb (void *gcc_data, void * /*user_data */)
}
iface->register_known_function ("PyList_Append",
- make_unique<kf_PyList_Append> ());
- iface->register_known_function ("PyList_New", make_unique<kf_PyList_New> ());
+ std::make_unique<kf_PyList_Append> ());
+ iface->register_known_function ("PyList_New", std::make_unique<kf_PyList_New> ());
iface->register_known_function ("PyLong_FromLong",
- make_unique<kf_PyLong_FromLong> ());
+ std::make_unique<kf_PyLong_FromLong> ());
iface->register_known_function (
"__analyzer_cpython_dump_refcounts",
- make_unique<kf_analyzer_cpython_dump_refcounts> ());
+ std::make_unique<kf_analyzer_cpython_dump_refcounts> ());
}
} // namespace ana
diff --git a/gcc/testsuite/gcc.dg/plugin/analyzer_gil_plugin.cc b/gcc/testsuite/gcc.dg/plugin/analyzer_gil_plugin.cc
index 77767c8..c101c45 100644
--- a/gcc/testsuite/gcc.dg/plugin/analyzer_gil_plugin.cc
+++ b/gcc/testsuite/gcc.dg/plugin/analyzer_gil_plugin.cc
@@ -5,19 +5,19 @@
/* { dg-options "-g" } */
#define INCLUDE_MEMORY
+#define INCLUDE_STRING
#define INCLUDE_VECTOR
#include "gcc-plugin.h"
#include "config.h"
#include "system.h"
#include "coretypes.h"
-#include "make-unique.h"
#include "diagnostic.h"
#include "tree.h"
#include "gimple.h"
#include "gimple-iterator.h"
#include "gimple-walk.h"
-#include "diagnostic-event-id.h"
-#include "analyzer/analyzer.h"
+#include "diagnostics/event-id.h"
+#include "analyzer/common.h"
#include "analyzer/analyzer-logging.h"
#include "json.h"
#include "analyzer/sm.h"
@@ -66,7 +66,7 @@ public:
private:
void check_for_pyobject_in_call (sm_context &sm_ctxt,
const supernode *node,
- const gcall *call,
+ const gcall &call,
tree callee_fndecl) const;
public:
@@ -120,20 +120,22 @@ public:
return false;
}
- diagnostic_event::meaning
+ diagnostics::paths::event::meaning
get_meaning_for_state_change (const evdesc::state_change &change)
const final override
{
+ using event = diagnostics::paths::event;
+
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 event::meaning (event::verb::release,
+ 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 event::meaning (event::verb::acquire,
+ event::noun::lock);
}
- return diagnostic_event::meaning ();
+ return event::meaning ();
}
protected:
gil_diagnostic (const gil_state_machine &sm) : m_sm (sm)
@@ -147,7 +149,7 @@ public:
class double_save_thread : public gil_diagnostic
{
public:
- double_save_thread (const gil_state_machine &sm, const gcall *call)
+ double_save_thread (const gil_state_machine &sm, const gcall &call)
: gil_diagnostic (sm), m_call (call)
{}
@@ -160,7 +162,7 @@ class double_save_thread : public gil_diagnostic
{
const double_save_thread &sub_other
= (const double_save_thread &)base_other;
- return m_call == sub_other.m_call;
+ return &m_call == &sub_other.m_call;
}
bool emit (diagnostic_emission_context &ctxt) final override
@@ -179,13 +181,13 @@ class double_save_thread : public gil_diagnostic
}
private:
- const gcall *m_call;
+ const gcall &m_call;
};
class fncall_without_gil : public gil_diagnostic
{
public:
- fncall_without_gil (const gil_state_machine &sm, const gcall *call,
+ fncall_without_gil (const gil_state_machine &sm, const gcall &call,
tree callee_fndecl, unsigned arg_idx)
: gil_diagnostic (sm), m_call (call), m_callee_fndecl (callee_fndecl),
m_arg_idx (arg_idx)
@@ -200,7 +202,7 @@ class fncall_without_gil : public gil_diagnostic
{
const fncall_without_gil &sub_other
= (const fncall_without_gil &)base_other;
- return (m_call == sub_other.m_call
+ return (&m_call == &sub_other.m_call
&& m_callee_fndecl == sub_other.m_callee_fndecl
&& m_arg_idx == sub_other.m_arg_idx);
}
@@ -233,7 +235,7 @@ class fncall_without_gil : public gil_diagnostic
}
private:
- const gcall *m_call;
+ const gcall &m_call;
tree m_callee_fndecl;
unsigned m_arg_idx;
};
@@ -313,21 +315,21 @@ check_for_pyobject (gimple *, tree op, tree, void *data)
void
gil_state_machine::check_for_pyobject_in_call (sm_context &sm_ctxt,
const supernode *node,
- const gcall *call,
+ const gcall &call,
tree callee_fndecl) const
{
- for (unsigned i = 0; i < gimple_call_num_args (call); i++)
+ for (unsigned i = 0; i < gimple_call_num_args (&call); i++)
{
- tree arg = gimple_call_arg (call, i);
+ tree arg = gimple_call_arg (&call, i);
if (TREE_CODE (TREE_TYPE (arg)) != POINTER_TYPE)
continue;
tree type = TREE_TYPE (TREE_TYPE (arg));
if (type_based_on_pyobject_p (type))
{
- sm_ctxt.warn (node, call, NULL_TREE,
- make_unique<fncall_without_gil> (*this, call,
- callee_fndecl,
- i));
+ sm_ctxt.warn (node, &call, NULL_TREE,
+ std::make_unique<fncall_without_gil> (*this, call,
+ callee_fndecl,
+ i));
sm_ctxt.set_global_state (m_stop);
}
}
@@ -341,8 +343,9 @@ gil_state_machine::on_stmt (sm_context &sm_ctxt,
const gimple *stmt) const
{
const state_t global_state = sm_ctxt.get_global_state ();
- if (const gcall *call = dyn_cast <const gcall *> (stmt))
+ if (const gcall *call_stmt = dyn_cast <const gcall *> (stmt))
{
+ const gcall &call = *call_stmt;
if (tree callee_fndecl = sm_ctxt.get_fndecl_for_call (call))
{
if (is_named_call_p (callee_fndecl, "PyEval_SaveThread", call, 0))
@@ -353,7 +356,7 @@ gil_state_machine::on_stmt (sm_context &sm_ctxt,
if (global_state == m_released_gil)
{
sm_ctxt.warn (node, stmt, NULL_TREE,
- make_unique<double_save_thread> (*this, call));
+ std::make_unique<double_save_thread> (*this, call));
sm_ctxt.set_global_state (m_stop);
}
else
@@ -409,7 +412,7 @@ gil_state_machine::check_for_pyobject_usage_without_gil (sm_context &sm_ctxt,
if (type_based_on_pyobject_p (type))
{
sm_ctxt.warn (node, stmt, NULL_TREE,
- make_unique<pyobject_usage_without_gil> (*this, op));
+ std::make_unique<pyobject_usage_without_gil> (*this, op));
sm_ctxt.set_global_state (m_stop);
}
}
@@ -425,7 +428,7 @@ gil_analyzer_init_cb (void *gcc_data, void */*user_data*/)
if (0)
inform (input_location, "got here: gil_analyzer_init_cb");
iface->register_state_machine
- (make_unique<gil_state_machine> (iface->get_logger ()));
+ (std::make_unique<gil_state_machine> (iface->get_logger ()));
}
} // namespace ana
diff --git a/gcc/testsuite/gcc.dg/plugin/analyzer_kernel_plugin.cc b/gcc/testsuite/gcc.dg/plugin/analyzer_kernel_plugin.cc
index 7f2158e..fc282a7 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"
@@ -22,14 +23,14 @@
#include "target.h"
#include "fold-const.h"
#include "tree-pretty-print.h"
-#include "diagnostic-color.h"
-#include "diagnostic-metadata.h"
+#include "diagnostics/color.h"
+#include "diagnostics/metadata.h"
#include "tristate.h"
#include "bitmap.h"
#include "selftest.h"
#include "function.h"
#include "json.h"
-#include "analyzer/analyzer.h"
+#include "analyzer/common.h"
#include "analyzer/analyzer-logging.h"
#include "ordered-hash-map.h"
#include "options.h"
@@ -44,7 +45,6 @@
#include "analyzer/region-model.h"
#include "analyzer/call-details.h"
#include "analyzer/call-info.h"
-#include "make-unique.h"
int plugin_is_GPL_compatible;
@@ -106,7 +106,7 @@ class copy_across_boundary_fn : public known_function
if (ctxt)
{
/* Bifurcate state, creating a "failure" out-edge. */
- ctxt->bifurcate (make_unique<copy_failure> (cd));
+ ctxt->bifurcate (std::make_unique<copy_failure> (cd));
/* The "unbifurcated" state is the "success" case. */
copy_success success (cd,
@@ -238,11 +238,13 @@ kernel_analyzer_init_cb (void *gcc_data, void */*user_data*/)
inform (input_location, "got here: kernel_analyzer_init_cb");
iface->register_known_function
("copy_from_user",
- make_unique<known_function_copy_from_user> ());
- iface->register_known_function ("copy_to_user",
- make_unique<known_function_copy_to_user> ());
- iface->register_known_function ("__check_object_size",
- make_unique<known_function___check_object_size> ());
+ std::make_unique<known_function_copy_from_user> ());
+ iface->register_known_function
+ ("copy_to_user",
+ std::make_unique<known_function_copy_to_user> ());
+ iface->register_known_function
+ ("__check_object_size",
+ std::make_unique<known_function___check_object_size> ());
}
} // namespace ana
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 c060407..44fcf37 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"
@@ -22,14 +23,14 @@
#include "target.h"
#include "fold-const.h"
#include "tree-pretty-print.h"
-#include "diagnostic-color.h"
-#include "diagnostic-metadata.h"
+#include "diagnostics/color.h"
+#include "diagnostics/metadata.h"
#include "tristate.h"
#include "bitmap.h"
#include "selftest.h"
#include "function.h"
#include "json.h"
-#include "analyzer/analyzer.h"
+#include "analyzer/common.h"
#include "analyzer/analyzer-logging.h"
#include "ordered-hash-map.h"
#include "options.h"
@@ -44,7 +45,6 @@
#include "analyzer/region-model.h"
#include "analyzer/call-details.h"
#include "analyzer/call-info.h"
-#include "make-unique.h"
int plugin_is_GPL_compatible;
@@ -168,7 +168,7 @@ public:
if (cd.get_ctxt ())
{
/* Bifurcate state, creating a "failure" out-edge. */
- cd.get_ctxt ()->bifurcate (make_unique<copy_failure> (cd));
+ cd.get_ctxt ()->bifurcate (std::make_unique<copy_failure> (cd));
/* The "unbifurcated" state is the "success" case. */
copy_success success (cd,
@@ -189,11 +189,12 @@ known_fn_analyzer_init_cb (void *gcc_data, void */*user_data*/)
LOG_SCOPE (iface->get_logger ());
if (0)
inform (input_location, "got here: known_fn_analyzer_init_cb");
- iface->register_known_function ("returns_42",
- make_unique<known_function_returns_42> ());
+ iface->register_known_function
+ ("returns_42",
+ std::make_unique<known_function_returns_42> ());
iface->register_known_function
("attempt_to_copy",
- make_unique<known_function_attempt_to_copy> ());
+ std::make_unique<known_function_attempt_to_copy> ());
}
} // namespace ana
diff --git a/gcc/testsuite/gcc.dg/plugin/diagnostic-test-graphs-html.c b/gcc/testsuite/gcc.dg/plugin/diagnostic-test-graphs-html.c
new file mode 100644
index 0000000..2256a63
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/plugin/diagnostic-test-graphs-html.c
@@ -0,0 +1,13 @@
+/* { dg-do compile } */
+/* { dg-options "-fdiagnostics-add-output=experimental-html:javascript=no" } */
+
+extern void here (void);
+
+void test_graphs (void)
+{
+ here (); /* { dg-error "this is a placeholder error, with graphs" } */
+}
+
+/* Use a Python script to verify various properties about the generated
+ HTML file:
+ { dg-final { run-html-pytest diagnostic-test-graphs-html.c "diagnostic-test-graphs-html.py" } } */
diff --git a/gcc/testsuite/gcc.dg/plugin/diagnostic-test-graphs-html.py b/gcc/testsuite/gcc.dg/plugin/diagnostic-test-graphs-html.py
new file mode 100644
index 0000000..9ff4645
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/plugin/diagnostic-test-graphs-html.py
@@ -0,0 +1,48 @@
+# 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_result_graph(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
+
+ 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].tail == ' this is a placeholder error, with graphs'
+
+ graph = diag.find("./xhtml:div[@class='gcc-directed-graph']", ns)
+ assert graph is not None
+
+ header = graph.find("./xhtml:h2", ns)
+ assert header.text == 'foo'
+
+def test_run_graph(html_tree):
+ root = html_tree.getroot ()
+ assert root.tag == make_tag('html')
+
+ body = root.find('xhtml:body', ns)
+ assert body is not None
+
+ graph = body.find("./xhtml:div[@class='gcc-directed-graph']", ns)
+ assert graph is not None
+
+ header = graph.find("./xhtml:h2", ns)
+ assert header.text == 'Optimization Passes'
diff --git a/gcc/testsuite/gcc.dg/plugin/diagnostic-test-graphs-sarif.c b/gcc/testsuite/gcc.dg/plugin/diagnostic-test-graphs-sarif.c
new file mode 100644
index 0000000..4170f51
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/plugin/diagnostic-test-graphs-sarif.c
@@ -0,0 +1,16 @@
+/* { dg-do compile } */
+/* { dg-options "-fdiagnostics-add-output=sarif" } */
+
+extern void here (void);
+
+void test_graphs (void)
+{
+ here (); /* { dg-error "this is a placeholder error, with graphs" } */
+}
+
+/* Verify that some JSON was written to a file with the expected name. */
+/* { dg-final { verify-sarif-file } } */
+
+/* Use a Python script to verify various properties about the generated
+ .sarif file:
+ { dg-final { run-sarif-pytest diagnostic-test-graphs-sarif.c "diagnostic-test-graphs-sarif.py" } } */
diff --git a/gcc/testsuite/gcc.dg/plugin/diagnostic-test-graphs-sarif.py b/gcc/testsuite/gcc.dg/plugin/diagnostic-test-graphs-sarif.py
new file mode 100644
index 0000000..4bb7535
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/plugin/diagnostic-test-graphs-sarif.py
@@ -0,0 +1,55 @@
+from sarif import *
+
+import pytest
+
+@pytest.fixture(scope='function', autouse=True)
+def sarif():
+ return sarif_from_env()
+
+def test_basics(sarif):
+ schema = sarif['$schema']
+ assert schema == "https://docs.oasis-open.org/sarif/sarif/v2.1.0/errata01/os/schemas/sarif-schema-2.1.0.json"
+
+ version = sarif['version']
+ assert version == "2.1.0"
+
+def test_result_graph(sarif):
+ runs = sarif['runs']
+ run = runs[0]
+ results = run['results']
+
+ assert len(results) == 1
+
+ result = results[0]
+ assert result['level'] == 'error'
+ assert result['message']['text'] == "this is a placeholder error, with graphs"
+
+ assert len(result['graphs']) == 2
+
+ assert result['graphs'][0]['description']['text'] == 'foo'
+
+ assert len(result['graphs'][0]['nodes']) == 2
+ assert result['graphs'][0]['nodes'][0]['id'] == 'a'
+ assert result['graphs'][0]['nodes'][1]['id'] == 'b'
+ assert result['graphs'][0]['nodes'][1]['properties']['/placeholder-prefix/color'] == 'red'
+ assert len(result['graphs'][0]['nodes'][1]['children']) == 1
+ assert result['graphs'][0]['nodes'][1]['children'][0]['id'] == 'c'
+ assert result['graphs'][0]['nodes'][1]['children'][0]['label']['text'] == 'I am a node label'
+
+ assert len(result['graphs'][0]['edges']) == 1
+ result['graphs'][0]['edges'][0]['id'] == 'my-edge'
+ assert result['graphs'][0]['edges'][0]['label']['text'] == 'I am an edge label'
+ assert result['graphs'][0]['edges'][0]['sourceNodeId'] == 'a'
+ assert result['graphs'][0]['edges'][0]['targetNodeId'] == 'c'
+
+ assert result['graphs'][1]['description']['text'] == 'bar'
+
+def test_run_graph(sarif):
+ runs = sarif['runs']
+ run = runs[0]
+
+ assert len(run['graphs']) == 1
+
+ assert run['graphs'][0]['description']['text'] == 'Optimization Passes'
+ assert run['graphs'][0]['nodes'][0]['id'] == 'all_lowering_passes'
+ assert run['graphs'][0]['edges'][0]['id'] == 'edge0'
diff --git a/gcc/testsuite/gcc.dg/plugin/diagnostic-test-graphs.c b/gcc/testsuite/gcc.dg/plugin/diagnostic-test-graphs.c
new file mode 100644
index 0000000..7973954
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/plugin/diagnostic-test-graphs.c
@@ -0,0 +1,8 @@
+/* { dg-do compile } */
+
+extern void here (void);
+
+void test_graphs (void)
+{
+ here (); /* { dg-error "this is a placeholder error, with graphs" } */
+}
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-nesting-html.c b/gcc/testsuite/gcc.dg/plugin/diagnostic-test-nesting-html.c
new file mode 100644
index 0000000..8ff7b35
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/plugin/diagnostic-test-nesting-html.c
@@ -0,0 +1,13 @@
+/* { dg-do compile } */
+/* { dg-options "-fdiagnostics-add-output=experimental-html:javascript=no" } */
+
+extern void foo (void);
+
+void test_nesting (void)
+{
+ foo (); /* { dg-error "top-level error" } */
+}
+
+/* Use a Python script to verify various properties about the generated
+ .html file:
+ { dg-final { run-html-pytest diagnostic-test-nesting-html.c "diagnostic-test-nesting-html.py" } } */
diff --git a/gcc/testsuite/gcc.dg/plugin/diagnostic-test-nesting-html.py b/gcc/testsuite/gcc.dg/plugin/diagnostic-test-nesting-html.py
new file mode 100644
index 0000000..3899ba5
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/plugin/diagnostic-test-nesting-html.py
@@ -0,0 +1,69 @@
+# Verify that nesting 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_nesting(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
+
+ 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].tail == ' top-level error'
+
+ # We expect 12 messages, with the given IDs and text:
+ for i in range(12):
+ child = diag.find(".//xhtml:div[@id='gcc-diag-%i']" % (i + 1),
+ ns)
+ assert child is not None
+
+ message = child.find("./xhtml:div[@class='gcc-message']", ns)
+ assert message.attrib['id'] == 'gcc-diag-%i-message' % (i + 1)
+
+ if i % 4 == 0:
+ assert message.text == 'child %i' % (i / 4)
+ else:
+ assert message.text == 'grandchild %i %i' % ((i / 4), (i % 4) - 1)
+
+ # We expect the messages to be organized into nested <ul> with
+ # "nesting-level" set, all below a <ul>
+ child_ul = diag.find("./xhtml:ul[@nesting-level='1']", ns)
+ assert child_ul is not None
+ msg_id = 1
+ for i in range(3):
+ child_li = child_ul.find("./xhtml:li[@nesting-level='1'][%i]" % (i + 1), ns)
+ assert child_li is not None
+ child = child_li.find("./xhtml:div[@id='gcc-diag-%i']" % msg_id, ns)
+ assert child is not None
+ message = child.find("./xhtml:div[@class='gcc-message']", ns)
+ assert message.attrib['id'] == 'gcc-diag-%i-message' % msg_id
+ assert message.text == 'child %i' % i
+ msg_id += 1
+ grandchild_ul = child_ul.find("./xhtml:ul[@nesting-level='2'][%i]" % (i + 1), ns)
+ assert grandchild_ul is not None
+ for j in range(3):
+ grandchild_li = grandchild_ul.find("./xhtml:li[@nesting-level='2'][%i]" % (j + 1), ns)
+ assert grandchild_li is not None
+ grandchild = grandchild_li.find("./xhtml:div[@id='gcc-diag-%i']" % msg_id, ns)
+ assert grandchild is not None
+ message = grandchild.find("./xhtml:div[@class='gcc-message']", ns)
+ assert message.attrib['id'] == 'gcc-diag-%i-message' % msg_id
+ assert message.text == 'grandchild %i %i' % (i, j)
+ msg_id += 1
diff --git a/gcc/testsuite/gcc.dg/plugin/diagnostic-test-nesting-no-show-nesting.c b/gcc/testsuite/gcc.dg/plugin/diagnostic-test-nesting-no-show-nesting.c
new file mode 100644
index 0000000..3492899
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/plugin/diagnostic-test-nesting-no-show-nesting.c
@@ -0,0 +1,9 @@
+/* { dg-do compile } */
+/* { dg-options "-fno-diagnostics-show-nesting" } */
+
+extern void foo (void);
+
+void test_nesting (void)
+{
+ foo (); /* { dg-error "top-level error" } */
+}
diff --git a/gcc/testsuite/gcc.dg/plugin/diagnostic-test-nesting-show-nesting.c b/gcc/testsuite/gcc.dg/plugin/diagnostic-test-nesting-show-nesting.c
new file mode 100644
index 0000000..8fc2edb
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/plugin/diagnostic-test-nesting-show-nesting.c
@@ -0,0 +1,24 @@
+/* { dg-do compile } */
+/* { dg-options "-fdiagnostics-show-nesting" } */
+
+extern void foo (void);
+
+void test_nesting (void)
+{
+ foo (); /* { dg-error "top-level error" } */
+}
+
+/* { dg-begin-multiline-output "" }
+ * child 0
+ * grandchild 0 0
+ * grandchild 0 1
+ * grandchild 0 2
+ * child 1
+ * grandchild 1 0
+ * grandchild 1 1
+ * grandchild 1 2
+ * child 2
+ * grandchild 2 0
+ * grandchild 2 1
+ * grandchild 2 2
+ { dg-end-multiline-output "" } */
diff --git a/gcc/testsuite/gcc.dg/plugin/diagnostic-test-nesting-text-indented-show-levels.c b/gcc/testsuite/gcc.dg/plugin/diagnostic-test-nesting-text-indented-show-levels.c
index f44c8eb..4be52fe 100644
--- a/gcc/testsuite/gcc.dg/plugin/diagnostic-test-nesting-text-indented-show-levels.c
+++ b/gcc/testsuite/gcc.dg/plugin/diagnostic-test-nesting-text-indented-show-levels.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-options "-fdiagnostics-set-output=text:experimental-nesting=yes,experimental-nesting-show-levels=yes" } */
+/* { dg-options "-fdiagnostics-set-output=text:show-nesting=yes,show-nesting-levels=yes" } */
extern void foo (void);
diff --git a/gcc/testsuite/gcc.dg/plugin/diagnostic-test-nesting-text-indented-unicode.c b/gcc/testsuite/gcc.dg/plugin/diagnostic-test-nesting-text-indented-unicode.c
index 39e29f7..c069c3f 100644
--- a/gcc/testsuite/gcc.dg/plugin/diagnostic-test-nesting-text-indented-unicode.c
+++ b/gcc/testsuite/gcc.dg/plugin/diagnostic-test-nesting-text-indented-unicode.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-options "-fdiagnostics-set-output=text:experimental-nesting=yes -fdiagnostics-text-art-charset=unicode" } */
+/* { dg-options "-fdiagnostics-set-output=text:show-nesting=yes -fdiagnostics-text-art-charset=unicode" } */
extern void foo (void);
diff --git a/gcc/testsuite/gcc.dg/plugin/diagnostic-test-nesting-text-indented.c b/gcc/testsuite/gcc.dg/plugin/diagnostic-test-nesting-text-indented.c
index e103429..a35254d 100644
--- a/gcc/testsuite/gcc.dg/plugin/diagnostic-test-nesting-text-indented.c
+++ b/gcc/testsuite/gcc.dg/plugin/diagnostic-test-nesting-text-indented.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-options "-fdiagnostics-set-output=text:experimental-nesting=yes" } */
+/* { dg-options "-fdiagnostics-set-output=text:show-nesting=yes" } */
extern void foo (void);
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..eaca35a
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/plugin/diagnostic-test-show-locus.py
@@ -0,0 +1,115 @@
+# Verify that diagnostics/source-printing.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 7e6d7e1..48f8325 100644
--- a/gcc/testsuite/gcc.dg/plugin/diagnostic_group_plugin.cc
+++ b/gcc/testsuite/gcc.dg/plugin/diagnostic_group_plugin.cc
@@ -27,9 +27,8 @@
#include "plugin-version.h"
#include "c-family/c-common.h"
#include "diagnostic.h"
-#include "diagnostic-format-text.h"
+#include "diagnostics/text-sink.h"
#include "context.h"
-#include "make-unique.h"
int plugin_is_GPL_compatible;
@@ -166,8 +165,8 @@ pass_test_groups::execute (function *fun)
expected output. */
void
-test_diagnostic_text_starter (diagnostic_text_output_format &text_output,
- const diagnostic_info *diagnostic)
+test_diagnostic_text_starter (diagnostics::text_sink &text_output,
+ const diagnostics::diagnostic_info *diagnostic)
{
pp_set_prefix (text_output.get_printer (), xstrdup ("PREFIX: "));
}
@@ -176,21 +175,22 @@ test_diagnostic_text_starter (diagnostic_text_output_format &text_output,
expected output. */
void
-test_diagnostic_start_span_fn (const diagnostic_location_print_policy &,
- pretty_printer *pp,
+test_diagnostic_start_span_fn (const diagnostics::location_print_policy &,
+ diagnostics::to_text &sink,
expanded_location)
{
+ pretty_printer *pp = diagnostics::get_printer (sink);
pp_string (pp, "START_SPAN_FN: ");
pp_newline (pp);
}
-/* Custom output format subclass. */
+/* Custom text_sink subclass. */
-class test_output_format : public diagnostic_text_output_format
+class custom_test_sink : public diagnostics::text_sink
{
public:
- test_output_format (diagnostic_context &context)
- : diagnostic_text_output_format (context)
+ custom_test_sink (diagnostics::context &context)
+ : diagnostics::text_sink (context)
{}
void on_begin_group () final override
@@ -228,9 +228,9 @@ plugin_init (struct plugin_name_args *plugin_info,
if (!plugin_default_version_check (version, &gcc_version))
return 1;
- diagnostic_text_starter (global_dc) = test_diagnostic_text_starter;
- diagnostic_start_span (global_dc) = test_diagnostic_start_span_fn;
- global_dc->set_output_format (::make_unique<test_output_format> (*global_dc));
+ diagnostics::text_starter (global_dc) = test_diagnostic_text_starter;
+ diagnostics::start_span (global_dc) = test_diagnostic_start_span_fn;
+ global_dc->set_sink (::std::make_unique<custom_test_sink> (*global_dc));
pass_info.pass = new pass_test_groups (g);
pass_info.reference_pass_name = "*warn_function_noreturn";
diff --git a/gcc/testsuite/gcc.dg/plugin/diagnostic_plugin_show_trees.cc b/gcc/testsuite/gcc.dg/plugin/diagnostic_plugin_show_trees.cc
index 44b94da..7e34a42 100644
--- a/gcc/testsuite/gcc.dg/plugin/diagnostic_plugin_show_trees.cc
+++ b/gcc/testsuite/gcc.dg/plugin/diagnostic_plugin_show_trees.cc
@@ -115,7 +115,7 @@ plugin_init (struct plugin_name_args *plugin_info,
if (!plugin_default_version_check (version, &gcc_version))
return 1;
- global_dc->m_source_printing.max_width = 80;
+ global_dc->get_source_printing_options ().max_width = 80;
register_callback (plugin_name,
PLUGIN_PRE_GENERICIZE,
diff --git a/gcc/testsuite/gcc.dg/plugin/diagnostic_plugin_test_graphs.cc b/gcc/testsuite/gcc.dg/plugin/diagnostic_plugin_test_graphs.cc
new file mode 100644
index 0000000..7398a29
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/plugin/diagnostic_plugin_test_graphs.cc
@@ -0,0 +1,283 @@
+/* This plugin exercises diagnostic graphs.
+ We emit an error with a pair of digraphs associated with it,
+ and a global digraph showing the optimization passes. */
+
+#define INCLUDE_MAP
+#define INCLUDE_STRING
+#define INCLUDE_VECTOR
+#include "gcc-plugin.h"
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
+#include "tree.h"
+#include "stringpool.h"
+#include "toplev.h"
+#include "basic-block.h"
+#include "hash-table.h"
+#include "vec.h"
+#include "ggc.h"
+#include "basic-block.h"
+#include "tree-ssa-alias.h"
+#include "internal-fn.h"
+#include "gimple.h"
+#include "gimple-iterator.h"
+#include "gimple-fold.h"
+#include "tree-eh.h"
+#include "gimple-expr.h"
+#include "is-a.h"
+#include "tree.h"
+#include "tree-pass.h"
+#include "intl.h"
+#include "plugin-version.h"
+#include "diagnostic.h"
+#include "context.h"
+#include "gcc-rich-location.h"
+#include "diagnostics/metadata.h"
+#include "diagnostics/digraphs.h"
+#include "pass_manager.h"
+
+
+int plugin_is_GPL_compatible;
+
+const pass_data pass_data_test_graph_emission =
+{
+ GIMPLE_PASS, /* type */
+ "test_graph_emission", /* name */
+ OPTGROUP_NONE, /* optinfo_flags */
+ TV_NONE, /* tv_id */
+ PROP_ssa, /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ 0, /* todo_flags_finish */
+};
+
+class pass_test_graph_emission : public gimple_opt_pass
+{
+public:
+ pass_test_graph_emission(gcc::context *ctxt)
+ : gimple_opt_pass(pass_data_test_graph_emission, ctxt)
+ {}
+
+ /* opt_pass methods: */
+ bool gate (function *) { return true; }
+ virtual unsigned int execute (function *);
+
+}; // class pass_test_graph_emission
+
+/* Determine if STMT is a call with NUM_ARGS arguments to a function
+ named FUNCNAME.
+ If so, return STMT as a gcall *. Otherwise return NULL. */
+
+static gcall *
+check_for_named_call (gimple *stmt,
+ const char *funcname, unsigned int num_args)
+{
+ gcc_assert (funcname);
+
+ gcall *call = dyn_cast <gcall *> (stmt);
+ if (!call)
+ return NULL;
+
+ tree fndecl = gimple_call_fndecl (call);
+ if (!fndecl)
+ return NULL;
+
+ if (strcmp (IDENTIFIER_POINTER (DECL_NAME (fndecl)), funcname))
+ return NULL;
+
+ if (gimple_call_num_args (call) != num_args)
+ {
+ error_at (stmt->location, "expected number of args: %i (got %i)",
+ num_args, gimple_call_num_args (call));
+ return NULL;
+ }
+
+ return call;
+}
+
+class lazy_passes_graph : public lazily_created<diagnostics::digraphs::digraph>
+{
+public:
+ lazy_passes_graph (const ::gcc::pass_manager &pass_manager_)
+ : m_pass_manager (pass_manager_)
+ {
+ }
+
+private:
+ std::unique_ptr<diagnostics::digraphs::digraph>
+ create_object () const final override
+ {
+ auto g = std::make_unique<diagnostics::digraphs::digraph> ();
+ g->set_description ("Optimization Passes");
+
+#define DEF_PASS_LIST(NAME) \
+ add_top_level_pass_list (*g, #NAME, m_pass_manager.NAME);
+
+ GCC_PASS_LISTS
+
+#undef DEF_PASS_LIST
+
+ return g;
+ }
+
+ void
+ add_top_level_pass_list (diagnostics::digraphs::digraph &g,
+ const char *pass_list_name,
+ const opt_pass *p) const
+ {
+ gcc_assert (p);
+ auto n = std::make_unique<diagnostics::digraphs::node> (g, pass_list_name);
+ n->set_label (pass_list_name);
+ add_child_pass (g, *n, *p);
+ g.add_node (std::move (n));
+ }
+
+ diagnostics::digraphs::node &
+ add_child_pass (diagnostics::digraphs::digraph &g,
+ diagnostics::digraphs::node &parent_node,
+ const opt_pass &p) const
+ {
+ std::string node_label;
+ std::string node_id;
+ if (p.static_pass_number > 0 )
+ {
+ node_label = std::to_string (p.static_pass_number) + "_" + p.name;
+ node_id = node_label;
+ }
+ else
+ {
+ node_label = std::string (p.name);
+ pretty_printer pp;
+ pp_printf (&pp, "%s_%p", p.name, &p);
+ node_id = pp_formatted_text (&pp);
+ }
+ auto n
+ = std::make_unique<diagnostics::digraphs::node> (g,
+ std::move (node_id));
+ n->set_label (node_label.c_str ());
+ diagnostics::digraphs::node &result = *n;
+ parent_node.add_child (std::move (n));
+
+ // TODO: add attrs for things like type, properties_*, etc
+
+ if (p.sub)
+ {
+ auto &other_node = add_child_pass (g, parent_node, *p.sub);
+ g.add_edge (nullptr, result, other_node, "sub");
+ }
+
+ if (p.next)
+ {
+ auto &other_node = add_child_pass (g, parent_node, *p.next);
+ g.add_edge (nullptr, result, other_node, "next");
+ }
+
+ return result;
+ }
+
+ const ::gcc::pass_manager &m_pass_manager;
+};
+
+static void
+report_diag_with_graphs (location_t loc)
+{
+ class my_lazy_digraphs : public diagnostics::metadata::lazy_digraphs
+ {
+ public:
+ using diagnostic_graph = diagnostics::digraphs::digraph;
+ using diagnostic_node = diagnostics::digraphs::node;
+ using diagnostic_edge = diagnostics::digraphs::edge;
+
+ std::unique_ptr<std::vector<std::unique_ptr<diagnostic_graph>>>
+ create_object () const final override
+ {
+ auto graphs
+ = std::make_unique<std::vector<std::unique_ptr<diagnostic_graph>>> ();
+
+ graphs->push_back (make_test_graph ("foo"));
+ graphs->push_back (make_test_graph ("bar"));
+
+ return graphs;
+ }
+
+ private:
+ std::unique_ptr<diagnostic_graph>
+ make_test_graph (const char *desc) const
+ {
+ auto g = std::make_unique<diagnostic_graph> ();
+ g->set_description (desc);
+ auto a = std::make_unique<diagnostic_node> (*g, "a");
+ auto b = std::make_unique<diagnostic_node> (*g, "b");
+#define KEY_PREFIX "/placeholder-prefix/"
+ b->set_attr (KEY_PREFIX, "color", "red");
+#undef KEY_PREFIX
+ auto c = std::make_unique<diagnostic_node> (*g, "c");
+ c->set_label ("I am a node label");
+
+ auto e = std::make_unique<diagnostic_edge> (*g, "my-edge", *a, *c);
+ e->set_label ("I am an edge label");
+ g->add_edge (std::move (e));
+
+ g->add_node (std::move (a));
+
+ b->add_child (std::move (c));
+ g->add_node (std::move (b));
+
+ return g;
+ }
+ };
+
+ gcc_rich_location rich_loc (loc);
+ diagnostics::metadata meta;
+ my_lazy_digraphs ldg;
+ meta.set_lazy_digraphs (&ldg);
+ error_meta (&rich_loc, meta,
+ "this is a placeholder error, with graphs");
+}
+
+/* Exercise diagnostic graph emission. */
+
+unsigned int
+pass_test_graph_emission::execute (function *fun)
+{
+ gimple_stmt_iterator gsi;
+ basic_block bb;
+
+ FOR_EACH_BB_FN (bb, fun)
+ for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
+ {
+ gimple *stmt = gsi_stmt (gsi);
+
+ if (gcall *call = check_for_named_call (stmt, "here", 0))
+ report_diag_with_graphs (gimple_location (call));
+ }
+
+ return 0;
+}
+
+int
+plugin_init (struct plugin_name_args *plugin_info,
+ struct plugin_gcc_version *version)
+{
+ struct register_pass_info pass_info;
+ 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;
+
+ pass_info.pass = new pass_test_graph_emission (g);
+ pass_info.reference_pass_name = "ssa";
+ pass_info.ref_pass_instance_number = 1;
+ pass_info.pos_op = PASS_POS_INSERT_AFTER;
+ register_callback (plugin_name, PLUGIN_PASS_MANAGER_SETUP, NULL,
+ &pass_info);
+
+ gcc_assert (::g->get_passes ());
+ global_dc->report_global_digraph (lazy_passes_graph (*::g->get_passes ()));
+
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/plugin/diagnostic_plugin_test_inlining.cc b/gcc/testsuite/gcc.dg/plugin/diagnostic_plugin_test_inlining.cc
index 7edce1f..d38538d 100644
--- a/gcc/testsuite/gcc.dg/plugin/diagnostic_plugin_test_inlining.cc
+++ b/gcc/testsuite/gcc.dg/plugin/diagnostic_plugin_test_inlining.cc
@@ -169,7 +169,7 @@ plugin_init (struct plugin_name_args *plugin_info,
if (!plugin_default_version_check (version, &gcc_version))
return 1;
- global_dc->m_source_printing.max_width = 80;
+ global_dc->get_source_printing_options ().max_width = 80;
pass_info.pass = new pass_test_inlining (g);
pass_info.reference_pass_name = "*warn_function_noreturn";
diff --git a/gcc/testsuite/gcc.dg/plugin/diagnostic_plugin_test_metadata.cc b/gcc/testsuite/gcc.dg/plugin/diagnostic_plugin_test_metadata.cc
index b86a8b3..f172258 100644
--- a/gcc/testsuite/gcc.dg/plugin/diagnostic_plugin_test_metadata.cc
+++ b/gcc/testsuite/gcc.dg/plugin/diagnostic_plugin_test_metadata.cc
@@ -1,5 +1,6 @@
-/* This plugin exercises diagnostic_metadata. */
+/* This plugin exercises diagnostics::metadata. */
+#define INCLUDE_VECTOR
#include "gcc-plugin.h"
#include "config.h"
#include "system.h"
@@ -28,7 +29,7 @@
#include "diagnostic.h"
#include "context.h"
#include "gcc-rich-location.h"
-#include "diagnostic-metadata.h"
+#include "diagnostics/metadata.h"
int plugin_is_GPL_compatible;
@@ -89,7 +90,7 @@ check_for_named_call (gimple *stmt,
return call;
}
-/* Exercise diagnostic_metadata. */
+/* Exercise diagnostics::metadata. */
unsigned int
pass_test_metadata::execute (function *fun)
@@ -106,13 +107,13 @@ pass_test_metadata::execute (function *fun)
if (gcall *call = check_for_named_call (stmt, "gets", 1))
{
gcc_rich_location richloc (gimple_location (call));
- diagnostic_metadata m;
+ diagnostics::metadata m;
/* CWE-242: Use of Inherently Dangerous Function. */
m.add_cwe (242);
- /* Example of a diagnostic_metadata::rule. */
- diagnostic_metadata::precanned_rule
+ /* Example of a diagnostics::metadata::rule. */
+ diagnostics::metadata::precanned_rule
test_rule ("STR34-C", "https://example.com/");
m.add_rule (test_rule);
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..875f4a8 100644
--- a/gcc/testsuite/gcc.dg/plugin/diagnostic_plugin_test_paths.cc
+++ b/gcc/testsuite/gcc.dg/plugin/diagnostic_plugin_test_paths.cc
@@ -6,6 +6,7 @@
specific tests within the compiler's IR. We can't use any real
diagnostics for this, so we have to fake it, hence this plugin. */
+#define INCLUDE_VECTOR
#include "gcc-plugin.h"
#include "config.h"
#include "system.h"
@@ -32,8 +33,7 @@
#include "intl.h"
#include "plugin-version.h"
#include "diagnostic.h"
-#include "diagnostic-path.h"
-#include "diagnostic-metadata.h"
+#include "diagnostics/metadata.h"
#include "context.h"
#include "print-tree.h"
#include "gcc-rich-location.h"
@@ -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,13 +216,14 @@ 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
add_event_2 (event_location_t evloc, int stack_depth,
const char *desc,
- diagnostic_thread_id_t thread_id = 0)
+ diagnostics::paths::thread_id_t thread_id = 0)
{
gcc_assert (evloc.m_fun);
return add_thread_event (thread_id, evloc.m_loc, evloc.m_fun->decl,
@@ -229,7 +232,7 @@ class test_diagnostic_path : public simple_diagnostic_path
diagnostic_event_id_t
add_event_2_with_event_id (event_location_t evloc, int stack_depth,
const char *fmt,
- diagnostic_thread_id_t thread_id,
+ diagnostics::paths::thread_id_t thread_id,
diagnostic_event_id_t event_id)
{
gcc_assert (evloc.m_fun);
@@ -239,7 +242,7 @@ class test_diagnostic_path : public simple_diagnostic_path
}
void add_entry (event_location_t evloc, int stack_depth,
const char *funcname,
- diagnostic_thread_id_t thread_id = 0)
+ diagnostics::paths::thread_id_t thread_id = 0)
{
gcc_assert (evloc.m_fun);
add_thread_event (thread_id, evloc.m_loc, evloc.m_fun->decl, stack_depth,
@@ -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
@@ -357,7 +363,7 @@ example_2 ()
richloc.set_path (&path);
- diagnostic_metadata m;
+ diagnostics::metadata m;
m.add_cwe (415); /* CWE-415: Double Free. */
warning_meta (&richloc, m, 0,
@@ -435,7 +441,7 @@ example_3 ()
richloc.set_path (&path);
- diagnostic_metadata m;
+ diagnostics::metadata m;
/* CWE-479: Signal Handler Use of a Non-reentrant Function. */
m.add_cwe (479);
@@ -496,8 +502,8 @@ example_4 ()
gcc_rich_location richloc (call_to_acquire_lock_a_in_bar.m_loc);
test_diagnostic_path path (global_dc->get_reference_printer ());
- diagnostic_thread_id_t thread_1 = path.add_thread ("Thread 1");
- diagnostic_thread_id_t thread_2 = path.add_thread ("Thread 2");
+ diagnostics::paths::thread_id_t thread_1 = path.add_thread ("Thread 1");
+ diagnostics::paths::thread_id_t thread_2 = path.add_thread ("Thread 2");
path.add_entry (entry_to_foo, 0, "foo", thread_1);
diagnostic_event_id_t event_a_acquired
= path.add_event_2 (call_to_acquire_lock_a_in_foo, 1,
@@ -518,7 +524,7 @@ example_4 ()
thread_2, event_a_acquired);
richloc.set_path (&path);
- diagnostic_metadata m;
+ diagnostics::metadata m;
warning_meta (&richloc, m, 0,
"deadlock due to inconsistent lock acquisition order");
}
@@ -553,7 +559,7 @@ plugin_init (struct plugin_name_args *plugin_info,
if (!plugin_default_version_check (version, &gcc_version))
return 1;
- global_dc->m_source_printing.max_width = 80;
+ global_dc->get_source_printing_options ().max_width = 80;
pass_info.pass = make_pass_test_show_path (g);
pass_info.reference_pass_name = "whole-program";
diff --git a/gcc/testsuite/gcc.dg/plugin/diagnostic_plugin_test_show_locus.cc b/gcc/testsuite/gcc.dg/plugin/diagnostic_plugin_test_show_locus.cc
index cd3834b..92839cd 100644
--- a/gcc/testsuite/gcc.dg/plugin/diagnostic_plugin_test_show_locus.cc
+++ b/gcc/testsuite/gcc.dg/plugin/diagnostic_plugin_test_show_locus.cc
@@ -62,7 +62,8 @@
#include "print-tree.h"
#include "gcc-rich-location.h"
#include "text-range-label.h"
-#include "diagnostic-format-text.h"
+#include "diagnostics/text-sink.h"
+#include "diagnostics/file-cache.h"
int plugin_is_GPL_compatible;
@@ -125,14 +126,14 @@ static bool force_show_locus_color = false;
/* We want to verify the colorized output of diagnostic_show_locus,
but turning on colorization for everything confuses "dg-warning" etc.
Hence we special-case it within this plugin by using this modified
- version of default_diagnostic_text_finalizer, which, if "color" is
+ version of diagnostics::default_text_finalizer, which, if "color" is
passed in as a plugin argument turns on colorization, but just
for diagnostic_show_locus. */
static void
-custom_diagnostic_text_finalizer (diagnostic_text_output_format &text_output,
- const diagnostic_info *diagnostic,
- diagnostic_t)
+custom_diagnostic_text_finalizer (diagnostics::text_sink &text_output,
+ const diagnostics::diagnostic_info *diag,
+ enum diagnostics::kind)
{
pretty_printer *const pp = text_output.get_printer ();
bool old_show_color = pp_show_color (pp);
@@ -143,7 +144,7 @@ custom_diagnostic_text_finalizer (diagnostic_text_output_format &text_output,
pp_newline (pp);
diagnostic_show_locus (&text_output.get_context (),
text_output.get_source_printing_options (),
- diagnostic->richloc, diagnostic->kind, pp);
+ diag->m_richloc, diag->m_kind, pp);
pp_show_color (pp) = old_show_color;
pp_set_prefix (pp, saved_prefix);
pp_flush (pp);
@@ -176,11 +177,11 @@ test_show_locus (function *fun)
location_t fnstart = fun->function_start_locus;
int fnstart_line = LOCATION_LINE (fnstart);
- diagnostic_text_finalizer (global_dc) = custom_diagnostic_text_finalizer;
+ diagnostics::text_finalizer (global_dc) = custom_diagnostic_text_finalizer;
/* Hardcode the "terminal width", to verify the behavior of
very wide lines. */
- global_dc->m_source_printing.max_width = 71;
+ global_dc->get_source_printing_options ().max_width = 71;
if (0 == strcmp (fnname, "test_simple"))
{
@@ -251,7 +252,7 @@ test_show_locus (function *fun)
if (0 == strcmp (fnname, "test_very_wide_line"))
{
const int line = fnstart_line + 2;
- global_dc->m_source_printing.show_ruler_p = true;
+ global_dc->get_source_printing_options ().show_ruler_p = true;
text_range_label label0 ("label 0");
text_range_label label1 ("label 1");
rich_location richloc (line_table,
@@ -263,7 +264,7 @@ test_show_locus (function *fun)
&label1);
richloc.add_fixit_replace ("bar * foo");
warning_at (&richloc, 0, "test");
- global_dc->m_source_printing.show_ruler_p = false;
+ global_dc->get_source_printing_options ().show_ruler_p = false;
}
/* Likewise, but with a secondary location that's immediately before
@@ -271,7 +272,7 @@ test_show_locus (function *fun)
if (0 == strcmp (fnname, "test_very_wide_line_2"))
{
const int line = fnstart_line + 2;
- global_dc->m_source_printing.show_ruler_p = true;
+ global_dc->get_source_printing_options ().show_ruler_p = true;
text_range_label label0 ("label 0");
text_range_label label1 ("label 1");
rich_location richloc (line_table,
@@ -283,7 +284,7 @@ test_show_locus (function *fun)
richloc.add_range (get_loc (line, 34), SHOW_RANGE_WITHOUT_CARET,
&label1);
warning_at (&richloc, 0, "test");
- global_dc->m_source_printing.show_ruler_p = false;
+ global_dc->get_source_printing_options ().show_ruler_p = false;
}
/* Example of multiple carets. */
@@ -294,11 +295,11 @@ test_show_locus (function *fun)
location_t caret_b = get_loc (line, 11);
rich_location richloc (line_table, caret_a);
add_range (&richloc, caret_b, caret_b, SHOW_RANGE_WITH_CARET);
- global_dc->m_source_printing.caret_chars[0] = 'A';
- global_dc->m_source_printing.caret_chars[1] = 'B';
+ global_dc->get_source_printing_options ().caret_chars[0] = 'A';
+ global_dc->get_source_printing_options ().caret_chars[1] = 'B';
warning_at (&richloc, 0, "test");
- global_dc->m_source_printing.caret_chars[0] = '^';
- global_dc->m_source_printing.caret_chars[1] = '^';
+ global_dc->get_source_printing_options ().caret_chars[0] = '^';
+ global_dc->get_source_printing_options ().caret_chars[1] = '^';
}
/* Tests of rendering fixit hints. */
@@ -412,11 +413,11 @@ test_show_locus (function *fun)
location_t caret_b = get_loc (line - 1, 19);
rich_location richloc (line_table, caret_a);
richloc.add_range (caret_b, SHOW_RANGE_WITH_CARET);
- global_dc->m_source_printing.caret_chars[0] = '1';
- global_dc->m_source_printing.caret_chars[1] = '2';
+ global_dc->get_source_printing_options ().caret_chars[0] = '1';
+ global_dc->get_source_printing_options ().caret_chars[1] = '2';
warning_at (&richloc, 0, "test");
- global_dc->m_source_printing.caret_chars[0] = '^';
- global_dc->m_source_printing.caret_chars[1] = '^';
+ global_dc->get_source_printing_options ().caret_chars[0] = '^';
+ global_dc->get_source_printing_options ().caret_chars[1] = '^';
}
/* Example of using the "%q+D" format code, which as well as printing
@@ -443,8 +444,8 @@ test_show_locus (function *fun)
rich_location richloc (line_table, loc);
for (int line = start_line; line <= finish_line; line++)
{
- file_cache &fc = global_dc->get_file_cache ();
- char_span content = fc.get_source_line (file, line);
+ diagnostics::file_cache &fc = global_dc->get_file_cache ();
+ diagnostics::char_span content = fc.get_source_line (file, line);
gcc_assert (content);
/* Split line up into words. */
for (int idx = 0; idx < content.length (); idx++)
@@ -464,7 +465,8 @@ test_show_locus (function *fun)
richloc.add_range (word, SHOW_RANGE_WITH_CARET, &label);
/* Add a fixit, converting to upper case. */
- char_span word_span = content.subspan (start_idx, idx - start_idx);
+ diagnostics::char_span word_span
+ = content.subspan (start_idx, idx - start_idx);
char *copy = word_span.xstrdup ();
for (char *ch = copy; *ch; ch++)
*ch = TOUPPER (*ch);
diff --git a/gcc/testsuite/gcc.dg/plugin/diagnostic_plugin_test_string_literals.cc b/gcc/testsuite/gcc.dg/plugin/diagnostic_plugin_test_string_literals.cc
index 1b5fad2..b64d60f 100644
--- a/gcc/testsuite/gcc.dg/plugin/diagnostic_plugin_test_string_literals.cc
+++ b/gcc/testsuite/gcc.dg/plugin/diagnostic_plugin_test_string_literals.cc
@@ -208,7 +208,7 @@ plugin_init (struct plugin_name_args *plugin_info,
if (!plugin_default_version_check (version, &gcc_version))
return 1;
- global_dc->m_source_printing.max_width = 80;
+ global_dc->get_source_printing_options ().max_width = 80;
pass_info.pass = new pass_test_string_literals (g);
pass_info.reference_pass_name = "ssa";
diff --git a/gcc/testsuite/gcc.dg/plugin/diagnostic_plugin_test_text_art.cc b/gcc/testsuite/gcc.dg/plugin/diagnostic_plugin_test_text_art.cc
index e28d697..ce2f1d3 100644
--- a/gcc/testsuite/gcc.dg/plugin/diagnostic_plugin_test_text_art.cc
+++ b/gcc/testsuite/gcc.dg/plugin/diagnostic_plugin_test_text_art.cc
@@ -9,7 +9,7 @@
#include "coretypes.h"
#include "plugin-version.h"
#include "diagnostic.h"
-#include "diagnostic-diagram.h"
+#include "diagnostics/diagram.h"
#include "text-art/canvas.h"
#include "text-art/table.h"
@@ -22,7 +22,7 @@ using namespace text_art;
static void
emit_canvas (const canvas &c, const char *alt_text)
{
- diagnostic_diagram diagram (c, alt_text);
+ diagnostics::diagram diagram (c, alt_text);
global_dc->emit_diagram (diagram);
}
diff --git a/gcc/testsuite/gcc.dg/plugin/diagnostic_plugin_test_tree_expression_range.cc b/gcc/testsuite/gcc.dg/plugin/diagnostic_plugin_test_tree_expression_range.cc
index fbdb2f8..bbd0faa 100644
--- a/gcc/testsuite/gcc.dg/plugin/diagnostic_plugin_test_tree_expression_range.cc
+++ b/gcc/testsuite/gcc.dg/plugin/diagnostic_plugin_test_tree_expression_range.cc
@@ -89,7 +89,7 @@ plugin_init (struct plugin_name_args *plugin_info,
if (!plugin_default_version_check (version, &gcc_version))
return 1;
- global_dc->m_source_printing.max_width = 130;
+ global_dc->get_source_printing_options ().max_width = 130;
register_callback (plugin_name,
PLUGIN_PRE_GENERICIZE,
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 2ce267c..0000000
--- a/gcc/testsuite/gcc.dg/plugin/diagnostic_plugin_xhtml_format.cc
+++ /dev/null
@@ -1,986 +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 "make-unique.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 (::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 = ::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 = ::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 = ::make_unique<xml::document> ();
- {
- auto html_element = ::make_unique<xml::element> ("html", false);
- html_element->set_attr
- ("xmlns",
- label_text::borrow ("http://www.w3.org/1999/xhtml"));
- {
- {
- auto head_element = ::make_unique<xml::element> ("head", false);
- {
- auto title_element = ::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 = ::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 = ::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 = ::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 = ::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 = ::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 ::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 = ::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 = ::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 = ::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
- (::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/expensive_selftests_plugin.cc b/gcc/testsuite/gcc.dg/plugin/expensive_selftests_plugin.cc
index 7b9b8d4..67722d4 100644
--- a/gcc/testsuite/gcc.dg/plugin/expensive_selftests_plugin.cc
+++ b/gcc/testsuite/gcc.dg/plugin/expensive_selftests_plugin.cc
@@ -6,9 +6,9 @@
#include "system.h"
#include "coretypes.h"
#include "diagnostic.h"
-#include "edit-context.h"
+#include "diagnostics/changes.h"
#include "selftest.h"
-#include "selftest-diagnostic.h"
+#include "diagnostics/selftest-context.h"
int plugin_is_GPL_compatible;
@@ -47,14 +47,15 @@ static void
test_richloc (rich_location *richloc)
{
/* Run the diagnostic and fix-it printing code. */
- test_diagnostic_context dc;
- diagnostic_show_locus (&dc, dc.m_source_printing,
- richloc, DK_ERROR, dc.get_reference_printer ());
+ diagnostics::selftest::test_context dc;
+ diagnostic_show_locus (&dc, dc.get_source_printing_options (),
+ richloc, diagnostics::kind::error,
+ dc.get_reference_printer ());
/* Generate a diff. */
- edit_context ec (global_dc->get_file_cache ());
- ec.add_fixits (richloc);
- char *diff = ec.generate_diff (true);
+ diagnostics::changes::change_set edit (global_dc->get_file_cache ());
+ edit.add_fixits (richloc);
+ char *diff = edit.generate_diff (true);
free (diff);
}
diff --git a/gcc/testsuite/gcc.dg/plugin/infoleak-net-ethtool-ioctl.c b/gcc/testsuite/gcc.dg/plugin/infoleak-net-ethtool-ioctl.c
index 52846c4..afb4a57 100644
--- a/gcc/testsuite/gcc.dg/plugin/infoleak-net-ethtool-ioctl.c
+++ b/gcc/testsuite/gcc.dg/plugin/infoleak-net-ethtool-ioctl.c
@@ -11,8 +11,7 @@ typedef unsigned int __u32;
typedef __s8 s8;
typedef __u32 u32;
enum { false = 0, true = 1 };
-typedef unsigned long __kernel_ulong_t;
-typedef __kernel_ulong_t __kernel_size_t;
+typedef __SIZE_TYPE__ __kernel_size_t;
typedef _Bool bool;
typedef __kernel_size_t size_t;
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..00ad870 100644
--- a/gcc/testsuite/gcc.dg/plugin/location_overflow_plugin.cc
+++ b/gcc/testsuite/gcc.dg/plugin/location_overflow_plugin.cc
@@ -7,7 +7,7 @@
#include "coretypes.h"
#include "spellcheck.h"
#include "diagnostic.h"
-#include "diagnostic-format-text.h"
+#include "diagnostics/text-sink.h"
int plugin_is_GPL_compatible;
@@ -39,12 +39,12 @@ on_pragma_registration (void */*gcc_data*/, void */*user_data*/)
/* We add some extra testing during diagnostics by chaining up
to the text finalizer. */
-static diagnostic_text_finalizer_fn original_text_finalizer = NULL;
+static diagnostics::text_finalizer_fn original_text_finalizer = NULL;
static void
-verify_unpacked_ranges (diagnostic_text_output_format &text_output,
- const diagnostic_info *diagnostic,
- diagnostic_t orig_diag_kind)
+verify_unpacked_ranges (diagnostics::text_sink &text_output,
+ const diagnostics::diagnostic_info *diagnostic,
+ enum diagnostics::kind orig_diag_kind)
{
/* Verify that the locations are ad-hoc, not packed. */
location_t loc = diagnostic_location (diagnostic);
@@ -56,9 +56,9 @@ verify_unpacked_ranges (diagnostic_text_output_format &text_output,
}
static void
-verify_no_columns (diagnostic_text_output_format &text_output,
- const diagnostic_info *diagnostic,
- diagnostic_t orig_diag_kind)
+verify_no_columns (diagnostics::text_sink &text_output,
+ const diagnostics::diagnostic_info *diagnostic,
+ enum diagnostics::kind orig_diag_kind)
{
/* Verify that the locations have no columns. */
location_t loc = diagnostic_location (diagnostic);
@@ -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,
@@ -95,19 +104,19 @@ plugin_init (struct plugin_name_args *plugin_info,
NULL); /* void *user_data */
/* Hack in additional testing, based on the exact value supplied. */
- original_text_finalizer = diagnostic_text_finalizer (global_dc);
+ original_text_finalizer = diagnostics::text_finalizer (global_dc);
switch (base_location)
{
case LINE_MAP_MAX_LOCATION_WITH_PACKED_RANGES + 1:
- diagnostic_text_finalizer (global_dc) = verify_unpacked_ranges;
+ diagnostics::text_finalizer (global_dc) = verify_unpacked_ranges;
break;
case LINE_MAP_MAX_LOCATION_WITH_COLS + 1:
- diagnostic_text_finalizer (global_dc) = verify_no_columns;
+ diagnostics::text_finalizer (global_dc) = verify_no_columns;
break;
default:
- error_at (UNKNOWN_LOCATION, "unrecognized value for plugin argument");
+ break;
}
return 0;
diff --git a/gcc/testsuite/gcc.dg/plugin/must-tail-call-2.c b/gcc/testsuite/gcc.dg/plugin/must-tail-call-2.c
index d51d15c..6f65f4a 100644
--- a/gcc/testsuite/gcc.dg/plugin/must-tail-call-2.c
+++ b/gcc/testsuite/gcc.dg/plugin/must-tail-call-2.c
@@ -55,5 +55,5 @@ volatile fn_ptr_t fn_ptr;
void
test_5 (void)
{
- fn_ptr (); /* { dg-error "cannot tail-call: " } */
+ fn_ptr ();
}
diff --git a/gcc/testsuite/gcc.dg/plugin/plugin.exp b/gcc/testsuite/gcc.dg/plugin/plugin.exp
index 90c9162..c7cc36c 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,17 +105,24 @@ 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_graphs.cc
+ diagnostic-test-graphs.c \
+ diagnostic-test-graphs-html.c \
+ diagnostic-test-graphs-sarif.c } \
{ diagnostic_plugin_test_nesting.cc \
+ diagnostic-test-nesting-show-nesting.c \
+ diagnostic-test-nesting-no-show-nesting.c \
diagnostic-test-nesting-text-plain.c \
diagnostic-test-nesting-text-indented.c \
diagnostic-test-nesting-text-indented-show-levels.c \
diagnostic-test-nesting-text-indented-unicode.c \
+ diagnostic-test-nesting-html.c \
diagnostic-test-nesting-sarif.c } \
{ 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 +143,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 } \