File: | build/gcc/diagnostic-show-locus.cc |
Warning: | line 1778, column 7 Value stored to 'c' is never read |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
1 | /* Diagnostic subroutines for printing source-code |
2 | Copyright (C) 1999-2023 Free Software Foundation, Inc. |
3 | Contributed by Gabriel Dos Reis <gdr@codesourcery.com> |
4 | |
5 | This file is part of GCC. |
6 | |
7 | GCC is free software; you can redistribute it and/or modify it under |
8 | the terms of the GNU General Public License as published by the Free |
9 | Software Foundation; either version 3, or (at your option) any later |
10 | version. |
11 | |
12 | GCC is distributed in the hope that it will be useful, but WITHOUT ANY |
13 | WARRANTY; without even the implied warranty of MERCHANTABILITY or |
14 | FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
15 | for more details. |
16 | |
17 | You should have received a copy of the GNU General Public License |
18 | along with GCC; see the file COPYING3. If not see |
19 | <http://www.gnu.org/licenses/>. */ |
20 | |
21 | #include "config.h" |
22 | #include "system.h" |
23 | #include "coretypes.h" |
24 | #include "version.h" |
25 | #include "demangle.h" |
26 | #include "intl.h" |
27 | #include "backtrace.h" |
28 | #include "diagnostic.h" |
29 | #include "diagnostic-color.h" |
30 | #include "gcc-rich-location.h" |
31 | #include "selftest.h" |
32 | #include "selftest-diagnostic.h" |
33 | #include "cpplib.h" |
34 | |
35 | #ifdef HAVE_TERMIOS_H |
36 | # include <termios.h> |
37 | #endif |
38 | |
39 | #ifdef GWINSZ_IN_SYS_IOCTL1 |
40 | # include <sys/ioctl.h> |
41 | #endif |
42 | |
43 | /* Disable warnings about quoting issues in the pp_xxx calls below |
44 | that (intentionally) don't follow GCC diagnostic conventions. */ |
45 | #if __GNUC__4 >= 10 |
46 | # pragma GCC diagnostic push |
47 | # pragma GCC diagnostic ignored "-Wformat-diag" |
48 | #endif |
49 | |
50 | /* Classes for rendering source code and diagnostics, within an |
51 | anonymous namespace. |
52 | The work is done by "class layout", which embeds and uses |
53 | "class colorizer" and "class layout_range" to get things done. */ |
54 | |
55 | namespace { |
56 | |
57 | /* The state at a given point of the source code, assuming that we're |
58 | in a range: which range are we in, and whether we should draw a caret at |
59 | this point. */ |
60 | |
61 | struct point_state |
62 | { |
63 | int range_idx; |
64 | bool draw_caret_p; |
65 | }; |
66 | |
67 | /* A class to inject colorization codes when printing the diagnostic locus. |
68 | |
69 | It has one kind of colorization for each of: |
70 | - normal text |
71 | - range 0 (the "primary location") |
72 | - range 1 |
73 | - range 2 |
74 | |
75 | The class caches the lookup of the color codes for the above. |
76 | |
77 | The class also has responsibility for tracking which of the above is |
78 | active, filtering out unnecessary changes. This allows |
79 | layout::print_source_line and layout::print_annotation_line |
80 | to simply request a colorization code for *every* character they print, |
81 | via this class, and have the filtering be done for them here. */ |
82 | |
83 | class colorizer |
84 | { |
85 | public: |
86 | colorizer (diagnostic_context *context, |
87 | diagnostic_t diagnostic_kind); |
88 | ~colorizer (); |
89 | |
90 | void set_range (int range_idx) |
91 | { |
92 | /* Normally we emphasize the primary location, then alternate between |
93 | two colors for the secondary locations. |
94 | But if we're printing a run of events in a diagnostic path, that |
95 | makes no sense, so print all of them with the same colorization. */ |
96 | if (m_diagnostic_kind == DK_DIAGNOSTIC_PATH) |
97 | set_state (0); |
98 | else |
99 | set_state (range_idx); |
100 | } |
101 | void set_normal_text () { set_state (STATE_NORMAL_TEXT); } |
102 | void set_fixit_insert () { set_state (STATE_FIXIT_INSERT); } |
103 | void set_fixit_delete () { set_state (STATE_FIXIT_DELETE); } |
104 | |
105 | private: |
106 | void set_state (int state); |
107 | void begin_state (int state); |
108 | void finish_state (int state); |
109 | const char *get_color_by_name (const char *); |
110 | |
111 | private: |
112 | static const int STATE_NORMAL_TEXT = -1; |
113 | static const int STATE_FIXIT_INSERT = -2; |
114 | static const int STATE_FIXIT_DELETE = -3; |
115 | |
116 | diagnostic_context *m_context; |
117 | diagnostic_t m_diagnostic_kind; |
118 | int m_current_state; |
119 | const char *m_range1; |
120 | const char *m_range2; |
121 | const char *m_fixit_insert; |
122 | const char *m_fixit_delete; |
123 | const char *m_stop_color; |
124 | }; |
125 | |
126 | /* In order to handle multibyte sources properly, all of this logic needs to be |
127 | aware of the distinction between the number of bytes and the number of |
128 | display columns occupied by a character, which are not the same for non-ASCII |
129 | characters. For example, the Unicode pi symbol, U+03C0, is encoded in UTF-8 |
130 | as "\xcf\x80", and thus occupies 2 bytes of space while only occupying 1 |
131 | display column when it is output. A typical emoji, such as U+1F602 (in |
132 | UTF-8, "\xf0\x9f\x98\x82"), requires 4 bytes and has a display width of 2. |
133 | |
134 | The below example line, which is also used for selftests below, shows how the |
135 | display column and byte column are related: |
136 | |
137 | 0000000001111111111222222 display |
138 | 1234567890123456789012345 columns |
139 | SS_foo = P_bar.SS_fieldP; |
140 | 0000000111111111222222223 byte |
141 | 1356789012456789134567891 columns |
142 | |
143 | Here SS represents the two display columns for the U+1F602 emoji, and P |
144 | represents the one display column for the U+03C0 pi symbol. As an example, a |
145 | diagnostic pointing to the final P on this line is at byte column 29 and |
146 | display column 24. This reflects the fact that the three extended characters |
147 | before the final P occupy cumulatively 5 more bytes than they do display |
148 | columns (a difference of 2 for each of the two SSs, and one for the other P). |
149 | |
150 | One or the other of the two column units is more useful depending on the |
151 | context. For instance, in order to output the caret at the correct location, |
152 | we need to count display columns; in order to colorize a source line, we need |
153 | to count the bytes. All locations are provided to us as byte counts, which |
154 | we augment with the display column on demand so that it can be used when |
155 | needed. This is not the most efficient way to do things since it requires |
156 | looping over the whole line each time, but it should be fine for the purpose |
157 | of outputting diagnostics. |
158 | |
159 | In order to keep straight which units (byte or display) are in use at a |
160 | given time, the following enum lets us specify that explicitly. */ |
161 | |
162 | enum column_unit { |
163 | /* Measured in raw bytes. */ |
164 | CU_BYTES = 0, |
165 | |
166 | /* Measured in display units. */ |
167 | CU_DISPLAY_COLS, |
168 | |
169 | /* For arrays indexed by column_unit. */ |
170 | CU_NUM_UNITS |
171 | }; |
172 | |
173 | /* Utility class to augment an exploc with the corresponding display column. */ |
174 | |
175 | class exploc_with_display_col : public expanded_location |
176 | { |
177 | public: |
178 | exploc_with_display_col (const expanded_location &exploc, |
179 | const cpp_char_column_policy &policy, |
180 | enum location_aspect aspect) |
181 | : expanded_location (exploc), |
182 | m_display_col (location_compute_display_column (exploc, policy)) |
183 | { |
184 | if (exploc.column > 0) |
185 | { |
186 | /* m_display_col is now the final column of the byte. |
187 | If escaping has happened, we may want the first column instead. */ |
188 | if (aspect != LOCATION_ASPECT_FINISH) |
189 | { |
190 | expanded_location prev_exploc (exploc); |
191 | prev_exploc.column--; |
192 | int prev_display_col |
193 | = (location_compute_display_column (prev_exploc, policy)); |
194 | m_display_col = prev_display_col + 1; |
195 | } |
196 | } |
197 | } |
198 | |
199 | int m_display_col; |
200 | }; |
201 | |
202 | |
203 | /* A point within a layout_range; similar to an exploc_with_display_col, |
204 | but after filtering on file. */ |
205 | |
206 | class layout_point |
207 | { |
208 | public: |
209 | layout_point (const exploc_with_display_col &exploc) |
210 | : m_line (exploc.line) |
211 | { |
212 | m_columns[CU_BYTES] = exploc.column; |
213 | m_columns[CU_DISPLAY_COLS] = exploc.m_display_col; |
214 | } |
215 | |
216 | linenum_type m_line; |
217 | int m_columns[CU_NUM_UNITS]; |
218 | }; |
219 | |
220 | /* A class for use by "class layout" below: a filtered location_range. */ |
221 | |
222 | class layout_range |
223 | { |
224 | public: |
225 | layout_range (const exploc_with_display_col &start_exploc, |
226 | const exploc_with_display_col &finish_exploc, |
227 | enum range_display_kind range_display_kind, |
228 | const exploc_with_display_col &caret_exploc, |
229 | unsigned original_idx, |
230 | const range_label *label); |
231 | |
232 | bool contains_point (linenum_type row, int column, |
233 | enum column_unit col_unit) const; |
234 | bool intersects_line_p (linenum_type row) const; |
235 | |
236 | layout_point m_start; |
237 | layout_point m_finish; |
238 | enum range_display_kind m_range_display_kind; |
239 | layout_point m_caret; |
240 | unsigned m_original_idx; |
241 | const range_label *m_label; |
242 | }; |
243 | |
244 | /* A struct for use by layout::print_source_line for telling |
245 | layout::print_annotation_line the extents of the source line that |
246 | it printed, so that underlines can be clipped appropriately. Units |
247 | are 1-based display columns. */ |
248 | |
249 | struct line_bounds |
250 | { |
251 | int m_first_non_ws_disp_col; |
252 | int m_last_non_ws_disp_col; |
253 | |
254 | line_bounds () |
255 | { |
256 | m_first_non_ws_disp_col = INT_MAX2147483647; |
257 | m_last_non_ws_disp_col = 0; |
258 | } |
259 | }; |
260 | |
261 | /* A range of contiguous source lines within a layout (e.g. "lines 5-10" |
262 | or "line 23"). During the layout ctor, layout::calculate_line_spans |
263 | splits the pertinent source lines into a list of disjoint line_span |
264 | instances (e.g. lines 5-10, lines 15-20, line 23). */ |
265 | |
266 | class line_span |
267 | { |
268 | public: |
269 | line_span (linenum_type first_line, linenum_type last_line) |
270 | : m_first_line (first_line), m_last_line (last_line) |
271 | { |
272 | gcc_assert (first_line <= last_line)((void)(!(first_line <= last_line) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 272, __FUNCTION__), 0 : 0)); |
273 | } |
274 | linenum_type get_first_line () const { return m_first_line; } |
275 | linenum_type get_last_line () const { return m_last_line; } |
276 | |
277 | bool contains_line_p (linenum_type line) const |
278 | { |
279 | return line >= m_first_line && line <= m_last_line; |
280 | } |
281 | |
282 | static int comparator (const void *p1, const void *p2) |
283 | { |
284 | const line_span *ls1 = (const line_span *)p1; |
285 | const line_span *ls2 = (const line_span *)p2; |
286 | int first_line_cmp = compare (ls1->m_first_line, ls2->m_first_line); |
287 | if (first_line_cmp) |
288 | return first_line_cmp; |
289 | return compare (ls1->m_last_line, ls2->m_last_line); |
290 | } |
291 | |
292 | linenum_type m_first_line; |
293 | linenum_type m_last_line; |
294 | }; |
295 | |
296 | #if CHECKING_P1 |
297 | |
298 | /* Selftests for line_span. */ |
299 | |
300 | static void |
301 | test_line_span () |
302 | { |
303 | line_span line_one (1, 1); |
304 | ASSERT_EQ (1, line_one.get_first_line ())do { const char *desc_ = "ASSERT_EQ (" "(1)" ", " "(line_one.get_first_line ())" ")"; if (((1)) == ((line_one.get_first_line ()))) ::selftest ::pass ((((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 304, __FUNCTION__)))), desc_); else ::selftest::fail ((((:: selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 304, __FUNCTION__)))), desc_); } while (0); |
305 | ASSERT_EQ (1, line_one.get_last_line ())do { const char *desc_ = "ASSERT_EQ (" "(1)" ", " "(line_one.get_last_line ())" ")"; if (((1)) == ((line_one.get_last_line ()))) ::selftest:: pass ((((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 305, __FUNCTION__)))), desc_); else ::selftest::fail ((((:: selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 305, __FUNCTION__)))), desc_); } while (0); |
306 | ASSERT_FALSE (line_one.contains_line_p (0))do { const char *desc_ = "ASSERT_FALSE (" "(line_one.contains_line_p (0))" ")"; bool actual_ = ((line_one.contains_line_p (0))); if (actual_ ) ::selftest::fail (((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 306, __FUNCTION__))), desc_); else ::selftest::pass (((::selftest ::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 306, __FUNCTION__))), desc_); } while (0); |
307 | ASSERT_TRUE (line_one.contains_line_p (1))do { const char *desc_ = "ASSERT_TRUE (" "(line_one.contains_line_p (1))" ")"; bool actual_ = ((line_one.contains_line_p (1))); if (actual_ ) ::selftest::pass (((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 307, __FUNCTION__))), desc_); else ::selftest::fail (((::selftest ::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 307, __FUNCTION__))), desc_); } while (0); |
308 | ASSERT_FALSE (line_one.contains_line_p (2))do { const char *desc_ = "ASSERT_FALSE (" "(line_one.contains_line_p (2))" ")"; bool actual_ = ((line_one.contains_line_p (2))); if (actual_ ) ::selftest::fail (((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 308, __FUNCTION__))), desc_); else ::selftest::pass (((::selftest ::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 308, __FUNCTION__))), desc_); } while (0); |
309 | |
310 | line_span lines_1_to_3 (1, 3); |
311 | ASSERT_EQ (1, lines_1_to_3.get_first_line ())do { const char *desc_ = "ASSERT_EQ (" "(1)" ", " "(lines_1_to_3.get_first_line ())" ")"; if (((1)) == ((lines_1_to_3.get_first_line ()))) ::selftest ::pass ((((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 311, __FUNCTION__)))), desc_); else ::selftest::fail ((((:: selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 311, __FUNCTION__)))), desc_); } while (0); |
312 | ASSERT_EQ (3, lines_1_to_3.get_last_line ())do { const char *desc_ = "ASSERT_EQ (" "(3)" ", " "(lines_1_to_3.get_last_line ())" ")"; if (((3)) == ((lines_1_to_3.get_last_line ()))) ::selftest ::pass ((((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 312, __FUNCTION__)))), desc_); else ::selftest::fail ((((:: selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 312, __FUNCTION__)))), desc_); } while (0); |
313 | ASSERT_TRUE (lines_1_to_3.contains_line_p (1))do { const char *desc_ = "ASSERT_TRUE (" "(lines_1_to_3.contains_line_p (1))" ")"; bool actual_ = ((lines_1_to_3.contains_line_p (1))); if (actual_) ::selftest::pass (((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 313, __FUNCTION__))), desc_); else ::selftest::fail (((::selftest ::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 313, __FUNCTION__))), desc_); } while (0); |
314 | ASSERT_TRUE (lines_1_to_3.contains_line_p (3))do { const char *desc_ = "ASSERT_TRUE (" "(lines_1_to_3.contains_line_p (3))" ")"; bool actual_ = ((lines_1_to_3.contains_line_p (3))); if (actual_) ::selftest::pass (((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 314, __FUNCTION__))), desc_); else ::selftest::fail (((::selftest ::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 314, __FUNCTION__))), desc_); } while (0); |
315 | |
316 | ASSERT_EQ (0, line_span::comparator (&line_one, &line_one))do { const char *desc_ = "ASSERT_EQ (" "(0)" ", " "(line_span::comparator (&line_one, &line_one))" ")"; if (((0)) == ((line_span::comparator (&line_one, & line_one)))) ::selftest::pass ((((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 316, __FUNCTION__)))), desc_); else ::selftest::fail ((((:: selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 316, __FUNCTION__)))), desc_); } while (0); |
317 | ASSERT_GT (line_span::comparator (&lines_1_to_3, &line_one), 0)do { const char *desc_ = "ASSERT_GT (" "(line_span::comparator (&lines_1_to_3, &line_one))" ", " "(0)" ")"; if (((line_span::comparator (&lines_1_to_3 , &line_one))) > ((0))) ::selftest::pass ((((::selftest ::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 317, __FUNCTION__)))), desc_); else ::selftest::fail ((((:: selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 317, __FUNCTION__)))), desc_); } while (0); |
318 | ASSERT_LT (line_span::comparator (&line_one, &lines_1_to_3), 0)do { const char *desc_ = "ASSERT_LT (" "(line_span::comparator (&line_one, &lines_1_to_3))" ", " "(0)" ")"; if (((line_span::comparator (&line_one, & lines_1_to_3))) < ((0))) ::selftest::pass ((((::selftest:: location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 318, __FUNCTION__)))), desc_); else ::selftest::fail ((((:: selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 318, __FUNCTION__)))), desc_); } while (0); |
319 | |
320 | /* A linenum > 2^31. */ |
321 | const linenum_type LARGEST_LINE = 0xffffffff; |
322 | line_span largest_line (LARGEST_LINE, LARGEST_LINE); |
323 | ASSERT_EQ (LARGEST_LINE, largest_line.get_first_line ())do { const char *desc_ = "ASSERT_EQ (" "(LARGEST_LINE)" ", " "(largest_line.get_first_line ())" ")"; if (((LARGEST_LINE)) == ((largest_line.get_first_line ( )))) ::selftest::pass ((((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 323, __FUNCTION__)))), desc_); else ::selftest::fail ((((:: selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 323, __FUNCTION__)))), desc_); } while (0); |
324 | ASSERT_EQ (LARGEST_LINE, largest_line.get_last_line ())do { const char *desc_ = "ASSERT_EQ (" "(LARGEST_LINE)" ", " "(largest_line.get_last_line ())" ")"; if (((LARGEST_LINE)) == ((largest_line.get_last_line () ))) ::selftest::pass ((((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 324, __FUNCTION__)))), desc_); else ::selftest::fail ((((:: selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 324, __FUNCTION__)))), desc_); } while (0); |
325 | |
326 | ASSERT_GT (line_span::comparator (&largest_line, &line_one), 0)do { const char *desc_ = "ASSERT_GT (" "(line_span::comparator (&largest_line, &line_one))" ", " "(0)" ")"; if (((line_span::comparator (&largest_line , &line_one))) > ((0))) ::selftest::pass ((((::selftest ::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 326, __FUNCTION__)))), desc_); else ::selftest::fail ((((:: selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 326, __FUNCTION__)))), desc_); } while (0); |
327 | ASSERT_LT (line_span::comparator (&line_one, &largest_line), 0)do { const char *desc_ = "ASSERT_LT (" "(line_span::comparator (&line_one, &largest_line))" ", " "(0)" ")"; if (((line_span::comparator (&line_one, & largest_line))) < ((0))) ::selftest::pass ((((::selftest:: location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 327, __FUNCTION__)))), desc_); else ::selftest::fail ((((:: selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 327, __FUNCTION__)))), desc_); } while (0); |
328 | } |
329 | |
330 | #endif /* #if CHECKING_P */ |
331 | |
332 | /* A bundle of information containing how to print unicode |
333 | characters and bytes when quoting source code. |
334 | |
335 | Provides a unified place to support escaping some subset |
336 | of characters to some format. |
337 | |
338 | Extends char_column_policy; printing is split out to avoid |
339 | libcpp having to know about pretty_printer. */ |
340 | |
341 | struct char_display_policy : public cpp_char_column_policy |
342 | { |
343 | public: |
344 | char_display_policy (int tabstop, |
345 | int (*width_cb) (cppchar_t c), |
346 | void (*print_cb) (pretty_printer *pp, |
347 | const cpp_decoded_char &cp)) |
348 | : cpp_char_column_policy (tabstop, width_cb), |
349 | m_print_cb (print_cb) |
350 | { |
351 | } |
352 | |
353 | void (*m_print_cb) (pretty_printer *pp, |
354 | const cpp_decoded_char &cp); |
355 | }; |
356 | |
357 | /* A class to control the overall layout when printing a diagnostic. |
358 | |
359 | The layout is determined within the constructor. |
360 | It is then printed by repeatedly calling the "print_source_line", |
361 | "print_annotation_line" and "print_any_fixits" methods. |
362 | |
363 | We assume we have disjoint ranges. */ |
364 | |
365 | class layout |
366 | { |
367 | public: |
368 | layout (diagnostic_context *context, |
369 | rich_location *richloc, |
370 | diagnostic_t diagnostic_kind); |
371 | |
372 | bool maybe_add_location_range (const location_range *loc_range, |
373 | unsigned original_idx, |
374 | bool restrict_to_current_line_spans); |
375 | |
376 | int get_num_line_spans () const { return m_line_spans.length (); } |
377 | const line_span *get_line_span (int idx) const { return &m_line_spans[idx]; } |
378 | |
379 | int get_linenum_width () const { return m_linenum_width; } |
380 | int get_x_offset_display () const { return m_x_offset_display; } |
381 | |
382 | void print_gap_in_line_numbering (); |
383 | bool print_heading_for_line_span_index_p (int line_span_idx) const; |
384 | |
385 | expanded_location get_expanded_location (const line_span *) const; |
386 | |
387 | void print_line (linenum_type row); |
388 | |
389 | void on_bad_codepoint (const char *ptr, cppchar_t ch, size_t ch_sz); |
390 | |
391 | private: |
392 | bool will_show_line_p (linenum_type row) const; |
393 | void print_leading_fixits (linenum_type row); |
394 | line_bounds print_source_line (linenum_type row, const char *line, |
395 | int line_bytes); |
396 | bool should_print_annotation_line_p (linenum_type row) const; |
397 | void start_annotation_line (char margin_char = ' ') const; |
398 | void print_annotation_line (linenum_type row, const line_bounds lbounds); |
399 | void print_any_labels (linenum_type row); |
400 | void print_trailing_fixits (linenum_type row); |
401 | |
402 | bool annotation_line_showed_range_p (linenum_type line, int start_column, |
403 | int finish_column) const; |
404 | void show_ruler (int max_column) const; |
405 | |
406 | bool validate_fixit_hint_p (const fixit_hint *hint); |
407 | |
408 | void calculate_line_spans (); |
409 | void calculate_linenum_width (); |
410 | void calculate_x_offset_display (); |
411 | |
412 | void print_newline (); |
413 | |
414 | bool |
415 | get_state_at_point (/* Inputs. */ |
416 | linenum_type row, int column, |
417 | int first_non_ws, int last_non_ws, |
418 | enum column_unit col_unit, |
419 | /* Outputs. */ |
420 | point_state *out_state); |
421 | |
422 | int |
423 | get_x_bound_for_row (linenum_type row, int caret_column, |
424 | int last_non_ws); |
425 | |
426 | void |
427 | move_to_column (int *column, int dest_column, bool add_left_margin); |
428 | |
429 | private: |
430 | diagnostic_context *m_context; |
431 | pretty_printer *m_pp; |
432 | char_display_policy m_policy; |
433 | location_t m_primary_loc; |
434 | exploc_with_display_col m_exploc; |
435 | colorizer m_colorizer; |
436 | bool m_colorize_source_p; |
437 | bool m_show_labels_p; |
438 | bool m_show_line_numbers_p; |
439 | bool m_diagnostic_path_p; |
440 | auto_vec <layout_range> m_layout_ranges; |
441 | auto_vec <const fixit_hint *> m_fixit_hints; |
442 | auto_vec <line_span> m_line_spans; |
443 | int m_linenum_width; |
444 | int m_x_offset_display; |
445 | bool m_escape_on_output; |
446 | }; |
447 | |
448 | /* Implementation of "class colorizer". */ |
449 | |
450 | /* The constructor for "colorizer". Lookup and store color codes for the |
451 | different kinds of things we might need to print. */ |
452 | |
453 | colorizer::colorizer (diagnostic_context *context, |
454 | diagnostic_t diagnostic_kind) : |
455 | m_context (context), |
456 | m_diagnostic_kind (diagnostic_kind), |
457 | m_current_state (STATE_NORMAL_TEXT) |
458 | { |
459 | m_range1 = get_color_by_name ("range1"); |
460 | m_range2 = get_color_by_name ("range2"); |
461 | m_fixit_insert = get_color_by_name ("fixit-insert"); |
462 | m_fixit_delete = get_color_by_name ("fixit-delete"); |
463 | m_stop_color = colorize_stop (pp_show_color (context->printer)(context->printer)->show_color); |
464 | } |
465 | |
466 | /* The destructor for "colorize". If colorization is on, print a code to |
467 | turn it off. */ |
468 | |
469 | colorizer::~colorizer () |
470 | { |
471 | finish_state (m_current_state); |
472 | } |
473 | |
474 | /* Update state, printing color codes if necessary if there's a state |
475 | change. */ |
476 | |
477 | void |
478 | colorizer::set_state (int new_state) |
479 | { |
480 | if (m_current_state != new_state) |
481 | { |
482 | finish_state (m_current_state); |
483 | m_current_state = new_state; |
484 | begin_state (new_state); |
485 | } |
486 | } |
487 | |
488 | /* Turn on any colorization for STATE. */ |
489 | |
490 | void |
491 | colorizer::begin_state (int state) |
492 | { |
493 | switch (state) |
494 | { |
495 | case STATE_NORMAL_TEXT: |
496 | break; |
497 | |
498 | case STATE_FIXIT_INSERT: |
499 | pp_string (m_context->printer, m_fixit_insert); |
500 | break; |
501 | |
502 | case STATE_FIXIT_DELETE: |
503 | pp_string (m_context->printer, m_fixit_delete); |
504 | break; |
505 | |
506 | case 0: |
507 | /* Make range 0 be the same color as the "kind" text |
508 | (error vs warning vs note). */ |
509 | pp_string |
510 | (m_context->printer, |
511 | colorize_start (pp_show_color (m_context->printer)(m_context->printer)->show_color, |
512 | diagnostic_get_color_for_kind (m_diagnostic_kind))); |
513 | break; |
514 | |
515 | case 1: |
516 | pp_string (m_context->printer, m_range1); |
517 | break; |
518 | |
519 | case 2: |
520 | pp_string (m_context->printer, m_range2); |
521 | break; |
522 | |
523 | default: |
524 | /* For ranges beyond 2, alternate between color 1 and color 2. */ |
525 | { |
526 | gcc_assert (state > 2)((void)(!(state > 2) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 526, __FUNCTION__), 0 : 0)); |
527 | pp_string (m_context->printer, |
528 | state % 2 ? m_range1 : m_range2); |
529 | } |
530 | break; |
531 | } |
532 | } |
533 | |
534 | /* Turn off any colorization for STATE. */ |
535 | |
536 | void |
537 | colorizer::finish_state (int state) |
538 | { |
539 | if (state != STATE_NORMAL_TEXT) |
540 | pp_string (m_context->printer, m_stop_color); |
541 | } |
542 | |
543 | /* Get the color code for NAME (or the empty string if |
544 | colorization is disabled). */ |
545 | |
546 | const char * |
547 | colorizer::get_color_by_name (const char *name) |
548 | { |
549 | return colorize_start (pp_show_color (m_context->printer)(m_context->printer)->show_color, name); |
550 | } |
551 | |
552 | /* Implementation of class layout_range. */ |
553 | |
554 | /* The constructor for class layout_range. |
555 | Initialize various layout_point fields from expanded_location |
556 | equivalents; we've already filtered on file. */ |
557 | |
558 | layout_range::layout_range (const exploc_with_display_col &start_exploc, |
559 | const exploc_with_display_col &finish_exploc, |
560 | enum range_display_kind range_display_kind, |
561 | const exploc_with_display_col &caret_exploc, |
562 | unsigned original_idx, |
563 | const range_label *label) |
564 | : m_start (start_exploc), |
565 | m_finish (finish_exploc), |
566 | m_range_display_kind (range_display_kind), |
567 | m_caret (caret_exploc), |
568 | m_original_idx (original_idx), |
569 | m_label (label) |
570 | { |
571 | } |
572 | |
573 | /* Is (column, row) within the given range? |
574 | We've already filtered on the file. |
575 | |
576 | Ranges are closed (both limits are within the range). |
577 | |
578 | Example A: a single-line range: |
579 | start: (col=22, line=2) |
580 | finish: (col=38, line=2) |
581 | |
582 | |00000011111111112222222222333333333344444444444 |
583 | |34567890123456789012345678901234567890123456789 |
584 | --+----------------------------------------------- |
585 | 01|bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb |
586 | 02|bbbbbbbbbbbbbbbbbbbSwwwwwwwwwwwwwwwFaaaaaaaaaaa |
587 | 03|aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa |
588 | |
589 | Example B: a multiline range with |
590 | start: (col=14, line=3) |
591 | finish: (col=08, line=5) |
592 | |
593 | |00000011111111112222222222333333333344444444444 |
594 | |34567890123456789012345678901234567890123456789 |
595 | --+----------------------------------------------- |
596 | 01|bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb |
597 | 02|bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb |
598 | 03|bbbbbbbbbbbSwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwww |
599 | 04|wwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwww |
600 | 05|wwwwwFaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa |
601 | 06|aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa |
602 | --+----------------------------------------------- |
603 | |
604 | Legend: |
605 | - 'b' indicates a point *before* the range |
606 | - 'S' indicates the start of the range |
607 | - 'w' indicates a point within the range |
608 | - 'F' indicates the finish of the range (which is |
609 | within it). |
610 | - 'a' indicates a subsequent point *after* the range. |
611 | |
612 | COL_UNIT controls whether we check the byte column or |
613 | the display column; one or the other is more convenient |
614 | depending on the context. */ |
615 | |
616 | bool |
617 | layout_range::contains_point (linenum_type row, int column, |
618 | enum column_unit col_unit) const |
619 | { |
620 | gcc_assert (m_start.m_line <= m_finish.m_line)((void)(!(m_start.m_line <= m_finish.m_line) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 620, __FUNCTION__), 0 : 0)); |
621 | /* ...but the equivalent isn't true for the columns; |
622 | consider example B in the comment above. */ |
623 | |
624 | if (row < m_start.m_line) |
625 | /* Points before the first line of the range are |
626 | outside it (corresponding to line 01 in example A |
627 | and lines 01 and 02 in example B above). */ |
628 | return false; |
629 | |
630 | if (row == m_start.m_line) |
631 | /* On same line as start of range (corresponding |
632 | to line 02 in example A and line 03 in example B). */ |
633 | { |
634 | if (column < m_start.m_columns[col_unit]) |
635 | /* Points on the starting line of the range, but |
636 | before the column in which it begins. */ |
637 | return false; |
638 | |
639 | if (row < m_finish.m_line) |
640 | /* This is a multiline range; the point |
641 | is within it (corresponds to line 03 in example B |
642 | from column 14 onwards) */ |
643 | return true; |
644 | else |
645 | { |
646 | /* This is a single-line range. */ |
647 | gcc_assert (row == m_finish.m_line)((void)(!(row == m_finish.m_line) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 647, __FUNCTION__), 0 : 0)); |
648 | return column <= m_finish.m_columns[col_unit]; |
649 | } |
650 | } |
651 | |
652 | /* The point is in a line beyond that containing the |
653 | start of the range: lines 03 onwards in example A, |
654 | and lines 04 onwards in example B. */ |
655 | gcc_assert (row > m_start.m_line)((void)(!(row > m_start.m_line) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 655, __FUNCTION__), 0 : 0)); |
656 | |
657 | if (row > m_finish.m_line) |
658 | /* The point is beyond the final line of the range |
659 | (lines 03 onwards in example A, and lines 06 onwards |
660 | in example B). */ |
661 | return false; |
662 | |
663 | if (row < m_finish.m_line) |
664 | { |
665 | /* The point is in a line that's fully within a multiline |
666 | range (e.g. line 04 in example B). */ |
667 | gcc_assert (m_start.m_line < m_finish.m_line)((void)(!(m_start.m_line < m_finish.m_line) ? fancy_abort ( "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 667, __FUNCTION__), 0 : 0)); |
668 | return true; |
669 | } |
670 | |
671 | gcc_assert (row == m_finish.m_line)((void)(!(row == m_finish.m_line) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 671, __FUNCTION__), 0 : 0)); |
672 | |
673 | return column <= m_finish.m_columns[col_unit]; |
674 | } |
675 | |
676 | /* Does this layout_range contain any part of line ROW? */ |
677 | |
678 | bool |
679 | layout_range::intersects_line_p (linenum_type row) const |
680 | { |
681 | gcc_assert (m_start.m_line <= m_finish.m_line)((void)(!(m_start.m_line <= m_finish.m_line) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 681, __FUNCTION__), 0 : 0)); |
682 | if (row < m_start.m_line) |
683 | return false; |
684 | if (row > m_finish.m_line) |
685 | return false; |
686 | return true; |
687 | } |
688 | |
689 | #if CHECKING_P1 |
690 | |
691 | /* Default for when we don't care what the tab expansion is set to. */ |
692 | static const int def_tabstop = 8; |
693 | |
694 | static cpp_char_column_policy def_policy () |
695 | { |
696 | return cpp_char_column_policy (def_tabstop, cpp_wcwidth); |
697 | } |
698 | |
699 | /* Create some expanded locations for testing layout_range. The filename |
700 | member of the explocs is set to the empty string. This member will only be |
701 | inspected by the calls to location_compute_display_column() made from the |
702 | layout_point constructors. That function will check for an empty filename |
703 | argument and not attempt to open it, rather treating the non-existent data |
704 | as if the display width were the same as the byte count. Tests exercising a |
705 | real difference between byte count and display width are performed later, |
706 | e.g. in test_diagnostic_show_locus_one_liner_utf8(). */ |
707 | |
708 | static layout_range |
709 | make_range (int start_line, int start_col, int end_line, int end_col) |
710 | { |
711 | const expanded_location start_exploc |
712 | = {"", start_line, start_col, NULL__null, false}; |
713 | const expanded_location finish_exploc |
714 | = {"", end_line, end_col, NULL__null, false}; |
715 | return layout_range (exploc_with_display_col (start_exploc, def_policy (), |
716 | LOCATION_ASPECT_START), |
717 | exploc_with_display_col (finish_exploc, def_policy (), |
718 | LOCATION_ASPECT_FINISH), |
719 | SHOW_RANGE_WITHOUT_CARET, |
720 | exploc_with_display_col (start_exploc, def_policy (), |
721 | LOCATION_ASPECT_CARET), |
722 | 0, NULL__null); |
723 | } |
724 | |
725 | /* Selftests for layout_range::contains_point and |
726 | layout_range::intersects_line_p. */ |
727 | |
728 | /* Selftest for layout_range, where the layout_range |
729 | is a range with start==end i.e. a single point. */ |
730 | |
731 | static void |
732 | test_layout_range_for_single_point () |
733 | { |
734 | layout_range point = make_range (7, 10, 7, 10); |
735 | |
736 | /* Tests for layout_range::contains_point. */ |
737 | |
738 | for (int i = 0; i != CU_NUM_UNITS; ++i) |
739 | { |
740 | const enum column_unit col_unit = (enum column_unit) i; |
741 | |
742 | /* Before the line. */ |
743 | ASSERT_FALSE (point.contains_point (6, 1, col_unit))do { const char *desc_ = "ASSERT_FALSE (" "(point.contains_point (6, 1, col_unit))" ")"; bool actual_ = ((point.contains_point (6, 1, col_unit)) ); if (actual_) ::selftest::fail (((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 743, __FUNCTION__))), desc_); else ::selftest::pass (((::selftest ::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 743, __FUNCTION__))), desc_); } while (0); |
744 | |
745 | /* On the line, but before start. */ |
746 | ASSERT_FALSE (point.contains_point (7, 9, col_unit))do { const char *desc_ = "ASSERT_FALSE (" "(point.contains_point (7, 9, col_unit))" ")"; bool actual_ = ((point.contains_point (7, 9, col_unit)) ); if (actual_) ::selftest::fail (((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 746, __FUNCTION__))), desc_); else ::selftest::pass (((::selftest ::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 746, __FUNCTION__))), desc_); } while (0); |
747 | |
748 | /* At the point. */ |
749 | ASSERT_TRUE (point.contains_point (7, 10, col_unit))do { const char *desc_ = "ASSERT_TRUE (" "(point.contains_point (7, 10, col_unit))" ")"; bool actual_ = ((point.contains_point (7, 10, col_unit) )); if (actual_) ::selftest::pass (((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 749, __FUNCTION__))), desc_); else ::selftest::fail (((::selftest ::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 749, __FUNCTION__))), desc_); } while (0); |
750 | |
751 | /* On the line, after the point. */ |
752 | ASSERT_FALSE (point.contains_point (7, 11, col_unit))do { const char *desc_ = "ASSERT_FALSE (" "(point.contains_point (7, 11, col_unit))" ")"; bool actual_ = ((point.contains_point (7, 11, col_unit) )); if (actual_) ::selftest::fail (((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 752, __FUNCTION__))), desc_); else ::selftest::pass (((::selftest ::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 752, __FUNCTION__))), desc_); } while (0); |
753 | |
754 | /* After the line. */ |
755 | ASSERT_FALSE (point.contains_point (8, 1, col_unit))do { const char *desc_ = "ASSERT_FALSE (" "(point.contains_point (8, 1, col_unit))" ")"; bool actual_ = ((point.contains_point (8, 1, col_unit)) ); if (actual_) ::selftest::fail (((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 755, __FUNCTION__))), desc_); else ::selftest::pass (((::selftest ::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 755, __FUNCTION__))), desc_); } while (0); |
756 | } |
757 | |
758 | /* Tests for layout_range::intersects_line_p. */ |
759 | ASSERT_FALSE (point.intersects_line_p (6))do { const char *desc_ = "ASSERT_FALSE (" "(point.intersects_line_p (6))" ")"; bool actual_ = ((point.intersects_line_p (6))); if (actual_ ) ::selftest::fail (((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 759, __FUNCTION__))), desc_); else ::selftest::pass (((::selftest ::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 759, __FUNCTION__))), desc_); } while (0); |
760 | ASSERT_TRUE (point.intersects_line_p (7))do { const char *desc_ = "ASSERT_TRUE (" "(point.intersects_line_p (7))" ")"; bool actual_ = ((point.intersects_line_p (7))); if (actual_ ) ::selftest::pass (((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 760, __FUNCTION__))), desc_); else ::selftest::fail (((::selftest ::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 760, __FUNCTION__))), desc_); } while (0); |
761 | ASSERT_FALSE (point.intersects_line_p (8))do { const char *desc_ = "ASSERT_FALSE (" "(point.intersects_line_p (8))" ")"; bool actual_ = ((point.intersects_line_p (8))); if (actual_ ) ::selftest::fail (((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 761, __FUNCTION__))), desc_); else ::selftest::pass (((::selftest ::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 761, __FUNCTION__))), desc_); } while (0); |
762 | } |
763 | |
764 | /* Selftest for layout_range, where the layout_range |
765 | is the single-line range shown as "Example A" above. */ |
766 | |
767 | static void |
768 | test_layout_range_for_single_line () |
769 | { |
770 | layout_range example_a = make_range (2, 22, 2, 38); |
771 | |
772 | /* Tests for layout_range::contains_point. */ |
773 | |
774 | for (int i = 0; i != CU_NUM_UNITS; ++i) |
775 | { |
776 | const enum column_unit col_unit = (enum column_unit) i; |
777 | |
778 | /* Before the line. */ |
779 | ASSERT_FALSE (example_a.contains_point (1, 1, col_unit))do { const char *desc_ = "ASSERT_FALSE (" "(example_a.contains_point (1, 1, col_unit))" ")"; bool actual_ = ((example_a.contains_point (1, 1, col_unit ))); if (actual_) ::selftest::fail (((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 779, __FUNCTION__))), desc_); else ::selftest::pass (((::selftest ::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 779, __FUNCTION__))), desc_); } while (0); |
780 | |
781 | /* On the line, but before start. */ |
782 | ASSERT_FALSE (example_a.contains_point (2, 21, col_unit))do { const char *desc_ = "ASSERT_FALSE (" "(example_a.contains_point (2, 21, col_unit))" ")"; bool actual_ = ((example_a.contains_point (2, 21, col_unit ))); if (actual_) ::selftest::fail (((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 782, __FUNCTION__))), desc_); else ::selftest::pass (((::selftest ::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 782, __FUNCTION__))), desc_); } while (0); |
783 | |
784 | /* On the line, at the start. */ |
785 | ASSERT_TRUE (example_a.contains_point (2, 22, col_unit))do { const char *desc_ = "ASSERT_TRUE (" "(example_a.contains_point (2, 22, col_unit))" ")"; bool actual_ = ((example_a.contains_point (2, 22, col_unit ))); if (actual_) ::selftest::pass (((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 785, __FUNCTION__))), desc_); else ::selftest::fail (((::selftest ::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 785, __FUNCTION__))), desc_); } while (0); |
786 | |
787 | /* On the line, within the range. */ |
788 | ASSERT_TRUE (example_a.contains_point (2, 23, col_unit))do { const char *desc_ = "ASSERT_TRUE (" "(example_a.contains_point (2, 23, col_unit))" ")"; bool actual_ = ((example_a.contains_point (2, 23, col_unit ))); if (actual_) ::selftest::pass (((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 788, __FUNCTION__))), desc_); else ::selftest::fail (((::selftest ::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 788, __FUNCTION__))), desc_); } while (0); |
789 | |
790 | /* On the line, at the end. */ |
791 | ASSERT_TRUE (example_a.contains_point (2, 38, col_unit))do { const char *desc_ = "ASSERT_TRUE (" "(example_a.contains_point (2, 38, col_unit))" ")"; bool actual_ = ((example_a.contains_point (2, 38, col_unit ))); if (actual_) ::selftest::pass (((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 791, __FUNCTION__))), desc_); else ::selftest::fail (((::selftest ::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 791, __FUNCTION__))), desc_); } while (0); |
792 | |
793 | /* On the line, after the end. */ |
794 | ASSERT_FALSE (example_a.contains_point (2, 39, col_unit))do { const char *desc_ = "ASSERT_FALSE (" "(example_a.contains_point (2, 39, col_unit))" ")"; bool actual_ = ((example_a.contains_point (2, 39, col_unit ))); if (actual_) ::selftest::fail (((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 794, __FUNCTION__))), desc_); else ::selftest::pass (((::selftest ::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 794, __FUNCTION__))), desc_); } while (0); |
795 | |
796 | /* After the line. */ |
797 | ASSERT_FALSE (example_a.contains_point (2, 39, col_unit))do { const char *desc_ = "ASSERT_FALSE (" "(example_a.contains_point (2, 39, col_unit))" ")"; bool actual_ = ((example_a.contains_point (2, 39, col_unit ))); if (actual_) ::selftest::fail (((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 797, __FUNCTION__))), desc_); else ::selftest::pass (((::selftest ::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 797, __FUNCTION__))), desc_); } while (0); |
798 | } |
799 | |
800 | /* Tests for layout_range::intersects_line_p. */ |
801 | ASSERT_FALSE (example_a.intersects_line_p (1))do { const char *desc_ = "ASSERT_FALSE (" "(example_a.intersects_line_p (1))" ")"; bool actual_ = ((example_a.intersects_line_p (1))); if ( actual_) ::selftest::fail (((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 801, __FUNCTION__))), desc_); else ::selftest::pass (((::selftest ::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 801, __FUNCTION__))), desc_); } while (0); |
802 | ASSERT_TRUE (example_a.intersects_line_p (2))do { const char *desc_ = "ASSERT_TRUE (" "(example_a.intersects_line_p (2))" ")"; bool actual_ = ((example_a.intersects_line_p (2))); if ( actual_) ::selftest::pass (((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 802, __FUNCTION__))), desc_); else ::selftest::fail (((::selftest ::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 802, __FUNCTION__))), desc_); } while (0); |
803 | ASSERT_FALSE (example_a.intersects_line_p (3))do { const char *desc_ = "ASSERT_FALSE (" "(example_a.intersects_line_p (3))" ")"; bool actual_ = ((example_a.intersects_line_p (3))); if ( actual_) ::selftest::fail (((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 803, __FUNCTION__))), desc_); else ::selftest::pass (((::selftest ::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 803, __FUNCTION__))), desc_); } while (0); |
804 | } |
805 | |
806 | /* Selftest for layout_range, where the layout_range |
807 | is the multi-line range shown as "Example B" above. */ |
808 | |
809 | static void |
810 | test_layout_range_for_multiple_lines () |
811 | { |
812 | layout_range example_b = make_range (3, 14, 5, 8); |
813 | |
814 | /* Tests for layout_range::contains_point. */ |
815 | |
816 | for (int i = 0; i != CU_NUM_UNITS; ++i) |
817 | { |
818 | const enum column_unit col_unit = (enum column_unit) i; |
819 | |
820 | /* Before first line. */ |
821 | ASSERT_FALSE (example_b.contains_point (1, 1, col_unit))do { const char *desc_ = "ASSERT_FALSE (" "(example_b.contains_point (1, 1, col_unit))" ")"; bool actual_ = ((example_b.contains_point (1, 1, col_unit ))); if (actual_) ::selftest::fail (((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 821, __FUNCTION__))), desc_); else ::selftest::pass (((::selftest ::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 821, __FUNCTION__))), desc_); } while (0); |
822 | |
823 | /* On the first line, but before start. */ |
824 | ASSERT_FALSE (example_b.contains_point (3, 13, col_unit))do { const char *desc_ = "ASSERT_FALSE (" "(example_b.contains_point (3, 13, col_unit))" ")"; bool actual_ = ((example_b.contains_point (3, 13, col_unit ))); if (actual_) ::selftest::fail (((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 824, __FUNCTION__))), desc_); else ::selftest::pass (((::selftest ::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 824, __FUNCTION__))), desc_); } while (0); |
825 | |
826 | /* At the start. */ |
827 | ASSERT_TRUE (example_b.contains_point (3, 14, col_unit))do { const char *desc_ = "ASSERT_TRUE (" "(example_b.contains_point (3, 14, col_unit))" ")"; bool actual_ = ((example_b.contains_point (3, 14, col_unit ))); if (actual_) ::selftest::pass (((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 827, __FUNCTION__))), desc_); else ::selftest::fail (((::selftest ::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 827, __FUNCTION__))), desc_); } while (0); |
828 | |
829 | /* On the first line, within the range. */ |
830 | ASSERT_TRUE (example_b.contains_point (3, 15, col_unit))do { const char *desc_ = "ASSERT_TRUE (" "(example_b.contains_point (3, 15, col_unit))" ")"; bool actual_ = ((example_b.contains_point (3, 15, col_unit ))); if (actual_) ::selftest::pass (((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 830, __FUNCTION__))), desc_); else ::selftest::fail (((::selftest ::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 830, __FUNCTION__))), desc_); } while (0); |
831 | |
832 | /* On an interior line. |
833 | The column number should not matter; try various boundary |
834 | values. */ |
835 | ASSERT_TRUE (example_b.contains_point (4, 1, col_unit))do { const char *desc_ = "ASSERT_TRUE (" "(example_b.contains_point (4, 1, col_unit))" ")"; bool actual_ = ((example_b.contains_point (4, 1, col_unit ))); if (actual_) ::selftest::pass (((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 835, __FUNCTION__))), desc_); else ::selftest::fail (((::selftest ::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 835, __FUNCTION__))), desc_); } while (0); |
836 | ASSERT_TRUE (example_b.contains_point (4, 7, col_unit))do { const char *desc_ = "ASSERT_TRUE (" "(example_b.contains_point (4, 7, col_unit))" ")"; bool actual_ = ((example_b.contains_point (4, 7, col_unit ))); if (actual_) ::selftest::pass (((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 836, __FUNCTION__))), desc_); else ::selftest::fail (((::selftest ::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 836, __FUNCTION__))), desc_); } while (0); |
837 | ASSERT_TRUE (example_b.contains_point (4, 8, col_unit))do { const char *desc_ = "ASSERT_TRUE (" "(example_b.contains_point (4, 8, col_unit))" ")"; bool actual_ = ((example_b.contains_point (4, 8, col_unit ))); if (actual_) ::selftest::pass (((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 837, __FUNCTION__))), desc_); else ::selftest::fail (((::selftest ::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 837, __FUNCTION__))), desc_); } while (0); |
838 | ASSERT_TRUE (example_b.contains_point (4, 9, col_unit))do { const char *desc_ = "ASSERT_TRUE (" "(example_b.contains_point (4, 9, col_unit))" ")"; bool actual_ = ((example_b.contains_point (4, 9, col_unit ))); if (actual_) ::selftest::pass (((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 838, __FUNCTION__))), desc_); else ::selftest::fail (((::selftest ::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 838, __FUNCTION__))), desc_); } while (0); |
839 | ASSERT_TRUE (example_b.contains_point (4, 13, col_unit))do { const char *desc_ = "ASSERT_TRUE (" "(example_b.contains_point (4, 13, col_unit))" ")"; bool actual_ = ((example_b.contains_point (4, 13, col_unit ))); if (actual_) ::selftest::pass (((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 839, __FUNCTION__))), desc_); else ::selftest::fail (((::selftest ::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 839, __FUNCTION__))), desc_); } while (0); |
840 | ASSERT_TRUE (example_b.contains_point (4, 14, col_unit))do { const char *desc_ = "ASSERT_TRUE (" "(example_b.contains_point (4, 14, col_unit))" ")"; bool actual_ = ((example_b.contains_point (4, 14, col_unit ))); if (actual_) ::selftest::pass (((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 840, __FUNCTION__))), desc_); else ::selftest::fail (((::selftest ::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 840, __FUNCTION__))), desc_); } while (0); |
841 | ASSERT_TRUE (example_b.contains_point (4, 15, col_unit))do { const char *desc_ = "ASSERT_TRUE (" "(example_b.contains_point (4, 15, col_unit))" ")"; bool actual_ = ((example_b.contains_point (4, 15, col_unit ))); if (actual_) ::selftest::pass (((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 841, __FUNCTION__))), desc_); else ::selftest::fail (((::selftest ::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 841, __FUNCTION__))), desc_); } while (0); |
842 | |
843 | /* On the final line, before the end. */ |
844 | ASSERT_TRUE (example_b.contains_point (5, 7, col_unit))do { const char *desc_ = "ASSERT_TRUE (" "(example_b.contains_point (5, 7, col_unit))" ")"; bool actual_ = ((example_b.contains_point (5, 7, col_unit ))); if (actual_) ::selftest::pass (((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 844, __FUNCTION__))), desc_); else ::selftest::fail (((::selftest ::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 844, __FUNCTION__))), desc_); } while (0); |
845 | |
846 | /* On the final line, at the end. */ |
847 | ASSERT_TRUE (example_b.contains_point (5, 8, col_unit))do { const char *desc_ = "ASSERT_TRUE (" "(example_b.contains_point (5, 8, col_unit))" ")"; bool actual_ = ((example_b.contains_point (5, 8, col_unit ))); if (actual_) ::selftest::pass (((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 847, __FUNCTION__))), desc_); else ::selftest::fail (((::selftest ::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 847, __FUNCTION__))), desc_); } while (0); |
848 | |
849 | /* On the final line, after the end. */ |
850 | ASSERT_FALSE (example_b.contains_point (5, 9, col_unit))do { const char *desc_ = "ASSERT_FALSE (" "(example_b.contains_point (5, 9, col_unit))" ")"; bool actual_ = ((example_b.contains_point (5, 9, col_unit ))); if (actual_) ::selftest::fail (((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 850, __FUNCTION__))), desc_); else ::selftest::pass (((::selftest ::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 850, __FUNCTION__))), desc_); } while (0); |
851 | |
852 | /* After the line. */ |
853 | ASSERT_FALSE (example_b.contains_point (6, 1, col_unit))do { const char *desc_ = "ASSERT_FALSE (" "(example_b.contains_point (6, 1, col_unit))" ")"; bool actual_ = ((example_b.contains_point (6, 1, col_unit ))); if (actual_) ::selftest::fail (((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 853, __FUNCTION__))), desc_); else ::selftest::pass (((::selftest ::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 853, __FUNCTION__))), desc_); } while (0); |
854 | } |
855 | |
856 | /* Tests for layout_range::intersects_line_p. */ |
857 | ASSERT_FALSE (example_b.intersects_line_p (2))do { const char *desc_ = "ASSERT_FALSE (" "(example_b.intersects_line_p (2))" ")"; bool actual_ = ((example_b.intersects_line_p (2))); if ( actual_) ::selftest::fail (((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 857, __FUNCTION__))), desc_); else ::selftest::pass (((::selftest ::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 857, __FUNCTION__))), desc_); } while (0); |
858 | ASSERT_TRUE (example_b.intersects_line_p (3))do { const char *desc_ = "ASSERT_TRUE (" "(example_b.intersects_line_p (3))" ")"; bool actual_ = ((example_b.intersects_line_p (3))); if ( actual_) ::selftest::pass (((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 858, __FUNCTION__))), desc_); else ::selftest::fail (((::selftest ::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 858, __FUNCTION__))), desc_); } while (0); |
859 | ASSERT_TRUE (example_b.intersects_line_p (4))do { const char *desc_ = "ASSERT_TRUE (" "(example_b.intersects_line_p (4))" ")"; bool actual_ = ((example_b.intersects_line_p (4))); if ( actual_) ::selftest::pass (((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 859, __FUNCTION__))), desc_); else ::selftest::fail (((::selftest ::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 859, __FUNCTION__))), desc_); } while (0); |
860 | ASSERT_TRUE (example_b.intersects_line_p (5))do { const char *desc_ = "ASSERT_TRUE (" "(example_b.intersects_line_p (5))" ")"; bool actual_ = ((example_b.intersects_line_p (5))); if ( actual_) ::selftest::pass (((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 860, __FUNCTION__))), desc_); else ::selftest::fail (((::selftest ::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 860, __FUNCTION__))), desc_); } while (0); |
861 | ASSERT_FALSE (example_b.intersects_line_p (6))do { const char *desc_ = "ASSERT_FALSE (" "(example_b.intersects_line_p (6))" ")"; bool actual_ = ((example_b.intersects_line_p (6))); if ( actual_) ::selftest::fail (((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 861, __FUNCTION__))), desc_); else ::selftest::pass (((::selftest ::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 861, __FUNCTION__))), desc_); } while (0); |
862 | } |
863 | |
864 | #endif /* #if CHECKING_P */ |
865 | |
866 | /* Given a source line LINE of length LINE_BYTES bytes, determine the length |
867 | (still in bytes, not display cols) without any trailing whitespace. */ |
868 | |
869 | static int |
870 | get_line_bytes_without_trailing_whitespace (const char *line, int line_bytes) |
871 | { |
872 | int result = line_bytes; |
873 | while (result > 0) |
874 | { |
875 | char ch = line[result - 1]; |
876 | if (ch == ' ' || ch == '\t' || ch == '\r') |
877 | result--; |
878 | else |
879 | break; |
880 | } |
881 | gcc_assert (result >= 0)((void)(!(result >= 0) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 881, __FUNCTION__), 0 : 0)); |
882 | gcc_assert (result <= line_bytes)((void)(!(result <= line_bytes) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 882, __FUNCTION__), 0 : 0)); |
883 | gcc_assert (result == 0 ||((void)(!(result == 0 || (line[result - 1] != ' ' && line [result -1] != '\t' && line[result -1] != '\r')) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 886, __FUNCTION__), 0 : 0)) |
884 | (line[result - 1] != ' '((void)(!(result == 0 || (line[result - 1] != ' ' && line [result -1] != '\t' && line[result -1] != '\r')) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 886, __FUNCTION__), 0 : 0)) |
885 | && line[result -1] != '\t'((void)(!(result == 0 || (line[result - 1] != ' ' && line [result -1] != '\t' && line[result -1] != '\r')) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 886, __FUNCTION__), 0 : 0)) |
886 | && line[result -1] != '\r'))((void)(!(result == 0 || (line[result - 1] != ' ' && line [result -1] != '\t' && line[result -1] != '\r')) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 886, __FUNCTION__), 0 : 0)); |
887 | return result; |
888 | } |
889 | |
890 | #if CHECKING_P1 |
891 | |
892 | /* A helper function for testing get_line_bytes_without_trailing_whitespace. */ |
893 | |
894 | static void |
895 | assert_eq (const char *line, int expected_bytes) |
896 | { |
897 | int actual_value |
898 | = get_line_bytes_without_trailing_whitespace (line, strlen (line)); |
899 | ASSERT_EQ (actual_value, expected_bytes)do { const char *desc_ = "ASSERT_EQ (" "(actual_value)" ", " "(expected_bytes)" ")"; if (((actual_value)) == ((expected_bytes))) ::selftest:: pass ((((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 899, __FUNCTION__)))), desc_); else ::selftest::fail ((((:: selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 899, __FUNCTION__)))), desc_); } while (0); |
900 | } |
901 | |
902 | /* Verify that get_line_bytes_without_trailing_whitespace is sane for |
903 | various inputs. It is not required to handle newlines. */ |
904 | |
905 | static void |
906 | test_get_line_bytes_without_trailing_whitespace () |
907 | { |
908 | assert_eq ("", 0); |
909 | assert_eq (" ", 0); |
910 | assert_eq ("\t", 0); |
911 | assert_eq ("\r", 0); |
912 | assert_eq ("hello world", 11); |
913 | assert_eq ("hello world ", 11); |
914 | assert_eq ("hello world \t\t ", 11); |
915 | assert_eq ("hello world\r", 11); |
916 | } |
917 | |
918 | #endif /* #if CHECKING_P */ |
919 | |
920 | /* Helper function for layout's ctor, for sanitizing locations relative |
921 | to the primary location within a diagnostic. |
922 | |
923 | Compare LOC_A and LOC_B to see if it makes sense to print underlines |
924 | connecting their expanded locations. Doing so is only guaranteed to |
925 | make sense if the locations share the same macro expansion "history" |
926 | i.e. they can be traced through the same macro expansions, eventually |
927 | reaching an ordinary map. |
928 | |
929 | This may be too strong a condition, but it effectively sanitizes |
930 | PR c++/70105, which has an example of printing an expression where the |
931 | final location of the expression is in a different macro, which |
932 | erroneously was leading to hundreds of lines of irrelevant source |
933 | being printed. */ |
934 | |
935 | static bool |
936 | compatible_locations_p (location_t loc_a, location_t loc_b) |
937 | { |
938 | if (IS_ADHOC_LOC (loc_a)) |
939 | loc_a = get_location_from_adhoc_loc (line_table, loc_a); |
940 | if (IS_ADHOC_LOC (loc_b)) |
941 | loc_b = get_location_from_adhoc_loc (line_table, loc_b); |
942 | |
943 | /* If either location is one of the special locations outside of a |
944 | linemap, they are only compatible if they are equal. */ |
945 | if (loc_a < RESERVED_LOCATION_COUNT |
946 | || loc_b < RESERVED_LOCATION_COUNT) |
947 | return loc_a == loc_b; |
948 | |
949 | const line_map *map_a = linemap_lookup (line_table, loc_a); |
950 | linemap_assert (map_a)do { if (! (map_a)) fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 950, __FUNCTION__); } while (0); |
951 | |
952 | const line_map *map_b = linemap_lookup (line_table, loc_b); |
953 | linemap_assert (map_b)do { if (! (map_b)) fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 953, __FUNCTION__); } while (0); |
954 | |
955 | /* Are they within the same map? */ |
956 | if (map_a == map_b) |
957 | { |
958 | /* Are both within the same macro expansion? */ |
959 | if (linemap_macro_expansion_map_p (map_a)) |
960 | { |
961 | /* If so, then they're only compatible if either both are |
962 | from the macro definition, or both from the macro arguments. */ |
963 | bool loc_a_from_defn |
964 | = linemap_location_from_macro_definition_p (line_table, loc_a); |
965 | bool loc_b_from_defn |
966 | = linemap_location_from_macro_definition_p (line_table, loc_b); |
967 | if (loc_a_from_defn != loc_b_from_defn) |
968 | return false; |
969 | |
970 | /* Expand each location towards the spelling location, and |
971 | recurse. */ |
972 | const line_map_macro *macro_map = linemap_check_macro (map_a); |
973 | location_t loc_a_toward_spelling |
974 | = linemap_macro_map_loc_unwind_toward_spelling (line_table, |
975 | macro_map, |
976 | loc_a); |
977 | location_t loc_b_toward_spelling |
978 | = linemap_macro_map_loc_unwind_toward_spelling (line_table, |
979 | macro_map, |
980 | loc_b); |
981 | return compatible_locations_p (loc_a_toward_spelling, |
982 | loc_b_toward_spelling); |
983 | } |
984 | |
985 | /* Otherwise they are within the same ordinary map. */ |
986 | return true; |
987 | } |
988 | else |
989 | { |
990 | /* Within different maps. */ |
991 | |
992 | /* If either is within a macro expansion, they are incompatible. */ |
993 | if (linemap_macro_expansion_map_p (map_a) |
994 | || linemap_macro_expansion_map_p (map_b)) |
995 | return false; |
996 | |
997 | /* Within two different ordinary maps; they are compatible iff they |
998 | are in the same file. */ |
999 | const line_map_ordinary *ord_map_a = linemap_check_ordinary (map_a); |
1000 | const line_map_ordinary *ord_map_b = linemap_check_ordinary (map_b); |
1001 | return ord_map_a->to_file == ord_map_b->to_file; |
1002 | } |
1003 | } |
1004 | |
1005 | /* Comparator for sorting fix-it hints. */ |
1006 | |
1007 | static int |
1008 | fixit_cmp (const void *p_a, const void *p_b) |
1009 | { |
1010 | const fixit_hint * hint_a = *static_cast<const fixit_hint * const *> (p_a); |
1011 | const fixit_hint * hint_b = *static_cast<const fixit_hint * const *> (p_b); |
1012 | return hint_a->get_start_loc () - hint_b->get_start_loc (); |
1013 | } |
1014 | |
1015 | /* Callbacks for use when not escaping the source. */ |
1016 | |
1017 | /* The default callback for char_column_policy::m_width_cb is cpp_wcwidth. */ |
1018 | |
1019 | /* Callback for char_display_policy::m_print_cb for printing source chars |
1020 | when not escaping the source. */ |
1021 | |
1022 | static void |
1023 | default_print_decoded_ch (pretty_printer *pp, |
1024 | const cpp_decoded_char &decoded_ch) |
1025 | { |
1026 | for (const char *ptr = decoded_ch.m_start_byte; |
1027 | ptr != decoded_ch.m_next_byte; ptr++) |
1028 | { |
1029 | if (*ptr == '\0' || *ptr == '\r') |
1030 | { |
1031 | pp_space (pp)pp_character (pp, ' '); |
1032 | continue; |
1033 | } |
1034 | |
1035 | pp_character (pp, *ptr); |
1036 | } |
1037 | } |
1038 | |
1039 | /* Callbacks for use with DIAGNOSTICS_ESCAPE_FORMAT_BYTES. */ |
1040 | |
1041 | static const int width_per_escaped_byte = 4; |
1042 | |
1043 | /* Callback for char_column_policy::m_width_cb for determining the |
1044 | display width when escaping with DIAGNOSTICS_ESCAPE_FORMAT_BYTES. */ |
1045 | |
1046 | static int |
1047 | escape_as_bytes_width (cppchar_t ch) |
1048 | { |
1049 | if (ch < 0x80 && ISPRINT (ch)(_sch_istable[(ch) & 0xff] & (unsigned short)(_sch_isprint ))) |
1050 | return cpp_wcwidth (ch); |
1051 | else |
1052 | { |
1053 | if (ch <= 0x7F) return 1 * width_per_escaped_byte; |
1054 | if (ch <= 0x7FF) return 2 * width_per_escaped_byte; |
1055 | if (ch <= 0xFFFF) return 3 * width_per_escaped_byte; |
1056 | return 4 * width_per_escaped_byte; |
1057 | } |
1058 | } |
1059 | |
1060 | /* Callback for char_display_policy::m_print_cb for printing source chars |
1061 | when escaping with DIAGNOSTICS_ESCAPE_FORMAT_BYTES. */ |
1062 | |
1063 | static void |
1064 | escape_as_bytes_print (pretty_printer *pp, |
1065 | const cpp_decoded_char &decoded_ch) |
1066 | { |
1067 | if (!decoded_ch.m_valid_ch) |
1068 | { |
1069 | for (const char *iter = decoded_ch.m_start_byte; |
1070 | iter != decoded_ch.m_next_byte; ++iter) |
1071 | { |
1072 | char buf[16]; |
1073 | sprintf (buf, "<%02x>", (unsigned char)*iter); |
1074 | pp_string (pp, buf); |
1075 | } |
1076 | return; |
1077 | } |
1078 | |
1079 | cppchar_t ch = decoded_ch.m_ch; |
1080 | if (ch < 0x80 && ISPRINT (ch)(_sch_istable[(ch) & 0xff] & (unsigned short)(_sch_isprint ))) |
1081 | pp_character (pp, ch); |
1082 | else |
1083 | { |
1084 | for (const char *iter = decoded_ch.m_start_byte; |
1085 | iter < decoded_ch.m_next_byte; ++iter) |
1086 | { |
1087 | char buf[16]; |
1088 | sprintf (buf, "<%02x>", (unsigned char)*iter); |
1089 | pp_string (pp, buf); |
1090 | } |
1091 | } |
1092 | } |
1093 | |
1094 | /* Callbacks for use with DIAGNOSTICS_ESCAPE_FORMAT_UNICODE. */ |
1095 | |
1096 | /* Callback for char_column_policy::m_width_cb for determining the |
1097 | display width when escaping with DIAGNOSTICS_ESCAPE_FORMAT_UNICODE. */ |
1098 | |
1099 | static int |
1100 | escape_as_unicode_width (cppchar_t ch) |
1101 | { |
1102 | if (ch < 0x80 && ISPRINT (ch)(_sch_istable[(ch) & 0xff] & (unsigned short)(_sch_isprint ))) |
1103 | return cpp_wcwidth (ch); |
1104 | else |
1105 | { |
1106 | // Width of "<U+%04x>" |
1107 | if (ch > 0xfffff) |
1108 | return 10; |
1109 | else if (ch > 0xffff) |
1110 | return 9; |
1111 | else |
1112 | return 8; |
1113 | } |
1114 | } |
1115 | |
1116 | /* Callback for char_display_policy::m_print_cb for printing source chars |
1117 | when escaping with DIAGNOSTICS_ESCAPE_FORMAT_UNICODE. */ |
1118 | |
1119 | static void |
1120 | escape_as_unicode_print (pretty_printer *pp, |
1121 | const cpp_decoded_char &decoded_ch) |
1122 | { |
1123 | if (!decoded_ch.m_valid_ch) |
1124 | { |
1125 | escape_as_bytes_print (pp, decoded_ch); |
1126 | return; |
1127 | } |
1128 | |
1129 | cppchar_t ch = decoded_ch.m_ch; |
1130 | if (ch < 0x80 && ISPRINT (ch)(_sch_istable[(ch) & 0xff] & (unsigned short)(_sch_isprint ))) |
1131 | pp_character (pp, ch); |
1132 | else |
1133 | { |
1134 | char buf[16]; |
1135 | sprintf (buf, "<U+%04X>", ch); |
1136 | pp_string (pp, buf); |
1137 | } |
1138 | } |
1139 | |
1140 | /* Populate a char_display_policy based on DC and RICHLOC. */ |
1141 | |
1142 | static char_display_policy |
1143 | make_policy (const diagnostic_context &dc, |
1144 | const rich_location &richloc) |
1145 | { |
1146 | /* The default is to not escape non-ASCII bytes. */ |
1147 | char_display_policy result |
1148 | (dc.tabstop, cpp_wcwidth, default_print_decoded_ch); |
1149 | |
1150 | /* If the diagnostic suggests escaping non-ASCII bytes, then |
1151 | use policy from user-supplied options. */ |
1152 | if (richloc.escape_on_output_p ()) |
1153 | { |
1154 | result.m_undecoded_byte_width = width_per_escaped_byte; |
1155 | switch (dc.escape_format) |
1156 | { |
1157 | default: |
1158 | gcc_unreachable ()(fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 1158, __FUNCTION__)); |
1159 | case DIAGNOSTICS_ESCAPE_FORMAT_UNICODE: |
1160 | result.m_width_cb = escape_as_unicode_width; |
1161 | result.m_print_cb = escape_as_unicode_print; |
1162 | break; |
1163 | case DIAGNOSTICS_ESCAPE_FORMAT_BYTES: |
1164 | result.m_width_cb = escape_as_bytes_width; |
1165 | result.m_print_cb = escape_as_bytes_print; |
1166 | break; |
1167 | } |
1168 | } |
1169 | |
1170 | return result; |
1171 | } |
1172 | |
1173 | /* Implementation of class layout. */ |
1174 | |
1175 | /* Constructor for class layout. |
1176 | |
1177 | Filter the ranges from the rich_location to those that we can |
1178 | sanely print, populating m_layout_ranges and m_fixit_hints. |
1179 | Determine the range of lines that we will print, splitting them |
1180 | up into an ordered list of disjoint spans of contiguous line numbers. |
1181 | Determine m_x_offset_display, to ensure that the primary caret |
1182 | will fit within the max_width provided by the diagnostic_context. */ |
1183 | |
1184 | layout::layout (diagnostic_context * context, |
1185 | rich_location *richloc, |
1186 | diagnostic_t diagnostic_kind) |
1187 | : m_context (context), |
1188 | m_pp (context->printer), |
1189 | m_policy (make_policy (*context, *richloc)), |
1190 | m_primary_loc (richloc->get_range (0)->m_loc), |
1191 | m_exploc (richloc->get_expanded_location (0), m_policy, |
1192 | LOCATION_ASPECT_CARET), |
1193 | m_colorizer (context, diagnostic_kind), |
1194 | m_colorize_source_p (context->colorize_source_p), |
1195 | m_show_labels_p (context->show_labels_p), |
1196 | m_show_line_numbers_p (context->show_line_numbers_p), |
1197 | m_diagnostic_path_p (diagnostic_kind == DK_DIAGNOSTIC_PATH), |
1198 | m_layout_ranges (richloc->get_num_locations ()), |
1199 | m_fixit_hints (richloc->get_num_fixit_hints ()), |
1200 | m_line_spans (1 + richloc->get_num_locations ()), |
1201 | m_linenum_width (0), |
1202 | m_x_offset_display (0), |
1203 | m_escape_on_output (richloc->escape_on_output_p ()) |
1204 | { |
1205 | for (unsigned int idx = 0; idx < richloc->get_num_locations (); idx++) |
1206 | { |
1207 | /* This diagnostic printer can only cope with "sufficiently sane" ranges. |
1208 | Ignore any ranges that are awkward to handle. */ |
1209 | const location_range *loc_range = richloc->get_range (idx); |
1210 | maybe_add_location_range (loc_range, idx, false); |
1211 | } |
1212 | |
1213 | /* Populate m_fixit_hints, filtering to only those that are in the |
1214 | same file. */ |
1215 | for (unsigned int i = 0; i < richloc->get_num_fixit_hints (); i++) |
1216 | { |
1217 | const fixit_hint *hint = richloc->get_fixit_hint (i); |
1218 | if (validate_fixit_hint_p (hint)) |
1219 | m_fixit_hints.safe_push (hint); |
1220 | } |
1221 | |
1222 | /* Sort m_fixit_hints. */ |
1223 | m_fixit_hints.qsort (fixit_cmp)qsort (fixit_cmp); |
1224 | |
1225 | /* Populate the indicated members. */ |
1226 | calculate_line_spans (); |
1227 | calculate_linenum_width (); |
1228 | calculate_x_offset_display (); |
1229 | |
1230 | if (context->show_ruler_p) |
1231 | show_ruler (m_x_offset_display + m_context->caret_max_width); |
1232 | } |
1233 | |
1234 | |
1235 | /* Attempt to add LOC_RANGE to m_layout_ranges, filtering them to |
1236 | those that we can sanely print. |
1237 | |
1238 | ORIGINAL_IDX is the index of LOC_RANGE within its rich_location, |
1239 | (for use as extrinsic state by label ranges FIXME). |
1240 | |
1241 | If RESTRICT_TO_CURRENT_LINE_SPANS is true, then LOC_RANGE is also |
1242 | filtered against this layout instance's current line spans: it |
1243 | will only be added if the location is fully within the lines |
1244 | already specified by other locations. |
1245 | |
1246 | Return true iff LOC_RANGE was added. */ |
1247 | |
1248 | bool |
1249 | layout::maybe_add_location_range (const location_range *loc_range, |
1250 | unsigned original_idx, |
1251 | bool restrict_to_current_line_spans) |
1252 | { |
1253 | gcc_assert (loc_range)((void)(!(loc_range) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 1253, __FUNCTION__), 0 : 0)); |
1254 | |
1255 | /* Split the "range" into caret and range information. */ |
1256 | source_range src_range = get_range_from_loc (line_table, loc_range->m_loc); |
1257 | |
1258 | /* Expand the various locations. */ |
1259 | expanded_location start |
1260 | = linemap_client_expand_location_to_spelling_point |
1261 | (src_range.m_start, LOCATION_ASPECT_START); |
1262 | expanded_location finish |
1263 | = linemap_client_expand_location_to_spelling_point |
1264 | (src_range.m_finish, LOCATION_ASPECT_FINISH); |
1265 | expanded_location caret |
1266 | = linemap_client_expand_location_to_spelling_point |
1267 | (loc_range->m_loc, LOCATION_ASPECT_CARET); |
1268 | |
1269 | /* If any part of the range isn't in the same file as the primary |
1270 | location of this diagnostic, ignore the range. */ |
1271 | if (start.file != m_exploc.file) |
1272 | return false; |
1273 | if (finish.file != m_exploc.file) |
1274 | return false; |
1275 | if (loc_range->m_range_display_kind == SHOW_RANGE_WITH_CARET) |
1276 | if (caret.file != m_exploc.file) |
1277 | return false; |
1278 | |
1279 | /* Sanitize the caret location for non-primary ranges. */ |
1280 | if (m_layout_ranges.length () > 0) |
1281 | if (loc_range->m_range_display_kind == SHOW_RANGE_WITH_CARET) |
1282 | if (!compatible_locations_p (loc_range->m_loc, m_primary_loc)) |
1283 | /* Discard any non-primary ranges that can't be printed |
1284 | sanely relative to the primary location. */ |
1285 | return false; |
1286 | |
1287 | /* Everything is now known to be in the correct source file, |
1288 | but it may require further sanitization. */ |
1289 | layout_range ri (exploc_with_display_col (start, m_policy, |
1290 | LOCATION_ASPECT_START), |
1291 | exploc_with_display_col (finish, m_policy, |
1292 | LOCATION_ASPECT_FINISH), |
1293 | loc_range->m_range_display_kind, |
1294 | exploc_with_display_col (caret, m_policy, |
1295 | LOCATION_ASPECT_CARET), |
1296 | original_idx, loc_range->m_label); |
1297 | |
1298 | /* If we have a range that finishes before it starts (perhaps |
1299 | from something built via macro expansion), printing the |
1300 | range is likely to be nonsensical. Also, attempting to do so |
1301 | breaks assumptions within the printing code (PR c/68473). |
1302 | Similarly, don't attempt to print ranges if one or both ends |
1303 | of the range aren't sane to print relative to the |
1304 | primary location (PR c++/70105). */ |
1305 | if (start.line > finish.line |
1306 | || !compatible_locations_p (src_range.m_start, m_primary_loc) |
1307 | || !compatible_locations_p (src_range.m_finish, m_primary_loc)) |
1308 | { |
1309 | /* Is this the primary location? */ |
1310 | if (m_layout_ranges.length () == 0) |
1311 | { |
1312 | /* We want to print the caret for the primary location, but |
1313 | we must sanitize away m_start and m_finish. */ |
1314 | ri.m_start = ri.m_caret; |
1315 | ri.m_finish = ri.m_caret; |
1316 | } |
1317 | else |
1318 | /* This is a non-primary range; ignore it. */ |
1319 | return false; |
1320 | } |
1321 | |
1322 | /* Potentially filter to just the lines already specified by other |
1323 | locations. This is for use by gcc_rich_location::add_location_if_nearby. |
1324 | The layout ctor doesn't use it, and can't because m_line_spans |
1325 | hasn't been set up at that point. */ |
1326 | if (restrict_to_current_line_spans) |
1327 | { |
1328 | if (!will_show_line_p (start.line)) |
1329 | return false; |
1330 | if (!will_show_line_p (finish.line)) |
1331 | return false; |
1332 | if (loc_range->m_range_display_kind == SHOW_RANGE_WITH_CARET) |
1333 | if (!will_show_line_p (caret.line)) |
1334 | return false; |
1335 | } |
1336 | |
1337 | /* Passed all the tests; add the range to m_layout_ranges so that |
1338 | it will be printed. */ |
1339 | m_layout_ranges.safe_push (ri); |
1340 | return true; |
1341 | } |
1342 | |
1343 | /* Return true iff ROW is within one of the line spans for this layout. */ |
1344 | |
1345 | bool |
1346 | layout::will_show_line_p (linenum_type row) const |
1347 | { |
1348 | for (int line_span_idx = 0; line_span_idx < get_num_line_spans (); |
1349 | line_span_idx++) |
1350 | { |
1351 | const line_span *line_span = get_line_span (line_span_idx); |
1352 | if (line_span->contains_line_p (row)) |
1353 | return true; |
1354 | } |
1355 | return false; |
1356 | } |
1357 | |
1358 | /* Print a line showing a gap in the line numbers, for showing the boundary |
1359 | between two line spans. */ |
1360 | |
1361 | void |
1362 | layout::print_gap_in_line_numbering () |
1363 | { |
1364 | gcc_assert (m_show_line_numbers_p)((void)(!(m_show_line_numbers_p) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 1364, __FUNCTION__), 0 : 0)); |
1365 | |
1366 | pp_emit_prefix (m_pp); |
1367 | |
1368 | for (int i = 0; i < m_linenum_width + 1; i++) |
1369 | pp_character (m_pp, '.'); |
1370 | |
1371 | pp_newline (m_pp); |
1372 | } |
1373 | |
1374 | /* Return true iff we should print a heading when starting the |
1375 | line span with the given index. */ |
1376 | |
1377 | bool |
1378 | layout::print_heading_for_line_span_index_p (int line_span_idx) const |
1379 | { |
1380 | /* We print a heading for every change of line span, hence for every |
1381 | line span after the initial one. */ |
1382 | if (line_span_idx > 0) |
1383 | return true; |
1384 | |
1385 | /* We also do it for the initial span if the primary location of the |
1386 | diagnostic is in a different span. */ |
1387 | if (m_exploc.line > (int)get_line_span (0)->m_last_line) |
1388 | return true; |
1389 | |
1390 | return false; |
1391 | } |
1392 | |
1393 | /* Get an expanded_location for the first location of interest within |
1394 | the given line_span. |
1395 | Used when printing a heading to indicate a new line span. */ |
1396 | |
1397 | expanded_location |
1398 | layout::get_expanded_location (const line_span *line_span) const |
1399 | { |
1400 | /* Whenever possible, use the caret location. */ |
1401 | if (line_span->contains_line_p (m_exploc.line)) |
1402 | return m_exploc; |
1403 | |
1404 | /* Otherwise, use the start of the first range that's present |
1405 | within the line_span. */ |
1406 | for (unsigned int i = 0; i < m_layout_ranges.length (); i++) |
1407 | { |
1408 | const layout_range *lr = &m_layout_ranges[i]; |
1409 | if (line_span->contains_line_p (lr->m_start.m_line)) |
1410 | { |
1411 | expanded_location exploc = m_exploc; |
1412 | exploc.line = lr->m_start.m_line; |
1413 | exploc.column = lr->m_start.m_columns[CU_BYTES]; |
1414 | return exploc; |
1415 | } |
1416 | } |
1417 | |
1418 | /* Otherwise, use the location of the first fixit-hint present within |
1419 | the line_span. */ |
1420 | for (unsigned int i = 0; i < m_fixit_hints.length (); i++) |
1421 | { |
1422 | const fixit_hint *hint = m_fixit_hints[i]; |
1423 | location_t loc = hint->get_start_loc (); |
1424 | expanded_location exploc = expand_location (loc); |
1425 | if (line_span->contains_line_p (exploc.line)) |
1426 | return exploc; |
1427 | } |
1428 | |
1429 | /* It should not be possible to have a line span that didn't |
1430 | contain any of the layout_range or fixit_hint instances. */ |
1431 | gcc_unreachable ()(fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 1431, __FUNCTION__)); |
1432 | return m_exploc; |
1433 | } |
1434 | |
1435 | /* Determine if HINT is meaningful to print within this layout. */ |
1436 | |
1437 | bool |
1438 | layout::validate_fixit_hint_p (const fixit_hint *hint) |
1439 | { |
1440 | if (LOCATION_FILE (hint->get_start_loc ())((expand_location (hint->get_start_loc ())).file) != m_exploc.file) |
1441 | return false; |
1442 | if (LOCATION_FILE (hint->get_next_loc ())((expand_location (hint->get_next_loc ())).file) != m_exploc.file) |
1443 | return false; |
1444 | |
1445 | return true; |
1446 | } |
1447 | |
1448 | /* Determine the range of lines affected by HINT. |
1449 | This assumes that HINT has already been filtered by |
1450 | validate_fixit_hint_p, and so affects the correct source file. */ |
1451 | |
1452 | static line_span |
1453 | get_line_span_for_fixit_hint (const fixit_hint *hint) |
1454 | { |
1455 | gcc_assert (hint)((void)(!(hint) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 1455, __FUNCTION__), 0 : 0)); |
1456 | |
1457 | int start_line = LOCATION_LINE (hint->get_start_loc ())((expand_location (hint->get_start_loc ())).line); |
1458 | |
1459 | /* For line-insertion fix-it hints, add the previous line to the |
1460 | span, to give the user more context on the proposed change. */ |
1461 | if (hint->ends_with_newline_p ()) |
1462 | if (start_line > 1) |
1463 | start_line--; |
1464 | |
1465 | return line_span (start_line, |
1466 | LOCATION_LINE (hint->get_next_loc ())((expand_location (hint->get_next_loc ())).line)); |
1467 | } |
1468 | |
1469 | /* We want to print the pertinent source code at a diagnostic. The |
1470 | rich_location can contain multiple locations. This will have been |
1471 | filtered into m_exploc (the caret for the primary location) and |
1472 | m_layout_ranges, for those ranges within the same source file. |
1473 | |
1474 | We will print a subset of the lines within the source file in question, |
1475 | as a collection of "spans" of lines. |
1476 | |
1477 | This function populates m_line_spans with an ordered, disjoint list of |
1478 | the line spans of interest. |
1479 | |
1480 | Printing a gap between line spans takes one line, so, when printing |
1481 | line numbers, we allow a gap of up to one line between spans when |
1482 | merging, since it makes more sense to print the source line rather than a |
1483 | "gap-in-line-numbering" line. When not printing line numbers, it's |
1484 | better to be more explicit about what's going on, so keeping them as |
1485 | separate spans is preferred. |
1486 | |
1487 | For example, if the primary range is on lines 8-10, with secondary ranges |
1488 | covering lines 5-6 and lines 13-15: |
1489 | |
1490 | 004 |
1491 | 005 |RANGE 1 |
1492 | 006 |RANGE 1 |
1493 | 007 |
1494 | 008 |PRIMARY RANGE |
1495 | 009 |PRIMARY CARET |
1496 | 010 |PRIMARY RANGE |
1497 | 011 |
1498 | 012 |
1499 | 013 |RANGE 2 |
1500 | 014 |RANGE 2 |
1501 | 015 |RANGE 2 |
1502 | 016 |
1503 | |
1504 | With line numbering on, we want two spans: lines 5-10 and lines 13-15. |
1505 | |
1506 | With line numbering off (with span headers), we want three spans: lines 5-6, |
1507 | lines 8-10, and lines 13-15. */ |
1508 | |
1509 | void |
1510 | layout::calculate_line_spans () |
1511 | { |
1512 | /* This should only be called once, by the ctor. */ |
1513 | gcc_assert (m_line_spans.length () == 0)((void)(!(m_line_spans.length () == 0) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 1513, __FUNCTION__), 0 : 0)); |
1514 | |
1515 | /* Populate tmp_spans with individual spans, for each of |
1516 | m_exploc, and for m_layout_ranges. */ |
1517 | auto_vec<line_span> tmp_spans (1 + m_layout_ranges.length ()); |
1518 | tmp_spans.safe_push (line_span (m_exploc.line, m_exploc.line)); |
1519 | for (unsigned int i = 0; i < m_layout_ranges.length (); i++) |
1520 | { |
1521 | const layout_range *lr = &m_layout_ranges[i]; |
1522 | gcc_assert (lr->m_start.m_line <= lr->m_finish.m_line)((void)(!(lr->m_start.m_line <= lr->m_finish.m_line) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 1522, __FUNCTION__), 0 : 0)); |
1523 | tmp_spans.safe_push (line_span (lr->m_start.m_line, |
1524 | lr->m_finish.m_line)); |
1525 | } |
1526 | |
1527 | /* Also add spans for any fix-it hints, in case they cover other lines. */ |
1528 | for (unsigned int i = 0; i < m_fixit_hints.length (); i++) |
1529 | { |
1530 | const fixit_hint *hint = m_fixit_hints[i]; |
1531 | gcc_assert (hint)((void)(!(hint) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 1531, __FUNCTION__), 0 : 0)); |
1532 | tmp_spans.safe_push (get_line_span_for_fixit_hint (hint)); |
1533 | } |
1534 | |
1535 | /* Sort them. */ |
1536 | tmp_spans.qsort(line_span::comparator)qsort (line_span::comparator); |
1537 | |
1538 | /* Now iterate through tmp_spans, copying into m_line_spans, and |
1539 | combining where possible. */ |
1540 | gcc_assert (tmp_spans.length () > 0)((void)(!(tmp_spans.length () > 0) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 1540, __FUNCTION__), 0 : 0)); |
1541 | m_line_spans.safe_push (tmp_spans[0]); |
1542 | for (unsigned int i = 1; i < tmp_spans.length (); i++) |
1543 | { |
1544 | line_span *current = &m_line_spans[m_line_spans.length () - 1]; |
1545 | const line_span *next = &tmp_spans[i]; |
1546 | gcc_assert (next->m_first_line >= current->m_first_line)((void)(!(next->m_first_line >= current->m_first_line ) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 1546, __FUNCTION__), 0 : 0)); |
1547 | const int merger_distance = m_show_line_numbers_p ? 1 : 0; |
1548 | if ((linenum_arith_t)next->m_first_line |
1549 | <= (linenum_arith_t)current->m_last_line + 1 + merger_distance) |
1550 | { |
1551 | /* We can merge them. */ |
1552 | if (next->m_last_line > current->m_last_line) |
1553 | current->m_last_line = next->m_last_line; |
1554 | } |
1555 | else |
1556 | { |
1557 | /* No merger possible. */ |
1558 | m_line_spans.safe_push (*next); |
1559 | } |
1560 | } |
1561 | |
1562 | /* Verify the result, in m_line_spans. */ |
1563 | gcc_assert (m_line_spans.length () > 0)((void)(!(m_line_spans.length () > 0) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 1563, __FUNCTION__), 0 : 0)); |
1564 | for (unsigned int i = 1; i < m_line_spans.length (); i++) |
1565 | { |
1566 | const line_span *prev = &m_line_spans[i - 1]; |
1567 | const line_span *next = &m_line_spans[i]; |
1568 | /* The individual spans must be sane. */ |
1569 | gcc_assert (prev->m_first_line <= prev->m_last_line)((void)(!(prev->m_first_line <= prev->m_last_line) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 1569, __FUNCTION__), 0 : 0)); |
1570 | gcc_assert (next->m_first_line <= next->m_last_line)((void)(!(next->m_first_line <= next->m_last_line) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 1570, __FUNCTION__), 0 : 0)); |
1571 | /* The spans must be ordered. */ |
1572 | gcc_assert (prev->m_first_line < next->m_first_line)((void)(!(prev->m_first_line < next->m_first_line) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 1572, __FUNCTION__), 0 : 0)); |
1573 | /* There must be a gap of at least one line between separate spans. */ |
1574 | gcc_assert ((prev->m_last_line + 1) < next->m_first_line)((void)(!((prev->m_last_line + 1) < next->m_first_line ) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 1574, __FUNCTION__), 0 : 0)); |
1575 | } |
1576 | } |
1577 | |
1578 | /* Determine how many display columns need to be reserved for line numbers, |
1579 | based on the largest line number that will be needed, and populate |
1580 | m_linenum_width. */ |
1581 | |
1582 | void |
1583 | layout::calculate_linenum_width () |
1584 | { |
1585 | gcc_assert (m_line_spans.length () > 0)((void)(!(m_line_spans.length () > 0) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 1585, __FUNCTION__), 0 : 0)); |
1586 | const line_span *last_span = &m_line_spans[m_line_spans.length () - 1]; |
1587 | int highest_line = last_span->m_last_line; |
1588 | if (highest_line < 0) |
1589 | highest_line = 0; |
1590 | m_linenum_width = num_digits (highest_line); |
1591 | /* If we're showing jumps in the line-numbering, allow at least 3 chars. */ |
1592 | if (m_line_spans.length () > 1) |
1593 | m_linenum_width = MAX (m_linenum_width, 3)((m_linenum_width) > (3) ? (m_linenum_width) : (3)); |
1594 | /* If there's a minimum margin width, apply it (subtracting 1 for the space |
1595 | after the line number. */ |
1596 | m_linenum_width = MAX (m_linenum_width, m_context->min_margin_width - 1)((m_linenum_width) > (m_context->min_margin_width - 1) ? (m_linenum_width) : (m_context->min_margin_width - 1)); |
1597 | } |
1598 | |
1599 | /* Calculate m_x_offset_display, which improves readability in case the source |
1600 | line of interest is longer than the user's display. All lines output will be |
1601 | shifted to the left (so that their beginning is no longer displayed) by |
1602 | m_x_offset_display display columns, so that the caret is in a reasonable |
1603 | location. */ |
1604 | |
1605 | void |
1606 | layout::calculate_x_offset_display () |
1607 | { |
1608 | m_x_offset_display = 0; |
1609 | |
1610 | const int max_width = m_context->caret_max_width; |
1611 | if (!max_width) |
1612 | { |
1613 | /* Nothing to do, the width is not capped. */ |
1614 | return; |
1615 | } |
1616 | |
1617 | const char_span line = location_get_source_line (m_exploc.file, |
1618 | m_exploc.line); |
1619 | if (!line) |
1620 | { |
1621 | /* Nothing to do, we couldn't find the source line. */ |
1622 | return; |
1623 | } |
1624 | int caret_display_column = m_exploc.m_display_col; |
1625 | const int line_bytes |
1626 | = get_line_bytes_without_trailing_whitespace (line.get_buffer (), |
1627 | line.length ()); |
1628 | int eol_display_column |
1629 | = cpp_display_width (line.get_buffer (), line_bytes, m_policy); |
1630 | if (caret_display_column > eol_display_column |
1631 | || !caret_display_column) |
1632 | { |
1633 | /* This does not make sense, so don't try to do anything in this case. */ |
1634 | return; |
1635 | } |
1636 | |
1637 | /* Adjust caret and eol positions to include the left margin. If we are |
1638 | outputting line numbers, then the left margin is equal to m_linenum_width |
1639 | plus three for the " | " which follows it. Otherwise the left margin width |
1640 | is equal to 1, because layout::print_source_line() will prefix each line |
1641 | with a space. */ |
1642 | const int source_display_cols = eol_display_column; |
1643 | int left_margin_size = 1; |
1644 | if (m_show_line_numbers_p) |
1645 | left_margin_size = m_linenum_width + 3; |
1646 | caret_display_column += left_margin_size; |
1647 | eol_display_column += left_margin_size; |
1648 | |
1649 | if (eol_display_column <= max_width) |
1650 | { |
1651 | /* Nothing to do, everything fits in the display. */ |
1652 | return; |
1653 | } |
1654 | |
1655 | /* The line is too long for the display. Calculate an offset such that the |
1656 | caret is not too close to the right edge of the screen. It will be |
1657 | CARET_LINE_MARGIN display columns from the right edge, unless it is closer |
1658 | than that to the end of the source line anyway. */ |
1659 | int right_margin_size = CARET_LINE_MARGIN; |
1660 | right_margin_size = MIN (eol_display_column - caret_display_column,((eol_display_column - caret_display_column) < (right_margin_size ) ? (eol_display_column - caret_display_column) : (right_margin_size )) |
1661 | right_margin_size)((eol_display_column - caret_display_column) < (right_margin_size ) ? (eol_display_column - caret_display_column) : (right_margin_size )); |
1662 | if (right_margin_size + left_margin_size >= max_width) |
1663 | { |
1664 | /* The max_width is very small, so anything we try to do will not be very |
1665 | effective; just punt in this case and output with no offset. */ |
1666 | return; |
1667 | } |
1668 | const int max_caret_display_column = max_width - right_margin_size; |
1669 | if (caret_display_column > max_caret_display_column) |
1670 | { |
1671 | m_x_offset_display = caret_display_column - max_caret_display_column; |
1672 | /* Make sure we don't offset the line into oblivion. */ |
1673 | static const int min_cols_visible = 2; |
1674 | if (source_display_cols - m_x_offset_display < min_cols_visible) |
1675 | m_x_offset_display = 0; |
1676 | } |
1677 | } |
1678 | |
1679 | /* Print line ROW of source code, potentially colorized at any ranges, and |
1680 | return the line bounds. LINE is the source line (not necessarily |
1681 | 0-terminated) and LINE_BYTES is its length in bytes. In order to handle both |
1682 | colorization and tab expansion, this function tracks the line position in |
1683 | both byte and display column units. */ |
1684 | |
1685 | line_bounds |
1686 | layout::print_source_line (linenum_type row, const char *line, int line_bytes) |
1687 | { |
1688 | m_colorizer.set_normal_text (); |
1689 | |
1690 | pp_emit_prefix (m_pp); |
1691 | if (m_show_line_numbers_p) |
1692 | { |
1693 | int width = num_digits (row); |
1694 | for (int i = 0; i < m_linenum_width - width; i++) |
1695 | pp_space (m_pp)pp_character (m_pp, ' '); |
1696 | pp_printf (m_pp, "%i | ", row); |
1697 | } |
1698 | else |
1699 | pp_space (m_pp)pp_character (m_pp, ' '); |
1700 | |
1701 | /* We will stop printing the source line at any trailing whitespace. */ |
1702 | line_bytes = get_line_bytes_without_trailing_whitespace (line, |
1703 | line_bytes); |
1704 | |
1705 | /* This object helps to keep track of which display column we are at, which is |
1706 | necessary for computing the line bounds in display units, for doing |
1707 | tab expansion, and for implementing m_x_offset_display. */ |
1708 | cpp_display_width_computation dw (line, line_bytes, m_policy); |
1709 | |
1710 | /* Skip the first m_x_offset_display display columns. In case the leading |
1711 | portion that will be skipped ends with a character with wcwidth > 1, then |
1712 | it is possible we skipped too much, so account for that by padding with |
1713 | spaces. Note that this does the right thing too in case a tab was the last |
1714 | character to be skipped over; the tab is effectively replaced by the |
1715 | correct number of trailing spaces needed to offset by the desired number of |
1716 | display columns. */ |
1717 | for (int skipped_display_cols = dw.advance_display_cols (m_x_offset_display); |
1718 | skipped_display_cols > m_x_offset_display; --skipped_display_cols) |
1719 | pp_space (m_pp)pp_character (m_pp, ' '); |
1720 | |
1721 | /* Print the line and compute the line_bounds. */ |
1722 | line_bounds lbounds; |
1723 | while (!dw.done ()) |
1724 | { |
1725 | /* Assuming colorization is enabled for the caret and underline |
1726 | characters, we may also colorize the associated characters |
1727 | within the source line. |
1728 | |
1729 | For frontends that generate range information, we color the |
1730 | associated characters in the source line the same as the |
1731 | carets and underlines in the annotation line, to make it easier |
1732 | for the reader to see the pertinent code. |
1733 | |
1734 | For frontends that only generate carets, we don't colorize the |
1735 | characters above them, since this would look strange (e.g. |
1736 | colorizing just the first character in a token). */ |
1737 | if (m_colorize_source_p) |
1738 | { |
1739 | bool in_range_p; |
1740 | point_state state; |
1741 | const int start_byte_col = dw.bytes_processed () + 1; |
1742 | in_range_p = get_state_at_point (row, start_byte_col, |
1743 | 0, INT_MAX2147483647, |
1744 | CU_BYTES, |
1745 | &state); |
1746 | if (in_range_p) |
1747 | m_colorizer.set_range (state.range_idx); |
1748 | else |
1749 | m_colorizer.set_normal_text (); |
1750 | } |
1751 | |
1752 | /* Get the display width of the next character to be output, expanding |
1753 | tabs and replacing some control bytes with spaces as necessary. */ |
1754 | const char *c = dw.next_byte (); |
1755 | const int start_disp_col = dw.display_cols_processed () + 1; |
1756 | cpp_decoded_char cp; |
1757 | const int this_display_width = dw.process_next_codepoint (&cp); |
1758 | if (*c == '\t') |
1759 | { |
1760 | /* The returned display width is the number of spaces into which the |
1761 | tab should be expanded. */ |
1762 | for (int i = 0; i != this_display_width; ++i) |
1763 | pp_space (m_pp)pp_character (m_pp, ' '); |
1764 | continue; |
1765 | } |
1766 | |
1767 | /* We have a (possibly multibyte) character to output; update the line |
1768 | bounds if it is not whitespace. */ |
1769 | if (*c != ' ') |
1770 | { |
1771 | lbounds.m_last_non_ws_disp_col = dw.display_cols_processed (); |
1772 | if (lbounds.m_first_non_ws_disp_col == INT_MAX2147483647) |
1773 | lbounds.m_first_non_ws_disp_col = start_disp_col; |
1774 | } |
1775 | |
1776 | /* Output the character. */ |
1777 | m_policy.m_print_cb (m_pp, cp); |
1778 | c = dw.next_byte (); |
Value stored to 'c' is never read | |
1779 | } |
1780 | print_newline (); |
1781 | return lbounds; |
1782 | } |
1783 | |
1784 | /* Determine if we should print an annotation line for ROW. |
1785 | i.e. if any of m_layout_ranges contains ROW. */ |
1786 | |
1787 | bool |
1788 | layout::should_print_annotation_line_p (linenum_type row) const |
1789 | { |
1790 | layout_range *range; |
1791 | int i; |
1792 | FOR_EACH_VEC_ELT (m_layout_ranges, i, range)for (i = 0; (m_layout_ranges).iterate ((i), &(range)); ++ (i)) |
1793 | { |
1794 | if (range->m_range_display_kind == SHOW_LINES_WITHOUT_RANGE) |
1795 | return false; |
1796 | if (range->intersects_line_p (row)) |
1797 | return true; |
1798 | } |
1799 | return false; |
1800 | } |
1801 | |
1802 | /* Begin an annotation line. If m_show_line_numbers_p, print the left |
1803 | margin, which is empty for annotation lines. Otherwise, do nothing. */ |
1804 | |
1805 | void |
1806 | layout::start_annotation_line (char margin_char) const |
1807 | { |
1808 | pp_emit_prefix (m_pp); |
1809 | if (m_show_line_numbers_p) |
1810 | { |
1811 | /* Print the margin. If MARGIN_CHAR != ' ', then print up to 3 |
1812 | of it, right-aligned, padded with spaces. */ |
1813 | int i; |
1814 | for (i = 0; i < m_linenum_width - 3; i++) |
1815 | pp_space (m_pp)pp_character (m_pp, ' '); |
1816 | for (; i < m_linenum_width; i++) |
1817 | pp_character (m_pp, margin_char); |
1818 | pp_string (m_pp, " |"); |
1819 | } |
1820 | } |
1821 | |
1822 | /* Print a line consisting of the caret/underlines for the given |
1823 | source line. */ |
1824 | |
1825 | void |
1826 | layout::print_annotation_line (linenum_type row, const line_bounds lbounds) |
1827 | { |
1828 | int x_bound = get_x_bound_for_row (row, m_exploc.m_display_col, |
1829 | lbounds.m_last_non_ws_disp_col); |
1830 | |
1831 | start_annotation_line (); |
1832 | pp_space (m_pp)pp_character (m_pp, ' '); |
1833 | |
1834 | for (int column = 1 + m_x_offset_display; column < x_bound; column++) |
1835 | { |
1836 | bool in_range_p; |
1837 | point_state state; |
1838 | in_range_p = get_state_at_point (row, column, |
1839 | lbounds.m_first_non_ws_disp_col, |
1840 | lbounds.m_last_non_ws_disp_col, |
1841 | CU_DISPLAY_COLS, |
1842 | &state); |
1843 | if (in_range_p) |
1844 | { |
1845 | /* Within a range. Draw either the caret or an underline. */ |
1846 | m_colorizer.set_range (state.range_idx); |
1847 | if (state.draw_caret_p) |
1848 | { |
1849 | /* Draw the caret. */ |
1850 | char caret_char; |
1851 | if (state.range_idx < rich_location::STATICALLY_ALLOCATED_RANGES) |
1852 | caret_char = m_context->caret_chars[state.range_idx]; |
1853 | else |
1854 | caret_char = '^'; |
1855 | pp_character (m_pp, caret_char); |
1856 | } |
1857 | else |
1858 | pp_character (m_pp, '~'); |
1859 | } |
1860 | else |
1861 | { |
1862 | /* Not in a range. */ |
1863 | m_colorizer.set_normal_text (); |
1864 | pp_character (m_pp, ' '); |
1865 | } |
1866 | } |
1867 | print_newline (); |
1868 | } |
1869 | |
1870 | /* A version of label_text that can live inside a vec. |
1871 | Requires manual cleanup via maybe_free. */ |
1872 | |
1873 | struct pod_label_text |
1874 | { |
1875 | pod_label_text () |
1876 | : m_buffer (NULL__null), m_caller_owned (false) |
1877 | {} |
1878 | |
1879 | pod_label_text (label_text &&other) |
1880 | : m_buffer (const_cast<char*> (other.get ())), |
1881 | m_caller_owned (other.is_owner ()) |
1882 | { |
1883 | other.release (); |
1884 | } |
1885 | |
1886 | void maybe_free () |
1887 | { |
1888 | if (m_caller_owned) |
1889 | free (m_buffer); |
1890 | } |
1891 | |
1892 | char *m_buffer; |
1893 | bool m_caller_owned; |
1894 | }; |
1895 | |
1896 | /* Implementation detail of layout::print_any_labels. |
1897 | |
1898 | A label within the given row of source. */ |
1899 | |
1900 | class line_label |
1901 | { |
1902 | public: |
1903 | line_label (const cpp_char_column_policy &policy, |
1904 | int state_idx, int column, |
1905 | label_text text) |
1906 | : m_state_idx (state_idx), m_column (column), |
1907 | m_text (std::move (text)), m_label_line (0), m_has_vbar (true) |
1908 | { |
1909 | const int bytes = strlen (m_text.m_buffer); |
1910 | m_display_width = cpp_display_width (m_text.m_buffer, bytes, policy); |
1911 | } |
1912 | |
1913 | /* Sorting is primarily by column, then by state index. */ |
1914 | static int comparator (const void *p1, const void *p2) |
1915 | { |
1916 | const line_label *ll1 = (const line_label *)p1; |
1917 | const line_label *ll2 = (const line_label *)p2; |
1918 | int column_cmp = compare (ll1->m_column, ll2->m_column); |
1919 | if (column_cmp) |
1920 | return column_cmp; |
1921 | /* Order by reverse state index, so that labels are printed |
1922 | in order of insertion into the rich_location when the |
1923 | sorted list is walked backwards. */ |
1924 | return -compare (ll1->m_state_idx, ll2->m_state_idx); |
1925 | } |
1926 | |
1927 | int m_state_idx; |
1928 | int m_column; |
1929 | pod_label_text m_text; |
1930 | size_t m_display_width; |
1931 | int m_label_line; |
1932 | bool m_has_vbar; |
1933 | }; |
1934 | |
1935 | /* Print any labels in this row. */ |
1936 | void |
1937 | layout::print_any_labels (linenum_type row) |
1938 | { |
1939 | int i; |
1940 | auto_vec<line_label> labels; |
1941 | |
1942 | /* Gather the labels that are to be printed into "labels". */ |
1943 | { |
1944 | layout_range *range; |
1945 | FOR_EACH_VEC_ELT (m_layout_ranges, i, range)for (i = 0; (m_layout_ranges).iterate ((i), &(range)); ++ (i)) |
1946 | { |
1947 | /* Most ranges don't have labels, so reject this first. */ |
1948 | if (range->m_label == NULL__null) |
1949 | continue; |
1950 | |
1951 | /* The range's caret must be on this line. */ |
1952 | if (range->m_caret.m_line != row) |
1953 | continue; |
1954 | |
1955 | /* Reject labels that aren't fully visible due to clipping |
1956 | by m_x_offset_display. */ |
1957 | const int disp_col = range->m_caret.m_columns[CU_DISPLAY_COLS]; |
1958 | if (disp_col <= m_x_offset_display) |
1959 | continue; |
1960 | |
1961 | label_text text; |
1962 | text = range->m_label->get_text (range->m_original_idx); |
1963 | |
1964 | /* Allow for labels that return NULL from their get_text |
1965 | implementation (so e.g. such labels can control their own |
1966 | visibility). */ |
1967 | if (text.get () == NULL__null) |
1968 | continue; |
1969 | |
1970 | labels.safe_push (line_label (m_policy, i, disp_col, std::move (text))); |
1971 | } |
1972 | } |
1973 | |
1974 | /* Bail out if there are no labels on this row. */ |
1975 | if (labels.length () == 0) |
1976 | return; |
1977 | |
1978 | /* Sort them. */ |
1979 | labels.qsort(line_label::comparator)qsort (line_label::comparator); |
1980 | |
1981 | /* Figure out how many "label lines" we need, and which |
1982 | one each label is printed in. |
1983 | |
1984 | For example, if the labels aren't too densely packed, |
1985 | we can fit them on the same line, giving two "label lines": |
1986 | |
1987 | foo + bar |
1988 | ~~~ ~~~ |
1989 | | | : label line 0 |
1990 | l0 l1 : label line 1 |
1991 | |
1992 | If they would touch each other or overlap, then we need |
1993 | additional "label lines": |
1994 | |
1995 | foo + bar |
1996 | ~~~ ~~~ |
1997 | | | : label line 0 |
1998 | | label 1 : label line 1 |
1999 | label 0 : label line 2 |
2000 | |
2001 | Place the final label on label line 1, and work backwards, adding |
2002 | label lines as needed. |
2003 | |
2004 | If multiple labels are at the same place, put them on separate |
2005 | label lines: |
2006 | |
2007 | foo + bar |
2008 | ^ : label line 0 |
2009 | | : label line 1 |
2010 | label 0 : label line 2 |
2011 | label 1 : label line 3. */ |
2012 | |
2013 | int max_label_line = 1; |
2014 | { |
2015 | int next_column = INT_MAX2147483647; |
2016 | line_label *label; |
2017 | FOR_EACH_VEC_ELT_REVERSE (labels, i, label)for (i = (labels).length () - 1; (labels).iterate ((i), & (label)); (i)--) |
2018 | { |
2019 | /* Would this label "touch" or overlap the next label? */ |
2020 | if (label->m_column + label->m_display_width >= (size_t)next_column) |
2021 | { |
2022 | max_label_line++; |
2023 | |
2024 | /* If we've already seen labels with the same column, suppress the |
2025 | vertical bar for subsequent ones in this backwards iteration; |
2026 | hence only the one with the highest label_line has m_has_vbar set. */ |
2027 | if (label->m_column == next_column) |
2028 | label->m_has_vbar = false; |
2029 | } |
2030 | |
2031 | label->m_label_line = max_label_line; |
2032 | next_column = label->m_column; |
2033 | } |
2034 | } |
2035 | |
2036 | /* Print the "label lines". For each label within the line, print |
2037 | either a vertical bar ('|') for the labels that are lower down, or the |
2038 | labels themselves once we've reached their line. */ |
2039 | { |
2040 | for (int label_line = 0; label_line <= max_label_line; label_line++) |
2041 | { |
2042 | start_annotation_line (); |
2043 | pp_space (m_pp)pp_character (m_pp, ' '); |
2044 | int column = 1 + m_x_offset_display; |
2045 | line_label *label; |
2046 | FOR_EACH_VEC_ELT (labels, i, label)for (i = 0; (labels).iterate ((i), &(label)); ++(i)) |
2047 | { |
2048 | if (label_line > label->m_label_line) |
2049 | /* We've printed all the labels for this label line. */ |
2050 | break; |
2051 | |
2052 | if (label_line == label->m_label_line) |
2053 | { |
2054 | gcc_assert (column <= label->m_column)((void)(!(column <= label->m_column) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 2054, __FUNCTION__), 0 : 0)); |
2055 | move_to_column (&column, label->m_column, true); |
2056 | /* Colorize the text, unless it's for events in a |
2057 | diagnostic_path. */ |
2058 | if (!m_diagnostic_path_p) |
2059 | m_colorizer.set_range (label->m_state_idx); |
2060 | pp_string (m_pp, label->m_text.m_buffer); |
2061 | m_colorizer.set_normal_text (); |
2062 | column += label->m_display_width; |
2063 | } |
2064 | else if (label->m_has_vbar) |
2065 | { |
2066 | gcc_assert (column <= label->m_column)((void)(!(column <= label->m_column) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 2066, __FUNCTION__), 0 : 0)); |
2067 | move_to_column (&column, label->m_column, true); |
2068 | m_colorizer.set_range (label->m_state_idx); |
2069 | pp_character (m_pp, '|'); |
2070 | m_colorizer.set_normal_text (); |
2071 | column++; |
2072 | } |
2073 | } |
2074 | print_newline (); |
2075 | } |
2076 | } |
2077 | |
2078 | /* Clean up. */ |
2079 | { |
2080 | line_label *label; |
2081 | FOR_EACH_VEC_ELT (labels, i, label)for (i = 0; (labels).iterate ((i), &(label)); ++(i)) |
2082 | label->m_text.maybe_free (); |
2083 | } |
2084 | } |
2085 | |
2086 | /* If there are any fixit hints inserting new lines before source line ROW, |
2087 | print them. |
2088 | |
2089 | They are printed on lines of their own, before the source line |
2090 | itself, with a leading '+'. */ |
2091 | |
2092 | void |
2093 | layout::print_leading_fixits (linenum_type row) |
2094 | { |
2095 | for (unsigned int i = 0; i < m_fixit_hints.length (); i++) |
2096 | { |
2097 | const fixit_hint *hint = m_fixit_hints[i]; |
2098 | |
2099 | if (!hint->ends_with_newline_p ()) |
2100 | /* Not a newline fixit; print it in print_trailing_fixits. */ |
2101 | continue; |
2102 | |
2103 | gcc_assert (hint->insertion_p ())((void)(!(hint->insertion_p ()) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 2103, __FUNCTION__), 0 : 0)); |
2104 | |
2105 | if (hint->affects_line_p (m_exploc.file, row)) |
2106 | { |
2107 | /* Printing the '+' with normal colorization |
2108 | and the inserted line with "insert" colorization |
2109 | helps them stand out from each other, and from |
2110 | the surrounding text. */ |
2111 | m_colorizer.set_normal_text (); |
2112 | start_annotation_line ('+'); |
2113 | pp_character (m_pp, '+'); |
2114 | m_colorizer.set_fixit_insert (); |
2115 | /* Print all but the trailing newline of the fix-it hint. |
2116 | We have to print the newline separately to avoid |
2117 | getting additional pp prefixes printed. */ |
2118 | for (size_t i = 0; i < hint->get_length () - 1; i++) |
2119 | pp_character (m_pp, hint->get_string ()[i]); |
2120 | m_colorizer.set_normal_text (); |
2121 | pp_newline (m_pp); |
2122 | } |
2123 | } |
2124 | } |
2125 | |
2126 | /* Subroutine of layout::print_trailing_fixits. |
2127 | |
2128 | Determine if the annotation line printed for LINE contained |
2129 | the exact range from START_COLUMN to FINISH_COLUMN (in display units). */ |
2130 | |
2131 | bool |
2132 | layout::annotation_line_showed_range_p (linenum_type line, int start_column, |
2133 | int finish_column) const |
2134 | { |
2135 | layout_range *range; |
2136 | int i; |
2137 | FOR_EACH_VEC_ELT (m_layout_ranges, i, range)for (i = 0; (m_layout_ranges).iterate ((i), &(range)); ++ (i)) |
2138 | if (range->m_start.m_line == line |
2139 | && range->m_start.m_columns[CU_DISPLAY_COLS] == start_column |
2140 | && range->m_finish.m_line == line |
2141 | && range->m_finish.m_columns[CU_DISPLAY_COLS] == finish_column) |
2142 | return true; |
2143 | return false; |
2144 | } |
2145 | |
2146 | /* Classes for printing trailing fix-it hints i.e. those that |
2147 | don't add new lines. |
2148 | |
2149 | For insertion, these can look like: |
2150 | |
2151 | new_text |
2152 | |
2153 | For replacement, these can look like: |
2154 | |
2155 | ------------- : underline showing affected range |
2156 | new_text |
2157 | |
2158 | For deletion, these can look like: |
2159 | |
2160 | ------------- : underline showing affected range |
2161 | |
2162 | This can become confusing if they overlap, and so we need |
2163 | to do some preprocessing to decide what to print. |
2164 | We use the list of fixit_hint instances affecting the line |
2165 | to build a list of "correction" instances, and print the |
2166 | latter. |
2167 | |
2168 | For example, consider a set of fix-its for converting |
2169 | a C-style cast to a C++ const_cast. |
2170 | |
2171 | Given: |
2172 | |
2173 | ..000000000111111111122222222223333333333. |
2174 | ..123456789012345678901234567890123456789. |
2175 | foo *f = (foo *)ptr->field; |
2176 | ^~~~~ |
2177 | |
2178 | and the fix-it hints: |
2179 | - replace col 10 (the open paren) with "const_cast<" |
2180 | - replace col 16 (the close paren) with "> (" |
2181 | - insert ")" before col 27 |
2182 | |
2183 | then we would get odd-looking output: |
2184 | |
2185 | foo *f = (foo *)ptr->field; |
2186 | ^~~~~ |
2187 | - |
2188 | const_cast< |
2189 | - |
2190 | > ( ) |
2191 | |
2192 | It would be better to detect when fixit hints are going to |
2193 | overlap (those that require new lines), and to consolidate |
2194 | the printing of such fixits, giving something like: |
2195 | |
2196 | foo *f = (foo *)ptr->field; |
2197 | ^~~~~ |
2198 | ----------------- |
2199 | const_cast<foo *> (ptr->field) |
2200 | |
2201 | This works by detecting when the printing would overlap, and |
2202 | effectively injecting no-op replace hints into the gaps between |
2203 | such fix-its, so that the printing joins up. |
2204 | |
2205 | In the above example, the overlap of: |
2206 | - replace col 10 (the open paren) with "const_cast<" |
2207 | and: |
2208 | - replace col 16 (the close paren) with "> (" |
2209 | is fixed by injecting a no-op: |
2210 | - replace cols 11-15 with themselves ("foo *") |
2211 | and consolidating these, making: |
2212 | - replace cols 10-16 with "const_cast<" + "foo *" + "> (" |
2213 | i.e.: |
2214 | - replace cols 10-16 with "const_cast<foo *> (" |
2215 | |
2216 | This overlaps with the final fix-it hint: |
2217 | - insert ")" before col 27 |
2218 | and so we repeat the consolidation process, by injecting |
2219 | a no-op: |
2220 | - replace cols 17-26 with themselves ("ptr->field") |
2221 | giving: |
2222 | - replace cols 10-26 with "const_cast<foo *> (" + "ptr->field" + ")" |
2223 | i.e.: |
2224 | - replace cols 10-26 with "const_cast<foo *> (ptr->field)" |
2225 | |
2226 | and is thus printed as desired. */ |
2227 | |
2228 | /* A range of (byte or display) columns within a line. */ |
2229 | |
2230 | class column_range |
2231 | { |
2232 | public: |
2233 | column_range (int start_, int finish_) : start (start_), finish (finish_) |
2234 | { |
2235 | /* We must have either a range, or an insertion. */ |
2236 | gcc_assert (start <= finish || finish == start - 1)((void)(!(start <= finish || finish == start - 1) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 2236, __FUNCTION__), 0 : 0)); |
2237 | } |
2238 | |
2239 | bool operator== (const column_range &other) const |
2240 | { |
2241 | return start == other.start && finish == other.finish; |
2242 | } |
2243 | |
2244 | int start; |
2245 | int finish; |
2246 | }; |
2247 | |
2248 | /* Get the range of bytes or display columns that HINT would affect. */ |
2249 | static column_range |
2250 | get_affected_range (const cpp_char_column_policy &policy, |
2251 | const fixit_hint *hint, enum column_unit col_unit) |
2252 | { |
2253 | expanded_location exploc_start = expand_location (hint->get_start_loc ()); |
2254 | expanded_location exploc_finish = expand_location (hint->get_next_loc ()); |
2255 | --exploc_finish.column; |
2256 | |
2257 | int start_column; |
2258 | int finish_column; |
2259 | if (col_unit == CU_DISPLAY_COLS) |
2260 | { |
2261 | start_column = location_compute_display_column (exploc_start, policy); |
2262 | if (hint->insertion_p ()) |
2263 | finish_column = start_column - 1; |
2264 | else |
2265 | finish_column = location_compute_display_column (exploc_finish, policy); |
2266 | } |
2267 | else |
2268 | { |
2269 | start_column = exploc_start.column; |
2270 | finish_column = exploc_finish.column; |
2271 | } |
2272 | return column_range (start_column, finish_column); |
2273 | } |
2274 | |
2275 | /* Get the range of display columns that would be printed for HINT. */ |
2276 | |
2277 | static column_range |
2278 | get_printed_columns (const cpp_char_column_policy &policy, |
2279 | const fixit_hint *hint) |
2280 | { |
2281 | expanded_location exploc = expand_location (hint->get_start_loc ()); |
2282 | int start_column = location_compute_display_column (exploc, policy); |
2283 | int hint_width = cpp_display_width (hint->get_string (), hint->get_length (), |
2284 | policy); |
2285 | int final_hint_column = start_column + hint_width - 1; |
2286 | if (hint->insertion_p ()) |
2287 | { |
2288 | return column_range (start_column, final_hint_column); |
2289 | } |
2290 | else |
2291 | { |
2292 | exploc = expand_location (hint->get_next_loc ()); |
2293 | --exploc.column; |
2294 | int finish_column = location_compute_display_column (exploc, policy); |
2295 | return column_range (start_column, |
2296 | MAX (finish_column, final_hint_column)((finish_column) > (final_hint_column) ? (finish_column) : (final_hint_column))); |
2297 | } |
2298 | } |
2299 | |
2300 | /* A correction on a particular line. |
2301 | This describes a plan for how to print one or more fixit_hint |
2302 | instances that affected the line, potentially consolidating hints |
2303 | into corrections to make the result easier for the user to read. */ |
2304 | |
2305 | class correction |
2306 | { |
2307 | public: |
2308 | correction (column_range affected_bytes, |
2309 | column_range affected_columns, |
2310 | column_range printed_columns, |
2311 | const char *new_text, size_t new_text_len, |
2312 | const cpp_char_column_policy &policy) |
2313 | : m_affected_bytes (affected_bytes), |
2314 | m_affected_columns (affected_columns), |
2315 | m_printed_columns (printed_columns), |
2316 | m_text (xstrdup (new_text)), |
2317 | m_byte_length (new_text_len), |
2318 | m_policy (policy), |
2319 | m_alloc_sz (new_text_len + 1) |
2320 | { |
2321 | compute_display_cols (); |
2322 | } |
2323 | |
2324 | ~correction () { free (m_text); } |
2325 | |
2326 | bool insertion_p () const |
2327 | { |
2328 | return m_affected_bytes.start == m_affected_bytes.finish + 1; |
2329 | } |
2330 | |
2331 | void ensure_capacity (size_t len); |
2332 | void ensure_terminated (); |
2333 | |
2334 | void compute_display_cols () |
2335 | { |
2336 | m_display_cols = cpp_display_width (m_text, m_byte_length, m_policy); |
2337 | } |
2338 | |
2339 | void overwrite (int dst_offset, const char_span &src_span) |
2340 | { |
2341 | gcc_assert (dst_offset >= 0)((void)(!(dst_offset >= 0) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 2341, __FUNCTION__), 0 : 0)); |
2342 | gcc_assert (dst_offset + src_span.length () < m_alloc_sz)((void)(!(dst_offset + src_span.length () < m_alloc_sz) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 2342, __FUNCTION__), 0 : 0)); |
2343 | memcpy (m_text + dst_offset, src_span.get_buffer (), |
2344 | src_span.length ()); |
2345 | } |
2346 | |
2347 | /* If insert, then start: the column before which the text |
2348 | is to be inserted, and finish is offset by the length of |
2349 | the replacement. |
2350 | If replace, then the range of columns affected. */ |
2351 | column_range m_affected_bytes; |
2352 | column_range m_affected_columns; |
2353 | |
2354 | /* If insert, then start: the column before which the text |
2355 | is to be inserted, and finish is offset by the length of |
2356 | the replacement. |
2357 | If replace, then the range of columns affected. */ |
2358 | column_range m_printed_columns; |
2359 | |
2360 | /* The text to be inserted/used as replacement. */ |
2361 | char *m_text; |
2362 | size_t m_byte_length; /* Not including null-terminator. */ |
2363 | int m_display_cols; |
2364 | const cpp_char_column_policy &m_policy; |
2365 | size_t m_alloc_sz; |
2366 | }; |
2367 | |
2368 | /* Ensure that m_text can hold a string of length LEN |
2369 | (plus 1 for 0-termination). */ |
2370 | |
2371 | void |
2372 | correction::ensure_capacity (size_t len) |
2373 | { |
2374 | /* Allow 1 extra byte for 0-termination. */ |
2375 | if (m_alloc_sz < (len + 1)) |
2376 | { |
2377 | size_t new_alloc_sz = (len + 1) * 2; |
2378 | m_text = (char *)xrealloc (m_text, new_alloc_sz); |
2379 | m_alloc_sz = new_alloc_sz; |
2380 | } |
2381 | } |
2382 | |
2383 | /* Ensure that m_text is 0-terminated. */ |
2384 | |
2385 | void |
2386 | correction::ensure_terminated () |
2387 | { |
2388 | /* 0-terminate the buffer. */ |
2389 | gcc_assert (m_byte_length < m_alloc_sz)((void)(!(m_byte_length < m_alloc_sz) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 2389, __FUNCTION__), 0 : 0)); |
2390 | m_text[m_byte_length] = '\0'; |
2391 | } |
2392 | |
2393 | /* A list of corrections affecting a particular line. |
2394 | This is used by layout::print_trailing_fixits for planning |
2395 | how to print the fix-it hints affecting the line. */ |
2396 | |
2397 | class line_corrections |
2398 | { |
2399 | public: |
2400 | line_corrections (const char_display_policy &policy, |
2401 | const char *filename, |
2402 | linenum_type row) |
2403 | : m_policy (policy), m_filename (filename), m_row (row) |
2404 | {} |
2405 | ~line_corrections (); |
2406 | |
2407 | void add_hint (const fixit_hint *hint); |
2408 | |
2409 | const char_display_policy &m_policy; |
2410 | const char *m_filename; |
2411 | linenum_type m_row; |
2412 | auto_vec <correction *> m_corrections; |
2413 | }; |
2414 | |
2415 | /* struct line_corrections. */ |
2416 | |
2417 | line_corrections::~line_corrections () |
2418 | { |
2419 | unsigned i; |
2420 | correction *c; |
2421 | FOR_EACH_VEC_ELT (m_corrections, i, c)for (i = 0; (m_corrections).iterate ((i), &(c)); ++(i)) |
2422 | delete c; |
2423 | } |
2424 | |
2425 | /* A struct wrapping a particular source line, allowing |
2426 | run-time bounds-checking of accesses in a checked build. */ |
2427 | |
2428 | class source_line |
2429 | { |
2430 | public: |
2431 | source_line (const char *filename, int line); |
2432 | |
2433 | char_span as_span () { return char_span (chars, width); } |
2434 | |
2435 | const char *chars; |
2436 | int width; |
2437 | }; |
2438 | |
2439 | /* source_line's ctor. */ |
2440 | |
2441 | source_line::source_line (const char *filename, int line) |
2442 | { |
2443 | char_span span = location_get_source_line (filename, line); |
2444 | chars = span.get_buffer (); |
2445 | width = span.length (); |
2446 | } |
2447 | |
2448 | /* Add HINT to the corrections for this line. |
2449 | Attempt to consolidate nearby hints so that they will not |
2450 | overlap with printed. */ |
2451 | |
2452 | void |
2453 | line_corrections::add_hint (const fixit_hint *hint) |
2454 | { |
2455 | column_range affected_bytes = get_affected_range (m_policy, hint, CU_BYTES); |
2456 | column_range affected_columns = get_affected_range (m_policy, hint, |
2457 | CU_DISPLAY_COLS); |
2458 | column_range printed_columns = get_printed_columns (m_policy, hint); |
2459 | |
2460 | /* Potentially consolidate. */ |
2461 | if (!m_corrections.is_empty ()) |
2462 | { |
2463 | correction *last_correction |
2464 | = m_corrections[m_corrections.length () - 1]; |
2465 | |
2466 | /* The following consolidation code assumes that the fix-it hints |
2467 | have been sorted by start (done within layout's ctor). */ |
2468 | gcc_assert (affected_bytes.start((void)(!(affected_bytes.start >= last_correction->m_affected_bytes .start) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 2469, __FUNCTION__), 0 : 0)) |
2469 | >= last_correction->m_affected_bytes.start)((void)(!(affected_bytes.start >= last_correction->m_affected_bytes .start) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 2469, __FUNCTION__), 0 : 0)); |
2470 | gcc_assert (printed_columns.start((void)(!(printed_columns.start >= last_correction->m_printed_columns .start) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 2471, __FUNCTION__), 0 : 0)) |
2471 | >= last_correction->m_printed_columns.start)((void)(!(printed_columns.start >= last_correction->m_printed_columns .start) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 2471, __FUNCTION__), 0 : 0)); |
2472 | |
2473 | if (printed_columns.start <= last_correction->m_printed_columns.finish) |
2474 | { |
2475 | /* We have two hints for which the printed forms of the hints |
2476 | would touch or overlap, so we need to consolidate them to avoid |
2477 | confusing the user. |
2478 | Attempt to inject a "replace" correction from immediately |
2479 | after the end of the last hint to immediately before the start |
2480 | of the next hint. */ |
2481 | column_range between (last_correction->m_affected_bytes.finish + 1, |
2482 | affected_bytes.start - 1); |
2483 | |
2484 | /* Try to read the source. */ |
2485 | source_line line (m_filename, m_row); |
2486 | if (line.chars && between.finish < line.width) |
2487 | { |
2488 | /* Consolidate into the last correction: |
2489 | add a no-op "replace" of the "between" text, and |
2490 | add the text from the new hint. */ |
2491 | int old_byte_len = last_correction->m_byte_length; |
2492 | gcc_assert (old_byte_len >= 0)((void)(!(old_byte_len >= 0) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 2492, __FUNCTION__), 0 : 0)); |
2493 | int between_byte_len = between.finish + 1 - between.start; |
2494 | gcc_assert (between_byte_len >= 0)((void)(!(between_byte_len >= 0) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 2494, __FUNCTION__), 0 : 0)); |
2495 | int new_byte_len |
2496 | = old_byte_len + between_byte_len + hint->get_length (); |
2497 | gcc_assert (new_byte_len >= 0)((void)(!(new_byte_len >= 0) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 2497, __FUNCTION__), 0 : 0)); |
2498 | last_correction->ensure_capacity (new_byte_len); |
2499 | last_correction->overwrite |
2500 | (old_byte_len, |
2501 | line.as_span ().subspan (between.start - 1, |
2502 | between.finish + 1 - between.start)); |
2503 | last_correction->overwrite (old_byte_len + between_byte_len, |
2504 | char_span (hint->get_string (), |
2505 | hint->get_length ())); |
2506 | last_correction->m_byte_length = new_byte_len; |
2507 | last_correction->ensure_terminated (); |
2508 | last_correction->m_affected_bytes.finish |
2509 | = affected_bytes.finish; |
2510 | last_correction->m_affected_columns.finish |
2511 | = affected_columns.finish; |
2512 | int prev_display_cols = last_correction->m_display_cols; |
2513 | last_correction->compute_display_cols (); |
2514 | last_correction->m_printed_columns.finish |
2515 | += last_correction->m_display_cols - prev_display_cols; |
2516 | return; |
2517 | } |
2518 | } |
2519 | } |
2520 | |
2521 | /* If no consolidation happened, add a new correction instance. */ |
2522 | m_corrections.safe_push (new correction (affected_bytes, |
2523 | affected_columns, |
2524 | printed_columns, |
2525 | hint->get_string (), |
2526 | hint->get_length (), |
2527 | m_policy)); |
2528 | } |
2529 | |
2530 | /* If there are any fixit hints on source line ROW, print them. |
2531 | They are printed in order, attempting to combine them onto lines, but |
2532 | starting new lines if necessary. |
2533 | Fix-it hints that insert new lines are handled separately, |
2534 | in layout::print_leading_fixits. */ |
2535 | |
2536 | void |
2537 | layout::print_trailing_fixits (linenum_type row) |
2538 | { |
2539 | /* Build a list of correction instances for the line, |
2540 | potentially consolidating hints (for the sake of readability). */ |
2541 | line_corrections corrections (m_policy, m_exploc.file, row); |
2542 | for (unsigned int i = 0; i < m_fixit_hints.length (); i++) |
2543 | { |
2544 | const fixit_hint *hint = m_fixit_hints[i]; |
2545 | |
2546 | /* Newline fixits are handled by layout::print_leading_fixits. */ |
2547 | if (hint->ends_with_newline_p ()) |
2548 | continue; |
2549 | |
2550 | if (hint->affects_line_p (m_exploc.file, row)) |
2551 | corrections.add_hint (hint); |
2552 | } |
2553 | |
2554 | /* Now print the corrections. */ |
2555 | unsigned i; |
2556 | correction *c; |
2557 | int column = m_x_offset_display; |
2558 | |
2559 | if (!corrections.m_corrections.is_empty ()) |
2560 | start_annotation_line (); |
2561 | |
2562 | FOR_EACH_VEC_ELT (corrections.m_corrections, i, c)for (i = 0; (corrections.m_corrections).iterate ((i), &(c )); ++(i)) |
2563 | { |
2564 | /* For now we assume each fixit hint can only touch one line. */ |
2565 | if (c->insertion_p ()) |
2566 | { |
2567 | /* This assumes the insertion just affects one line. */ |
2568 | int start_column = c->m_printed_columns.start; |
2569 | move_to_column (&column, start_column, true); |
2570 | m_colorizer.set_fixit_insert (); |
2571 | pp_string (m_pp, c->m_text); |
2572 | m_colorizer.set_normal_text (); |
2573 | column += c->m_display_cols; |
2574 | } |
2575 | else |
2576 | { |
2577 | /* If the range of the replacement wasn't printed in the |
2578 | annotation line, then print an extra underline to |
2579 | indicate exactly what is being replaced. |
2580 | Always show it for removals. */ |
2581 | int start_column = c->m_affected_columns.start; |
2582 | int finish_column = c->m_affected_columns.finish; |
2583 | if (!annotation_line_showed_range_p (row, start_column, |
2584 | finish_column) |
2585 | || c->m_byte_length == 0) |
2586 | { |
2587 | move_to_column (&column, start_column, true); |
2588 | m_colorizer.set_fixit_delete (); |
2589 | for (; column <= finish_column; column++) |
2590 | pp_character (m_pp, '-'); |
2591 | m_colorizer.set_normal_text (); |
2592 | } |
2593 | /* Print the replacement text. REPLACE also covers |
2594 | removals, so only do this extra work (potentially starting |
2595 | a new line) if we have actual replacement text. */ |
2596 | if (c->m_byte_length > 0) |
2597 | { |
2598 | move_to_column (&column, start_column, true); |
2599 | m_colorizer.set_fixit_insert (); |
2600 | pp_string (m_pp, c->m_text); |
2601 | m_colorizer.set_normal_text (); |
2602 | column += c->m_display_cols; |
2603 | } |
2604 | } |
2605 | } |
2606 | |
2607 | /* Add a trailing newline, if necessary. */ |
2608 | move_to_column (&column, 0, false); |
2609 | } |
2610 | |
2611 | /* Disable any colorization and emit a newline. */ |
2612 | |
2613 | void |
2614 | layout::print_newline () |
2615 | { |
2616 | m_colorizer.set_normal_text (); |
2617 | pp_newline (m_pp); |
2618 | } |
2619 | |
2620 | /* Return true if (ROW/COLUMN) is within a range of the layout. |
2621 | If it returns true, OUT_STATE is written to, with the |
2622 | range index, and whether we should draw the caret at |
2623 | (ROW/COLUMN) (as opposed to an underline). COL_UNIT controls |
2624 | whether all inputs and outputs are in bytes or display column units. */ |
2625 | |
2626 | bool |
2627 | layout::get_state_at_point (/* Inputs. */ |
2628 | linenum_type row, int column, |
2629 | int first_non_ws, int last_non_ws, |
2630 | enum column_unit col_unit, |
2631 | /* Outputs. */ |
2632 | point_state *out_state) |
2633 | { |
2634 | layout_range *range; |
2635 | int i; |
2636 | FOR_EACH_VEC_ELT (m_layout_ranges, i, range)for (i = 0; (m_layout_ranges).iterate ((i), &(range)); ++ (i)) |
2637 | { |
2638 | if (range->m_range_display_kind == SHOW_LINES_WITHOUT_RANGE) |
2639 | /* Bail out early, so that such ranges don't affect underlining or |
2640 | source colorization. */ |
2641 | continue; |
2642 | |
2643 | if (range->contains_point (row, column, col_unit)) |
2644 | { |
2645 | out_state->range_idx = i; |
2646 | |
2647 | /* Are we at the range's caret? is it visible? */ |
2648 | out_state->draw_caret_p = false; |
2649 | if (range->m_range_display_kind == SHOW_RANGE_WITH_CARET |
2650 | && row == range->m_caret.m_line |
2651 | && column == range->m_caret.m_columns[col_unit]) |
2652 | out_state->draw_caret_p = true; |
2653 | |
2654 | /* Within a multiline range, don't display any underline |
2655 | in any leading or trailing whitespace on a line. |
2656 | We do display carets, however. */ |
2657 | if (!out_state->draw_caret_p) |
2658 | if (column < first_non_ws || column > last_non_ws) |
2659 | return false; |
2660 | |
2661 | /* We are within a range. */ |
2662 | return true; |
2663 | } |
2664 | } |
2665 | |
2666 | return false; |
2667 | } |
2668 | |
2669 | /* Helper function for use by layout::print_line when printing the |
2670 | annotation line under the source line. |
2671 | Get the display column beyond the rightmost one that could contain a caret |
2672 | or range marker, given that we stop rendering at trailing whitespace. |
2673 | ROW is the source line within the given file. |
2674 | CARET_COLUMN is the display column of range 0's caret. |
2675 | LAST_NON_WS_COLUMN is the last display column containing a non-whitespace |
2676 | character of source (as determined when printing the source line). */ |
2677 | |
2678 | int |
2679 | layout::get_x_bound_for_row (linenum_type row, int caret_column, |
2680 | int last_non_ws_column) |
2681 | { |
2682 | int result = caret_column + 1; |
2683 | |
2684 | layout_range *range; |
2685 | int i; |
2686 | FOR_EACH_VEC_ELT (m_layout_ranges, i, range)for (i = 0; (m_layout_ranges).iterate ((i), &(range)); ++ (i)) |
2687 | { |
2688 | if (row >= range->m_start.m_line) |
2689 | { |
2690 | if (range->m_finish.m_line == row) |
2691 | { |
2692 | /* On the final line within a range; ensure that |
2693 | we render up to the end of the range. */ |
2694 | const int disp_col = range->m_finish.m_columns[CU_DISPLAY_COLS]; |
2695 | if (result <= disp_col) |
2696 | result = disp_col + 1; |
2697 | } |
2698 | else if (row < range->m_finish.m_line) |
2699 | { |
2700 | /* Within a multiline range; ensure that we render up to the |
2701 | last non-whitespace column. */ |
2702 | if (result <= last_non_ws_column) |
2703 | result = last_non_ws_column + 1; |
2704 | } |
2705 | } |
2706 | } |
2707 | |
2708 | return result; |
2709 | } |
2710 | |
2711 | /* Given *COLUMN as an x-coordinate, print spaces to position |
2712 | successive output at DEST_COLUMN, printing a newline if necessary, |
2713 | and updating *COLUMN. If ADD_LEFT_MARGIN, then print the (empty) |
2714 | left margin after any newline. */ |
2715 | |
2716 | void |
2717 | layout::move_to_column (int *column, int dest_column, bool add_left_margin) |
2718 | { |
2719 | /* Start a new line if we need to. */ |
2720 | if (*column > dest_column) |
2721 | { |
2722 | print_newline (); |
2723 | if (add_left_margin) |
2724 | start_annotation_line (); |
2725 | *column = m_x_offset_display; |
2726 | } |
2727 | |
2728 | while (*column < dest_column) |
2729 | { |
2730 | pp_space (m_pp)pp_character (m_pp, ' '); |
2731 | (*column)++; |
2732 | } |
2733 | } |
2734 | |
2735 | /* For debugging layout issues, render a ruler giving column numbers |
2736 | (after the 1-column indent). */ |
2737 | |
2738 | void |
2739 | layout::show_ruler (int max_column) const |
2740 | { |
2741 | /* Hundreds. */ |
2742 | if (max_column > 99) |
2743 | { |
2744 | start_annotation_line (); |
2745 | pp_space (m_pp)pp_character (m_pp, ' '); |
2746 | for (int column = 1 + m_x_offset_display; column <= max_column; column++) |
2747 | if (column % 10 == 0) |
2748 | pp_character (m_pp, '0' + (column / 100) % 10); |
2749 | else |
2750 | pp_space (m_pp)pp_character (m_pp, ' '); |
2751 | pp_newline (m_pp); |
2752 | } |
2753 | |
2754 | /* Tens. */ |
2755 | start_annotation_line (); |
2756 | pp_space (m_pp)pp_character (m_pp, ' '); |
2757 | for (int column = 1 + m_x_offset_display; column <= max_column; column++) |
2758 | if (column % 10 == 0) |
2759 | pp_character (m_pp, '0' + (column / 10) % 10); |
2760 | else |
2761 | pp_space (m_pp)pp_character (m_pp, ' '); |
2762 | pp_newline (m_pp); |
2763 | |
2764 | /* Units. */ |
2765 | start_annotation_line (); |
2766 | pp_space (m_pp)pp_character (m_pp, ' '); |
2767 | for (int column = 1 + m_x_offset_display; column <= max_column; column++) |
2768 | pp_character (m_pp, '0' + (column % 10)); |
2769 | pp_newline (m_pp); |
2770 | } |
2771 | |
2772 | /* Print leading fix-its (for new lines inserted before the source line) |
2773 | then the source line, followed by an annotation line |
2774 | consisting of any caret/underlines, then any fixits. |
2775 | If the source line can't be read, print nothing. */ |
2776 | void |
2777 | layout::print_line (linenum_type row) |
2778 | { |
2779 | char_span line = location_get_source_line (m_exploc.file, row); |
2780 | if (!line) |
2781 | return; |
2782 | |
2783 | print_leading_fixits (row); |
2784 | const line_bounds lbounds |
2785 | = print_source_line (row, line.get_buffer (), line.length ()); |
2786 | if (should_print_annotation_line_p (row)) |
2787 | print_annotation_line (row, lbounds); |
2788 | if (m_show_labels_p) |
2789 | print_any_labels (row); |
2790 | print_trailing_fixits (row); |
2791 | } |
2792 | |
2793 | } /* End of anonymous namespace. */ |
2794 | |
2795 | /* If LOC is within the spans of lines that will already be printed for |
2796 | this gcc_rich_location, then add it as a secondary location and return true. |
2797 | |
2798 | Otherwise return false. */ |
2799 | |
2800 | bool |
2801 | gcc_rich_location::add_location_if_nearby (location_t loc, |
2802 | bool restrict_to_current_line_spans, |
2803 | const range_label *label) |
2804 | { |
2805 | /* Use the layout location-handling logic to sanitize LOC, |
2806 | filtering it to the current line spans within a temporary |
2807 | layout instance. */ |
2808 | layout layout (global_dc, this, DK_ERROR); |
2809 | location_range loc_range; |
2810 | loc_range.m_loc = loc; |
2811 | loc_range.m_range_display_kind = SHOW_RANGE_WITHOUT_CARET; |
2812 | if (!layout.maybe_add_location_range (&loc_range, 0, |
2813 | restrict_to_current_line_spans)) |
2814 | return false; |
2815 | |
2816 | add_range (loc, SHOW_RANGE_WITHOUT_CARET, label); |
2817 | return true; |
2818 | } |
2819 | |
2820 | /* Print the physical source code corresponding to the location of |
2821 | this diagnostic, with additional annotations. */ |
2822 | |
2823 | void |
2824 | diagnostic_show_locus (diagnostic_context * context, |
2825 | rich_location *richloc, |
2826 | diagnostic_t diagnostic_kind) |
2827 | { |
2828 | location_t loc = richloc->get_loc (); |
2829 | /* Do nothing if source-printing has been disabled. */ |
2830 | if (!context->show_caret) |
2831 | return; |
2832 | |
2833 | /* Don't attempt to print source for UNKNOWN_LOCATION and for builtins. */ |
2834 | if (loc <= BUILTINS_LOCATION((location_t) 1)) |
2835 | return; |
2836 | |
2837 | /* Don't print the same source location twice in a row, unless we have |
2838 | fix-it hints, or multiple locations, or a label. */ |
2839 | if (loc == context->last_location |
2840 | && richloc->get_num_fixit_hints () == 0 |
2841 | && richloc->get_num_locations () == 1 |
2842 | && richloc->get_range (0)->m_label == NULL__null) |
2843 | return; |
2844 | |
2845 | context->last_location = loc; |
2846 | |
2847 | layout layout (context, richloc, diagnostic_kind); |
2848 | for (int line_span_idx = 0; line_span_idx < layout.get_num_line_spans (); |
2849 | line_span_idx++) |
2850 | { |
2851 | const line_span *line_span = layout.get_line_span (line_span_idx); |
2852 | if (context->show_line_numbers_p) |
2853 | { |
2854 | /* With line numbers, we should show whenever the line-numbering |
2855 | "jumps". */ |
2856 | if (line_span_idx > 0) |
2857 | layout.print_gap_in_line_numbering (); |
2858 | } |
2859 | else |
2860 | { |
2861 | /* Without line numbers, we print headings for some line spans. */ |
2862 | if (layout.print_heading_for_line_span_index_p (line_span_idx)) |
2863 | { |
2864 | expanded_location exploc |
2865 | = layout.get_expanded_location (line_span); |
2866 | context->start_span (context, exploc); |
2867 | } |
2868 | } |
2869 | /* Iterate over the lines within this span (using linenum_arith_t to |
2870 | avoid overflow with 0xffffffff causing an infinite loop). */ |
2871 | linenum_arith_t last_line = line_span->get_last_line (); |
2872 | for (linenum_arith_t row = line_span->get_first_line (); |
2873 | row <= last_line; row++) |
2874 | layout.print_line (row); |
2875 | } |
2876 | } |
2877 | |
2878 | #if CHECKING_P1 |
2879 | |
2880 | namespace selftest { |
2881 | |
2882 | /* Selftests for diagnostic_show_locus. */ |
2883 | |
2884 | /* Verify that cpp_display_width correctly handles escaping. */ |
2885 | |
2886 | static void |
2887 | test_display_widths () |
2888 | { |
2889 | gcc_rich_location richloc (UNKNOWN_LOCATION((location_t) 0)); |
2890 | |
2891 | /* U+03C0 "GREEK SMALL LETTER PI". */ |
2892 | const char *pi = "\xCF\x80"; |
2893 | /* U+1F642 "SLIGHTLY SMILING FACE". */ |
2894 | const char *emoji = "\xF0\x9F\x99\x82"; |
2895 | /* Stray trailing byte of a UTF-8 character. */ |
2896 | const char *stray = "\xBF"; |
2897 | /* U+10FFFF. */ |
2898 | const char *max_codepoint = "\xF4\x8F\xBF\xBF"; |
2899 | |
2900 | /* No escaping. */ |
2901 | { |
2902 | test_diagnostic_context dc; |
2903 | char_display_policy policy (make_policy (dc, richloc)); |
2904 | ASSERT_EQ (cpp_display_width (pi, strlen (pi), policy), 1)do { const char *desc_ = "ASSERT_EQ (" "(cpp_display_width (pi, strlen (pi), policy))" ", " "(1)" ")"; if (((cpp_display_width (pi, strlen (pi), policy ))) == ((1))) ::selftest::pass ((((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 2904, __FUNCTION__)))), desc_); else ::selftest::fail ((((:: selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 2904, __FUNCTION__)))), desc_); } while (0); |
2905 | ASSERT_EQ (cpp_display_width (emoji, strlen (emoji), policy), 2)do { const char *desc_ = "ASSERT_EQ (" "(cpp_display_width (emoji, strlen (emoji), policy))" ", " "(2)" ")"; if (((cpp_display_width (emoji, strlen (emoji ), policy))) == ((2))) ::selftest::pass ((((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 2905, __FUNCTION__)))), desc_); else ::selftest::fail ((((:: selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 2905, __FUNCTION__)))), desc_); } while (0); |
2906 | ASSERT_EQ (cpp_display_width (stray, strlen (stray), policy), 1)do { const char *desc_ = "ASSERT_EQ (" "(cpp_display_width (stray, strlen (stray), policy))" ", " "(1)" ")"; if (((cpp_display_width (stray, strlen (stray ), policy))) == ((1))) ::selftest::pass ((((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 2906, __FUNCTION__)))), desc_); else ::selftest::fail ((((:: selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 2906, __FUNCTION__)))), desc_); } while (0); |
2907 | /* Don't check width of U+10FFFF; it's in a private use plane. */ |
2908 | } |
2909 | |
2910 | richloc.set_escape_on_output (true); |
2911 | |
2912 | { |
2913 | test_diagnostic_context dc; |
2914 | dc.escape_format = DIAGNOSTICS_ESCAPE_FORMAT_UNICODE; |
2915 | char_display_policy policy (make_policy (dc, richloc)); |
2916 | ASSERT_EQ (cpp_display_width (pi, strlen (pi), policy), 8)do { const char *desc_ = "ASSERT_EQ (" "(cpp_display_width (pi, strlen (pi), policy))" ", " "(8)" ")"; if (((cpp_display_width (pi, strlen (pi), policy ))) == ((8))) ::selftest::pass ((((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 2916, __FUNCTION__)))), desc_); else ::selftest::fail ((((:: selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 2916, __FUNCTION__)))), desc_); } while (0); |
2917 | ASSERT_EQ (cpp_display_width (emoji, strlen (emoji), policy), 9)do { const char *desc_ = "ASSERT_EQ (" "(cpp_display_width (emoji, strlen (emoji), policy))" ", " "(9)" ")"; if (((cpp_display_width (emoji, strlen (emoji ), policy))) == ((9))) ::selftest::pass ((((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 2917, __FUNCTION__)))), desc_); else ::selftest::fail ((((:: selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 2917, __FUNCTION__)))), desc_); } while (0); |
2918 | ASSERT_EQ (cpp_display_width (stray, strlen (stray), policy), 4)do { const char *desc_ = "ASSERT_EQ (" "(cpp_display_width (stray, strlen (stray), policy))" ", " "(4)" ")"; if (((cpp_display_width (stray, strlen (stray ), policy))) == ((4))) ::selftest::pass ((((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 2918, __FUNCTION__)))), desc_); else ::selftest::fail ((((:: selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 2918, __FUNCTION__)))), desc_); } while (0); |
2919 | ASSERT_EQ (cpp_display_width (max_codepoint, strlen (max_codepoint),do { const char *desc_ = "ASSERT_EQ (" "(cpp_display_width (max_codepoint, strlen (max_codepoint), policy))" ", " "(strlen (\"<U+10FFFF>\"))" ")"; if (((cpp_display_width (max_codepoint, strlen (max_codepoint), policy))) == ((strlen ("<U+10FFFF>")))) ::selftest::pass ((((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 2921, __FUNCTION__)))), desc_); else ::selftest::fail ((((:: selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 2921, __FUNCTION__)))), desc_); } while (0) |
2920 | policy),do { const char *desc_ = "ASSERT_EQ (" "(cpp_display_width (max_codepoint, strlen (max_codepoint), policy))" ", " "(strlen (\"<U+10FFFF>\"))" ")"; if (((cpp_display_width (max_codepoint, strlen (max_codepoint), policy))) == ((strlen ("<U+10FFFF>")))) ::selftest::pass ((((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 2921, __FUNCTION__)))), desc_); else ::selftest::fail ((((:: selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 2921, __FUNCTION__)))), desc_); } while (0) |
2921 | strlen ("<U+10FFFF>"))do { const char *desc_ = "ASSERT_EQ (" "(cpp_display_width (max_codepoint, strlen (max_codepoint), policy))" ", " "(strlen (\"<U+10FFFF>\"))" ")"; if (((cpp_display_width (max_codepoint, strlen (max_codepoint), policy))) == ((strlen ("<U+10FFFF>")))) ::selftest::pass ((((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 2921, __FUNCTION__)))), desc_); else ::selftest::fail ((((:: selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 2921, __FUNCTION__)))), desc_); } while (0); |
2922 | } |
2923 | |
2924 | { |
2925 | test_diagnostic_context dc; |
2926 | dc.escape_format = DIAGNOSTICS_ESCAPE_FORMAT_BYTES; |
2927 | char_display_policy policy (make_policy (dc, richloc)); |
2928 | ASSERT_EQ (cpp_display_width (pi, strlen (pi), policy), 8)do { const char *desc_ = "ASSERT_EQ (" "(cpp_display_width (pi, strlen (pi), policy))" ", " "(8)" ")"; if (((cpp_display_width (pi, strlen (pi), policy ))) == ((8))) ::selftest::pass ((((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 2928, __FUNCTION__)))), desc_); else ::selftest::fail ((((:: selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 2928, __FUNCTION__)))), desc_); } while (0); |
2929 | ASSERT_EQ (cpp_display_width (emoji, strlen (emoji), policy), 16)do { const char *desc_ = "ASSERT_EQ (" "(cpp_display_width (emoji, strlen (emoji), policy))" ", " "(16)" ")"; if (((cpp_display_width (emoji, strlen (emoji ), policy))) == ((16))) ::selftest::pass ((((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 2929, __FUNCTION__)))), desc_); else ::selftest::fail ((((:: selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 2929, __FUNCTION__)))), desc_); } while (0); |
2930 | ASSERT_EQ (cpp_display_width (stray, strlen (stray), policy), 4)do { const char *desc_ = "ASSERT_EQ (" "(cpp_display_width (stray, strlen (stray), policy))" ", " "(4)" ")"; if (((cpp_display_width (stray, strlen (stray ), policy))) == ((4))) ::selftest::pass ((((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 2930, __FUNCTION__)))), desc_); else ::selftest::fail ((((:: selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 2930, __FUNCTION__)))), desc_); } while (0); |
2931 | ASSERT_EQ (cpp_display_width (max_codepoint, strlen (max_codepoint),do { const char *desc_ = "ASSERT_EQ (" "(cpp_display_width (max_codepoint, strlen (max_codepoint), policy))" ", " "(16)" ")"; if (((cpp_display_width (max_codepoint, strlen (max_codepoint), policy))) == ((16))) ::selftest::pass ((((:: selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 2933, __FUNCTION__)))), desc_); else ::selftest::fail ((((:: selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 2933, __FUNCTION__)))), desc_); } while (0) |
2932 | policy),do { const char *desc_ = "ASSERT_EQ (" "(cpp_display_width (max_codepoint, strlen (max_codepoint), policy))" ", " "(16)" ")"; if (((cpp_display_width (max_codepoint, strlen (max_codepoint), policy))) == ((16))) ::selftest::pass ((((:: selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 2933, __FUNCTION__)))), desc_); else ::selftest::fail ((((:: selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 2933, __FUNCTION__)))), desc_); } while (0) |
2933 | 16)do { const char *desc_ = "ASSERT_EQ (" "(cpp_display_width (max_codepoint, strlen (max_codepoint), policy))" ", " "(16)" ")"; if (((cpp_display_width (max_codepoint, strlen (max_codepoint), policy))) == ((16))) ::selftest::pass ((((:: selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 2933, __FUNCTION__)))), desc_); else ::selftest::fail ((((:: selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 2933, __FUNCTION__)))), desc_); } while (0); |
2934 | } |
2935 | } |
2936 | |
2937 | /* For precise tests of the layout, make clear where the source line will |
2938 | start. test_left_margin sets the total byte count from the left side of the |
2939 | screen to the start of source lines, after the line number and the separator, |
2940 | which consists of the three characters " | ". */ |
2941 | static const int test_linenum_sep = 3; |
2942 | static const int test_left_margin = 7; |
2943 | |
2944 | /* Helper function for test_layout_x_offset_display_utf8(). */ |
2945 | static void |
2946 | test_offset_impl (int caret_byte_col, int max_width, |
2947 | int expected_x_offset_display, |
2948 | int left_margin = test_left_margin) |
2949 | { |
2950 | test_diagnostic_context dc; |
2951 | dc.caret_max_width = max_width; |
2952 | /* diagnostic_context::min_margin_width sets the minimum space reserved for |
2953 | the line number plus one space after. */ |
2954 | dc.min_margin_width = left_margin - test_linenum_sep + 1; |
2955 | dc.show_line_numbers_p = true; |
2956 | rich_location richloc (line_table, |
2957 | linemap_position_for_column (line_table, |
2958 | caret_byte_col)); |
2959 | layout test_layout (&dc, &richloc, DK_ERROR); |
2960 | ASSERT_EQ (left_margin - test_linenum_sep,do { const char *desc_ = "ASSERT_EQ (" "(left_margin - test_linenum_sep)" ", " "(test_layout.get_linenum_width ())" ")"; if (((left_margin - test_linenum_sep)) == ((test_layout.get_linenum_width ())) ) ::selftest::pass ((((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 2961, __FUNCTION__)))), desc_); else ::selftest::fail ((((:: selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 2961, __FUNCTION__)))), desc_); } while (0) |
2961 | test_layout.get_linenum_width ())do { const char *desc_ = "ASSERT_EQ (" "(left_margin - test_linenum_sep)" ", " "(test_layout.get_linenum_width ())" ")"; if (((left_margin - test_linenum_sep)) == ((test_layout.get_linenum_width ())) ) ::selftest::pass ((((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 2961, __FUNCTION__)))), desc_); else ::selftest::fail ((((:: selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 2961, __FUNCTION__)))), desc_); } while (0); |
2962 | ASSERT_EQ (expected_x_offset_display,do { const char *desc_ = "ASSERT_EQ (" "(expected_x_offset_display)" ", " "(test_layout.get_x_offset_display ())" ")"; if (((expected_x_offset_display )) == ((test_layout.get_x_offset_display ()))) ::selftest::pass ((((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 2963, __FUNCTION__)))), desc_); else ::selftest::fail ((((:: selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 2963, __FUNCTION__)))), desc_); } while (0) |
2963 | test_layout.get_x_offset_display ())do { const char *desc_ = "ASSERT_EQ (" "(expected_x_offset_display)" ", " "(test_layout.get_x_offset_display ())" ")"; if (((expected_x_offset_display )) == ((test_layout.get_x_offset_display ()))) ::selftest::pass ((((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 2963, __FUNCTION__)))), desc_); else ::selftest::fail ((((:: selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 2963, __FUNCTION__)))), desc_); } while (0); |
2964 | } |
2965 | |
2966 | /* Test that layout::calculate_x_offset_display() works. */ |
2967 | static void |
2968 | test_layout_x_offset_display_utf8 (const line_table_case &case_) |
2969 | { |
2970 | |
2971 | const char *content |
2972 | = "This line is very long, so that we can use it to test the logic for " |
2973 | "clipping long lines. Also this: \xf0\x9f\x98\x82\xf0\x9f\x98\x82 is a " |
2974 | "pair of emojis that occupies 8 bytes and 4 display columns, starting at " |
2975 | "column #102.\n"; |
2976 | |
2977 | /* Number of bytes in the line, subtracting one to remove the newline. */ |
2978 | const int line_bytes = strlen (content) - 1; |
2979 | |
2980 | /* Number of display columns occupied by the line; each of the 2 emojis |
2981 | takes up 2 fewer display columns than it does bytes. */ |
2982 | const int line_display_cols = line_bytes - 2*2; |
2983 | |
2984 | /* The column of the first emoji. Byte or display is the same as there are |
2985 | no multibyte characters earlier on the line. */ |
2986 | const int emoji_col = 102; |
2987 | |
2988 | temp_source_file tmp (SELFTEST_LOCATION(::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 2988, __FUNCTION__)), ".c", content); |
2989 | line_table_test ltt (case_); |
2990 | |
2991 | linemap_add (line_table, LC_ENTER, false, tmp.get_filename (), 1); |
2992 | |
2993 | location_t line_end = linemap_position_for_column (line_table, line_bytes); |
2994 | |
2995 | /* Don't attempt to run the tests if column data might be unavailable. */ |
2996 | if (line_end > LINE_MAP_MAX_LOCATION_WITH_COLS) |
2997 | return; |
2998 | |
2999 | ASSERT_STREQ (tmp.get_filename (), LOCATION_FILE (line_end))do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 2999, __FUNCTION__)), "tmp.get_filename ()", "LOCATION_FILE (line_end)" , (tmp.get_filename ()), (((expand_location (line_end)).file) )); } while (0); |
3000 | ASSERT_EQ (1, LOCATION_LINE (line_end))do { const char *desc_ = "ASSERT_EQ (" "(1)" ", " "(((expand_location (line_end)).line))" ")"; if (((1)) == ((((expand_location (line_end)).line)))) :: selftest::pass ((((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 3000, __FUNCTION__)))), desc_); else ::selftest::fail ((((:: selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 3000, __FUNCTION__)))), desc_); } while (0); |
3001 | ASSERT_EQ (line_bytes, LOCATION_COLUMN (line_end))do { const char *desc_ = "ASSERT_EQ (" "(line_bytes)" ", " "(((expand_location (line_end)).column))" ")"; if (((line_bytes)) == ((((expand_location (line_end)).column )))) ::selftest::pass ((((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 3001, __FUNCTION__)))), desc_); else ::selftest::fail ((((:: selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 3001, __FUNCTION__)))), desc_); } while (0); |
3002 | |
3003 | char_span lspan = location_get_source_line (tmp.get_filename (), 1); |
3004 | ASSERT_EQ (line_display_cols,do { const char *desc_ = "ASSERT_EQ (" "(line_display_cols)" ", " "(cpp_display_width (lspan.get_buffer (), lspan.length (), def_policy ()))" ")"; if (((line_display_cols)) == ((cpp_display_width (lspan .get_buffer (), lspan.length (), def_policy ())))) ::selftest ::pass ((((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 3006, __FUNCTION__)))), desc_); else ::selftest::fail ((((:: selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 3006, __FUNCTION__)))), desc_); } while (0) |
3005 | cpp_display_width (lspan.get_buffer (), lspan.length (),do { const char *desc_ = "ASSERT_EQ (" "(line_display_cols)" ", " "(cpp_display_width (lspan.get_buffer (), lspan.length (), def_policy ()))" ")"; if (((line_display_cols)) == ((cpp_display_width (lspan .get_buffer (), lspan.length (), def_policy ())))) ::selftest ::pass ((((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 3006, __FUNCTION__)))), desc_); else ::selftest::fail ((((:: selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 3006, __FUNCTION__)))), desc_); } while (0) |
3006 | def_policy ()))do { const char *desc_ = "ASSERT_EQ (" "(line_display_cols)" ", " "(cpp_display_width (lspan.get_buffer (), lspan.length (), def_policy ()))" ")"; if (((line_display_cols)) == ((cpp_display_width (lspan .get_buffer (), lspan.length (), def_policy ())))) ::selftest ::pass ((((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 3006, __FUNCTION__)))), desc_); else ::selftest::fail ((((:: selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 3006, __FUNCTION__)))), desc_); } while (0); |
3007 | ASSERT_EQ (line_display_cols,do { const char *desc_ = "ASSERT_EQ (" "(line_display_cols)" ", " "(location_compute_display_column (expand_location (line_end), def_policy ()))" ")"; if (((line_display_cols)) == ((location_compute_display_column (expand_location (line_end), def_policy ())))) ::selftest::pass ((((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 3009, __FUNCTION__)))), desc_); else ::selftest::fail ((((:: selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 3009, __FUNCTION__)))), desc_); } while (0) |
3008 | location_compute_display_column (expand_location (line_end),do { const char *desc_ = "ASSERT_EQ (" "(line_display_cols)" ", " "(location_compute_display_column (expand_location (line_end), def_policy ()))" ")"; if (((line_display_cols)) == ((location_compute_display_column (expand_location (line_end), def_policy ())))) ::selftest::pass ((((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 3009, __FUNCTION__)))), desc_); else ::selftest::fail ((((:: selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 3009, __FUNCTION__)))), desc_); } while (0) |
3009 | def_policy ()))do { const char *desc_ = "ASSERT_EQ (" "(line_display_cols)" ", " "(location_compute_display_column (expand_location (line_end), def_policy ()))" ")"; if (((line_display_cols)) == ((location_compute_display_column (expand_location (line_end), def_policy ())))) ::selftest::pass ((((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 3009, __FUNCTION__)))), desc_); else ::selftest::fail ((((:: selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 3009, __FUNCTION__)))), desc_); } while (0); |
3010 | ASSERT_EQ (0, memcmp (lspan.get_buffer () + (emoji_col - 1),do { const char *desc_ = "ASSERT_EQ (" "(0)" ", " "(memcmp (lspan.get_buffer () + (emoji_col - 1), \"\\xf0\\x9f\\x98\\x82\\xf0\\x9f\\x98\\x82\", 8))" ")"; if (((0)) == ((memcmp (lspan.get_buffer () + (emoji_col - 1), "\xf0\x9f\x98\x82\xf0\x9f\x98\x82", 8)))) ::selftest:: pass ((((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 3011, __FUNCTION__)))), desc_); else ::selftest::fail ((((:: selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 3011, __FUNCTION__)))), desc_); } while (0) |
3011 | "\xf0\x9f\x98\x82\xf0\x9f\x98\x82", 8))do { const char *desc_ = "ASSERT_EQ (" "(0)" ", " "(memcmp (lspan.get_buffer () + (emoji_col - 1), \"\\xf0\\x9f\\x98\\x82\\xf0\\x9f\\x98\\x82\", 8))" ")"; if (((0)) == ((memcmp (lspan.get_buffer () + (emoji_col - 1), "\xf0\x9f\x98\x82\xf0\x9f\x98\x82", 8)))) ::selftest:: pass ((((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 3011, __FUNCTION__)))), desc_); else ::selftest::fail ((((:: selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 3011, __FUNCTION__)))), desc_); } while (0); |
3012 | |
3013 | /* (caret_byte, max_width, expected_x_offset_display, [left_margin]) */ |
3014 | |
3015 | /* No constraint on the width -> no offset. */ |
3016 | test_offset_impl (emoji_col, 0, 0); |
3017 | |
3018 | /* Caret is before the beginning -> no offset. */ |
3019 | test_offset_impl (0, 100, 0); |
3020 | |
3021 | /* Caret is past the end of the line -> no offset. */ |
3022 | test_offset_impl (line_bytes+1, 100, 0); |
3023 | |
3024 | /* Line fits in the display -> no offset. */ |
3025 | test_offset_impl (line_bytes, line_display_cols + test_left_margin, 0); |
3026 | test_offset_impl (emoji_col, line_display_cols + test_left_margin, 0); |
3027 | |
3028 | /* Line is too long for the display but caret location is OK |
3029 | anyway -> no offset. */ |
3030 | static const int small_width = 24; |
3031 | test_offset_impl (1, small_width, 0); |
3032 | |
3033 | /* Width constraint is very small -> no offset. */ |
3034 | test_offset_impl (emoji_col, CARET_LINE_MARGIN, 0); |
3035 | |
3036 | /* Line would be offset, but due to large line numbers, offsetting |
3037 | would remove the whole line -> no offset. */ |
3038 | static const int huge_left_margin = 100; |
3039 | test_offset_impl (emoji_col, huge_left_margin, 0, huge_left_margin); |
3040 | |
3041 | /* Line is the same length as the display, but the line number makes it too |
3042 | long, so offset is required. Caret is at the end so padding on the right |
3043 | is not in effect. */ |
3044 | for (int excess = 1; excess <= 3; ++excess) |
3045 | test_offset_impl (line_bytes, line_display_cols + test_left_margin - excess, |
3046 | excess); |
3047 | |
3048 | /* Line is much too long for the display, caret is near the end -> |
3049 | offset should be such that the line fits in the display and caret |
3050 | remains the same distance from the end that it was. */ |
3051 | for (int caret_offset = 0, max_offset = MIN (CARET_LINE_MARGIN, 10)((CARET_LINE_MARGIN) < (10) ? (CARET_LINE_MARGIN) : (10)); |
3052 | caret_offset <= max_offset; ++caret_offset) |
3053 | test_offset_impl (line_bytes - caret_offset, small_width, |
3054 | line_display_cols + test_left_margin - small_width); |
3055 | |
3056 | /* As previous case but caret is closer to the middle; now we want it to end |
3057 | up CARET_LINE_MARGIN bytes from the end. */ |
3058 | ASSERT_GT (line_display_cols - emoji_col, CARET_LINE_MARGIN)do { const char *desc_ = "ASSERT_GT (" "(line_display_cols - emoji_col)" ", " "(CARET_LINE_MARGIN)" ")"; if (((line_display_cols - emoji_col )) > ((CARET_LINE_MARGIN))) ::selftest::pass ((((::selftest ::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 3058, __FUNCTION__)))), desc_); else ::selftest::fail ((((:: selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 3058, __FUNCTION__)))), desc_); } while (0); |
3059 | test_offset_impl (emoji_col, small_width, |
3060 | emoji_col + test_left_margin |
3061 | - (small_width - CARET_LINE_MARGIN)); |
3062 | |
3063 | /* Test that the source line is offset as expected when printed. */ |
3064 | { |
3065 | test_diagnostic_context dc; |
3066 | dc.caret_max_width = small_width - 6; |
3067 | dc.min_margin_width = test_left_margin - test_linenum_sep + 1; |
3068 | dc.show_line_numbers_p = true; |
3069 | dc.show_ruler_p = true; |
3070 | rich_location richloc (line_table, |
3071 | linemap_position_for_column (line_table, |
3072 | emoji_col)); |
3073 | layout test_layout (&dc, &richloc, DK_ERROR); |
3074 | test_layout.print_line (1); |
3075 | ASSERT_STREQ (" | 1 \n"do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 3082, __FUNCTION__)), "\" | 1 \\n\" \" | 1 \\n\" \" | 234567890123456789\\n\" \" 1 | \\xf0\\x9f\\x98\\x82\\xf0\\x9f\\x98\\x82 is a pair of emojis \" \"that occupies 8 bytes and 4 display columns, starting at \" \"column #102.\\n\" \" | ^\\n\\n\"" , "pp_formatted_text (dc.printer)", (" | 1 \n" " | 1 \n" " | 234567890123456789\n" " 1 | \xf0\x9f\x98\x82\xf0\x9f\x98\x82 is a pair of emojis " "that occupies 8 bytes and 4 display columns, starting at " "column #102.\n" " | ^\n\n"), (pp_formatted_text (dc.printer))); } while ( 0) |
3076 | " | 1 \n"do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 3082, __FUNCTION__)), "\" | 1 \\n\" \" | 1 \\n\" \" | 234567890123456789\\n\" \" 1 | \\xf0\\x9f\\x98\\x82\\xf0\\x9f\\x98\\x82 is a pair of emojis \" \"that occupies 8 bytes and 4 display columns, starting at \" \"column #102.\\n\" \" | ^\\n\\n\"" , "pp_formatted_text (dc.printer)", (" | 1 \n" " | 1 \n" " | 234567890123456789\n" " 1 | \xf0\x9f\x98\x82\xf0\x9f\x98\x82 is a pair of emojis " "that occupies 8 bytes and 4 display columns, starting at " "column #102.\n" " | ^\n\n"), (pp_formatted_text (dc.printer))); } while ( 0) |
3077 | " | 234567890123456789\n"do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 3082, __FUNCTION__)), "\" | 1 \\n\" \" | 1 \\n\" \" | 234567890123456789\\n\" \" 1 | \\xf0\\x9f\\x98\\x82\\xf0\\x9f\\x98\\x82 is a pair of emojis \" \"that occupies 8 bytes and 4 display columns, starting at \" \"column #102.\\n\" \" | ^\\n\\n\"" , "pp_formatted_text (dc.printer)", (" | 1 \n" " | 1 \n" " | 234567890123456789\n" " 1 | \xf0\x9f\x98\x82\xf0\x9f\x98\x82 is a pair of emojis " "that occupies 8 bytes and 4 display columns, starting at " "column #102.\n" " | ^\n\n"), (pp_formatted_text (dc.printer))); } while ( 0) |
3078 | " 1 | \xf0\x9f\x98\x82\xf0\x9f\x98\x82 is a pair of emojis "do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 3082, __FUNCTION__)), "\" | 1 \\n\" \" | 1 \\n\" \" | 234567890123456789\\n\" \" 1 | \\xf0\\x9f\\x98\\x82\\xf0\\x9f\\x98\\x82 is a pair of emojis \" \"that occupies 8 bytes and 4 display columns, starting at \" \"column #102.\\n\" \" | ^\\n\\n\"" , "pp_formatted_text (dc.printer)", (" | 1 \n" " | 1 \n" " | 234567890123456789\n" " 1 | \xf0\x9f\x98\x82\xf0\x9f\x98\x82 is a pair of emojis " "that occupies 8 bytes and 4 display columns, starting at " "column #102.\n" " | ^\n\n"), (pp_formatted_text (dc.printer))); } while ( 0) |
3079 | "that occupies 8 bytes and 4 display columns, starting at "do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 3082, __FUNCTION__)), "\" | 1 \\n\" \" | 1 \\n\" \" | 234567890123456789\\n\" \" 1 | \\xf0\\x9f\\x98\\x82\\xf0\\x9f\\x98\\x82 is a pair of emojis \" \"that occupies 8 bytes and 4 display columns, starting at \" \"column #102.\\n\" \" | ^\\n\\n\"" , "pp_formatted_text (dc.printer)", (" | 1 \n" " | 1 \n" " | 234567890123456789\n" " 1 | \xf0\x9f\x98\x82\xf0\x9f\x98\x82 is a pair of emojis " "that occupies 8 bytes and 4 display columns, starting at " "column #102.\n" " | ^\n\n"), (pp_formatted_text (dc.printer))); } while ( 0) |
3080 | "column #102.\n"do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 3082, __FUNCTION__)), "\" | 1 \\n\" \" | 1 \\n\" \" | 234567890123456789\\n\" \" 1 | \\xf0\\x9f\\x98\\x82\\xf0\\x9f\\x98\\x82 is a pair of emojis \" \"that occupies 8 bytes and 4 display columns, starting at \" \"column #102.\\n\" \" | ^\\n\\n\"" , "pp_formatted_text (dc.printer)", (" | 1 \n" " | 1 \n" " | 234567890123456789\n" " 1 | \xf0\x9f\x98\x82\xf0\x9f\x98\x82 is a pair of emojis " "that occupies 8 bytes and 4 display columns, starting at " "column #102.\n" " | ^\n\n"), (pp_formatted_text (dc.printer))); } while ( 0) |
3081 | " | ^\n\n",do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 3082, __FUNCTION__)), "\" | 1 \\n\" \" | 1 \\n\" \" | 234567890123456789\\n\" \" 1 | \\xf0\\x9f\\x98\\x82\\xf0\\x9f\\x98\\x82 is a pair of emojis \" \"that occupies 8 bytes and 4 display columns, starting at \" \"column #102.\\n\" \" | ^\\n\\n\"" , "pp_formatted_text (dc.printer)", (" | 1 \n" " | 1 \n" " | 234567890123456789\n" " 1 | \xf0\x9f\x98\x82\xf0\x9f\x98\x82 is a pair of emojis " "that occupies 8 bytes and 4 display columns, starting at " "column #102.\n" " | ^\n\n"), (pp_formatted_text (dc.printer))); } while ( 0) |
3082 | pp_formatted_text (dc.printer))do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 3082, __FUNCTION__)), "\" | 1 \\n\" \" | 1 \\n\" \" | 234567890123456789\\n\" \" 1 | \\xf0\\x9f\\x98\\x82\\xf0\\x9f\\x98\\x82 is a pair of emojis \" \"that occupies 8 bytes and 4 display columns, starting at \" \"column #102.\\n\" \" | ^\\n\\n\"" , "pp_formatted_text (dc.printer)", (" | 1 \n" " | 1 \n" " | 234567890123456789\n" " 1 | \xf0\x9f\x98\x82\xf0\x9f\x98\x82 is a pair of emojis " "that occupies 8 bytes and 4 display columns, starting at " "column #102.\n" " | ^\n\n"), (pp_formatted_text (dc.printer))); } while ( 0); |
3083 | } |
3084 | |
3085 | /* Similar to the previous example, but now the offset called for would split |
3086 | the first emoji in the middle of the UTF-8 sequence. Check that we replace |
3087 | it with a padding space in this case. */ |
3088 | { |
3089 | test_diagnostic_context dc; |
3090 | dc.caret_max_width = small_width - 5; |
3091 | dc.min_margin_width = test_left_margin - test_linenum_sep + 1; |
3092 | dc.show_line_numbers_p = true; |
3093 | dc.show_ruler_p = true; |
3094 | rich_location richloc (line_table, |
3095 | linemap_position_for_column (line_table, |
3096 | emoji_col + 2)); |
3097 | layout test_layout (&dc, &richloc, DK_ERROR); |
3098 | test_layout.print_line (1); |
3099 | ASSERT_STREQ (" | 1 1 \n"do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 3106, __FUNCTION__)), "\" | 1 1 \\n\" \" | 1 2 \\n\" \" | 3456789012345678901\\n\" \" 1 | \\xf0\\x9f\\x98\\x82 is a pair of emojis \" \"that occupies 8 bytes and 4 display columns, starting at \" \"column #102.\\n\" \" | ^\\n\\n\"" , "pp_formatted_text (dc.printer)", (" | 1 1 \n" " | 1 2 \n" " | 3456789012345678901\n" " 1 | \xf0\x9f\x98\x82 is a pair of emojis " "that occupies 8 bytes and 4 display columns, starting at " "column #102.\n" " | ^\n\n"), (pp_formatted_text (dc.printer ))); } while (0) |
3100 | " | 1 2 \n"do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 3106, __FUNCTION__)), "\" | 1 1 \\n\" \" | 1 2 \\n\" \" | 3456789012345678901\\n\" \" 1 | \\xf0\\x9f\\x98\\x82 is a pair of emojis \" \"that occupies 8 bytes and 4 display columns, starting at \" \"column #102.\\n\" \" | ^\\n\\n\"" , "pp_formatted_text (dc.printer)", (" | 1 1 \n" " | 1 2 \n" " | 3456789012345678901\n" " 1 | \xf0\x9f\x98\x82 is a pair of emojis " "that occupies 8 bytes and 4 display columns, starting at " "column #102.\n" " | ^\n\n"), (pp_formatted_text (dc.printer ))); } while (0) |
3101 | " | 3456789012345678901\n"do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 3106, __FUNCTION__)), "\" | 1 1 \\n\" \" | 1 2 \\n\" \" | 3456789012345678901\\n\" \" 1 | \\xf0\\x9f\\x98\\x82 is a pair of emojis \" \"that occupies 8 bytes and 4 display columns, starting at \" \"column #102.\\n\" \" | ^\\n\\n\"" , "pp_formatted_text (dc.printer)", (" | 1 1 \n" " | 1 2 \n" " | 3456789012345678901\n" " 1 | \xf0\x9f\x98\x82 is a pair of emojis " "that occupies 8 bytes and 4 display columns, starting at " "column #102.\n" " | ^\n\n"), (pp_formatted_text (dc.printer ))); } while (0) |
3102 | " 1 | \xf0\x9f\x98\x82 is a pair of emojis "do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 3106, __FUNCTION__)), "\" | 1 1 \\n\" \" | 1 2 \\n\" \" | 3456789012345678901\\n\" \" 1 | \\xf0\\x9f\\x98\\x82 is a pair of emojis \" \"that occupies 8 bytes and 4 display columns, starting at \" \"column #102.\\n\" \" | ^\\n\\n\"" , "pp_formatted_text (dc.printer)", (" | 1 1 \n" " | 1 2 \n" " | 3456789012345678901\n" " 1 | \xf0\x9f\x98\x82 is a pair of emojis " "that occupies 8 bytes and 4 display columns, starting at " "column #102.\n" " | ^\n\n"), (pp_formatted_text (dc.printer ))); } while (0) |
3103 | "that occupies 8 bytes and 4 display columns, starting at "do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 3106, __FUNCTION__)), "\" | 1 1 \\n\" \" | 1 2 \\n\" \" | 3456789012345678901\\n\" \" 1 | \\xf0\\x9f\\x98\\x82 is a pair of emojis \" \"that occupies 8 bytes and 4 display columns, starting at \" \"column #102.\\n\" \" | ^\\n\\n\"" , "pp_formatted_text (dc.printer)", (" | 1 1 \n" " | 1 2 \n" " | 3456789012345678901\n" " 1 | \xf0\x9f\x98\x82 is a pair of emojis " "that occupies 8 bytes and 4 display columns, starting at " "column #102.\n" " | ^\n\n"), (pp_formatted_text (dc.printer ))); } while (0) |
3104 | "column #102.\n"do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 3106, __FUNCTION__)), "\" | 1 1 \\n\" \" | 1 2 \\n\" \" | 3456789012345678901\\n\" \" 1 | \\xf0\\x9f\\x98\\x82 is a pair of emojis \" \"that occupies 8 bytes and 4 display columns, starting at \" \"column #102.\\n\" \" | ^\\n\\n\"" , "pp_formatted_text (dc.printer)", (" | 1 1 \n" " | 1 2 \n" " | 3456789012345678901\n" " 1 | \xf0\x9f\x98\x82 is a pair of emojis " "that occupies 8 bytes and 4 display columns, starting at " "column #102.\n" " | ^\n\n"), (pp_formatted_text (dc.printer ))); } while (0) |
3105 | " | ^\n\n",do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 3106, __FUNCTION__)), "\" | 1 1 \\n\" \" | 1 2 \\n\" \" | 3456789012345678901\\n\" \" 1 | \\xf0\\x9f\\x98\\x82 is a pair of emojis \" \"that occupies 8 bytes and 4 display columns, starting at \" \"column #102.\\n\" \" | ^\\n\\n\"" , "pp_formatted_text (dc.printer)", (" | 1 1 \n" " | 1 2 \n" " | 3456789012345678901\n" " 1 | \xf0\x9f\x98\x82 is a pair of emojis " "that occupies 8 bytes and 4 display columns, starting at " "column #102.\n" " | ^\n\n"), (pp_formatted_text (dc.printer ))); } while (0) |
3106 | pp_formatted_text (dc.printer))do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 3106, __FUNCTION__)), "\" | 1 1 \\n\" \" | 1 2 \\n\" \" | 3456789012345678901\\n\" \" 1 | \\xf0\\x9f\\x98\\x82 is a pair of emojis \" \"that occupies 8 bytes and 4 display columns, starting at \" \"column #102.\\n\" \" | ^\\n\\n\"" , "pp_formatted_text (dc.printer)", (" | 1 1 \n" " | 1 2 \n" " | 3456789012345678901\n" " 1 | \xf0\x9f\x98\x82 is a pair of emojis " "that occupies 8 bytes and 4 display columns, starting at " "column #102.\n" " | ^\n\n"), (pp_formatted_text (dc.printer ))); } while (0); |
3107 | } |
3108 | |
3109 | } |
3110 | |
3111 | static void |
3112 | test_layout_x_offset_display_tab (const line_table_case &case_) |
3113 | { |
3114 | const char *content |
3115 | = "This line is very long, so that we can use it to test the logic for " |
3116 | "clipping long lines. Also this: `\t' is a tab that occupies 1 byte and " |
3117 | "a variable number of display columns, starting at column #103.\n"; |
3118 | |
3119 | /* Number of bytes in the line, subtracting one to remove the newline. */ |
3120 | const int line_bytes = strlen (content) - 1; |
3121 | |
3122 | /* The column where the tab begins. Byte or display is the same as there are |
3123 | no multibyte characters earlier on the line. */ |
3124 | const int tab_col = 103; |
3125 | |
3126 | /* Effective extra size of the tab beyond what a single space would have taken |
3127 | up, indexed by tabstop. */ |
3128 | static const int num_tabstops = 11; |
3129 | int extra_width[num_tabstops]; |
3130 | for (int tabstop = 1; tabstop != num_tabstops; ++tabstop) |
3131 | { |
3132 | const int this_tab_size = tabstop - (tab_col - 1) % tabstop; |
3133 | extra_width[tabstop] = this_tab_size - 1; |
3134 | } |
3135 | /* Example of this calculation: if tabstop is 10, the tab starting at column |
3136 | #103 has to expand into 8 spaces, covering columns 103-110, so that the |
3137 | next character is at column #111. So it takes up 7 more columns than |
3138 | a space would have taken up. */ |
3139 | ASSERT_EQ (7, extra_width[10])do { const char *desc_ = "ASSERT_EQ (" "(7)" ", " "(extra_width[10])" ")"; if (((7)) == ((extra_width[10]))) ::selftest::pass (((( ::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 3139, __FUNCTION__)))), desc_); else ::selftest::fail ((((:: selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 3139, __FUNCTION__)))), desc_); } while (0); |
3140 | |
3141 | temp_source_file tmp (SELFTEST_LOCATION(::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 3141, __FUNCTION__)), ".c", content); |
3142 | line_table_test ltt (case_); |
3143 | |
3144 | linemap_add (line_table, LC_ENTER, false, tmp.get_filename (), 1); |
3145 | |
3146 | location_t line_end = linemap_position_for_column (line_table, line_bytes); |
3147 | |
3148 | /* Don't attempt to run the tests if column data might be unavailable. */ |
3149 | if (line_end > LINE_MAP_MAX_LOCATION_WITH_COLS) |
3150 | return; |
3151 | |
3152 | /* Check that cpp_display_width handles the tabs as expected. */ |
3153 | char_span lspan = location_get_source_line (tmp.get_filename (), 1); |
3154 | ASSERT_EQ ('\t', *(lspan.get_buffer () + (tab_col - 1)))do { const char *desc_ = "ASSERT_EQ (" "('\\t')" ", " "(*(lspan.get_buffer () + (tab_col - 1)))" ")"; if ((('\t')) == ((*(lspan.get_buffer () + (tab_col - 1) )))) ::selftest::pass ((((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 3154, __FUNCTION__)))), desc_); else ::selftest::fail ((((:: selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 3154, __FUNCTION__)))), desc_); } while (0); |
3155 | for (int tabstop = 1; tabstop != num_tabstops; ++tabstop) |
3156 | { |
3157 | cpp_char_column_policy policy (tabstop, cpp_wcwidth); |
3158 | ASSERT_EQ (line_bytes + extra_width[tabstop],do { const char *desc_ = "ASSERT_EQ (" "(line_bytes + extra_width[tabstop])" ", " "(cpp_display_width (lspan.get_buffer (), lspan.length (), policy))" ")"; if (((line_bytes + extra_width[tabstop])) == ((cpp_display_width (lspan.get_buffer (), lspan.length (), policy)))) ::selftest ::pass ((((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 3160, __FUNCTION__)))), desc_); else ::selftest::fail ((((:: selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 3160, __FUNCTION__)))), desc_); } while (0) |
3159 | cpp_display_width (lspan.get_buffer (), lspan.length (),do { const char *desc_ = "ASSERT_EQ (" "(line_bytes + extra_width[tabstop])" ", " "(cpp_display_width (lspan.get_buffer (), lspan.length (), policy))" ")"; if (((line_bytes + extra_width[tabstop])) == ((cpp_display_width (lspan.get_buffer (), lspan.length (), policy)))) ::selftest ::pass ((((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 3160, __FUNCTION__)))), desc_); else ::selftest::fail ((((:: selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 3160, __FUNCTION__)))), desc_); } while (0) |
3160 | policy))do { const char *desc_ = "ASSERT_EQ (" "(line_bytes + extra_width[tabstop])" ", " "(cpp_display_width (lspan.get_buffer (), lspan.length (), policy))" ")"; if (((line_bytes + extra_width[tabstop])) == ((cpp_display_width (lspan.get_buffer (), lspan.length (), policy)))) ::selftest ::pass ((((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 3160, __FUNCTION__)))), desc_); else ::selftest::fail ((((:: selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 3160, __FUNCTION__)))), desc_); } while (0); |
3161 | ASSERT_EQ (line_bytes + extra_width[tabstop],do { const char *desc_ = "ASSERT_EQ (" "(line_bytes + extra_width[tabstop])" ", " "(location_compute_display_column (expand_location (line_end), policy))" ")"; if (((line_bytes + extra_width[tabstop])) == ((location_compute_display_column (expand_location (line_end), policy)))) ::selftest::pass ((( (::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 3163, __FUNCTION__)))), desc_); else ::selftest::fail ((((:: selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 3163, __FUNCTION__)))), desc_); } while (0) |
3162 | location_compute_display_column (expand_location (line_end),do { const char *desc_ = "ASSERT_EQ (" "(line_bytes + extra_width[tabstop])" ", " "(location_compute_display_column (expand_location (line_end), policy))" ")"; if (((line_bytes + extra_width[tabstop])) == ((location_compute_display_column (expand_location (line_end), policy)))) ::selftest::pass ((( (::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 3163, __FUNCTION__)))), desc_); else ::selftest::fail ((((:: selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 3163, __FUNCTION__)))), desc_); } while (0) |
3163 | policy))do { const char *desc_ = "ASSERT_EQ (" "(line_bytes + extra_width[tabstop])" ", " "(location_compute_display_column (expand_location (line_end), policy))" ")"; if (((line_bytes + extra_width[tabstop])) == ((location_compute_display_column (expand_location (line_end), policy)))) ::selftest::pass ((( (::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 3163, __FUNCTION__)))), desc_); else ::selftest::fail ((((:: selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 3163, __FUNCTION__)))), desc_); } while (0); |
3164 | } |
3165 | |
3166 | /* Check that the tab is expanded to the expected number of spaces. */ |
3167 | rich_location richloc (line_table, |
3168 | linemap_position_for_column (line_table, |
3169 | tab_col + 1)); |
3170 | for (int tabstop = 1; tabstop != num_tabstops; ++tabstop) |
3171 | { |
3172 | test_diagnostic_context dc; |
3173 | dc.tabstop = tabstop; |
3174 | layout test_layout (&dc, &richloc, DK_ERROR); |
3175 | test_layout.print_line (1); |
3176 | const char *out = pp_formatted_text (dc.printer); |
3177 | ASSERT_EQ (NULL, strchr (out, '\t'))do { const char *desc_ = "ASSERT_EQ (" "(__null)" ", " "(strchr (out, '\\t'))" ")"; if (((__null)) == ((strchr (out, '\t')))) ::selftest::pass ((((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 3177, __FUNCTION__)))), desc_); else ::selftest::fail ((((:: selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 3177, __FUNCTION__)))), desc_); } while (0); |
3178 | const char *left_quote = strchr (out, '`'); |
3179 | const char *right_quote = strchr (out, '\''); |
3180 | ASSERT_NE (NULL, left_quote)do { const char *desc_ = "ASSERT_NE (" "NULL" ", " "left_quote" ")"; if ((__null) != (left_quote)) ::selftest::pass ((::selftest ::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 3180, __FUNCTION__)), desc_); else ::selftest::fail ((::selftest ::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 3180, __FUNCTION__)), desc_); } while (0); |
3181 | ASSERT_NE (NULL, right_quote)do { const char *desc_ = "ASSERT_NE (" "NULL" ", " "right_quote" ")"; if ((__null) != (right_quote)) ::selftest::pass ((::selftest ::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 3181, __FUNCTION__)), desc_); else ::selftest::fail ((::selftest ::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 3181, __FUNCTION__)), desc_); } while (0); |
3182 | ASSERT_EQ (right_quote - left_quote, extra_width[tabstop] + 2)do { const char *desc_ = "ASSERT_EQ (" "(right_quote - left_quote)" ", " "(extra_width[tabstop] + 2)" ")"; if (((right_quote - left_quote )) == ((extra_width[tabstop] + 2))) ::selftest::pass ((((::selftest ::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 3182, __FUNCTION__)))), desc_); else ::selftest::fail ((((:: selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 3182, __FUNCTION__)))), desc_); } while (0); |
3183 | } |
3184 | |
3185 | /* Check that the line is offset properly and that the tab is broken up |
3186 | into the expected number of spaces when it is the last character skipped |
3187 | over. */ |
3188 | for (int tabstop = 1; tabstop != num_tabstops; ++tabstop) |
3189 | { |
3190 | test_diagnostic_context dc; |
3191 | dc.tabstop = tabstop; |
3192 | static const int small_width = 24; |
3193 | dc.caret_max_width = small_width - 4; |
3194 | dc.min_margin_width = test_left_margin - test_linenum_sep + 1; |
3195 | dc.show_line_numbers_p = true; |
3196 | layout test_layout (&dc, &richloc, DK_ERROR); |
3197 | test_layout.print_line (1); |
3198 | |
3199 | /* We have arranged things so that two columns will be printed before |
3200 | the caret. If the tab results in more than one space, this should |
3201 | produce two spaces in the output; otherwise, it will be a single space |
3202 | preceded by the opening quote before the tab character. */ |
3203 | const char *output1 |
3204 | = " 1 | ' is a tab that occupies 1 byte and a variable number of " |
3205 | "display columns, starting at column #103.\n" |
3206 | " | ^\n\n"; |
3207 | const char *output2 |
3208 | = " 1 | ` ' is a tab that occupies 1 byte and a variable number of " |
3209 | "display columns, starting at column #103.\n" |
3210 | " | ^\n\n"; |
3211 | const char *expected_output = (extra_width[tabstop] ? output1 : output2); |
3212 | ASSERT_STREQ (expected_output, pp_formatted_text (dc.printer))do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 3212, __FUNCTION__)), "expected_output", "pp_formatted_text (dc.printer)" , (expected_output), (pp_formatted_text (dc.printer))); } while (0); |
3213 | } |
3214 | } |
3215 | |
3216 | |
3217 | /* Verify that diagnostic_show_locus works sanely on UNKNOWN_LOCATION. */ |
3218 | |
3219 | static void |
3220 | test_diagnostic_show_locus_unknown_location () |
3221 | { |
3222 | test_diagnostic_context dc; |
3223 | rich_location richloc (line_table, UNKNOWN_LOCATION((location_t) 0)); |
3224 | diagnostic_show_locus (&dc, &richloc, DK_ERROR); |
3225 | ASSERT_STREQ ("", pp_formatted_text (dc.printer))do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 3225, __FUNCTION__)), "\"\"", "pp_formatted_text (dc.printer)" , (""), (pp_formatted_text (dc.printer))); } while (0); |
3226 | } |
3227 | |
3228 | /* Verify that diagnostic_show_locus works sanely for various |
3229 | single-line cases. |
3230 | |
3231 | All of these work on the following 1-line source file: |
3232 | .0000000001111111 |
3233 | .1234567890123456 |
3234 | "foo = bar.field;\n" |
3235 | which is set up by test_diagnostic_show_locus_one_liner and calls |
3236 | them. */ |
3237 | |
3238 | /* Just a caret. */ |
3239 | |
3240 | static void |
3241 | test_one_liner_simple_caret () |
3242 | { |
3243 | test_diagnostic_context dc; |
3244 | location_t caret = linemap_position_for_column (line_table, 10); |
3245 | rich_location richloc (line_table, caret); |
3246 | diagnostic_show_locus (&dc, &richloc, DK_ERROR); |
3247 | ASSERT_STREQ (" foo = bar.field;\n"do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 3249, __FUNCTION__)), "\" foo = bar.field;\\n\" \" ^\\n\"" , "pp_formatted_text (dc.printer)", (" foo = bar.field;\n" " ^\n" ), (pp_formatted_text (dc.printer))); } while (0) |
3248 | " ^\n",do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 3249, __FUNCTION__)), "\" foo = bar.field;\\n\" \" ^\\n\"" , "pp_formatted_text (dc.printer)", (" foo = bar.field;\n" " ^\n" ), (pp_formatted_text (dc.printer))); } while (0) |
3249 | pp_formatted_text (dc.printer))do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 3249, __FUNCTION__)), "\" foo = bar.field;\\n\" \" ^\\n\"" , "pp_formatted_text (dc.printer)", (" foo = bar.field;\n" " ^\n" ), (pp_formatted_text (dc.printer))); } while (0); |
3250 | } |
3251 | |
3252 | /* Caret and range. */ |
3253 | |
3254 | static void |
3255 | test_one_liner_caret_and_range () |
3256 | { |
3257 | test_diagnostic_context dc; |
3258 | location_t caret = linemap_position_for_column (line_table, 10); |
3259 | location_t start = linemap_position_for_column (line_table, 7); |
3260 | location_t finish = linemap_position_for_column (line_table, 15); |
3261 | location_t loc = make_location (caret, start, finish); |
3262 | rich_location richloc (line_table, loc); |
3263 | diagnostic_show_locus (&dc, &richloc, DK_ERROR); |
3264 | ASSERT_STREQ (" foo = bar.field;\n"do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 3266, __FUNCTION__)), "\" foo = bar.field;\\n\" \" ~~~^~~~~~\\n\"" , "pp_formatted_text (dc.printer)", (" foo = bar.field;\n" " ~~~^~~~~~\n" ), (pp_formatted_text (dc.printer))); } while (0) |
3265 | " ~~~^~~~~~\n",do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 3266, __FUNCTION__)), "\" foo = bar.field;\\n\" \" ~~~^~~~~~\\n\"" , "pp_formatted_text (dc.printer)", (" foo = bar.field;\n" " ~~~^~~~~~\n" ), (pp_formatted_text (dc.printer))); } while (0) |
3266 | pp_formatted_text (dc.printer))do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 3266, __FUNCTION__)), "\" foo = bar.field;\\n\" \" ~~~^~~~~~\\n\"" , "pp_formatted_text (dc.printer)", (" foo = bar.field;\n" " ~~~^~~~~~\n" ), (pp_formatted_text (dc.printer))); } while (0); |
3267 | } |
3268 | |
3269 | /* Multiple ranges and carets. */ |
3270 | |
3271 | static void |
3272 | test_one_liner_multiple_carets_and_ranges () |
3273 | { |
3274 | test_diagnostic_context dc; |
3275 | location_t foo |
3276 | = make_location (linemap_position_for_column (line_table, 2), |
3277 | linemap_position_for_column (line_table, 1), |
3278 | linemap_position_for_column (line_table, 3)); |
3279 | dc.caret_chars[0] = 'A'; |
3280 | |
3281 | location_t bar |
3282 | = make_location (linemap_position_for_column (line_table, 8), |
3283 | linemap_position_for_column (line_table, 7), |
3284 | linemap_position_for_column (line_table, 9)); |
3285 | dc.caret_chars[1] = 'B'; |
3286 | |
3287 | location_t field |
3288 | = make_location (linemap_position_for_column (line_table, 13), |
3289 | linemap_position_for_column (line_table, 11), |
3290 | linemap_position_for_column (line_table, 15)); |
3291 | dc.caret_chars[2] = 'C'; |
3292 | |
3293 | rich_location richloc (line_table, foo); |
3294 | richloc.add_range (bar, SHOW_RANGE_WITH_CARET); |
3295 | richloc.add_range (field, SHOW_RANGE_WITH_CARET); |
3296 | diagnostic_show_locus (&dc, &richloc, DK_ERROR); |
3297 | ASSERT_STREQ (" foo = bar.field;\n"do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 3299, __FUNCTION__)), "\" foo = bar.field;\\n\" \" ~A~ ~B~ ~~C~~\\n\"" , "pp_formatted_text (dc.printer)", (" foo = bar.field;\n" " ~A~ ~B~ ~~C~~\n" ), (pp_formatted_text (dc.printer))); } while (0) |
3298 | " ~A~ ~B~ ~~C~~\n",do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 3299, __FUNCTION__)), "\" foo = bar.field;\\n\" \" ~A~ ~B~ ~~C~~\\n\"" , "pp_formatted_text (dc.printer)", (" foo = bar.field;\n" " ~A~ ~B~ ~~C~~\n" ), (pp_formatted_text (dc.printer))); } while (0) |
3299 | pp_formatted_text (dc.printer))do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 3299, __FUNCTION__)), "\" foo = bar.field;\\n\" \" ~A~ ~B~ ~~C~~\\n\"" , "pp_formatted_text (dc.printer)", (" foo = bar.field;\n" " ~A~ ~B~ ~~C~~\n" ), (pp_formatted_text (dc.printer))); } while (0); |
3300 | } |
3301 | |
3302 | /* Insertion fix-it hint: adding an "&" to the front of "bar.field". */ |
3303 | |
3304 | static void |
3305 | test_one_liner_fixit_insert_before () |
3306 | { |
3307 | test_diagnostic_context dc; |
3308 | location_t caret = linemap_position_for_column (line_table, 7); |
3309 | rich_location richloc (line_table, caret); |
3310 | richloc.add_fixit_insert_before ("&"); |
3311 | diagnostic_show_locus (&dc, &richloc, DK_ERROR); |
3312 | ASSERT_STREQ (" foo = bar.field;\n"do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 3315, __FUNCTION__)), "\" foo = bar.field;\\n\" \" ^\\n\" \" &\\n\"" , "pp_formatted_text (dc.printer)", (" foo = bar.field;\n" " ^\n" " &\n"), (pp_formatted_text (dc.printer))); } while (0) |
3313 | " ^\n"do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 3315, __FUNCTION__)), "\" foo = bar.field;\\n\" \" ^\\n\" \" &\\n\"" , "pp_formatted_text (dc.printer)", (" foo = bar.field;\n" " ^\n" " &\n"), (pp_formatted_text (dc.printer))); } while (0) |
3314 | " &\n",do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 3315, __FUNCTION__)), "\" foo = bar.field;\\n\" \" ^\\n\" \" &\\n\"" , "pp_formatted_text (dc.printer)", (" foo = bar.field;\n" " ^\n" " &\n"), (pp_formatted_text (dc.printer))); } while (0) |
3315 | pp_formatted_text (dc.printer))do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 3315, __FUNCTION__)), "\" foo = bar.field;\\n\" \" ^\\n\" \" &\\n\"" , "pp_formatted_text (dc.printer)", (" foo = bar.field;\n" " ^\n" " &\n"), (pp_formatted_text (dc.printer))); } while (0); |
3316 | } |
3317 | |
3318 | /* Insertion fix-it hint: adding a "[0]" after "foo". */ |
3319 | |
3320 | static void |
3321 | test_one_liner_fixit_insert_after () |
3322 | { |
3323 | test_diagnostic_context dc; |
3324 | location_t start = linemap_position_for_column (line_table, 1); |
3325 | location_t finish = linemap_position_for_column (line_table, 3); |
3326 | location_t foo = make_location (start, start, finish); |
3327 | rich_location richloc (line_table, foo); |
3328 | richloc.add_fixit_insert_after ("[0]"); |
3329 | diagnostic_show_locus (&dc, &richloc, DK_ERROR); |
3330 | ASSERT_STREQ (" foo = bar.field;\n"do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 3333, __FUNCTION__)), "\" foo = bar.field;\\n\" \" ^~~\\n\" \" [0]\\n\"" , "pp_formatted_text (dc.printer)", (" foo = bar.field;\n" " ^~~\n" " [0]\n"), (pp_formatted_text (dc.printer))); } while (0) |
3331 | " ^~~\n"do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 3333, __FUNCTION__)), "\" foo = bar.field;\\n\" \" ^~~\\n\" \" [0]\\n\"" , "pp_formatted_text (dc.printer)", (" foo = bar.field;\n" " ^~~\n" " [0]\n"), (pp_formatted_text (dc.printer))); } while (0) |
3332 | " [0]\n",do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 3333, __FUNCTION__)), "\" foo = bar.field;\\n\" \" ^~~\\n\" \" [0]\\n\"" , "pp_formatted_text (dc.printer)", (" foo = bar.field;\n" " ^~~\n" " [0]\n"), (pp_formatted_text (dc.printer))); } while (0) |
3333 | pp_formatted_text (dc.printer))do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 3333, __FUNCTION__)), "\" foo = bar.field;\\n\" \" ^~~\\n\" \" [0]\\n\"" , "pp_formatted_text (dc.printer)", (" foo = bar.field;\n" " ^~~\n" " [0]\n"), (pp_formatted_text (dc.printer))); } while (0); |
3334 | } |
3335 | |
3336 | /* Removal fix-it hint: removal of the ".field". |
3337 | Also verify the interaction of pp_set_prefix with rulers and |
3338 | fix-it hints. */ |
3339 | |
3340 | static void |
3341 | test_one_liner_fixit_remove () |
3342 | { |
3343 | location_t start = linemap_position_for_column (line_table, 10); |
3344 | location_t finish = linemap_position_for_column (line_table, 15); |
3345 | location_t dot = make_location (start, start, finish); |
3346 | rich_location richloc (line_table, dot); |
3347 | richloc.add_fixit_remove (); |
3348 | |
3349 | /* Normal. */ |
3350 | { |
3351 | test_diagnostic_context dc; |
3352 | diagnostic_show_locus (&dc, &richloc, DK_ERROR); |
3353 | ASSERT_STREQ (" foo = bar.field;\n"do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 3356, __FUNCTION__)), "\" foo = bar.field;\\n\" \" ^~~~~~\\n\" \" ------\\n\"" , "pp_formatted_text (dc.printer)", (" foo = bar.field;\n" " ^~~~~~\n" " ------\n"), (pp_formatted_text (dc.printer))); } while (0) |
3354 | " ^~~~~~\n"do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 3356, __FUNCTION__)), "\" foo = bar.field;\\n\" \" ^~~~~~\\n\" \" ------\\n\"" , "pp_formatted_text (dc.printer)", (" foo = bar.field;\n" " ^~~~~~\n" " ------\n"), (pp_formatted_text (dc.printer))); } while (0) |
3355 | " ------\n",do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 3356, __FUNCTION__)), "\" foo = bar.field;\\n\" \" ^~~~~~\\n\" \" ------\\n\"" , "pp_formatted_text (dc.printer)", (" foo = bar.field;\n" " ^~~~~~\n" " ------\n"), (pp_formatted_text (dc.printer))); } while (0) |
3356 | pp_formatted_text (dc.printer))do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 3356, __FUNCTION__)), "\" foo = bar.field;\\n\" \" ^~~~~~\\n\" \" ------\\n\"" , "pp_formatted_text (dc.printer)", (" foo = bar.field;\n" " ^~~~~~\n" " ------\n"), (pp_formatted_text (dc.printer))); } while (0); |
3357 | } |
3358 | |
3359 | /* Test of adding a prefix. */ |
3360 | { |
3361 | test_diagnostic_context dc; |
3362 | pp_prefixing_rule (dc.printer)(dc.printer)->wrapping.rule = DIAGNOSTICS_SHOW_PREFIX_EVERY_LINE; |
3363 | pp_set_prefix (dc.printer, xstrdup ("TEST PREFIX:")); |
3364 | diagnostic_show_locus (&dc, &richloc, DK_ERROR); |
3365 | ASSERT_STREQ ("TEST PREFIX: foo = bar.field;\n"do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 3368, __FUNCTION__)), "\"TEST PREFIX: foo = bar.field;\\n\" \"TEST PREFIX: ^~~~~~\\n\" \"TEST PREFIX: ------\\n\"" , "pp_formatted_text (dc.printer)", ("TEST PREFIX: foo = bar.field;\n" "TEST PREFIX: ^~~~~~\n" "TEST PREFIX: ------\n" ), (pp_formatted_text (dc.printer))); } while (0) |
3366 | "TEST PREFIX: ^~~~~~\n"do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 3368, __FUNCTION__)), "\"TEST PREFIX: foo = bar.field;\\n\" \"TEST PREFIX: ^~~~~~\\n\" \"TEST PREFIX: ------\\n\"" , "pp_formatted_text (dc.printer)", ("TEST PREFIX: foo = bar.field;\n" "TEST PREFIX: ^~~~~~\n" "TEST PREFIX: ------\n" ), (pp_formatted_text (dc.printer))); } while (0) |
3367 | "TEST PREFIX: ------\n",do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 3368, __FUNCTION__)), "\"TEST PREFIX: foo = bar.field;\\n\" \"TEST PREFIX: ^~~~~~\\n\" \"TEST PREFIX: ------\\n\"" , "pp_formatted_text (dc.printer)", ("TEST PREFIX: foo = bar.field;\n" "TEST PREFIX: ^~~~~~\n" "TEST PREFIX: ------\n" ), (pp_formatted_text (dc.printer))); } while (0) |
3368 | pp_formatted_text (dc.printer))do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 3368, __FUNCTION__)), "\"TEST PREFIX: foo = bar.field;\\n\" \"TEST PREFIX: ^~~~~~\\n\" \"TEST PREFIX: ------\\n\"" , "pp_formatted_text (dc.printer)", ("TEST PREFIX: foo = bar.field;\n" "TEST PREFIX: ^~~~~~\n" "TEST PREFIX: ------\n" ), (pp_formatted_text (dc.printer))); } while (0); |
3369 | } |
3370 | |
3371 | /* Normal, with ruler. */ |
3372 | { |
3373 | test_diagnostic_context dc; |
3374 | dc.show_ruler_p = true; |
3375 | dc.caret_max_width = 104; |
3376 | diagnostic_show_locus (&dc, &richloc, DK_ERROR); |
3377 | ASSERT_STREQ (" 0 0 0 0 0 0 0 0 0 1 \n"do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 3383, __FUNCTION__)), "\" 0 0 0 0 0 0 0 0 0 1 \\n\" \" 1 2 3 4 5 6 7 8 9 0 \\n\" \" 12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234\\n\" \" foo = bar.field;\\n\" \" ^~~~~~\\n\" \" ------\\n\"" , "pp_formatted_text (dc.printer)", (" 0 0 0 0 0 0 0 0 0 1 \n" " 1 2 3 4 5 6 7 8 9 0 \n" " 12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234\n" " foo = bar.field;\n" " ^~~~~~\n" " ------\n" ), (pp_formatted_text (dc.printer))); } while (0) |
3378 | " 1 2 3 4 5 6 7 8 9 0 \n"do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 3383, __FUNCTION__)), "\" 0 0 0 0 0 0 0 0 0 1 \\n\" \" 1 2 3 4 5 6 7 8 9 0 \\n\" \" 12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234\\n\" \" foo = bar.field;\\n\" \" ^~~~~~\\n\" \" ------\\n\"" , "pp_formatted_text (dc.printer)", (" 0 0 0 0 0 0 0 0 0 1 \n" " 1 2 3 4 5 6 7 8 9 0 \n" " 12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234\n" " foo = bar.field;\n" " ^~~~~~\n" " ------\n" ), (pp_formatted_text (dc.printer))); } while (0) |
3379 | " 12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234\n"do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 3383, __FUNCTION__)), "\" 0 0 0 0 0 0 0 0 0 1 \\n\" \" 1 2 3 4 5 6 7 8 9 0 \\n\" \" 12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234\\n\" \" foo = bar.field;\\n\" \" ^~~~~~\\n\" \" ------\\n\"" , "pp_formatted_text (dc.printer)", (" 0 0 0 0 0 0 0 0 0 1 \n" " 1 2 3 4 5 6 7 8 9 0 \n" " 12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234\n" " foo = bar.field;\n" " ^~~~~~\n" " ------\n" ), (pp_formatted_text (dc.printer))); } while (0) |
3380 | " foo = bar.field;\n"do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 3383, __FUNCTION__)), "\" 0 0 0 0 0 0 0 0 0 1 \\n\" \" 1 2 3 4 5 6 7 8 9 0 \\n\" \" 12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234\\n\" \" foo = bar.field;\\n\" \" ^~~~~~\\n\" \" ------\\n\"" , "pp_formatted_text (dc.printer)", (" 0 0 0 0 0 0 0 0 0 1 \n" " 1 2 3 4 5 6 7 8 9 0 \n" " 12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234\n" " foo = bar.field;\n" " ^~~~~~\n" " ------\n" ), (pp_formatted_text (dc.printer))); } while (0) |
3381 | " ^~~~~~\n"do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 3383, __FUNCTION__)), "\" 0 0 0 0 0 0 0 0 0 1 \\n\" \" 1 2 3 4 5 6 7 8 9 0 \\n\" \" 12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234\\n\" \" foo = bar.field;\\n\" \" ^~~~~~\\n\" \" ------\\n\"" , "pp_formatted_text (dc.printer)", (" 0 0 0 0 0 0 0 0 0 1 \n" " 1 2 3 4 5 6 7 8 9 0 \n" " 12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234\n" " foo = bar.field;\n" " ^~~~~~\n" " ------\n" ), (pp_formatted_text (dc.printer))); } while (0) |
3382 | " ------\n",do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 3383, __FUNCTION__)), "\" 0 0 0 0 0 0 0 0 0 1 \\n\" \" 1 2 3 4 5 6 7 8 9 0 \\n\" \" 12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234\\n\" \" foo = bar.field;\\n\" \" ^~~~~~\\n\" \" ------\\n\"" , "pp_formatted_text (dc.printer)", (" 0 0 0 0 0 0 0 0 0 1 \n" " 1 2 3 4 5 6 7 8 9 0 \n" " 12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234\n" " foo = bar.field;\n" " ^~~~~~\n" " ------\n" ), (pp_formatted_text (dc.printer))); } while (0) |
3383 | pp_formatted_text (dc.printer))do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 3383, __FUNCTION__)), "\" 0 0 0 0 0 0 0 0 0 1 \\n\" \" 1 2 3 4 5 6 7 8 9 0 \\n\" \" 12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234\\n\" \" foo = bar.field;\\n\" \" ^~~~~~\\n\" \" ------\\n\"" , "pp_formatted_text (dc.printer)", (" 0 0 0 0 0 0 0 0 0 1 \n" " 1 2 3 4 5 6 7 8 9 0 \n" " 12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234\n" " foo = bar.field;\n" " ^~~~~~\n" " ------\n" ), (pp_formatted_text (dc.printer))); } while (0); |
3384 | } |
3385 | |
3386 | /* Test of adding a prefix, with ruler. */ |
3387 | { |
3388 | test_diagnostic_context dc; |
3389 | dc.show_ruler_p = true; |
3390 | dc.caret_max_width = 50; |
3391 | pp_prefixing_rule (dc.printer)(dc.printer)->wrapping.rule = DIAGNOSTICS_SHOW_PREFIX_EVERY_LINE; |
3392 | pp_set_prefix (dc.printer, xstrdup ("TEST PREFIX:")); |
3393 | diagnostic_show_locus (&dc, &richloc, DK_ERROR); |
3394 | ASSERT_STREQ ("TEST PREFIX: 1 2 3 4 5\n"do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 3399, __FUNCTION__)), "\"TEST PREFIX: 1 2 3 4 5\\n\" \"TEST PREFIX: 12345678901234567890123456789012345678901234567890\\n\" \"TEST PREFIX: foo = bar.field;\\n\" \"TEST PREFIX: ^~~~~~\\n\" \"TEST PREFIX: ------\\n\"" , "pp_formatted_text (dc.printer)", ("TEST PREFIX: 1 2 3 4 5\n" "TEST PREFIX: 12345678901234567890123456789012345678901234567890\n" "TEST PREFIX: foo = bar.field;\n" "TEST PREFIX: ^~~~~~\n" "TEST PREFIX: ------\n"), (pp_formatted_text (dc.printer ))); } while (0) |
3395 | "TEST PREFIX: 12345678901234567890123456789012345678901234567890\n"do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 3399, __FUNCTION__)), "\"TEST PREFIX: 1 2 3 4 5\\n\" \"TEST PREFIX: 12345678901234567890123456789012345678901234567890\\n\" \"TEST PREFIX: foo = bar.field;\\n\" \"TEST PREFIX: ^~~~~~\\n\" \"TEST PREFIX: ------\\n\"" , "pp_formatted_text (dc.printer)", ("TEST PREFIX: 1 2 3 4 5\n" "TEST PREFIX: 12345678901234567890123456789012345678901234567890\n" "TEST PREFIX: foo = bar.field;\n" "TEST PREFIX: ^~~~~~\n" "TEST PREFIX: ------\n"), (pp_formatted_text (dc.printer ))); } while (0) |
3396 | "TEST PREFIX: foo = bar.field;\n"do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 3399, __FUNCTION__)), "\"TEST PREFIX: 1 2 3 4 5\\n\" \"TEST PREFIX: 12345678901234567890123456789012345678901234567890\\n\" \"TEST PREFIX: foo = bar.field;\\n\" \"TEST PREFIX: ^~~~~~\\n\" \"TEST PREFIX: ------\\n\"" , "pp_formatted_text (dc.printer)", ("TEST PREFIX: 1 2 3 4 5\n" "TEST PREFIX: 12345678901234567890123456789012345678901234567890\n" "TEST PREFIX: foo = bar.field;\n" "TEST PREFIX: ^~~~~~\n" "TEST PREFIX: ------\n"), (pp_formatted_text (dc.printer ))); } while (0) |
3397 | "TEST PREFIX: ^~~~~~\n"do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 3399, __FUNCTION__)), "\"TEST PREFIX: 1 2 3 4 5\\n\" \"TEST PREFIX: 12345678901234567890123456789012345678901234567890\\n\" \"TEST PREFIX: foo = bar.field;\\n\" \"TEST PREFIX: ^~~~~~\\n\" \"TEST PREFIX: ------\\n\"" , "pp_formatted_text (dc.printer)", ("TEST PREFIX: 1 2 3 4 5\n" "TEST PREFIX: 12345678901234567890123456789012345678901234567890\n" "TEST PREFIX: foo = bar.field;\n" "TEST PREFIX: ^~~~~~\n" "TEST PREFIX: ------\n"), (pp_formatted_text (dc.printer ))); } while (0) |
3398 | "TEST PREFIX: ------\n",do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 3399, __FUNCTION__)), "\"TEST PREFIX: 1 2 3 4 5\\n\" \"TEST PREFIX: 12345678901234567890123456789012345678901234567890\\n\" \"TEST PREFIX: foo = bar.field;\\n\" \"TEST PREFIX: ^~~~~~\\n\" \"TEST PREFIX: ------\\n\"" , "pp_formatted_text (dc.printer)", ("TEST PREFIX: 1 2 3 4 5\n" "TEST PREFIX: 12345678901234567890123456789012345678901234567890\n" "TEST PREFIX: foo = bar.field;\n" "TEST PREFIX: ^~~~~~\n" "TEST PREFIX: ------\n"), (pp_formatted_text (dc.printer ))); } while (0) |
3399 | pp_formatted_text (dc.printer))do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 3399, __FUNCTION__)), "\"TEST PREFIX: 1 2 3 4 5\\n\" \"TEST PREFIX: 12345678901234567890123456789012345678901234567890\\n\" \"TEST PREFIX: foo = bar.field;\\n\" \"TEST PREFIX: ^~~~~~\\n\" \"TEST PREFIX: ------\\n\"" , "pp_formatted_text (dc.printer)", ("TEST PREFIX: 1 2 3 4 5\n" "TEST PREFIX: 12345678901234567890123456789012345678901234567890\n" "TEST PREFIX: foo = bar.field;\n" "TEST PREFIX: ^~~~~~\n" "TEST PREFIX: ------\n"), (pp_formatted_text (dc.printer ))); } while (0); |
3400 | } |
3401 | |
3402 | /* Test of adding a prefix, with ruler and line numbers. */ |
3403 | { |
3404 | test_diagnostic_context dc; |
3405 | dc.show_ruler_p = true; |
3406 | dc.caret_max_width = 50; |
3407 | dc.show_line_numbers_p = true; |
3408 | pp_prefixing_rule (dc.printer)(dc.printer)->wrapping.rule = DIAGNOSTICS_SHOW_PREFIX_EVERY_LINE; |
3409 | pp_set_prefix (dc.printer, xstrdup ("TEST PREFIX:")); |
3410 | diagnostic_show_locus (&dc, &richloc, DK_ERROR); |
3411 | ASSERT_STREQ ("TEST PREFIX: | 1 2 3 4 5\n"do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 3416, __FUNCTION__)), "\"TEST PREFIX: | 1 2 3 4 5\\n\" \"TEST PREFIX: | 12345678901234567890123456789012345678901234567890\\n\" \"TEST PREFIX: 1 | foo = bar.field;\\n\" \"TEST PREFIX: | ^~~~~~\\n\" \"TEST PREFIX: | ------\\n\"" , "pp_formatted_text (dc.printer)", ("TEST PREFIX: | 1 2 3 4 5\n" "TEST PREFIX: | 12345678901234567890123456789012345678901234567890\n" "TEST PREFIX: 1 | foo = bar.field;\n" "TEST PREFIX: | ^~~~~~\n" "TEST PREFIX: | ------\n"), (pp_formatted_text (dc.printer))); } while (0) |
3412 | "TEST PREFIX: | 12345678901234567890123456789012345678901234567890\n"do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 3416, __FUNCTION__)), "\"TEST PREFIX: | 1 2 3 4 5\\n\" \"TEST PREFIX: | 12345678901234567890123456789012345678901234567890\\n\" \"TEST PREFIX: 1 | foo = bar.field;\\n\" \"TEST PREFIX: | ^~~~~~\\n\" \"TEST PREFIX: | ------\\n\"" , "pp_formatted_text (dc.printer)", ("TEST PREFIX: | 1 2 3 4 5\n" "TEST PREFIX: | 12345678901234567890123456789012345678901234567890\n" "TEST PREFIX: 1 | foo = bar.field;\n" "TEST PREFIX: | ^~~~~~\n" "TEST PREFIX: | ------\n"), (pp_formatted_text (dc.printer))); } while (0) |
3413 | "TEST PREFIX: 1 | foo = bar.field;\n"do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 3416, __FUNCTION__)), "\"TEST PREFIX: | 1 2 3 4 5\\n\" \"TEST PREFIX: | 12345678901234567890123456789012345678901234567890\\n\" \"TEST PREFIX: 1 | foo = bar.field;\\n\" \"TEST PREFIX: | ^~~~~~\\n\" \"TEST PREFIX: | ------\\n\"" , "pp_formatted_text (dc.printer)", ("TEST PREFIX: | 1 2 3 4 5\n" "TEST PREFIX: | 12345678901234567890123456789012345678901234567890\n" "TEST PREFIX: 1 | foo = bar.field;\n" "TEST PREFIX: | ^~~~~~\n" "TEST PREFIX: | ------\n"), (pp_formatted_text (dc.printer))); } while (0) |
3414 | "TEST PREFIX: | ^~~~~~\n"do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 3416, __FUNCTION__)), "\"TEST PREFIX: | 1 2 3 4 5\\n\" \"TEST PREFIX: | 12345678901234567890123456789012345678901234567890\\n\" \"TEST PREFIX: 1 | foo = bar.field;\\n\" \"TEST PREFIX: | ^~~~~~\\n\" \"TEST PREFIX: | ------\\n\"" , "pp_formatted_text (dc.printer)", ("TEST PREFIX: | 1 2 3 4 5\n" "TEST PREFIX: | 12345678901234567890123456789012345678901234567890\n" "TEST PREFIX: 1 | foo = bar.field;\n" "TEST PREFIX: | ^~~~~~\n" "TEST PREFIX: | ------\n"), (pp_formatted_text (dc.printer))); } while (0) |
3415 | "TEST PREFIX: | ------\n",do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 3416, __FUNCTION__)), "\"TEST PREFIX: | 1 2 3 4 5\\n\" \"TEST PREFIX: | 12345678901234567890123456789012345678901234567890\\n\" \"TEST PREFIX: 1 | foo = bar.field;\\n\" \"TEST PREFIX: | ^~~~~~\\n\" \"TEST PREFIX: | ------\\n\"" , "pp_formatted_text (dc.printer)", ("TEST PREFIX: | 1 2 3 4 5\n" "TEST PREFIX: | 12345678901234567890123456789012345678901234567890\n" "TEST PREFIX: 1 | foo = bar.field;\n" "TEST PREFIX: | ^~~~~~\n" "TEST PREFIX: | ------\n"), (pp_formatted_text (dc.printer))); } while (0) |
3416 | pp_formatted_text (dc.printer))do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 3416, __FUNCTION__)), "\"TEST PREFIX: | 1 2 3 4 5\\n\" \"TEST PREFIX: | 12345678901234567890123456789012345678901234567890\\n\" \"TEST PREFIX: 1 | foo = bar.field;\\n\" \"TEST PREFIX: | ^~~~~~\\n\" \"TEST PREFIX: | ------\\n\"" , "pp_formatted_text (dc.printer)", ("TEST PREFIX: | 1 2 3 4 5\n" "TEST PREFIX: | 12345678901234567890123456789012345678901234567890\n" "TEST PREFIX: 1 | foo = bar.field;\n" "TEST PREFIX: | ^~~~~~\n" "TEST PREFIX: | ------\n"), (pp_formatted_text (dc.printer))); } while (0); |
3417 | } |
3418 | } |
3419 | |
3420 | /* Replace fix-it hint: replacing "field" with "m_field". */ |
3421 | |
3422 | static void |
3423 | test_one_liner_fixit_replace () |
3424 | { |
3425 | test_diagnostic_context dc; |
3426 | location_t start = linemap_position_for_column (line_table, 11); |
3427 | location_t finish = linemap_position_for_column (line_table, 15); |
3428 | location_t field = make_location (start, start, finish); |
3429 | rich_location richloc (line_table, field); |
3430 | richloc.add_fixit_replace ("m_field"); |
3431 | diagnostic_show_locus (&dc, &richloc, DK_ERROR); |
3432 | ASSERT_STREQ (" foo = bar.field;\n"do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 3435, __FUNCTION__)), "\" foo = bar.field;\\n\" \" ^~~~~\\n\" \" m_field\\n\"" , "pp_formatted_text (dc.printer)", (" foo = bar.field;\n" " ^~~~~\n" " m_field\n"), (pp_formatted_text (dc.printer))); } while (0) |
3433 | " ^~~~~\n"do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 3435, __FUNCTION__)), "\" foo = bar.field;\\n\" \" ^~~~~\\n\" \" m_field\\n\"" , "pp_formatted_text (dc.printer)", (" foo = bar.field;\n" " ^~~~~\n" " m_field\n"), (pp_formatted_text (dc.printer))); } while (0) |
3434 | " m_field\n",do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 3435, __FUNCTION__)), "\" foo = bar.field;\\n\" \" ^~~~~\\n\" \" m_field\\n\"" , "pp_formatted_text (dc.printer)", (" foo = bar.field;\n" " ^~~~~\n" " m_field\n"), (pp_formatted_text (dc.printer))); } while (0) |
3435 | pp_formatted_text (dc.printer))do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 3435, __FUNCTION__)), "\" foo = bar.field;\\n\" \" ^~~~~\\n\" \" m_field\\n\"" , "pp_formatted_text (dc.printer)", (" foo = bar.field;\n" " ^~~~~\n" " m_field\n"), (pp_formatted_text (dc.printer))); } while (0); |
3436 | } |
3437 | |
3438 | /* Replace fix-it hint: replacing "field" with "m_field", |
3439 | but where the caret was elsewhere. */ |
3440 | |
3441 | static void |
3442 | test_one_liner_fixit_replace_non_equal_range () |
3443 | { |
3444 | test_diagnostic_context dc; |
3445 | location_t equals = linemap_position_for_column (line_table, 5); |
3446 | location_t start = linemap_position_for_column (line_table, 11); |
3447 | location_t finish = linemap_position_for_column (line_table, 15); |
3448 | rich_location richloc (line_table, equals); |
3449 | source_range range; |
3450 | range.m_start = start; |
3451 | range.m_finish = finish; |
3452 | richloc.add_fixit_replace (range, "m_field"); |
3453 | diagnostic_show_locus (&dc, &richloc, DK_ERROR); |
3454 | /* The replacement range is not indicated in the annotation line, so |
3455 | it should be indicated via an additional underline. */ |
3456 | ASSERT_STREQ (" foo = bar.field;\n"do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 3460, __FUNCTION__)), "\" foo = bar.field;\\n\" \" ^\\n\" \" -----\\n\" \" m_field\\n\"" , "pp_formatted_text (dc.printer)", (" foo = bar.field;\n" " ^\n" " -----\n" " m_field\n"), (pp_formatted_text (dc.printer))); } while (0) |
3457 | " ^\n"do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 3460, __FUNCTION__)), "\" foo = bar.field;\\n\" \" ^\\n\" \" -----\\n\" \" m_field\\n\"" , "pp_formatted_text (dc.printer)", (" foo = bar.field;\n" " ^\n" " -----\n" " m_field\n"), (pp_formatted_text (dc.printer))); } while (0) |
3458 | " -----\n"do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 3460, __FUNCTION__)), "\" foo = bar.field;\\n\" \" ^\\n\" \" -----\\n\" \" m_field\\n\"" , "pp_formatted_text (dc.printer)", (" foo = bar.field;\n" " ^\n" " -----\n" " m_field\n"), (pp_formatted_text (dc.printer))); } while (0) |
3459 | " m_field\n",do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 3460, __FUNCTION__)), "\" foo = bar.field;\\n\" \" ^\\n\" \" -----\\n\" \" m_field\\n\"" , "pp_formatted_text (dc.printer)", (" foo = bar.field;\n" " ^\n" " -----\n" " m_field\n"), (pp_formatted_text (dc.printer))); } while (0) |
3460 | pp_formatted_text (dc.printer))do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 3460, __FUNCTION__)), "\" foo = bar.field;\\n\" \" ^\\n\" \" -----\\n\" \" m_field\\n\"" , "pp_formatted_text (dc.printer)", (" foo = bar.field;\n" " ^\n" " -----\n" " m_field\n"), (pp_formatted_text (dc.printer))); } while (0); |
3461 | } |
3462 | |
3463 | /* Replace fix-it hint: replacing "field" with "m_field", |
3464 | where the caret was elsewhere, but where a secondary range |
3465 | exactly covers "field". */ |
3466 | |
3467 | static void |
3468 | test_one_liner_fixit_replace_equal_secondary_range () |
3469 | { |
3470 | test_diagnostic_context dc; |
3471 | location_t equals = linemap_position_for_column (line_table, 5); |
3472 | location_t start = linemap_position_for_column (line_table, 11); |
3473 | location_t finish = linemap_position_for_column (line_table, 15); |
3474 | rich_location richloc (line_table, equals); |
3475 | location_t field = make_location (start, start, finish); |
3476 | richloc.add_range (field); |
3477 | richloc.add_fixit_replace (field, "m_field"); |
3478 | diagnostic_show_locus (&dc, &richloc, DK_ERROR); |
3479 | /* The replacement range is indicated in the annotation line, |
3480 | so it shouldn't be indicated via an additional underline. */ |
3481 | ASSERT_STREQ (" foo = bar.field;\n"do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 3484, __FUNCTION__)), "\" foo = bar.field;\\n\" \" ^ ~~~~~\\n\" \" m_field\\n\"" , "pp_formatted_text (dc.printer)", (" foo = bar.field;\n" " ^ ~~~~~\n" " m_field\n"), (pp_formatted_text (dc.printer))); } while (0) |
3482 | " ^ ~~~~~\n"do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 3484, __FUNCTION__)), "\" foo = bar.field;\\n\" \" ^ ~~~~~\\n\" \" m_field\\n\"" , "pp_formatted_text (dc.printer)", (" foo = bar.field;\n" " ^ ~~~~~\n" " m_field\n"), (pp_formatted_text (dc.printer))); } while (0) |
3483 | " m_field\n",do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 3484, __FUNCTION__)), "\" foo = bar.field;\\n\" \" ^ ~~~~~\\n\" \" m_field\\n\"" , "pp_formatted_text (dc.printer)", (" foo = bar.field;\n" " ^ ~~~~~\n" " m_field\n"), (pp_formatted_text (dc.printer))); } while (0) |
3484 | pp_formatted_text (dc.printer))do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 3484, __FUNCTION__)), "\" foo = bar.field;\\n\" \" ^ ~~~~~\\n\" \" m_field\\n\"" , "pp_formatted_text (dc.printer)", (" foo = bar.field;\n" " ^ ~~~~~\n" " m_field\n"), (pp_formatted_text (dc.printer))); } while (0); |
3485 | } |
3486 | |
3487 | /* Verify that we can use ad-hoc locations when adding fixits to a |
3488 | rich_location. */ |
3489 | |
3490 | static void |
3491 | test_one_liner_fixit_validation_adhoc_locations () |
3492 | { |
3493 | /* Generate a range that's too long to be packed, so must |
3494 | be stored as an ad-hoc location (given the defaults |
3495 | of 5 bits or 0 bits of packed range); 41 columns > 2**5. */ |
3496 | const location_t c7 = linemap_position_for_column (line_table, 7); |
3497 | const location_t c47 = linemap_position_for_column (line_table, 47); |
3498 | const location_t loc = make_location (c7, c7, c47); |
3499 | |
3500 | if (c47 > LINE_MAP_MAX_LOCATION_WITH_COLS) |
3501 | return; |
3502 | |
3503 | ASSERT_TRUE (IS_ADHOC_LOC (loc))do { const char *desc_ = "ASSERT_TRUE (" "(IS_ADHOC_LOC (loc))" ")"; bool actual_ = ((IS_ADHOC_LOC (loc))); if (actual_) ::selftest ::pass (((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 3503, __FUNCTION__))), desc_); else ::selftest::fail (((::selftest ::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 3503, __FUNCTION__))), desc_); } while (0); |
3504 | |
3505 | /* Insert. */ |
3506 | { |
3507 | rich_location richloc (line_table, loc); |
3508 | richloc.add_fixit_insert_before (loc, "test"); |
3509 | /* It should not have been discarded by the validator. */ |
3510 | ASSERT_EQ (1, richloc.get_num_fixit_hints ())do { const char *desc_ = "ASSERT_EQ (" "(1)" ", " "(richloc.get_num_fixit_hints ())" ")"; if (((1)) == ((richloc.get_num_fixit_hints ()))) ::selftest ::pass ((((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 3510, __FUNCTION__)))), desc_); else ::selftest::fail ((((:: selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 3510, __FUNCTION__)))), desc_); } while (0); |
3511 | |
3512 | test_diagnostic_context dc; |
3513 | diagnostic_show_locus (&dc, &richloc, DK_ERROR); |
3514 | ASSERT_STREQ (" foo = bar.field;\n"do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 3517, __FUNCTION__)), "\" foo = bar.field;\\n\" \" ^~~~~~~~~~ \\n\" \" test\\n\"" , "pp_formatted_text (dc.printer)", (" foo = bar.field;\n" " ^~~~~~~~~~ \n" " test\n"), (pp_formatted_text (dc.printer))); } while (0) |
3515 | " ^~~~~~~~~~ \n"do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 3517, __FUNCTION__)), "\" foo = bar.field;\\n\" \" ^~~~~~~~~~ \\n\" \" test\\n\"" , "pp_formatted_text (dc.printer)", (" foo = bar.field;\n" " ^~~~~~~~~~ \n" " test\n"), (pp_formatted_text (dc.printer))); } while (0) |
3516 | " test\n",do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 3517, __FUNCTION__)), "\" foo = bar.field;\\n\" \" ^~~~~~~~~~ \\n\" \" test\\n\"" , "pp_formatted_text (dc.printer)", (" foo = bar.field;\n" " ^~~~~~~~~~ \n" " test\n"), (pp_formatted_text (dc.printer))); } while (0) |
3517 | pp_formatted_text (dc.printer))do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 3517, __FUNCTION__)), "\" foo = bar.field;\\n\" \" ^~~~~~~~~~ \\n\" \" test\\n\"" , "pp_formatted_text (dc.printer)", (" foo = bar.field;\n" " ^~~~~~~~~~ \n" " test\n"), (pp_formatted_text (dc.printer))); } while (0); |
3518 | } |
3519 | |
3520 | /* Remove. */ |
3521 | { |
3522 | rich_location richloc (line_table, loc); |
3523 | source_range range = source_range::from_locations (loc, c47); |
3524 | richloc.add_fixit_remove (range); |
3525 | /* It should not have been discarded by the validator. */ |
3526 | ASSERT_EQ (1, richloc.get_num_fixit_hints ())do { const char *desc_ = "ASSERT_EQ (" "(1)" ", " "(richloc.get_num_fixit_hints ())" ")"; if (((1)) == ((richloc.get_num_fixit_hints ()))) ::selftest ::pass ((((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 3526, __FUNCTION__)))), desc_); else ::selftest::fail ((((:: selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 3526, __FUNCTION__)))), desc_); } while (0); |
3527 | |
3528 | test_diagnostic_context dc; |
3529 | diagnostic_show_locus (&dc, &richloc, DK_ERROR); |
3530 | ASSERT_STREQ (" foo = bar.field;\n"do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 3533, __FUNCTION__)), "\" foo = bar.field;\\n\" \" ^~~~~~~~~~ \\n\" \" -----------------------------------------\\n\"" , "pp_formatted_text (dc.printer)", (" foo = bar.field;\n" " ^~~~~~~~~~ \n" " -----------------------------------------\n"), (pp_formatted_text (dc.printer))); } while (0) |
3531 | " ^~~~~~~~~~ \n"do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 3533, __FUNCTION__)), "\" foo = bar.field;\\n\" \" ^~~~~~~~~~ \\n\" \" -----------------------------------------\\n\"" , "pp_formatted_text (dc.printer)", (" foo = bar.field;\n" " ^~~~~~~~~~ \n" " -----------------------------------------\n"), (pp_formatted_text (dc.printer))); } while (0) |
3532 | " -----------------------------------------\n",do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 3533, __FUNCTION__)), "\" foo = bar.field;\\n\" \" ^~~~~~~~~~ \\n\" \" -----------------------------------------\\n\"" , "pp_formatted_text (dc.printer)", (" foo = bar.field;\n" " ^~~~~~~~~~ \n" " -----------------------------------------\n"), (pp_formatted_text (dc.printer))); } while (0) |
3533 | pp_formatted_text (dc.printer))do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 3533, __FUNCTION__)), "\" foo = bar.field;\\n\" \" ^~~~~~~~~~ \\n\" \" -----------------------------------------\\n\"" , "pp_formatted_text (dc.printer)", (" foo = bar.field;\n" " ^~~~~~~~~~ \n" " -----------------------------------------\n"), (pp_formatted_text (dc.printer))); } while (0); |
3534 | } |
3535 | |
3536 | /* Replace. */ |
3537 | { |
3538 | rich_location richloc (line_table, loc); |
3539 | source_range range = source_range::from_locations (loc, c47); |
3540 | richloc.add_fixit_replace (range, "test"); |
3541 | /* It should not have been discarded by the validator. */ |
3542 | ASSERT_EQ (1, richloc.get_num_fixit_hints ())do { const char *desc_ = "ASSERT_EQ (" "(1)" ", " "(richloc.get_num_fixit_hints ())" ")"; if (((1)) == ((richloc.get_num_fixit_hints ()))) ::selftest ::pass ((((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 3542, __FUNCTION__)))), desc_); else ::selftest::fail ((((:: selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 3542, __FUNCTION__)))), desc_); } while (0); |
3543 | |
3544 | test_diagnostic_context dc; |
3545 | diagnostic_show_locus (&dc, &richloc, DK_ERROR); |
3546 | ASSERT_STREQ (" foo = bar.field;\n"do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 3549, __FUNCTION__)), "\" foo = bar.field;\\n\" \" ^~~~~~~~~~ \\n\" \" test\\n\"" , "pp_formatted_text (dc.printer)", (" foo = bar.field;\n" " ^~~~~~~~~~ \n" " test\n"), (pp_formatted_text (dc.printer))); } while (0) |
3547 | " ^~~~~~~~~~ \n"do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 3549, __FUNCTION__)), "\" foo = bar.field;\\n\" \" ^~~~~~~~~~ \\n\" \" test\\n\"" , "pp_formatted_text (dc.printer)", (" foo = bar.field;\n" " ^~~~~~~~~~ \n" " test\n"), (pp_formatted_text (dc.printer))); } while (0) |
3548 | " test\n",do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 3549, __FUNCTION__)), "\" foo = bar.field;\\n\" \" ^~~~~~~~~~ \\n\" \" test\\n\"" , "pp_formatted_text (dc.printer)", (" foo = bar.field;\n" " ^~~~~~~~~~ \n" " test\n"), (pp_formatted_text (dc.printer))); } while (0) |
3549 | pp_formatted_text (dc.printer))do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 3549, __FUNCTION__)), "\" foo = bar.field;\\n\" \" ^~~~~~~~~~ \\n\" \" test\\n\"" , "pp_formatted_text (dc.printer)", (" foo = bar.field;\n" " ^~~~~~~~~~ \n" " test\n"), (pp_formatted_text (dc.printer))); } while (0); |
3550 | } |
3551 | } |
3552 | |
3553 | /* Test of consolidating insertions at the same location. */ |
3554 | |
3555 | static void |
3556 | test_one_liner_many_fixits_1 () |
3557 | { |
3558 | test_diagnostic_context dc; |
3559 | location_t equals = linemap_position_for_column (line_table, 5); |
3560 | rich_location richloc (line_table, equals); |
3561 | for (int i = 0; i < 19; i++) |
3562 | richloc.add_fixit_insert_before ("a"); |
3563 | ASSERT_EQ (1, richloc.get_num_fixit_hints ())do { const char *desc_ = "ASSERT_EQ (" "(1)" ", " "(richloc.get_num_fixit_hints ())" ")"; if (((1)) == ((richloc.get_num_fixit_hints ()))) ::selftest ::pass ((((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 3563, __FUNCTION__)))), desc_); else ::selftest::fail ((((:: selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 3563, __FUNCTION__)))), desc_); } while (0); |
3564 | diagnostic_show_locus (&dc, &richloc, DK_ERROR); |
3565 | ASSERT_STREQ (" foo = bar.field;\n"do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 3568, __FUNCTION__)), "\" foo = bar.field;\\n\" \" ^\\n\" \" aaaaaaaaaaaaaaaaaaa\\n\"" , "pp_formatted_text (dc.printer)", (" foo = bar.field;\n" " ^\n" " aaaaaaaaaaaaaaaaaaa\n"), (pp_formatted_text (dc.printer ))); } while (0) |
3566 | " ^\n"do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 3568, __FUNCTION__)), "\" foo = bar.field;\\n\" \" ^\\n\" \" aaaaaaaaaaaaaaaaaaa\\n\"" , "pp_formatted_text (dc.printer)", (" foo = bar.field;\n" " ^\n" " aaaaaaaaaaaaaaaaaaa\n"), (pp_formatted_text (dc.printer ))); } while (0) |
3567 | " aaaaaaaaaaaaaaaaaaa\n",do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 3568, __FUNCTION__)), "\" foo = bar.field;\\n\" \" ^\\n\" \" aaaaaaaaaaaaaaaaaaa\\n\"" , "pp_formatted_text (dc.printer)", (" foo = bar.field;\n" " ^\n" " aaaaaaaaaaaaaaaaaaa\n"), (pp_formatted_text (dc.printer ))); } while (0) |
3568 | pp_formatted_text (dc.printer))do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 3568, __FUNCTION__)), "\" foo = bar.field;\\n\" \" ^\\n\" \" aaaaaaaaaaaaaaaaaaa\\n\"" , "pp_formatted_text (dc.printer)", (" foo = bar.field;\n" " ^\n" " aaaaaaaaaaaaaaaaaaa\n"), (pp_formatted_text (dc.printer ))); } while (0); |
3569 | } |
3570 | |
3571 | /* Ensure that we can add an arbitrary number of fix-it hints to a |
3572 | rich_location, even if they are not consolidated. */ |
3573 | |
3574 | static void |
3575 | test_one_liner_many_fixits_2 () |
3576 | { |
3577 | test_diagnostic_context dc; |
3578 | location_t equals = linemap_position_for_column (line_table, 5); |
3579 | rich_location richloc (line_table, equals); |
3580 | for (int i = 0; i < 19; i++) |
3581 | { |
3582 | location_t loc = linemap_position_for_column (line_table, (i * 2) + 1); |
3583 | richloc.add_fixit_insert_before (loc, "a"); |
3584 | } |
3585 | ASSERT_EQ (19, richloc.get_num_fixit_hints ())do { const char *desc_ = "ASSERT_EQ (" "(19)" ", " "(richloc.get_num_fixit_hints ())" ")"; if (((19)) == ((richloc.get_num_fixit_hints ()))) ::selftest ::pass ((((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 3585, __FUNCTION__)))), desc_); else ::selftest::fail ((((:: selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 3585, __FUNCTION__)))), desc_); } while (0); |
3586 | diagnostic_show_locus (&dc, &richloc, DK_ERROR); |
3587 | ASSERT_STREQ (" foo = bar.field;\n"do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 3590, __FUNCTION__)), "\" foo = bar.field;\\n\" \" ^\\n\" \" a a a a a a a a a a a a a a a a a a a\\n\"" , "pp_formatted_text (dc.printer)", (" foo = bar.field;\n" " ^\n" " a a a a a a a a a a a a a a a a a a a\n"), (pp_formatted_text (dc.printer))); } while (0) |
3588 | " ^\n"do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 3590, __FUNCTION__)), "\" foo = bar.field;\\n\" \" ^\\n\" \" a a a a a a a a a a a a a a a a a a a\\n\"" , "pp_formatted_text (dc.printer)", (" foo = bar.field;\n" " ^\n" " a a a a a a a a a a a a a a a a a a a\n"), (pp_formatted_text (dc.printer))); } while (0) |
3589 | " a a a a a a a a a a a a a a a a a a a\n",do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 3590, __FUNCTION__)), "\" foo = bar.field;\\n\" \" ^\\n\" \" a a a a a a a a a a a a a a a a a a a\\n\"" , "pp_formatted_text (dc.printer)", (" foo = bar.field;\n" " ^\n" " a a a a a a a a a a a a a a a a a a a\n"), (pp_formatted_text (dc.printer))); } while (0) |
3590 | pp_formatted_text (dc.printer))do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 3590, __FUNCTION__)), "\" foo = bar.field;\\n\" \" ^\\n\" \" a a a a a a a a a a a a a a a a a a a\\n\"" , "pp_formatted_text (dc.printer)", (" foo = bar.field;\n" " ^\n" " a a a a a a a a a a a a a a a a a a a\n"), (pp_formatted_text (dc.printer))); } while (0); |
3591 | } |
3592 | |
3593 | /* Test of labeling the ranges within a rich_location. */ |
3594 | |
3595 | static void |
3596 | test_one_liner_labels () |
3597 | { |
3598 | location_t foo |
3599 | = make_location (linemap_position_for_column (line_table, 1), |
3600 | linemap_position_for_column (line_table, 1), |
3601 | linemap_position_for_column (line_table, 3)); |
3602 | location_t bar |
3603 | = make_location (linemap_position_for_column (line_table, 7), |
3604 | linemap_position_for_column (line_table, 7), |
3605 | linemap_position_for_column (line_table, 9)); |
3606 | location_t field |
3607 | = make_location (linemap_position_for_column (line_table, 11), |
3608 | linemap_position_for_column (line_table, 11), |
3609 | linemap_position_for_column (line_table, 15)); |
3610 | |
3611 | /* Example where all the labels fit on one line. */ |
3612 | { |
3613 | text_range_label label0 ("0"); |
3614 | text_range_label label1 ("1"); |
3615 | text_range_label label2 ("2"); |
3616 | gcc_rich_location richloc (foo, &label0); |
3617 | richloc.add_range (bar, SHOW_RANGE_WITHOUT_CARET, &label1); |
3618 | richloc.add_range (field, SHOW_RANGE_WITHOUT_CARET, &label2); |
3619 | |
3620 | { |
3621 | test_diagnostic_context dc; |
3622 | diagnostic_show_locus (&dc, &richloc, DK_ERROR); |
3623 | ASSERT_STREQ (" foo = bar.field;\n"do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 3627, __FUNCTION__)), "\" foo = bar.field;\\n\" \" ^~~ ~~~ ~~~~~\\n\" \" | | |\\n\" \" 0 1 2\\n\"" , "pp_formatted_text (dc.printer)", (" foo = bar.field;\n" " ^~~ ~~~ ~~~~~\n" " | | |\n" " 0 1 2\n"), (pp_formatted_text (dc.printer ))); } while (0) |
3624 | " ^~~ ~~~ ~~~~~\n"do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 3627, __FUNCTION__)), "\" foo = bar.field;\\n\" \" ^~~ ~~~ ~~~~~\\n\" \" | | |\\n\" \" 0 1 2\\n\"" , "pp_formatted_text (dc.printer)", (" foo = bar.field;\n" " ^~~ ~~~ ~~~~~\n" " | | |\n" " 0 1 2\n"), (pp_formatted_text (dc.printer ))); } while (0) |
3625 | " | | |\n"do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 3627, __FUNCTION__)), "\" foo = bar.field;\\n\" \" ^~~ ~~~ ~~~~~\\n\" \" | | |\\n\" \" 0 1 2\\n\"" , "pp_formatted_text (dc.printer)", (" foo = bar.field;\n" " ^~~ ~~~ ~~~~~\n" " | | |\n" " 0 1 2\n"), (pp_formatted_text (dc.printer ))); } while (0) |
3626 | " 0 1 2\n",do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 3627, __FUNCTION__)), "\" foo = bar.field;\\n\" \" ^~~ ~~~ ~~~~~\\n\" \" | | |\\n\" \" 0 1 2\\n\"" , "pp_formatted_text (dc.printer)", (" foo = bar.field;\n" " ^~~ ~~~ ~~~~~\n" " | | |\n" " 0 1 2\n"), (pp_formatted_text (dc.printer ))); } while (0) |
3627 | pp_formatted_text (dc.printer))do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 3627, __FUNCTION__)), "\" foo = bar.field;\\n\" \" ^~~ ~~~ ~~~~~\\n\" \" | | |\\n\" \" 0 1 2\\n\"" , "pp_formatted_text (dc.printer)", (" foo = bar.field;\n" " ^~~ ~~~ ~~~~~\n" " | | |\n" " 0 1 2\n"), (pp_formatted_text (dc.printer ))); } while (0); |
3628 | } |
3629 | |
3630 | /* Verify that we can disable label-printing. */ |
3631 | { |
3632 | test_diagnostic_context dc; |
3633 | dc.show_labels_p = false; |
3634 | diagnostic_show_locus (&dc, &richloc, DK_ERROR); |
3635 | ASSERT_STREQ (" foo = bar.field;\n"do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 3637, __FUNCTION__)), "\" foo = bar.field;\\n\" \" ^~~ ~~~ ~~~~~\\n\"" , "pp_formatted_text (dc.printer)", (" foo = bar.field;\n" " ^~~ ~~~ ~~~~~\n" ), (pp_formatted_text (dc.printer))); } while (0) |
3636 | " ^~~ ~~~ ~~~~~\n",do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 3637, __FUNCTION__)), "\" foo = bar.field;\\n\" \" ^~~ ~~~ ~~~~~\\n\"" , "pp_formatted_text (dc.printer)", (" foo = bar.field;\n" " ^~~ ~~~ ~~~~~\n" ), (pp_formatted_text (dc.printer))); } while (0) |
3637 | pp_formatted_text (dc.printer))do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 3637, __FUNCTION__)), "\" foo = bar.field;\\n\" \" ^~~ ~~~ ~~~~~\\n\"" , "pp_formatted_text (dc.printer)", (" foo = bar.field;\n" " ^~~ ~~~ ~~~~~\n" ), (pp_formatted_text (dc.printer))); } while (0); |
3638 | } |
3639 | } |
3640 | |
3641 | /* Example where the labels need extra lines. */ |
3642 | { |
3643 | text_range_label label0 ("label 0"); |
3644 | text_range_label label1 ("label 1"); |
3645 | text_range_label label2 ("label 2"); |
3646 | gcc_rich_location richloc (foo, &label0); |
3647 | richloc.add_range (bar, SHOW_RANGE_WITHOUT_CARET, &label1); |
3648 | richloc.add_range (field, SHOW_RANGE_WITHOUT_CARET, &label2); |
3649 | |
3650 | test_diagnostic_context dc; |
3651 | diagnostic_show_locus (&dc, &richloc, DK_ERROR); |
3652 | ASSERT_STREQ (" foo = bar.field;\n"do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 3658, __FUNCTION__)), "\" foo = bar.field;\\n\" \" ^~~ ~~~ ~~~~~\\n\" \" | | |\\n\" \" | | label 2\\n\" \" | label 1\\n\" \" label 0\\n\"" , "pp_formatted_text (dc.printer)", (" foo = bar.field;\n" " ^~~ ~~~ ~~~~~\n" " | | |\n" " | | label 2\n" " | label 1\n" " label 0\n" ), (pp_formatted_text (dc.printer))); } while (0) |
3653 | " ^~~ ~~~ ~~~~~\n"do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 3658, __FUNCTION__)), "\" foo = bar.field;\\n\" \" ^~~ ~~~ ~~~~~\\n\" \" | | |\\n\" \" | | label 2\\n\" \" | label 1\\n\" \" label 0\\n\"" , "pp_formatted_text (dc.printer)", (" foo = bar.field;\n" " ^~~ ~~~ ~~~~~\n" " | | |\n" " | | label 2\n" " | label 1\n" " label 0\n" ), (pp_formatted_text (dc.printer))); } while (0) |
3654 | " | | |\n"do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 3658, __FUNCTION__)), "\" foo = bar.field;\\n\" \" ^~~ ~~~ ~~~~~\\n\" \" | | |\\n\" \" | | label 2\\n\" \" | label 1\\n\" \" label 0\\n\"" , "pp_formatted_text (dc.printer)", (" foo = bar.field;\n" " ^~~ ~~~ ~~~~~\n" " | | |\n" " | | label 2\n" " | label 1\n" " label 0\n" ), (pp_formatted_text (dc.printer))); } while (0) |
3655 | " | | label 2\n"do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 3658, __FUNCTION__)), "\" foo = bar.field;\\n\" \" ^~~ ~~~ ~~~~~\\n\" \" | | |\\n\" \" | | label 2\\n\" \" | label 1\\n\" \" label 0\\n\"" , "pp_formatted_text (dc.printer)", (" foo = bar.field;\n" " ^~~ ~~~ ~~~~~\n" " | | |\n" " | | label 2\n" " | label 1\n" " label 0\n" ), (pp_formatted_text (dc.printer))); } while (0) |
3656 | " | label 1\n"do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 3658, __FUNCTION__)), "\" foo = bar.field;\\n\" \" ^~~ ~~~ ~~~~~\\n\" \" | | |\\n\" \" | | label 2\\n\" \" | label 1\\n\" \" label 0\\n\"" , "pp_formatted_text (dc.printer)", (" foo = bar.field;\n" " ^~~ ~~~ ~~~~~\n" " | | |\n" " | | label 2\n" " | label 1\n" " label 0\n" ), (pp_formatted_text (dc.printer))); } while (0) |
3657 | " label 0\n",do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 3658, __FUNCTION__)), "\" foo = bar.field;\\n\" \" ^~~ ~~~ ~~~~~\\n\" \" | | |\\n\" \" | | label 2\\n\" \" | label 1\\n\" \" label 0\\n\"" , "pp_formatted_text (dc.printer)", (" foo = bar.field;\n" " ^~~ ~~~ ~~~~~\n" " | | |\n" " | | label 2\n" " | label 1\n" " label 0\n" ), (pp_formatted_text (dc.printer))); } while (0) |
3658 | pp_formatted_text (dc.printer))do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 3658, __FUNCTION__)), "\" foo = bar.field;\\n\" \" ^~~ ~~~ ~~~~~\\n\" \" | | |\\n\" \" | | label 2\\n\" \" | label 1\\n\" \" label 0\\n\"" , "pp_formatted_text (dc.printer)", (" foo = bar.field;\n" " ^~~ ~~~ ~~~~~\n" " | | |\n" " | | label 2\n" " | label 1\n" " label 0\n" ), (pp_formatted_text (dc.printer))); } while (0); |
3659 | } |
3660 | |
3661 | /* Example of boundary conditions: label 0 and 1 have just enough clearance, |
3662 | but label 1 just touches label 2. */ |
3663 | { |
3664 | text_range_label label0 ("aaaaa"); |
3665 | text_range_label label1 ("bbbb"); |
3666 | text_range_label label2 ("c"); |
3667 | gcc_rich_location richloc (foo, &label0); |
3668 | richloc.add_range (bar, SHOW_RANGE_WITHOUT_CARET, &label1); |
3669 | richloc.add_range (field, SHOW_RANGE_WITHOUT_CARET, &label2); |
3670 | |
3671 | test_diagnostic_context dc; |
3672 | diagnostic_show_locus (&dc, &richloc, DK_ERROR); |
3673 | ASSERT_STREQ (" foo = bar.field;\n"do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 3678, __FUNCTION__)), "\" foo = bar.field;\\n\" \" ^~~ ~~~ ~~~~~\\n\" \" | | |\\n\" \" | | c\\n\" \" aaaaa bbbb\\n\"" , "pp_formatted_text (dc.printer)", (" foo = bar.field;\n" " ^~~ ~~~ ~~~~~\n" " | | |\n" " | | c\n" " aaaaa bbbb\n"), (pp_formatted_text (dc.printer))); } while (0) |
3674 | " ^~~ ~~~ ~~~~~\n"do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 3678, __FUNCTION__)), "\" foo = bar.field;\\n\" \" ^~~ ~~~ ~~~~~\\n\" \" | | |\\n\" \" | | c\\n\" \" aaaaa bbbb\\n\"" , "pp_formatted_text (dc.printer)", (" foo = bar.field;\n" " ^~~ ~~~ ~~~~~\n" " | | |\n" " | | c\n" " aaaaa bbbb\n"), (pp_formatted_text (dc.printer))); } while (0) |
3675 | " | | |\n"do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 3678, __FUNCTION__)), "\" foo = bar.field;\\n\" \" ^~~ ~~~ ~~~~~\\n\" \" | | |\\n\" \" | | c\\n\" \" aaaaa bbbb\\n\"" , "pp_formatted_text (dc.printer)", (" foo = bar.field;\n" " ^~~ ~~~ ~~~~~\n" " | | |\n" " | | c\n" " aaaaa bbbb\n"), (pp_formatted_text (dc.printer))); } while (0) |
3676 | " | | c\n"do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 3678, __FUNCTION__)), "\" foo = bar.field;\\n\" \" ^~~ ~~~ ~~~~~\\n\" \" | | |\\n\" \" | | c\\n\" \" aaaaa bbbb\\n\"" , "pp_formatted_text (dc.printer)", (" foo = bar.field;\n" " ^~~ ~~~ ~~~~~\n" " | | |\n" " | | c\n" " aaaaa bbbb\n"), (pp_formatted_text (dc.printer))); } while (0) |
3677 | " aaaaa bbbb\n",do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 3678, __FUNCTION__)), "\" foo = bar.field;\\n\" \" ^~~ ~~~ ~~~~~\\n\" \" | | |\\n\" \" | | c\\n\" \" aaaaa bbbb\\n\"" , "pp_formatted_text (dc.printer)", (" foo = bar.field;\n" " ^~~ ~~~ ~~~~~\n" " | | |\n" " | | c\n" " aaaaa bbbb\n"), (pp_formatted_text (dc.printer))); } while (0) |
3678 | pp_formatted_text (dc.printer))do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 3678, __FUNCTION__)), "\" foo = bar.field;\\n\" \" ^~~ ~~~ ~~~~~\\n\" \" | | |\\n\" \" | | c\\n\" \" aaaaa bbbb\\n\"" , "pp_formatted_text (dc.printer)", (" foo = bar.field;\n" " ^~~ ~~~ ~~~~~\n" " | | |\n" " | | c\n" " aaaaa bbbb\n"), (pp_formatted_text (dc.printer))); } while (0); |
3679 | } |
3680 | |
3681 | /* Example of out-of-order ranges (thus requiring a sort). */ |
3682 | { |
3683 | text_range_label label0 ("0"); |
3684 | text_range_label label1 ("1"); |
3685 | text_range_label label2 ("2"); |
3686 | gcc_rich_location richloc (field, &label0); |
3687 | richloc.add_range (bar, SHOW_RANGE_WITHOUT_CARET, &label1); |
3688 | richloc.add_range (foo, SHOW_RANGE_WITHOUT_CARET, &label2); |
3689 | |
3690 | test_diagnostic_context dc; |
3691 | diagnostic_show_locus (&dc, &richloc, DK_ERROR); |
3692 | ASSERT_STREQ (" foo = bar.field;\n"do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 3696, __FUNCTION__)), "\" foo = bar.field;\\n\" \" ~~~ ~~~ ^~~~~\\n\" \" | | |\\n\" \" 2 1 0\\n\"" , "pp_formatted_text (dc.printer)", (" foo = bar.field;\n" " ~~~ ~~~ ^~~~~\n" " | | |\n" " 2 1 0\n"), (pp_formatted_text (dc.printer ))); } while (0) |
3693 | " ~~~ ~~~ ^~~~~\n"do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 3696, __FUNCTION__)), "\" foo = bar.field;\\n\" \" ~~~ ~~~ ^~~~~\\n\" \" | | |\\n\" \" 2 1 0\\n\"" , "pp_formatted_text (dc.printer)", (" foo = bar.field;\n" " ~~~ ~~~ ^~~~~\n" " | | |\n" " 2 1 0\n"), (pp_formatted_text (dc.printer ))); } while (0) |
3694 | " | | |\n"do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 3696, __FUNCTION__)), "\" foo = bar.field;\\n\" \" ~~~ ~~~ ^~~~~\\n\" \" | | |\\n\" \" 2 1 0\\n\"" , "pp_formatted_text (dc.printer)", (" foo = bar.field;\n" " ~~~ ~~~ ^~~~~\n" " | | |\n" " 2 1 0\n"), (pp_formatted_text (dc.printer ))); } while (0) |
3695 | " 2 1 0\n",do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 3696, __FUNCTION__)), "\" foo = bar.field;\\n\" \" ~~~ ~~~ ^~~~~\\n\" \" | | |\\n\" \" 2 1 0\\n\"" , "pp_formatted_text (dc.printer)", (" foo = bar.field;\n" " ~~~ ~~~ ^~~~~\n" " | | |\n" " 2 1 0\n"), (pp_formatted_text (dc.printer ))); } while (0) |
3696 | pp_formatted_text (dc.printer))do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 3696, __FUNCTION__)), "\" foo = bar.field;\\n\" \" ~~~ ~~~ ^~~~~\\n\" \" | | |\\n\" \" 2 1 0\\n\"" , "pp_formatted_text (dc.printer)", (" foo = bar.field;\n" " ~~~ ~~~ ^~~~~\n" " | | |\n" " 2 1 0\n"), (pp_formatted_text (dc.printer ))); } while (0); |
3697 | } |
3698 | |
3699 | /* Ensure we don't ICE if multiple ranges with labels are on |
3700 | the same point. */ |
3701 | { |
3702 | text_range_label label0 ("label 0"); |
3703 | text_range_label label1 ("label 1"); |
3704 | text_range_label label2 ("label 2"); |
3705 | gcc_rich_location richloc (bar, &label0); |
3706 | richloc.add_range (bar, SHOW_RANGE_WITHOUT_CARET, &label1); |
3707 | richloc.add_range (bar, SHOW_RANGE_WITHOUT_CARET, &label2); |
3708 | |
3709 | test_diagnostic_context dc; |
3710 | diagnostic_show_locus (&dc, &richloc, DK_ERROR); |
3711 | ASSERT_STREQ (" foo = bar.field;\n"do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 3717, __FUNCTION__)), "\" foo = bar.field;\\n\" \" ^~~\\n\" \" |\\n\" \" label 0\\n\" \" label 1\\n\" \" label 2\\n\"" , "pp_formatted_text (dc.printer)", (" foo = bar.field;\n" " ^~~\n" " |\n" " label 0\n" " label 1\n" " label 2\n" ), (pp_formatted_text (dc.printer))); } while (0) |
3712 | " ^~~\n"do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 3717, __FUNCTION__)), "\" foo = bar.field;\\n\" \" ^~~\\n\" \" |\\n\" \" label 0\\n\" \" label 1\\n\" \" label 2\\n\"" , "pp_formatted_text (dc.printer)", (" foo = bar.field;\n" " ^~~\n" " |\n" " label 0\n" " label 1\n" " label 2\n" ), (pp_formatted_text (dc.printer))); } while (0) |
3713 | " |\n"do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 3717, __FUNCTION__)), "\" foo = bar.field;\\n\" \" ^~~\\n\" \" |\\n\" \" label 0\\n\" \" label 1\\n\" \" label 2\\n\"" , "pp_formatted_text (dc.printer)", (" foo = bar.field;\n" " ^~~\n" " |\n" " label 0\n" " label 1\n" " label 2\n" ), (pp_formatted_text (dc.printer))); } while (0) |
3714 | " label 0\n"do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 3717, __FUNCTION__)), "\" foo = bar.field;\\n\" \" ^~~\\n\" \" |\\n\" \" label 0\\n\" \" label 1\\n\" \" label 2\\n\"" , "pp_formatted_text (dc.printer)", (" foo = bar.field;\n" " ^~~\n" " |\n" " label 0\n" " label 1\n" " label 2\n" ), (pp_formatted_text (dc.printer))); } while (0) |
3715 | " label 1\n"do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 3717, __FUNCTION__)), "\" foo = bar.field;\\n\" \" ^~~\\n\" \" |\\n\" \" label 0\\n\" \" label 1\\n\" \" label 2\\n\"" , "pp_formatted_text (dc.printer)", (" foo = bar.field;\n" " ^~~\n" " |\n" " label 0\n" " label 1\n" " label 2\n" ), (pp_formatted_text (dc.printer))); } while (0) |
3716 | " label 2\n",do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 3717, __FUNCTION__)), "\" foo = bar.field;\\n\" \" ^~~\\n\" \" |\\n\" \" label 0\\n\" \" label 1\\n\" \" label 2\\n\"" , "pp_formatted_text (dc.printer)", (" foo = bar.field;\n" " ^~~\n" " |\n" " label 0\n" " label 1\n" " label 2\n" ), (pp_formatted_text (dc.printer))); } while (0) |
3717 | pp_formatted_text (dc.printer))do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 3717, __FUNCTION__)), "\" foo = bar.field;\\n\" \" ^~~\\n\" \" |\\n\" \" label 0\\n\" \" label 1\\n\" \" label 2\\n\"" , "pp_formatted_text (dc.printer)", (" foo = bar.field;\n" " ^~~\n" " |\n" " label 0\n" " label 1\n" " label 2\n" ), (pp_formatted_text (dc.printer))); } while (0); |
3718 | } |
3719 | |
3720 | /* Example of out-of-order ranges (thus requiring a sort), where |
3721 | they overlap, and there are multiple ranges on the same point. */ |
3722 | { |
3723 | text_range_label label_0a ("label 0a"); |
3724 | text_range_label label_1a ("label 1a"); |
3725 | text_range_label label_2a ("label 2a"); |
3726 | text_range_label label_0b ("label 0b"); |
3727 | text_range_label label_1b ("label 1b"); |
3728 | text_range_label label_2b ("label 2b"); |
3729 | text_range_label label_0c ("label 0c"); |
3730 | text_range_label label_1c ("label 1c"); |
3731 | text_range_label label_2c ("label 2c"); |
3732 | gcc_rich_location richloc (field, &label_0a); |
3733 | richloc.add_range (bar, SHOW_RANGE_WITHOUT_CARET, &label_1a); |
3734 | richloc.add_range (foo, SHOW_RANGE_WITHOUT_CARET, &label_2a); |
3735 | |
3736 | richloc.add_range (field, SHOW_RANGE_WITHOUT_CARET, &label_0b); |
3737 | richloc.add_range (bar, SHOW_RANGE_WITHOUT_CARET, &label_1b); |
3738 | richloc.add_range (foo, SHOW_RANGE_WITHOUT_CARET, &label_2b); |
3739 | |
3740 | richloc.add_range (field, SHOW_RANGE_WITHOUT_CARET, &label_0c); |
3741 | richloc.add_range (bar, SHOW_RANGE_WITHOUT_CARET, &label_1c); |
3742 | richloc.add_range (foo, SHOW_RANGE_WITHOUT_CARET, &label_2c); |
3743 | |
3744 | test_diagnostic_context dc; |
3745 | diagnostic_show_locus (&dc, &richloc, DK_ERROR); |
3746 | ASSERT_STREQ (" foo = bar.field;\n"do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 3758, __FUNCTION__)), "\" foo = bar.field;\\n\" \" ~~~ ~~~ ^~~~~\\n\" \" | | |\\n\" \" | | label 0a\\n\" \" | | label 0b\\n\" \" | | label 0c\\n\" \" | label 1a\\n\" \" | label 1b\\n\" \" | label 1c\\n\" \" label 2a\\n\" \" label 2b\\n\" \" label 2c\\n\"" , "pp_formatted_text (dc.printer)", (" foo = bar.field;\n" " ~~~ ~~~ ^~~~~\n" " | | |\n" " | | label 0a\n" " | | label 0b\n" " | | label 0c\n" " | label 1a\n" " | label 1b\n" " | label 1c\n" " label 2a\n" " label 2b\n" " label 2c\n" ), (pp_formatted_text (dc.printer))); } while (0) |
3747 | " ~~~ ~~~ ^~~~~\n"do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 3758, __FUNCTION__)), "\" foo = bar.field;\\n\" \" ~~~ ~~~ ^~~~~\\n\" \" | | |\\n\" \" | | label 0a\\n\" \" | | label 0b\\n\" \" | | label 0c\\n\" \" | label 1a\\n\" \" | label 1b\\n\" \" | label 1c\\n\" \" label 2a\\n\" \" label 2b\\n\" \" label 2c\\n\"" , "pp_formatted_text (dc.printer)", (" foo = bar.field;\n" " ~~~ ~~~ ^~~~~\n" " | | |\n" " | | label 0a\n" " | | label 0b\n" " | | label 0c\n" " | label 1a\n" " | label 1b\n" " | label 1c\n" " label 2a\n" " label 2b\n" " label 2c\n" ), (pp_formatted_text (dc.printer))); } while (0) |
3748 | " | | |\n"do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 3758, __FUNCTION__)), "\" foo = bar.field;\\n\" \" ~~~ ~~~ ^~~~~\\n\" \" | | |\\n\" \" | | label 0a\\n\" \" | | label 0b\\n\" \" | | label 0c\\n\" \" | label 1a\\n\" \" | label 1b\\n\" \" | label 1c\\n\" \" label 2a\\n\" \" label 2b\\n\" \" label 2c\\n\"" , "pp_formatted_text (dc.printer)", (" foo = bar.field;\n" " ~~~ ~~~ ^~~~~\n" " | | |\n" " | | label 0a\n" " | | label 0b\n" " | | label 0c\n" " | label 1a\n" " | label 1b\n" " | label 1c\n" " label 2a\n" " label 2b\n" " label 2c\n" ), (pp_formatted_text (dc.printer))); } while (0) |
3749 | " | | label 0a\n"do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 3758, __FUNCTION__)), "\" foo = bar.field;\\n\" \" ~~~ ~~~ ^~~~~\\n\" \" | | |\\n\" \" | | label 0a\\n\" \" | | label 0b\\n\" \" | | label 0c\\n\" \" | label 1a\\n\" \" | label 1b\\n\" \" | label 1c\\n\" \" label 2a\\n\" \" label 2b\\n\" \" label 2c\\n\"" , "pp_formatted_text (dc.printer)", (" foo = bar.field;\n" " ~~~ ~~~ ^~~~~\n" " | | |\n" " | | label 0a\n" " | | label 0b\n" " | | label 0c\n" " | label 1a\n" " | label 1b\n" " | label 1c\n" " label 2a\n" " label 2b\n" " label 2c\n" ), (pp_formatted_text (dc.printer))); } while (0) |
3750 | " | | label 0b\n"do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 3758, __FUNCTION__)), "\" foo = bar.field;\\n\" \" ~~~ ~~~ ^~~~~\\n\" \" | | |\\n\" \" | | label 0a\\n\" \" | | label 0b\\n\" \" | | label 0c\\n\" \" | label 1a\\n\" \" | label 1b\\n\" \" | label 1c\\n\" \" label 2a\\n\" \" label 2b\\n\" \" label 2c\\n\"" , "pp_formatted_text (dc.printer)", (" foo = bar.field;\n" " ~~~ ~~~ ^~~~~\n" " | | |\n" " | | label 0a\n" " | | label 0b\n" " | | label 0c\n" " | label 1a\n" " | label 1b\n" " | label 1c\n" " label 2a\n" " label 2b\n" " label 2c\n" ), (pp_formatted_text (dc.printer))); } while (0) |
3751 | " | | label 0c\n"do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 3758, __FUNCTION__)), "\" foo = bar.field;\\n\" \" ~~~ ~~~ ^~~~~\\n\" \" | | |\\n\" \" | | label 0a\\n\" \" | | label 0b\\n\" \" | | label 0c\\n\" \" | label 1a\\n\" \" | label 1b\\n\" \" | label 1c\\n\" \" label 2a\\n\" \" label 2b\\n\" \" label 2c\\n\"" , "pp_formatted_text (dc.printer)", (" foo = bar.field;\n" " ~~~ ~~~ ^~~~~\n" " | | |\n" " | | label 0a\n" " | | label 0b\n" " | | label 0c\n" " | label 1a\n" " | label 1b\n" " | label 1c\n" " label 2a\n" " label 2b\n" " label 2c\n" ), (pp_formatted_text (dc.printer))); } while (0) |
3752 | " | label 1a\n"do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 3758, __FUNCTION__)), "\" foo = bar.field;\\n\" \" ~~~ ~~~ ^~~~~\\n\" \" | | |\\n\" \" | | label 0a\\n\" \" | | label 0b\\n\" \" | | label 0c\\n\" \" | label 1a\\n\" \" | label 1b\\n\" \" | label 1c\\n\" \" label 2a\\n\" \" label 2b\\n\" \" label 2c\\n\"" , "pp_formatted_text (dc.printer)", (" foo = bar.field;\n" " ~~~ ~~~ ^~~~~\n" " | | |\n" " | | label 0a\n" " | | label 0b\n" " | | label 0c\n" " | label 1a\n" " | label 1b\n" " | label 1c\n" " label 2a\n" " label 2b\n" " label 2c\n" ), (pp_formatted_text (dc.printer))); } while (0) |
3753 | " | label 1b\n"do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 3758, __FUNCTION__)), "\" foo = bar.field;\\n\" \" ~~~ ~~~ ^~~~~\\n\" \" | | |\\n\" \" | | label 0a\\n\" \" | | label 0b\\n\" \" | | label 0c\\n\" \" | label 1a\\n\" \" | label 1b\\n\" \" | label 1c\\n\" \" label 2a\\n\" \" label 2b\\n\" \" label 2c\\n\"" , "pp_formatted_text (dc.printer)", (" foo = bar.field;\n" " ~~~ ~~~ ^~~~~\n" " | | |\n" " | | label 0a\n" " | | label 0b\n" " | | label 0c\n" " | label 1a\n" " | label 1b\n" " | label 1c\n" " label 2a\n" " label 2b\n" " label 2c\n" ), (pp_formatted_text (dc.printer))); } while (0) |
3754 | " | label 1c\n"do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 3758, __FUNCTION__)), "\" foo = bar.field;\\n\" \" ~~~ ~~~ ^~~~~\\n\" \" | | |\\n\" \" | | label 0a\\n\" \" | | label 0b\\n\" \" | | label 0c\\n\" \" | label 1a\\n\" \" | label 1b\\n\" \" | label 1c\\n\" \" label 2a\\n\" \" label 2b\\n\" \" label 2c\\n\"" , "pp_formatted_text (dc.printer)", (" foo = bar.field;\n" " ~~~ ~~~ ^~~~~\n" " | | |\n" " | | label 0a\n" " | | label 0b\n" " | | label 0c\n" " | label 1a\n" " | label 1b\n" " | label 1c\n" " label 2a\n" " label 2b\n" " label 2c\n" ), (pp_formatted_text (dc.printer))); } while (0) |
3755 | " label 2a\n"do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 3758, __FUNCTION__)), "\" foo = bar.field;\\n\" \" ~~~ ~~~ ^~~~~\\n\" \" | | |\\n\" \" | | label 0a\\n\" \" | | label 0b\\n\" \" | | label 0c\\n\" \" | label 1a\\n\" \" | label 1b\\n\" \" | label 1c\\n\" \" label 2a\\n\" \" label 2b\\n\" \" label 2c\\n\"" , "pp_formatted_text (dc.printer)", (" foo = bar.field;\n" " ~~~ ~~~ ^~~~~\n" " | | |\n" " | | label 0a\n" " | | label 0b\n" " | | label 0c\n" " | label 1a\n" " | label 1b\n" " | label 1c\n" " label 2a\n" " label 2b\n" " label 2c\n" ), (pp_formatted_text (dc.printer))); } while (0) |
3756 | " label 2b\n"do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 3758, __FUNCTION__)), "\" foo = bar.field;\\n\" \" ~~~ ~~~ ^~~~~\\n\" \" | | |\\n\" \" | | label 0a\\n\" \" | | label 0b\\n\" \" | | label 0c\\n\" \" | label 1a\\n\" \" | label 1b\\n\" \" | label 1c\\n\" \" label 2a\\n\" \" label 2b\\n\" \" label 2c\\n\"" , "pp_formatted_text (dc.printer)", (" foo = bar.field;\n" " ~~~ ~~~ ^~~~~\n" " | | |\n" " | | label 0a\n" " | | label 0b\n" " | | label 0c\n" " | label 1a\n" " | label 1b\n" " | label 1c\n" " label 2a\n" " label 2b\n" " label 2c\n" ), (pp_formatted_text (dc.printer))); } while (0) |
3757 | " label 2c\n",do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 3758, __FUNCTION__)), "\" foo = bar.field;\\n\" \" ~~~ ~~~ ^~~~~\\n\" \" | | |\\n\" \" | | label 0a\\n\" \" | | label 0b\\n\" \" | | label 0c\\n\" \" | label 1a\\n\" \" | label 1b\\n\" \" | label 1c\\n\" \" label 2a\\n\" \" label 2b\\n\" \" label 2c\\n\"" , "pp_formatted_text (dc.printer)", (" foo = bar.field;\n" " ~~~ ~~~ ^~~~~\n" " | | |\n" " | | label 0a\n" " | | label 0b\n" " | | label 0c\n" " | label 1a\n" " | label 1b\n" " | label 1c\n" " label 2a\n" " label 2b\n" " label 2c\n" ), (pp_formatted_text (dc.printer))); } while (0) |
3758 | pp_formatted_text (dc.printer))do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 3758, __FUNCTION__)), "\" foo = bar.field;\\n\" \" ~~~ ~~~ ^~~~~\\n\" \" | | |\\n\" \" | | label 0a\\n\" \" | | label 0b\\n\" \" | | label 0c\\n\" \" | label 1a\\n\" \" | label 1b\\n\" \" | label 1c\\n\" \" label 2a\\n\" \" label 2b\\n\" \" label 2c\\n\"" , "pp_formatted_text (dc.printer)", (" foo = bar.field;\n" " ~~~ ~~~ ^~~~~\n" " | | |\n" " | | label 0a\n" " | | label 0b\n" " | | label 0c\n" " | label 1a\n" " | label 1b\n" " | label 1c\n" " label 2a\n" " label 2b\n" " label 2c\n" ), (pp_formatted_text (dc.printer))); } while (0); |
3759 | } |
3760 | |
3761 | /* Verify that a NULL result from range_label::get_text is |
3762 | handled gracefully. */ |
3763 | { |
3764 | text_range_label label (NULL__null); |
3765 | gcc_rich_location richloc (bar, &label); |
3766 | |
3767 | test_diagnostic_context dc; |
3768 | diagnostic_show_locus (&dc, &richloc, DK_ERROR); |
3769 | ASSERT_STREQ (" foo = bar.field;\n"do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 3771, __FUNCTION__)), "\" foo = bar.field;\\n\" \" ^~~\\n\"" , "pp_formatted_text (dc.printer)", (" foo = bar.field;\n" " ^~~\n" ), (pp_formatted_text (dc.printer))); } while (0) |
3770 | " ^~~\n",do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 3771, __FUNCTION__)), "\" foo = bar.field;\\n\" \" ^~~\\n\"" , "pp_formatted_text (dc.printer)", (" foo = bar.field;\n" " ^~~\n" ), (pp_formatted_text (dc.printer))); } while (0) |
3771 | pp_formatted_text (dc.printer))do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 3771, __FUNCTION__)), "\" foo = bar.field;\\n\" \" ^~~\\n\"" , "pp_formatted_text (dc.printer)", (" foo = bar.field;\n" " ^~~\n" ), (pp_formatted_text (dc.printer))); } while (0); |
3772 | } |
3773 | |
3774 | /* TODO: example of formatted printing (needs to be in |
3775 | gcc-rich-location.cc due to Makefile.in issues). */ |
3776 | } |
3777 | |
3778 | /* Run the various one-liner tests. */ |
3779 | |
3780 | static void |
3781 | test_diagnostic_show_locus_one_liner (const line_table_case &case_) |
3782 | { |
3783 | /* Create a tempfile and write some text to it. |
3784 | ....................0000000001111111. |
3785 | ....................1234567890123456. */ |
3786 | const char *content = "foo = bar.field;\n"; |
3787 | temp_source_file tmp (SELFTEST_LOCATION(::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 3787, __FUNCTION__)), ".c", content); |
3788 | line_table_test ltt (case_); |
3789 | |
3790 | linemap_add (line_table, LC_ENTER, false, tmp.get_filename (), 1); |
3791 | |
3792 | location_t line_end = linemap_position_for_column (line_table, 16); |
3793 | |
3794 | /* Don't attempt to run the tests if column data might be unavailable. */ |
3795 | if (line_end > LINE_MAP_MAX_LOCATION_WITH_COLS) |
3796 | return; |
3797 | |
3798 | ASSERT_STREQ (tmp.get_filename (), LOCATION_FILE (line_end))do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 3798, __FUNCTION__)), "tmp.get_filename ()", "LOCATION_FILE (line_end)" , (tmp.get_filename ()), (((expand_location (line_end)).file) )); } while (0); |
3799 | ASSERT_EQ (1, LOCATION_LINE (line_end))do { const char *desc_ = "ASSERT_EQ (" "(1)" ", " "(((expand_location (line_end)).line))" ")"; if (((1)) == ((((expand_location (line_end)).line)))) :: selftest::pass ((((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 3799, __FUNCTION__)))), desc_); else ::selftest::fail ((((:: selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 3799, __FUNCTION__)))), desc_); } while (0); |
3800 | ASSERT_EQ (16, LOCATION_COLUMN (line_end))do { const char *desc_ = "ASSERT_EQ (" "(16)" ", " "(((expand_location (line_end)).column))" ")"; if (((16)) == ((((expand_location (line_end)).column))) ) ::selftest::pass ((((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 3800, __FUNCTION__)))), desc_); else ::selftest::fail ((((:: selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 3800, __FUNCTION__)))), desc_); } while (0); |
3801 | |
3802 | test_one_liner_simple_caret (); |
3803 | test_one_liner_caret_and_range (); |
3804 | test_one_liner_multiple_carets_and_ranges (); |
3805 | test_one_liner_fixit_insert_before (); |
3806 | test_one_liner_fixit_insert_after (); |
3807 | test_one_liner_fixit_remove (); |
3808 | test_one_liner_fixit_replace (); |
3809 | test_one_liner_fixit_replace_non_equal_range (); |
3810 | test_one_liner_fixit_replace_equal_secondary_range (); |
3811 | test_one_liner_fixit_validation_adhoc_locations (); |
3812 | test_one_liner_many_fixits_1 (); |
3813 | test_one_liner_many_fixits_2 (); |
3814 | test_one_liner_labels (); |
3815 | } |
3816 | |
3817 | /* Version of all one-liner tests exercising multibyte awareness. For |
3818 | simplicity we stick to using two multibyte characters in the test, U+1F602 |
3819 | == "\xf0\x9f\x98\x82", which uses 4 bytes and 2 display columns, and U+03C0 |
3820 | == "\xcf\x80", which uses 2 bytes and 1 display column. Note: all of the |
3821 | below asserts would be easier to read if we used UTF-8 directly in the |
3822 | string constants, but it seems better not to demand the host compiler |
3823 | support this, when it isn't otherwise necessary. Instead, whenever an |
3824 | extended character appears in a string, we put a line break after it so that |
3825 | all succeeding characters can appear visually at the correct display column. |
3826 | |
3827 | All of these work on the following 1-line source file: |
3828 | |
3829 | .0000000001111111111222222 display |
3830 | .1234567890123456789012345 columns |
3831 | "SS_foo = P_bar.SS_fieldP;\n" |
3832 | .0000000111111111222222223 byte |
3833 | .1356789012456789134567891 columns |
3834 | |
3835 | which is set up by test_diagnostic_show_locus_one_liner and calls |
3836 | them. Here SS represents the two display columns for the U+1F602 emoji and |
3837 | P represents the one display column for the U+03C0 pi symbol. */ |
3838 | |
3839 | /* Just a caret. */ |
3840 | |
3841 | static void |
3842 | test_one_liner_simple_caret_utf8 () |
3843 | { |
3844 | test_diagnostic_context dc; |
3845 | location_t caret = linemap_position_for_column (line_table, 18); |
3846 | rich_location richloc (line_table, caret); |
3847 | diagnostic_show_locus (&dc, &richloc, DK_ERROR); |
3848 | ASSERT_STREQ (" \xf0\x9f\x98\x82"do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 3854, __FUNCTION__)), "\" \\xf0\\x9f\\x98\\x82\" \"_foo = \\xcf\\x80\" \"_bar.\\xf0\\x9f\\x98\\x82\" \"_field\\xcf\\x80\" \";\\n\" \" ^\\n\"" , "pp_formatted_text (dc.printer)", (" \xf0\x9f\x98\x82" "_foo = \xcf\x80" "_bar.\xf0\x9f\x98\x82" "_field\xcf\x80" ";\n" " ^\n" ), (pp_formatted_text (dc.printer))); } while (0) |
3849 | "_foo = \xcf\x80"do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 3854, __FUNCTION__)), "\" \\xf0\\x9f\\x98\\x82\" \"_foo = \\xcf\\x80\" \"_bar.\\xf0\\x9f\\x98\\x82\" \"_field\\xcf\\x80\" \";\\n\" \" ^\\n\"" , "pp_formatted_text (dc.printer)", (" \xf0\x9f\x98\x82" "_foo = \xcf\x80" "_bar.\xf0\x9f\x98\x82" "_field\xcf\x80" ";\n" " ^\n" ), (pp_formatted_text (dc.printer))); } while (0) |
3850 | "_bar.\xf0\x9f\x98\x82"do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 3854, __FUNCTION__)), "\" \\xf0\\x9f\\x98\\x82\" \"_foo = \\xcf\\x80\" \"_bar.\\xf0\\x9f\\x98\\x82\" \"_field\\xcf\\x80\" \";\\n\" \" ^\\n\"" , "pp_formatted_text (dc.printer)", (" \xf0\x9f\x98\x82" "_foo = \xcf\x80" "_bar.\xf0\x9f\x98\x82" "_field\xcf\x80" ";\n" " ^\n" ), (pp_formatted_text (dc.printer))); } while (0) |
3851 | "_field\xcf\x80"do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 3854, __FUNCTION__)), "\" \\xf0\\x9f\\x98\\x82\" \"_foo = \\xcf\\x80\" \"_bar.\\xf0\\x9f\\x98\\x82\" \"_field\\xcf\\x80\" \";\\n\" \" ^\\n\"" , "pp_formatted_text (dc.printer)", (" \xf0\x9f\x98\x82" "_foo = \xcf\x80" "_bar.\xf0\x9f\x98\x82" "_field\xcf\x80" ";\n" " ^\n" ), (pp_formatted_text (dc.printer))); } while (0) |
3852 | ";\n"do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 3854, __FUNCTION__)), "\" \\xf0\\x9f\\x98\\x82\" \"_foo = \\xcf\\x80\" \"_bar.\\xf0\\x9f\\x98\\x82\" \"_field\\xcf\\x80\" \";\\n\" \" ^\\n\"" , "pp_formatted_text (dc.printer)", (" \xf0\x9f\x98\x82" "_foo = \xcf\x80" "_bar.\xf0\x9f\x98\x82" "_field\xcf\x80" ";\n" " ^\n" ), (pp_formatted_text (dc.printer))); } while (0) |
3853 | " ^\n",do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 3854, __FUNCTION__)), "\" \\xf0\\x9f\\x98\\x82\" \"_foo = \\xcf\\x80\" \"_bar.\\xf0\\x9f\\x98\\x82\" \"_field\\xcf\\x80\" \";\\n\" \" ^\\n\"" , "pp_formatted_text (dc.printer)", (" \xf0\x9f\x98\x82" "_foo = \xcf\x80" "_bar.\xf0\x9f\x98\x82" "_field\xcf\x80" ";\n" " ^\n" ), (pp_formatted_text (dc.printer))); } while (0) |
3854 | pp_formatted_text (dc.printer))do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 3854, __FUNCTION__)), "\" \\xf0\\x9f\\x98\\x82\" \"_foo = \\xcf\\x80\" \"_bar.\\xf0\\x9f\\x98\\x82\" \"_field\\xcf\\x80\" \";\\n\" \" ^\\n\"" , "pp_formatted_text (dc.printer)", (" \xf0\x9f\x98\x82" "_foo = \xcf\x80" "_bar.\xf0\x9f\x98\x82" "_field\xcf\x80" ";\n" " ^\n" ), (pp_formatted_text (dc.printer))); } while (0); |
3855 | } |
3856 | |
3857 | /* Caret and range. */ |
3858 | static void |
3859 | test_one_liner_caret_and_range_utf8 () |
3860 | { |
3861 | test_diagnostic_context dc; |
3862 | location_t caret = linemap_position_for_column (line_table, 18); |
3863 | location_t start = linemap_position_for_column (line_table, 12); |
3864 | location_t finish = linemap_position_for_column (line_table, 30); |
3865 | location_t loc = make_location (caret, start, finish); |
3866 | rich_location richloc (line_table, loc); |
3867 | diagnostic_show_locus (&dc, &richloc, DK_ERROR); |
3868 | ASSERT_STREQ (" \xf0\x9f\x98\x82"do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 3874, __FUNCTION__)), "\" \\xf0\\x9f\\x98\\x82\" \"_foo = \\xcf\\x80\" \"_bar.\\xf0\\x9f\\x98\\x82\" \"_field\\xcf\\x80\" \";\\n\" \" ~~~~~^~~~~~~~~~\\n\"" , "pp_formatted_text (dc.printer)", (" \xf0\x9f\x98\x82" "_foo = \xcf\x80" "_bar.\xf0\x9f\x98\x82" "_field\xcf\x80" ";\n" " ~~~~~^~~~~~~~~~\n" ), (pp_formatted_text (dc.printer))); } while (0) |
3869 | "_foo = \xcf\x80"do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 3874, __FUNCTION__)), "\" \\xf0\\x9f\\x98\\x82\" \"_foo = \\xcf\\x80\" \"_bar.\\xf0\\x9f\\x98\\x82\" \"_field\\xcf\\x80\" \";\\n\" \" ~~~~~^~~~~~~~~~\\n\"" , "pp_formatted_text (dc.printer)", (" \xf0\x9f\x98\x82" "_foo = \xcf\x80" "_bar.\xf0\x9f\x98\x82" "_field\xcf\x80" ";\n" " ~~~~~^~~~~~~~~~\n" ), (pp_formatted_text (dc.printer))); } while (0) |
3870 | "_bar.\xf0\x9f\x98\x82"do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 3874, __FUNCTION__)), "\" \\xf0\\x9f\\x98\\x82\" \"_foo = \\xcf\\x80\" \"_bar.\\xf0\\x9f\\x98\\x82\" \"_field\\xcf\\x80\" \";\\n\" \" ~~~~~^~~~~~~~~~\\n\"" , "pp_formatted_text (dc.printer)", (" \xf0\x9f\x98\x82" "_foo = \xcf\x80" "_bar.\xf0\x9f\x98\x82" "_field\xcf\x80" ";\n" " ~~~~~^~~~~~~~~~\n" ), (pp_formatted_text (dc.printer))); } while (0) |
3871 | "_field\xcf\x80"do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 3874, __FUNCTION__)), "\" \\xf0\\x9f\\x98\\x82\" \"_foo = \\xcf\\x80\" \"_bar.\\xf0\\x9f\\x98\\x82\" \"_field\\xcf\\x80\" \";\\n\" \" ~~~~~^~~~~~~~~~\\n\"" , "pp_formatted_text (dc.printer)", (" \xf0\x9f\x98\x82" "_foo = \xcf\x80" "_bar.\xf0\x9f\x98\x82" "_field\xcf\x80" ";\n" " ~~~~~^~~~~~~~~~\n" ), (pp_formatted_text (dc.printer))); } while (0) |
3872 | ";\n"do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 3874, __FUNCTION__)), "\" \\xf0\\x9f\\x98\\x82\" \"_foo = \\xcf\\x80\" \"_bar.\\xf0\\x9f\\x98\\x82\" \"_field\\xcf\\x80\" \";\\n\" \" ~~~~~^~~~~~~~~~\\n\"" , "pp_formatted_text (dc.printer)", (" \xf0\x9f\x98\x82" "_foo = \xcf\x80" "_bar.\xf0\x9f\x98\x82" "_field\xcf\x80" ";\n" " ~~~~~^~~~~~~~~~\n" ), (pp_formatted_text (dc.printer))); } while (0) |
3873 | " ~~~~~^~~~~~~~~~\n",do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 3874, __FUNCTION__)), "\" \\xf0\\x9f\\x98\\x82\" \"_foo = \\xcf\\x80\" \"_bar.\\xf0\\x9f\\x98\\x82\" \"_field\\xcf\\x80\" \";\\n\" \" ~~~~~^~~~~~~~~~\\n\"" , "pp_formatted_text (dc.printer)", (" \xf0\x9f\x98\x82" "_foo = \xcf\x80" "_bar.\xf0\x9f\x98\x82" "_field\xcf\x80" ";\n" " ~~~~~^~~~~~~~~~\n" ), (pp_formatted_text (dc.printer))); } while (0) |
3874 | pp_formatted_text (dc.printer))do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 3874, __FUNCTION__)), "\" \\xf0\\x9f\\x98\\x82\" \"_foo = \\xcf\\x80\" \"_bar.\\xf0\\x9f\\x98\\x82\" \"_field\\xcf\\x80\" \";\\n\" \" ~~~~~^~~~~~~~~~\\n\"" , "pp_formatted_text (dc.printer)", (" \xf0\x9f\x98\x82" "_foo = \xcf\x80" "_bar.\xf0\x9f\x98\x82" "_field\xcf\x80" ";\n" " ~~~~~^~~~~~~~~~\n" ), (pp_formatted_text (dc.printer))); } while (0); |
3875 | } |
3876 | |
3877 | /* Multiple ranges and carets. */ |
3878 | |
3879 | static void |
3880 | test_one_liner_multiple_carets_and_ranges_utf8 () |
3881 | { |
3882 | test_diagnostic_context dc; |
3883 | location_t foo |
3884 | = make_location (linemap_position_for_column (line_table, 7), |
3885 | linemap_position_for_column (line_table, 1), |
3886 | linemap_position_for_column (line_table, 8)); |
3887 | dc.caret_chars[0] = 'A'; |
3888 | |
3889 | location_t bar |
3890 | = make_location (linemap_position_for_column (line_table, 16), |
3891 | linemap_position_for_column (line_table, 12), |
3892 | linemap_position_for_column (line_table, 17)); |
3893 | dc.caret_chars[1] = 'B'; |
3894 | |
3895 | location_t field |
3896 | = make_location (linemap_position_for_column (line_table, 26), |
3897 | linemap_position_for_column (line_table, 19), |
3898 | linemap_position_for_column (line_table, 30)); |
3899 | dc.caret_chars[2] = 'C'; |
3900 | rich_location richloc (line_table, foo); |
3901 | richloc.add_range (bar, SHOW_RANGE_WITH_CARET); |
3902 | richloc.add_range (field, SHOW_RANGE_WITH_CARET); |
3903 | diagnostic_show_locus (&dc, &richloc, DK_ERROR); |
3904 | ASSERT_STREQ (" \xf0\x9f\x98\x82"do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 3910, __FUNCTION__)), "\" \\xf0\\x9f\\x98\\x82\" \"_foo = \\xcf\\x80\" \"_bar.\\xf0\\x9f\\x98\\x82\" \"_field\\xcf\\x80\" \";\\n\" \" ~~~~A~ ~~~B~ ~~~~~C~~~\\n\"" , "pp_formatted_text (dc.printer)", (" \xf0\x9f\x98\x82" "_foo = \xcf\x80" "_bar.\xf0\x9f\x98\x82" "_field\xcf\x80" ";\n" " ~~~~A~ ~~~B~ ~~~~~C~~~\n" ), (pp_formatted_text (dc.printer))); } while (0) |
3905 | "_foo = \xcf\x80"do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 3910, __FUNCTION__)), "\" \\xf0\\x9f\\x98\\x82\" \"_foo = \\xcf\\x80\" \"_bar.\\xf0\\x9f\\x98\\x82\" \"_field\\xcf\\x80\" \";\\n\" \" ~~~~A~ ~~~B~ ~~~~~C~~~\\n\"" , "pp_formatted_text (dc.printer)", (" \xf0\x9f\x98\x82" "_foo = \xcf\x80" "_bar.\xf0\x9f\x98\x82" "_field\xcf\x80" ";\n" " ~~~~A~ ~~~B~ ~~~~~C~~~\n" ), (pp_formatted_text (dc.printer))); } while (0) |
3906 | "_bar.\xf0\x9f\x98\x82"do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 3910, __FUNCTION__)), "\" \\xf0\\x9f\\x98\\x82\" \"_foo = \\xcf\\x80\" \"_bar.\\xf0\\x9f\\x98\\x82\" \"_field\\xcf\\x80\" \";\\n\" \" ~~~~A~ ~~~B~ ~~~~~C~~~\\n\"" , "pp_formatted_text (dc.printer)", (" \xf0\x9f\x98\x82" "_foo = \xcf\x80" "_bar.\xf0\x9f\x98\x82" "_field\xcf\x80" ";\n" " ~~~~A~ ~~~B~ ~~~~~C~~~\n" ), (pp_formatted_text (dc.printer))); } while (0) |
3907 | "_field\xcf\x80"do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 3910, __FUNCTION__)), "\" \\xf0\\x9f\\x98\\x82\" \"_foo = \\xcf\\x80\" \"_bar.\\xf0\\x9f\\x98\\x82\" \"_field\\xcf\\x80\" \";\\n\" \" ~~~~A~ ~~~B~ ~~~~~C~~~\\n\"" , "pp_formatted_text (dc.printer)", (" \xf0\x9f\x98\x82" "_foo = \xcf\x80" "_bar.\xf0\x9f\x98\x82" "_field\xcf\x80" ";\n" " ~~~~A~ ~~~B~ ~~~~~C~~~\n" ), (pp_formatted_text (dc.printer))); } while (0) |
3908 | ";\n"do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 3910, __FUNCTION__)), "\" \\xf0\\x9f\\x98\\x82\" \"_foo = \\xcf\\x80\" \"_bar.\\xf0\\x9f\\x98\\x82\" \"_field\\xcf\\x80\" \";\\n\" \" ~~~~A~ ~~~B~ ~~~~~C~~~\\n\"" , "pp_formatted_text (dc.printer)", (" \xf0\x9f\x98\x82" "_foo = \xcf\x80" "_bar.\xf0\x9f\x98\x82" "_field\xcf\x80" ";\n" " ~~~~A~ ~~~B~ ~~~~~C~~~\n" ), (pp_formatted_text (dc.printer))); } while (0) |
3909 | " ~~~~A~ ~~~B~ ~~~~~C~~~\n",do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 3910, __FUNCTION__)), "\" \\xf0\\x9f\\x98\\x82\" \"_foo = \\xcf\\x80\" \"_bar.\\xf0\\x9f\\x98\\x82\" \"_field\\xcf\\x80\" \";\\n\" \" ~~~~A~ ~~~B~ ~~~~~C~~~\\n\"" , "pp_formatted_text (dc.printer)", (" \xf0\x9f\x98\x82" "_foo = \xcf\x80" "_bar.\xf0\x9f\x98\x82" "_field\xcf\x80" ";\n" " ~~~~A~ ~~~B~ ~~~~~C~~~\n" ), (pp_formatted_text (dc.printer))); } while (0) |
3910 | pp_formatted_text (dc.printer))do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 3910, __FUNCTION__)), "\" \\xf0\\x9f\\x98\\x82\" \"_foo = \\xcf\\x80\" \"_bar.\\xf0\\x9f\\x98\\x82\" \"_field\\xcf\\x80\" \";\\n\" \" ~~~~A~ ~~~B~ ~~~~~C~~~\\n\"" , "pp_formatted_text (dc.printer)", (" \xf0\x9f\x98\x82" "_foo = \xcf\x80" "_bar.\xf0\x9f\x98\x82" "_field\xcf\x80" ";\n" " ~~~~A~ ~~~B~ ~~~~~C~~~\n" ), (pp_formatted_text (dc.printer))); } while (0); |
3911 | } |
3912 | |
3913 | /* Insertion fix-it hint: adding an "&" to the front of "P_bar.field". */ |
3914 | |
3915 | static void |
3916 | test_one_liner_fixit_insert_before_utf8 () |
3917 | { |
3918 | test_diagnostic_context dc; |
3919 | location_t caret = linemap_position_for_column (line_table, 12); |
3920 | rich_location richloc (line_table, caret); |
3921 | richloc.add_fixit_insert_before ("&"); |
3922 | diagnostic_show_locus (&dc, &richloc, DK_ERROR); |
3923 | ASSERT_STREQ (" \xf0\x9f\x98\x82"do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 3930, __FUNCTION__)), "\" \\xf0\\x9f\\x98\\x82\" \"_foo = \\xcf\\x80\" \"_bar.\\xf0\\x9f\\x98\\x82\" \"_field\\xcf\\x80\" \";\\n\" \" ^\\n\" \" &\\n\"" , "pp_formatted_text (dc.printer)", (" \xf0\x9f\x98\x82" "_foo = \xcf\x80" "_bar.\xf0\x9f\x98\x82" "_field\xcf\x80" ";\n" " ^\n" " &\n"), (pp_formatted_text (dc.printer))); } while (0) |
3924 | "_foo = \xcf\x80"do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 3930, __FUNCTION__)), "\" \\xf0\\x9f\\x98\\x82\" \"_foo = \\xcf\\x80\" \"_bar.\\xf0\\x9f\\x98\\x82\" \"_field\\xcf\\x80\" \";\\n\" \" ^\\n\" \" &\\n\"" , "pp_formatted_text (dc.printer)", (" \xf0\x9f\x98\x82" "_foo = \xcf\x80" "_bar.\xf0\x9f\x98\x82" "_field\xcf\x80" ";\n" " ^\n" " &\n"), (pp_formatted_text (dc.printer))); } while (0) |
3925 | "_bar.\xf0\x9f\x98\x82"do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 3930, __FUNCTION__)), "\" \\xf0\\x9f\\x98\\x82\" \"_foo = \\xcf\\x80\" \"_bar.\\xf0\\x9f\\x98\\x82\" \"_field\\xcf\\x80\" \";\\n\" \" ^\\n\" \" &\\n\"" , "pp_formatted_text (dc.printer)", (" \xf0\x9f\x98\x82" "_foo = \xcf\x80" "_bar.\xf0\x9f\x98\x82" "_field\xcf\x80" ";\n" " ^\n" " &\n"), (pp_formatted_text (dc.printer))); } while (0) |
3926 | "_field\xcf\x80"do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 3930, __FUNCTION__)), "\" \\xf0\\x9f\\x98\\x82\" \"_foo = \\xcf\\x80\" \"_bar.\\xf0\\x9f\\x98\\x82\" \"_field\\xcf\\x80\" \";\\n\" \" ^\\n\" \" &\\n\"" , "pp_formatted_text (dc.printer)", (" \xf0\x9f\x98\x82" "_foo = \xcf\x80" "_bar.\xf0\x9f\x98\x82" "_field\xcf\x80" ";\n" " ^\n" " &\n"), (pp_formatted_text (dc.printer))); } while (0) |
3927 | ";\n"do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 3930, __FUNCTION__)), "\" \\xf0\\x9f\\x98\\x82\" \"_foo = \\xcf\\x80\" \"_bar.\\xf0\\x9f\\x98\\x82\" \"_field\\xcf\\x80\" \";\\n\" \" ^\\n\" \" &\\n\"" , "pp_formatted_text (dc.printer)", (" \xf0\x9f\x98\x82" "_foo = \xcf\x80" "_bar.\xf0\x9f\x98\x82" "_field\xcf\x80" ";\n" " ^\n" " &\n"), (pp_formatted_text (dc.printer))); } while (0) |
3928 | " ^\n"do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 3930, __FUNCTION__)), "\" \\xf0\\x9f\\x98\\x82\" \"_foo = \\xcf\\x80\" \"_bar.\\xf0\\x9f\\x98\\x82\" \"_field\\xcf\\x80\" \";\\n\" \" ^\\n\" \" &\\n\"" , "pp_formatted_text (dc.printer)", (" \xf0\x9f\x98\x82" "_foo = \xcf\x80" "_bar.\xf0\x9f\x98\x82" "_field\xcf\x80" ";\n" " ^\n" " &\n"), (pp_formatted_text (dc.printer))); } while (0) |
3929 | " &\n",do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 3930, __FUNCTION__)), "\" \\xf0\\x9f\\x98\\x82\" \"_foo = \\xcf\\x80\" \"_bar.\\xf0\\x9f\\x98\\x82\" \"_field\\xcf\\x80\" \";\\n\" \" ^\\n\" \" &\\n\"" , "pp_formatted_text (dc.printer)", (" \xf0\x9f\x98\x82" "_foo = \xcf\x80" "_bar.\xf0\x9f\x98\x82" "_field\xcf\x80" ";\n" " ^\n" " &\n"), (pp_formatted_text (dc.printer))); } while (0) |
3930 | pp_formatted_text (dc.printer))do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 3930, __FUNCTION__)), "\" \\xf0\\x9f\\x98\\x82\" \"_foo = \\xcf\\x80\" \"_bar.\\xf0\\x9f\\x98\\x82\" \"_field\\xcf\\x80\" \";\\n\" \" ^\\n\" \" &\\n\"" , "pp_formatted_text (dc.printer)", (" \xf0\x9f\x98\x82" "_foo = \xcf\x80" "_bar.\xf0\x9f\x98\x82" "_field\xcf\x80" ";\n" " ^\n" " &\n"), (pp_formatted_text (dc.printer))); } while (0); |
3931 | } |
3932 | |
3933 | /* Insertion fix-it hint: adding a "[0]" after "SS_foo". */ |
3934 | |
3935 | static void |
3936 | test_one_liner_fixit_insert_after_utf8 () |
3937 | { |
3938 | test_diagnostic_context dc; |
3939 | location_t start = linemap_position_for_column (line_table, 1); |
3940 | location_t finish = linemap_position_for_column (line_table, 8); |
3941 | location_t foo = make_location (start, start, finish); |
3942 | rich_location richloc (line_table, foo); |
3943 | richloc.add_fixit_insert_after ("[0]"); |
3944 | diagnostic_show_locus (&dc, &richloc, DK_ERROR); |
3945 | ASSERT_STREQ (" \xf0\x9f\x98\x82"do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 3952, __FUNCTION__)), "\" \\xf0\\x9f\\x98\\x82\" \"_foo = \\xcf\\x80\" \"_bar.\\xf0\\x9f\\x98\\x82\" \"_field\\xcf\\x80\" \";\\n\" \" ^~~~~~\\n\" \" [0]\\n\"" , "pp_formatted_text (dc.printer)", (" \xf0\x9f\x98\x82" "_foo = \xcf\x80" "_bar.\xf0\x9f\x98\x82" "_field\xcf\x80" ";\n" " ^~~~~~\n" " [0]\n" ), (pp_formatted_text (dc.printer))); } while (0) |
3946 | "_foo = \xcf\x80"do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 3952, __FUNCTION__)), "\" \\xf0\\x9f\\x98\\x82\" \"_foo = \\xcf\\x80\" \"_bar.\\xf0\\x9f\\x98\\x82\" \"_field\\xcf\\x80\" \";\\n\" \" ^~~~~~\\n\" \" [0]\\n\"" , "pp_formatted_text (dc.printer)", (" \xf0\x9f\x98\x82" "_foo = \xcf\x80" "_bar.\xf0\x9f\x98\x82" "_field\xcf\x80" ";\n" " ^~~~~~\n" " [0]\n" ), (pp_formatted_text (dc.printer))); } while (0) |
3947 | "_bar.\xf0\x9f\x98\x82"do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 3952, __FUNCTION__)), "\" \\xf0\\x9f\\x98\\x82\" \"_foo = \\xcf\\x80\" \"_bar.\\xf0\\x9f\\x98\\x82\" \"_field\\xcf\\x80\" \";\\n\" \" ^~~~~~\\n\" \" [0]\\n\"" , "pp_formatted_text (dc.printer)", (" \xf0\x9f\x98\x82" "_foo = \xcf\x80" "_bar.\xf0\x9f\x98\x82" "_field\xcf\x80" ";\n" " ^~~~~~\n" " [0]\n" ), (pp_formatted_text (dc.printer))); } while (0) |
3948 | "_field\xcf\x80"do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 3952, __FUNCTION__)), "\" \\xf0\\x9f\\x98\\x82\" \"_foo = \\xcf\\x80\" \"_bar.\\xf0\\x9f\\x98\\x82\" \"_field\\xcf\\x80\" \";\\n\" \" ^~~~~~\\n\" \" [0]\\n\"" , "pp_formatted_text (dc.printer)", (" \xf0\x9f\x98\x82" "_foo = \xcf\x80" "_bar.\xf0\x9f\x98\x82" "_field\xcf\x80" ";\n" " ^~~~~~\n" " [0]\n" ), (pp_formatted_text (dc.printer))); } while (0) |
3949 | ";\n"do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 3952, __FUNCTION__)), "\" \\xf0\\x9f\\x98\\x82\" \"_foo = \\xcf\\x80\" \"_bar.\\xf0\\x9f\\x98\\x82\" \"_field\\xcf\\x80\" \";\\n\" \" ^~~~~~\\n\" \" [0]\\n\"" , "pp_formatted_text (dc.printer)", (" \xf0\x9f\x98\x82" "_foo = \xcf\x80" "_bar.\xf0\x9f\x98\x82" "_field\xcf\x80" ";\n" " ^~~~~~\n" " [0]\n" ), (pp_formatted_text (dc.printer))); } while (0) |
3950 | " ^~~~~~\n"do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 3952, __FUNCTION__)), "\" \\xf0\\x9f\\x98\\x82\" \"_foo = \\xcf\\x80\" \"_bar.\\xf0\\x9f\\x98\\x82\" \"_field\\xcf\\x80\" \";\\n\" \" ^~~~~~\\n\" \" [0]\\n\"" , "pp_formatted_text (dc.printer)", (" \xf0\x9f\x98\x82" "_foo = \xcf\x80" "_bar.\xf0\x9f\x98\x82" "_field\xcf\x80" ";\n" " ^~~~~~\n" " [0]\n" ), (pp_formatted_text (dc.printer))); } while (0) |
3951 | " [0]\n",do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 3952, __FUNCTION__)), "\" \\xf0\\x9f\\x98\\x82\" \"_foo = \\xcf\\x80\" \"_bar.\\xf0\\x9f\\x98\\x82\" \"_field\\xcf\\x80\" \";\\n\" \" ^~~~~~\\n\" \" [0]\\n\"" , "pp_formatted_text (dc.printer)", (" \xf0\x9f\x98\x82" "_foo = \xcf\x80" "_bar.\xf0\x9f\x98\x82" "_field\xcf\x80" ";\n" " ^~~~~~\n" " [0]\n" ), (pp_formatted_text (dc.printer))); } while (0) |
3952 | pp_formatted_text (dc.printer))do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 3952, __FUNCTION__)), "\" \\xf0\\x9f\\x98\\x82\" \"_foo = \\xcf\\x80\" \"_bar.\\xf0\\x9f\\x98\\x82\" \"_field\\xcf\\x80\" \";\\n\" \" ^~~~~~\\n\" \" [0]\\n\"" , "pp_formatted_text (dc.printer)", (" \xf0\x9f\x98\x82" "_foo = \xcf\x80" "_bar.\xf0\x9f\x98\x82" "_field\xcf\x80" ";\n" " ^~~~~~\n" " [0]\n" ), (pp_formatted_text (dc.printer))); } while (0); |
3953 | } |
3954 | |
3955 | /* Removal fix-it hint: removal of the ".SS_fieldP". */ |
3956 | |
3957 | static void |
3958 | test_one_liner_fixit_remove_utf8 () |
3959 | { |
3960 | test_diagnostic_context dc; |
3961 | location_t start = linemap_position_for_column (line_table, 18); |
3962 | location_t finish = linemap_position_for_column (line_table, 30); |
3963 | location_t dot = make_location (start, start, finish); |
3964 | rich_location richloc (line_table, dot); |
3965 | richloc.add_fixit_remove (); |
3966 | diagnostic_show_locus (&dc, &richloc, DK_ERROR); |
3967 | ASSERT_STREQ (" \xf0\x9f\x98\x82"do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 3974, __FUNCTION__)), "\" \\xf0\\x9f\\x98\\x82\" \"_foo = \\xcf\\x80\" \"_bar.\\xf0\\x9f\\x98\\x82\" \"_field\\xcf\\x80\" \";\\n\" \" ^~~~~~~~~~\\n\" \" ----------\\n\"" , "pp_formatted_text (dc.printer)", (" \xf0\x9f\x98\x82" "_foo = \xcf\x80" "_bar.\xf0\x9f\x98\x82" "_field\xcf\x80" ";\n" " ^~~~~~~~~~\n" " ----------\n"), (pp_formatted_text (dc.printer ))); } while (0) |
3968 | "_foo = \xcf\x80"do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 3974, __FUNCTION__)), "\" \\xf0\\x9f\\x98\\x82\" \"_foo = \\xcf\\x80\" \"_bar.\\xf0\\x9f\\x98\\x82\" \"_field\\xcf\\x80\" \";\\n\" \" ^~~~~~~~~~\\n\" \" ----------\\n\"" , "pp_formatted_text (dc.printer)", (" \xf0\x9f\x98\x82" "_foo = \xcf\x80" "_bar.\xf0\x9f\x98\x82" "_field\xcf\x80" ";\n" " ^~~~~~~~~~\n" " ----------\n"), (pp_formatted_text (dc.printer ))); } while (0) |
3969 | "_bar.\xf0\x9f\x98\x82"do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 3974, __FUNCTION__)), "\" \\xf0\\x9f\\x98\\x82\" \"_foo = \\xcf\\x80\" \"_bar.\\xf0\\x9f\\x98\\x82\" \"_field\\xcf\\x80\" \";\\n\" \" ^~~~~~~~~~\\n\" \" ----------\\n\"" , "pp_formatted_text (dc.printer)", (" \xf0\x9f\x98\x82" "_foo = \xcf\x80" "_bar.\xf0\x9f\x98\x82" "_field\xcf\x80" ";\n" " ^~~~~~~~~~\n" " ----------\n"), (pp_formatted_text (dc.printer ))); } while (0) |
3970 | "_field\xcf\x80"do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 3974, __FUNCTION__)), "\" \\xf0\\x9f\\x98\\x82\" \"_foo = \\xcf\\x80\" \"_bar.\\xf0\\x9f\\x98\\x82\" \"_field\\xcf\\x80\" \";\\n\" \" ^~~~~~~~~~\\n\" \" ----------\\n\"" , "pp_formatted_text (dc.printer)", (" \xf0\x9f\x98\x82" "_foo = \xcf\x80" "_bar.\xf0\x9f\x98\x82" "_field\xcf\x80" ";\n" " ^~~~~~~~~~\n" " ----------\n"), (pp_formatted_text (dc.printer ))); } while (0) |
3971 | ";\n"do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 3974, __FUNCTION__)), "\" \\xf0\\x9f\\x98\\x82\" \"_foo = \\xcf\\x80\" \"_bar.\\xf0\\x9f\\x98\\x82\" \"_field\\xcf\\x80\" \";\\n\" \" ^~~~~~~~~~\\n\" \" ----------\\n\"" , "pp_formatted_text (dc.printer)", (" \xf0\x9f\x98\x82" "_foo = \xcf\x80" "_bar.\xf0\x9f\x98\x82" "_field\xcf\x80" ";\n" " ^~~~~~~~~~\n" " ----------\n"), (pp_formatted_text (dc.printer ))); } while (0) |
3972 | " ^~~~~~~~~~\n"do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 3974, __FUNCTION__)), "\" \\xf0\\x9f\\x98\\x82\" \"_foo = \\xcf\\x80\" \"_bar.\\xf0\\x9f\\x98\\x82\" \"_field\\xcf\\x80\" \";\\n\" \" ^~~~~~~~~~\\n\" \" ----------\\n\"" , "pp_formatted_text (dc.printer)", (" \xf0\x9f\x98\x82" "_foo = \xcf\x80" "_bar.\xf0\x9f\x98\x82" "_field\xcf\x80" ";\n" " ^~~~~~~~~~\n" " ----------\n"), (pp_formatted_text (dc.printer ))); } while (0) |
3973 | " ----------\n",do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 3974, __FUNCTION__)), "\" \\xf0\\x9f\\x98\\x82\" \"_foo = \\xcf\\x80\" \"_bar.\\xf0\\x9f\\x98\\x82\" \"_field\\xcf\\x80\" \";\\n\" \" ^~~~~~~~~~\\n\" \" ----------\\n\"" , "pp_formatted_text (dc.printer)", (" \xf0\x9f\x98\x82" "_foo = \xcf\x80" "_bar.\xf0\x9f\x98\x82" "_field\xcf\x80" ";\n" " ^~~~~~~~~~\n" " ----------\n"), (pp_formatted_text (dc.printer ))); } while (0) |
3974 | pp_formatted_text (dc.printer))do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 3974, __FUNCTION__)), "\" \\xf0\\x9f\\x98\\x82\" \"_foo = \\xcf\\x80\" \"_bar.\\xf0\\x9f\\x98\\x82\" \"_field\\xcf\\x80\" \";\\n\" \" ^~~~~~~~~~\\n\" \" ----------\\n\"" , "pp_formatted_text (dc.printer)", (" \xf0\x9f\x98\x82" "_foo = \xcf\x80" "_bar.\xf0\x9f\x98\x82" "_field\xcf\x80" ";\n" " ^~~~~~~~~~\n" " ----------\n"), (pp_formatted_text (dc.printer ))); } while (0); |
3975 | } |
3976 | |
3977 | /* Replace fix-it hint: replacing "SS_fieldP" with "m_SSfieldP". */ |
3978 | |
3979 | static void |
3980 | test_one_liner_fixit_replace_utf8 () |
3981 | { |
3982 | test_diagnostic_context dc; |
3983 | location_t start = linemap_position_for_column (line_table, 19); |
3984 | location_t finish = linemap_position_for_column (line_table, 30); |
3985 | location_t field = make_location (start, start, finish); |
3986 | rich_location richloc (line_table, field); |
3987 | richloc.add_fixit_replace ("m_\xf0\x9f\x98\x82_field\xcf\x80"); |
3988 | diagnostic_show_locus (&dc, &richloc, DK_ERROR); |
3989 | ASSERT_STREQ (" \xf0\x9f\x98\x82"do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 3997, __FUNCTION__)), "\" \\xf0\\x9f\\x98\\x82\" \"_foo = \\xcf\\x80\" \"_bar.\\xf0\\x9f\\x98\\x82\" \"_field\\xcf\\x80\" \";\\n\" \" ^~~~~~~~~\\n\" \" m_\\xf0\\x9f\\x98\\x82\" \"_field\\xcf\\x80\\n\"" , "pp_formatted_text (dc.printer)", (" \xf0\x9f\x98\x82" "_foo = \xcf\x80" "_bar.\xf0\x9f\x98\x82" "_field\xcf\x80" ";\n" " ^~~~~~~~~\n" " m_\xf0\x9f\x98\x82" "_field\xcf\x80\n"), (pp_formatted_text (dc.printer))); } while (0) |
3990 | "_foo = \xcf\x80"do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 3997, __FUNCTION__)), "\" \\xf0\\x9f\\x98\\x82\" \"_foo = \\xcf\\x80\" \"_bar.\\xf0\\x9f\\x98\\x82\" \"_field\\xcf\\x80\" \";\\n\" \" ^~~~~~~~~\\n\" \" m_\\xf0\\x9f\\x98\\x82\" \"_field\\xcf\\x80\\n\"" , "pp_formatted_text (dc.printer)", (" \xf0\x9f\x98\x82" "_foo = \xcf\x80" "_bar.\xf0\x9f\x98\x82" "_field\xcf\x80" ";\n" " ^~~~~~~~~\n" " m_\xf0\x9f\x98\x82" "_field\xcf\x80\n"), (pp_formatted_text (dc.printer))); } while (0) |
3991 | "_bar.\xf0\x9f\x98\x82"do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 3997, __FUNCTION__)), "\" \\xf0\\x9f\\x98\\x82\" \"_foo = \\xcf\\x80\" \"_bar.\\xf0\\x9f\\x98\\x82\" \"_field\\xcf\\x80\" \";\\n\" \" ^~~~~~~~~\\n\" \" m_\\xf0\\x9f\\x98\\x82\" \"_field\\xcf\\x80\\n\"" , "pp_formatted_text (dc.printer)", (" \xf0\x9f\x98\x82" "_foo = \xcf\x80" "_bar.\xf0\x9f\x98\x82" "_field\xcf\x80" ";\n" " ^~~~~~~~~\n" " m_\xf0\x9f\x98\x82" "_field\xcf\x80\n"), (pp_formatted_text (dc.printer))); } while (0) |
3992 | "_field\xcf\x80"do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 3997, __FUNCTION__)), "\" \\xf0\\x9f\\x98\\x82\" \"_foo = \\xcf\\x80\" \"_bar.\\xf0\\x9f\\x98\\x82\" \"_field\\xcf\\x80\" \";\\n\" \" ^~~~~~~~~\\n\" \" m_\\xf0\\x9f\\x98\\x82\" \"_field\\xcf\\x80\\n\"" , "pp_formatted_text (dc.printer)", (" \xf0\x9f\x98\x82" "_foo = \xcf\x80" "_bar.\xf0\x9f\x98\x82" "_field\xcf\x80" ";\n" " ^~~~~~~~~\n" " m_\xf0\x9f\x98\x82" "_field\xcf\x80\n"), (pp_formatted_text (dc.printer))); } while (0) |
3993 | ";\n"do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 3997, __FUNCTION__)), "\" \\xf0\\x9f\\x98\\x82\" \"_foo = \\xcf\\x80\" \"_bar.\\xf0\\x9f\\x98\\x82\" \"_field\\xcf\\x80\" \";\\n\" \" ^~~~~~~~~\\n\" \" m_\\xf0\\x9f\\x98\\x82\" \"_field\\xcf\\x80\\n\"" , "pp_formatted_text (dc.printer)", (" \xf0\x9f\x98\x82" "_foo = \xcf\x80" "_bar.\xf0\x9f\x98\x82" "_field\xcf\x80" ";\n" " ^~~~~~~~~\n" " m_\xf0\x9f\x98\x82" "_field\xcf\x80\n"), (pp_formatted_text (dc.printer))); } while (0) |
3994 | " ^~~~~~~~~\n"do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 3997, __FUNCTION__)), "\" \\xf0\\x9f\\x98\\x82\" \"_foo = \\xcf\\x80\" \"_bar.\\xf0\\x9f\\x98\\x82\" \"_field\\xcf\\x80\" \";\\n\" \" ^~~~~~~~~\\n\" \" m_\\xf0\\x9f\\x98\\x82\" \"_field\\xcf\\x80\\n\"" , "pp_formatted_text (dc.printer)", (" \xf0\x9f\x98\x82" "_foo = \xcf\x80" "_bar.\xf0\x9f\x98\x82" "_field\xcf\x80" ";\n" " ^~~~~~~~~\n" " m_\xf0\x9f\x98\x82" "_field\xcf\x80\n"), (pp_formatted_text (dc.printer))); } while (0) |
3995 | " m_\xf0\x9f\x98\x82"do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 3997, __FUNCTION__)), "\" \\xf0\\x9f\\x98\\x82\" \"_foo = \\xcf\\x80\" \"_bar.\\xf0\\x9f\\x98\\x82\" \"_field\\xcf\\x80\" \";\\n\" \" ^~~~~~~~~\\n\" \" m_\\xf0\\x9f\\x98\\x82\" \"_field\\xcf\\x80\\n\"" , "pp_formatted_text (dc.printer)", (" \xf0\x9f\x98\x82" "_foo = \xcf\x80" "_bar.\xf0\x9f\x98\x82" "_field\xcf\x80" ";\n" " ^~~~~~~~~\n" " m_\xf0\x9f\x98\x82" "_field\xcf\x80\n"), (pp_formatted_text (dc.printer))); } while (0) |
3996 | "_field\xcf\x80\n",do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 3997, __FUNCTION__)), "\" \\xf0\\x9f\\x98\\x82\" \"_foo = \\xcf\\x80\" \"_bar.\\xf0\\x9f\\x98\\x82\" \"_field\\xcf\\x80\" \";\\n\" \" ^~~~~~~~~\\n\" \" m_\\xf0\\x9f\\x98\\x82\" \"_field\\xcf\\x80\\n\"" , "pp_formatted_text (dc.printer)", (" \xf0\x9f\x98\x82" "_foo = \xcf\x80" "_bar.\xf0\x9f\x98\x82" "_field\xcf\x80" ";\n" " ^~~~~~~~~\n" " m_\xf0\x9f\x98\x82" "_field\xcf\x80\n"), (pp_formatted_text (dc.printer))); } while (0) |
3997 | pp_formatted_text (dc.printer))do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 3997, __FUNCTION__)), "\" \\xf0\\x9f\\x98\\x82\" \"_foo = \\xcf\\x80\" \"_bar.\\xf0\\x9f\\x98\\x82\" \"_field\\xcf\\x80\" \";\\n\" \" ^~~~~~~~~\\n\" \" m_\\xf0\\x9f\\x98\\x82\" \"_field\\xcf\\x80\\n\"" , "pp_formatted_text (dc.printer)", (" \xf0\x9f\x98\x82" "_foo = \xcf\x80" "_bar.\xf0\x9f\x98\x82" "_field\xcf\x80" ";\n" " ^~~~~~~~~\n" " m_\xf0\x9f\x98\x82" "_field\xcf\x80\n"), (pp_formatted_text (dc.printer))); } while (0); |
3998 | } |
3999 | |
4000 | /* Replace fix-it hint: replacing "SS_fieldP" with "m_SSfieldP", |
4001 | but where the caret was elsewhere. */ |
4002 | |
4003 | static void |
4004 | test_one_liner_fixit_replace_non_equal_range_utf8 () |
4005 | { |
4006 | test_diagnostic_context dc; |
4007 | location_t equals = linemap_position_for_column (line_table, 10); |
4008 | location_t start = linemap_position_for_column (line_table, 19); |
4009 | location_t finish = linemap_position_for_column (line_table, 30); |
4010 | rich_location richloc (line_table, equals); |
4011 | source_range range; |
4012 | range.m_start = start; |
4013 | range.m_finish = finish; |
4014 | richloc.add_fixit_replace (range, "m_\xf0\x9f\x98\x82_field\xcf\x80"); |
4015 | diagnostic_show_locus (&dc, &richloc, DK_ERROR); |
4016 | /* The replacement range is not indicated in the annotation line, so |
4017 | it should be indicated via an additional underline. */ |
4018 | ASSERT_STREQ (" \xf0\x9f\x98\x82"do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 4027, __FUNCTION__)), "\" \\xf0\\x9f\\x98\\x82\" \"_foo = \\xcf\\x80\" \"_bar.\\xf0\\x9f\\x98\\x82\" \"_field\\xcf\\x80\" \";\\n\" \" ^\\n\" \" ---------\\n\" \" m_\\xf0\\x9f\\x98\\x82\" \"_field\\xcf\\x80\\n\"" , "pp_formatted_text (dc.printer)", (" \xf0\x9f\x98\x82" "_foo = \xcf\x80" "_bar.\xf0\x9f\x98\x82" "_field\xcf\x80" ";\n" " ^\n" " ---------\n" " m_\xf0\x9f\x98\x82" "_field\xcf\x80\n"), (pp_formatted_text (dc.printer))); } while (0) |
4019 | "_foo = \xcf\x80"do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 4027, __FUNCTION__)), "\" \\xf0\\x9f\\x98\\x82\" \"_foo = \\xcf\\x80\" \"_bar.\\xf0\\x9f\\x98\\x82\" \"_field\\xcf\\x80\" \";\\n\" \" ^\\n\" \" ---------\\n\" \" m_\\xf0\\x9f\\x98\\x82\" \"_field\\xcf\\x80\\n\"" , "pp_formatted_text (dc.printer)", (" \xf0\x9f\x98\x82" "_foo = \xcf\x80" "_bar.\xf0\x9f\x98\x82" "_field\xcf\x80" ";\n" " ^\n" " ---------\n" " m_\xf0\x9f\x98\x82" "_field\xcf\x80\n"), (pp_formatted_text (dc.printer))); } while (0) |
4020 | "_bar.\xf0\x9f\x98\x82"do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 4027, __FUNCTION__)), "\" \\xf0\\x9f\\x98\\x82\" \"_foo = \\xcf\\x80\" \"_bar.\\xf0\\x9f\\x98\\x82\" \"_field\\xcf\\x80\" \";\\n\" \" ^\\n\" \" ---------\\n\" \" m_\\xf0\\x9f\\x98\\x82\" \"_field\\xcf\\x80\\n\"" , "pp_formatted_text (dc.printer)", (" \xf0\x9f\x98\x82" "_foo = \xcf\x80" "_bar.\xf0\x9f\x98\x82" "_field\xcf\x80" ";\n" " ^\n" " ---------\n" " m_\xf0\x9f\x98\x82" "_field\xcf\x80\n"), (pp_formatted_text (dc.printer))); } while (0) |
4021 | "_field\xcf\x80"do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 4027, __FUNCTION__)), "\" \\xf0\\x9f\\x98\\x82\" \"_foo = \\xcf\\x80\" \"_bar.\\xf0\\x9f\\x98\\x82\" \"_field\\xcf\\x80\" \";\\n\" \" ^\\n\" \" ---------\\n\" \" m_\\xf0\\x9f\\x98\\x82\" \"_field\\xcf\\x80\\n\"" , "pp_formatted_text (dc.printer)", (" \xf0\x9f\x98\x82" "_foo = \xcf\x80" "_bar.\xf0\x9f\x98\x82" "_field\xcf\x80" ";\n" " ^\n" " ---------\n" " m_\xf0\x9f\x98\x82" "_field\xcf\x80\n"), (pp_formatted_text (dc.printer))); } while (0) |
4022 | ";\n"do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 4027, __FUNCTION__)), "\" \\xf0\\x9f\\x98\\x82\" \"_foo = \\xcf\\x80\" \"_bar.\\xf0\\x9f\\x98\\x82\" \"_field\\xcf\\x80\" \";\\n\" \" ^\\n\" \" ---------\\n\" \" m_\\xf0\\x9f\\x98\\x82\" \"_field\\xcf\\x80\\n\"" , "pp_formatted_text (dc.printer)", (" \xf0\x9f\x98\x82" "_foo = \xcf\x80" "_bar.\xf0\x9f\x98\x82" "_field\xcf\x80" ";\n" " ^\n" " ---------\n" " m_\xf0\x9f\x98\x82" "_field\xcf\x80\n"), (pp_formatted_text (dc.printer))); } while (0) |
4023 | " ^\n"do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 4027, __FUNCTION__)), "\" \\xf0\\x9f\\x98\\x82\" \"_foo = \\xcf\\x80\" \"_bar.\\xf0\\x9f\\x98\\x82\" \"_field\\xcf\\x80\" \";\\n\" \" ^\\n\" \" ---------\\n\" \" m_\\xf0\\x9f\\x98\\x82\" \"_field\\xcf\\x80\\n\"" , "pp_formatted_text (dc.printer)", (" \xf0\x9f\x98\x82" "_foo = \xcf\x80" "_bar.\xf0\x9f\x98\x82" "_field\xcf\x80" ";\n" " ^\n" " ---------\n" " m_\xf0\x9f\x98\x82" "_field\xcf\x80\n"), (pp_formatted_text (dc.printer))); } while (0) |
4024 | " ---------\n"do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 4027, __FUNCTION__)), "\" \\xf0\\x9f\\x98\\x82\" \"_foo = \\xcf\\x80\" \"_bar.\\xf0\\x9f\\x98\\x82\" \"_field\\xcf\\x80\" \";\\n\" \" ^\\n\" \" ---------\\n\" \" m_\\xf0\\x9f\\x98\\x82\" \"_field\\xcf\\x80\\n\"" , "pp_formatted_text (dc.printer)", (" \xf0\x9f\x98\x82" "_foo = \xcf\x80" "_bar.\xf0\x9f\x98\x82" "_field\xcf\x80" ";\n" " ^\n" " ---------\n" " m_\xf0\x9f\x98\x82" "_field\xcf\x80\n"), (pp_formatted_text (dc.printer))); } while (0) |
4025 | " m_\xf0\x9f\x98\x82"do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 4027, __FUNCTION__)), "\" \\xf0\\x9f\\x98\\x82\" \"_foo = \\xcf\\x80\" \"_bar.\\xf0\\x9f\\x98\\x82\" \"_field\\xcf\\x80\" \";\\n\" \" ^\\n\" \" ---------\\n\" \" m_\\xf0\\x9f\\x98\\x82\" \"_field\\xcf\\x80\\n\"" , "pp_formatted_text (dc.printer)", (" \xf0\x9f\x98\x82" "_foo = \xcf\x80" "_bar.\xf0\x9f\x98\x82" "_field\xcf\x80" ";\n" " ^\n" " ---------\n" " m_\xf0\x9f\x98\x82" "_field\xcf\x80\n"), (pp_formatted_text (dc.printer))); } while (0) |
4026 | "_field\xcf\x80\n",do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 4027, __FUNCTION__)), "\" \\xf0\\x9f\\x98\\x82\" \"_foo = \\xcf\\x80\" \"_bar.\\xf0\\x9f\\x98\\x82\" \"_field\\xcf\\x80\" \";\\n\" \" ^\\n\" \" ---------\\n\" \" m_\\xf0\\x9f\\x98\\x82\" \"_field\\xcf\\x80\\n\"" , "pp_formatted_text (dc.printer)", (" \xf0\x9f\x98\x82" "_foo = \xcf\x80" "_bar.\xf0\x9f\x98\x82" "_field\xcf\x80" ";\n" " ^\n" " ---------\n" " m_\xf0\x9f\x98\x82" "_field\xcf\x80\n"), (pp_formatted_text (dc.printer))); } while (0) |
4027 | pp_formatted_text (dc.printer))do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 4027, __FUNCTION__)), "\" \\xf0\\x9f\\x98\\x82\" \"_foo = \\xcf\\x80\" \"_bar.\\xf0\\x9f\\x98\\x82\" \"_field\\xcf\\x80\" \";\\n\" \" ^\\n\" \" ---------\\n\" \" m_\\xf0\\x9f\\x98\\x82\" \"_field\\xcf\\x80\\n\"" , "pp_formatted_text (dc.printer)", (" \xf0\x9f\x98\x82" "_foo = \xcf\x80" "_bar.\xf0\x9f\x98\x82" "_field\xcf\x80" ";\n" " ^\n" " ---------\n" " m_\xf0\x9f\x98\x82" "_field\xcf\x80\n"), (pp_formatted_text (dc.printer))); } while (0); |
4028 | } |
4029 | |
4030 | /* Replace fix-it hint: replacing "SS_fieldP" with "m_SSfieldP", |
4031 | where the caret was elsewhere, but where a secondary range |
4032 | exactly covers "field". */ |
4033 | |
4034 | static void |
4035 | test_one_liner_fixit_replace_equal_secondary_range_utf8 () |
4036 | { |
4037 | test_diagnostic_context dc; |
4038 | location_t equals = linemap_position_for_column (line_table, 10); |
4039 | location_t start = linemap_position_for_column (line_table, 19); |
4040 | location_t finish = linemap_position_for_column (line_table, 30); |
4041 | rich_location richloc (line_table, equals); |
4042 | location_t field = make_location (start, start, finish); |
4043 | richloc.add_range (field); |
4044 | richloc.add_fixit_replace (field, "m_\xf0\x9f\x98\x82_field\xcf\x80"); |
4045 | diagnostic_show_locus (&dc, &richloc, DK_ERROR); |
4046 | /* The replacement range is indicated in the annotation line, |
4047 | so it shouldn't be indicated via an additional underline. */ |
4048 | ASSERT_STREQ (" \xf0\x9f\x98\x82"do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 4056, __FUNCTION__)), "\" \\xf0\\x9f\\x98\\x82\" \"_foo = \\xcf\\x80\" \"_bar.\\xf0\\x9f\\x98\\x82\" \"_field\\xcf\\x80\" \";\\n\" \" ^ ~~~~~~~~~\\n\" \" m_\\xf0\\x9f\\x98\\x82\" \"_field\\xcf\\x80\\n\"" , "pp_formatted_text (dc.printer)", (" \xf0\x9f\x98\x82" "_foo = \xcf\x80" "_bar.\xf0\x9f\x98\x82" "_field\xcf\x80" ";\n" " ^ ~~~~~~~~~\n" " m_\xf0\x9f\x98\x82" "_field\xcf\x80\n"), (pp_formatted_text (dc.printer))); } while (0) |
4049 | "_foo = \xcf\x80"do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 4056, __FUNCTION__)), "\" \\xf0\\x9f\\x98\\x82\" \"_foo = \\xcf\\x80\" \"_bar.\\xf0\\x9f\\x98\\x82\" \"_field\\xcf\\x80\" \";\\n\" \" ^ ~~~~~~~~~\\n\" \" m_\\xf0\\x9f\\x98\\x82\" \"_field\\xcf\\x80\\n\"" , "pp_formatted_text (dc.printer)", (" \xf0\x9f\x98\x82" "_foo = \xcf\x80" "_bar.\xf0\x9f\x98\x82" "_field\xcf\x80" ";\n" " ^ ~~~~~~~~~\n" " m_\xf0\x9f\x98\x82" "_field\xcf\x80\n"), (pp_formatted_text (dc.printer))); } while (0) |
4050 | "_bar.\xf0\x9f\x98\x82"do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 4056, __FUNCTION__)), "\" \\xf0\\x9f\\x98\\x82\" \"_foo = \\xcf\\x80\" \"_bar.\\xf0\\x9f\\x98\\x82\" \"_field\\xcf\\x80\" \";\\n\" \" ^ ~~~~~~~~~\\n\" \" m_\\xf0\\x9f\\x98\\x82\" \"_field\\xcf\\x80\\n\"" , "pp_formatted_text (dc.printer)", (" \xf0\x9f\x98\x82" "_foo = \xcf\x80" "_bar.\xf0\x9f\x98\x82" "_field\xcf\x80" ";\n" " ^ ~~~~~~~~~\n" " m_\xf0\x9f\x98\x82" "_field\xcf\x80\n"), (pp_formatted_text (dc.printer))); } while (0) |
4051 | "_field\xcf\x80"do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 4056, __FUNCTION__)), "\" \\xf0\\x9f\\x98\\x82\" \"_foo = \\xcf\\x80\" \"_bar.\\xf0\\x9f\\x98\\x82\" \"_field\\xcf\\x80\" \";\\n\" \" ^ ~~~~~~~~~\\n\" \" m_\\xf0\\x9f\\x98\\x82\" \"_field\\xcf\\x80\\n\"" , "pp_formatted_text (dc.printer)", (" \xf0\x9f\x98\x82" "_foo = \xcf\x80" "_bar.\xf0\x9f\x98\x82" "_field\xcf\x80" ";\n" " ^ ~~~~~~~~~\n" " m_\xf0\x9f\x98\x82" "_field\xcf\x80\n"), (pp_formatted_text (dc.printer))); } while (0) |
4052 | ";\n"do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 4056, __FUNCTION__)), "\" \\xf0\\x9f\\x98\\x82\" \"_foo = \\xcf\\x80\" \"_bar.\\xf0\\x9f\\x98\\x82\" \"_field\\xcf\\x80\" \";\\n\" \" ^ ~~~~~~~~~\\n\" \" m_\\xf0\\x9f\\x98\\x82\" \"_field\\xcf\\x80\\n\"" , "pp_formatted_text (dc.printer)", (" \xf0\x9f\x98\x82" "_foo = \xcf\x80" "_bar.\xf0\x9f\x98\x82" "_field\xcf\x80" ";\n" " ^ ~~~~~~~~~\n" " m_\xf0\x9f\x98\x82" "_field\xcf\x80\n"), (pp_formatted_text (dc.printer))); } while (0) |
4053 | " ^ ~~~~~~~~~\n"do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 4056, __FUNCTION__)), "\" \\xf0\\x9f\\x98\\x82\" \"_foo = \\xcf\\x80\" \"_bar.\\xf0\\x9f\\x98\\x82\" \"_field\\xcf\\x80\" \";\\n\" \" ^ ~~~~~~~~~\\n\" \" m_\\xf0\\x9f\\x98\\x82\" \"_field\\xcf\\x80\\n\"" , "pp_formatted_text (dc.printer)", (" \xf0\x9f\x98\x82" "_foo = \xcf\x80" "_bar.\xf0\x9f\x98\x82" "_field\xcf\x80" ";\n" " ^ ~~~~~~~~~\n" " m_\xf0\x9f\x98\x82" "_field\xcf\x80\n"), (pp_formatted_text (dc.printer))); } while (0) |
4054 | " m_\xf0\x9f\x98\x82"do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 4056, __FUNCTION__)), "\" \\xf0\\x9f\\x98\\x82\" \"_foo = \\xcf\\x80\" \"_bar.\\xf0\\x9f\\x98\\x82\" \"_field\\xcf\\x80\" \";\\n\" \" ^ ~~~~~~~~~\\n\" \" m_\\xf0\\x9f\\x98\\x82\" \"_field\\xcf\\x80\\n\"" , "pp_formatted_text (dc.printer)", (" \xf0\x9f\x98\x82" "_foo = \xcf\x80" "_bar.\xf0\x9f\x98\x82" "_field\xcf\x80" ";\n" " ^ ~~~~~~~~~\n" " m_\xf0\x9f\x98\x82" "_field\xcf\x80\n"), (pp_formatted_text (dc.printer))); } while (0) |
4055 | "_field\xcf\x80\n",do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 4056, __FUNCTION__)), "\" \\xf0\\x9f\\x98\\x82\" \"_foo = \\xcf\\x80\" \"_bar.\\xf0\\x9f\\x98\\x82\" \"_field\\xcf\\x80\" \";\\n\" \" ^ ~~~~~~~~~\\n\" \" m_\\xf0\\x9f\\x98\\x82\" \"_field\\xcf\\x80\\n\"" , "pp_formatted_text (dc.printer)", (" \xf0\x9f\x98\x82" "_foo = \xcf\x80" "_bar.\xf0\x9f\x98\x82" "_field\xcf\x80" ";\n" " ^ ~~~~~~~~~\n" " m_\xf0\x9f\x98\x82" "_field\xcf\x80\n"), (pp_formatted_text (dc.printer))); } while (0) |
4056 | pp_formatted_text (dc.printer))do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 4056, __FUNCTION__)), "\" \\xf0\\x9f\\x98\\x82\" \"_foo = \\xcf\\x80\" \"_bar.\\xf0\\x9f\\x98\\x82\" \"_field\\xcf\\x80\" \";\\n\" \" ^ ~~~~~~~~~\\n\" \" m_\\xf0\\x9f\\x98\\x82\" \"_field\\xcf\\x80\\n\"" , "pp_formatted_text (dc.printer)", (" \xf0\x9f\x98\x82" "_foo = \xcf\x80" "_bar.\xf0\x9f\x98\x82" "_field\xcf\x80" ";\n" " ^ ~~~~~~~~~\n" " m_\xf0\x9f\x98\x82" "_field\xcf\x80\n"), (pp_formatted_text (dc.printer))); } while (0); |
4057 | } |
4058 | |
4059 | /* Verify that we can use ad-hoc locations when adding fixits to a |
4060 | rich_location. */ |
4061 | |
4062 | static void |
4063 | test_one_liner_fixit_validation_adhoc_locations_utf8 () |
4064 | { |
4065 | /* Generate a range that's too long to be packed, so must |
4066 | be stored as an ad-hoc location (given the defaults |
4067 | of 5 bits or 0 bits of packed range); 41 columns > 2**5. */ |
4068 | const location_t c12 = linemap_position_for_column (line_table, 12); |
4069 | const location_t c52 = linemap_position_for_column (line_table, 52); |
4070 | const location_t loc = make_location (c12, c12, c52); |
4071 | |
4072 | if (c52 > LINE_MAP_MAX_LOCATION_WITH_COLS) |
4073 | return; |
4074 | |
4075 | ASSERT_TRUE (IS_ADHOC_LOC (loc))do { const char *desc_ = "ASSERT_TRUE (" "(IS_ADHOC_LOC (loc))" ")"; bool actual_ = ((IS_ADHOC_LOC (loc))); if (actual_) ::selftest ::pass (((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 4075, __FUNCTION__))), desc_); else ::selftest::fail (((::selftest ::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 4075, __FUNCTION__))), desc_); } while (0); |
4076 | |
4077 | /* Insert. */ |
4078 | { |
4079 | rich_location richloc (line_table, loc); |
4080 | richloc.add_fixit_insert_before (loc, "test"); |
4081 | /* It should not have been discarded by the validator. */ |
4082 | ASSERT_EQ (1, richloc.get_num_fixit_hints ())do { const char *desc_ = "ASSERT_EQ (" "(1)" ", " "(richloc.get_num_fixit_hints ())" ")"; if (((1)) == ((richloc.get_num_fixit_hints ()))) ::selftest ::pass ((((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 4082, __FUNCTION__)))), desc_); else ::selftest::fail ((((:: selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 4082, __FUNCTION__)))), desc_); } while (0); |
4083 | |
4084 | test_diagnostic_context dc; |
4085 | diagnostic_show_locus (&dc, &richloc, DK_ERROR); |
4086 | ASSERT_STREQ (" \xf0\x9f\x98\x82"do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 4093, __FUNCTION__)), "\" \\xf0\\x9f\\x98\\x82\" \"_foo = \\xcf\\x80\" \"_bar.\\xf0\\x9f\\x98\\x82\" \"_field\\xcf\\x80\" \";\\n\" \" ^~~~~~~~~~~~~~~~ \\n\" \" test\\n\"" , "pp_formatted_text (dc.printer)", (" \xf0\x9f\x98\x82" "_foo = \xcf\x80" "_bar.\xf0\x9f\x98\x82" "_field\xcf\x80" ";\n" " ^~~~~~~~~~~~~~~~ \n" " test\n"), (pp_formatted_text (dc.printer))); } while (0) |
4087 | "_foo = \xcf\x80"do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 4093, __FUNCTION__)), "\" \\xf0\\x9f\\x98\\x82\" \"_foo = \\xcf\\x80\" \"_bar.\\xf0\\x9f\\x98\\x82\" \"_field\\xcf\\x80\" \";\\n\" \" ^~~~~~~~~~~~~~~~ \\n\" \" test\\n\"" , "pp_formatted_text (dc.printer)", (" \xf0\x9f\x98\x82" "_foo = \xcf\x80" "_bar.\xf0\x9f\x98\x82" "_field\xcf\x80" ";\n" " ^~~~~~~~~~~~~~~~ \n" " test\n"), (pp_formatted_text (dc.printer))); } while (0) |
4088 | "_bar.\xf0\x9f\x98\x82"do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 4093, __FUNCTION__)), "\" \\xf0\\x9f\\x98\\x82\" \"_foo = \\xcf\\x80\" \"_bar.\\xf0\\x9f\\x98\\x82\" \"_field\\xcf\\x80\" \";\\n\" \" ^~~~~~~~~~~~~~~~ \\n\" \" test\\n\"" , "pp_formatted_text (dc.printer)", (" \xf0\x9f\x98\x82" "_foo = \xcf\x80" "_bar.\xf0\x9f\x98\x82" "_field\xcf\x80" ";\n" " ^~~~~~~~~~~~~~~~ \n" " test\n"), (pp_formatted_text (dc.printer))); } while (0) |
4089 | "_field\xcf\x80"do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 4093, __FUNCTION__)), "\" \\xf0\\x9f\\x98\\x82\" \"_foo = \\xcf\\x80\" \"_bar.\\xf0\\x9f\\x98\\x82\" \"_field\\xcf\\x80\" \";\\n\" \" ^~~~~~~~~~~~~~~~ \\n\" \" test\\n\"" , "pp_formatted_text (dc.printer)", (" \xf0\x9f\x98\x82" "_foo = \xcf\x80" "_bar.\xf0\x9f\x98\x82" "_field\xcf\x80" ";\n" " ^~~~~~~~~~~~~~~~ \n" " test\n"), (pp_formatted_text (dc.printer))); } while (0) |
4090 | ";\n"do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 4093, __FUNCTION__)), "\" \\xf0\\x9f\\x98\\x82\" \"_foo = \\xcf\\x80\" \"_bar.\\xf0\\x9f\\x98\\x82\" \"_field\\xcf\\x80\" \";\\n\" \" ^~~~~~~~~~~~~~~~ \\n\" \" test\\n\"" , "pp_formatted_text (dc.printer)", (" \xf0\x9f\x98\x82" "_foo = \xcf\x80" "_bar.\xf0\x9f\x98\x82" "_field\xcf\x80" ";\n" " ^~~~~~~~~~~~~~~~ \n" " test\n"), (pp_formatted_text (dc.printer))); } while (0) |
4091 | " ^~~~~~~~~~~~~~~~ \n"do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 4093, __FUNCTION__)), "\" \\xf0\\x9f\\x98\\x82\" \"_foo = \\xcf\\x80\" \"_bar.\\xf0\\x9f\\x98\\x82\" \"_field\\xcf\\x80\" \";\\n\" \" ^~~~~~~~~~~~~~~~ \\n\" \" test\\n\"" , "pp_formatted_text (dc.printer)", (" \xf0\x9f\x98\x82" "_foo = \xcf\x80" "_bar.\xf0\x9f\x98\x82" "_field\xcf\x80" ";\n" " ^~~~~~~~~~~~~~~~ \n" " test\n"), (pp_formatted_text (dc.printer))); } while (0) |
4092 | " test\n",do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 4093, __FUNCTION__)), "\" \\xf0\\x9f\\x98\\x82\" \"_foo = \\xcf\\x80\" \"_bar.\\xf0\\x9f\\x98\\x82\" \"_field\\xcf\\x80\" \";\\n\" \" ^~~~~~~~~~~~~~~~ \\n\" \" test\\n\"" , "pp_formatted_text (dc.printer)", (" \xf0\x9f\x98\x82" "_foo = \xcf\x80" "_bar.\xf0\x9f\x98\x82" "_field\xcf\x80" ";\n" " ^~~~~~~~~~~~~~~~ \n" " test\n"), (pp_formatted_text (dc.printer))); } while (0) |
4093 | pp_formatted_text (dc.printer))do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 4093, __FUNCTION__)), "\" \\xf0\\x9f\\x98\\x82\" \"_foo = \\xcf\\x80\" \"_bar.\\xf0\\x9f\\x98\\x82\" \"_field\\xcf\\x80\" \";\\n\" \" ^~~~~~~~~~~~~~~~ \\n\" \" test\\n\"" , "pp_formatted_text (dc.printer)", (" \xf0\x9f\x98\x82" "_foo = \xcf\x80" "_bar.\xf0\x9f\x98\x82" "_field\xcf\x80" ";\n" " ^~~~~~~~~~~~~~~~ \n" " test\n"), (pp_formatted_text (dc.printer))); } while (0); |
4094 | } |
4095 | |
4096 | /* Remove. */ |
4097 | { |
4098 | rich_location richloc (line_table, loc); |
4099 | source_range range = source_range::from_locations (loc, c52); |
4100 | richloc.add_fixit_remove (range); |
4101 | /* It should not have been discarded by the validator. */ |
4102 | ASSERT_EQ (1, richloc.get_num_fixit_hints ())do { const char *desc_ = "ASSERT_EQ (" "(1)" ", " "(richloc.get_num_fixit_hints ())" ")"; if (((1)) == ((richloc.get_num_fixit_hints ()))) ::selftest ::pass ((((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 4102, __FUNCTION__)))), desc_); else ::selftest::fail ((((:: selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 4102, __FUNCTION__)))), desc_); } while (0); |
4103 | |
4104 | test_diagnostic_context dc; |
4105 | diagnostic_show_locus (&dc, &richloc, DK_ERROR); |
4106 | ASSERT_STREQ (" \xf0\x9f\x98\x82"do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 4113, __FUNCTION__)), "\" \\xf0\\x9f\\x98\\x82\" \"_foo = \\xcf\\x80\" \"_bar.\\xf0\\x9f\\x98\\x82\" \"_field\\xcf\\x80\" \";\\n\" \" ^~~~~~~~~~~~~~~~ \\n\" \" -------------------------------------\\n\"" , "pp_formatted_text (dc.printer)", (" \xf0\x9f\x98\x82" "_foo = \xcf\x80" "_bar.\xf0\x9f\x98\x82" "_field\xcf\x80" ";\n" " ^~~~~~~~~~~~~~~~ \n" " -------------------------------------\n"), (pp_formatted_text (dc.printer))); } while (0) |
4107 | "_foo = \xcf\x80"do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 4113, __FUNCTION__)), "\" \\xf0\\x9f\\x98\\x82\" \"_foo = \\xcf\\x80\" \"_bar.\\xf0\\x9f\\x98\\x82\" \"_field\\xcf\\x80\" \";\\n\" \" ^~~~~~~~~~~~~~~~ \\n\" \" -------------------------------------\\n\"" , "pp_formatted_text (dc.printer)", (" \xf0\x9f\x98\x82" "_foo = \xcf\x80" "_bar.\xf0\x9f\x98\x82" "_field\xcf\x80" ";\n" " ^~~~~~~~~~~~~~~~ \n" " -------------------------------------\n"), (pp_formatted_text (dc.printer))); } while (0) |
4108 | "_bar.\xf0\x9f\x98\x82"do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 4113, __FUNCTION__)), "\" \\xf0\\x9f\\x98\\x82\" \"_foo = \\xcf\\x80\" \"_bar.\\xf0\\x9f\\x98\\x82\" \"_field\\xcf\\x80\" \";\\n\" \" ^~~~~~~~~~~~~~~~ \\n\" \" -------------------------------------\\n\"" , "pp_formatted_text (dc.printer)", (" \xf0\x9f\x98\x82" "_foo = \xcf\x80" "_bar.\xf0\x9f\x98\x82" "_field\xcf\x80" ";\n" " ^~~~~~~~~~~~~~~~ \n" " -------------------------------------\n"), (pp_formatted_text (dc.printer))); } while (0) |
4109 | "_field\xcf\x80"do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 4113, __FUNCTION__)), "\" \\xf0\\x9f\\x98\\x82\" \"_foo = \\xcf\\x80\" \"_bar.\\xf0\\x9f\\x98\\x82\" \"_field\\xcf\\x80\" \";\\n\" \" ^~~~~~~~~~~~~~~~ \\n\" \" -------------------------------------\\n\"" , "pp_formatted_text (dc.printer)", (" \xf0\x9f\x98\x82" "_foo = \xcf\x80" "_bar.\xf0\x9f\x98\x82" "_field\xcf\x80" ";\n" " ^~~~~~~~~~~~~~~~ \n" " -------------------------------------\n"), (pp_formatted_text (dc.printer))); } while (0) |
4110 | ";\n"do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 4113, __FUNCTION__)), "\" \\xf0\\x9f\\x98\\x82\" \"_foo = \\xcf\\x80\" \"_bar.\\xf0\\x9f\\x98\\x82\" \"_field\\xcf\\x80\" \";\\n\" \" ^~~~~~~~~~~~~~~~ \\n\" \" -------------------------------------\\n\"" , "pp_formatted_text (dc.printer)", (" \xf0\x9f\x98\x82" "_foo = \xcf\x80" "_bar.\xf0\x9f\x98\x82" "_field\xcf\x80" ";\n" " ^~~~~~~~~~~~~~~~ \n" " -------------------------------------\n"), (pp_formatted_text (dc.printer))); } while (0) |
4111 | " ^~~~~~~~~~~~~~~~ \n"do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 4113, __FUNCTION__)), "\" \\xf0\\x9f\\x98\\x82\" \"_foo = \\xcf\\x80\" \"_bar.\\xf0\\x9f\\x98\\x82\" \"_field\\xcf\\x80\" \";\\n\" \" ^~~~~~~~~~~~~~~~ \\n\" \" -------------------------------------\\n\"" , "pp_formatted_text (dc.printer)", (" \xf0\x9f\x98\x82" "_foo = \xcf\x80" "_bar.\xf0\x9f\x98\x82" "_field\xcf\x80" ";\n" " ^~~~~~~~~~~~~~~~ \n" " -------------------------------------\n"), (pp_formatted_text (dc.printer))); } while (0) |
4112 | " -------------------------------------\n",do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 4113, __FUNCTION__)), "\" \\xf0\\x9f\\x98\\x82\" \"_foo = \\xcf\\x80\" \"_bar.\\xf0\\x9f\\x98\\x82\" \"_field\\xcf\\x80\" \";\\n\" \" ^~~~~~~~~~~~~~~~ \\n\" \" -------------------------------------\\n\"" , "pp_formatted_text (dc.printer)", (" \xf0\x9f\x98\x82" "_foo = \xcf\x80" "_bar.\xf0\x9f\x98\x82" "_field\xcf\x80" ";\n" " ^~~~~~~~~~~~~~~~ \n" " -------------------------------------\n"), (pp_formatted_text (dc.printer))); } while (0) |
4113 | pp_formatted_text (dc.printer))do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 4113, __FUNCTION__)), "\" \\xf0\\x9f\\x98\\x82\" \"_foo = \\xcf\\x80\" \"_bar.\\xf0\\x9f\\x98\\x82\" \"_field\\xcf\\x80\" \";\\n\" \" ^~~~~~~~~~~~~~~~ \\n\" \" -------------------------------------\\n\"" , "pp_formatted_text (dc.printer)", (" \xf0\x9f\x98\x82" "_foo = \xcf\x80" "_bar.\xf0\x9f\x98\x82" "_field\xcf\x80" ";\n" " ^~~~~~~~~~~~~~~~ \n" " -------------------------------------\n"), (pp_formatted_text (dc.printer))); } while (0); |
4114 | } |
4115 | |
4116 | /* Replace. */ |
4117 | { |
4118 | rich_location richloc (line_table, loc); |
4119 | source_range range = source_range::from_locations (loc, c52); |
4120 | richloc.add_fixit_replace (range, "test"); |
4121 | /* It should not have been discarded by the validator. */ |
4122 | ASSERT_EQ (1, richloc.get_num_fixit_hints ())do { const char *desc_ = "ASSERT_EQ (" "(1)" ", " "(richloc.get_num_fixit_hints ())" ")"; if (((1)) == ((richloc.get_num_fixit_hints ()))) ::selftest ::pass ((((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 4122, __FUNCTION__)))), desc_); else ::selftest::fail ((((:: selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 4122, __FUNCTION__)))), desc_); } while (0); |
4123 | |
4124 | test_diagnostic_context dc; |
4125 | diagnostic_show_locus (&dc, &richloc, DK_ERROR); |
4126 | ASSERT_STREQ (" \xf0\x9f\x98\x82"do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 4133, __FUNCTION__)), "\" \\xf0\\x9f\\x98\\x82\" \"_foo = \\xcf\\x80\" \"_bar.\\xf0\\x9f\\x98\\x82\" \"_field\\xcf\\x80\" \";\\n\" \" ^~~~~~~~~~~~~~~~ \\n\" \" test\\n\"" , "pp_formatted_text (dc.printer)", (" \xf0\x9f\x98\x82" "_foo = \xcf\x80" "_bar.\xf0\x9f\x98\x82" "_field\xcf\x80" ";\n" " ^~~~~~~~~~~~~~~~ \n" " test\n"), (pp_formatted_text (dc.printer))); } while (0) |
4127 | "_foo = \xcf\x80"do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 4133, __FUNCTION__)), "\" \\xf0\\x9f\\x98\\x82\" \"_foo = \\xcf\\x80\" \"_bar.\\xf0\\x9f\\x98\\x82\" \"_field\\xcf\\x80\" \";\\n\" \" ^~~~~~~~~~~~~~~~ \\n\" \" test\\n\"" , "pp_formatted_text (dc.printer)", (" \xf0\x9f\x98\x82" "_foo = \xcf\x80" "_bar.\xf0\x9f\x98\x82" "_field\xcf\x80" ";\n" " ^~~~~~~~~~~~~~~~ \n" " test\n"), (pp_formatted_text (dc.printer))); } while (0) |
4128 | "_bar.\xf0\x9f\x98\x82"do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 4133, __FUNCTION__)), "\" \\xf0\\x9f\\x98\\x82\" \"_foo = \\xcf\\x80\" \"_bar.\\xf0\\x9f\\x98\\x82\" \"_field\\xcf\\x80\" \";\\n\" \" ^~~~~~~~~~~~~~~~ \\n\" \" test\\n\"" , "pp_formatted_text (dc.printer)", (" \xf0\x9f\x98\x82" "_foo = \xcf\x80" "_bar.\xf0\x9f\x98\x82" "_field\xcf\x80" ";\n" " ^~~~~~~~~~~~~~~~ \n" " test\n"), (pp_formatted_text (dc.printer))); } while (0) |
4129 | "_field\xcf\x80"do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 4133, __FUNCTION__)), "\" \\xf0\\x9f\\x98\\x82\" \"_foo = \\xcf\\x80\" \"_bar.\\xf0\\x9f\\x98\\x82\" \"_field\\xcf\\x80\" \";\\n\" \" ^~~~~~~~~~~~~~~~ \\n\" \" test\\n\"" , "pp_formatted_text (dc.printer)", (" \xf0\x9f\x98\x82" "_foo = \xcf\x80" "_bar.\xf0\x9f\x98\x82" "_field\xcf\x80" ";\n" " ^~~~~~~~~~~~~~~~ \n" " test\n"), (pp_formatted_text (dc.printer))); } while (0) |
4130 | ";\n"do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 4133, __FUNCTION__)), "\" \\xf0\\x9f\\x98\\x82\" \"_foo = \\xcf\\x80\" \"_bar.\\xf0\\x9f\\x98\\x82\" \"_field\\xcf\\x80\" \";\\n\" \" ^~~~~~~~~~~~~~~~ \\n\" \" test\\n\"" , "pp_formatted_text (dc.printer)", (" \xf0\x9f\x98\x82" "_foo = \xcf\x80" "_bar.\xf0\x9f\x98\x82" "_field\xcf\x80" ";\n" " ^~~~~~~~~~~~~~~~ \n" " test\n"), (pp_formatted_text (dc.printer))); } while (0) |
4131 | " ^~~~~~~~~~~~~~~~ \n"do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 4133, __FUNCTION__)), "\" \\xf0\\x9f\\x98\\x82\" \"_foo = \\xcf\\x80\" \"_bar.\\xf0\\x9f\\x98\\x82\" \"_field\\xcf\\x80\" \";\\n\" \" ^~~~~~~~~~~~~~~~ \\n\" \" test\\n\"" , "pp_formatted_text (dc.printer)", (" \xf0\x9f\x98\x82" "_foo = \xcf\x80" "_bar.\xf0\x9f\x98\x82" "_field\xcf\x80" ";\n" " ^~~~~~~~~~~~~~~~ \n" " test\n"), (pp_formatted_text (dc.printer))); } while (0) |
4132 | " test\n",do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 4133, __FUNCTION__)), "\" \\xf0\\x9f\\x98\\x82\" \"_foo = \\xcf\\x80\" \"_bar.\\xf0\\x9f\\x98\\x82\" \"_field\\xcf\\x80\" \";\\n\" \" ^~~~~~~~~~~~~~~~ \\n\" \" test\\n\"" , "pp_formatted_text (dc.printer)", (" \xf0\x9f\x98\x82" "_foo = \xcf\x80" "_bar.\xf0\x9f\x98\x82" "_field\xcf\x80" ";\n" " ^~~~~~~~~~~~~~~~ \n" " test\n"), (pp_formatted_text (dc.printer))); } while (0) |
4133 | pp_formatted_text (dc.printer))do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 4133, __FUNCTION__)), "\" \\xf0\\x9f\\x98\\x82\" \"_foo = \\xcf\\x80\" \"_bar.\\xf0\\x9f\\x98\\x82\" \"_field\\xcf\\x80\" \";\\n\" \" ^~~~~~~~~~~~~~~~ \\n\" \" test\\n\"" , "pp_formatted_text (dc.printer)", (" \xf0\x9f\x98\x82" "_foo = \xcf\x80" "_bar.\xf0\x9f\x98\x82" "_field\xcf\x80" ";\n" " ^~~~~~~~~~~~~~~~ \n" " test\n"), (pp_formatted_text (dc.printer))); } while (0); |
4134 | } |
4135 | } |
4136 | |
4137 | /* Test of consolidating insertions at the same location. */ |
4138 | |
4139 | static void |
4140 | test_one_liner_many_fixits_1_utf8 () |
4141 | { |
4142 | test_diagnostic_context dc; |
4143 | location_t equals = linemap_position_for_column (line_table, 10); |
4144 | rich_location richloc (line_table, equals); |
4145 | for (int i = 0; i < 19; i++) |
4146 | richloc.add_fixit_insert_before (i & 1 ? "@" : "\xcf\x80"); |
4147 | ASSERT_EQ (1, richloc.get_num_fixit_hints ())do { const char *desc_ = "ASSERT_EQ (" "(1)" ", " "(richloc.get_num_fixit_hints ())" ")"; if (((1)) == ((richloc.get_num_fixit_hints ()))) ::selftest ::pass ((((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 4147, __FUNCTION__)))), desc_); else ::selftest::fail ((((:: selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 4147, __FUNCTION__)))), desc_); } while (0); |
4148 | diagnostic_show_locus (&dc, &richloc, DK_ERROR); |
4149 | ASSERT_STREQ (" \xf0\x9f\x98\x82"do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 4157, __FUNCTION__)), "\" \\xf0\\x9f\\x98\\x82\" \"_foo = \\xcf\\x80\" \"_bar.\\xf0\\x9f\\x98\\x82\" \"_field\\xcf\\x80\" \";\\n\" \" ^\\n\" \" \\xcf\\x80@\\xcf\\x80@\\xcf\\x80@\\xcf\\x80@\\xcf\\x80@\" \"\\xcf\\x80@\\xcf\\x80@\\xcf\\x80@\\xcf\\x80@\\xcf\\x80\\n\"" , "pp_formatted_text (dc.printer)", (" \xf0\x9f\x98\x82" "_foo = \xcf\x80" "_bar.\xf0\x9f\x98\x82" "_field\xcf\x80" ";\n" " ^\n" " \xcf\x80@\xcf\x80@\xcf\x80@\xcf\x80@\xcf\x80@" "\xcf\x80@\xcf\x80@\xcf\x80@\xcf\x80@\xcf\x80\n" ), (pp_formatted_text (dc.printer))); } while (0) |
4150 | "_foo = \xcf\x80"do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 4157, __FUNCTION__)), "\" \\xf0\\x9f\\x98\\x82\" \"_foo = \\xcf\\x80\" \"_bar.\\xf0\\x9f\\x98\\x82\" \"_field\\xcf\\x80\" \";\\n\" \" ^\\n\" \" \\xcf\\x80@\\xcf\\x80@\\xcf\\x80@\\xcf\\x80@\\xcf\\x80@\" \"\\xcf\\x80@\\xcf\\x80@\\xcf\\x80@\\xcf\\x80@\\xcf\\x80\\n\"" , "pp_formatted_text (dc.printer)", (" \xf0\x9f\x98\x82" "_foo = \xcf\x80" "_bar.\xf0\x9f\x98\x82" "_field\xcf\x80" ";\n" " ^\n" " \xcf\x80@\xcf\x80@\xcf\x80@\xcf\x80@\xcf\x80@" "\xcf\x80@\xcf\x80@\xcf\x80@\xcf\x80@\xcf\x80\n" ), (pp_formatted_text (dc.printer))); } while (0) |
4151 | "_bar.\xf0\x9f\x98\x82"do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 4157, __FUNCTION__)), "\" \\xf0\\x9f\\x98\\x82\" \"_foo = \\xcf\\x80\" \"_bar.\\xf0\\x9f\\x98\\x82\" \"_field\\xcf\\x80\" \";\\n\" \" ^\\n\" \" \\xcf\\x80@\\xcf\\x80@\\xcf\\x80@\\xcf\\x80@\\xcf\\x80@\" \"\\xcf\\x80@\\xcf\\x80@\\xcf\\x80@\\xcf\\x80@\\xcf\\x80\\n\"" , "pp_formatted_text (dc.printer)", (" \xf0\x9f\x98\x82" "_foo = \xcf\x80" "_bar.\xf0\x9f\x98\x82" "_field\xcf\x80" ";\n" " ^\n" " \xcf\x80@\xcf\x80@\xcf\x80@\xcf\x80@\xcf\x80@" "\xcf\x80@\xcf\x80@\xcf\x80@\xcf\x80@\xcf\x80\n" ), (pp_formatted_text (dc.printer))); } while (0) |
4152 | "_field\xcf\x80"do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 4157, __FUNCTION__)), "\" \\xf0\\x9f\\x98\\x82\" \"_foo = \\xcf\\x80\" \"_bar.\\xf0\\x9f\\x98\\x82\" \"_field\\xcf\\x80\" \";\\n\" \" ^\\n\" \" \\xcf\\x80@\\xcf\\x80@\\xcf\\x80@\\xcf\\x80@\\xcf\\x80@\" \"\\xcf\\x80@\\xcf\\x80@\\xcf\\x80@\\xcf\\x80@\\xcf\\x80\\n\"" , "pp_formatted_text (dc.printer)", (" \xf0\x9f\x98\x82" "_foo = \xcf\x80" "_bar.\xf0\x9f\x98\x82" "_field\xcf\x80" ";\n" " ^\n" " \xcf\x80@\xcf\x80@\xcf\x80@\xcf\x80@\xcf\x80@" "\xcf\x80@\xcf\x80@\xcf\x80@\xcf\x80@\xcf\x80\n" ), (pp_formatted_text (dc.printer))); } while (0) |
4153 | ";\n"do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 4157, __FUNCTION__)), "\" \\xf0\\x9f\\x98\\x82\" \"_foo = \\xcf\\x80\" \"_bar.\\xf0\\x9f\\x98\\x82\" \"_field\\xcf\\x80\" \";\\n\" \" ^\\n\" \" \\xcf\\x80@\\xcf\\x80@\\xcf\\x80@\\xcf\\x80@\\xcf\\x80@\" \"\\xcf\\x80@\\xcf\\x80@\\xcf\\x80@\\xcf\\x80@\\xcf\\x80\\n\"" , "pp_formatted_text (dc.printer)", (" \xf0\x9f\x98\x82" "_foo = \xcf\x80" "_bar.\xf0\x9f\x98\x82" "_field\xcf\x80" ";\n" " ^\n" " \xcf\x80@\xcf\x80@\xcf\x80@\xcf\x80@\xcf\x80@" "\xcf\x80@\xcf\x80@\xcf\x80@\xcf\x80@\xcf\x80\n" ), (pp_formatted_text (dc.printer))); } while (0) |
4154 | " ^\n"do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 4157, __FUNCTION__)), "\" \\xf0\\x9f\\x98\\x82\" \"_foo = \\xcf\\x80\" \"_bar.\\xf0\\x9f\\x98\\x82\" \"_field\\xcf\\x80\" \";\\n\" \" ^\\n\" \" \\xcf\\x80@\\xcf\\x80@\\xcf\\x80@\\xcf\\x80@\\xcf\\x80@\" \"\\xcf\\x80@\\xcf\\x80@\\xcf\\x80@\\xcf\\x80@\\xcf\\x80\\n\"" , "pp_formatted_text (dc.printer)", (" \xf0\x9f\x98\x82" "_foo = \xcf\x80" "_bar.\xf0\x9f\x98\x82" "_field\xcf\x80" ";\n" " ^\n" " \xcf\x80@\xcf\x80@\xcf\x80@\xcf\x80@\xcf\x80@" "\xcf\x80@\xcf\x80@\xcf\x80@\xcf\x80@\xcf\x80\n" ), (pp_formatted_text (dc.printer))); } while (0) |
4155 | " \xcf\x80@\xcf\x80@\xcf\x80@\xcf\x80@\xcf\x80@"do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 4157, __FUNCTION__)), "\" \\xf0\\x9f\\x98\\x82\" \"_foo = \\xcf\\x80\" \"_bar.\\xf0\\x9f\\x98\\x82\" \"_field\\xcf\\x80\" \";\\n\" \" ^\\n\" \" \\xcf\\x80@\\xcf\\x80@\\xcf\\x80@\\xcf\\x80@\\xcf\\x80@\" \"\\xcf\\x80@\\xcf\\x80@\\xcf\\x80@\\xcf\\x80@\\xcf\\x80\\n\"" , "pp_formatted_text (dc.printer)", (" \xf0\x9f\x98\x82" "_foo = \xcf\x80" "_bar.\xf0\x9f\x98\x82" "_field\xcf\x80" ";\n" " ^\n" " \xcf\x80@\xcf\x80@\xcf\x80@\xcf\x80@\xcf\x80@" "\xcf\x80@\xcf\x80@\xcf\x80@\xcf\x80@\xcf\x80\n" ), (pp_formatted_text (dc.printer))); } while (0) |
4156 | "\xcf\x80@\xcf\x80@\xcf\x80@\xcf\x80@\xcf\x80\n",do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 4157, __FUNCTION__)), "\" \\xf0\\x9f\\x98\\x82\" \"_foo = \\xcf\\x80\" \"_bar.\\xf0\\x9f\\x98\\x82\" \"_field\\xcf\\x80\" \";\\n\" \" ^\\n\" \" \\xcf\\x80@\\xcf\\x80@\\xcf\\x80@\\xcf\\x80@\\xcf\\x80@\" \"\\xcf\\x80@\\xcf\\x80@\\xcf\\x80@\\xcf\\x80@\\xcf\\x80\\n\"" , "pp_formatted_text (dc.printer)", (" \xf0\x9f\x98\x82" "_foo = \xcf\x80" "_bar.\xf0\x9f\x98\x82" "_field\xcf\x80" ";\n" " ^\n" " \xcf\x80@\xcf\x80@\xcf\x80@\xcf\x80@\xcf\x80@" "\xcf\x80@\xcf\x80@\xcf\x80@\xcf\x80@\xcf\x80\n" ), (pp_formatted_text (dc.printer))); } while (0) |
4157 | pp_formatted_text (dc.printer))do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 4157, __FUNCTION__)), "\" \\xf0\\x9f\\x98\\x82\" \"_foo = \\xcf\\x80\" \"_bar.\\xf0\\x9f\\x98\\x82\" \"_field\\xcf\\x80\" \";\\n\" \" ^\\n\" \" \\xcf\\x80@\\xcf\\x80@\\xcf\\x80@\\xcf\\x80@\\xcf\\x80@\" \"\\xcf\\x80@\\xcf\\x80@\\xcf\\x80@\\xcf\\x80@\\xcf\\x80\\n\"" , "pp_formatted_text (dc.printer)", (" \xf0\x9f\x98\x82" "_foo = \xcf\x80" "_bar.\xf0\x9f\x98\x82" "_field\xcf\x80" ";\n" " ^\n" " \xcf\x80@\xcf\x80@\xcf\x80@\xcf\x80@\xcf\x80@" "\xcf\x80@\xcf\x80@\xcf\x80@\xcf\x80@\xcf\x80\n" ), (pp_formatted_text (dc.printer))); } while (0); |
4158 | } |
4159 | |
4160 | /* Ensure that we can add an arbitrary number of fix-it hints to a |
4161 | rich_location, even if they are not consolidated. */ |
4162 | |
4163 | static void |
4164 | test_one_liner_many_fixits_2_utf8 () |
4165 | { |
4166 | test_diagnostic_context dc; |
4167 | location_t equals = linemap_position_for_column (line_table, 10); |
4168 | rich_location richloc (line_table, equals); |
4169 | const int nlocs = 19; |
4170 | int locs[nlocs] = {1, 5, 7, 9, 11, 14, 16, 18, 23, 25, 27, 29, 32, |
4171 | 34, 36, 38, 40, 42, 44}; |
4172 | for (int i = 0; i != nlocs; ++i) |
4173 | { |
4174 | location_t loc = linemap_position_for_column (line_table, locs[i]); |
4175 | richloc.add_fixit_insert_before (loc, i & 1 ? "@" : "\xcf\x80"); |
4176 | } |
4177 | |
4178 | ASSERT_EQ (nlocs, richloc.get_num_fixit_hints ())do { const char *desc_ = "ASSERT_EQ (" "(nlocs)" ", " "(richloc.get_num_fixit_hints ())" ")"; if (((nlocs)) == ((richloc.get_num_fixit_hints ()))) :: selftest::pass ((((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 4178, __FUNCTION__)))), desc_); else ::selftest::fail ((((:: selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 4178, __FUNCTION__)))), desc_); } while (0); |
4179 | diagnostic_show_locus (&dc, &richloc, DK_ERROR); |
4180 | ASSERT_STREQ (" \xf0\x9f\x98\x82"do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 4188, __FUNCTION__)), "\" \\xf0\\x9f\\x98\\x82\" \"_foo = \\xcf\\x80\" \"_bar.\\xf0\\x9f\\x98\\x82\" \"_field\\xcf\\x80\" \";\\n\" \" ^\\n\" \" \\xcf\\x80 @ \\xcf\\x80 @ \\xcf\\x80 @ \\xcf\\x80 @ \\xcf\\x80 @\" \" \\xcf\\x80 @ \\xcf\\x80 @ \\xcf\\x80 @ \\xcf\\x80 @ \\xcf\\x80\\n\"" , "pp_formatted_text (dc.printer)", (" \xf0\x9f\x98\x82" "_foo = \xcf\x80" "_bar.\xf0\x9f\x98\x82" "_field\xcf\x80" ";\n" " ^\n" " \xcf\x80 @ \xcf\x80 @ \xcf\x80 @ \xcf\x80 @ \xcf\x80 @" " \xcf\x80 @ \xcf\x80 @ \xcf\x80 @ \xcf\x80 @ \xcf\x80\n" ), (pp_formatted_text (dc.printer))); } while (0) |
4181 | "_foo = \xcf\x80"do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 4188, __FUNCTION__)), "\" \\xf0\\x9f\\x98\\x82\" \"_foo = \\xcf\\x80\" \"_bar.\\xf0\\x9f\\x98\\x82\" \"_field\\xcf\\x80\" \";\\n\" \" ^\\n\" \" \\xcf\\x80 @ \\xcf\\x80 @ \\xcf\\x80 @ \\xcf\\x80 @ \\xcf\\x80 @\" \" \\xcf\\x80 @ \\xcf\\x80 @ \\xcf\\x80 @ \\xcf\\x80 @ \\xcf\\x80\\n\"" , "pp_formatted_text (dc.printer)", (" \xf0\x9f\x98\x82" "_foo = \xcf\x80" "_bar.\xf0\x9f\x98\x82" "_field\xcf\x80" ";\n" " ^\n" " \xcf\x80 @ \xcf\x80 @ \xcf\x80 @ \xcf\x80 @ \xcf\x80 @" " \xcf\x80 @ \xcf\x80 @ \xcf\x80 @ \xcf\x80 @ \xcf\x80\n" ), (pp_formatted_text (dc.printer))); } while (0) |
4182 | "_bar.\xf0\x9f\x98\x82"do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 4188, __FUNCTION__)), "\" \\xf0\\x9f\\x98\\x82\" \"_foo = \\xcf\\x80\" \"_bar.\\xf0\\x9f\\x98\\x82\" \"_field\\xcf\\x80\" \";\\n\" \" ^\\n\" \" \\xcf\\x80 @ \\xcf\\x80 @ \\xcf\\x80 @ \\xcf\\x80 @ \\xcf\\x80 @\" \" \\xcf\\x80 @ \\xcf\\x80 @ \\xcf\\x80 @ \\xcf\\x80 @ \\xcf\\x80\\n\"" , "pp_formatted_text (dc.printer)", (" \xf0\x9f\x98\x82" "_foo = \xcf\x80" "_bar.\xf0\x9f\x98\x82" "_field\xcf\x80" ";\n" " ^\n" " \xcf\x80 @ \xcf\x80 @ \xcf\x80 @ \xcf\x80 @ \xcf\x80 @" " \xcf\x80 @ \xcf\x80 @ \xcf\x80 @ \xcf\x80 @ \xcf\x80\n" ), (pp_formatted_text (dc.printer))); } while (0) |
4183 | "_field\xcf\x80"do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 4188, __FUNCTION__)), "\" \\xf0\\x9f\\x98\\x82\" \"_foo = \\xcf\\x80\" \"_bar.\\xf0\\x9f\\x98\\x82\" \"_field\\xcf\\x80\" \";\\n\" \" ^\\n\" \" \\xcf\\x80 @ \\xcf\\x80 @ \\xcf\\x80 @ \\xcf\\x80 @ \\xcf\\x80 @\" \" \\xcf\\x80 @ \\xcf\\x80 @ \\xcf\\x80 @ \\xcf\\x80 @ \\xcf\\x80\\n\"" , "pp_formatted_text (dc.printer)", (" \xf0\x9f\x98\x82" "_foo = \xcf\x80" "_bar.\xf0\x9f\x98\x82" "_field\xcf\x80" ";\n" " ^\n" " \xcf\x80 @ \xcf\x80 @ \xcf\x80 @ \xcf\x80 @ \xcf\x80 @" " \xcf\x80 @ \xcf\x80 @ \xcf\x80 @ \xcf\x80 @ \xcf\x80\n" ), (pp_formatted_text (dc.printer))); } while (0) |
4184 | ";\n"do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 4188, __FUNCTION__)), "\" \\xf0\\x9f\\x98\\x82\" \"_foo = \\xcf\\x80\" \"_bar.\\xf0\\x9f\\x98\\x82\" \"_field\\xcf\\x80\" \";\\n\" \" ^\\n\" \" \\xcf\\x80 @ \\xcf\\x80 @ \\xcf\\x80 @ \\xcf\\x80 @ \\xcf\\x80 @\" \" \\xcf\\x80 @ \\xcf\\x80 @ \\xcf\\x80 @ \\xcf\\x80 @ \\xcf\\x80\\n\"" , "pp_formatted_text (dc.printer)", (" \xf0\x9f\x98\x82" "_foo = \xcf\x80" "_bar.\xf0\x9f\x98\x82" "_field\xcf\x80" ";\n" " ^\n" " \xcf\x80 @ \xcf\x80 @ \xcf\x80 @ \xcf\x80 @ \xcf\x80 @" " \xcf\x80 @ \xcf\x80 @ \xcf\x80 @ \xcf\x80 @ \xcf\x80\n" ), (pp_formatted_text (dc.printer))); } while (0) |
4185 | " ^\n"do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 4188, __FUNCTION__)), "\" \\xf0\\x9f\\x98\\x82\" \"_foo = \\xcf\\x80\" \"_bar.\\xf0\\x9f\\x98\\x82\" \"_field\\xcf\\x80\" \";\\n\" \" ^\\n\" \" \\xcf\\x80 @ \\xcf\\x80 @ \\xcf\\x80 @ \\xcf\\x80 @ \\xcf\\x80 @\" \" \\xcf\\x80 @ \\xcf\\x80 @ \\xcf\\x80 @ \\xcf\\x80 @ \\xcf\\x80\\n\"" , "pp_formatted_text (dc.printer)", (" \xf0\x9f\x98\x82" "_foo = \xcf\x80" "_bar.\xf0\x9f\x98\x82" "_field\xcf\x80" ";\n" " ^\n" " \xcf\x80 @ \xcf\x80 @ \xcf\x80 @ \xcf\x80 @ \xcf\x80 @" " \xcf\x80 @ \xcf\x80 @ \xcf\x80 @ \xcf\x80 @ \xcf\x80\n" ), (pp_formatted_text (dc.printer))); } while (0) |
4186 | " \xcf\x80 @ \xcf\x80 @ \xcf\x80 @ \xcf\x80 @ \xcf\x80 @"do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 4188, __FUNCTION__)), "\" \\xf0\\x9f\\x98\\x82\" \"_foo = \\xcf\\x80\" \"_bar.\\xf0\\x9f\\x98\\x82\" \"_field\\xcf\\x80\" \";\\n\" \" ^\\n\" \" \\xcf\\x80 @ \\xcf\\x80 @ \\xcf\\x80 @ \\xcf\\x80 @ \\xcf\\x80 @\" \" \\xcf\\x80 @ \\xcf\\x80 @ \\xcf\\x80 @ \\xcf\\x80 @ \\xcf\\x80\\n\"" , "pp_formatted_text (dc.printer)", (" \xf0\x9f\x98\x82" "_foo = \xcf\x80" "_bar.\xf0\x9f\x98\x82" "_field\xcf\x80" ";\n" " ^\n" " \xcf\x80 @ \xcf\x80 @ \xcf\x80 @ \xcf\x80 @ \xcf\x80 @" " \xcf\x80 @ \xcf\x80 @ \xcf\x80 @ \xcf\x80 @ \xcf\x80\n" ), (pp_formatted_text (dc.printer))); } while (0) |
4187 | " \xcf\x80 @ \xcf\x80 @ \xcf\x80 @ \xcf\x80 @ \xcf\x80\n",do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 4188, __FUNCTION__)), "\" \\xf0\\x9f\\x98\\x82\" \"_foo = \\xcf\\x80\" \"_bar.\\xf0\\x9f\\x98\\x82\" \"_field\\xcf\\x80\" \";\\n\" \" ^\\n\" \" \\xcf\\x80 @ \\xcf\\x80 @ \\xcf\\x80 @ \\xcf\\x80 @ \\xcf\\x80 @\" \" \\xcf\\x80 @ \\xcf\\x80 @ \\xcf\\x80 @ \\xcf\\x80 @ \\xcf\\x80\\n\"" , "pp_formatted_text (dc.printer)", (" \xf0\x9f\x98\x82" "_foo = \xcf\x80" "_bar.\xf0\x9f\x98\x82" "_field\xcf\x80" ";\n" " ^\n" " \xcf\x80 @ \xcf\x80 @ \xcf\x80 @ \xcf\x80 @ \xcf\x80 @" " \xcf\x80 @ \xcf\x80 @ \xcf\x80 @ \xcf\x80 @ \xcf\x80\n" ), (pp_formatted_text (dc.printer))); } while (0) |
4188 | pp_formatted_text (dc.printer))do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 4188, __FUNCTION__)), "\" \\xf0\\x9f\\x98\\x82\" \"_foo = \\xcf\\x80\" \"_bar.\\xf0\\x9f\\x98\\x82\" \"_field\\xcf\\x80\" \";\\n\" \" ^\\n\" \" \\xcf\\x80 @ \\xcf\\x80 @ \\xcf\\x80 @ \\xcf\\x80 @ \\xcf\\x80 @\" \" \\xcf\\x80 @ \\xcf\\x80 @ \\xcf\\x80 @ \\xcf\\x80 @ \\xcf\\x80\\n\"" , "pp_formatted_text (dc.printer)", (" \xf0\x9f\x98\x82" "_foo = \xcf\x80" "_bar.\xf0\x9f\x98\x82" "_field\xcf\x80" ";\n" " ^\n" " \xcf\x80 @ \xcf\x80 @ \xcf\x80 @ \xcf\x80 @ \xcf\x80 @" " \xcf\x80 @ \xcf\x80 @ \xcf\x80 @ \xcf\x80 @ \xcf\x80\n" ), (pp_formatted_text (dc.printer))); } while (0); |
4189 | } |
4190 | |
4191 | /* Test of labeling the ranges within a rich_location. */ |
4192 | |
4193 | static void |
4194 | test_one_liner_labels_utf8 () |
4195 | { |
4196 | location_t foo |
4197 | = make_location (linemap_position_for_column (line_table, 1), |
4198 | linemap_position_for_column (line_table, 1), |
4199 | linemap_position_for_column (line_table, 8)); |
4200 | location_t bar |
4201 | = make_location (linemap_position_for_column (line_table, 12), |
4202 | linemap_position_for_column (line_table, 12), |
4203 | linemap_position_for_column (line_table, 17)); |
4204 | location_t field |
4205 | = make_location (linemap_position_for_column (line_table, 19), |
4206 | linemap_position_for_column (line_table, 19), |
4207 | linemap_position_for_column (line_table, 30)); |
4208 | |
4209 | /* Example where all the labels fit on one line. */ |
4210 | { |
4211 | /* These three labels contain multibyte characters such that their byte |
4212 | lengths are respectively (12, 10, 18), but their display widths are only |
4213 | (6, 5, 9). All three fit on the line when considering the display |
4214 | widths, but not when considering the byte widths, so verify that we do |
4215 | indeed put them all on one line. */ |
4216 | text_range_label label0 |
4217 | ("\xcf\x80\xcf\x80\xcf\x80\xcf\x80\xcf\x80\xcf\x80"); |
4218 | text_range_label label1 |
4219 | ("\xf0\x9f\x98\x82\xf0\x9f\x98\x82\xcf\x80"); |
4220 | text_range_label label2 |
4221 | ("\xf0\x9f\x98\x82\xcf\x80\xf0\x9f\x98\x82\xf0\x9f\x98\x82\xcf\x80" |
4222 | "\xcf\x80"); |
4223 | gcc_rich_location richloc (foo, &label0); |
4224 | richloc.add_range (bar, SHOW_RANGE_WITHOUT_CARET, &label1); |
4225 | richloc.add_range (field, SHOW_RANGE_WITHOUT_CARET, &label2); |
4226 | |
4227 | { |
4228 | test_diagnostic_context dc; |
4229 | diagnostic_show_locus (&dc, &richloc, DK_ERROR); |
4230 | ASSERT_STREQ (" \xf0\x9f\x98\x82"do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 4241, __FUNCTION__)), "\" \\xf0\\x9f\\x98\\x82\" \"_foo = \\xcf\\x80\" \"_bar.\\xf0\\x9f\\x98\\x82\" \"_field\\xcf\\x80\" \";\\n\" \" ^~~~~~ ~~~~~ ~~~~~~~~~\\n\" \" | | |\\n\" \" \\xcf\\x80\\xcf\\x80\\xcf\\x80\\xcf\\x80\\xcf\\x80\\xcf\\x80\" \" \\xf0\\x9f\\x98\\x82\\xf0\\x9f\\x98\\x82\\xcf\\x80\" \" \\xf0\\x9f\\x98\\x82\\xcf\\x80\\xf0\\x9f\\x98\\x82\" \"\\xf0\\x9f\\x98\\x82\\xcf\\x80\\xcf\\x80\\n\"" , "pp_formatted_text (dc.printer)", (" \xf0\x9f\x98\x82" "_foo = \xcf\x80" "_bar.\xf0\x9f\x98\x82" "_field\xcf\x80" ";\n" " ^~~~~~ ~~~~~ ~~~~~~~~~\n" " | | |\n" " \xcf\x80\xcf\x80\xcf\x80\xcf\x80\xcf\x80\xcf\x80" " \xf0\x9f\x98\x82\xf0\x9f\x98\x82\xcf\x80" " \xf0\x9f\x98\x82\xcf\x80\xf0\x9f\x98\x82" "\xf0\x9f\x98\x82\xcf\x80\xcf\x80\n"), (pp_formatted_text (dc .printer))); } while (0) |
4231 | "_foo = \xcf\x80"do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 4241, __FUNCTION__)), "\" \\xf0\\x9f\\x98\\x82\" \"_foo = \\xcf\\x80\" \"_bar.\\xf0\\x9f\\x98\\x82\" \"_field\\xcf\\x80\" \";\\n\" \" ^~~~~~ ~~~~~ ~~~~~~~~~\\n\" \" | | |\\n\" \" \\xcf\\x80\\xcf\\x80\\xcf\\x80\\xcf\\x80\\xcf\\x80\\xcf\\x80\" \" \\xf0\\x9f\\x98\\x82\\xf0\\x9f\\x98\\x82\\xcf\\x80\" \" \\xf0\\x9f\\x98\\x82\\xcf\\x80\\xf0\\x9f\\x98\\x82\" \"\\xf0\\x9f\\x98\\x82\\xcf\\x80\\xcf\\x80\\n\"" , "pp_formatted_text (dc.printer)", (" \xf0\x9f\x98\x82" "_foo = \xcf\x80" "_bar.\xf0\x9f\x98\x82" "_field\xcf\x80" ";\n" " ^~~~~~ ~~~~~ ~~~~~~~~~\n" " | | |\n" " \xcf\x80\xcf\x80\xcf\x80\xcf\x80\xcf\x80\xcf\x80" " \xf0\x9f\x98\x82\xf0\x9f\x98\x82\xcf\x80" " \xf0\x9f\x98\x82\xcf\x80\xf0\x9f\x98\x82" "\xf0\x9f\x98\x82\xcf\x80\xcf\x80\n"), (pp_formatted_text (dc .printer))); } while (0) |
4232 | "_bar.\xf0\x9f\x98\x82"do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 4241, __FUNCTION__)), "\" \\xf0\\x9f\\x98\\x82\" \"_foo = \\xcf\\x80\" \"_bar.\\xf0\\x9f\\x98\\x82\" \"_field\\xcf\\x80\" \";\\n\" \" ^~~~~~ ~~~~~ ~~~~~~~~~\\n\" \" | | |\\n\" \" \\xcf\\x80\\xcf\\x80\\xcf\\x80\\xcf\\x80\\xcf\\x80\\xcf\\x80\" \" \\xf0\\x9f\\x98\\x82\\xf0\\x9f\\x98\\x82\\xcf\\x80\" \" \\xf0\\x9f\\x98\\x82\\xcf\\x80\\xf0\\x9f\\x98\\x82\" \"\\xf0\\x9f\\x98\\x82\\xcf\\x80\\xcf\\x80\\n\"" , "pp_formatted_text (dc.printer)", (" \xf0\x9f\x98\x82" "_foo = \xcf\x80" "_bar.\xf0\x9f\x98\x82" "_field\xcf\x80" ";\n" " ^~~~~~ ~~~~~ ~~~~~~~~~\n" " | | |\n" " \xcf\x80\xcf\x80\xcf\x80\xcf\x80\xcf\x80\xcf\x80" " \xf0\x9f\x98\x82\xf0\x9f\x98\x82\xcf\x80" " \xf0\x9f\x98\x82\xcf\x80\xf0\x9f\x98\x82" "\xf0\x9f\x98\x82\xcf\x80\xcf\x80\n"), (pp_formatted_text (dc .printer))); } while (0) |
4233 | "_field\xcf\x80"do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 4241, __FUNCTION__)), "\" \\xf0\\x9f\\x98\\x82\" \"_foo = \\xcf\\x80\" \"_bar.\\xf0\\x9f\\x98\\x82\" \"_field\\xcf\\x80\" \";\\n\" \" ^~~~~~ ~~~~~ ~~~~~~~~~\\n\" \" | | |\\n\" \" \\xcf\\x80\\xcf\\x80\\xcf\\x80\\xcf\\x80\\xcf\\x80\\xcf\\x80\" \" \\xf0\\x9f\\x98\\x82\\xf0\\x9f\\x98\\x82\\xcf\\x80\" \" \\xf0\\x9f\\x98\\x82\\xcf\\x80\\xf0\\x9f\\x98\\x82\" \"\\xf0\\x9f\\x98\\x82\\xcf\\x80\\xcf\\x80\\n\"" , "pp_formatted_text (dc.printer)", (" \xf0\x9f\x98\x82" "_foo = \xcf\x80" "_bar.\xf0\x9f\x98\x82" "_field\xcf\x80" ";\n" " ^~~~~~ ~~~~~ ~~~~~~~~~\n" " | | |\n" " \xcf\x80\xcf\x80\xcf\x80\xcf\x80\xcf\x80\xcf\x80" " \xf0\x9f\x98\x82\xf0\x9f\x98\x82\xcf\x80" " \xf0\x9f\x98\x82\xcf\x80\xf0\x9f\x98\x82" "\xf0\x9f\x98\x82\xcf\x80\xcf\x80\n"), (pp_formatted_text (dc .printer))); } while (0) |
4234 | ";\n"do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 4241, __FUNCTION__)), "\" \\xf0\\x9f\\x98\\x82\" \"_foo = \\xcf\\x80\" \"_bar.\\xf0\\x9f\\x98\\x82\" \"_field\\xcf\\x80\" \";\\n\" \" ^~~~~~ ~~~~~ ~~~~~~~~~\\n\" \" | | |\\n\" \" \\xcf\\x80\\xcf\\x80\\xcf\\x80\\xcf\\x80\\xcf\\x80\\xcf\\x80\" \" \\xf0\\x9f\\x98\\x82\\xf0\\x9f\\x98\\x82\\xcf\\x80\" \" \\xf0\\x9f\\x98\\x82\\xcf\\x80\\xf0\\x9f\\x98\\x82\" \"\\xf0\\x9f\\x98\\x82\\xcf\\x80\\xcf\\x80\\n\"" , "pp_formatted_text (dc.printer)", (" \xf0\x9f\x98\x82" "_foo = \xcf\x80" "_bar.\xf0\x9f\x98\x82" "_field\xcf\x80" ";\n" " ^~~~~~ ~~~~~ ~~~~~~~~~\n" " | | |\n" " \xcf\x80\xcf\x80\xcf\x80\xcf\x80\xcf\x80\xcf\x80" " \xf0\x9f\x98\x82\xf0\x9f\x98\x82\xcf\x80" " \xf0\x9f\x98\x82\xcf\x80\xf0\x9f\x98\x82" "\xf0\x9f\x98\x82\xcf\x80\xcf\x80\n"), (pp_formatted_text (dc .printer))); } while (0) |
4235 | " ^~~~~~ ~~~~~ ~~~~~~~~~\n"do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 4241, __FUNCTION__)), "\" \\xf0\\x9f\\x98\\x82\" \"_foo = \\xcf\\x80\" \"_bar.\\xf0\\x9f\\x98\\x82\" \"_field\\xcf\\x80\" \";\\n\" \" ^~~~~~ ~~~~~ ~~~~~~~~~\\n\" \" | | |\\n\" \" \\xcf\\x80\\xcf\\x80\\xcf\\x80\\xcf\\x80\\xcf\\x80\\xcf\\x80\" \" \\xf0\\x9f\\x98\\x82\\xf0\\x9f\\x98\\x82\\xcf\\x80\" \" \\xf0\\x9f\\x98\\x82\\xcf\\x80\\xf0\\x9f\\x98\\x82\" \"\\xf0\\x9f\\x98\\x82\\xcf\\x80\\xcf\\x80\\n\"" , "pp_formatted_text (dc.printer)", (" \xf0\x9f\x98\x82" "_foo = \xcf\x80" "_bar.\xf0\x9f\x98\x82" "_field\xcf\x80" ";\n" " ^~~~~~ ~~~~~ ~~~~~~~~~\n" " | | |\n" " \xcf\x80\xcf\x80\xcf\x80\xcf\x80\xcf\x80\xcf\x80" " \xf0\x9f\x98\x82\xf0\x9f\x98\x82\xcf\x80" " \xf0\x9f\x98\x82\xcf\x80\xf0\x9f\x98\x82" "\xf0\x9f\x98\x82\xcf\x80\xcf\x80\n"), (pp_formatted_text (dc .printer))); } while (0) |
4236 | " | | |\n"do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 4241, __FUNCTION__)), "\" \\xf0\\x9f\\x98\\x82\" \"_foo = \\xcf\\x80\" \"_bar.\\xf0\\x9f\\x98\\x82\" \"_field\\xcf\\x80\" \";\\n\" \" ^~~~~~ ~~~~~ ~~~~~~~~~\\n\" \" | | |\\n\" \" \\xcf\\x80\\xcf\\x80\\xcf\\x80\\xcf\\x80\\xcf\\x80\\xcf\\x80\" \" \\xf0\\x9f\\x98\\x82\\xf0\\x9f\\x98\\x82\\xcf\\x80\" \" \\xf0\\x9f\\x98\\x82\\xcf\\x80\\xf0\\x9f\\x98\\x82\" \"\\xf0\\x9f\\x98\\x82\\xcf\\x80\\xcf\\x80\\n\"" , "pp_formatted_text (dc.printer)", (" \xf0\x9f\x98\x82" "_foo = \xcf\x80" "_bar.\xf0\x9f\x98\x82" "_field\xcf\x80" ";\n" " ^~~~~~ ~~~~~ ~~~~~~~~~\n" " | | |\n" " \xcf\x80\xcf\x80\xcf\x80\xcf\x80\xcf\x80\xcf\x80" " \xf0\x9f\x98\x82\xf0\x9f\x98\x82\xcf\x80" " \xf0\x9f\x98\x82\xcf\x80\xf0\x9f\x98\x82" "\xf0\x9f\x98\x82\xcf\x80\xcf\x80\n"), (pp_formatted_text (dc .printer))); } while (0) |
4237 | " \xcf\x80\xcf\x80\xcf\x80\xcf\x80\xcf\x80\xcf\x80"do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 4241, __FUNCTION__)), "\" \\xf0\\x9f\\x98\\x82\" \"_foo = \\xcf\\x80\" \"_bar.\\xf0\\x9f\\x98\\x82\" \"_field\\xcf\\x80\" \";\\n\" \" ^~~~~~ ~~~~~ ~~~~~~~~~\\n\" \" | | |\\n\" \" \\xcf\\x80\\xcf\\x80\\xcf\\x80\\xcf\\x80\\xcf\\x80\\xcf\\x80\" \" \\xf0\\x9f\\x98\\x82\\xf0\\x9f\\x98\\x82\\xcf\\x80\" \" \\xf0\\x9f\\x98\\x82\\xcf\\x80\\xf0\\x9f\\x98\\x82\" \"\\xf0\\x9f\\x98\\x82\\xcf\\x80\\xcf\\x80\\n\"" , "pp_formatted_text (dc.printer)", (" \xf0\x9f\x98\x82" "_foo = \xcf\x80" "_bar.\xf0\x9f\x98\x82" "_field\xcf\x80" ";\n" " ^~~~~~ ~~~~~ ~~~~~~~~~\n" " | | |\n" " \xcf\x80\xcf\x80\xcf\x80\xcf\x80\xcf\x80\xcf\x80" " \xf0\x9f\x98\x82\xf0\x9f\x98\x82\xcf\x80" " \xf0\x9f\x98\x82\xcf\x80\xf0\x9f\x98\x82" "\xf0\x9f\x98\x82\xcf\x80\xcf\x80\n"), (pp_formatted_text (dc .printer))); } while (0) |
4238 | " \xf0\x9f\x98\x82\xf0\x9f\x98\x82\xcf\x80"do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 4241, __FUNCTION__)), "\" \\xf0\\x9f\\x98\\x82\" \"_foo = \\xcf\\x80\" \"_bar.\\xf0\\x9f\\x98\\x82\" \"_field\\xcf\\x80\" \";\\n\" \" ^~~~~~ ~~~~~ ~~~~~~~~~\\n\" \" | | |\\n\" \" \\xcf\\x80\\xcf\\x80\\xcf\\x80\\xcf\\x80\\xcf\\x80\\xcf\\x80\" \" \\xf0\\x9f\\x98\\x82\\xf0\\x9f\\x98\\x82\\xcf\\x80\" \" \\xf0\\x9f\\x98\\x82\\xcf\\x80\\xf0\\x9f\\x98\\x82\" \"\\xf0\\x9f\\x98\\x82\\xcf\\x80\\xcf\\x80\\n\"" , "pp_formatted_text (dc.printer)", (" \xf0\x9f\x98\x82" "_foo = \xcf\x80" "_bar.\xf0\x9f\x98\x82" "_field\xcf\x80" ";\n" " ^~~~~~ ~~~~~ ~~~~~~~~~\n" " | | |\n" " \xcf\x80\xcf\x80\xcf\x80\xcf\x80\xcf\x80\xcf\x80" " \xf0\x9f\x98\x82\xf0\x9f\x98\x82\xcf\x80" " \xf0\x9f\x98\x82\xcf\x80\xf0\x9f\x98\x82" "\xf0\x9f\x98\x82\xcf\x80\xcf\x80\n"), (pp_formatted_text (dc .printer))); } while (0) |
4239 | " \xf0\x9f\x98\x82\xcf\x80\xf0\x9f\x98\x82"do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 4241, __FUNCTION__)), "\" \\xf0\\x9f\\x98\\x82\" \"_foo = \\xcf\\x80\" \"_bar.\\xf0\\x9f\\x98\\x82\" \"_field\\xcf\\x80\" \";\\n\" \" ^~~~~~ ~~~~~ ~~~~~~~~~\\n\" \" | | |\\n\" \" \\xcf\\x80\\xcf\\x80\\xcf\\x80\\xcf\\x80\\xcf\\x80\\xcf\\x80\" \" \\xf0\\x9f\\x98\\x82\\xf0\\x9f\\x98\\x82\\xcf\\x80\" \" \\xf0\\x9f\\x98\\x82\\xcf\\x80\\xf0\\x9f\\x98\\x82\" \"\\xf0\\x9f\\x98\\x82\\xcf\\x80\\xcf\\x80\\n\"" , "pp_formatted_text (dc.printer)", (" \xf0\x9f\x98\x82" "_foo = \xcf\x80" "_bar.\xf0\x9f\x98\x82" "_field\xcf\x80" ";\n" " ^~~~~~ ~~~~~ ~~~~~~~~~\n" " | | |\n" " \xcf\x80\xcf\x80\xcf\x80\xcf\x80\xcf\x80\xcf\x80" " \xf0\x9f\x98\x82\xf0\x9f\x98\x82\xcf\x80" " \xf0\x9f\x98\x82\xcf\x80\xf0\x9f\x98\x82" "\xf0\x9f\x98\x82\xcf\x80\xcf\x80\n"), (pp_formatted_text (dc .printer))); } while (0) |
4240 | "\xf0\x9f\x98\x82\xcf\x80\xcf\x80\n",do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 4241, __FUNCTION__)), "\" \\xf0\\x9f\\x98\\x82\" \"_foo = \\xcf\\x80\" \"_bar.\\xf0\\x9f\\x98\\x82\" \"_field\\xcf\\x80\" \";\\n\" \" ^~~~~~ ~~~~~ ~~~~~~~~~\\n\" \" | | |\\n\" \" \\xcf\\x80\\xcf\\x80\\xcf\\x80\\xcf\\x80\\xcf\\x80\\xcf\\x80\" \" \\xf0\\x9f\\x98\\x82\\xf0\\x9f\\x98\\x82\\xcf\\x80\" \" \\xf0\\x9f\\x98\\x82\\xcf\\x80\\xf0\\x9f\\x98\\x82\" \"\\xf0\\x9f\\x98\\x82\\xcf\\x80\\xcf\\x80\\n\"" , "pp_formatted_text (dc.printer)", (" \xf0\x9f\x98\x82" "_foo = \xcf\x80" "_bar.\xf0\x9f\x98\x82" "_field\xcf\x80" ";\n" " ^~~~~~ ~~~~~ ~~~~~~~~~\n" " | | |\n" " \xcf\x80\xcf\x80\xcf\x80\xcf\x80\xcf\x80\xcf\x80" " \xf0\x9f\x98\x82\xf0\x9f\x98\x82\xcf\x80" " \xf0\x9f\x98\x82\xcf\x80\xf0\x9f\x98\x82" "\xf0\x9f\x98\x82\xcf\x80\xcf\x80\n"), (pp_formatted_text (dc .printer))); } while (0) |
4241 | pp_formatted_text (dc.printer))do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 4241, __FUNCTION__)), "\" \\xf0\\x9f\\x98\\x82\" \"_foo = \\xcf\\x80\" \"_bar.\\xf0\\x9f\\x98\\x82\" \"_field\\xcf\\x80\" \";\\n\" \" ^~~~~~ ~~~~~ ~~~~~~~~~\\n\" \" | | |\\n\" \" \\xcf\\x80\\xcf\\x80\\xcf\\x80\\xcf\\x80\\xcf\\x80\\xcf\\x80\" \" \\xf0\\x9f\\x98\\x82\\xf0\\x9f\\x98\\x82\\xcf\\x80\" \" \\xf0\\x9f\\x98\\x82\\xcf\\x80\\xf0\\x9f\\x98\\x82\" \"\\xf0\\x9f\\x98\\x82\\xcf\\x80\\xcf\\x80\\n\"" , "pp_formatted_text (dc.printer)", (" \xf0\x9f\x98\x82" "_foo = \xcf\x80" "_bar.\xf0\x9f\x98\x82" "_field\xcf\x80" ";\n" " ^~~~~~ ~~~~~ ~~~~~~~~~\n" " | | |\n" " \xcf\x80\xcf\x80\xcf\x80\xcf\x80\xcf\x80\xcf\x80" " \xf0\x9f\x98\x82\xf0\x9f\x98\x82\xcf\x80" " \xf0\x9f\x98\x82\xcf\x80\xf0\x9f\x98\x82" "\xf0\x9f\x98\x82\xcf\x80\xcf\x80\n"), (pp_formatted_text (dc .printer))); } while (0); |
4242 | } |
4243 | |
4244 | } |
4245 | |
4246 | /* Example where the labels need extra lines. */ |
4247 | { |
4248 | text_range_label label0 ("label 0\xf0\x9f\x98\x82"); |
4249 | text_range_label label1 ("label 1\xcf\x80"); |
4250 | text_range_label label2 ("label 2\xcf\x80"); |
4251 | gcc_rich_location richloc (foo, &label0); |
4252 | richloc.add_range (bar, SHOW_RANGE_WITHOUT_CARET, &label1); |
4253 | richloc.add_range (field, SHOW_RANGE_WITHOUT_CARET, &label2); |
4254 | |
4255 | test_diagnostic_context dc; |
4256 | diagnostic_show_locus (&dc, &richloc, DK_ERROR); |
4257 | |
4258 | ASSERT_STREQ (" \xf0\x9f\x98\x82"do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 4268, __FUNCTION__)), "\" \\xf0\\x9f\\x98\\x82\" \"_foo = \\xcf\\x80\" \"_bar.\\xf0\\x9f\\x98\\x82\" \"_field\\xcf\\x80\" \";\\n\" \" ^~~~~~ ~~~~~ ~~~~~~~~~\\n\" \" | | |\\n\" \" | | label 2\\xcf\\x80\\n\" \" | label 1\\xcf\\x80\\n\" \" label 0\\xf0\\x9f\\x98\\x82\\n\"" , "pp_formatted_text (dc.printer)", (" \xf0\x9f\x98\x82" "_foo = \xcf\x80" "_bar.\xf0\x9f\x98\x82" "_field\xcf\x80" ";\n" " ^~~~~~ ~~~~~ ~~~~~~~~~\n" " | | |\n" " | | label 2\xcf\x80\n" " | label 1\xcf\x80\n" " label 0\xf0\x9f\x98\x82\n"), (pp_formatted_text (dc.printer ))); } while (0) |
4259 | "_foo = \xcf\x80"do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 4268, __FUNCTION__)), "\" \\xf0\\x9f\\x98\\x82\" \"_foo = \\xcf\\x80\" \"_bar.\\xf0\\x9f\\x98\\x82\" \"_field\\xcf\\x80\" \";\\n\" \" ^~~~~~ ~~~~~ ~~~~~~~~~\\n\" \" | | |\\n\" \" | | label 2\\xcf\\x80\\n\" \" | label 1\\xcf\\x80\\n\" \" label 0\\xf0\\x9f\\x98\\x82\\n\"" , "pp_formatted_text (dc.printer)", (" \xf0\x9f\x98\x82" "_foo = \xcf\x80" "_bar.\xf0\x9f\x98\x82" "_field\xcf\x80" ";\n" " ^~~~~~ ~~~~~ ~~~~~~~~~\n" " | | |\n" " | | label 2\xcf\x80\n" " | label 1\xcf\x80\n" " label 0\xf0\x9f\x98\x82\n"), (pp_formatted_text (dc.printer ))); } while (0) |
4260 | "_bar.\xf0\x9f\x98\x82"do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 4268, __FUNCTION__)), "\" \\xf0\\x9f\\x98\\x82\" \"_foo = \\xcf\\x80\" \"_bar.\\xf0\\x9f\\x98\\x82\" \"_field\\xcf\\x80\" \";\\n\" \" ^~~~~~ ~~~~~ ~~~~~~~~~\\n\" \" | | |\\n\" \" | | label 2\\xcf\\x80\\n\" \" | label 1\\xcf\\x80\\n\" \" label 0\\xf0\\x9f\\x98\\x82\\n\"" , "pp_formatted_text (dc.printer)", (" \xf0\x9f\x98\x82" "_foo = \xcf\x80" "_bar.\xf0\x9f\x98\x82" "_field\xcf\x80" ";\n" " ^~~~~~ ~~~~~ ~~~~~~~~~\n" " | | |\n" " | | label 2\xcf\x80\n" " | label 1\xcf\x80\n" " label 0\xf0\x9f\x98\x82\n"), (pp_formatted_text (dc.printer ))); } while (0) |
4261 | "_field\xcf\x80"do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 4268, __FUNCTION__)), "\" \\xf0\\x9f\\x98\\x82\" \"_foo = \\xcf\\x80\" \"_bar.\\xf0\\x9f\\x98\\x82\" \"_field\\xcf\\x80\" \";\\n\" \" ^~~~~~ ~~~~~ ~~~~~~~~~\\n\" \" | | |\\n\" \" | | label 2\\xcf\\x80\\n\" \" | label 1\\xcf\\x80\\n\" \" label 0\\xf0\\x9f\\x98\\x82\\n\"" , "pp_formatted_text (dc.printer)", (" \xf0\x9f\x98\x82" "_foo = \xcf\x80" "_bar.\xf0\x9f\x98\x82" "_field\xcf\x80" ";\n" " ^~~~~~ ~~~~~ ~~~~~~~~~\n" " | | |\n" " | | label 2\xcf\x80\n" " | label 1\xcf\x80\n" " label 0\xf0\x9f\x98\x82\n"), (pp_formatted_text (dc.printer ))); } while (0) |
4262 | ";\n"do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 4268, __FUNCTION__)), "\" \\xf0\\x9f\\x98\\x82\" \"_foo = \\xcf\\x80\" \"_bar.\\xf0\\x9f\\x98\\x82\" \"_field\\xcf\\x80\" \";\\n\" \" ^~~~~~ ~~~~~ ~~~~~~~~~\\n\" \" | | |\\n\" \" | | label 2\\xcf\\x80\\n\" \" | label 1\\xcf\\x80\\n\" \" label 0\\xf0\\x9f\\x98\\x82\\n\"" , "pp_formatted_text (dc.printer)", (" \xf0\x9f\x98\x82" "_foo = \xcf\x80" "_bar.\xf0\x9f\x98\x82" "_field\xcf\x80" ";\n" " ^~~~~~ ~~~~~ ~~~~~~~~~\n" " | | |\n" " | | label 2\xcf\x80\n" " | label 1\xcf\x80\n" " label 0\xf0\x9f\x98\x82\n"), (pp_formatted_text (dc.printer ))); } while (0) |
4263 | " ^~~~~~ ~~~~~ ~~~~~~~~~\n"do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 4268, __FUNCTION__)), "\" \\xf0\\x9f\\x98\\x82\" \"_foo = \\xcf\\x80\" \"_bar.\\xf0\\x9f\\x98\\x82\" \"_field\\xcf\\x80\" \";\\n\" \" ^~~~~~ ~~~~~ ~~~~~~~~~\\n\" \" | | |\\n\" \" | | label 2\\xcf\\x80\\n\" \" | label 1\\xcf\\x80\\n\" \" label 0\\xf0\\x9f\\x98\\x82\\n\"" , "pp_formatted_text (dc.printer)", (" \xf0\x9f\x98\x82" "_foo = \xcf\x80" "_bar.\xf0\x9f\x98\x82" "_field\xcf\x80" ";\n" " ^~~~~~ ~~~~~ ~~~~~~~~~\n" " | | |\n" " | | label 2\xcf\x80\n" " | label 1\xcf\x80\n" " label 0\xf0\x9f\x98\x82\n"), (pp_formatted_text (dc.printer ))); } while (0) |
4264 | " | | |\n"do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 4268, __FUNCTION__)), "\" \\xf0\\x9f\\x98\\x82\" \"_foo = \\xcf\\x80\" \"_bar.\\xf0\\x9f\\x98\\x82\" \"_field\\xcf\\x80\" \";\\n\" \" ^~~~~~ ~~~~~ ~~~~~~~~~\\n\" \" | | |\\n\" \" | | label 2\\xcf\\x80\\n\" \" | label 1\\xcf\\x80\\n\" \" label 0\\xf0\\x9f\\x98\\x82\\n\"" , "pp_formatted_text (dc.printer)", (" \xf0\x9f\x98\x82" "_foo = \xcf\x80" "_bar.\xf0\x9f\x98\x82" "_field\xcf\x80" ";\n" " ^~~~~~ ~~~~~ ~~~~~~~~~\n" " | | |\n" " | | label 2\xcf\x80\n" " | label 1\xcf\x80\n" " label 0\xf0\x9f\x98\x82\n"), (pp_formatted_text (dc.printer ))); } while (0) |
4265 | " | | label 2\xcf\x80\n"do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 4268, __FUNCTION__)), "\" \\xf0\\x9f\\x98\\x82\" \"_foo = \\xcf\\x80\" \"_bar.\\xf0\\x9f\\x98\\x82\" \"_field\\xcf\\x80\" \";\\n\" \" ^~~~~~ ~~~~~ ~~~~~~~~~\\n\" \" | | |\\n\" \" | | label 2\\xcf\\x80\\n\" \" | label 1\\xcf\\x80\\n\" \" label 0\\xf0\\x9f\\x98\\x82\\n\"" , "pp_formatted_text (dc.printer)", (" \xf0\x9f\x98\x82" "_foo = \xcf\x80" "_bar.\xf0\x9f\x98\x82" "_field\xcf\x80" ";\n" " ^~~~~~ ~~~~~ ~~~~~~~~~\n" " | | |\n" " | | label 2\xcf\x80\n" " | label 1\xcf\x80\n" " label 0\xf0\x9f\x98\x82\n"), (pp_formatted_text (dc.printer ))); } while (0) |
4266 | " | label 1\xcf\x80\n"do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 4268, __FUNCTION__)), "\" \\xf0\\x9f\\x98\\x82\" \"_foo = \\xcf\\x80\" \"_bar.\\xf0\\x9f\\x98\\x82\" \"_field\\xcf\\x80\" \";\\n\" \" ^~~~~~ ~~~~~ ~~~~~~~~~\\n\" \" | | |\\n\" \" | | label 2\\xcf\\x80\\n\" \" | label 1\\xcf\\x80\\n\" \" label 0\\xf0\\x9f\\x98\\x82\\n\"" , "pp_formatted_text (dc.printer)", (" \xf0\x9f\x98\x82" "_foo = \xcf\x80" "_bar.\xf0\x9f\x98\x82" "_field\xcf\x80" ";\n" " ^~~~~~ ~~~~~ ~~~~~~~~~\n" " | | |\n" " | | label 2\xcf\x80\n" " | label 1\xcf\x80\n" " label 0\xf0\x9f\x98\x82\n"), (pp_formatted_text (dc.printer ))); } while (0) |
4267 | " label 0\xf0\x9f\x98\x82\n",do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 4268, __FUNCTION__)), "\" \\xf0\\x9f\\x98\\x82\" \"_foo = \\xcf\\x80\" \"_bar.\\xf0\\x9f\\x98\\x82\" \"_field\\xcf\\x80\" \";\\n\" \" ^~~~~~ ~~~~~ ~~~~~~~~~\\n\" \" | | |\\n\" \" | | label 2\\xcf\\x80\\n\" \" | label 1\\xcf\\x80\\n\" \" label 0\\xf0\\x9f\\x98\\x82\\n\"" , "pp_formatted_text (dc.printer)", (" \xf0\x9f\x98\x82" "_foo = \xcf\x80" "_bar.\xf0\x9f\x98\x82" "_field\xcf\x80" ";\n" " ^~~~~~ ~~~~~ ~~~~~~~~~\n" " | | |\n" " | | label 2\xcf\x80\n" " | label 1\xcf\x80\n" " label 0\xf0\x9f\x98\x82\n"), (pp_formatted_text (dc.printer ))); } while (0) |
4268 | pp_formatted_text (dc.printer))do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 4268, __FUNCTION__)), "\" \\xf0\\x9f\\x98\\x82\" \"_foo = \\xcf\\x80\" \"_bar.\\xf0\\x9f\\x98\\x82\" \"_field\\xcf\\x80\" \";\\n\" \" ^~~~~~ ~~~~~ ~~~~~~~~~\\n\" \" | | |\\n\" \" | | label 2\\xcf\\x80\\n\" \" | label 1\\xcf\\x80\\n\" \" label 0\\xf0\\x9f\\x98\\x82\\n\"" , "pp_formatted_text (dc.printer)", (" \xf0\x9f\x98\x82" "_foo = \xcf\x80" "_bar.\xf0\x9f\x98\x82" "_field\xcf\x80" ";\n" " ^~~~~~ ~~~~~ ~~~~~~~~~\n" " | | |\n" " | | label 2\xcf\x80\n" " | label 1\xcf\x80\n" " label 0\xf0\x9f\x98\x82\n"), (pp_formatted_text (dc.printer ))); } while (0); |
4269 | } |
4270 | |
4271 | /* Example of boundary conditions: label 0 and 1 have just enough clearance, |
4272 | but label 1 just touches label 2. */ |
4273 | { |
4274 | text_range_label label0 ("aaaaa\xf0\x9f\x98\x82\xcf\x80"); |
4275 | text_range_label label1 ("bb\xf0\x9f\x98\x82\xf0\x9f\x98\x82"); |
4276 | text_range_label label2 ("c"); |
4277 | gcc_rich_location richloc (foo, &label0); |
4278 | richloc.add_range (bar, SHOW_RANGE_WITHOUT_CARET, &label1); |
4279 | richloc.add_range (field, SHOW_RANGE_WITHOUT_CARET, &label2); |
4280 | |
4281 | test_diagnostic_context dc; |
4282 | diagnostic_show_locus (&dc, &richloc, DK_ERROR); |
4283 | ASSERT_STREQ (" \xf0\x9f\x98\x82"do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 4293, __FUNCTION__)), "\" \\xf0\\x9f\\x98\\x82\" \"_foo = \\xcf\\x80\" \"_bar.\\xf0\\x9f\\x98\\x82\" \"_field\\xcf\\x80\" \";\\n\" \" ^~~~~~ ~~~~~ ~~~~~~~~~\\n\" \" | | |\\n\" \" | | c\\n\" \" aaaaa\\xf0\\x9f\\x98\\x82\\xcf\\x80\" \" bb\\xf0\\x9f\\x98\\x82\\xf0\\x9f\\x98\\x82\\n\"" , "pp_formatted_text (dc.printer)", (" \xf0\x9f\x98\x82" "_foo = \xcf\x80" "_bar.\xf0\x9f\x98\x82" "_field\xcf\x80" ";\n" " ^~~~~~ ~~~~~ ~~~~~~~~~\n" " | | |\n" " | | c\n" " aaaaa\xf0\x9f\x98\x82\xcf\x80" " bb\xf0\x9f\x98\x82\xf0\x9f\x98\x82\n"), (pp_formatted_text (dc.printer))); } while (0) |
4284 | "_foo = \xcf\x80"do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 4293, __FUNCTION__)), "\" \\xf0\\x9f\\x98\\x82\" \"_foo = \\xcf\\x80\" \"_bar.\\xf0\\x9f\\x98\\x82\" \"_field\\xcf\\x80\" \";\\n\" \" ^~~~~~ ~~~~~ ~~~~~~~~~\\n\" \" | | |\\n\" \" | | c\\n\" \" aaaaa\\xf0\\x9f\\x98\\x82\\xcf\\x80\" \" bb\\xf0\\x9f\\x98\\x82\\xf0\\x9f\\x98\\x82\\n\"" , "pp_formatted_text (dc.printer)", (" \xf0\x9f\x98\x82" "_foo = \xcf\x80" "_bar.\xf0\x9f\x98\x82" "_field\xcf\x80" ";\n" " ^~~~~~ ~~~~~ ~~~~~~~~~\n" " | | |\n" " | | c\n" " aaaaa\xf0\x9f\x98\x82\xcf\x80" " bb\xf0\x9f\x98\x82\xf0\x9f\x98\x82\n"), (pp_formatted_text (dc.printer))); } while (0) |
4285 | "_bar.\xf0\x9f\x98\x82"do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 4293, __FUNCTION__)), "\" \\xf0\\x9f\\x98\\x82\" \"_foo = \\xcf\\x80\" \"_bar.\\xf0\\x9f\\x98\\x82\" \"_field\\xcf\\x80\" \";\\n\" \" ^~~~~~ ~~~~~ ~~~~~~~~~\\n\" \" | | |\\n\" \" | | c\\n\" \" aaaaa\\xf0\\x9f\\x98\\x82\\xcf\\x80\" \" bb\\xf0\\x9f\\x98\\x82\\xf0\\x9f\\x98\\x82\\n\"" , "pp_formatted_text (dc.printer)", (" \xf0\x9f\x98\x82" "_foo = \xcf\x80" "_bar.\xf0\x9f\x98\x82" "_field\xcf\x80" ";\n" " ^~~~~~ ~~~~~ ~~~~~~~~~\n" " | | |\n" " | | c\n" " aaaaa\xf0\x9f\x98\x82\xcf\x80" " bb\xf0\x9f\x98\x82\xf0\x9f\x98\x82\n"), (pp_formatted_text (dc.printer))); } while (0) |
4286 | "_field\xcf\x80"do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 4293, __FUNCTION__)), "\" \\xf0\\x9f\\x98\\x82\" \"_foo = \\xcf\\x80\" \"_bar.\\xf0\\x9f\\x98\\x82\" \"_field\\xcf\\x80\" \";\\n\" \" ^~~~~~ ~~~~~ ~~~~~~~~~\\n\" \" | | |\\n\" \" | | c\\n\" \" aaaaa\\xf0\\x9f\\x98\\x82\\xcf\\x80\" \" bb\\xf0\\x9f\\x98\\x82\\xf0\\x9f\\x98\\x82\\n\"" , "pp_formatted_text (dc.printer)", (" \xf0\x9f\x98\x82" "_foo = \xcf\x80" "_bar.\xf0\x9f\x98\x82" "_field\xcf\x80" ";\n" " ^~~~~~ ~~~~~ ~~~~~~~~~\n" " | | |\n" " | | c\n" " aaaaa\xf0\x9f\x98\x82\xcf\x80" " bb\xf0\x9f\x98\x82\xf0\x9f\x98\x82\n"), (pp_formatted_text (dc.printer))); } while (0) |
4287 | ";\n"do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 4293, __FUNCTION__)), "\" \\xf0\\x9f\\x98\\x82\" \"_foo = \\xcf\\x80\" \"_bar.\\xf0\\x9f\\x98\\x82\" \"_field\\xcf\\x80\" \";\\n\" \" ^~~~~~ ~~~~~ ~~~~~~~~~\\n\" \" | | |\\n\" \" | | c\\n\" \" aaaaa\\xf0\\x9f\\x98\\x82\\xcf\\x80\" \" bb\\xf0\\x9f\\x98\\x82\\xf0\\x9f\\x98\\x82\\n\"" , "pp_formatted_text (dc.printer)", (" \xf0\x9f\x98\x82" "_foo = \xcf\x80" "_bar.\xf0\x9f\x98\x82" "_field\xcf\x80" ";\n" " ^~~~~~ ~~~~~ ~~~~~~~~~\n" " | | |\n" " | | c\n" " aaaaa\xf0\x9f\x98\x82\xcf\x80" " bb\xf0\x9f\x98\x82\xf0\x9f\x98\x82\n"), (pp_formatted_text (dc.printer))); } while (0) |
4288 | " ^~~~~~ ~~~~~ ~~~~~~~~~\n"do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 4293, __FUNCTION__)), "\" \\xf0\\x9f\\x98\\x82\" \"_foo = \\xcf\\x80\" \"_bar.\\xf0\\x9f\\x98\\x82\" \"_field\\xcf\\x80\" \";\\n\" \" ^~~~~~ ~~~~~ ~~~~~~~~~\\n\" \" | | |\\n\" \" | | c\\n\" \" aaaaa\\xf0\\x9f\\x98\\x82\\xcf\\x80\" \" bb\\xf0\\x9f\\x98\\x82\\xf0\\x9f\\x98\\x82\\n\"" , "pp_formatted_text (dc.printer)", (" \xf0\x9f\x98\x82" "_foo = \xcf\x80" "_bar.\xf0\x9f\x98\x82" "_field\xcf\x80" ";\n" " ^~~~~~ ~~~~~ ~~~~~~~~~\n" " | | |\n" " | | c\n" " aaaaa\xf0\x9f\x98\x82\xcf\x80" " bb\xf0\x9f\x98\x82\xf0\x9f\x98\x82\n"), (pp_formatted_text (dc.printer))); } while (0) |
4289 | " | | |\n"do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 4293, __FUNCTION__)), "\" \\xf0\\x9f\\x98\\x82\" \"_foo = \\xcf\\x80\" \"_bar.\\xf0\\x9f\\x98\\x82\" \"_field\\xcf\\x80\" \";\\n\" \" ^~~~~~ ~~~~~ ~~~~~~~~~\\n\" \" | | |\\n\" \" | | c\\n\" \" aaaaa\\xf0\\x9f\\x98\\x82\\xcf\\x80\" \" bb\\xf0\\x9f\\x98\\x82\\xf0\\x9f\\x98\\x82\\n\"" , "pp_formatted_text (dc.printer)", (" \xf0\x9f\x98\x82" "_foo = \xcf\x80" "_bar.\xf0\x9f\x98\x82" "_field\xcf\x80" ";\n" " ^~~~~~ ~~~~~ ~~~~~~~~~\n" " | | |\n" " | | c\n" " aaaaa\xf0\x9f\x98\x82\xcf\x80" " bb\xf0\x9f\x98\x82\xf0\x9f\x98\x82\n"), (pp_formatted_text (dc.printer))); } while (0) |
4290 | " | | c\n"do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 4293, __FUNCTION__)), "\" \\xf0\\x9f\\x98\\x82\" \"_foo = \\xcf\\x80\" \"_bar.\\xf0\\x9f\\x98\\x82\" \"_field\\xcf\\x80\" \";\\n\" \" ^~~~~~ ~~~~~ ~~~~~~~~~\\n\" \" | | |\\n\" \" | | c\\n\" \" aaaaa\\xf0\\x9f\\x98\\x82\\xcf\\x80\" \" bb\\xf0\\x9f\\x98\\x82\\xf0\\x9f\\x98\\x82\\n\"" , "pp_formatted_text (dc.printer)", (" \xf0\x9f\x98\x82" "_foo = \xcf\x80" "_bar.\xf0\x9f\x98\x82" "_field\xcf\x80" ";\n" " ^~~~~~ ~~~~~ ~~~~~~~~~\n" " | | |\n" " | | c\n" " aaaaa\xf0\x9f\x98\x82\xcf\x80" " bb\xf0\x9f\x98\x82\xf0\x9f\x98\x82\n"), (pp_formatted_text (dc.printer))); } while (0) |
4291 | " aaaaa\xf0\x9f\x98\x82\xcf\x80"do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 4293, __FUNCTION__)), "\" \\xf0\\x9f\\x98\\x82\" \"_foo = \\xcf\\x80\" \"_bar.\\xf0\\x9f\\x98\\x82\" \"_field\\xcf\\x80\" \";\\n\" \" ^~~~~~ ~~~~~ ~~~~~~~~~\\n\" \" | | |\\n\" \" | | c\\n\" \" aaaaa\\xf0\\x9f\\x98\\x82\\xcf\\x80\" \" bb\\xf0\\x9f\\x98\\x82\\xf0\\x9f\\x98\\x82\\n\"" , "pp_formatted_text (dc.printer)", (" \xf0\x9f\x98\x82" "_foo = \xcf\x80" "_bar.\xf0\x9f\x98\x82" "_field\xcf\x80" ";\n" " ^~~~~~ ~~~~~ ~~~~~~~~~\n" " | | |\n" " | | c\n" " aaaaa\xf0\x9f\x98\x82\xcf\x80" " bb\xf0\x9f\x98\x82\xf0\x9f\x98\x82\n"), (pp_formatted_text (dc.printer))); } while (0) |
4292 | " bb\xf0\x9f\x98\x82\xf0\x9f\x98\x82\n",do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 4293, __FUNCTION__)), "\" \\xf0\\x9f\\x98\\x82\" \"_foo = \\xcf\\x80\" \"_bar.\\xf0\\x9f\\x98\\x82\" \"_field\\xcf\\x80\" \";\\n\" \" ^~~~~~ ~~~~~ ~~~~~~~~~\\n\" \" | | |\\n\" \" | | c\\n\" \" aaaaa\\xf0\\x9f\\x98\\x82\\xcf\\x80\" \" bb\\xf0\\x9f\\x98\\x82\\xf0\\x9f\\x98\\x82\\n\"" , "pp_formatted_text (dc.printer)", (" \xf0\x9f\x98\x82" "_foo = \xcf\x80" "_bar.\xf0\x9f\x98\x82" "_field\xcf\x80" ";\n" " ^~~~~~ ~~~~~ ~~~~~~~~~\n" " | | |\n" " | | c\n" " aaaaa\xf0\x9f\x98\x82\xcf\x80" " bb\xf0\x9f\x98\x82\xf0\x9f\x98\x82\n"), (pp_formatted_text (dc.printer))); } while (0) |
4293 | pp_formatted_text (dc.printer))do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 4293, __FUNCTION__)), "\" \\xf0\\x9f\\x98\\x82\" \"_foo = \\xcf\\x80\" \"_bar.\\xf0\\x9f\\x98\\x82\" \"_field\\xcf\\x80\" \";\\n\" \" ^~~~~~ ~~~~~ ~~~~~~~~~\\n\" \" | | |\\n\" \" | | c\\n\" \" aaaaa\\xf0\\x9f\\x98\\x82\\xcf\\x80\" \" bb\\xf0\\x9f\\x98\\x82\\xf0\\x9f\\x98\\x82\\n\"" , "pp_formatted_text (dc.printer)", (" \xf0\x9f\x98\x82" "_foo = \xcf\x80" "_bar.\xf0\x9f\x98\x82" "_field\xcf\x80" ";\n" " ^~~~~~ ~~~~~ ~~~~~~~~~\n" " | | |\n" " | | c\n" " aaaaa\xf0\x9f\x98\x82\xcf\x80" " bb\xf0\x9f\x98\x82\xf0\x9f\x98\x82\n"), (pp_formatted_text (dc.printer))); } while (0); |
4294 | } |
4295 | |
4296 | /* Example of escaping the source lines. */ |
4297 | { |
4298 | text_range_label label0 ("label 0\xf0\x9f\x98\x82"); |
4299 | text_range_label label1 ("label 1\xcf\x80"); |
4300 | text_range_label label2 ("label 2\xcf\x80"); |
4301 | gcc_rich_location richloc (foo, &label0); |
4302 | richloc.add_range (bar, SHOW_RANGE_WITHOUT_CARET, &label1); |
4303 | richloc.add_range (field, SHOW_RANGE_WITHOUT_CARET, &label2); |
4304 | richloc.set_escape_on_output (true); |
4305 | |
4306 | { |
4307 | test_diagnostic_context dc; |
4308 | dc.escape_format = DIAGNOSTICS_ESCAPE_FORMAT_UNICODE; |
4309 | diagnostic_show_locus (&dc, &richloc, DK_ERROR); |
4310 | ASSERT_STREQ (" <U+1F602>_foo = <U+03C0>_bar.<U+1F602>_field<U+03C0>;\n"do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 4316, __FUNCTION__)), "\" <U+1F602>_foo = <U+03C0>_bar.<U+1F602>_field<U+03C0>;\\n\" \" ^~~~~~~~~~~~~ ~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~\\n\" \" | | |\\n\" \" | | label 2\\xcf\\x80\\n\" \" | label 1\\xcf\\x80\\n\" \" label 0\\xf0\\x9f\\x98\\x82\\n\"" , "pp_formatted_text (dc.printer)", (" <U+1F602>_foo = <U+03C0>_bar.<U+1F602>_field<U+03C0>;\n" " ^~~~~~~~~~~~~ ~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~\n" " | | |\n" " | | label 2\xcf\x80\n" " | label 1\xcf\x80\n" " label 0\xf0\x9f\x98\x82\n"), (pp_formatted_text (dc.printer ))); } while (0) |
4311 | " ^~~~~~~~~~~~~ ~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~\n"do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 4316, __FUNCTION__)), "\" <U+1F602>_foo = <U+03C0>_bar.<U+1F602>_field<U+03C0>;\\n\" \" ^~~~~~~~~~~~~ ~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~\\n\" \" | | |\\n\" \" | | label 2\\xcf\\x80\\n\" \" | label 1\\xcf\\x80\\n\" \" label 0\\xf0\\x9f\\x98\\x82\\n\"" , "pp_formatted_text (dc.printer)", (" <U+1F602>_foo = <U+03C0>_bar.<U+1F602>_field<U+03C0>;\n" " ^~~~~~~~~~~~~ ~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~\n" " | | |\n" " | | label 2\xcf\x80\n" " | label 1\xcf\x80\n" " label 0\xf0\x9f\x98\x82\n"), (pp_formatted_text (dc.printer ))); } while (0) |
4312 | " | | |\n"do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 4316, __FUNCTION__)), "\" <U+1F602>_foo = <U+03C0>_bar.<U+1F602>_field<U+03C0>;\\n\" \" ^~~~~~~~~~~~~ ~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~\\n\" \" | | |\\n\" \" | | label 2\\xcf\\x80\\n\" \" | label 1\\xcf\\x80\\n\" \" label 0\\xf0\\x9f\\x98\\x82\\n\"" , "pp_formatted_text (dc.printer)", (" <U+1F602>_foo = <U+03C0>_bar.<U+1F602>_field<U+03C0>;\n" " ^~~~~~~~~~~~~ ~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~\n" " | | |\n" " | | label 2\xcf\x80\n" " | label 1\xcf\x80\n" " label 0\xf0\x9f\x98\x82\n"), (pp_formatted_text (dc.printer ))); } while (0) |
4313 | " | | label 2\xcf\x80\n"do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 4316, __FUNCTION__)), "\" <U+1F602>_foo = <U+03C0>_bar.<U+1F602>_field<U+03C0>;\\n\" \" ^~~~~~~~~~~~~ ~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~\\n\" \" | | |\\n\" \" | | label 2\\xcf\\x80\\n\" \" | label 1\\xcf\\x80\\n\" \" label 0\\xf0\\x9f\\x98\\x82\\n\"" , "pp_formatted_text (dc.printer)", (" <U+1F602>_foo = <U+03C0>_bar.<U+1F602>_field<U+03C0>;\n" " ^~~~~~~~~~~~~ ~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~\n" " | | |\n" " | | label 2\xcf\x80\n" " | label 1\xcf\x80\n" " label 0\xf0\x9f\x98\x82\n"), (pp_formatted_text (dc.printer ))); } while (0) |
4314 | " | label 1\xcf\x80\n"do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 4316, __FUNCTION__)), "\" <U+1F602>_foo = <U+03C0>_bar.<U+1F602>_field<U+03C0>;\\n\" \" ^~~~~~~~~~~~~ ~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~\\n\" \" | | |\\n\" \" | | label 2\\xcf\\x80\\n\" \" | label 1\\xcf\\x80\\n\" \" label 0\\xf0\\x9f\\x98\\x82\\n\"" , "pp_formatted_text (dc.printer)", (" <U+1F602>_foo = <U+03C0>_bar.<U+1F602>_field<U+03C0>;\n" " ^~~~~~~~~~~~~ ~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~\n" " | | |\n" " | | label 2\xcf\x80\n" " | label 1\xcf\x80\n" " label 0\xf0\x9f\x98\x82\n"), (pp_formatted_text (dc.printer ))); } while (0) |
4315 | " label 0\xf0\x9f\x98\x82\n",do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 4316, __FUNCTION__)), "\" <U+1F602>_foo = <U+03C0>_bar.<U+1F602>_field<U+03C0>;\\n\" \" ^~~~~~~~~~~~~ ~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~\\n\" \" | | |\\n\" \" | | label 2\\xcf\\x80\\n\" \" | label 1\\xcf\\x80\\n\" \" label 0\\xf0\\x9f\\x98\\x82\\n\"" , "pp_formatted_text (dc.printer)", (" <U+1F602>_foo = <U+03C0>_bar.<U+1F602>_field<U+03C0>;\n" " ^~~~~~~~~~~~~ ~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~\n" " | | |\n" " | | label 2\xcf\x80\n" " | label 1\xcf\x80\n" " label 0\xf0\x9f\x98\x82\n"), (pp_formatted_text (dc.printer ))); } while (0) |
4316 | pp_formatted_text (dc.printer))do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 4316, __FUNCTION__)), "\" <U+1F602>_foo = <U+03C0>_bar.<U+1F602>_field<U+03C0>;\\n\" \" ^~~~~~~~~~~~~ ~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~\\n\" \" | | |\\n\" \" | | label 2\\xcf\\x80\\n\" \" | label 1\\xcf\\x80\\n\" \" label 0\\xf0\\x9f\\x98\\x82\\n\"" , "pp_formatted_text (dc.printer)", (" <U+1F602>_foo = <U+03C0>_bar.<U+1F602>_field<U+03C0>;\n" " ^~~~~~~~~~~~~ ~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~\n" " | | |\n" " | | label 2\xcf\x80\n" " | label 1\xcf\x80\n" " label 0\xf0\x9f\x98\x82\n"), (pp_formatted_text (dc.printer ))); } while (0); |
4317 | } |
4318 | { |
4319 | test_diagnostic_context dc; |
4320 | dc.escape_format = DIAGNOSTICS_ESCAPE_FORMAT_BYTES; |
4321 | diagnostic_show_locus (&dc, &richloc, DK_ERROR); |
4322 | ASSERT_STREQdo { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 4329, __FUNCTION__)), "\" <f0><9f><98><82>_foo = <cf><80>_bar.<f0><9f><98><82>_field<cf><80>;\\n\" \" ^~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\\n\" \" | | |\\n\" \" | | label 2\\xcf\\x80\\n\" \" | label 1\\xcf\\x80\\n\" \" label 0\\xf0\\x9f\\x98\\x82\\n\"" , "pp_formatted_text (dc.printer)", (" <f0><9f><98><82>_foo = <cf><80>_bar.<f0><9f><98><82>_field<cf><80>;\n" " ^~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n" " | | |\n" " | | label 2\xcf\x80\n" " | label 1\xcf\x80\n" " label 0\xf0\x9f\x98\x82\n" ), (pp_formatted_text (dc.printer))); } while (0) |
4323 | (" <f0><9f><98><82>_foo = <cf><80>_bar.<f0><9f><98><82>_field<cf><80>;\n"do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 4329, __FUNCTION__)), "\" <f0><9f><98><82>_foo = <cf><80>_bar.<f0><9f><98><82>_field<cf><80>;\\n\" \" ^~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\\n\" \" | | |\\n\" \" | | label 2\\xcf\\x80\\n\" \" | label 1\\xcf\\x80\\n\" \" label 0\\xf0\\x9f\\x98\\x82\\n\"" , "pp_formatted_text (dc.printer)", (" <f0><9f><98><82>_foo = <cf><80>_bar.<f0><9f><98><82>_field<cf><80>;\n" " ^~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n" " | | |\n" " | | label 2\xcf\x80\n" " | label 1\xcf\x80\n" " label 0\xf0\x9f\x98\x82\n" ), (pp_formatted_text (dc.printer))); } while (0) |
4324 | " ^~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n"do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 4329, __FUNCTION__)), "\" <f0><9f><98><82>_foo = <cf><80>_bar.<f0><9f><98><82>_field<cf><80>;\\n\" \" ^~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\\n\" \" | | |\\n\" \" | | label 2\\xcf\\x80\\n\" \" | label 1\\xcf\\x80\\n\" \" label 0\\xf0\\x9f\\x98\\x82\\n\"" , "pp_formatted_text (dc.printer)", (" <f0><9f><98><82>_foo = <cf><80>_bar.<f0><9f><98><82>_field<cf><80>;\n" " ^~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n" " | | |\n" " | | label 2\xcf\x80\n" " | label 1\xcf\x80\n" " label 0\xf0\x9f\x98\x82\n" ), (pp_formatted_text (dc.printer))); } while (0) |
4325 | " | | |\n"do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 4329, __FUNCTION__)), "\" <f0><9f><98><82>_foo = <cf><80>_bar.<f0><9f><98><82>_field<cf><80>;\\n\" \" ^~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\\n\" \" | | |\\n\" \" | | label 2\\xcf\\x80\\n\" \" | label 1\\xcf\\x80\\n\" \" label 0\\xf0\\x9f\\x98\\x82\\n\"" , "pp_formatted_text (dc.printer)", (" <f0><9f><98><82>_foo = <cf><80>_bar.<f0><9f><98><82>_field<cf><80>;\n" " ^~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n" " | | |\n" " | | label 2\xcf\x80\n" " | label 1\xcf\x80\n" " label 0\xf0\x9f\x98\x82\n" ), (pp_formatted_text (dc.printer))); } while (0) |
4326 | " | | label 2\xcf\x80\n"do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 4329, __FUNCTION__)), "\" <f0><9f><98><82>_foo = <cf><80>_bar.<f0><9f><98><82>_field<cf><80>;\\n\" \" ^~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\\n\" \" | | |\\n\" \" | | label 2\\xcf\\x80\\n\" \" | label 1\\xcf\\x80\\n\" \" label 0\\xf0\\x9f\\x98\\x82\\n\"" , "pp_formatted_text (dc.printer)", (" <f0><9f><98><82>_foo = <cf><80>_bar.<f0><9f><98><82>_field<cf><80>;\n" " ^~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n" " | | |\n" " | | label 2\xcf\x80\n" " | label 1\xcf\x80\n" " label 0\xf0\x9f\x98\x82\n" ), (pp_formatted_text (dc.printer))); } while (0) |
4327 | " | label 1\xcf\x80\n"do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 4329, __FUNCTION__)), "\" <f0><9f><98><82>_foo = <cf><80>_bar.<f0><9f><98><82>_field<cf><80>;\\n\" \" ^~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\\n\" \" | | |\\n\" \" | | label 2\\xcf\\x80\\n\" \" | label 1\\xcf\\x80\\n\" \" label 0\\xf0\\x9f\\x98\\x82\\n\"" , "pp_formatted_text (dc.printer)", (" <f0><9f><98><82>_foo = <cf><80>_bar.<f0><9f><98><82>_field<cf><80>;\n" " ^~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n" " | | |\n" " | | label 2\xcf\x80\n" " | label 1\xcf\x80\n" " label 0\xf0\x9f\x98\x82\n" ), (pp_formatted_text (dc.printer))); } while (0) |
4328 | " label 0\xf0\x9f\x98\x82\n",do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 4329, __FUNCTION__)), "\" <f0><9f><98><82>_foo = <cf><80>_bar.<f0><9f><98><82>_field<cf><80>;\\n\" \" ^~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\\n\" \" | | |\\n\" \" | | label 2\\xcf\\x80\\n\" \" | label 1\\xcf\\x80\\n\" \" label 0\\xf0\\x9f\\x98\\x82\\n\"" , "pp_formatted_text (dc.printer)", (" <f0><9f><98><82>_foo = <cf><80>_bar.<f0><9f><98><82>_field<cf><80>;\n" " ^~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n" " | | |\n" " | | label 2\xcf\x80\n" " | label 1\xcf\x80\n" " label 0\xf0\x9f\x98\x82\n" ), (pp_formatted_text (dc.printer))); } while (0) |
4329 | pp_formatted_text (dc.printer))do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 4329, __FUNCTION__)), "\" <f0><9f><98><82>_foo = <cf><80>_bar.<f0><9f><98><82>_field<cf><80>;\\n\" \" ^~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\\n\" \" | | |\\n\" \" | | label 2\\xcf\\x80\\n\" \" | label 1\\xcf\\x80\\n\" \" label 0\\xf0\\x9f\\x98\\x82\\n\"" , "pp_formatted_text (dc.printer)", (" <f0><9f><98><82>_foo = <cf><80>_bar.<f0><9f><98><82>_field<cf><80>;\n" " ^~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n" " | | |\n" " | | label 2\xcf\x80\n" " | label 1\xcf\x80\n" " label 0\xf0\x9f\x98\x82\n" ), (pp_formatted_text (dc.printer))); } while (0); |
4330 | } |
4331 | } |
4332 | } |
4333 | |
4334 | /* Make sure that colorization codes don't interrupt a multibyte |
4335 | sequence, which would corrupt it. */ |
4336 | static void |
4337 | test_one_liner_colorized_utf8 () |
4338 | { |
4339 | test_diagnostic_context dc; |
4340 | dc.colorize_source_p = true; |
4341 | diagnostic_color_init (&dc, DIAGNOSTICS_COLOR_YES); |
4342 | const location_t pi = linemap_position_for_column (line_table, 12); |
4343 | rich_location richloc (line_table, pi); |
4344 | diagnostic_show_locus (&dc, &richloc, DK_ERROR); |
4345 | |
4346 | /* In order to avoid having the test depend on exactly how the colorization |
4347 | was effected, just confirm there are two pi characters in the output. */ |
4348 | const char *result = pp_formatted_text (dc.printer); |
4349 | const char *null_term = result + strlen (result); |
4350 | const char *first_pi = strstr (result, "\xcf\x80"); |
4351 | ASSERT_TRUE (first_pi && first_pi <= null_term - 2)do { const char *desc_ = "ASSERT_TRUE (" "(first_pi && first_pi <= null_term - 2)" ")"; bool actual_ = ((first_pi && first_pi <= null_term - 2)); if (actual_) ::selftest::pass (((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 4351, __FUNCTION__))), desc_); else ::selftest::fail (((::selftest ::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 4351, __FUNCTION__))), desc_); } while (0); |
4352 | ASSERT_STR_CONTAINS (first_pi + 2, "\xcf\x80")do { ::selftest::assert_str_contains ((::selftest::location ( "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 4352, __FUNCTION__)), "first_pi + 2", "\"\\xcf\\x80\"", (first_pi + 2), ("\xcf\x80")); } while (0); |
4353 | } |
4354 | |
4355 | /* Run the various one-liner tests. */ |
4356 | |
4357 | static void |
4358 | test_diagnostic_show_locus_one_liner_utf8 (const line_table_case &case_) |
4359 | { |
4360 | /* Create a tempfile and write some text to it. */ |
4361 | const char *content |
4362 | /* Display columns. |
4363 | 0000000000000000000000011111111111111111111111111111112222222222222 |
4364 | 1111111122222222345678900000000123456666666677777777890123444444445 */ |
4365 | = "\xf0\x9f\x98\x82_foo = \xcf\x80_bar.\xf0\x9f\x98\x82_field\xcf\x80;\n"; |
4366 | /* 0000000000000000000001111111111111111111222222222222222222222233333 |
4367 | 1111222233334444567890122223333456789999000011112222345678999900001 |
4368 | Byte columns. */ |
4369 | temp_source_file tmp (SELFTEST_LOCATION(::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 4369, __FUNCTION__)), ".c", content); |
4370 | line_table_test ltt (case_); |
4371 | |
4372 | linemap_add (line_table, LC_ENTER, false, tmp.get_filename (), 1); |
4373 | |
4374 | location_t line_end = linemap_position_for_column (line_table, 31); |
4375 | |
4376 | /* Don't attempt to run the tests if column data might be unavailable. */ |
4377 | if (line_end > LINE_MAP_MAX_LOCATION_WITH_COLS) |
4378 | return; |
4379 | |
4380 | ASSERT_STREQ (tmp.get_filename (), LOCATION_FILE (line_end))do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 4380, __FUNCTION__)), "tmp.get_filename ()", "LOCATION_FILE (line_end)" , (tmp.get_filename ()), (((expand_location (line_end)).file) )); } while (0); |
4381 | ASSERT_EQ (1, LOCATION_LINE (line_end))do { const char *desc_ = "ASSERT_EQ (" "(1)" ", " "(((expand_location (line_end)).line))" ")"; if (((1)) == ((((expand_location (line_end)).line)))) :: selftest::pass ((((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 4381, __FUNCTION__)))), desc_); else ::selftest::fail ((((:: selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 4381, __FUNCTION__)))), desc_); } while (0); |
4382 | ASSERT_EQ (31, LOCATION_COLUMN (line_end))do { const char *desc_ = "ASSERT_EQ (" "(31)" ", " "(((expand_location (line_end)).column))" ")"; if (((31)) == ((((expand_location (line_end)).column))) ) ::selftest::pass ((((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 4382, __FUNCTION__)))), desc_); else ::selftest::fail ((((:: selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 4382, __FUNCTION__)))), desc_); } while (0); |
4383 | |
4384 | char_span lspan = location_get_source_line (tmp.get_filename (), 1); |
4385 | ASSERT_EQ (25, cpp_display_width (lspan.get_buffer (), lspan.length (),do { const char *desc_ = "ASSERT_EQ (" "(25)" ", " "(cpp_display_width (lspan.get_buffer (), lspan.length (), def_policy ()))" ")"; if (((25)) == ((cpp_display_width (lspan.get_buffer (), lspan.length (), def_policy ())))) ::selftest::pass ((((::selftest ::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 4386, __FUNCTION__)))), desc_); else ::selftest::fail ((((:: selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 4386, __FUNCTION__)))), desc_); } while (0) |
4386 | def_policy ()))do { const char *desc_ = "ASSERT_EQ (" "(25)" ", " "(cpp_display_width (lspan.get_buffer (), lspan.length (), def_policy ()))" ")"; if (((25)) == ((cpp_display_width (lspan.get_buffer (), lspan.length (), def_policy ())))) ::selftest::pass ((((::selftest ::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 4386, __FUNCTION__)))), desc_); else ::selftest::fail ((((:: selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 4386, __FUNCTION__)))), desc_); } while (0); |
4387 | ASSERT_EQ (25, location_compute_display_column (expand_location (line_end),do { const char *desc_ = "ASSERT_EQ (" "(25)" ", " "(location_compute_display_column (expand_location (line_end), def_policy ()))" ")"; if (((25)) == ((location_compute_display_column (expand_location (line_end), def_policy ())))) ::selftest::pass ((((::selftest ::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 4388, __FUNCTION__)))), desc_); else ::selftest::fail ((((:: selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 4388, __FUNCTION__)))), desc_); } while (0) |
4388 | def_policy ()))do { const char *desc_ = "ASSERT_EQ (" "(25)" ", " "(location_compute_display_column (expand_location (line_end), def_policy ()))" ")"; if (((25)) == ((location_compute_display_column (expand_location (line_end), def_policy ())))) ::selftest::pass ((((::selftest ::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 4388, __FUNCTION__)))), desc_); else ::selftest::fail ((((:: selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 4388, __FUNCTION__)))), desc_); } while (0); |
4389 | |
4390 | test_one_liner_simple_caret_utf8 (); |
4391 | test_one_liner_caret_and_range_utf8 (); |
4392 | test_one_liner_multiple_carets_and_ranges_utf8 (); |
4393 | test_one_liner_fixit_insert_before_utf8 (); |
4394 | test_one_liner_fixit_insert_after_utf8 (); |
4395 | test_one_liner_fixit_remove_utf8 (); |
4396 | test_one_liner_fixit_replace_utf8 (); |
4397 | test_one_liner_fixit_replace_non_equal_range_utf8 (); |
4398 | test_one_liner_fixit_replace_equal_secondary_range_utf8 (); |
4399 | test_one_liner_fixit_validation_adhoc_locations_utf8 (); |
4400 | test_one_liner_many_fixits_1_utf8 (); |
4401 | test_one_liner_many_fixits_2_utf8 (); |
4402 | test_one_liner_labels_utf8 (); |
4403 | test_one_liner_colorized_utf8 (); |
4404 | } |
4405 | |
4406 | /* Verify that gcc_rich_location::add_location_if_nearby works. */ |
4407 | |
4408 | static void |
4409 | test_add_location_if_nearby (const line_table_case &case_) |
4410 | { |
4411 | /* Create a tempfile and write some text to it. |
4412 | ...000000000111111111122222222223333333333. |
4413 | ...123456789012345678901234567890123456789. */ |
4414 | const char *content |
4415 | = ("struct same_line { double x; double y; ;\n" /* line 1. */ |
4416 | "struct different_line\n" /* line 2. */ |
4417 | "{\n" /* line 3. */ |
4418 | " double x;\n" /* line 4. */ |
4419 | " double y;\n" /* line 5. */ |
4420 | ";\n"); /* line 6. */ |
4421 | temp_source_file tmp (SELFTEST_LOCATION(::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 4421, __FUNCTION__)), ".c", content); |
4422 | line_table_test ltt (case_); |
4423 | |
4424 | const line_map_ordinary *ord_map |
4425 | = linemap_check_ordinary (linemap_add (line_table, LC_ENTER, false, |
4426 | tmp.get_filename (), 0)); |
4427 | |
4428 | linemap_line_start (line_table, 1, 100); |
4429 | |
4430 | const location_t final_line_end |
4431 | = linemap_position_for_line_and_column (line_table, ord_map, 6, 7); |
4432 | |
4433 | /* Don't attempt to run the tests if column data might be unavailable. */ |
4434 | if (final_line_end > LINE_MAP_MAX_LOCATION_WITH_COLS) |
4435 | return; |
4436 | |
4437 | /* Test of add_location_if_nearby on the same line as the |
4438 | primary location. */ |
4439 | { |
4440 | const location_t missing_close_brace_1_39 |
4441 | = linemap_position_for_line_and_column (line_table, ord_map, 1, 39); |
4442 | const location_t matching_open_brace_1_18 |
4443 | = linemap_position_for_line_and_column (line_table, ord_map, 1, 18); |
4444 | gcc_rich_location richloc (missing_close_brace_1_39); |
4445 | bool added = richloc.add_location_if_nearby (matching_open_brace_1_18); |
4446 | ASSERT_TRUE (added)do { const char *desc_ = "ASSERT_TRUE (" "(added)" ")"; bool actual_ = ((added)); if (actual_) ::selftest::pass (((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 4446, __FUNCTION__))), desc_); else ::selftest::fail (((::selftest ::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 4446, __FUNCTION__))), desc_); } while (0); |
4447 | ASSERT_EQ (2, richloc.get_num_locations ())do { const char *desc_ = "ASSERT_EQ (" "(2)" ", " "(richloc.get_num_locations ())" ")"; if (((2)) == ((richloc.get_num_locations ()))) ::selftest ::pass ((((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 4447, __FUNCTION__)))), desc_); else ::selftest::fail ((((:: selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 4447, __FUNCTION__)))), desc_); } while (0); |
4448 | test_diagnostic_context dc; |
4449 | diagnostic_show_locus (&dc, &richloc, DK_ERROR); |
4450 | ASSERT_STREQ (" struct same_line { double x; double y; ;\n"do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 4452, __FUNCTION__)), "\" struct same_line { double x; double y; ;\\n\" \" ~ ^\\n\"" , "pp_formatted_text (dc.printer)", (" struct same_line { double x; double y; ;\n" " ~ ^\n"), (pp_formatted_text (dc.printer))); } while (0) |
4451 | " ~ ^\n",do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 4452, __FUNCTION__)), "\" struct same_line { double x; double y; ;\\n\" \" ~ ^\\n\"" , "pp_formatted_text (dc.printer)", (" struct same_line { double x; double y; ;\n" " ~ ^\n"), (pp_formatted_text (dc.printer))); } while (0) |
4452 | pp_formatted_text (dc.printer))do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 4452, __FUNCTION__)), "\" struct same_line { double x; double y; ;\\n\" \" ~ ^\\n\"" , "pp_formatted_text (dc.printer)", (" struct same_line { double x; double y; ;\n" " ~ ^\n"), (pp_formatted_text (dc.printer))); } while (0); |
4453 | } |
4454 | |
4455 | /* Test of add_location_if_nearby on a different line to the |
4456 | primary location. */ |
4457 | { |
4458 | const location_t missing_close_brace_6_1 |
4459 | = linemap_position_for_line_and_column (line_table, ord_map, 6, 1); |
4460 | const location_t matching_open_brace_3_1 |
4461 | = linemap_position_for_line_and_column (line_table, ord_map, 3, 1); |
4462 | gcc_rich_location richloc (missing_close_brace_6_1); |
4463 | bool added = richloc.add_location_if_nearby (matching_open_brace_3_1); |
4464 | ASSERT_FALSE (added)do { const char *desc_ = "ASSERT_FALSE (" "(added)" ")"; bool actual_ = ((added)); if (actual_) ::selftest::fail (((::selftest ::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 4464, __FUNCTION__))), desc_); else ::selftest::pass (((::selftest ::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 4464, __FUNCTION__))), desc_); } while (0); |
4465 | ASSERT_EQ (1, richloc.get_num_locations ())do { const char *desc_ = "ASSERT_EQ (" "(1)" ", " "(richloc.get_num_locations ())" ")"; if (((1)) == ((richloc.get_num_locations ()))) ::selftest ::pass ((((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 4465, __FUNCTION__)))), desc_); else ::selftest::fail ((((:: selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 4465, __FUNCTION__)))), desc_); } while (0); |
4466 | } |
4467 | } |
4468 | |
4469 | /* Verify that we print fixits even if they only affect lines |
4470 | outside those covered by the ranges in the rich_location. */ |
4471 | |
4472 | static void |
4473 | test_diagnostic_show_locus_fixit_lines (const line_table_case &case_) |
4474 | { |
4475 | /* Create a tempfile and write some text to it. |
4476 | ...000000000111111111122222222223333333333. |
4477 | ...123456789012345678901234567890123456789. */ |
4478 | const char *content |
4479 | = ("struct point { double x; double y; };\n" /* line 1. */ |
4480 | "struct point origin = {x: 0.0,\n" /* line 2. */ |
4481 | " y\n" /* line 3. */ |
4482 | "\n" /* line 4. */ |
4483 | "\n" /* line 5. */ |
4484 | " : 0.0};\n"); /* line 6. */ |
4485 | temp_source_file tmp (SELFTEST_LOCATION(::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 4485, __FUNCTION__)), ".c", content); |
4486 | line_table_test ltt (case_); |
4487 | |
4488 | const line_map_ordinary *ord_map |
4489 | = linemap_check_ordinary (linemap_add (line_table, LC_ENTER, false, |
4490 | tmp.get_filename (), 0)); |
4491 | |
4492 | linemap_line_start (line_table, 1, 100); |
4493 | |
4494 | const location_t final_line_end |
4495 | = linemap_position_for_line_and_column (line_table, ord_map, 6, 36); |
4496 | |
4497 | /* Don't attempt to run the tests if column data might be unavailable. */ |
4498 | if (final_line_end > LINE_MAP_MAX_LOCATION_WITH_COLS) |
4499 | return; |
4500 | |
4501 | /* A pair of tests for modernizing the initializers to C99-style. */ |
4502 | |
4503 | /* The one-liner case (line 2). */ |
4504 | { |
4505 | test_diagnostic_context dc; |
4506 | const location_t x |
4507 | = linemap_position_for_line_and_column (line_table, ord_map, 2, 24); |
4508 | const location_t colon |
4509 | = linemap_position_for_line_and_column (line_table, ord_map, 2, 25); |
4510 | rich_location richloc (line_table, colon); |
4511 | richloc.add_fixit_insert_before (x, "."); |
4512 | richloc.add_fixit_replace (colon, "="); |
4513 | diagnostic_show_locus (&dc, &richloc, DK_ERROR); |
4514 | ASSERT_STREQ (" struct point origin = {x: 0.0,\n"do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 4517, __FUNCTION__)), "\" struct point origin = {x: 0.0,\\n\" \" ^\\n\" \" .=\\n\"" , "pp_formatted_text (dc.printer)", (" struct point origin = {x: 0.0,\n" " ^\n" " .=\n" ), (pp_formatted_text (dc.printer))); } while (0) |
4515 | " ^\n"do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 4517, __FUNCTION__)), "\" struct point origin = {x: 0.0,\\n\" \" ^\\n\" \" .=\\n\"" , "pp_formatted_text (dc.printer)", (" struct point origin = {x: 0.0,\n" " ^\n" " .=\n" ), (pp_formatted_text (dc.printer))); } while (0) |
4516 | " .=\n",do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 4517, __FUNCTION__)), "\" struct point origin = {x: 0.0,\\n\" \" ^\\n\" \" .=\\n\"" , "pp_formatted_text (dc.printer)", (" struct point origin = {x: 0.0,\n" " ^\n" " .=\n" ), (pp_formatted_text (dc.printer))); } while (0) |
4517 | pp_formatted_text (dc.printer))do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc" , 4517, __FUNCTION__)), "\" struct point origin = {x: 0.0,\\n\" \" ^\\n\" \" .=\\n\"" , "pp_formatted_text (dc.printer)", (" struct point origin = {x: 0.0,\n" " ^\n" " .=\n" ), (pp_formatted_text (dc.printer))); } while (0); |
4518 | } |
4519 | |
4520 | /* The multiline case. The caret for the rich_location is on line 6; |
4521 | verify that insertion fixit on line 3 is still printed (and that |
4522 | span starts are printed due to the gap between the span at line 3 |
4523 | and that at line 6). */ |
4524 | { |
4525 | test_diagnostic_context dc; |
4526 | const location_t y |
4527 | = linemap_position_for_line_and_column (line_table, ord_map, 3, 24); |
4528 | const location_t colon |
4529 | = linemap_position_for_line_and_column (line_table, ord_map, 6, 25); |
4530 | rich_location richloc (line_table, colon); |
4531 | richloc.add_fixit_insert_before (y, "."); |
4532 | richloc.add_fixit_replace (colon, "="); |
4533 | diagnostic_show_locus (&dc, &richloc, DK_ERROR); |
4534 | ASSERT_STREQ ("FILENAME:3:24:\n"do { ::selftest::assert_streq ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/diagnostic-show-locus.cc |