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