summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--meta/recipes-devtools/gcc/gcc-15.1.inc1
-rw-r--r--meta/recipes-devtools/gcc/gcc/0026-fix-incorrect-preprocessor-line-numbers.patch475
2 files changed, 476 insertions, 0 deletions
diff --git a/meta/recipes-devtools/gcc/gcc-15.1.inc b/meta/recipes-devtools/gcc/gcc-15.1.inc
index 0e6ae67c8b..0032500cdc 100644
--- a/meta/recipes-devtools/gcc/gcc-15.1.inc
+++ b/meta/recipes-devtools/gcc/gcc-15.1.inc
@@ -72,6 +72,7 @@ SRC_URI = "${BASEURI} \
72 file://0024-Avoid-hardcoded-build-paths-into-ppc-libgcc.patch \ 72 file://0024-Avoid-hardcoded-build-paths-into-ppc-libgcc.patch \
73 file://0025-gcc-testsuite-tweaks-for-mips-OE.patch \ 73 file://0025-gcc-testsuite-tweaks-for-mips-OE.patch \
74 file://0026-arm-fully-validate-mem_noofs_operand-PR120351.patch \ 74 file://0026-arm-fully-validate-mem_noofs_operand-PR120351.patch \
75 file://0026-fix-incorrect-preprocessor-line-numbers.patch \
75" 76"
76 77
77S = "${TMPDIR}/work-shared/gcc-${PV}-${PR}/${SOURCEDIR}" 78S = "${TMPDIR}/work-shared/gcc-${PV}-${PR}/${SOURCEDIR}"
diff --git a/meta/recipes-devtools/gcc/gcc/0026-fix-incorrect-preprocessor-line-numbers.patch b/meta/recipes-devtools/gcc/gcc/0026-fix-incorrect-preprocessor-line-numbers.patch
new file mode 100644
index 0000000000..f799085662
--- /dev/null
+++ b/meta/recipes-devtools/gcc/gcc/0026-fix-incorrect-preprocessor-line-numbers.patch
@@ -0,0 +1,475 @@
1From edf745dc519ddbfef127e2789bf11bfbacd300b7 Mon Sep 17 00:00:00 2001
2From: Jakub Jelinek <jakub@redhat.com>
3Date: Wed, 7 May 2025 17:25:42 +0200
4Subject: libcpp: Further fixes for incorrect line numbers in large files
5 [PR120061]
6MIME-Version: 1.0
7Content-Type: text/plain; charset=UTF-8
8Content-Transfer-Encoding: 8bit
9
10The backport of the PR108900 fix to 14 branch broke building chromium
11because static_assert (__LINE__ == expected_line_number, ""); now triggers
12as the __LINE__ values are off by one.
13This isn't the case on the trunk and 15 branch because we've switched
14to 64-bit location_t and so one actually needs far longer header files
15to trigger it.
16https://gcc.gnu.org/bugzilla/show_bug.cgi?id=120061#c11
17https://gcc.gnu.org/bugzilla/show_bug.cgi?id=120061#c12
18contain (large) testcases in patch form which show on the 14 branch
19that the first one used to fail before the PR108900 backport and now
20works correctly, while the second one attempts to match the chromium
21behavior and it used to pass before the PR108900 backport and now it
22FAILs.
23The two testcases show rare problematic cases, because
24do_include_common -> parse_include -> check_eol -> check_eol_1 ->
25cpp_get_token_1 -> _cpp_lex_token -> _cpp_lex_direct -> linemap_line_start
26triggers there
27 /* Allocate the new line_map. However, if the current map only has a
28 single line we can sometimes just increase its column_bits instead. */
29 if (line_delta < 0
30 || last_line != ORDINARY_MAP_STARTING_LINE_NUMBER (map)
31 || SOURCE_COLUMN (map, highest) >= (1U << (column_bits - range_bits))
32 || ( /* We can't reuse the map if the line offset is sufficiently
33 large to cause overflow when computing location_t values. */
34 (to_line - ORDINARY_MAP_STARTING_LINE_NUMBER (map))
35 >= (((uint64_t) 1)
36 << (CHAR_BIT * sizeof (linenum_type) - column_bits)))
37 || range_bits < map->m_range_bits)
38 map = linemap_check_ordinary
39 (const_cast <line_map *>
40 (linemap_add (set, LC_RENAME,
41 ORDINARY_MAP_IN_SYSTEM_HEADER_P (map),
42 ORDINARY_MAP_FILE_NAME (map),
43 to_line)));
44and so creates a new ordinary map on the line right after the
45(problematic) #include line.
46Now, in the spot that r14-11679-g8a884140c2bcb7 patched,
47pfile->line_table->highest_location in all 3 tests (also
48https://gcc.gnu.org/bugzilla/show_bug.cgi?id=120061#c13
49) is before the decrement the start of the line after the #include line and so
50the decrement is really desirable in that case to put highest_location
51somewhere on the line where the #include actually is.
52But at the same time it is also undesirable, because if we do decrement it,
53then linemap_add LC_ENTER called from _cpp_do_file_change will then
54 /* Generate a start_location above the current highest_location.
55 If possible, make the low range bits be zero. */
56 location_t start_location = set->highest_location + 1;
57 unsigned range_bits = 0;
58 if (start_location < LINE_MAP_MAX_LOCATION_WITH_COLS)
59 range_bits = set->default_range_bits;
60 start_location += (1 << range_bits) - 1;
61 start_location &= ~((1 << range_bits) - 1);
62
63 linemap_assert (!LINEMAPS_ORDINARY_USED (set)
64 || (start_location
65 >= MAP_START_LOCATION (LINEMAPS_LAST_ORDINARY_MAP (set))));
66and we can end up with the new LC_ENTER ordinary map having the same
67start_location as the preceding LC_RENAME one.
68Next thing that happens is computation of included_from:
69 if (reason == LC_ENTER)
70 {
71 if (set->depth == 0)
72 map->included_from = 0;
73 else
74 /* The location of the end of the just-closed map. */
75 map->included_from
76 = (((map[0].start_location - 1 - map[-1].start_location)
77 & ~((1 << map[-1].m_column_and_range_bits) - 1))
78 + map[-1].start_location);
79The normal case (e.g. with the testcase included at the start of this comment) is
80that map[-1] starts somewhere earlier and so map->included_from computation above
81nicely computes location_t which expands to the start of the #include line.
82With r14-11679 reverted, for #c11 as well as #c12
83map[0].start_location == map[-1].start_location above, and so it is
84((location_t) -1 & ~((1 << map[-1].m_column_and_range_bits) - 1)))
85+ map[-1].start_location,
86which happens to be start of the #include line.
87For #c11 map[0].start_location is 0x500003a0 and map[-1] has
88m_column_and_range_bits 7 and map[-2] has m_column_and_range_bits 12 and
89map[0].included_from is set to 0x50000320.
90For #c12 map[0].start_location is 0x606c0402 and map[-2].start_location is
910x606c0400 and m_column_and_range_bits is 0 for all 3 maps.
92map[0].included_from is set to 0x606c0401.
93The last important part is again in linemap_add when doing LC_LEAVE:
94 /* (MAP - 1) points to the map we are leaving. The
95 map from which (MAP - 1) got included should be the map
96 that comes right before MAP in the same file. */
97 from = linemap_included_from_linemap (set, map - 1);
98
99 /* A TO_FILE of NULL is special - we use the natural values. */
100 if (to_file == NULL)
101 {
102 to_file = ORDINARY_MAP_FILE_NAME (from);
103 to_line = SOURCE_LINE (from, from[1].start_location);
104 sysp = ORDINARY_MAP_IN_SYSTEM_HEADER_P (from);
105 }
106Here it wants to compute the right to_line which ought to be the line after
107the #include directive.
108On the #c11 testcase that doesn't work correctly though, because
109map[-1].included_from is 0x50000320, from[0] for that is LC_ENTER with
110start_location 0x4080 and m_column_and_range_bits 12 but note that we've
111earlier computed map[-1].start_location + (-1 & 0xffffff80) and so only
112decreased by 7 bits, so to_line is still on the line with #include and not
113after it. In the #c12 that doesn't happen, all the ordinary maps involved
114there had 0 m_column_and_range_bits and so this computes correct line.
115
116Below is a fix for the trunk including testcases using the
117location_overflow_plugin hack to simulate the bugs without needing huge
118files (in the 14 case it is just 330KB and almost 10MB, but in the 15
119case it would need to be far bigger).
120The pre- r15-9018 trunk has
121FAIL: gcc.dg/plugin/location-overflow-test-pr116047.c -fplugin=./location_overflow_plugin.so scan-file static_assert[^\n\r]*6[^\n\r]*== 6
122and current trunk
123FAIL: gcc.dg/plugin/location-overflow-test-pr116047.c -fplugin=./location_overflow_plugin.so scan-file static_assert[^\n\r]*6[^\n\r]*== 6
124FAIL: gcc.dg/plugin/location-overflow-test-pr120061.c -fplugin=./location_overflow_plugin.so scan-file static_assert[^\n\r]*5[^\n\r]*== 5
125and with the patch everything PASSes.
126I'll post afterwards a 14 version of the patch.
127
128The patch reverts the r15-9018 change, because it is incorrect,
129we really need to decrement it even when crossing ordinary map
130boundaries, so that the location is not on the line after the #include
131line but somewhere on the #include line. It also patches two spots
132in linemap_add mentioned above to make sure we get correct locations
133both in the included_from location_t when doing LC_ENTER (second
134line-map.cc hunk) and when doing LC_LEAVE to compute the right to_line
135(first line-map.cc hunk), both in presence of an added LC_RENAME
136with the same start_location as the following LC_ENTER (i.e. the
137problematic cases).
138The LC_ENTER hunk is mostly to ensure included_form location_t is
139at the start of the #include line (column 0), without it we can
140decrease include_from not enough and end up at some random column
141in the middle of the line, because it is masking away
142map[-1].m_column_and_range_bits bits even when in the end the resulting
143include_from location_t will be found in map[-2] map with perhaps
144different m_column_and_range_bits. That alone doesn't fix the bug
145though.
146The more important is the LC_LEAVE hunk and the problem there is
147caused by linemap_line_start not actually doing
148 r = set->highest_line + (line_delta << map->m_column_and_range_bits);
149when adding a new map (the LC_RENAME one because we need to switch to
150different number of directly encoded ranges, or columns, etc.).
151So, in the original PR108900 case that
152 to_line = SOURCE_LINE (from, from[1].start_location);
153doesn't do the right thing, from there is the last < 0x50000000 map
154with m_column_and_range_bits 12, from[1] is the first one above it
155and map[-1].included_from is the correct location of column 0 on
156the #include line, but as the new LC_RENAME map has been created without
157actually increasing highest_location to be on the new line (we've just
158set to_line of the new LC_RENAME map to the correct line),
159 to_line = SOURCE_LINE (from, from[1].start_location);
160stays on the same source line. I've tried to just replace that with
161 to_line = SOURCE_LINE (from, linemap_included_from (map - 1)) + 1;
162i.e. just find out the #include line from map[-1].included_from and
163add 1 to it, unfortunately that breaks the
164c-c++-common/cpp/line-4.c
165test where we expect to stay on the same 0 line for LC_LEAVE from
166<command line> and gcc.dg/cpp/trad/Wunused.c, gcc.dg/cpp/trad/builtins.c
167and c-c++-common/analyzer/named-constants-via-macros-traditional.c tests
168all with -traditional-cpp preprocessing where to_line is also off-by-one
169from the expected one.
170So, this patch instead conditionalizes it, uses the
171 to_line = SOURCE_LINE (from, linemap_included_from (map - 1)) + 1;
172way only if from[1] is a LC_RENAME map (rather than the usual
173LC_ENTER one), that should limit it to the problematic cases of when
174parse_include peeked after EOL and had to create LC_RENAME map with
175the same start_location as the LC_ENTER after it.
176
177Some further justification for the LC_ENTER hunk, using the
178https://gcc.gnu.org/pipermail/gcc-patches/2025-May/682774.html testcase
179(old is 14 before r14-11679, vanilla current 14 and new with the 14 patch)
180I get
181$ /usr/src/gcc-14/obj/gcc/cc1.old -quiet -std=c23 pr116047.c -nostdinc
182In file included from pr116047-1.h:327677:21,
183 from pr116047.c:4:
184pr116047-2.h:1:1: error: unknown type name ‘a’
185 1 | a b c;
186 | ^
187pr116047-2.h:1:5: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘c’
188 1 | a b c;
189 | ^
190pr116047-1.h:327677:1: error: static assertion failed: ""
191327677 | #include "pr116047-2.h"
192 | ^~~~~~~~~~~~~
193$ /usr/src/gcc-14/obj/gcc/cc1.vanilla -quiet -std=c23 pr116047.c -nostdinc
194In file included from pr116047-1.h:327678,
195 from pr116047.c:4:
196pr116047-2.h:1:1: error: unknown type name ‘a’
197 1 | a b c;
198 | ^
199pr116047-2.h:1:5: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘c’
200 1 | a b c;
201 | ^
202$ /usr/src/gcc-14/obj/gcc/cc1.new -quiet -std=c23 pr116047.c -nostdinc
203In file included from pr116047-1.h:327677,
204 from pr116047.c:4:
205pr116047-2.h:1:1: error: unknown type name ‘a’
206 1 | a b c;
207 | ^
208pr116047-2.h:1:5: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘c’
209 1 | a b c;
210 | ^
211
212pr116047-1.h has on lines 327677+327678:
213 #include "pr116047-2.h"
214 static_assert (__LINE__ == 327678, "");
215so the static_assert failure is something that was dealt mainly in the
216LC_LEAVE hunk and files.cc reversion, but please have a look at the
217In file included from lines.
21814.2 emits correct line (#include "pr116047-2.h" is indeed on line
219327677) but some random column in there (which is not normally printed
220for smaller headers; 21 is the . before extension in the filename).
221Current trunk emits incorrect line (327678 instead of 327677, clearly
222it didn't decrement).
223And the patched compiler emits the right line with no column, as would
224be printed if I remove e.g. 300000 newlines from the file.
225
2262025-05-07 Jakub Jelinek <jakub@redhat.com>
227
228 PR preprocessor/108900
229 PR preprocessor/116047
230 PR preprocessor/120061
231 * files.cc (_cpp_stack_file): Revert 2025-03-28 change.
232 * line-map.cc (linemap_add): Use
233 SOURCE_LINE (from, linemap_included_from (map - 1)) + 1; instead of
234 SOURCE_LINE (from, from[1].start_location); to compute to_line
235 for LC_LEAVE. For LC_ENTER included_from computation, look at
236 map[-2] or even lower if map[-1] has the same start_location as
237 map[0].
238
239 * gcc.dg/plugin/plugin.exp: Add location-overflow-test-pr116047.c
240 and location-overflow-test-pr120061.c.
241 * gcc.dg/plugin/location_overflow_plugin.cc (plugin_init): Don't error
242 on unknown values, instead just break. Handle 0x4fHHHHHH arguments
243 differently.
244 * gcc.dg/plugin/location-overflow-test-pr116047.c: New test.
245 * gcc.dg/plugin/location-overflow-test-pr116047-1.h: New test.
246 * gcc.dg/plugin/location-overflow-test-pr116047-2.h: New test.
247 * gcc.dg/plugin/location-overflow-test-pr120061.c: New test.
248 * gcc.dg/plugin/location-overflow-test-pr120061-1.h: New test.
249 * gcc.dg/plugin/location-overflow-test-pr120061-2.h: New test.
250
251Upstream-Status: Backport [https://gcc.gnu.org/cgit/gcc/commit/?id=edf745dc519ddbfef127e2789bf11bfbacd300b7]
252Signed-off-by: Yash Shinde <Yash.Shinde@windriver.com>
253---
254 .../plugin/location-overflow-test-pr116047-1.h | 6 +++
255 .../plugin/location-overflow-test-pr116047-2.h | 1 +
256 .../plugin/location-overflow-test-pr116047.c | 5 +++
257 .../plugin/location-overflow-test-pr120061-1.h | 6 +++
258 .../plugin/location-overflow-test-pr120061-2.h | 1 +
259 .../plugin/location-overflow-test-pr120061.c | 6 +++
260 .../gcc.dg/plugin/location_overflow_plugin.cc | 15 +++++--
261 gcc/testsuite/gcc.dg/plugin/plugin.exp | 4 +-
262 libcpp/files.cc | 8 ----
263 libcpp/line-map.cc | 48 ++++++++++++++++++----
264 10 files changed, 80 insertions(+), 20 deletions(-)
265 create mode 100644 gcc/testsuite/gcc.dg/plugin/location-overflow-test-pr116047-1.h
266 create mode 100644 gcc/testsuite/gcc.dg/plugin/location-overflow-test-pr116047-2.h
267 create mode 100644 gcc/testsuite/gcc.dg/plugin/location-overflow-test-pr116047.c
268 create mode 100644 gcc/testsuite/gcc.dg/plugin/location-overflow-test-pr120061-1.h
269 create mode 100644 gcc/testsuite/gcc.dg/plugin/location-overflow-test-pr120061-2.h
270 create mode 100644 gcc/testsuite/gcc.dg/plugin/location-overflow-test-pr120061.c
271
272diff --git a/gcc/testsuite/gcc.dg/plugin/location-overflow-test-pr116047-1.h b/gcc/testsuite/gcc.dg/plugin/location-overflow-test-pr116047-1.h
273new file mode 100644
274index 000000000000..3dd6434a938b
275--- /dev/null
276+++ b/gcc/testsuite/gcc.dg/plugin/location-overflow-test-pr116047-1.h
277@@ -0,0 +1,6 @@
278+
279+
280+
281+
282+#include "location-overflow-test-pr116047-2.h"
283+static_assert (__LINE__ == 6, "");
284diff --git a/gcc/testsuite/gcc.dg/plugin/location-overflow-test-pr116047-2.h b/gcc/testsuite/gcc.dg/plugin/location-overflow-test-pr116047-2.h
285new file mode 100644
286index 000000000000..048f715b4656
287--- /dev/null
288+++ b/gcc/testsuite/gcc.dg/plugin/location-overflow-test-pr116047-2.h
289@@ -0,0 +1 @@
290+int i;
291diff --git a/gcc/testsuite/gcc.dg/plugin/location-overflow-test-pr116047.c b/gcc/testsuite/gcc.dg/plugin/location-overflow-test-pr116047.c
292new file mode 100644
293index 000000000000..75161fa5f055
294--- /dev/null
295+++ b/gcc/testsuite/gcc.dg/plugin/location-overflow-test-pr116047.c
296@@ -0,0 +1,5 @@
297+/* PR preprocessor/116047 */
298+/* { dg-do preprocess } */
299+/* { dg-options "-nostdinc -std=c23 -fplugin-arg-location_overflow_plugin-value=0x4ffe0180" } */
300+#include "location-overflow-test-pr116047-1.h"
301+/* { dg-final { scan-file location-overflow-test-pr116047.i "static_assert\[^\n\r]\*6\[^\n\r]\*== 6" } } */
302diff --git a/gcc/testsuite/gcc.dg/plugin/location-overflow-test-pr120061-1.h b/gcc/testsuite/gcc.dg/plugin/location-overflow-test-pr120061-1.h
303new file mode 100644
304index 000000000000..ebf7704f568e
305--- /dev/null
306+++ b/gcc/testsuite/gcc.dg/plugin/location-overflow-test-pr120061-1.h
307@@ -0,0 +1,6 @@
308+
309+
310+
311+
312+#include "location-overflow-test-pr120061-2.h"
313+
314diff --git a/gcc/testsuite/gcc.dg/plugin/location-overflow-test-pr120061-2.h b/gcc/testsuite/gcc.dg/plugin/location-overflow-test-pr120061-2.h
315new file mode 100644
316index 000000000000..048f715b4656
317--- /dev/null
318+++ b/gcc/testsuite/gcc.dg/plugin/location-overflow-test-pr120061-2.h
319@@ -0,0 +1 @@
320+int i;
321diff --git a/gcc/testsuite/gcc.dg/plugin/location-overflow-test-pr120061.c b/gcc/testsuite/gcc.dg/plugin/location-overflow-test-pr120061.c
322new file mode 100644
323index 000000000000..e8e803898da3
324--- /dev/null
325+++ b/gcc/testsuite/gcc.dg/plugin/location-overflow-test-pr120061.c
326@@ -0,0 +1,6 @@
327+/* PR preprocessor/120061 */
328+/* { dg-do preprocess } */
329+/* { dg-options "-nostdinc -std=c23 -fplugin-arg-location_overflow_plugin-value=0x61000000" } */
330+#include "location-overflow-test-pr120061-1.h"
331+static_assert (__LINE__ == 5, "");
332+/* { dg-final { scan-file location-overflow-test-pr120061.i "static_assert\[^\n\r]\*5\[^\n\r]\*== 5" } } */
333diff --git a/gcc/testsuite/gcc.dg/plugin/location_overflow_plugin.cc b/gcc/testsuite/gcc.dg/plugin/location_overflow_plugin.cc
334index f731b1421b0f..f770d35ea518 100644
335--- a/gcc/testsuite/gcc.dg/plugin/location_overflow_plugin.cc
336+++ b/gcc/testsuite/gcc.dg/plugin/location_overflow_plugin.cc
337@@ -85,9 +85,18 @@ plugin_init (struct plugin_name_args *plugin_info,
338 error_at (UNKNOWN_LOCATION, "missing plugin argument");
339
340 /* With 64-bit locations, the thresholds are larger, so shift the base
341- location argument accordingly. */
342+ location argument accordingly, basically remap the GCC 14 32-bit
343+ location_t argument values to 64-bit location_t counterparts. There
344+ is one exception for values slightly before the 32-bit location_t
345+ LINE_MAP_MAX_LOCATION_WITH_PACKED_RANGES (0x50000000). In that case
346+ remap them to the same amount before the 64-bit location_t
347+ LINE_MAP_MAX_LOCATION_WITH_PACKED_RANGES -
348+ ((location_t) 0x50000000) << 31. */
349 gcc_assert (sizeof (location_t) == sizeof (uint64_t));
350- base_location = 1 + ((base_location - 1) << 31);
351+ if (base_location >= 0x4f000000 && base_location <= 0x4fffffff)
352+ base_location += (((location_t) 0x50000000) << 31) - 0x50000000;
353+ else
354+ base_location = 1 + ((base_location - 1) << 31);
355
356 register_callback (plugin_info->base_name,
357 PLUGIN_PRAGMAS,
358@@ -107,7 +116,7 @@ plugin_init (struct plugin_name_args *plugin_info,
359 break;
360
361 default:
362- error_at (UNKNOWN_LOCATION, "unrecognized value for plugin argument");
363+ break;
364 }
365
366 return 0;
367diff --git a/gcc/testsuite/gcc.dg/plugin/plugin.exp b/gcc/testsuite/gcc.dg/plugin/plugin.exp
368index 90c91621d0aa..96e76d2e0c36 100644
369--- a/gcc/testsuite/gcc.dg/plugin/plugin.exp
370+++ b/gcc/testsuite/gcc.dg/plugin/plugin.exp
371@@ -138,7 +138,9 @@ set plugin_test_list [list \
372 { location_overflow_plugin.cc \
373 location-overflow-test-1.c \
374 location-overflow-test-2.c \
375- location-overflow-test-pr83173.c } \
376+ location-overflow-test-pr83173.c \
377+ location-overflow-test-pr116047.c \
378+ location-overflow-test-pr120061.c } \
379 { must_tail_call_plugin.cc \
380 must-tail-call-1.c \
381 must-tail-call-2.c } \
382diff --git a/libcpp/files.cc b/libcpp/files.cc
383index c1abde6639fe..d80c4bfd9077 100644
384--- a/libcpp/files.cc
385+++ b/libcpp/files.cc
386@@ -1047,14 +1047,6 @@ _cpp_stack_file (cpp_reader *pfile, _cpp_file *file, include_type type,
387 && (pfile->line_table->highest_location
388 != LINE_MAP_MAX_LOCATION - 1));
389
390- if (decrement && LINEMAPS_ORDINARY_USED (pfile->line_table))
391- {
392- const line_map_ordinary *map
393- = LINEMAPS_LAST_ORDINARY_MAP (pfile->line_table);
394- if (map && map->start_location == pfile->line_table->highest_location)
395- decrement = false;
396- }
397-
398 if (decrement)
399 pfile->line_table->highest_location--;
400
401diff --git a/libcpp/line-map.cc b/libcpp/line-map.cc
402index 17e7f12551c0..cf6557117c81 100644
403--- a/libcpp/line-map.cc
404+++ b/libcpp/line-map.cc
405@@ -621,8 +621,8 @@ linemap_add (line_maps *set, enum lc_reason reason,
406 #include "included", inside the same "includer" file. */
407
408 linemap_assert (!MAIN_FILE_P (map - 1));
409- /* (MAP - 1) points to the map we are leaving. The
410- map from which (MAP - 1) got included should be the map
411+ /* (MAP - 1) points to the map we are leaving. The
412+ map from which (MAP - 1) got included should be usually the map
413 that comes right before MAP in the same file. */
414 from = linemap_included_from_linemap (set, map - 1);
415
416@@ -630,7 +630,24 @@ linemap_add (line_maps *set, enum lc_reason reason,
417 if (to_file == NULL)
418 {
419 to_file = ORDINARY_MAP_FILE_NAME (from);
420- to_line = SOURCE_LINE (from, from[1].start_location);
421+ /* Compute the line on which the map resumes, for #include this
422+ should be the line after the #include line. Usually FROM is
423+ the map right before LC_ENTER map - the first map of the included
424+ file, and in that case SOURCE_LINE (from, from[1].start_location);
425+ computes the right line (and does handle even some special cases
426+ (e.g. where for returning from <command line> we still want to
427+ be at line 0 or some -traditional-cpp cases). In rare cases
428+ FROM can be followed by LC_RENAME created by linemap_line_start
429+ for line right after #include line. If that happens,
430+ start_location of the FROM[1] map will be the same as
431+ start_location of FROM[2] LC_ENTER, but FROM[1] start_location
432+ might not have advance enough for moving to a full next line.
433+ In that case compute the line of #include line and add 1 to it
434+ to advance to the next line. See PR120061. */
435+ if (from[1].reason == LC_RENAME)
436+ to_line = SOURCE_LINE (from, linemap_included_from (map - 1)) + 1;
437+ else
438+ to_line = SOURCE_LINE (from, from[1].start_location);
439 sysp = ORDINARY_MAP_IN_SYSTEM_HEADER_P (from);
440 }
441 else
442@@ -660,11 +677,26 @@ linemap_add (line_maps *set, enum lc_reason reason,
443 if (set->depth == 0)
444 map->included_from = 0;
445 else
446- /* The location of the end of the just-closed map. */
447- map->included_from
448- = (((map[0].start_location - 1 - map[-1].start_location)
449- & ~((loc_one << map[-1].m_column_and_range_bits) - 1))
450- + map[-1].start_location);
451+ {
452+ /* Compute location from whence this line map was included.
453+ For #include this should be preferrably column 0 of the
454+ line on which #include directive appears.
455+ map[-1] is the just closed map and usually included_from
456+ falls within that map. In rare cases linemap_line_start
457+ can insert a new LC_RENAME map for the line immediately
458+ after #include line, in that case map[-1] will have the
459+ same start_location as the new one and so included_from
460+ would not be from map[-1] but likely map[-2]. If that
461+ happens, mask off map[-2] m_column_and_range_bits bits
462+ instead of map[-1]. See PR120061. */
463+ int i = -1;
464+ while (map[i].start_location == map[0].start_location)
465+ --i;
466+ map->included_from
467+ = (((map[0].start_location - 1 - map[i].start_location)
468+ & ~((loc_one << map[i].m_column_and_range_bits) - 1))
469+ + map[i].start_location);
470+ }
471 set->depth++;
472 if (set->trace_includes)
473 trace_include (set, map);
474--
475