Tweak the printing of -fdiagnostics-path-format=inline-events so that
any event with diagnostic_event::VERB_danger gains a warning emoji,
provided that the text art theme enables emoji support.

VERB_danger is set by the analyzer on the last event in a path, and so
this emoji appears at the end of all analyzer execution paths
highlighting the location of the problem.

Successfully bootstrapped & regrtested on x86_64-pc-linux-gnu.
Successful run of analyzer integration tests on x86_64-pc-linux-gnu.
Pushed to trunk as r15-534-g0b7ebe5427a4af.

gcc/testsuite/ChangeLog:
        * gcc.dg/analyzer/out-of-bounds-diagram-1-emoji.c: Update expected
        output to include warning emoji.
        * gcc.dg/analyzer/warning-emoji.c: New test.

gcc/ChangeLog:
        * tree-diagnostic-path.cc: Include "text-art/theme.h".
        (path_label::get_text): If the event has
        diagnostic_event::VERB_danger, and the theme enables emojis, then
        add a warning emoji between the event number and the event text.

Signed-off-by: David Malcolm <dmalc...@redhat.com>
---
 .../analyzer/out-of-bounds-diagram-1-emoji.c  |  2 +-
 gcc/testsuite/gcc.dg/analyzer/warning-emoji.c | 29 ++++++++++++++++++
 gcc/tree-diagnostic-path.cc                   | 30 +++++++++++++++++--
 3 files changed, 57 insertions(+), 4 deletions(-)
 create mode 100644 gcc/testsuite/gcc.dg/analyzer/warning-emoji.c

diff --git a/gcc/testsuite/gcc.dg/analyzer/out-of-bounds-diagram-1-emoji.c 
b/gcc/testsuite/gcc.dg/analyzer/out-of-bounds-diagram-1-emoji.c
index 1c6125225ff2..7b4ecf0d6b0c 100644
--- a/gcc/testsuite/gcc.dg/analyzer/out-of-bounds-diagram-1-emoji.c
+++ b/gcc/testsuite/gcc.dg/analyzer/out-of-bounds-diagram-1-emoji.c
@@ -29,7 +29,7 @@ void int_arr_write_element_after_end_off_by_one(int32_t x)
            |   arr[10] = x;
            |   ~~~~~~~~^~~
            |           |
-           |           (2) out-of-bounds write from byte 40 till byte 43 but 
'arr' ends at byte 40
+           |           (2) ⚠️  out-of-bounds write from byte 40 till byte 43 
but 'arr' ends at byte 40
            |
    { dg-end-multiline-output "" } */
 
diff --git a/gcc/testsuite/gcc.dg/analyzer/warning-emoji.c 
b/gcc/testsuite/gcc.dg/analyzer/warning-emoji.c
new file mode 100644
index 000000000000..47e5fb0acf90
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/analyzer/warning-emoji.c
@@ -0,0 +1,29 @@
+/* Verify that the final event in an analyzer path gets a "warning" emoji 
+   when -fdiagnostics-text-art-charset=emoji (and
+   -fdiagnostics-path-format=inline-events).  */
+
+/* { dg-additional-options "-fdiagnostics-show-line-numbers" } */
+/* { dg-additional-options "-fdiagnostics-show-caret" } */
+/* { dg-additional-options "-fdiagnostics-path-format=inline-events" } */
+/* { dg-additional-options "-fdiagnostics-text-art-charset=emoji" } */
+/* { dg-enable-nn-line-numbers "" } */
+
+void test (void *p)
+{
+  __builtin_free (p);
+  __builtin_free (p); /* { dg-warning "double-'free'" } */
+}
+
+/* { dg-begin-multiline-output "" }
+   NN |   __builtin_free (p);
+      |   ^~~~~~~~~~~~~~~~~~
+  'test': events 1-2
+   NN |   __builtin_free (p);
+      |   ^~~~~~~~~~~~~~~~~~
+      |   |
+      |   (1) first 'free' here
+   NN |   __builtin_free (p);
+      |   ~~~~~~~~~~~~~~~~~~
+      |   |
+      |   (2) ⚠️  second 'free' here; first 'free' was at (1)
+   { dg-end-multiline-output "" } */
diff --git a/gcc/tree-diagnostic-path.cc b/gcc/tree-diagnostic-path.cc
index 33389ef5d33e..bc90aaf321cc 100644
--- a/gcc/tree-diagnostic-path.cc
+++ b/gcc/tree-diagnostic-path.cc
@@ -36,6 +36,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "diagnostic-event-id.h"
 #include "selftest.h"
 #include "selftest-diagnostic.h"
+#include "text-art/theme.h"
 
 /* Anonymous namespace for path-printing code.  */
 
@@ -60,13 +61,36 @@ class path_label : public range_label
     /* Get the description of the event, perhaps with colorization:
        normally, we don't colorize within a range_label, but this
        is special-cased for diagnostic paths.  */
-    bool colorize = pp_show_color (global_dc->printer);
+    const bool colorize = pp_show_color (global_dc->printer);
     label_text event_text (event.get_desc (colorize));
     gcc_assert (event_text.get ());
+
+    const diagnostic_event::meaning meaning (event.get_meaning ());
+
     pretty_printer pp;
-    pp_show_color (&pp) = pp_show_color (global_dc->printer);
+    pp_show_color (&pp) = colorize;
     diagnostic_event_id_t event_id (event_idx);
-    pp_printf (&pp, "%@ %s", &event_id, event_text.get ());
+
+    pp_printf (&pp, "%@", &event_id);
+    pp_space (&pp);
+
+    if (meaning.m_verb == diagnostic_event::VERB_danger)
+      if (text_art::theme *theme = global_dc->get_diagram_theme ())
+       if (theme->emojis_p ())
+         {
+           pp_unicode_character (&pp, 0x26A0); /* U+26A0 WARNING SIGN.  */
+           /* Append U+FE0F VARIATION SELECTOR-16 to select the emoji
+              variation of the char.  */
+           pp_unicode_character (&pp, 0xFE0F);
+           /* U+26A0 WARNING SIGN has East_Asian_Width == Neutral, but in its
+              emoji variant is printed (by vte at least) with a 2nd half
+              overlapping the next char.  Hence we add two spaces here: a space
+              to be covered by this overlap, plus another space of padding.  */
+           pp_string (&pp, "  ");
+         }
+
+    pp_printf (&pp, "%s", event_text.get ());
+
     label_text result = label_text::take (xstrdup (pp_formatted_text (&pp)));
     return result;
   }
-- 
2.26.3

Reply via email to