diff options
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/testsuite/gcc.dg/analyzer/out-of-bounds-diagram-1-emoji.c | 26 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/analyzer/out-of-bounds-diagram-1-unicode.c | 26 | ||||
-rw-r--r-- | gcc/text-art/theme.cc | 30 | ||||
-rw-r--r-- | gcc/text-art/theme.h | 10 | ||||
-rw-r--r-- | gcc/tree-diagnostic-path.cc | 381 |
5 files changed, 331 insertions, 142 deletions
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 7b4ecf0..8d22e41 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 @@ -18,19 +18,19 @@ void int_arr_write_element_after_end_off_by_one(int32_t x) arr[10] = x; ~~~~~~~~^~~ event 1 (depth 0) - | - | int32_t arr[10]; - | ^~~ - | | - | (1) capacity: 40 bytes - | - +--> 'int_arr_write_element_after_end_off_by_one': event 2 (depth 1) - | - | arr[10] = x; - | ~~~~~~~~^~~ - | | - | (2) ⚠️ out-of-bounds write from byte 40 till byte 43 but 'arr' ends at byte 40 - | + │ + │ int32_t arr[10]; + │ ^~~ + │ | + │ (1) capacity: 40 bytes + │ + └──> 'int_arr_write_element_after_end_off_by_one': event 2 (depth 1) + │ + │ arr[10] = x; + │ ~~~~~~~~^~~ + │ | + │ (2) ⚠️ out-of-bounds write from byte 40 till byte 43 but 'arr' ends at byte 40 + │ { dg-end-multiline-output "" } */ /* { dg-begin-multiline-output "" } diff --git a/gcc/testsuite/gcc.dg/analyzer/out-of-bounds-diagram-1-unicode.c b/gcc/testsuite/gcc.dg/analyzer/out-of-bounds-diagram-1-unicode.c index 71f66ff..58c4a7b 100644 --- a/gcc/testsuite/gcc.dg/analyzer/out-of-bounds-diagram-1-unicode.c +++ b/gcc/testsuite/gcc.dg/analyzer/out-of-bounds-diagram-1-unicode.c @@ -18,19 +18,19 @@ void int_arr_write_element_after_end_off_by_one(int32_t x) arr[10] = x; ~~~~~~~~^~~ event 1 (depth 0) - | - | int32_t arr[10]; - | ^~~ - | | - | (1) capacity: 40 bytes - | - +--> 'int_arr_write_element_after_end_off_by_one': event 2 (depth 1) - | - | arr[10] = x; - | ~~~~~~~~^~~ - | | - | (2) out-of-bounds write from byte 40 till byte 43 but 'arr' ends at byte 40 - | + │ + │ int32_t arr[10]; + │ ^~~ + │ | + │ (1) capacity: 40 bytes + │ + └──> 'int_arr_write_element_after_end_off_by_one': event 2 (depth 1) + │ + │ arr[10] = x; + │ ~~~~~~~~^~~ + │ | + │ (2) out-of-bounds write from byte 40 till byte 43 but 'arr' ends at byte 40 + │ { dg-end-multiline-output "" } */ /* { dg-begin-multiline-output "" } diff --git a/gcc/text-art/theme.cc b/gcc/text-art/theme.cc index 4ac0cae..cba4c58 100644 --- a/gcc/text-art/theme.cc +++ b/gcc/text-art/theme.cc @@ -125,6 +125,21 @@ ascii_theme::get_cppchar (enum cell_kind kind) const case cell_kind::Y_ARROW_UP_TAIL: case cell_kind::Y_ARROW_DOWN_TAIL: return '|'; + + case cell_kind::INTERPROCEDURAL_PUSH_FRAME_LEFT: + return '+'; + case cell_kind::INTERPROCEDURAL_PUSH_FRAME_MIDDLE: + return '-'; + case cell_kind::INTERPROCEDURAL_PUSH_FRAME_RIGHT: + return '>'; + case cell_kind::INTERPROCEDURAL_DEPTH_MARKER: + return '|'; + case cell_kind::INTERPROCEDURAL_POP_FRAMES_LEFT: + return '<'; + case cell_kind::INTERPROCEDURAL_POP_FRAMES_MIDDLE: + return '-'; + case cell_kind::INTERPROCEDURAL_POP_FRAMES_RIGHT: + return '+'; } } @@ -180,5 +195,20 @@ unicode_theme::get_cppchar (enum cell_kind kind) const case cell_kind::Y_ARROW_UP_TAIL: case cell_kind::Y_ARROW_DOWN_TAIL: return 0x2502; /* "│": U+2502: BOX DRAWINGS LIGHT VERTICAL */ + + case cell_kind::INTERPROCEDURAL_PUSH_FRAME_LEFT: + return 0x2514; /* "└": U+2514: BOX DRAWINGS LIGHT UP AND RIGHT */ + case cell_kind::INTERPROCEDURAL_PUSH_FRAME_MIDDLE: + return 0x2500; /* "─": U+2500: BOX DRAWINGS LIGHT HORIZONTAL */ + case cell_kind::INTERPROCEDURAL_PUSH_FRAME_RIGHT: + return '>'; + case cell_kind::INTERPROCEDURAL_DEPTH_MARKER: + return 0x2502; /* "│": U+2502: BOX DRAWINGS LIGHT VERTICAL */ + case cell_kind::INTERPROCEDURAL_POP_FRAMES_LEFT: + return '<'; + case cell_kind::INTERPROCEDURAL_POP_FRAMES_MIDDLE: + return 0x2500; /* "─": U+2500: BOX DRAWINGS LIGHT HORIZONTAL */ + case cell_kind::INTERPROCEDURAL_POP_FRAMES_RIGHT: + return 0x2518; /* "┘": U+2518: BOX DRAWINGS LIGHT UP AND LEFT. */ } } diff --git a/gcc/text-art/theme.h b/gcc/text-art/theme.h index 62845ac..dd50f5a 100644 --- a/gcc/text-art/theme.h +++ b/gcc/text-art/theme.h @@ -63,6 +63,16 @@ class theme Y_ARROW_UP_TAIL, Y_ARROW_DOWN_HEAD, Y_ARROW_DOWN_TAIL, + + /* The interprocedural depth indications shown in execution paths + with DPF_INLINE_EVENTS. */ + INTERPROCEDURAL_PUSH_FRAME_LEFT, /* e.g. "+". */ + INTERPROCEDURAL_PUSH_FRAME_MIDDLE, /* e.g. "-". */ + INTERPROCEDURAL_PUSH_FRAME_RIGHT, /* e.g. ">". */ + INTERPROCEDURAL_DEPTH_MARKER, /* e.g. "|". */ + INTERPROCEDURAL_POP_FRAMES_LEFT, /* e.g. "<". */ + INTERPROCEDURAL_POP_FRAMES_MIDDLE, /* e.g. "-". */ + INTERPROCEDURAL_POP_FRAMES_RIGHT /* e.g. "+". */ }; virtual ~theme () = default; diff --git a/gcc/tree-diagnostic-path.cc b/gcc/tree-diagnostic-path.cc index bc90aaf..9ae5191 100644 --- a/gcc/tree-diagnostic-path.cc +++ b/gcc/tree-diagnostic-path.cc @@ -437,6 +437,15 @@ public: = colorize_start (pp_show_color (pp), line_color); const char *end_line_color = colorize_stop (pp_show_color (pp)); + text_art::ascii_theme fallback_theme; + text_art::theme *theme = dc->get_diagram_theme (); + if (!theme) + theme = &fallback_theme; + + cppchar_t depth_marker_char = theme->get_cppchar + (text_art::theme::cell_kind::INTERPROCEDURAL_DEPTH_MARKER); + /* e.g. "|". */ + const bool interprocedural_p = m_per_thread_summary.interprocedural_p (); write_indent (pp, m_cur_indent); @@ -446,11 +455,21 @@ public: { gcc_assert (interprocedural_p); /* Show pushed stack frame(s). */ - const char *push_prefix = "+--> "; + cppchar_t left = theme->get_cppchar + (text_art::theme::cell_kind::INTERPROCEDURAL_PUSH_FRAME_LEFT); + cppchar_t middle = theme->get_cppchar + (text_art::theme::cell_kind::INTERPROCEDURAL_PUSH_FRAME_MIDDLE); + cppchar_t right = theme->get_cppchar + (text_art::theme::cell_kind::INTERPROCEDURAL_PUSH_FRAME_RIGHT); + /* e.g. "+--> ". */ pp_string (pp, start_line_color); - pp_string (pp, push_prefix); + pp_unicode_character (pp, left); + pp_unicode_character (pp, middle); + pp_unicode_character (pp, middle); + pp_unicode_character (pp, right); + pp_space (pp); pp_string (pp, end_line_color); - m_cur_indent += strlen (push_prefix); + m_cur_indent += 5; } } if (range->m_fndecl) @@ -473,7 +492,7 @@ public: { write_indent (pp, m_cur_indent + per_frame_indent); pp_string (pp, start_line_color); - pp_string (pp, "|"); + pp_unicode_character (pp, depth_marker_char); pp_string (pp, end_line_color); pp_newline (pp); @@ -483,7 +502,7 @@ public: pretty_printer tmp_pp; write_indent (&tmp_pp, m_cur_indent + per_frame_indent); pp_string (&tmp_pp, start_line_color); - pp_string (&tmp_pp, "|"); + pp_unicode_character (&tmp_pp, depth_marker_char); pp_string (&tmp_pp, end_line_color); prefix = xstrdup (pp_formatted_text (&tmp_pp)); } @@ -494,7 +513,7 @@ public: write_indent (pp, m_cur_indent + per_frame_indent); pp_string (pp, start_line_color); - pp_string (pp, "|"); + pp_unicode_character (pp, depth_marker_char); pp_string (pp, end_line_color); pp_newline (pp); } @@ -510,9 +529,15 @@ public: /* Show returning from stack frame(s), by printing something like: " |\n" - " <------------ +\n" + " <-------------+\n" " |\n". */ gcc_assert (interprocedural_p); + cppchar_t left = theme->get_cppchar + (text_art::theme::cell_kind::INTERPROCEDURAL_POP_FRAMES_LEFT); + cppchar_t middle = theme->get_cppchar + (text_art::theme::cell_kind::INTERPROCEDURAL_POP_FRAMES_MIDDLE); + cppchar_t right = theme->get_cppchar + (text_art::theme::cell_kind::INTERPROCEDURAL_POP_FRAMES_RIGHT); int vbar_for_next_frame = *m_vbar_column_for_depth.get (next_range->m_stack_depth); @@ -520,18 +545,18 @@ public: = vbar_for_next_frame - per_frame_indent; write_indent (pp, vbar_for_next_frame); pp_string (pp, start_line_color); - pp_character (pp, '<'); + pp_unicode_character (pp, left); for (int i = indent_for_next_frame + per_frame_indent; i < m_cur_indent + per_frame_indent - 1; i++) - pp_character (pp, '-'); - pp_character (pp, '+'); + pp_unicode_character (pp, middle); + pp_unicode_character (pp, right); pp_string (pp, end_line_color); pp_newline (pp); m_cur_indent = indent_for_next_frame; write_indent (pp, vbar_for_next_frame); pp_string (pp, start_line_color); - pp_character (pp, '|'); + pp_unicode_character (pp, depth_marker_char); pp_string (pp, end_line_color); pp_newline (pp); } @@ -864,59 +889,119 @@ test_interprocedural_path_1 (pretty_printer *event_pp) path_summary summary (path, false); ASSERT_EQ (summary.get_num_ranges (), 9); - test_diagnostic_context dc; - print_path_summary_as_text (&summary, &dc, true); - ASSERT_STREQ - (" `test': events 1-2 (depth 0)\n" - " |\n" - " | (1): entering `test'\n" - " | (2): calling `make_boxed_int'\n" - " |\n" - " +--> `make_boxed_int': events 3-4 (depth 1)\n" - " |\n" - " | (3): entering `make_boxed_int'\n" - " | (4): calling `wrapped_malloc'\n" - " |\n" - " +--> `wrapped_malloc': events 5-6 (depth 2)\n" - " |\n" - " | (5): entering `wrapped_malloc'\n" - " | (6): calling malloc\n" - " |\n" - " <-------------+\n" - " |\n" - " `test': events 7-8 (depth 0)\n" - " |\n" - " | (7): returning to `test'\n" - " | (8): calling `free_boxed_int'\n" - " |\n" - " +--> `free_boxed_int': events 9-10 (depth 1)\n" - " |\n" - " | (9): entering `free_boxed_int'\n" - " | (10): calling `wrapped_free'\n" - " |\n" - " +--> `wrapped_free': events 11-12 (depth 2)\n" - " |\n" - " | (11): entering `wrapped_free'\n" - " | (12): calling free\n" - " |\n" - " <-------------+\n" - " |\n" - " `test': events 13-14 (depth 0)\n" - " |\n" - " | (13): returning to `test'\n" - " | (14): calling `free_boxed_int'\n" - " |\n" - " +--> `free_boxed_int': events 15-16 (depth 1)\n" - " |\n" - " | (15): entering `free_boxed_int'\n" - " | (16): calling `wrapped_free'\n" - " |\n" - " +--> `wrapped_free': events 17-18 (depth 2)\n" - " |\n" - " | (17): entering `wrapped_free'\n" - " | (18): calling free\n" - " |\n", - pp_formatted_text (dc.printer)); + { + test_diagnostic_context dc; + dc.set_text_art_charset (DIAGNOSTICS_TEXT_ART_CHARSET_ASCII); + print_path_summary_as_text (&summary, &dc, true); + ASSERT_STREQ + (" `test': events 1-2 (depth 0)\n" + " |\n" + " | (1): entering `test'\n" + " | (2): calling `make_boxed_int'\n" + " |\n" + " +--> `make_boxed_int': events 3-4 (depth 1)\n" + " |\n" + " | (3): entering `make_boxed_int'\n" + " | (4): calling `wrapped_malloc'\n" + " |\n" + " +--> `wrapped_malloc': events 5-6 (depth 2)\n" + " |\n" + " | (5): entering `wrapped_malloc'\n" + " | (6): calling malloc\n" + " |\n" + " <-------------+\n" + " |\n" + " `test': events 7-8 (depth 0)\n" + " |\n" + " | (7): returning to `test'\n" + " | (8): calling `free_boxed_int'\n" + " |\n" + " +--> `free_boxed_int': events 9-10 (depth 1)\n" + " |\n" + " | (9): entering `free_boxed_int'\n" + " | (10): calling `wrapped_free'\n" + " |\n" + " +--> `wrapped_free': events 11-12 (depth 2)\n" + " |\n" + " | (11): entering `wrapped_free'\n" + " | (12): calling free\n" + " |\n" + " <-------------+\n" + " |\n" + " `test': events 13-14 (depth 0)\n" + " |\n" + " | (13): returning to `test'\n" + " | (14): calling `free_boxed_int'\n" + " |\n" + " +--> `free_boxed_int': events 15-16 (depth 1)\n" + " |\n" + " | (15): entering `free_boxed_int'\n" + " | (16): calling `wrapped_free'\n" + " |\n" + " +--> `wrapped_free': events 17-18 (depth 2)\n" + " |\n" + " | (17): entering `wrapped_free'\n" + " | (18): calling free\n" + " |\n", + pp_formatted_text (dc.printer)); + } + { + test_diagnostic_context dc; + dc.set_text_art_charset (DIAGNOSTICS_TEXT_ART_CHARSET_UNICODE); + print_path_summary_as_text (&summary, &dc, true); + ASSERT_STREQ + (" `test': events 1-2 (depth 0)\n" + " │\n" + " │ (1): entering `test'\n" + " │ (2): calling `make_boxed_int'\n" + " │\n" + " └──> `make_boxed_int': events 3-4 (depth 1)\n" + " │\n" + " │ (3): entering `make_boxed_int'\n" + " │ (4): calling `wrapped_malloc'\n" + " │\n" + " └──> `wrapped_malloc': events 5-6 (depth 2)\n" + " │\n" + " │ (5): entering `wrapped_malloc'\n" + " │ (6): calling malloc\n" + " │\n" + " <─────────────┘\n" + " │\n" + " `test': events 7-8 (depth 0)\n" + " │\n" + " │ (7): returning to `test'\n" + " │ (8): calling `free_boxed_int'\n" + " │\n" + " └──> `free_boxed_int': events 9-10 (depth 1)\n" + " │\n" + " │ (9): entering `free_boxed_int'\n" + " │ (10): calling `wrapped_free'\n" + " │\n" + " └──> `wrapped_free': events 11-12 (depth 2)\n" + " │\n" + " │ (11): entering `wrapped_free'\n" + " │ (12): calling free\n" + " │\n" + " <─────────────┘\n" + " │\n" + " `test': events 13-14 (depth 0)\n" + " │\n" + " │ (13): returning to `test'\n" + " │ (14): calling `free_boxed_int'\n" + " │\n" + " └──> `free_boxed_int': events 15-16 (depth 1)\n" + " │\n" + " │ (15): entering `free_boxed_int'\n" + " │ (16): calling `wrapped_free'\n" + " │\n" + " └──> `wrapped_free': events 17-18 (depth 2)\n" + " │\n" + " │ (17): entering `wrapped_free'\n" + " │ (18): calling free\n" + " │\n", + pp_formatted_text (dc.printer)); + } + } /* Example where we pop the stack to an intermediate frame, rather than the @@ -946,35 +1031,70 @@ test_interprocedural_path_2 (pretty_printer *event_pp) path_summary summary (path, false); ASSERT_EQ (summary.get_num_ranges (), 5); - test_diagnostic_context dc; - print_path_summary_as_text (&summary, &dc, true); - ASSERT_STREQ - (" `foo': events 1-2 (depth 0)\n" - " |\n" - " | (1): entering `foo'\n" - " | (2): calling `bar'\n" - " |\n" - " +--> `bar': events 3-4 (depth 1)\n" - " |\n" - " | (3): entering `bar'\n" - " | (4): calling `baz'\n" - " |\n" - " +--> `baz': event 5 (depth 2)\n" - " |\n" - " | (5): entering `baz'\n" - " |\n" - " <------+\n" - " |\n" - " `bar': events 6-7 (depth 1)\n" - " |\n" - " | (6): returning to `bar'\n" - " | (7): calling `baz'\n" - " |\n" - " +--> `baz': event 8 (depth 2)\n" - " |\n" - " | (8): entering `baz'\n" - " |\n", - pp_formatted_text (dc.printer)); + { + test_diagnostic_context dc; + dc.set_text_art_charset (DIAGNOSTICS_TEXT_ART_CHARSET_ASCII); + print_path_summary_as_text (&summary, &dc, true); + ASSERT_STREQ + (" `foo': events 1-2 (depth 0)\n" + " |\n" + " | (1): entering `foo'\n" + " | (2): calling `bar'\n" + " |\n" + " +--> `bar': events 3-4 (depth 1)\n" + " |\n" + " | (3): entering `bar'\n" + " | (4): calling `baz'\n" + " |\n" + " +--> `baz': event 5 (depth 2)\n" + " |\n" + " | (5): entering `baz'\n" + " |\n" + " <------+\n" + " |\n" + " `bar': events 6-7 (depth 1)\n" + " |\n" + " | (6): returning to `bar'\n" + " | (7): calling `baz'\n" + " |\n" + " +--> `baz': event 8 (depth 2)\n" + " |\n" + " | (8): entering `baz'\n" + " |\n", + pp_formatted_text (dc.printer)); + } + { + test_diagnostic_context dc; + dc.set_text_art_charset (DIAGNOSTICS_TEXT_ART_CHARSET_UNICODE); + print_path_summary_as_text (&summary, &dc, true); + ASSERT_STREQ + (" `foo': events 1-2 (depth 0)\n" + " │\n" + " │ (1): entering `foo'\n" + " │ (2): calling `bar'\n" + " │\n" + " └──> `bar': events 3-4 (depth 1)\n" + " │\n" + " │ (3): entering `bar'\n" + " │ (4): calling `baz'\n" + " │\n" + " └──> `baz': event 5 (depth 2)\n" + " │\n" + " │ (5): entering `baz'\n" + " │\n" + " <──────┘\n" + " │\n" + " `bar': events 6-7 (depth 1)\n" + " │\n" + " │ (6): returning to `bar'\n" + " │ (7): calling `baz'\n" + " │\n" + " └──> `baz': event 8 (depth 2)\n" + " │\n" + " │ (8): entering `baz'\n" + " │\n", + pp_formatted_text (dc.printer)); + } } /* Verify that print_path_summary is sane in the face of a recursive @@ -998,29 +1118,58 @@ test_recursion (pretty_printer *event_pp) path_summary summary (path, false); ASSERT_EQ (summary.get_num_ranges (), 4); - test_diagnostic_context dc; - print_path_summary_as_text (&summary, &dc, true); - ASSERT_STREQ - (" `factorial': events 1-2 (depth 0)\n" - " |\n" - " | (1): entering `factorial'\n" - " | (2): calling `factorial'\n" - " |\n" - " +--> `factorial': events 3-4 (depth 1)\n" - " |\n" - " | (3): entering `factorial'\n" - " | (4): calling `factorial'\n" - " |\n" - " +--> `factorial': events 5-6 (depth 2)\n" - " |\n" - " | (5): entering `factorial'\n" - " | (6): calling `factorial'\n" - " |\n" - " +--> `factorial': event 7 (depth 3)\n" - " |\n" - " | (7): entering `factorial'\n" - " |\n", - pp_formatted_text (dc.printer)); + { + test_diagnostic_context dc; + dc.set_text_art_charset (DIAGNOSTICS_TEXT_ART_CHARSET_ASCII); + print_path_summary_as_text (&summary, &dc, true); + ASSERT_STREQ + (" `factorial': events 1-2 (depth 0)\n" + " |\n" + " | (1): entering `factorial'\n" + " | (2): calling `factorial'\n" + " |\n" + " +--> `factorial': events 3-4 (depth 1)\n" + " |\n" + " | (3): entering `factorial'\n" + " | (4): calling `factorial'\n" + " |\n" + " +--> `factorial': events 5-6 (depth 2)\n" + " |\n" + " | (5): entering `factorial'\n" + " | (6): calling `factorial'\n" + " |\n" + " +--> `factorial': event 7 (depth 3)\n" + " |\n" + " | (7): entering `factorial'\n" + " |\n", + pp_formatted_text (dc.printer)); + } + { + test_diagnostic_context dc; + dc.set_text_art_charset (DIAGNOSTICS_TEXT_ART_CHARSET_UNICODE); + print_path_summary_as_text (&summary, &dc, true); + ASSERT_STREQ + (" `factorial': events 1-2 (depth 0)\n" + " │\n" + " │ (1): entering `factorial'\n" + " │ (2): calling `factorial'\n" + " │\n" + " └──> `factorial': events 3-4 (depth 1)\n" + " │\n" + " │ (3): entering `factorial'\n" + " │ (4): calling `factorial'\n" + " │\n" + " └──> `factorial': events 5-6 (depth 2)\n" + " │\n" + " │ (5): entering `factorial'\n" + " │ (6): calling `factorial'\n" + " │\n" + " └──> `factorial': event 7 (depth 3)\n" + " │\n" + " │ (7): entering `factorial'\n" + " │\n", + pp_formatted_text (dc.printer)); + } } /* Run all of the selftests within this file. */ |