diff options
Diffstat (limited to 'meta/recipes-devtools/gcc/gcc/0005-CVE-2021-42574.patch')
-rw-r--r-- | meta/recipes-devtools/gcc/gcc/0005-CVE-2021-42574.patch | 575 |
1 files changed, 575 insertions, 0 deletions
diff --git a/meta/recipes-devtools/gcc/gcc/0005-CVE-2021-42574.patch b/meta/recipes-devtools/gcc/gcc/0005-CVE-2021-42574.patch new file mode 100644 index 0000000000..6e983a67b6 --- /dev/null +++ b/meta/recipes-devtools/gcc/gcc/0005-CVE-2021-42574.patch | |||
@@ -0,0 +1,575 @@ | |||
1 | From bef32d4a28595e933f24fef378cf052a30b674a7 Mon Sep 17 00:00:00 2001 | ||
2 | From: David Malcolm <dmalcolm@redhat.com> | ||
3 | Date: Tue, 2 Nov 2021 15:45:22 -0400 | ||
4 | Subject: [PATCH] libcpp: capture and underline ranges in -Wbidi-chars= | ||
5 | [PR103026] | ||
6 | MIME-Version: 1.0 | ||
7 | Content-Type: text/plain; charset=utf8 | ||
8 | Content-Transfer-Encoding: 8bit | ||
9 | |||
10 | This patch converts the bidi::vec to use a struct so that we can | ||
11 | capture location_t values for the bidirectional control characters. | ||
12 | |||
13 | Before: | ||
14 | |||
15 | Wbidi-chars-1.c: In function âmainâ: | ||
16 | Wbidi-chars-1.c:6:43: warning: unpaired UTF-8 bidirectional control character detected [-Wbidi-chars=] | ||
17 | 6 | /*<U+202E> } <U+2066>if (isAdmin)<U+2069> <U+2066> begin admins only */ | ||
18 | | ^ | ||
19 | Wbidi-chars-1.c:9:28: warning: unpaired UTF-8 bidirectional control character detected [-Wbidi-chars=] | ||
20 | 9 | /* end admins only <U+202E> { <U+2066>*/ | ||
21 | | ^ | ||
22 | |||
23 | After: | ||
24 | |||
25 | Wbidi-chars-1.c: In function âmainâ: | ||
26 | Wbidi-chars-1.c:6:43: warning: unpaired UTF-8 bidirectional control characters detected [-Wbidi-chars=] | ||
27 | 6 | /*<U+202E> } <U+2066>if (isAdmin)<U+2069> <U+2066> begin admins only */ | ||
28 | | ~~~~~~~~ ~~~~~~~~ ^ | ||
29 | | | | | | ||
30 | | | | end of bidirectional context | ||
31 | | U+202E (RIGHT-TO-LEFT OVERRIDE) U+2066 (LEFT-TO-RIGHT ISOLATE) | ||
32 | Wbidi-chars-1.c:9:28: warning: unpaired UTF-8 bidirectional control characters detected [-Wbidi-chars=] | ||
33 | 9 | /* end admins only <U+202E> { <U+2066>*/ | ||
34 | | ~~~~~~~~ ~~~~~~~~ ^ | ||
35 | | | | | | ||
36 | | | | end of bidirectional context | ||
37 | | | U+2066 (LEFT-TO-RIGHT ISOLATE) | ||
38 | | U+202E (RIGHT-TO-LEFT OVERRIDE) | ||
39 | |||
40 | Signed-off-by: David Malcolm <dmalcolm@redhat.com> | ||
41 | |||
42 | gcc/testsuite/ChangeLog: | ||
43 | PR preprocessor/103026 | ||
44 | * c-c++-common/Wbidi-chars-ranges.c: New test. | ||
45 | |||
46 | libcpp/ChangeLog: | ||
47 | PR preprocessor/103026 | ||
48 | * lex.c (struct bidi::context): New. | ||
49 | (bidi::vec): Convert to a vec of context rather than unsigned | ||
50 | char. | ||
51 | (bidi::ctx_at): Rename to... | ||
52 | (bidi::pop_kind_at): ...this and reimplement for above change. | ||
53 | (bidi::current_ctx): Update for change to vec. | ||
54 | (bidi::current_ctx_ucn_p): Likewise. | ||
55 | (bidi::current_ctx_loc): New. | ||
56 | (bidi::on_char): Update for usage of context struct. Add "loc" | ||
57 | param and pass it when pushing contexts. | ||
58 | (get_location_for_byte_range_in_cur_line): New. | ||
59 | (get_bidi_utf8): Rename to... | ||
60 | (get_bidi_utf8_1): ...this, reintroducing... | ||
61 | (get_bidi_utf8): ...as a wrapper, setting *OUT when the result is | ||
62 | not NONE. | ||
63 | (get_bidi_ucn): Rename to... | ||
64 | (get_bidi_ucn_1): ...this, reintroducing... | ||
65 | (get_bidi_ucn): ...as a wrapper, setting *OUT when the result is | ||
66 | not NONE. | ||
67 | (class unpaired_bidi_rich_location): New. | ||
68 | (maybe_warn_bidi_on_close): Use unpaired_bidi_rich_location when | ||
69 | reporting on unpaired bidi chars. Split into singular vs plural | ||
70 | spellings. | ||
71 | (maybe_warn_bidi_on_char): Pass in a location_t rather than a | ||
72 | const uchar * and use it when emitting warnings, and when calling | ||
73 | bidi::on_char. | ||
74 | (_cpp_skip_block_comment): Capture location when kind is not NONE | ||
75 | and pass it to maybe_warn_bidi_on_char. | ||
76 | (skip_line_comment): Likewise. | ||
77 | (forms_identifier_p): Likewise. | ||
78 | (lex_raw_string): Likewise. | ||
79 | (lex_string): Likewise. | ||
80 | |||
81 | Signed-off-by: David Malcolm <dmalcolm@redhat.com> | ||
82 | |||
83 | CVE: CVE-2021-42574 | ||
84 | Upstream-Status: Backport [https://gcc.gnu.org/git/gitweb.cgi?p=gcc.git;h=bef32d4a28595e933f24fef378cf052a30b674a7] | ||
85 | Signed-off-by: Pgowda <pgowda.cve@gmail.com> | ||
86 | |||
87 | --- | ||
88 | .../c-c++-common/Wbidi-chars-ranges.c | 54 ++++ | ||
89 | libcpp/lex.c | 251 ++++++++++++++---- | ||
90 | 2 files changed, 257 insertions(+), 48 deletions(-) | ||
91 | create mode 100644 gcc/testsuite/c-c++-common/Wbidi-chars-ranges.c | ||
92 | |||
93 | diff --git a/gcc/testsuite/c-c++-common/Wbidi-chars-ranges.c b/gcc/testsuite/c-c++-common/Wbidi-chars-ranges.c | ||
94 | --- a/gcc/testsuite/c-c++-common/Wbidi-chars-ranges.c 1969-12-31 16:00:00.000000000 -0800 | ||
95 | +++ b/gcc/testsuite/c-c++-common/Wbidi-chars-ranges.c 2021-12-25 01:39:55.116281847 -0800 | ||
96 | @@ -0,0 +1,54 @@ | ||
97 | +/* PR preprocessor/103026 */ | ||
98 | +/* { dg-do compile } */ | ||
99 | +/* { dg-options "-Wbidi-chars=unpaired -fdiagnostics-show-caret" } */ | ||
100 | +/* Verify that we escape and underline pertinent bidirectional | ||
101 | + control characters when quoting the source. */ | ||
102 | + | ||
103 | +int test_unpaired_bidi () { | ||
104 | + int isAdmin = 0; | ||
105 | + /* } if (isAdmin) begin admins only */ | ||
106 | +/* { dg-warning "bidirectional" "" { target *-*-* } .-1 } */ | ||
107 | +#if 0 | ||
108 | + { dg-begin-multiline-output "" } | ||
109 | + /*<U+202E> } <U+2066>if (isAdmin)<U+2069> <U+2066> begin admins only */ | ||
110 | + ~~~~~~~~ ~~~~~~~~ ^ | ||
111 | + | | | | ||
112 | + | | end of bidirectional context | ||
113 | + U+202E (RIGHT-TO-LEFT OVERRIDE) U+2066 (LEFT-TO-RIGHT ISOLATE) | ||
114 | + { dg-end-multiline-output "" } | ||
115 | +#endif | ||
116 | + | ||
117 | + __builtin_printf("You are an admin.\n"); | ||
118 | + /* end admins only { */ | ||
119 | +/* { dg-warning "bidirectional" "" { target *-*-* } .-1 } */ | ||
120 | +#if 0 | ||
121 | + { dg-begin-multiline-output "" } | ||
122 | + /* end admins only <U+202E> { <U+2066>*/ | ||
123 | + ~~~~~~~~ ~~~~~~~~ ^ | ||
124 | + | | | | ||
125 | + | | end of bidirectional context | ||
126 | + | U+2066 (LEFT-TO-RIGHT ISOLATE) | ||
127 | + U+202E (RIGHT-TO-LEFT OVERRIDE) | ||
128 | + { dg-end-multiline-output "" } | ||
129 | +#endif | ||
130 | + | ||
131 | + return 0; | ||
132 | +} | ||
133 | + | ||
134 | +int LRE__PDF_\u202c; | ||
135 | +/* { dg-warning "mismatch" "" { target *-*-* } .-1 } */ | ||
136 | +#if 0 | ||
137 | + { dg-begin-multiline-output "" } | ||
138 | + int LRE_<U+202A>_PDF_\u202c; | ||
139 | + ~~~~~~~~ ^~~~~~ | ||
140 | + { dg-end-multiline-output "" } | ||
141 | +#endif | ||
142 | + | ||
143 | +const char *s1 = "LRE__PDF_\u202c"; | ||
144 | +/* { dg-warning "mismatch" "" { target *-*-* } .-1 } */ | ||
145 | +#if 0 | ||
146 | + { dg-begin-multiline-output "" } | ||
147 | + const char *s1 = "LRE_<U+202A>_PDF_\u202c"; | ||
148 | + ~~~~~~~~ ^~~~~~ | ||
149 | + { dg-end-multiline-output "" } | ||
150 | +#endif | ||
151 | diff --git a/libcpp/lex.c b/libcpp/lex.c | ||
152 | --- a/libcpp/lex.c 2021-12-25 01:41:16.522868808 -0800 | ||
153 | +++ b/libcpp/lex.c 2021-12-25 06:28:58.530680302 -0800 | ||
154 | @@ -1172,11 +1172,34 @@ namespace bidi { | ||
155 | /* All the UTF-8 encodings of bidi characters start with E2. */ | ||
156 | constexpr uchar utf8_start = 0xe2; | ||
157 | |||
158 | + struct context | ||
159 | + { | ||
160 | + context () {} | ||
161 | + context (location_t loc, kind k, bool pdf, bool ucn) | ||
162 | + : m_loc (loc), m_kind (k), m_pdf (pdf), m_ucn (ucn) | ||
163 | + { | ||
164 | + } | ||
165 | + | ||
166 | + kind get_pop_kind () const | ||
167 | + { | ||
168 | + return m_pdf ? kind::PDF : kind::PDI; | ||
169 | + } | ||
170 | + bool ucn_p () const | ||
171 | + { | ||
172 | + return m_ucn; | ||
173 | + } | ||
174 | + | ||
175 | + location_t m_loc; | ||
176 | + kind m_kind; | ||
177 | + unsigned m_pdf : 1; | ||
178 | + unsigned m_ucn : 1; | ||
179 | + }; | ||
180 | + | ||
181 | /* A vector holding currently open bidi contexts. We use a char for | ||
182 | each context, its LSB is 1 if it represents a PDF context, 0 if it | ||
183 | represents a PDI context. The next bit is 1 if this context was open | ||
184 | by a bidi character written as a UCN, and 0 when it was UTF-8. */ | ||
185 | - semi_embedded_vec <unsigned char, 16> vec; | ||
186 | + semi_embedded_vec <context, 16> vec; | ||
187 | |||
188 | /* Close the whole comment/identifier/string literal/character constant | ||
189 | context. */ | ||
190 | @@ -1193,19 +1216,19 @@ namespace bidi { | ||
191 | vec.truncate (len - 1); | ||
192 | } | ||
193 | |||
194 | - /* Return the context of the Ith element. */ | ||
195 | - kind ctx_at (unsigned int i) | ||
196 | + /* Return the pop kind of the context of the Ith element. */ | ||
197 | + kind pop_kind_at (unsigned int i) | ||
198 | { | ||
199 | - return (vec[i] & 1) ? kind::PDF : kind::PDI; | ||
200 | + return vec[i].get_pop_kind (); | ||
201 | } | ||
202 | |||
203 | - /* Return which context is currently opened. */ | ||
204 | + /* Return the pop kind of the context that is currently opened. */ | ||
205 | kind current_ctx () | ||
206 | { | ||
207 | unsigned int len = vec.count (); | ||
208 | if (len == 0) | ||
209 | return kind::NONE; | ||
210 | - return ctx_at (len - 1); | ||
211 | + return vec[len - 1].get_pop_kind (); | ||
212 | } | ||
213 | |||
214 | /* Return true if the current context comes from a UCN origin, that is, | ||
215 | @@ -1214,11 +1237,19 @@ namespace bidi { | ||
216 | { | ||
217 | unsigned int len = vec.count (); | ||
218 | gcc_checking_assert (len > 0); | ||
219 | - return (vec[len - 1] >> 1) & 1; | ||
220 | + return vec[len - 1].m_ucn; | ||
221 | } | ||
222 | |||
223 | - /* We've read a bidi char, update the current vector as necessary. */ | ||
224 | - void on_char (kind k, bool ucn_p) | ||
225 | + location_t current_ctx_loc () | ||
226 | + { | ||
227 | + unsigned int len = vec.count (); | ||
228 | + gcc_checking_assert (len > 0); | ||
229 | + return vec[len - 1].m_loc; | ||
230 | + } | ||
231 | + | ||
232 | + /* We've read a bidi char, update the current vector as necessary. | ||
233 | + LOC is only valid when K is not kind::NONE. */ | ||
234 | + void on_char (kind k, bool ucn_p, location_t loc) | ||
235 | { | ||
236 | switch (k) | ||
237 | { | ||
238 | @@ -1226,12 +1257,12 @@ namespace bidi { | ||
239 | case kind::RLE: | ||
240 | case kind::LRO: | ||
241 | case kind::RLO: | ||
242 | - vec.push (ucn_p ? 3u : 1u); | ||
243 | + vec.push (context (loc, k, true, ucn_p)); | ||
244 | break; | ||
245 | case kind::LRI: | ||
246 | case kind::RLI: | ||
247 | case kind::FSI: | ||
248 | - vec.push (ucn_p ? 2u : 0u); | ||
249 | + vec.push (context (loc, k, false, ucn_p)); | ||
250 | break; | ||
251 | /* PDF terminates the scope of the last LRE, RLE, LRO, or RLO | ||
252 | whose scope has not yet been terminated. */ | ||
253 | @@ -1245,7 +1276,7 @@ namespace bidi { | ||
254 | yet been terminated. */ | ||
255 | case kind::PDI: | ||
256 | for (int i = vec.count () - 1; i >= 0; --i) | ||
257 | - if (ctx_at (i) == kind::PDI) | ||
258 | + if (pop_kind_at (i) == kind::PDI) | ||
259 | { | ||
260 | vec.truncate (i); | ||
261 | break; | ||
262 | @@ -1295,10 +1326,47 @@ namespace bidi { | ||
263 | } | ||
264 | } | ||
265 | |||
266 | +/* Get location_t for the range of bytes [START, START + NUM_BYTES) | ||
267 | + within the current line in FILE, with the caret at START. */ | ||
268 | + | ||
269 | +static location_t | ||
270 | +get_location_for_byte_range_in_cur_line (cpp_reader *pfile, | ||
271 | + const unsigned char *const start, | ||
272 | + size_t num_bytes) | ||
273 | +{ | ||
274 | + gcc_checking_assert (num_bytes > 0); | ||
275 | + | ||
276 | + /* CPP_BUF_COLUMN and linemap_position_for_column both refer | ||
277 | + to offsets in bytes, but CPP_BUF_COLUMN is 0-based, | ||
278 | + whereas linemap_position_for_column is 1-based. */ | ||
279 | + | ||
280 | + /* Get 0-based offsets within the line. */ | ||
281 | + size_t start_offset = CPP_BUF_COLUMN (pfile->buffer, start); | ||
282 | + size_t end_offset = start_offset + num_bytes - 1; | ||
283 | + | ||
284 | + /* Now convert to location_t, where "columns" are 1-based byte offsets. */ | ||
285 | + location_t start_loc = linemap_position_for_column (pfile->line_table, | ||
286 | + start_offset + 1); | ||
287 | + location_t end_loc = linemap_position_for_column (pfile->line_table, | ||
288 | + end_offset + 1); | ||
289 | + | ||
290 | + if (start_loc == end_loc) | ||
291 | + return start_loc; | ||
292 | + | ||
293 | + source_range src_range; | ||
294 | + src_range.m_start = start_loc; | ||
295 | + src_range.m_finish = end_loc; | ||
296 | + location_t combined_loc = COMBINE_LOCATION_DATA (pfile->line_table, | ||
297 | + start_loc, | ||
298 | + src_range, | ||
299 | + NULL); | ||
300 | + return combined_loc; | ||
301 | +} | ||
302 | + | ||
303 | /* Parse a sequence of 3 bytes starting with P and return its bidi code. */ | ||
304 | |||
305 | static bidi::kind | ||
306 | -get_bidi_utf8 (const unsigned char *const p) | ||
307 | +get_bidi_utf8_1 (const unsigned char *const p) | ||
308 | { | ||
309 | gcc_checking_assert (p[0] == bidi::utf8_start); | ||
310 | |||
311 | @@ -1340,10 +1408,25 @@ get_bidi_utf8 (const unsigned char *cons | ||
312 | return bidi::kind::NONE; | ||
313 | } | ||
314 | |||
315 | +/* Parse a sequence of 3 bytes starting with P and return its bidi code. | ||
316 | + If the kind is not NONE, write the location to *OUT.*/ | ||
317 | + | ||
318 | +static bidi::kind | ||
319 | +get_bidi_utf8 (cpp_reader *pfile, const unsigned char *const p, location_t *out) | ||
320 | +{ | ||
321 | + bidi::kind result = get_bidi_utf8_1 (p); | ||
322 | + if (result != bidi::kind::NONE) | ||
323 | + { | ||
324 | + /* We have a sequence of 3 bytes starting at P. */ | ||
325 | + *out = get_location_for_byte_range_in_cur_line (pfile, p, 3); | ||
326 | + } | ||
327 | + return result; | ||
328 | +} | ||
329 | + | ||
330 | /* Parse a UCN where P points just past \u or \U and return its bidi code. */ | ||
331 | |||
332 | static bidi::kind | ||
333 | -get_bidi_ucn (const unsigned char *p, bool is_U) | ||
334 | +get_bidi_ucn_1 (const unsigned char *p, bool is_U) | ||
335 | { | ||
336 | /* 6.4.3 Universal Character Names | ||
337 | \u hex-quad | ||
338 | @@ -1412,6 +1495,62 @@ get_bidi_ucn (const unsigned char *p, bo | ||
339 | return bidi::kind::NONE; | ||
340 | } | ||
341 | |||
342 | +/* Parse a UCN where P points just past \u or \U and return its bidi code. | ||
343 | + If the kind is not NONE, write the location to *OUT.*/ | ||
344 | + | ||
345 | +static bidi::kind | ||
346 | +get_bidi_ucn (cpp_reader *pfile, const unsigned char *p, bool is_U, | ||
347 | + location_t *out) | ||
348 | +{ | ||
349 | + bidi::kind result = get_bidi_ucn_1 (p, is_U); | ||
350 | + if (result != bidi::kind::NONE) | ||
351 | + { | ||
352 | + const unsigned char *start = p - 2; | ||
353 | + size_t num_bytes = 2 + (is_U ? 8 : 4); | ||
354 | + *out = get_location_for_byte_range_in_cur_line (pfile, start, num_bytes); | ||
355 | + } | ||
356 | + return result; | ||
357 | +} | ||
358 | + | ||
359 | +/* Subclass of rich_location for reporting on unpaired UTF-8 | ||
360 | + bidirectional control character(s). | ||
361 | + Escape the source lines on output, and show all unclosed | ||
362 | + bidi context, labelling everything. */ | ||
363 | + | ||
364 | +class unpaired_bidi_rich_location : public rich_location | ||
365 | +{ | ||
366 | + public: | ||
367 | + class custom_range_label : public range_label | ||
368 | + { | ||
369 | + public: | ||
370 | + label_text get_text (unsigned range_idx) const FINAL OVERRIDE | ||
371 | + { | ||
372 | + /* range 0 is the primary location; each subsequent range i + 1 | ||
373 | + is for bidi::vec[i]. */ | ||
374 | + if (range_idx > 0) | ||
375 | + { | ||
376 | + const bidi::context &ctxt (bidi::vec[range_idx - 1]); | ||
377 | + return label_text::borrow (bidi::to_str (ctxt.m_kind)); | ||
378 | + } | ||
379 | + else | ||
380 | + return label_text::borrow (_("end of bidirectional context")); | ||
381 | + } | ||
382 | + }; | ||
383 | + | ||
384 | + unpaired_bidi_rich_location (cpp_reader *pfile, location_t loc) | ||
385 | + : rich_location (pfile->line_table, loc, &m_custom_label) | ||
386 | + { | ||
387 | + set_escape_on_output (true); | ||
388 | + for (unsigned i = 0; i < bidi::vec.count (); i++) | ||
389 | + add_range (bidi::vec[i].m_loc, | ||
390 | + SHOW_RANGE_WITHOUT_CARET, | ||
391 | + &m_custom_label); | ||
392 | + } | ||
393 | + | ||
394 | + private: | ||
395 | + custom_range_label m_custom_label; | ||
396 | +}; | ||
397 | + | ||
398 | /* We're closing a bidi context, that is, we've encountered a newline, | ||
399 | are closing a C-style comment, or are at the end of a string literal, | ||
400 | character constant, or identifier. Warn if this context was not | ||
401 | @@ -1427,11 +1566,17 @@ maybe_warn_bidi_on_close (cpp_reader *pf | ||
402 | const location_t loc | ||
403 | = linemap_position_for_column (pfile->line_table, | ||
404 | CPP_BUF_COLUMN (pfile->buffer, p)); | ||
405 | - rich_location rich_loc (pfile->line_table, loc); | ||
406 | - rich_loc.set_escape_on_output (true); | ||
407 | - cpp_warning_at (pfile, CPP_W_BIDIRECTIONAL, &rich_loc, | ||
408 | - "unpaired UTF-8 bidirectional control character " | ||
409 | - "detected"); | ||
410 | + unpaired_bidi_rich_location rich_loc (pfile, loc); | ||
411 | + /* cpp_callbacks doesn't yet have a way to handle singular vs plural | ||
412 | + forms of a diagnostic, so fake it for now. */ | ||
413 | + if (bidi::vec.count () > 1) | ||
414 | + cpp_warning_at (pfile, CPP_W_BIDIRECTIONAL, &rich_loc, | ||
415 | + "unpaired UTF-8 bidirectional control characters " | ||
416 | + "detected"); | ||
417 | + else | ||
418 | + cpp_warning_at (pfile, CPP_W_BIDIRECTIONAL, &rich_loc, | ||
419 | + "unpaired UTF-8 bidirectional control character " | ||
420 | + "detected"); | ||
421 | } | ||
422 | /* We're done with this context. */ | ||
423 | bidi::on_close (); | ||
424 | @@ -1439,12 +1584,13 @@ maybe_warn_bidi_on_close (cpp_reader *pf | ||
425 | |||
426 | /* We're at the beginning or in the middle of an identifier/comment/string | ||
427 | literal/character constant. Warn if we've encountered a bidi character. | ||
428 | - KIND says which bidi character it was; P points to it in the character | ||
429 | - stream. UCN_P is true iff this bidi character was written as a UCN. */ | ||
430 | + KIND says which bidi control character it was; UCN_P is true iff this bidi | ||
431 | + control character was written as a UCN. LOC is the location of the | ||
432 | + character, but is only valid if KIND != bidi::kind::NONE. */ | ||
433 | |||
434 | static void | ||
435 | -maybe_warn_bidi_on_char (cpp_reader *pfile, const uchar *p, bidi::kind kind, | ||
436 | - bool ucn_p) | ||
437 | +maybe_warn_bidi_on_char (cpp_reader *pfile, bidi::kind kind, | ||
438 | + bool ucn_p, location_t loc) | ||
439 | { | ||
440 | if (__builtin_expect (kind == bidi::kind::NONE, 1)) | ||
441 | return; | ||
442 | @@ -1453,9 +1599,6 @@ maybe_warn_bidi_on_char (cpp_reader *pfi | ||
443 | |||
444 | if (warn_bidi != bidirectional_none) | ||
445 | { | ||
446 | - const location_t loc | ||
447 | - = linemap_position_for_column (pfile->line_table, | ||
448 | - CPP_BUF_COLUMN (pfile->buffer, p)); | ||
449 | rich_location rich_loc (pfile->line_table, loc); | ||
450 | rich_loc.set_escape_on_output (true); | ||
451 | |||
452 | @@ -1467,9 +1610,12 @@ maybe_warn_bidi_on_char (cpp_reader *pfi | ||
453 | { | ||
454 | if (warn_bidi == bidirectional_unpaired | ||
455 | && bidi::current_ctx_ucn_p () != ucn_p) | ||
456 | - cpp_warning_at (pfile, CPP_W_BIDIRECTIONAL, &rich_loc, | ||
457 | - "UTF-8 vs UCN mismatch when closing " | ||
458 | - "a context by \"%s\"", bidi::to_str (kind)); | ||
459 | + { | ||
460 | + rich_loc.add_range (bidi::current_ctx_loc ()); | ||
461 | + cpp_warning_at (pfile, CPP_W_BIDIRECTIONAL, &rich_loc, | ||
462 | + "UTF-8 vs UCN mismatch when closing " | ||
463 | + "a context by \"%s\"", bidi::to_str (kind)); | ||
464 | + } | ||
465 | } | ||
466 | else if (warn_bidi == bidirectional_any) | ||
467 | { | ||
468 | @@ -1484,7 +1630,7 @@ maybe_warn_bidi_on_char (cpp_reader *pfi | ||
469 | } | ||
470 | } | ||
471 | /* We're done with this context. */ | ||
472 | - bidi::on_char (kind, ucn_p); | ||
473 | + bidi::on_char (kind, ucn_p, loc); | ||
474 | } | ||
475 | |||
476 | /* Skip a C-style block comment. We find the end of the comment by | ||
477 | @@ -1552,8 +1698,9 @@ _cpp_skip_block_comment (cpp_reader *pfi | ||
478 | a bidirectional control character. */ | ||
479 | else if (__builtin_expect (c == bidi::utf8_start, 0) && warn_bidi_p) | ||
480 | { | ||
481 | - bidi::kind kind = get_bidi_utf8 (cur - 1); | ||
482 | - maybe_warn_bidi_on_char (pfile, cur, kind, /*ucn_p=*/false); | ||
483 | + location_t loc; | ||
484 | + bidi::kind kind = get_bidi_utf8 (pfile, cur - 1, &loc); | ||
485 | + maybe_warn_bidi_on_char (pfile, kind, /*ucn_p=*/false, loc); | ||
486 | } | ||
487 | } | ||
488 | |||
489 | @@ -1586,9 +1733,9 @@ skip_line_comment (cpp_reader *pfile) | ||
490 | { | ||
491 | if (__builtin_expect (*buffer->cur == bidi::utf8_start, 0)) | ||
492 | { | ||
493 | - bidi::kind kind = get_bidi_utf8 (buffer->cur); | ||
494 | - maybe_warn_bidi_on_char (pfile, buffer->cur, kind, | ||
495 | - /*ucn_p=*/false); | ||
496 | + location_t loc; | ||
497 | + bidi::kind kind = get_bidi_utf8 (pfile, buffer->cur, &loc); | ||
498 | + maybe_warn_bidi_on_char (pfile, kind, /*ucn_p=*/false, loc); | ||
499 | } | ||
500 | buffer->cur++; | ||
501 | } | ||
502 | @@ -1734,9 +1881,9 @@ forms_identifier_p (cpp_reader *pfile, i | ||
503 | if (__builtin_expect (*buffer->cur == bidi::utf8_start, 0) | ||
504 | && warn_bidi_p) | ||
505 | { | ||
506 | - bidi::kind kind = get_bidi_utf8 (buffer->cur); | ||
507 | - maybe_warn_bidi_on_char (pfile, buffer->cur, kind, | ||
508 | - /*ucn_p=*/false); | ||
509 | + location_t loc; | ||
510 | + bidi::kind kind = get_bidi_utf8 (pfile, buffer->cur, &loc); | ||
511 | + maybe_warn_bidi_on_char (pfile, kind, /*ucn_p=*/false, loc); | ||
512 | } | ||
513 | if (_cpp_valid_utf8 (pfile, &buffer->cur, buffer->rlimit, 1 + !first, | ||
514 | state, &s)) | ||
515 | @@ -1748,10 +1895,12 @@ forms_identifier_p (cpp_reader *pfile, i | ||
516 | buffer->cur += 2; | ||
517 | if (warn_bidi_p) | ||
518 | { | ||
519 | - bidi::kind kind = get_bidi_ucn (buffer->cur, | ||
520 | - buffer->cur[-1] == 'U'); | ||
521 | - maybe_warn_bidi_on_char (pfile, buffer->cur, kind, | ||
522 | - /*ucn_p=*/true); | ||
523 | + location_t loc; | ||
524 | + bidi::kind kind = get_bidi_ucn (pfile, | ||
525 | + buffer->cur, | ||
526 | + buffer->cur[-1] == 'U', | ||
527 | + &loc); | ||
528 | + maybe_warn_bidi_on_char (pfile, kind, /*ucn_p=*/true, loc); | ||
529 | } | ||
530 | if (_cpp_valid_ucn (pfile, &buffer->cur, buffer->rlimit, 1 + !first, | ||
531 | state, &s, NULL, NULL)) | ||
532 | @@ -2327,12 +2476,15 @@ lex_raw_string (cpp_reader *pfile, cpp_t | ||
533 | } | ||
534 | else if (__builtin_expect ((unsigned char) c == bidi::utf8_start, 0) | ||
535 | && warn_bidi_p) | ||
536 | - maybe_warn_bidi_on_char (pfile, pos - 1, get_bidi_utf8 (pos - 1), | ||
537 | - /*ucn_p=*/false); | ||
538 | + { | ||
539 | + location_t loc; | ||
540 | + bidi::kind kind = get_bidi_utf8 (pfile, cur - 1, &loc); | ||
541 | + maybe_warn_bidi_on_char (pfile, kind, /*ucn_p=*/false, loc); | ||
542 | + } | ||
543 | } | ||
544 | |||
545 | if (warn_bidi_p) | ||
546 | - maybe_warn_bidi_on_close (pfile, pos); | ||
547 | + maybe_warn_bidi_on_close (pfile, cur); | ||
548 | |||
549 | if (CPP_OPTION (pfile, user_literals)) | ||
550 | { | ||
551 | @@ -2438,8 +2590,10 @@ lex_string (cpp_reader *pfile, cpp_token | ||
552 | { | ||
553 | if ((cur[0] == 'u' || cur[0] == 'U') && warn_bidi_p) | ||
554 | { | ||
555 | - bidi::kind kind = get_bidi_ucn (cur + 1, cur[0] == 'U'); | ||
556 | - maybe_warn_bidi_on_char (pfile, cur, kind, /*ucn_p=*/true); | ||
557 | + location_t loc; | ||
558 | + bidi::kind kind = get_bidi_ucn (pfile, cur + 1, cur[0] == 'U', | ||
559 | + &loc); | ||
560 | + maybe_warn_bidi_on_char (pfile, kind, /*ucn_p=*/true, loc); | ||
561 | } | ||
562 | cur++; | ||
563 | } | ||
564 | @@ -2467,8 +2621,9 @@ lex_string (cpp_reader *pfile, cpp_token | ||
565 | saw_NUL = true; | ||
566 | else if (__builtin_expect (c == bidi::utf8_start, 0) && warn_bidi_p) | ||
567 | { | ||
568 | - bidi::kind kind = get_bidi_utf8 (cur - 1); | ||
569 | - maybe_warn_bidi_on_char (pfile, cur - 1, kind, /*ucn_p=*/false); | ||
570 | + location_t loc; | ||
571 | + bidi::kind kind = get_bidi_utf8 (pfile, cur - 1, &loc); | ||
572 | + maybe_warn_bidi_on_char (pfile, kind, /*ucn_p=*/false, loc); | ||
573 | } | ||
574 | } | ||
575 | |||