https://gcc.gnu.org/g:4b4023d52986b20369a0bdc9366d82c2b2f1efc7
commit r15-6118-g4b4023d52986b20369a0bdc9366d82c2b2f1efc7 Author: David Malcolm <dmalc...@redhat.com> Date: Wed Dec 11 10:32:14 2024 -0500 c++: tweak colorization of incompatible declspecs Introduce a helper function for complaining about "signed unsigned" and "short long". Add colorization there so that e.g. the 'signed' and 'unsigned' are given consistent contrasting colors in both the message and the quoted source. gcc/cp/ChangeLog: * decl.cc: Add #include "diagnostic-highlight-colors.h" and #include "pretty-print-markup.h". (complain_about_incompatible_declspecs): New. (grokdeclarator): Use it when complaining about both 'signed' and 'unsigned', and both 'long' and 'short'. gcc/ChangeLog: * diagnostic-highlight-colors.h: Tweak comment. * pretty-print-markup.h (class pp_element_quoted_string): New, based on pretty-print.cc's selftest::test_element, adding an optional highlight color. * pretty-print.cc (class test_element): Drop. (selftest::test_pp_format): Use pp_element_quoted_string. (selftest::test_urlification): Likewise. gcc/testsuite/ChangeLog: * g++.dg/diagnostic/long-short-colorization.C: New test. Signed-off-by: David Malcolm <dmalc...@redhat.com> Diff: --- gcc/cp/decl.cc | 36 +++++++++++++++------- gcc/diagnostic-highlight-colors.h | 3 +- gcc/pretty-print-markup.h | 25 +++++++++++++++ gcc/pretty-print.cc | 22 ++----------- .../g++.dg/diagnostic/long-short-colorization.C | 20 ++++++++++++ 5 files changed, 75 insertions(+), 31 deletions(-) diff --git a/gcc/cp/decl.cc b/gcc/cp/decl.cc index 2b56e15eb1a6..4ba6e3784cac 100644 --- a/gcc/cp/decl.cc +++ b/gcc/cp/decl.cc @@ -61,6 +61,8 @@ along with GCC; see the file COPYING3. If not see #include "langhooks-def.h" /* For lhd_simulate_record_decl */ #include "coroutines.h" #include "gcc-urlifier.h" +#include "diagnostic-highlight-colors.h" +#include "pretty-print-markup.h" /* Possible cases of bad specifiers type used by bad_specifiers. */ enum bad_spec_place { @@ -12437,6 +12439,23 @@ check_decltype_auto (location_t loc, tree type) return false; } +/* Issue an error about two mutually incompatible declspecs + with the given names and locations + e.g. "error: `signed' and `unsigned' specified together" */ + +static void +complain_about_incompatible_declspecs (const char *name_a, location_t loc_a, + const char *name_b, location_t loc_b) +{ + gcc_rich_location richloc (loc_a, nullptr, highlight_colors::lhs); + richloc.add_range (loc_b, SHOW_RANGE_WITHOUT_CARET, + nullptr, highlight_colors::rhs); + pp_element_quoted_string e_name_a (name_a, highlight_colors::lhs); + pp_element_quoted_string e_name_b (name_b, highlight_colors::rhs); + error_at (&richloc, "%e and %e specified together", + &e_name_a, &e_name_b); +} + /* Given declspecs and a declarator (abstract or otherwise), determine the name and type of the object declared and construct a DECL node for it. @@ -13070,18 +13089,13 @@ grokdeclarator (const cp_declarator *declarator, int ok = 0; if (signed_p && unsigned_p) - { - gcc_rich_location richloc (declspecs->locations[ds_signed]); - richloc.add_range (declspecs->locations[ds_unsigned]); - error_at (&richloc, - "%<signed%> and %<unsigned%> specified together"); - } + complain_about_incompatible_declspecs + ("signed", declspecs->locations[ds_signed], + "unsigned", declspecs->locations[ds_unsigned]); else if (long_p && short_p) - { - gcc_rich_location richloc (declspecs->locations[ds_long]); - richloc.add_range (declspecs->locations[ds_short]); - error_at (&richloc, "%<long%> and %<short%> specified together"); - } + complain_about_incompatible_declspecs + ("long", declspecs->locations[ds_long], + "short", declspecs->locations[ds_short]); else if (TREE_CODE (type) != INTEGER_TYPE || type == char8_type_node || type == char16_type_node diff --git a/gcc/diagnostic-highlight-colors.h b/gcc/diagnostic-highlight-colors.h index 66acfc8e8145..72e3ade358dc 100644 --- a/gcc/diagnostic-highlight-colors.h +++ b/gcc/diagnostic-highlight-colors.h @@ -47,7 +47,8 @@ namespace highlight_colors { extern const char *const expected; extern const char *const actual; -/* Color names for expressing "LHS" vs "RHS" values in a binary operation. */ +/* Color names for expressing "LHS" vs "RHS" values in a binary operation + or when we are listing two different things. */ extern const char *const lhs; extern const char *const rhs; diff --git a/gcc/pretty-print-markup.h b/gcc/pretty-print-markup.h index 8e6897ce25ff..0de04c7fee55 100644 --- a/gcc/pretty-print-markup.h +++ b/gcc/pretty-print-markup.h @@ -89,4 +89,29 @@ private: } // namespace pp_markup +class pp_element_quoted_string : public pp_element +{ +public: + pp_element_quoted_string (const char *text, + const char *highlight_color = nullptr) + : m_text (text), + m_highlight_color (highlight_color) + {} + + void add_to_phase_2 (pp_markup::context &ctxt) final override + { + ctxt.begin_quote (); + if (m_highlight_color) + ctxt.begin_highlight_color (m_highlight_color); + pp_string (&ctxt.m_pp, m_text); + if (m_highlight_color) + ctxt.end_highlight_color (); + ctxt.end_quote (); + } + +private: + const char *m_text; + const char *m_highlight_color; +}; + #endif /* GCC_PRETTY_PRINT_MARKUP_H */ diff --git a/gcc/pretty-print.cc b/gcc/pretty-print.cc index 0482ca189b70..2439d2f27b32 100644 --- a/gcc/pretty-print.cc +++ b/gcc/pretty-print.cc @@ -3314,22 +3314,6 @@ assert_pp_format_colored (const location &loc, const char *expected, (ARG1), (ARG2), (ARG3)); \ SELFTEST_END_STMT -class test_element : public pp_element -{ -public: - test_element (const char *text) : m_text (text) {} - - void add_to_phase_2 (pp_markup::context &ctxt) final override - { - ctxt.begin_quote (); - pp_string (&ctxt.m_pp, m_text); - ctxt.end_quote (); - } - -private: - const char *m_text; -}; - /* Verify that pp_format works, for various format codes. */ static void @@ -3444,8 +3428,8 @@ test_pp_format () /* Verify %e. */ { - test_element foo ("foo"); - test_element bar ("bar"); + pp_element_quoted_string foo ("foo"); + pp_element_quoted_string bar ("bar"); ASSERT_PP_FORMAT_2 ("before `foo' `bar' after", "before %e %e after", &foo, &bar); @@ -4204,7 +4188,7 @@ test_urlification () { pretty_printer pp; pp.set_url_format (URL_FORMAT_ST); - test_element elem ("-foption"); + pp_element_quoted_string elem ("-foption"); pp_printf_with_urlifier (&pp, &urlifier, "foo %e bar", &elem); diff --git a/gcc/testsuite/g++.dg/diagnostic/long-short-colorization.C b/gcc/testsuite/g++.dg/diagnostic/long-short-colorization.C new file mode 100644 index 000000000000..d2111fee1d21 --- /dev/null +++ b/gcc/testsuite/g++.dg/diagnostic/long-short-colorization.C @@ -0,0 +1,20 @@ +// Verify colorization of printing of declspec mismatches +// Use dg-*-multiline-output to avoid regexp interpretation. + +// { dg-options "-fdiagnostics-color=always -fdiagnostics-show-caret" } + +long short int a; +/* { dg-begin-multiline-output "" } +[m[K'[01m[K[01;32m[Klong[m[K[m[K' and '[01m[K[01;34m[Kshort[m[K[m[K' specified together + [01;32m[Kl[m[K[01;32m[Ko[m[K[01;32m[Kn[m[K[01;32m[Kg[m[K [01;34m[Ks[m[K[01;34m[Kh[m[K[01;34m[Ko[m[K[01;34m[Kr[m[K[01;34m[Kt[m[K int a; + [01;32m[K^[m[K[01;32m[K~[m[K[01;32m[K~[m[K[01;32m[K~[m[K [01;34m[K~[m[K[01;34m[K~[m[K[01;34m[K~[m[K[01;34m[K~[m[K[01;34m[K~[m[K + { dg-end-multiline-output "" } */ +short long int b; +/* { dg-begin-multiline-output "" } +[m[K'[01m[K[01;32m[Klong[m[K[m[K' and '[01m[K[01;34m[Kshort[m[K[m[K' specified together + [01;34m[Ks[m[K[01;34m[Kh[m[K[01;34m[Ko[m[K[01;34m[Kr[m[K[01;34m[Kt[m[K [01;32m[Kl[m[K[01;32m[Ko[m[K[01;32m[Kn[m[K[01;32m[Kg[m[K int b; + [01;34m[K~[m[K[01;34m[K~[m[K[01;34m[K~[m[K[01;34m[K~[m[K[01;34m[K~[m[K [01;32m[K^[m[K[01;32m[K~[m[K[01;32m[K~[m[K[01;32m[K~[m[K + { dg-end-multiline-output "" } */ + +// Discard the remaining colorized output that confuses dejagnu. +// { dg-prune-output diagnostic/long-short-colorization.C }