diff options
Diffstat (limited to 'meta')
| -rw-r--r-- | meta/recipes-devtools/gcc/gcc-15.1.inc | 1 | ||||
| -rw-r--r-- | meta/recipes-devtools/gcc/gcc/0026-fix-incorrect-preprocessor-line-numbers.patch | 475 |
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 | ||
| 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/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 @@ | |||
| 1 | From edf745dc519ddbfef127e2789bf11bfbacd300b7 Mon Sep 17 00:00:00 2001 | ||
| 2 | From: Jakub Jelinek <jakub@redhat.com> | ||
| 3 | Date: Wed, 7 May 2025 17:25:42 +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 | somewhere on the line where the #include actually is. | ||
| 52 | But at the same time it is also undesirable, because if we do decrement it, | ||
| 53 | then 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)))); | ||
| 66 | and we can end up with the new LC_ENTER ordinary map having the same | ||
| 67 | start_location as the preceding LC_RENAME one. | ||
| 68 | Next 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); | ||
| 79 | The normal case (e.g. with the testcase included at the start of this comment) is | ||
| 80 | that map[-1] starts somewhere earlier and so map->included_from computation above | ||
| 81 | nicely computes location_t which expands to the start of the #include line. | ||
| 82 | With r14-11679 reverted, for #c11 as well as #c12 | ||
| 83 | map[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, | ||
| 86 | which happens to be start of the #include line. | ||
| 87 | For #c11 map[0].start_location is 0x500003a0 and map[-1] has | ||
| 88 | m_column_and_range_bits 7 and map[-2] has m_column_and_range_bits 12 and | ||
| 89 | map[0].included_from is set to 0x50000320. | ||
| 90 | For #c12 map[0].start_location is 0x606c0402 and map[-2].start_location is | ||
| 91 | 0x606c0400 and m_column_and_range_bits is 0 for all 3 maps. | ||
| 92 | map[0].included_from is set to 0x606c0401. | ||
| 93 | The 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 | } | ||
| 106 | Here it wants to compute the right to_line which ought to be the line after | ||
| 107 | the #include directive. | ||
| 108 | On the #c11 testcase that doesn't work correctly though, because | ||
| 109 | map[-1].included_from is 0x50000320, from[0] for that is LC_ENTER with | ||
| 110 | start_location 0x4080 and m_column_and_range_bits 12 but note that we've | ||
| 111 | earlier computed map[-1].start_location + (-1 & 0xffffff80) and so only | ||
| 112 | decreased by 7 bits, so to_line is still on the line with #include and not | ||
| 113 | after it. In the #c12 that doesn't happen, all the ordinary maps involved | ||
| 114 | there had 0 m_column_and_range_bits and so this computes correct line. | ||
| 115 | |||
| 116 | Below is a fix for the trunk including testcases using the | ||
| 117 | location_overflow_plugin hack to simulate the bugs without needing huge | ||
| 118 | files (in the 14 case it is just 330KB and almost 10MB, but in the 15 | ||
| 119 | case it would need to be far bigger). | ||
| 120 | The pre- r15-9018 trunk has | ||
| 121 | FAIL: gcc.dg/plugin/location-overflow-test-pr116047.c -fplugin=./location_overflow_plugin.so scan-file static_assert[^\n\r]*6[^\n\r]*== 6 | ||
| 122 | and current trunk | ||
| 123 | FAIL: gcc.dg/plugin/location-overflow-test-pr116047.c -fplugin=./location_overflow_plugin.so scan-file static_assert[^\n\r]*6[^\n\r]*== 6 | ||
| 124 | FAIL: gcc.dg/plugin/location-overflow-test-pr120061.c -fplugin=./location_overflow_plugin.so scan-file static_assert[^\n\r]*5[^\n\r]*== 5 | ||
| 125 | and with the patch everything PASSes. | ||
| 126 | I'll post afterwards a 14 version of the patch. | ||
| 127 | |||
| 128 | The patch reverts the r15-9018 change, because it is incorrect, | ||
| 129 | we really need to decrement it even when crossing ordinary map | ||
| 130 | boundaries, so that the location is not on the line after the #include | ||
| 131 | line but somewhere on the #include line. It also patches two spots | ||
| 132 | in linemap_add mentioned above to make sure we get correct locations | ||
| 133 | both in the included_from location_t when doing LC_ENTER (second | ||
| 134 | line-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 | ||
| 136 | with the same start_location as the following LC_ENTER (i.e. the | ||
| 137 | problematic cases). | ||
| 138 | The LC_ENTER hunk is mostly to ensure included_form location_t is | ||
| 139 | at the start of the #include line (column 0), without it we can | ||
| 140 | decrease include_from not enough and end up at some random column | ||
| 141 | in the middle of the line, because it is masking away | ||
| 142 | map[-1].m_column_and_range_bits bits even when in the end the resulting | ||
| 143 | include_from location_t will be found in map[-2] map with perhaps | ||
| 144 | different m_column_and_range_bits. That alone doesn't fix the bug | ||
| 145 | though. | ||
| 146 | The more important is the LC_LEAVE hunk and the problem there is | ||
| 147 | caused by linemap_line_start not actually doing | ||
| 148 | r = set->highest_line + (line_delta << map->m_column_and_range_bits); | ||
| 149 | when adding a new map (the LC_RENAME one because we need to switch to | ||
| 150 | different number of directly encoded ranges, or columns, etc.). | ||
| 151 | So, in the original PR108900 case that | ||
| 152 | to_line = SOURCE_LINE (from, from[1].start_location); | ||
| 153 | doesn't do the right thing, from there is the last < 0x50000000 map | ||
| 154 | with m_column_and_range_bits 12, from[1] is the first one above it | ||
| 155 | and map[-1].included_from is the correct location of column 0 on | ||
| 156 | the #include line, but as the new LC_RENAME map has been created without | ||
| 157 | actually increasing highest_location to be on the new line (we've just | ||
| 158 | set to_line of the new LC_RENAME map to the correct line), | ||
| 159 | to_line = SOURCE_LINE (from, from[1].start_location); | ||
| 160 | stays 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; | ||
| 162 | i.e. just find out the #include line from map[-1].included_from and | ||
| 163 | add 1 to it, unfortunately that breaks the | ||
| 164 | c-c++-common/cpp/line-4.c | ||
| 165 | test 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 | ||
| 167 | and c-c++-common/analyzer/named-constants-via-macros-traditional.c tests | ||
| 168 | all with -traditional-cpp preprocessing where to_line is also off-by-one | ||
| 169 | from the expected one. | ||
| 170 | So, this patch instead conditionalizes it, uses the | ||
| 171 | to_line = SOURCE_LINE (from, linemap_included_from (map - 1)) + 1; | ||
| 172 | way only if from[1] is a LC_RENAME map (rather than the usual | ||
| 173 | LC_ENTER one), that should limit it to the problematic cases of when | ||
| 174 | parse_include peeked after EOL and had to create LC_RENAME map with | ||
| 175 | the same start_location as the LC_ENTER after it. | ||
| 176 | |||
| 177 | Some further justification for the LC_ENTER hunk, using the | ||
| 178 | https://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) | ||
| 180 | I get | ||
| 181 | $ /usr/src/gcc-14/obj/gcc/cc1.old -quiet -std=c23 pr116047.c -nostdinc | ||
| 182 | In file included from pr116047-1.h:327677:21, | ||
| 183 | from pr116047.c:4: | ||
| 184 | pr116047-2.h:1:1: error: unknown type name ‘a’ | ||
| 185 | 1 | a b c; | ||
| 186 | | ^ | ||
| 187 | pr116047-2.h:1:5: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘c’ | ||
| 188 | 1 | a b c; | ||
| 189 | | ^ | ||
| 190 | pr116047-1.h:327677:1: error: static assertion failed: "" | ||
| 191 | 327677 | #include "pr116047-2.h" | ||
| 192 | | ^~~~~~~~~~~~~ | ||
| 193 | $ /usr/src/gcc-14/obj/gcc/cc1.vanilla -quiet -std=c23 pr116047.c -nostdinc | ||
| 194 | In file included from pr116047-1.h:327678, | ||
| 195 | from pr116047.c:4: | ||
| 196 | pr116047-2.h:1:1: error: unknown type name ‘a’ | ||
| 197 | 1 | a b c; | ||
| 198 | | ^ | ||
| 199 | pr116047-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 | ||
| 203 | In file included from pr116047-1.h:327677, | ||
| 204 | from pr116047.c:4: | ||
| 205 | pr116047-2.h:1:1: error: unknown type name ‘a’ | ||
| 206 | 1 | a b c; | ||
| 207 | | ^ | ||
| 208 | pr116047-2.h:1:5: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘c’ | ||
| 209 | 1 | a b c; | ||
| 210 | | ^ | ||
| 211 | |||
| 212 | pr116047-1.h has on lines 327677+327678: | ||
| 213 | #include "pr116047-2.h" | ||
| 214 | static_assert (__LINE__ == 327678, ""); | ||
| 215 | so the static_assert failure is something that was dealt mainly in the | ||
| 216 | LC_LEAVE hunk and files.cc reversion, but please have a look at the | ||
| 217 | In file included from lines. | ||
| 218 | 14.2 emits correct line (#include "pr116047-2.h" is indeed on line | ||
| 219 | 327677) but some random column in there (which is not normally printed | ||
| 220 | for smaller headers; 21 is the . before extension in the filename). | ||
| 221 | Current trunk emits incorrect line (327678 instead of 327677, clearly | ||
| 222 | it didn't decrement). | ||
| 223 | And the patched compiler emits the right line with no column, as would | ||
| 224 | be printed if I remove e.g. 300000 newlines from the file. | ||
| 225 | |||
| 226 | 2025-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 | |||
| 251 | Upstream-Status: Backport [https://gcc.gnu.org/cgit/gcc/commit/?id=edf745dc519ddbfef127e2789bf11bfbacd300b7] | ||
| 252 | Signed-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 | |||
| 272 | 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 | ||
| 273 | new file mode 100644 | ||
| 274 | index 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, ""); | ||
| 284 | 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 | ||
| 285 | new file mode 100644 | ||
| 286 | index 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; | ||
| 291 | diff --git a/gcc/testsuite/gcc.dg/plugin/location-overflow-test-pr116047.c b/gcc/testsuite/gcc.dg/plugin/location-overflow-test-pr116047.c | ||
| 292 | new file mode 100644 | ||
| 293 | index 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" } } */ | ||
| 302 | 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 | ||
| 303 | new file mode 100644 | ||
| 304 | index 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 | + | ||
| 314 | 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 | ||
| 315 | new file mode 100644 | ||
| 316 | index 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; | ||
| 321 | diff --git a/gcc/testsuite/gcc.dg/plugin/location-overflow-test-pr120061.c b/gcc/testsuite/gcc.dg/plugin/location-overflow-test-pr120061.c | ||
| 322 | new file mode 100644 | ||
| 323 | index 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" } } */ | ||
| 333 | diff --git a/gcc/testsuite/gcc.dg/plugin/location_overflow_plugin.cc b/gcc/testsuite/gcc.dg/plugin/location_overflow_plugin.cc | ||
| 334 | index 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; | ||
| 367 | diff --git a/gcc/testsuite/gcc.dg/plugin/plugin.exp b/gcc/testsuite/gcc.dg/plugin/plugin.exp | ||
| 368 | index 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 } \ | ||
| 382 | diff --git a/libcpp/files.cc b/libcpp/files.cc | ||
| 383 | index 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 | |||
| 401 | diff --git a/libcpp/line-map.cc b/libcpp/line-map.cc | ||
| 402 | index 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 | |||
