aboutsummaryrefslogtreecommitdiff
path: root/gcc
AgeCommit message (Collapse)AuthorFilesLines
9 days[PATCH] PR modula2/120188: documented example does not work assignvalue m2pluginGaius Mulley4-2/+87
This patch corrects the gm2 command line used in the documentation to invoke the m2-plugin. The patch also includes the documentation example in dejagnu test code with an expect script to check whether plugins were enabled. gcc/ChangeLog: PR modula2/120188 * doc/gm2.texi (Semantic checking): Add -fm2-plugin command line option. gcc/testsuite/ChangeLog: PR modula2/120188 * lib/gm2-dg.exp (gm2-dg-frontend-configure-check): New function. (gm2-dg-runtest): Add -O2 to the option_list. * gm2.dg/doc/examples/plugin/fail/assignvalue.mod: New test. * gm2.dg/doc/examples/plugin/fail/doc-examples-plugin-fail.exp: New test. (cherry picked from commit 9ce4c801e8275fcf0336ae2fb548f6ebb3ca068b) Signed-off-by: Gaius Mulley <gaiusmod2@gmail.com>
9 dayslibfortran: Fix up _gfortran_{,m,s}findloc2_s{1,4} [PR120196]Jakub Jelinek1-0/+26
As mentioned in the PR, _gfortran_{,m,s}findloc2_s{1,4} iterate too many times in the back case if nothing is found. For !back, the loops are for (i = 1; i <= extent; i++) so i is in the body [1, extent] if nothing is found, but for back it is for (i = extent; i >= 0; i--) so i is in the body [0, extent] and compares one element before the start of the array. Note, findloc1_s{1,4} uses for (n = len; n > 0; n--, src -= delta * len_array) for the back loop and for (n = 1; n <= len; n++, src += delta * len_array) for !back. This patch fixes that. The testcase fails under valgrind without the libgfortran changes and succeeds with those. 2025-05-13 Jakub Jelinek <jakub@redhat.com> PR libfortran/120196 * m4/ifindloc2.m4 (header1, header2): For back use i > 0 rather than i >= 0 as for condition. * generated/findloc2_s1.c: Regenerate. * generated/findloc2_s4.c: Regenerate. * gfortran.dg/pr120196.f90: New test. (cherry picked from commit 748a7bc4624e7b000f6fdb93a8cf7da73ff193bb)
9 dayslibfortran: Fix up _gfortran_s{max,min}loc1_{4,8,16}_s{1,4} [PR120191]Jakub Jelinek1-0/+23
There is a bug in _gfortran_s{max,min}loc1_{4,8,16}_s{1,4} which the following testcase shows. The functions return but then crash in the caller. Seems that is because buffer overflows, I believe those functions for if (mask == NULL || *mask) condition being false are supposed to fill in the result array with all zeros (or allocate it and fill it with zeros). My understanding is the result array in that case is integer(kind={4,8,16}) and should have the extents the character input array has. The problem is that it uses * string_len in the extent multiplication: extent[n] = GFC_DESCRIPTOR_EXTENT(array,n) * string_len; and extent[n] = GFC_DESCRIPTOR_EXTENT(array,n + 1) * string_len; which is I guess fine and desirable for the extents of the character array, but not for the extents of the destination array. Yet the code uses that extent array for that purpose (and no other purposes). Here it uses it to set the dimensions for the case where it needs to allocate (as well as size): for (n = 0; n < rank; n++) { if (n == 0) str = 1; else str = GFC_DESCRIPTOR_STRIDE(retarray,n-1) * extent[n-1]; GFC_DIMENSION_SET(retarray->dim[n], 0, extent[n] - 1, str); } Here it uses it for bounds checking of the destination: if (unlikely (compile_options.bounds_check)) { for (n=0; n < rank; n++) { index_type ret_extent; ret_extent = GFC_DESCRIPTOR_EXTENT(retarray,n); if (extent[n] != ret_extent) runtime_error ("Incorrect extent in return value of" " MAXLOC intrinsic in dimension %ld:" " is %ld, should be %ld", (long int) n + 1, (long int) ret_extent, (long int) extent[n]); } } and here to find out how many retarray elements to actually fill in each dimension: while(1) { *dest = 0; count[0]++; dest += dstride[0]; n = 0; while (count[n] == extent[n]) { /* When we get to the end of a dimension, reset it and increment the next dimension. */ count[n] = 0; /* We could precalculate these products, but this is a less frequently used path so probably not worth it. */ dest -= dstride[n] * extent[n]; Seems maxloc1s.m4 and minloc1s.m4 are the only users of ifunction-s.m4, so we can change SCALAR_ARRAY_FUNCTION in there without breaking anything else. 2025-05-13 Jakub Jelinek <jakub@redhat.com> PR fortran/120191 * m4/ifunction-s.m4 (SCALAR_ARRAY_FUNCTION): Don't multiply GFC_DESCRIPTOR_EXTENT(array,) by string_len. * generated/maxloc1_4_s1.c: Regenerate. * generated/maxloc1_4_s4.c: Regenerate. * generated/maxloc1_8_s1.c: Regenerate. * generated/maxloc1_8_s4.c: Regenerate. * generated/maxloc1_16_s1.c: Regenerate. * generated/maxloc1_16_s4.c: Regenerate. * generated/minloc1_4_s1.c: Regenerate. * generated/minloc1_4_s4.c: Regenerate. * generated/minloc1_8_s1.c: Regenerate. * generated/minloc1_8_s4.c: Regenerate. * generated/minloc1_16_s1.c: Regenerate. * generated/minloc1_16_s4.c: Regenerate. * gfortran.dg/pr120191_3.f90: New test. (cherry picked from commit 781cfc454b8dc24952fe7f4c5c409296dca505e1)
9 dayslibfortran: Fix up _gfortran_s{max,min}loc2_{4,8,16}_s{1,4} [PR120191]Jakub Jelinek1-0/+84
I've tried to write a testcase for the BT_CHARACTER maxloc/minloc with named or unnamed arguments and indeed the just posted patch fixed the arguments in there in multiple cases to match what the library expects. But the testcase still fails, due to library problems. One dealt with in this patch are _gfortran_s{max,min}loc2_{4,8,16}_s{1,4} functions. Those are trivial wrappers around _gfortrani_{max,min}loc2_{4,8,16}_s{1,4} which should call those functions if the scalar mask is true and just return 0 otherwise. The two bugs I see there is that the back, len arguments are swapped, which means that it always acts as back=.true. and for len will use character length of 1 or 0 instead of the desired one. The _gfortrani_{max,min}loc2_{4,8,16}_s{1,4} functions have prototypes like GFC_INTEGER_4 maxloc2_4_s1 (gfc_array_s1 * const restrict array, GFC_LOGICAL_4 back, gfc_charlen_type len) so back comes before len, ditto for the GFC_INTEGER_4 smaxloc2_4_s1 (gfc_array_s1 * const restrict array, GFC_LOGICAL_4 *mask, GFC_LOGICAL_4 back, gfc_charlen_type len) The other problem is that it was just testing if (mask). In my limited Fortran understanding that means that the optional argument mask was supplied but nothing about its actual value. Other scalar mask generated routines use if (mask == NULL || *mask) as the condition when to call the non-masked function, i.e. when mask is not supplied (then it should act like .true. mask) or when it is supplied and evaluates to .true.). 2025-05-13 Jakub Jelinek <jakub@redhat.com> PR fortran/120191 * m4/maxloc2s.m4: For smaxloc2 call maxloc2 if mask is NULL or *mask. Swap back and len arguments. * m4/minloc2s.m4: Likewise. * generated/maxloc2_4_s1.c: Regenerate. * generated/maxloc2_4_s4.c: Regenerate. * generated/maxloc2_8_s1.c: Regenerate. * generated/maxloc2_8_s4.c: Regenerate. * generated/maxloc2_16_s1.c: Regenerate. * generated/maxloc2_16_s4.c: Regenerate. * generated/minloc2_4_s1.c: Regenerate. * generated/minloc2_4_s4.c: Regenerate. * generated/minloc2_8_s1.c: Regenerate. * generated/minloc2_8_s4.c: Regenerate. * generated/minloc2_16_s1.c: Regenerate. * generated/minloc2_16_s4.c: Regenerate. * gfortran.dg/pr120191_2.f90: New test. (cherry picked from commit 482f2192d4ef6af55acae2dc3e0df00b8487cc7d)
9 daysfortran: Fix up minloc/maxloc lowering [PR120191]Jakub Jelinek2-36/+629
We need to drop the kind argument from what is passed to the library, but need to do it not only when one uses the argument name for it (so kind=4 etc.) but also when one passes all the arguments to the intrinsics. The following patch uses what gfc_conv_intrinsic_findloc uses, which looks more efficient and cleaner, we already set automatic vars to point to the kind and back actual arguments, so we can just free/clear expr on the former and set name to "%VAL" on the latter. And similarly clears dim argument for the BT_CHARACTER case when using maxloc2/minloc2, again regardless of whether it was named or not. 2025-05-13 Jakub Jelinek <jakub@redhat.com> Daniil Kochergin <daniil2472s@gmail.com> Tobias Burnus <tburnus@baylibre.com> PR fortran/120191 * trans-intrinsic.cc (strip_kind_from_actual): Remove. (gfc_conv_intrinsic_minmaxloc): Don't call strip_kind_from_actual. Free and clear kind_arg->expr if non-NULL. Set back_arg->name to "%VAL" instead of a loop looking for last argument. Remove actual variable, use array_arg instead. Free and clear dim_arg->expr if non-NULL for BT_CHARACTER cases instead of using a loop. * gfortran.dg/pr120191_1.f90: New test. (cherry picked from commit ec249be3c287c6f1dfb328712ac9c39e6fa95eca)
9 daysDaily bump.GCC Administrator4-1/+21
10 daysc+: -Wabi false positive [PR120012]Jason Merrill2-2/+16
The warning compares the position of a field depending on whether or not the previous base/field is considered a POD for layout, but failed to consider whether the previous base/field is empty; layout of an empty base doesn't consider PODness. PR c++/120012 gcc/cp/ChangeLog: * class.cc (check_non_pod_aggregate): Check is_empty_class. gcc/testsuite/ChangeLog: * g++.dg/abi/base-defaulted2.C: New test. (cherry picked from commit b4b4dfbd22e06877052bd4cc4b191d9d138155cf)
10 daysUpdate gcc sv.poJoseph Myers1-1573/+274
* sv.po: Update.
10 daysDaily bump.GCC Administrator4-1/+102
11 daystree-optimization/120211 - constrain LOOP_VINFO_EARLY_BREAKS_LIVE_IVS moreRichard Biener3-0/+33
The PR120089 fix added more PHIs to LOOP_VINFO_EARLY_BREAKS_LIVE_IVS but not checking that we only add PHIs with a latch argument. The following adds this missing check. PR tree-optimization/120211 * tree-vect-stmts.cc (vect_stmt_relevant_p): Only add PHIs from the loop header to LOOP_VINFO_EARLY_BREAKS_LIVE_IVS. * gcc.dg/vect/vect-early-break_135-pr120211.c: New testcase. * gcc.dg/torture/pr120211-1.c: Likewise.
11 daysipa/120146 - deal with vanished varpool nodes in IPA PTARichard Biener2-2/+14
I don't understand why they vanish when still refered to, but lets deal with that in a conservative way. PR ipa/120146 * tree-ssa-structalias.cc (create_variable_info_for): If the symtab cannot tell us whether all refs to a variable are explicit assume they are not. * g++.dg/ipa/pr120146.C: New testcase. (cherry picked from commit b38e3a7196d25bc8bcb1fe55da7663745cea9470)
11 daystree-optimization/120143 - ICE with failed early break store moveRichard Biener2-1/+18
The early break vectorization store moving was incorrectly trying to move the pattern stmt instead of the original one which failed to register and then confused virtual SSA form due to the update triggered by a degenerate virtual PHI. PR tree-optimization/120143 * tree-vect-data-refs.cc (vect_analyze_early_break_dependences): Move/update the original stmts, not the pattern stmts which lack virtual operands and are not in the IL. * gcc.dg/vect/vect-early-break_135-pr120143.c: New testcase. (cherry picked from commit da377e7ebf84a05943fb768eaeb7d682dee865fa)
11 daystree-optimization/120089 - force all PHIs live for early-break vectRichard Biener3-15/+87
The following makes sure to even mark unsupported PHIs live when doing early-break vectorization since otherwise we fail to validate we can vectorize those and generate wrong code based on the scalar PHIs which would only work with a vectorization factor of one. PR tree-optimization/120089 * tree-vect-stmts.cc (vect_stmt_relevant_p): Mark all PHIs live when not already so and doing early-break vectorization. (vect_mark_stmts_to_be_vectorized): Skip virtual PHIs. * tree-vect-slp.cc (vect_analyze_slp): Robustify handling of early-break forced IVs. * gcc.dg/vect/vect-early-break_134-pr120089.c: New testcase. (cherry picked from commit 9def392a1b63a198d15d972f73b4afc888389d7c)
11 daystree-optimization/120043 - bogus conditional store eliminationRichard Biener2-1/+17
The following fixes conditional store elimination to properly check for conditional stores to readonly memory which we can obviously not store to unconditionally. The tree_could_trap_p predicate used is only considering rvalues and the chosen approach mimics that of loop store motion. PR tree-optimization/120043 * tree-ssa-phiopt.cc (cond_store_replacement): Check whether the store is to readonly memory. * gcc.dg/torture/pr120043.c: New testcase. (cherry picked from commit 93586e5d51188bf71f4f8fae4ee94ff631740f24)
11 daysFix PR 119928, formal arguments used to wrongly inferred for CLASS.Thomas Koenig2-62/+143
The problem was indeed that generating a formal from an actual arglist is a bad idea when classes are involved. Fixed in the attached patch. I think it still makes sense to remove the checks when the other attributes are present (or PR96073 may come back in different guise, even if I have to test case at present). I have also converted the test to a run-time check. gcc/fortran/ChangeLog: PR fortran/119928 * interface.cc (gfc_check_dummy_characteristics): Do not issue error if one dummy symbol has been generated from an actual argument and the other one has OPTIONAL, INTENT, ALLOCATABLE, POINTER, TARGET, VALUE, ASYNCHRONOUS or CONTIGUOUS. (gfc_get_formal_from_actual_arglist): Do nothing if symbol is a class. gcc/testsuite/ChangeLog: PR fortran/119928 * gfortran.dg/interface_60.f90: New test.
11 daysDaily bump.GCC Administrator2-1/+9
12 daystestsuite: Fix pr119131-1.c for targets which emit a psabi warning for ↵Andrew Pinski1-0/+1
vectors of DFP [PR119909] On PowerPC, there is a psabi warning for argument passing of a DFP vector. We are not expecting this warning and we get a failure due to it. Adding -Wno-psabi fixes the testcase. Committed as obvious after a quick test. gcc/testsuite/ChangeLog: PR testsuite/119909 * gcc.dg/torture/pr119131-1.c: Add -Wno-psabi. Signed-off-by: Andrew Pinski <quic_apinski@quicinc.com> (cherry picked from commit bfb61bf309ed207694a97adabc454bfd0936b269)
12 daysDaily bump.GCC Administrator4-1/+51
13 daysFortran: parsing issue with DO CONCURRENT;ENDDO on same line [PR120179]Harald Anlauf2-3/+7
PR fortran/120179 gcc/fortran/ChangeLog: * match.cc (gfc_match_do): Do not attempt to match end-of-statement twice. gcc/testsuite/ChangeLog: * gfortran.dg/do_concurrent_basic.f90: Extend testcase. (cherry picked from commit 6ce73ad4370c143a7d1e6a13b1d353db5884213f)
13 daysFortran: array subreferences and components of derived types [PR119986]Harald Anlauf3-4/+113
PR fortran/119986 gcc/fortran/ChangeLog: * expr.cc (is_subref_array): When searching for array references, do not terminate early so that inquiry references to complex components work. * primary.cc (gfc_variable_attr): A substring reference can refer to either a scalar or array character variable. Adjust search accordingly. gcc/testsuite/ChangeLog: * gfortran.dg/actual_array_subref.f90: New test. (cherry picked from commit fceb6022798b587c9111d0241aaff72602dcd626)
13 daysFix wrong optimization of complex boolean expressionEric Botcazou6-4/+92
The VRP2 pass turns: # prephitmp_3 = PHI <0(4)> _1 = prephitmp_3 == 0; _5 = stretch_14(D) ^ 1; _39 = _1 & _5; _40 = _39 | last_20(D); into _5 = stretch_14(D) ^ 1; _42 = ~stretch_14(D); _39 = _42; _40 = last_20(D) | _39; using the following step: Folding statement: _1 = prephitmp_3 == 0; Queued stmt for removal. Folds to: 1 Folding statement: _5 = stretch_14(D) ^ 1; Not folded Folding statement: _39 = _1 & _5; gimple_simplified to _42 = ~stretch_14(D); _39 = _42 & 1; Folded into: _39 = _42; Folding statement: _40 = _39 | last_20(D); Folded into: _40 = last_20(D) | _39; but stretch_14 is a 8-bit boolean so the two forms are not equivalent, that is to say dropping the "& 1" is wrong. It's another instance of the issue: https://gcc.gnu.org/pipermail/gcc-patches/2020-November/558537.html Here it's the reverse case: the bitwise NOT (~) is treated as logical by the machinery in range-op.cc but the bitwise AND (&) is *not* treated as logical by that of vr-values.cc, leading to the same problematic outcome. gcc/ * vr-values.cc (simplify_using_ranges::simplify) <BIT_AND_EXPR>: Do not call simplify_bit_ops_using_ranges for boolean types whose precision is not 1. gcc/testsuite/ * gnat.dg/opt106.adb: New test. * gnat.dg/opt106_pkg1.ads, gnat.dg/opt106_pkg1.adb: New helper. * gnat.dg/opt106_pkg2.ads, gnat.dg/opt106_pkg2.adb: Likewise.
13 daysDaily bump.GCC Administrator2-1/+34
2025-05-08fortran: Add testcases for PR120152, PR120153 and PR120158Jakub Jelinek4-0/+183
The following patch adds testcase coverage for the 3 recently fixed libgfortran PRs. On trunk before those fixes I'm getting with -m32 FAIL: gfortran.dg/pr120152_1.f90 -O0 (test for excess errors) FAIL: gfortran.dg/pr120152_1.f90 -Os (test for excess errors) and with -m64 FAIL: gfortran.dg/pr120152_1.f90 -O0 (test for excess errors) FAIL: gfortran.dg/pr120152_1.f90 -Os (test for excess errors) FAIL: gfortran.dg/pr120152_2.f90 -O0 (test for excess errors) FAIL: gfortran.dg/pr120152_2.f90 -Os (test for excess errors) FAIL: gfortran.dg/pr120153.f90 -O0 (test for excess errors) FAIL: gfortran.dg/pr120153.f90 -O1 (test for excess errors) FAIL: gfortran.dg/pr120153.f90 -O2 (test for excess errors) FAIL: gfortran.dg/pr120153.f90 -O3 -fomit-frame-pointer -funroll-loops -fpeel-loops -ftracer -finline-functions (test for excess errors) FAIL: gfortran.dg/pr120153.f90 -O3 -g (test for excess errors) FAIL: gfortran.dg/pr120153.f90 -Os (test for excess errors) FAIL: gfortran.dg/pr120158.f90 -O0 execution test FAIL: gfortran.dg/pr120158.f90 -O1 execution test FAIL: gfortran.dg/pr120158.f90 -O2 execution test FAIL: gfortran.dg/pr120158.f90 -O3 -fomit-frame-pointer -funroll-loops -fpeel-loops -ftracer -finline-functions execution test FAIL: gfortran.dg/pr120158.f90 -O3 -g execution test FAIL: gfortran.dg/pr120158.f90 -Os execution test On latest trunk everything PASSes. 2025-05-08 Jakub Jelinek <jakub@redhat.com> PR libfortran/120152 PR libfortran/120153 PR libfortran/120158 * gfortran.dg/pr120152_1.f90: New test. * gfortran.dg/pr120152_2.f90: New test. * gfortran.dg/pr120153.f90: New test. * gfortran.dg/pr120158.f90: New test. (cherry picked from commit 66f5f03853035cc917627e7d044bff8ccd9eca3f)
2025-05-08libcpp: Further fixes for incorrect line numbers in large files [PR120061]Jakub Jelinek8-4/+40
The backport of the PR108900 fix to 14 branch broke building chromium because static_assert (__LINE__ == expected_line_number, ""); now triggers as the __LINE__ values are off by one. This isn't the case on the trunk and 15 branch because we've switched to 64-bit location_t and so one actually needs far longer header files to trigger it. https://gcc.gnu.org/bugzilla/show_bug.cgi?id=120061#c11 https://gcc.gnu.org/bugzilla/show_bug.cgi?id=120061#c12 contain (large) testcases in patch form which show on the 14 branch that the first one used to fail before the PR108900 backport and now works correctly, while the second one attempts to match the chromium behavior and it used to pass before the PR108900 backport and now it FAILs. The two testcases show rare problematic cases, because do_include_common -> parse_include -> check_eol -> check_eol_1 -> cpp_get_token_1 -> _cpp_lex_token -> _cpp_lex_direct -> linemap_line_start triggers there /* Allocate the new line_map. However, if the current map only has a single line we can sometimes just increase its column_bits instead. */ if (line_delta < 0 || last_line != ORDINARY_MAP_STARTING_LINE_NUMBER (map) || SOURCE_COLUMN (map, highest) >= (1U << (column_bits - range_bits)) || ( /* We can't reuse the map if the line offset is sufficiently large to cause overflow when computing location_t values. */ (to_line - ORDINARY_MAP_STARTING_LINE_NUMBER (map)) >= (((uint64_t) 1) << (CHAR_BIT * sizeof (linenum_type) - column_bits))) || range_bits < map->m_range_bits) map = linemap_check_ordinary (const_cast <line_map *> (linemap_add (set, LC_RENAME, ORDINARY_MAP_IN_SYSTEM_HEADER_P (map), ORDINARY_MAP_FILE_NAME (map), to_line))); and so creates a new ordinary map on the line right after the (problematic) #include line. Now, in the spot that r14-11679-g8a884140c2bcb7 patched, pfile->line_table->highest_location in all 3 tests (also https://gcc.gnu.org/bugzilla/show_bug.cgi?id=120061#c13 ) is before the decrement the start of the line after the #include line and so the decrement is really desirable in that case to put highest_location somewhere on the line where the #include actually is. But at the same time it is also undesirable, because if we do decrement it, then linemap_add LC_ENTER called from _cpp_do_file_change will then /* Generate a start_location above the current highest_location. If possible, make the low range bits be zero. */ location_t start_location = set->highest_location + 1; unsigned range_bits = 0; if (start_location < LINE_MAP_MAX_LOCATION_WITH_COLS) range_bits = set->default_range_bits; start_location += (1 << range_bits) - 1; start_location &= ~((1 << range_bits) - 1); linemap_assert (!LINEMAPS_ORDINARY_USED (set) || (start_location >= MAP_START_LOCATION (LINEMAPS_LAST_ORDINARY_MAP (set)))); and we can end up with the new LC_ENTER ordinary map having the same start_location as the preceding LC_RENAME one. Next thing that happens is computation of included_from: if (reason == LC_ENTER) { if (set->depth == 0) map->included_from = 0; else /* The location of the end of the just-closed map. */ map->included_from = (((map[0].start_location - 1 - map[-1].start_location) & ~((1 << map[-1].m_column_and_range_bits) - 1)) + map[-1].start_location); The normal case (e.g. with the testcase included at the start of this comment) is that map[-1] starts somewhere earlier and so map->included_from computation above nicely computes location_t which expands to the start of the #include line. With r14-11679 reverted, for #c11 as well as #c12 map[0].start_location == map[-1].start_location above, and so it is ((location_t) -1 & ~((1 << map[-1].m_column_and_range_bits) - 1))) + map[-1].start_location, which happens to be start of the #include line. For #c11 map[0].start_location is 0x500003a0 and map[-1] has m_column_and_range_bits 7 and map[-2] has m_column_and_range_bits 12 and map[0].included_from is set to 0x50000320. For #c12 map[0].start_location is 0x606c0402 and map[-2].start_location is 0x606c0400 and m_column_and_range_bits is 0 for all 3 maps. map[0].included_from is set to 0x606c0401. The last important part is again in linemap_add when doing LC_LEAVE: /* (MAP - 1) points to the map we are leaving. The map from which (MAP - 1) got included should be the map that comes right before MAP in the same file. */ from = linemap_included_from_linemap (set, map - 1); /* A TO_FILE of NULL is special - we use the natural values. */ if (to_file == NULL) { to_file = ORDINARY_MAP_FILE_NAME (from); to_line = SOURCE_LINE (from, from[1].start_location); sysp = ORDINARY_MAP_IN_SYSTEM_HEADER_P (from); } Here it wants to compute the right to_line which ought to be the line after the #include directive. On the #c11 testcase that doesn't work correctly though, because map[-1].included_from is 0x50000320, from[0] for that is LC_ENTER with start_location 0x4080 and m_column_and_range_bits 12 but note that we've earlier computed map[-1].start_location + (-1 & 0xffffff80) and so only decreased by 7 bits, so to_line is still on the line with #include and not after it. In the #c12 that doesn't happen, all the ordinary maps involved there had 0 m_column_and_range_bits and so this computes correct line. Below is a fix for the trunk including testcases using the location_overflow_plugin hack to simulate the bugs without needing huge files (in the 14 case it is just 330KB and almost 10MB, but in the 15 case it would need to be far bigger). The pre- r15-9018 trunk has FAIL: gcc.dg/plugin/location-overflow-test-pr116047.c -fplugin=./location_overflow_plugin.so scan-file static_assert[^\n\r]*6[^\n\r]*== 6 and current trunk FAIL: gcc.dg/plugin/location-overflow-test-pr116047.c -fplugin=./location_overflow_plugin.so scan-file static_assert[^\n\r]*6[^\n\r]*== 6 FAIL: gcc.dg/plugin/location-overflow-test-pr120061.c -fplugin=./location_overflow_plugin.so scan-file static_assert[^\n\r]*5[^\n\r]*== 5 and with the patch everything PASSes. I'll post afterwards a 14 version of the patch. The patch reverts the r15-9018 change, because it is incorrect, we really need to decrement it even when crossing ordinary map boundaries, so that the location is not on the line after the #include line but somewhere on the #include line. It also patches two spots in linemap_add mentioned above to make sure we get correct locations both in the included_from location_t when doing LC_ENTER (second line-map.cc hunk) and when doing LC_LEAVE to compute the right to_line (first line-map.cc hunk), both in presence of an added LC_RENAME with the same start_location as the following LC_ENTER (i.e. the problematic cases). The LC_ENTER hunk is mostly to ensure included_form location_t is at the start of the #include line (column 0), without it we can decrease include_from not enough and end up at some random column in the middle of the line, because it is masking away map[-1].m_column_and_range_bits bits even when in the end the resulting include_from location_t will be found in map[-2] map with perhaps different m_column_and_range_bits. That alone doesn't fix the bug though. The more important is the LC_LEAVE hunk and the problem there is caused by linemap_line_start not actually doing r = set->highest_line + (line_delta << map->m_column_and_range_bits); when adding a new map (the LC_RENAME one because we need to switch to different number of directly encoded ranges, or columns, etc.). So, in the original PR108900 case that to_line = SOURCE_LINE (from, from[1].start_location); doesn't do the right thing, from there is the last < 0x50000000 map with m_column_and_range_bits 12, from[1] is the first one above it and map[-1].included_from is the correct location of column 0 on the #include line, but as the new LC_RENAME map has been created without actually increasing highest_location to be on the new line (we've just set to_line of the new LC_RENAME map to the correct line), to_line = SOURCE_LINE (from, from[1].start_location); stays on the same source line. I've tried to just replace that with to_line = SOURCE_LINE (from, linemap_included_from (map - 1)) + 1; i.e. just find out the #include line from map[-1].included_from and add 1 to it, unfortunately that breaks the c-c++-common/cpp/line-4.c test where we expect to stay on the same 0 line for LC_LEAVE from <command line> and gcc.dg/cpp/trad/Wunused.c, gcc.dg/cpp/trad/builtins.c and c-c++-common/analyzer/named-constants-via-macros-traditional.c tests all with -traditional-cpp preprocessing where to_line is also off-by-one from the expected one. So, this patch instead conditionalizes it, uses the to_line = SOURCE_LINE (from, linemap_included_from (map - 1)) + 1; way only if from[1] is a LC_RENAME map (rather than the usual LC_ENTER one), that should limit it to the problematic cases of when parse_include peeked after EOL and had to create LC_RENAME map with the same start_location as the LC_ENTER after it. Some further justification for the LC_ENTER hunk, using the https://gcc.gnu.org/pipermail/gcc-patches/2025-May/682774.html testcase (old is 14 before r14-11679, vanilla current 14 and new with the 14 patch) I get $ /usr/src/gcc-14/obj/gcc/cc1.old -quiet -std=c23 pr116047.c -nostdinc In file included from pr116047-1.h:327677:21, from pr116047.c:4: pr116047-2.h:1:1: error: unknown type name ‘a’ 1 | a b c; | ^ pr116047-2.h:1:5: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘c’ 1 | a b c; | ^ pr116047-1.h:327677:1: error: static assertion failed: "" 327677 | #include "pr116047-2.h" | ^~~~~~~~~~~~~ $ /usr/src/gcc-14/obj/gcc/cc1.vanilla -quiet -std=c23 pr116047.c -nostdinc In file included from pr116047-1.h:327678, from pr116047.c:4: pr116047-2.h:1:1: error: unknown type name ‘a’ 1 | a b c; | ^ pr116047-2.h:1:5: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘c’ 1 | a b c; | ^ $ /usr/src/gcc-14/obj/gcc/cc1.new -quiet -std=c23 pr116047.c -nostdinc In file included from pr116047-1.h:327677, from pr116047.c:4: pr116047-2.h:1:1: error: unknown type name ‘a’ 1 | a b c; | ^ pr116047-2.h:1:5: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘c’ 1 | a b c; | ^ pr116047-1.h has on lines 327677+327678: #include "pr116047-2.h" static_assert (__LINE__ == 327678, ""); so the static_assert failure is something that was dealt mainly in the LC_LEAVE hunk and files.cc reversion, but please have a look at the In file included from lines. 14.2 emits correct line (#include "pr116047-2.h" is indeed on line 327677) but some random column in there (which is not normally printed for smaller headers; 21 is the . before extension in the filename). Current trunk emits incorrect line (327678 instead of 327677, clearly it didn't decrement). And the patched compiler emits the right line with no column, as would be printed if I remove e.g. 300000 newlines from the file. 2025-05-07 Jakub Jelinek <jakub@redhat.com> PR preprocessor/108900 PR preprocessor/116047 PR preprocessor/120061 * files.cc (_cpp_stack_file): Revert 2025-03-28 change. * line-map.cc (linemap_add): Use SOURCE_LINE (from, linemap_included_from (map - 1)) + 1; instead of SOURCE_LINE (from, from[1].start_location); to compute to_line for LC_LEAVE. For LC_ENTER included_from computation, look at map[-2] or even lower if map[-1] has the same start_location as map[0]. * gcc.dg/plugin/plugin.exp: Add location-overflow-test-pr116047.c and location-overflow-test-pr120061.c. * gcc.dg/plugin/location_overflow_plugin.cc (plugin_init): Don't error on unknown values, instead just break. Handle 0x4fHHHHHH arguments differently. * gcc.dg/plugin/location-overflow-test-pr116047.c: New test. * gcc.dg/plugin/location-overflow-test-pr116047-1.h: New test. * gcc.dg/plugin/location-overflow-test-pr116047-2.h: New test. * gcc.dg/plugin/location-overflow-test-pr120061.c: New test. * gcc.dg/plugin/location-overflow-test-pr120061-1.h: New test. * gcc.dg/plugin/location-overflow-test-pr120061-2.h: New test. (cherry picked from commit edf745dc519ddbfef127e2789bf11bfbacd300b7)
2025-05-08Daily bump.GCC Administrator5-1/+53
2025-05-07c++: C++17/20 class layout divergence [PR120012]Jason Merrill4-12/+95
C++20 made a class with only explicitly defaulted constructors no longer aggregate, and this wrongly affected whether the class is considered "POD for layout purposes" under the ABI. Conveniently, we already have check_non_pod_aggregate to diagnose cases where this makes a difference, due to PR103681 around a C++14 aggregate change. This backport is the same code change as the trunk version, but since -fabi-version=21 cannot be selected, the fix is not available, only the warning, so the first testcase is different. PR c++/120012 gcc/cp/ChangeLog: * cp-tree.h (struct lang_type): Add non_aggregate_pod. (CLASSTYPE_NON_AGGREGATE_POD): New. * class.cc (check_bases_and_members): Set it. (check_non_pod_aggregate): Diagnose it. gcc/testsuite/ChangeLog: * g++.dg/abi/base-defaulted1.C: New test. * g++.dg/abi/base-defaulted1a.C: New test. (cherry picked from commit e6e3b0772ed40cc65a544bbe744ece62d8b9713e)
2025-05-07c++: let plain -Wabi warn about future changesJason Merrill1-15/+17
c_common_post_options limits flag_abi_version and flag_abi_compat_version to actual ABI version numbers, but let's not do that for warn_abi_version; we might want to add a warning relative to a future ABI version that isn't available in the current release, such backporting the PR120012 warning. Also allow plain -Wabi to include such a warning without complaining that it's useless. Also warn about an unsupported -fabi-version argument. gcc/c-family/ChangeLog: * c-opts.cc (c_common_post_options): Let plain -Wabi warn about changes in a future version. (cherry picked from commit 11e62bc6d9f8109a98facd1f90d4602869eb12e7)
2025-05-07ipa: Do not emit info about temporary clones to ipa-clones dump (PR119852)Martin Jambor2-1/+59
As described in PR 119852, the output of -fdump-ipa-clones can contain "(null)" as the suffix/reason for cloning when we need to create a clone to hold the original function during recursive inlining. Such clone is never output and so should not be part of the dump output either. gcc/ChangeLog: 2025-04-23 Martin Jambor <mjambor@suse.cz> PR ipa/119852 * cgraphclones.cc (dump_callgraph_transformation): Document the function. Do not dump if suffix is NULL. gcc/testsuite/ChangeLog: 2025-04-23 Martin Jambor <mjambor@suse.cz> PR ipa/119852 * gcc.dg/ipa/pr119852.c: New test. (cherry picked from commit fb5829a01651d427a63a12c44ecc8baa47dbfc83)
2025-05-07Document option -fdump-ipa-clonesMartin Jambor1-0/+87
I have noticed that the option -fdump-ipa-clones is not documented although there are users who depend on it. This patch adds the missing documentation along with the description of the information it dumps and the format it uses. I am never quite sure which of the texinfo mark-ups is the most appropriate in which situation, I'll of course incorporate any feedback on this as well as the general wording of the text. After we settle on a version, I'd like to backport the documentation also at least to GCC 15, 14 and 13. Is it perhaps OK for master and the branches or what would better be changed? Thanks, Martin gcc/ChangeLog: 2025-04-23 Martin Jambor <mjambor@suse.cz> * doc/invoke.texi (Developer Options): Document -fdump-ipa-clones. (cherry picked from commit 6ecc2fee06bdd60da0e9b3fe6660b553dbdca3ca)
2025-05-07Daily bump.GCC Administrator3-1/+30
2025-05-06Allow IPA_CP to handle UNDEFINED as VARYING.Andrew MacLeod2-0/+22
When applying a bitmask to reflect ranges, it is sometimes deferred and this can result in an UNDEFINED result. IPA is not expecting this, and add a check for it, and convert to VARYING if encountered. PR tree-optimization/120048 gcc/ * ipa-cp.cc (ipcp_store_vr_results): Check for UNDEFINED. gcc/testsuite/ * gcc.dg/pr120048.c: New.
2025-05-06gimple-fold: Fix fold_truth_andor_for_ifcombine [PR120074]Jakub Jelinek2-1/+25
The following testcase ICEs because of a mismatch between wide_int precision, in particular lr_and_mask has 32-bit precision while sign has 16-bit. decode_field_reference ensures that {ll,lr,rl,rr}_and_mask has {ll,lr,rl,rr}_bitsize precision, so the ll_and_mask |= sign; and rl_and_mask |= sign; and ll_and_mask &= sign; and rl_and_mask &= sign; cases should work right, sign has in those cases {ll,rl}_bitsize precision. The problem is that nothing until much later guarantees that ll_bitsize == lr_bitsize or rl_bitsize == rr_bitsize. In the testcase there is ((b ^ a) & 3) < 0 where a is 16-bit and b is 32-bit, so it is the lsignbit handling, and because of the xor the xor operand is moved to the *r_and_mask, so with ll_and_mask being 16-bit 3 and lr_and_mask being 32-bit 3. Now, either b in the above case would be INTEGER_CST, in that case if rr_arg was also INTEGER_CST we'd use the l_const && r_const case and try to handle it, or we'd run into (though much later) if (ll_bitsize != lr_bitsize || rl_bitsize != rr_bitsize ... return 0; One possibility is dealing with a different precision using wide_int::from. Another option used in this patch as it is safest is + if (ll_bitsize != lr_bitsize) + return 0; if (!lr_and_mask.get_precision ()) lr_and_mask = sign; else lr_and_mask &= sign; and similarly in the other hunk, i.e. punt if there is a mismatch early. And yet another option would be to compute the sign wide_int sign = wi::mask (ll_bitsize - 1, true, ll_bitsize); /* If ll_arg is zero-extended and we're testing the sign bit, we know what the result should be. Shifting the sign bit out of sign will get us to mask the entire field out, yielding zero, i.e., the sign bit of the zero-extended value. We know the masked value is being compared with zero, so the compare will get us the result we're looking for: TRUE if EQ_EXPR, FALSE if NE_EXPR. */ if (lsignbit > ll_bitsize && ll_unsignedp) sign <<= 1; once again for the lr_and_mask and rr_and_mask cases using rl_bitsize. As we just return 0; anyway unless l_const && r_const, if l_const & r_const are false it doesn't really matter what is chosen, but for the const cases it matters and I'm not sure what is right. So the second option might be safest. 2025-05-06 Jakub Jelinek <jakub@redhat.com> PR tree-optimization/120074 * gimple-fold.cc (fold_truth_andor_for_ifcombine): For lsignbit && l_xor case, punt if ll_bitsize != lr_bitsize. Similarly for rsignbit && r_xor case, punt if rl_bitsize != rr_bitsize. Formatting fix. * gcc.dg/pr120074.c: New test. (cherry picked from commit 81475602c3dd57ff6987e5f902814e8e3a0a0dde)
2025-05-06Daily bump.GCC Administrator4-1/+47
2025-05-05ipa/120006 - wrong code with IPA PTARichard Biener2-0/+67
When PTA gets support for special-handling more builtins in find_func_aliases the corresponding code in find_func_clobbers needs updating as well since for unhandled cases it assumes the former will populate ESCAPED accordingly. The following fixes a few omissions, the testcase runs into the missing strdup handling. I believe the more advanced handling using modref results and fnspecs opened a larger gap, the proper fix is to merge both functions, gating the clobber/use part on a parameter to avoid diverging. PR ipa/120006 * tree-ssa-structalias.cc (find_func_clobbers): Handle strdup, strndup, realloc, index, strchr, strrchr, memchr, strstr, strpbrk builtins like find_func_aliases does. * gcc.dg/torture/pr120006.c: New testcase. (cherry picked from commit a85b89e26b1f50997701eb428c2dd71668f216ff)
2025-05-05ipa/119973 - IPA PTA issue with global initializersRichard Biener2-5/+44
For global initializers with IPA PTA we initialize them from the IPA reference data but that lacks references to the constant pool. The following conservatively considers the whole initializer. PR ipa/119973 * tree-ssa-structalias.cc (create_variable_info_for): Build constraints from DECL_INITIAL directly rather than the IPA reference list which is incomplete. * gcc.dg/torture/pr119973.c: New testcase. (cherry picked from commit 7a16ef443b13fff9537baa533597836c57131262)
2025-05-05Ada: Fix assertion failure on Finalizable aspect for tagged record typeEric Botcazou2-11/+30
This is a (benign) assertion failure on the mainline for the new Finalizable aspect put on a tagged record type when not all the primitives are declared. This compiles and runs on the 15 branch because assertions are disabled. gcc/ada/ PR ada/120104 * exp_ch3.adb (Expand_Freeze_Record_Type): For a controlled tagged type, freeze only the controlled primitives that are present. gcc/testsuite/ * gnat.dg/specs/finalizable1.ads: New test.
2025-05-05Daily bump.GCC Administrator1-1/+1
2025-05-04Daily bump.GCC Administrator3-1/+26
2025-05-03Fortran: fix procedure pointer handling with -fcheck=pointer [PR102900]Harald Anlauf4-7/+46
PR fortran/102900 gcc/fortran/ChangeLog: * trans-decl.cc (gfc_generate_function_code): Use sym->result when generating fake result decl for functions returning allocatable or pointer results. * trans-expr.cc (gfc_conv_procedure_call): When checking the pointer status of an actual argument passed to a non-allocatable, non-pointer dummy which is of type CLASS, do not check the class container of the actual if it is just a procedure pointer. (gfc_trans_pointer_assignment): Fix treatment of assignment to NULL of a procedure pointer. gcc/testsuite/ChangeLog: * gfortran.dg/proc_ptr_52.f90: Add -fcheck=pointer to options. * gfortran.dg/proc_ptr_57.f90: New test. (cherry picked from commit cc8d86ee4680d56eefeb76a8f2f752282e2631e3)
2025-05-03Daily bump.GCC Administrator3-1/+19
2025-05-02c: Fix up RAW_DATA_CST handling in check_constexpr_init [PR120057]Jakub Jelinek4-2/+54
The pr120057-1.c testcase is incorrectly rejected since r15-4377 (and for a while it also ICEd after the error), i.e. the optimization of large C initializers using RAW_DATA_CST. Similarly, the embed-18.c testcase is incorrectly rejected since the embed support has been introduced and RAW_DATA_CST used for that. The callers of check_constexpr_init (store_init_value and output_init_element) compute int_const_expr as int_const_expr = (TREE_CODE (init) == INTEGER_CST && !TREE_OVERFLOW (init) && INTEGRAL_TYPE_P (TREE_TYPE (init))); but that is only passed through down to check_constexpr_init. I think tweaking those 2 callers to also allow RAW_DATA_CST for int_const_expr when check_constexpr_init needs top special case it no matter what would be larger, so the patch just changes check_constexpr_init to deal with RAW_DATA_CST in the initializers. For TYPE_UNSIGNED char precision integral types RAW_DATA_CST is always valid, for !TYPE_UNSIGNED we need to check for 128-255 values being turned into negative ones. 2025-05-02 Jakub Jelinek <jakub@redhat.com> PR c/120057 * c-typeck.cc (check_constexpr_init): Handle RAW_DATA_CST. * gcc.dg/cpp/embed-18.c: New test. * gcc.dg/pr120057-1.c: New test. * gcc.dg/pr120057-2.c: New test. (cherry picked from commit e81f2f4855876c5d85ab9870c5a150ee1a59ee73)
2025-05-02Daily bump.GCC Administrator3-1/+59
2025-05-01c++/modules: Ensure deduction guides for imported types are reachable [PR120023]Nathaniel Shead4-0/+38
In the linked PR, because the deduction guides depend on an imported type, we never walk the type and so never call add_deduction_guides. This patch ensures that we make bindings for deduction guides if we saw any deduction guide at all. PR c++/120023 gcc/cp/ChangeLog: * module.cc (depset::hash::find_dependencies): Also call add_deduction_guides when walking one. gcc/testsuite/ChangeLog: * g++.dg/modules/dguide-7_a.C: New test. * g++.dg/modules/dguide-7_b.C: New test. * g++.dg/modules/dguide-7_c.C: New test. Signed-off-by: Nathaniel Shead <nathanieloshead@gmail.com> Reviewed-by: Jason Merrill <jason@redhat.com> (cherry picked from commit fb4583566afdee50aad12e1219610813b44bdff4)
2025-05-01c++/modules: Fix imported CNTTPs being considered non-constant [PR119938]Nathaniel Shead3-1/+30
When importing a CNTTP object, since r15-3031-g0b7904e274fbd6 we shortcut the processing of the generated NTTP so that we don't attempt to recursively load pendings. However, due to an oversight we do not properly set TREE_CONSTANT or DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P on the decl, which confuses later processing. This patch ensures that this happens correctly. PR c++/119938 gcc/cp/ChangeLog: * pt.cc (get_template_parm_object): When !check_init, add assert that expr really is constant and mark decl as such. gcc/testsuite/ChangeLog: * g++.dg/modules/tpl-nttp-2_a.H: New test. * g++.dg/modules/tpl-nttp-2_b.C: New test. Signed-off-by: Nathaniel Shead <nathanieloshead@gmail.com> Reviewed-by: Jason Merrill <jason@redhat.com> (cherry picked from commit d613678c94f06809656e56b37f314501b37a5ddd)
2025-05-01c++/modules: Catch exposures of TU-local values through inline references ↵Nathaniel Shead2-7/+53
[PR119996] In r15-9136-g0210bedf481a9f we started erroring for inline variables that exposed TU-local entities in their definition, as such variables would need to have their definitions emitted in importers but would not know about the TU-local entities they referenced. A case we mised was potentially-constant references, which disable streaming of their definitions in make_dependency so as to comply with [expr.const] p9.2. This meant that we didn't see the definition referencing a TU-local entity, leading to nonsensical results. PR c++/119551 PR c++/119996 gcc/cp/ChangeLog: * module.cc (depset::hash::make_dependency): Also mark inline variables referencing TU-local values as exposures here. (depset::hash::finalize_dependencies): Add error message for inline variables. gcc/testsuite/ChangeLog: * g++.dg/modules/internal-13.C: New test. Signed-off-by: Nathaniel Shead <nathanieloshead@gmail.com> Reviewed-by: Jason Merrill <jason@redhat.com> (cherry picked from commit 22ccaded63e96e5a42f4e3676dbbb57aa05b36f9)
2025-05-01Daily bump.GCC Administrator6-1/+92
2025-04-30Update gcc .po filesJoseph Myers20-92971/+96411
* be.po, da.po, de.po, el.po, es.po, fi.po, fr.po, hr.po, id.po, ja.po, ka.po, nl.po, ru.po, sr.po, sv.po, tr.po, uk.po, vi.po, zh_CN.po, zh_TW.po: Update.
2025-04-30Always reflect lower bits from mask in subranges.Andrew MacLeod6-41/+61
During intersection, we expand the subranges to exclude the lower values from a bitmask with trailing zeros. This leads to inconsistant evaluations and in this case of this PR, that lead to an infinite cycle. Always expand the lower subranges in set_range_from_bitmask instead. PR tree-optimization/119712 gcc/ * value-range.cc (range_bitmask::adjust_range): Delete. (irange::set_range_from_bitmask): Integrate adjust_range. (irange::update_bitmask): Do nothing if bitmask doesnt change. (irange:intersect_bitmask): Do not call adjust_range. Exit if there is no second bitmask. * value-range.h (adjust_range): Remove prototype. gcc/testsuite/ * gcc.dg/pr119712.c: New. * gcc.dg/pr83072-2.c: Adjust. * gcc.dg/tree-ssa/phi-opt-value-5.c: Adjust. * gcc.dg/tree-ssa/vrp122.c: Adjust
2025-04-30testsuite: Force -mcmodel=small for gcc.target/aarch64/pr115258.cRichard Sandiford1-1/+1
The test implicitly assumed the default code model and so failed for -mcmodel=tiny. gcc/testsuite/ * gcc.target/aarch64/pr115258.c: Add -mcmodel=small. (cherry picked from commit 3584aab37f54bcd220c7061568af777e37f4f6ed)
2025-04-30c++: UNBOUND_CLASS_TEMPLATE context substitution [PR119981]Patrick Palka2-7/+30
In r15-123 and r14-11434 we unconditionally set processing_template_decl when substituting the context of an UNBOUND_CLASS_TEMPLATE, in order to handle instantiation of the dependently scoped friend declaration template<int N> template<class T> friend class A<N>::B; where the scope A<N> remains dependent after instantiation. But this turns out to misbehave for the UNBOUND_CLASS_TEMPLATE in the below testcase representing g<[]{}>::template fn since with the flag set substituting the args of test3 into the lambda causes us to defer the substitution and yield a lambda that still looks dependent, which in turn makes g<[]{}> still dependent and not suitable for qualified name lookup. This patch restricts setting processing_template_decl during UNBOUND_CLASS_TEMPLATE substitution to the case where there are multiple levels of introduced template parameters, as in the friend declaration. (This means we need to substitute the template parameter list(s) first, which makes sense since they lexically appear first.) PR c++/119981 PR c++/119378 gcc/cp/ChangeLog: * pt.cc (tsubst) <case UNBOUND_CLASS_TEMPLATE>: Substitute into template parameter list first. When substituting the context, only set processing_template_decl if there's more than one level of introduced template parameters. gcc/testsuite/ChangeLog: * g++.dg/cpp2a/lambda-targ15.C: New test. Reviewed-by: Jason Merrill <jason@redhat.com> (cherry picked from commit 05ea8baf6ff96c77a9a2467d5c45b1ed575fca92)