Eric Botcazou [Sun, 10 May 2026 10:51:44 +0000 (12:51 +0200)]
Ada: Fix Image for derived enumeration type with representation clause
The problem is that Expand_Image_Attribute incorrectly fetches the root type
for enumeration types, thus bypassing a clause present on the derived type.
The fix is to change the two fields Lit_Indexes and Lit_Strings defined for
enumeration types and subtypes to be formally present on root types only, as
well as to make Expand_Image_Attribute stick to base types.
gcc/ada/
PR ada/125240
* gen_il-gen-gen_entities.adb (Enumeration_Kind): Make
Lit_Indexes and Lit_Strings be defined for root types only.
* einfo.ads (Lit_Hash): Adjust description.
(Lit_Indexes): Likewise.
(Lit_Strings): Likewise.
(E_Enumeration_Type): Likewise.
* exp_imgv.adb (Expand_Image_Attribute): Do not fetch the root type
for enumeration types, except for character types, and adjust.
PR target/125238
* config/i386/i386-features.cc (ix86_broadcast_inner): Set kind
to X86_CSE_CONST_VECTOR if the vector load can be converted to
constant integer load.
gcc/testsuite/
PR target/125238
* gcc.target/i386/pr125238.c: New test.
Paul Thomas [Fri, 8 May 2026 05:34:21 +0000 (06:34 +0100)]
Fortran: Allow access to coarray elements within modules. [PR125051]
The parts of this patch is fix the problem are chunks 2 and 3. Chunk3 prevents
gfc_conv_intrinsic_caf_get from working in the module namespace, when the array
symbol is in a module. Equally, though, gfc_current_ns is not necessarily in
the referencing procedure namespace. The second chunk makes sure that this is
the case. As an aside, it seems to us that it makes considerably more sense that
gfc_current_ns be that of the current procedure. The first chunk makes sure that
result symbol initialization does not occur outside the function.
Passes regtesting with FC44/x86_64.
2026-05-10 Andre Vehreschild <vehre@gcc.gnu.org>
Paul Thomas <pault@gcc.gnu.org>
gcc/fortran
PR fortran/125051
* trans-decl.cc (gfc_get_symbol_decl): gfc_defer_symbol_init
must not be called for PDT types, classes or types with PDT
(gfc_generate_function_code): If gfc_current_ns is not the same
as the function namespace, stash it,change it to the function
namespace and restore after translation of the code.
* trans-intrinsic.cc (gfc_conv_intrinsic_caf_get): If the array
is in a module, use the symbol namespace.
* trans-openmp.cc (gfc_trans_omp_array_reduction_or_udr): If the
current namespace is not that of the procedure, change to the
procedure namspace and revert on leaving this function.
gcc/testsuite/
PR fortran/125051
* gfortran.dg/coarray/pr125051.f90: New test.
riscv_expand_epilogue will skip emitting sspopchk when cm.popret is
emitted. After this patch we will no longer emit cm.popret and instead
use cm.pop + sspopchk + a regular return:
sspush ra
cm.push {ra, s0-s1}, -32
..
cm.pop {ra, s0-s1}, 32
sspopchk ra
jr ra
Andrew Pinski [Sat, 9 May 2026 01:32:50 +0000 (18:32 -0700)]
cfghooks: constifify cfg_hooks [PR117871]
This constifies the hooks so the structs can't be changed at runtime.
The only odd place where we need to handle special is sel-sched.
This is because we make a copy of the current cfghooks and then
use its own. This changes things slightly there, there is still a
copy used but instead of copying back into the current cfghooks, we
just change the pointer back to the original one. This code is only
enabled by ia64 backend by default so I doubt it will change.
Boostrapped and tested on x86_64-linux-gnu.
PR middle-end/117871
gcc/ChangeLog:
* cfghooks.cc (cfg_hooks): Change the type
to be a pointer to a const struct cfg_hooks.
(get_cfg_hooks): Return the current pointer
rather the struct.
(set_cfg_hooks): Change the argument type and
set the cfg_hooks directly to it.
* cfghooks.h (gimple_cfg_hooks): Constify.
(rtl_cfg_hooks): Likewise.
(cfg_layout_rtl_cfg_hooks): Likewise.
(get_cfg_hooks): Update declration.
(set_cfg_hooks): Likewise.
* cfgrtl.cc (rtl_cfg_hooks): Constify.
(cfg_layout_rtl_cfg_hooks): Likewise.
* sel-sched-ir.cc (orig_cfg_hooks): Change to a pointer.
(sel_create_basic_block): Update
for orig_cfg_hooks being a pointer.
(sel_register_cfg_hooks): Update for the constification
of cfg_hooks.
* tree-cfg.cc (gimple_cfg_hooks): Constify.
Signed-off-by: Andrew Pinski <andrew.pinski@oss.qualcomm.com>
Andrew Pinski [Sat, 9 May 2026 00:51:54 +0000 (17:51 -0700)]
cfghooks: Remove name field
Now we have an IR field, we can remove the name field. The
only time the name is used was for internal errors so having
this field outside of the hooks is better anyways.
Bootstrapped and tested on x86_64-linux-gnu.
gcc/ChangeLog:
* cfghooks.cc (current_ir_name): New function.
(dump_bb_for_graph): Use current_ir_name
instead of accessing the name field.
(dump_bb_as_sarif_properties): Likewise.
(redirect_edge_and_branch): Likewise.
(can_remove_branch_p): Likewise.
(redirect_edge_and_branch_force): Likewise.
(split_block_1): Likewise.
(move_block_after): Likewise.
(delete_basic_block): Likewise.
(split_edge): Likewise.
(create_basic_block_1): Likewise.
(can_merge_blocks_p): Likewise.
(predict_edge): Likewise.
(predicted_by_p): Likewise.
(merge_blocks): Likewise.
(make_forwarder_block): Likewise.
(force_nonfallthru): Likewise.
(can_duplicate_block_p): Likewise.
(duplicate_block): Likewise.
(block_ends_with_call_p): Likewise.
(block_ends_with_condjump_p): Likewise.
(flow_call_edges_add): Likewise.
* cfghooks.h (struct cfg_hooks): Remove the name
field.
* cfgrtl.cc (rtl_cfg_hooks): Update for the removal
of the name field.
(cfg_layout_rtl_cfg_hooks): Likewise.
* tree-cfg.cc (struct cfg_hooks): Likewise.
Signed-off-by: Andrew Pinski <andrew.pinski@oss.qualcomm.com>
Andrew Pinski [Sat, 9 May 2026 00:16:10 +0000 (17:16 -0700)]
cfghooks: Move ir_type inside cfghooks
This is the first step in constification (and/or C++ification)
of the cfghooks. Currently we compare variables to figure out
what the current IR type is. Rather let's move the ir_type
into the cfghooks. This will help with constification due
to sel-sched overloading one of the hooks.
Bootstrapped and tested on x86_64-linux-gnu.
gcc/ChangeLog:
* cfghooks.cc (current_ir_type): Return cfghooks' ir field.
* cfghooks.h (struct cfg_hooks): Add ir field.
* cfgrtl.cc (rtl_cfg_hooks): Update for new ir field.
(cfg_layout_rtl_cfg_hooks): Likewise.
* tree-cfg.cc (gimple_cfg_hooks): Likewise.
Signed-off-by: Andrew Pinski <andrew.pinski@oss.qualcomm.com>
PR target/125239
* config/i386/i386-features.cc (ix86_place_single_vector_set):
For CONST_VECTOR source, check CONST0_RTX with
X86_CSE_CONST0_VECTOR and CONSTM1_RTX with X86_CSE_CONSTM1_VECTOR.
(ix86_broadcast_inner): Set x86_cse kind to X86_CSE_CONST0_VECTOR
for CONST0_RTX and X86_CSE_CONSTM1_VECTOR for CONSTM1_RTX.
gcc/testsuite/
PR target/125239
* gcc.target/i386/pr124407-1.c: Adjusted.
* gcc.target/i386/pr125239.c: New test.
Andrew Pinski [Fri, 8 May 2026 19:46:32 +0000 (12:46 -0700)]
match: Fix merged patterns for a!=b implies a and b are not zero [PR125234]
In r17-231-gc65691bc5a2873, I messed up the resulting constant for
`(a != b) & ((a | b) == 0)` and `(a == b) | ((a | b) != 0)`. I had
swapped which one was resulting in true/false. This fixes the issue
and adds a testcase to make sure it does not regress again.
Pushed as obvious after a bootstrap/test on x86_64-linux-gnu.
Marek Polacek [Thu, 7 May 2026 22:09:57 +0000 (18:09 -0400)]
c++: fix ICE with invalid targ [PR125043]
The patch that allowed DECL_NTTP_OBJECT_P in invalid_tparm_referent_p
also added the assert checking for tinfos/__func__ (r14-8189). But in
these tests we got to the assert with a temporary object coming from
create_temporary_var: either a reference temporary or compound literal
temporary. The former could be checked by seeing if the name starts
with _ZGR but the latter don't have it. So perhaps we can just check
DECL_IGNORED_P, always set for create_temporary_var objects.
PR c++/115181
PR c++/125043
PR c++/124979
gcc/cp/ChangeLog:
* pt.cc (invalid_tparm_referent_p): Allow DECL_IGNORED_P in an
assert.
gcc/testsuite/ChangeLog:
* g++.dg/cpp1z/nontype-auto27.C: New test.
* g++.dg/cpp1z/nontype-auto28.C: New test.
* g++.dg/cpp2a/nontype-class75.C: New test.
Roger Sayle [Fri, 8 May 2026 20:06:54 +0000 (21:06 +0100)]
PR middle-end/124637: Fix passing padded constant structs in registers on big-endian targets
This patch resolves PR middle-end/124637, a wrong code regression when
passing a struct as a register on big-endian targets. On big-endian
targets, store_constructor fills fields from the most significant bits,
so for structs narrower than word size, any padding is incorrectly
placed in the least significant bytes. This issue is fixed (on
affected targets) by using a (unsigned) right shift on the value
determined by store_constructor to correctly align the structure in
the least significant bytes, and place the padding in the high bits.
Many thanks to Manjunath Matti for testing this patch on real hardware,
and Drea Pinski for reviewing/approving it. The new test case may be
a little fragile, but currently "works for me". Please feel free to
tweak it for powerpc variants/environments I've not consider/encountered.
2026-05-08 Roger Sayle <roger@nextmovesoftware.com>
gcc/ChangeLog
PR middle-end/124637
* calls.cc (load_register_parameters): If using store_constructor
to place a constant structure in a register, use a right shift to
align the structure/padding if required on big-endian targets.
gcc/testsuite/ChangeLog
PR middle-end/124637
* gcc.target/powerpc/pr124637.c: New test case.
Harald Anlauf [Fri, 8 May 2026 19:45:31 +0000 (21:45 +0200)]
libfortran: fix static analyser cppcheck warning in free_format_data [PR125087]
The static analyser cppcheck reported a pointless assignment in function
free_format_data. The intent of the assignment was to finally nullify the
pointer to allocated format data after memory has been freed. Since C does
not support references, add a level of indirection to the function argument
so that the dereferenced argument can be nullified.
PR libfortran/125087
libgfortran/ChangeLog:
* io/format.c (free_format_data): Change argument from pointer to
format_data to pointer to pointer of object.
(free_format_hash_table): Adjust argument passed to
free_format_data.
(save_parsed_format): Likewise.
* io/format.h (free_format_data): Adjust prototype.
* io/transfer.c (st_read_done_worker): Adjust argument passed to
free_format_data.
(st_write_done_worker): Likewise.
Jeff Law [Fri, 8 May 2026 17:40:29 +0000 (11:40 -0600)]
[V2][RISC-V][PR target/124955] Utilize slliw for some left shifted signed bitfield extractions
Some functional change as was already posted, this time with a testcase. Given
it's been in my tester and through the pre-commit CI system, I'm going forward
now.
--
So as the PR notes, this is an attempt to squeeze out some instructions from a
hot part of leela, the random number generator in particular.
The key is realizing that the the first two statements are just a sign extended
bitfield of length 20. That ultimately gets shifted left 12 bits. 20+12 = 32,
so we can at least conceptually use slliw (shift left sign extending result
from SI to DI). The andi just turns off the low bit.
Given a sign extracted bitfield starting at bit 0, of size N that is then left
shifted by M where N+M == 32 is a natural slliw instruction. However, when I
tried to recognize that and generate the slliw form I saw code quality
regressions that didn't look particularly reasonable to try and fix. So we
want to be more selective about recognizing that idiom. So we recognize it
when we subsequently mask off some bits and the mask can be encoded via andi.
This likely could be extended to other logical operations that don't ultimately
affect the SI sign bit.
PR target/124955
gcc/
* config/riscv/riscv.md (masked shifted bitfield extraction): New
splitter to utilize slliw to eliminate the need for sign extnesion.
Jeff Law [Fri, 8 May 2026 17:19:02 +0000 (11:19 -0600)]
[RISC-V][PR tree-optimization/93504] Handle (X & C) | ((X^Y) & ~C) -> X ^ ( Y & ~C) in simplify-rtx
This is a trivial generalization of existing simplify-rtx code. Essentially
the code in question was handling IOR, but not XOR. I'm keeping the bz open as
this probably should have been cleaned up before getting into RTL.
The net is something like this:
> #define N 0x202
> #define OP ^
>
> unsigned f(unsigned a, unsigned b)
> {
> unsigned t = a OP b;
> unsigned t1 = t&N;
> unsigned t2 = a&~N;
> return t1 | t2;
> }
>
Originally compiled into:
xor a1,a0,a1
andi a1,a1,514
andi a0,a0,-515
or a0,a1,a0
ret
After it compiles into:
andi a1,a1,514
xor a0,a1,a0
ret
Bootstrapped and regression tested on x86, aarch64 and various targets in qemu.
Also tested on the usual embedded targets.
PR tree-optimization/93504
gcc/
* simplify-rtx.cc (simplify_context::simplify_binary_operation_1):
Generalize existing code for (X & C) | ((X|Y) & ~C) to handle
(X & C) | ((X^Y) & ~C) as well.
gcc/testsuite
* gcc.target/riscv/pr93504.c: New test.
Harald Anlauf [Thu, 7 May 2026 20:34:52 +0000 (22:34 +0200)]
Fortran: fix automatic deallocation with derived type IO [PR111952,PR125059]
The implementation of derived type IO wrongly forced allocatable instances
of the DT as static, which prevented automatic deallocation of local
variables. The motivation was an attempt to prevent optimizations leading
to certain testcase failures. Howver, the underlying reason of the problem
was a wrong fnspec of _gfortran_transfer_derived that declared the IO
variable as being only read ('r'). Declare the corresponding parameter as
being written ('w').
PR fortran/111952
PR fortran/125059
gcc/fortran/ChangeLog:
* trans-decl.cc (gfc_finish_var_decl): Remove bogus code forcing
a DT variable with DTIO as static.
* trans-io.cc (gfc_build_io_library_fndecls): Fix fnspec attribute.
Roger Sayle [Fri, 8 May 2026 13:39:13 +0000 (14:39 +0100)]
[PATCH] Restore bootstrap on aarch64
My recent change to synth_mult broke bootstrap on aarch64, as gimple's
array bounds checking pass reports a (false positive) problem in some
unreachable code. This leads to -Werror stopping in stage2 of the
bootstrap.
The solution/workaround is add some more conditionals to the code that
make it clear(er) to range analysis the conditions under which the new
code is run. I believe these tests are redundant, and hopefully will be
optimized by the compiler (if not now then at some point in the future).
This patch has been tested on an aarch64-apple-darwin24.3.0, where I was
able to reproduce the failure. Committed to mainline as obvious (to
quickly resolve the current breakage).
2026-05-08 Roger Sayle <roger@nextmovesoftware.com>
gcc/ChangeLog
* expmed.cc (synth_mult): Add more constraints to recent change
to avoid "false positive" array bounds warnings during bootstrap.
Xi Ruoyao [Fri, 1 May 2026 19:31:09 +0000 (03:31 +0800)]
LoongArch: Allow printing symbolic name with "%c" in inline asm
The gcc.dg/ipa/pr122458.c test relies on this. The doc says "%c" is
for "constant operand" and I think there's no harm to consider symbolic
name a constant operand.
gcc/
* config/loongarch/loongarch.cc (loongarch_print_operand): Print
the symbol name for SYMBOL_REF with %c.
Xi Ruoyao [Tue, 28 Apr 2026 12:32:38 +0000 (20:32 +0800)]
LoongArch: harden SSP canary set and test routines [PR 125049]
Add the stack_protect_combined_{set,test} expanders to expand the
routines as unsplitable insns which does not leave any sensitive data
(the canary value, the canary address, and all the intermediate values
used materializing the address) in a register. This prevents the
attacker from defeating SSP by probing the canary value from the
register context or overwriting the address spilled onto the stack.
PR target/125049
gcc/
* config/loongarch/predicates.md (ssp_operand): New
define_predicate.
(ssp_normal_operand): New define_predicate.
* config/loongarch/constraints.md (ZE): New define_constraint.
(ZF): New define_constraint.
* config/loongarch/loongarch.md (UNSPEC_SSP): New unspec.
(cbranch4): Add "@" to create gen_cbranch4(machine_mode, ...).
(@stack_protect_combined_set_normal_<mode>): New define_insn.
(@stack_protect_combined_set_extreme_<mode>): New define_insn.
(@stack_protect_combined_test_internal_<mode>): New define_insn.
(stack_protect_combined_set): New define_expand.
(stack_protect_combined_test): New define_expand.
* config/loongarch/loongarch-protos.h
(loongarch_output_asm_load_canary): Declare.
* config/loongarch/loongarch.cc (loongarch_print_operand): Allow
'v' to print d/w for DImode/SImode.
(loongarch_output_asm_load_canary): Implement.
Xi Ruoyao [Wed, 25 Feb 2026 15:17:10 +0000 (23:17 +0800)]
LoongArch: eliminate redundant extension after ctz.w
The ctz.w instruction writes to the entire $rd. So due to the range of
the CTZ result ([0, 32]), $rd is already both sign-extended and
zero-extended from its lower half. But in pr90838.c we can see two
redundant sign-extension (slli.w ...,0). Now get rid of them.
The "andi" instructions in pr90393.c are really needed, because the
source code logic should produce 0 for zero input, but the ctz.[dw]
instructions actually produce 64/32.
gcc/
* config/loongarch/loongarch.md (*ctzsi2_extend): New
define_insn.
gcc/testsuite/
* gcc.dg/pr90838.c: Adjust expectation for LoongArch.
Vijay Shankar [Fri, 8 May 2026 07:36:21 +0000 (02:36 -0500)]
rs6000: Emit insn with proper rounding mode for nearbyint
This patch emits instruction with proper rounding mode for
vec_nearbyint.Previously, xvrdpi was emitted which uses nearest away
rounding mode but nearbyint requires rounding mode to be current
rounding mode.
Bootstrapped and regtested on powerpc64le-linux-gnu with no regressions.
Richard Biener [Wed, 6 May 2026 11:47:48 +0000 (13:47 +0200)]
tree-optimization/125174 - cost OMP SIMD calls
The following makes the target aware of OMP SIMD calls. Scalar
costing costs calls as scalar_stmt, so make sure to at least do
this level of costing for the vector side.
PR tree-optimization/125174
* tree-vect-stmts.cc (vectorizable_simd_clone_call): Cost
the number of OMP SIMD calls number of vector stmts.
Bohan Lei [Wed, 15 Apr 2026 07:42:20 +0000 (15:42 +0800)]
RISC-V: Implement even-odd shuffles with vnsrl
This patch tries to implement some even-odd shuffles with vnsrl instead
of vcompress, which is inspired by the current behavior of LLVM. Since
vcompress is slower than vnsrl on many implementations, and that
vcompress needs a mask load, using vnsrl seems to be more desirable.
gcc/ChangeLog:
* config/riscv/riscv-v.cc (shuffle_even_odd_patterns): Use vnsrl
when possible.
gcc/testsuite/ChangeLog:
* gcc.target/riscv/rvv/autovec/vls-vlmax/shuffle-evenodd.c:
Match vnsrl patterns.
Thomas Schwinge [Fri, 8 May 2026 07:17:30 +0000 (09:17 +0200)]
testsuite: Fix test requirements: Adjust 'gcc.dg/plugin/diagnostic-test-paths-4.py'
Recent commit 4468e0da6e58f017faef1f248b4d1c4e27423b91
"testsuite: Fix test requirements" added a 'dg-require-effective-target signal'
line to 'gcc.dg/plugin/diagnostic-test-paths-4.c', which regressed:
PASS: gcc.dg/plugin/diagnostic-test-paths-4.c -fplugin=./diagnostic_plugin_test_paths.so (test for warnings, line [-13)-]{+14)+}
PASS: gcc.dg/plugin/diagnostic-test-paths-4.c -fplugin=./diagnostic_plugin_test_paths.so expected multiline pattern lines [-33-83-]{+34-84+}
PASS: gcc.dg/plugin/diagnostic-test-paths-4.c -fplugin=./diagnostic_plugin_test_paths.so (test for excess errors)
[-PASS:-]{+FAIL:+} gcc.dg/plugin/diagnostic-test-paths-4.c [-diagnostic-test-paths-4.py::test_path-]{+diagnostic-test-paths-4.py::test_paths - AssertionErro+}
..., as the latter file needs to be updated accordingly.
The narrow_gp_writes pass uses RTL-SSA and updates DF state via
df_insn_rescan / df_insn_delete. Both routines look up the insn's bb via
BLOCK_FOR_INSN to mark it dirty after a change, but pass_free_cfg has already
cleared those per-insn pointers by the time narrow_gp_writes runs. When
BLOCK_FOR_INSN returns NULL, the dirty-marking step is silently skipped,
leaving the DF stale.
Move the pass to run before pass_free_cfg.
Bootstrapped and regtested on aarch64-linux-gnu.
SPEC CPU 2017 shows no codegen differences (compared to previous placement).
OK for trunk?
Signed-off-by: Soumya AR <soumyaa@nvidia.com>
PR target/124895
gcc/ChangeLog:
* config/aarch64/aarch64-passes.def (pass_narrow_gp_writes): Move pass
before pass_free_cfg.
gcc/testsuite/ChangeLog:
* gcc.target/aarch64/narrow-gp-writes-8.c: New test.
1. Use CONST_VECTOR in REG_EQUAL note to avoid DF chain.
2. Keep constant integer load when crossing a function call since it is
faster than save and restore an integer register.
3. Convert CONST_VECTOR load no larger than integer register to constant
integer load even if there is no redundant CONST_VECTOR load.
Tested on Linux/x86-64.
gcc/
PR target/125100
* config/i386/i386-features.cc (x86_cse_kind): Add
X86_CSE_CONST_VECTOR.
(redundant_pattern): Add dest_mode.
(ix86_place_single_vector_set): Handle X86_CSE_CONST_VECTOR.
Generate SUBREG for constant integer source.
(ix86_broadcast_inner): Add an INSN argument. Use CONST_VECTOR
in REG_EQUAL note. Set load kind to X86_CSE_CONST_VECTOR for
native and converted CONST_VECTORs. Return CONST_VECTOR if it
can be converted to constant integer load.
(pass_x86_cse::candidate_vector_p): Add an INSN argument and
pass the insn to ix86_broadcast_inner.
(pass_x86_cse::x86_cse): Add a basic block bitmap for calls.
Pass the insn to candidate_vector_p. Handle X86_CSE_CONST_VECTOR.
Set dest_mode. Keep constant integer load when crossing a
function call. Convert CONST_VECTOR load no larger than integer
register to constant integer load even if there are no redundant
CONST_VECTOR loads.
Eikansh Gupta [Wed, 6 May 2026 12:38:45 +0000 (18:08 +0530)]
MATCH: Add simplification for MAX<a&CST0,a&CST1> and MIN<a&CST0,a&CST1> to match.pd [PR109878]
Min and max could be optimized if both operands are defined by
(same) variable restricted by an and(&). For signed types,
optimization can be done when both constant have same sign bit.
The patch also adds optimization for specific case of min/max(a, a&CST).
This patch adds match pattern for:
max (a & CST0, a & CST1) -> a & CST0 IFF CST0 & CST1 == CST1
min (a & CST0, a & CST1) -> a & CST0 IFF CST0 & CST1 == CST0
min (a, a & CST) --> a & CST
max (a, a & CST) --> a
The v2 of the patch has been approved. Patch link:
https://gcc.gnu.org/pipermail/gcc-patches/2024-July/657801.html
PR tree-optimization/109878
gcc/ChangeLog:
* match.pd(min/max (a & CST0, a & CST1)): New pattern.
(min/max (a, a & CST)): New pattern.
gcc/testsuite/ChangeLog:
* gcc.dg/tree-ssa/pr109878-1.c: New test.
* gcc.dg/tree-ssa/pr109878-2.c: New test.
* gcc.dg/tree-ssa/pr109878-3.c: New test.
* gcc.dg/tree-ssa/pr109878.c: New test.
Jeff Law [Thu, 7 May 2026 22:52:25 +0000 (16:52 -0600)]
[RISC-V][tree-optimization/106244] Improve code when generating (1 << N) & 0x1
So as noted in the PR, GCC fails to optimize this well:
int8_t f(int8_t x)
{
int8_t sh = 1 << x;
return sh & 1;
}
I strongly suspect this kind of code is exceedingly rare in practice. I just
happened to notice that it could be improved when looking for bugs to pass
along to Shreya & Austin. As noted in the PR, most of the time this is cleaned
up in gimple, but in some cases it slips through.
I'd love to tackle this in simplify-rtx, but SHIFT_COUNT_TRUNCATED, mode
handling for shift counts, subregs to deal with 32 bit objects on 64 bit
targets, etc make it fairly messy. Rather than spend a ton of time on it, I've
just created a simple risc-v splitter to handle the case of a 32bit shift on
rv64. The other cases can't be optimized.
I purposefully added the masking of the shift count. While the RISC-V port
does not define SHIFT_COUNT_TRUNCATED, it does have patterns that optimize away
the the masking when they can. If the masking got optimized away on the
assumption the count would be used in a shift/rotate and thus masked by the
hardware, we could have junk in the upper bits. It's worth noting that
because of the need to sanitize the shift count we're generating 2 insns, thus
we can't really improve for rv32 or for 64 bit objects on rv64. If we didn't
need to do that this would be a define_insn that generated a single
instruction.
Bootstrapped and regression tested on rv64 for on both the BPI and the Pioneer.
Also regression tested on riscv32-elf and riscv64-elf. Planning to push once
pre-commit CI gives the green light.
PR tree-optimization/106244
gcc/
* config/riscv/riscv.md ((and (ashift X Y) const_int 1)): New splitter.
gcc/testsuite/
* gcc.target/riscv/pr106244.c: New test.
Marek Polacek [Thu, 7 May 2026 13:51:53 +0000 (09:51 -0400)]
c++/reflection: ICE with bases_of [PR125206]
Here we crash in strip_typedefs_expr because we recurse on a
REFLECT_EXPR with TREE_BINFO as its operand, which is not a code this
function handles. It seems to me that we don't need to recurse for
REFLECT_EXPRs at all. Alternatively, we could just handle TREE_BINFO.
PR c++/125206
gcc/cp/ChangeLog:
* tree.cc (strip_typedefs_expr) <case REFLECT_EXPR>: Always
return instead of recursing.
rtlanal: Tweak operator precedence for comparisons
One quirk of the commutative operand precedence rules is that:
- PLUS and MINUS have precedence 4
- other binary arithmetic operators have precedence 2
- NOT and NEG have precedence 1
- (binary) comparison operators have precedence 0
This means that the arithmetic inverse operator (NEG) has a lower
precedence than the binary arithmetic operators, but the logical
inverse operator (NOT) has a higher precedence than binary comparisons
that produce a logical result. In other words, we have:
some binary > some unary > some other binary
This patch shuffles the precedence values so that all binary operators
have precedence over all unary operators. It means that existing
aarch64.md patterns such as:
This patch tackles two problems with the make_compound_operation(_int)
handling of PLUS:
(a) The PLUS case had some simplifications related to multiplications
of negative numbers. Those simplifications assigned the simplified
form to the variable "new_rtx", but the rest of the case ignored
new_rtx and returned the original expression "x". This had the
effect of discarding both the simplification result and the
recursive make_compound_operation results.
(b) The PLUS case applied maybe_swap_commutative_operands after
substituting the recursive make_compound_operation results.
That's good enough for unchained PLUSes. However, if the
expression is a nest of PLUSes, we might need to redistribute
operands in the entire nest.
For example, expand_compound_operation converts sign and zero
extensions to shifts. The extensions have commutative operand
priority 0, whereas the shifts have priority 2. This means that:
is correctly ordered, since PLUS has priority 4, NOT has priority 1,
and ZERO_EXTEND has priority 0. But when expand_compound_operation
converts the extends to shifts, the NOT becomes the lowest priority
operand, giving:
since, considered in isolation, neither PLUS needs a swap.
This result is not canonical, since the NOT should be first.
Both problems can be dealt with by using simplify_gen_binary instead.
That already has the simplifications for (a) and knows how to
redistribute operands in nested operations.
Although the MINUS case seemed to be ok, the simplifications there
also duplicate what simplify_gen_binary would do.
This is likely to be needed for Muhammad's uaddc/usubc patches.
gcc/
* combine.cc (make_compound_operation_int): Remove PLUS and MINUS
simplifications and PLUS operand order swapping. Delegate those
tasks to simplify_gen_binary instead.
object_allocator only allowed allocations to use the default constructor.
This patch generalises it to other constructors, in the same way as
rtl-ssa does for obstack allocations.
The first use case is likely to be Robin's backprop patch.
gcc/
* alloc-pool.h (object_allocator::allocate): Generalize to handle
non-default constructors.
Add post_ra_split_completed and use it for the RX port
Some targets need to be able to introduce new clobbers of the
condition-code register during register allocation. The main approach
for handling that situation is to ensure that the CC register is never
live before or during RA. This allows new clobbers to be introduced at
any time when !reload_completed.
This works well. However:
(a) Explicit uses and sets of the CC register are usually introduced by
the first post-reload split, rather than directly after RA.
(b) If the CC register is never live before and during RA, there is
no real need for patterns to have an explicit clobber of the CC
register at that point. Not having a CC clobber would allow more
recog attempts to succeed, both before and during RA. (AFAIK, only
combine and RTL-SSA keep tabs on when new CC clobbers can be
introduced as part of a recog attempt.)
(c) If a clobber of the CC register is hidden, it would need to be
made explicit before, or at the same time as, the explicit uses
and sets from (a).
The idea of this patch is therefore to allow the boundary between
"CC is never live" and "CC might be live" to be moved from
reload_completed to the first post-RA split. It converts the
RX port to this form.
gcc/
* rtl.h (post_ra_split_completed): Declare.
* final.cc (rest_of_clean_state): Set it to false.
* recog.cc (post_ra_split_completed): New variable.
(split_insn): Temporarily set post_ra_split_completed while walking
the new instructions.
(split_all_insns, split_all_insns_noflow): Set post_ra_split_completed
after completing a post-reload split.
* config/rx/rx.md (*cmpsi, *tstsi, *cmpsf, *conditional_branch)
(*sccc, *stcc, *stcc_reg, *abssi2_flags, *addsi3_flags, adc_internal)
(*adc_flags, *andsi3_flags, *negsi2_flags, *one_cmplsi2_flags)
(*iorsi3_flags, *rotlsi3_flags, *rotrsi3_flags, *ashrsi3_flags)
(*lshrsi3_flags, *ashlsi3_flags, *sat, *subsi3_flags, sbb_internal)
(*sbb_flags, *xorsi3_flags, *bmcc): Require post_ra_split_completed
rather than reload_completed.
(comparesi3_<extend_types:code><small_int_modes:mode>, addsi3_flags)
(subsi3_flags): Require post_ra_split_completed.
Mikael Morin [Thu, 7 May 2026 18:48:26 +0000 (20:48 +0200)]
fortran: Add bounds checking code to the scalarizer block [PR125192]
In gfc_conv_expr_descriptor, the array bounds checking code is added
to the root block, which is a different block from the scalarizer block
used to generate the array descriptor reference. This causes the array
bounds checking code to come before, which can be problematic if the
descriptor reference uses variables generated by the scalarizer, as they
are used in bounds checking code before their definition in that case.
This change adds the bounds checking code to the same block the
scalarizer uses to generate the array descriptor reference, solving the
use before definition problem.
PR fortran/125192
PR fortran/125198
gcc/fortran/ChangeLog:
* trans-array.cc (gfc_conv_expr_descriptor): Add bounds checking
code to the outermost loop's preliminary block.
Mikael Morin [Thu, 7 May 2026 18:48:13 +0000 (20:48 +0200)]
fortran: Only pass the block for bounds check generation
Among the scalarized expression SE passed as argument to the array
bounds check generation function, only the PRE block field is used,
to populate it with the bounds checking code.
This change refactors the code, so that only the block is passed as
argument and not a full scalarized expression.
gcc/fortran/ChangeLog:
* trans-array.cc (trans_array_bound_check): Replace references
to SE->PRE with references to the new argument BLOCK. Remove
argument SE.
(array_bound_check_elemental): Likewise. Update caller.
(conv_array_index_offset): Update caller.
(gfc_conv_expr_descriptor): Update caller.
This patch resolves PR middle-end/122871 by improving RTL expansion of
doubleword multiplications. The main change is to synth_mult adding
support for the case where the constant being multiplied has BITS_PER_WORD
or more trailing zeros. The shift_cost tables in expmed are only
parameterized for shifts less than BITS_PER_WORD, so doubleword shifts
by more than this can't use the usual code path. This patch teaches
synth_mult that for scalar doubleword multiplications, a doubleword shift
by more than BITS_PER_WORD typically requires two instructions; one to
set the result lowpart to zero, and the other a wordmode shift to
calculate the result highpart.
For the testcase given in the PR:
long long ashll_fn (long long a)
{
long long c;
c = a << 33;
c += a;
return c;
}
GCC for arm-linux-gnueabihf currently generates with -O2:
Additionally, this patch includes a clean-up (identified by A. Pinski)
to prevent RTL expansion of doubleword multiplications from
initially emitting multiply instructions by immediate constants 0, 1
or 2. These dubious multiplications eventually get tidied up by later
RTL optimization passes, but being sensible during RTL expansion
both speeds up the compiler and reduces unnecessary memory usage.
2026-05-07 Roger Sayle <roger@nextmovesoftware.com>
gcc/ChangeLog
PR middle-end/122871
* expmed.cc (synth_mult): Handle doubleword left shifts by
BITS_PER_WORD bits or more, for scalar modes.
* optabs.cc (expand_doubleword_mult): Avoid generating multiply
instructions by immediate constants 0, 1 or 2.
gcc/testsuite/ChangeLog
PR middle-end/122871
* gcc.target/arm/muldi-1.c: New test case.
Jakub Jelinek [Thu, 7 May 2026 15:31:09 +0000 (17:31 +0200)]
c++: Improve REFLECT_EXPR printing [PR125007]
The following patch fixes REFLECT_EXPR printing. Currently it prints everything
as ^^ followed by dumping the decl/type/expr handle of the REFLECT_EXPR_HANDLE
except the weird printing of data member specifications.
E.g. annotations are printed as ^^ and dump_expr on the REFLECT_EXPR_HANDLE,
which is a TREE_LIST so it prints the TREE_VALUE of TREE_VALUE of that in
the end and prints e.g. reflection of [[=1]] as ^^1.
The following patch prints reflections of annotations as ^^[[=1]] which is
also not valid C++ syntax, but because the IL doesn't store the decl/type
etc. in whose DECL_ATTRIBUTES/TYPE_ATTRIBUTES it appears, I'm afraid we
can't do much better (like print annotations_of(^^something)[N]).
For REFLECT_BASE/REFLECT_PARM/REFLECT_DATA_MEMBER_SPEC/REFLECT_VALUE/REFLECT_OBJECT,
it attempts to use the C++ valid syntax, so prints
bases_of(^^type,std::meta::access_context::unchecked())[N] {aka base_type}
parameters_of(^^decl)[N] {aka param_name}
data_member_spec(^^type,{.name="foo"})
std::meta::reflect_constant(X)
std::meta::reflect_object(X)
etc.
2026-05-07 Jakub Jelinek <jakub@redhat.com>
PR c++/125007
* cp-tree.h (maybe_update_function_parm): Declare.
* reflect.cc (maybe_update_function_parm): No longer static.
* error.cc (dump_expr) <case REFLECT_EXPR>: Improve printing
of various reflections.
Jakub Jelinek [Thu, 7 May 2026 15:29:23 +0000 (17:29 +0200)]
testsuite: Fix up gcc.dg/analyzer/divide-by-zero-6.c test
On Thu, May 07, 2026 at 01:35:07PM +0800, H.J. Lu wrote:
> I got
>
> FAIL: gcc.dg/analyzer/divide-by-zero-6.c (test for warnings, line 14)
> FAIL: gcc.dg/analyzer/divide-by-zero-6.c at line 15 (test for
> warnings, line 14)
> FAIL: gcc.dg/analyzer/divide-by-zero-6.c (test for excess errors)
> Excess errors:
> /export/gnu/import/git/gitlab/x86-gcc/gcc/testsuite/gcc.dg/analyzer/divide-by-zero-6.c:14:18:
> warning: use of uninitialized value '*f.y' [CWE-457]
> [-Wanalyzer-use-of-uninitialized-value]
The warnings are correct, but I guess the test wasn't meant to test two
completely different thing, one on 64-bit targets and one on 32-bit ones.
struct foo { int x; int y; };
has sizeof (8) on most targets (except on non-32-bit int), but the test
was using __builtin_memset (f, 0, sizeof (f)) where f is a pointer.
Now, this happens to clear the whole structure on 64-bit targets but only
first half of it on 32-bit ones, so on 64-bit it emits the expected warning
about division by zero, while on 32-bit about using uninitialized value.
I think the testcase was meant to clear the whole structure on all arches,
the following patch does that.
2026-05-07 Jakub Jelinek <jakub@redhat.com>
* gcc.dg/analyzer/divide-by-zero-6.c (init_foo): Use sizeof (*f)
rather than sizeof (f).
Jakub Jelinek [Thu, 7 May 2026 13:50:14 +0000 (15:50 +0200)]
c++: Constant evaluation of __builtin_{,dynamic_}object_size [PR124347]
The following patch tries to support constexpr folding of
__builtin_object_size and __builtin_dynamic_object_size.
There is already folding of this builtin in builtins.cc, but it doesn't look
through pointer conversions in the argument, only handles the case where
the argument is ADDR_EXPR (plus of course when inside of the objsz passes it
handles more through SSA_NAME tracking).
I've tried to handle this in builtins.cc first, see
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=124347#c1 but unfortunately
that resulted in some serious security regressions where some of __bos
or __bdos builtins were folded prematurely, in particular e.g. for cases
where we have __builtin_object_size (something, 1) and the whole object
size is unknown but object size of the element is known. With the patch
it would just return the remaining subobject size, when it actually should
return MIN_EXPR <object_size, remaining subobject size>. For mode 1
it is conservatively correct, but larger than necessary with security
implications of not caching out of bounds accesses.
So, this patch instead handles this in the FE, only for manifestly constant
evaluation, by stripping the pointer casts on the first argument in that
case.
2026-05-07 Jakub Jelinek <jakub@redhat.com>
PR c++/124347
* constexpr.cc (cxx_eval_builtin_function_call): For
mce_true strip nops in first argument of BUILT_IN*_OBJECT_SIZE
if the inner expression is ADDR_EXPR.
* g++.dg/ext/builtin-object-size4.C: New test.
* g++.dg/ext/builtin-object-size5.C: New test.
* g++.dg/ext/builtin-object-size6.C: New test.
Avinash Jayakar [Wed, 4 Mar 2026 10:00:24 +0000 (05:00 -0500)]
rs6000: Builtins for AES acceleration instructions [RFC02657]
This patch adds new builtins for AES acceleration instructions which
may or may not be supported in a future processor. Note, the names of
the builtins may change in future.
The following new builtins for AES acceleration can be used with
-mcpu=future option:
__vector_pair __builtin_aes_encrypt_paired (__vector_pair,
__vector_pair, uint2);
__vector_pair __builtin_aes128_encrypt_paired (__vector_pair,
__vector_pair);
__vector_pair __builtin_aes192_encrypt_paired (__vector_pair,
__vector_pair);
__vector_pair __builtin_aes256_encrypt_paired (__vector_pair,
__vector_pair);
__vector_pair __builtin_aes_decrypt_paired (__vector_pair,
__vector_pair, uint2);
__vector_pair __builtin_aes128_decrypt_paired (__vector_pair,
__vector_pair);
__vector_pair __builtin_aes192_decrypt_paired (__vector_pair,
__vector_pair);
__vector_pair __builtin_aes256_decrypt_paired (__vector_pair,
__vector_pair);
__vector_pair __builtin_aes_genlastkey_paired (__vector_pair, uint2);
__vector_pair __builtin_aes128_genlastkey_paired (__vector_pair);
__vector_pair __builtin_aes192_genlastkey_paired (__vector_pair);
__vector_pair __builtin_aes256_genlastkey_paired (__vector_pair);
vec_t __builtin_galois_field_mult (vec_t, vec_t, uint1);
vec_t __builtin_galois_field_mult_gcm (vec_t, vec_t);
vec_t __builtin_galois_field_mult_xts (vec_t, vec_t);
gcc/ChangeLog:
* config/rs6000/crypto.md (UNSPEC_XXAESENCP): New unspec entry.
(UNSPEC_XXAES128ENCP): Likewise.
(UNSPEC_XXAES192ENCP): Likewise.
(UNSPEC_XXAES256ENCP): Likewise.
(UNSPEC_XXAESDECP): Likewise.
(UNSPEC_XXAES128DECP): Likewise.
(UNSPEC_XXAES192DECP): Likewise.
(UNSPEC_XXAES256DECP): Likewise.
(UNSPEC_XXAESGENLKP): Likewise.
(UNSPEC_XXAES128GENLKP): Likewise.
(UNSPEC_XXAES192GENLKP): Likewise.
(UNSPEC_XXAES256GENLKP): Likewise.
(UNSPEC_XXGFMUL128): Likewise.
(UNSPEC_XXGFMUL128GCM): Likewise.
(UNSPEC_XXGFMUL128XTS): Likewise.
(AESACC_base_code): New iterator for xxaesencp and xxaesdecp base
mnemonics.
(AESACC_code): New iterator for xxaesencp and xxaesdecp extended
mnemonics.
(AESGENLKP_code): New iterator for xxaesgenlkp extended mnemonics.
(AESGF_code): New iterator for xxgfmul128 extended mnemonics.
(AESACC_base_insn): New attribute iterator for xxaesencp and xxaesdecp
base mnemonics.
(AESACC_insn): New attribute iterator for xxaesencp and xxaesdecp
extended mnemonics.
(AESGENLKP_insn): New attribute iterator for xxaesgenlkp extended
mnemonics.
(AESGF_insn): New attribute iterator for xxgfmul128 extended mnemonics.
(<AESACC_base_insn>): New define_insn for xxaesencp and xxaesdecp base
mnemonics.
(<AESACC_insn>): New define_insn for xxaesencp and xxaesdecp extended
mnemonics.
(<AESGENLKP_insn>): New define_insn for xxaesgenlkp extended mnemonics.
(xxaesgenlkp): New define_insn for genlkp base mnemonic.
(<AESGF_insn>): New define_insn for xxgfmul128 extended mnemonics.
(xxgfmul128): New define_insn for xxgfmul128 base mnemonic.
* config/rs6000/rs6000-builtins.def: Added new builtin definitions for
AES acceleration.
* doc/extend.texi: Add new section for AES acceleration builtins
for Future ISA.
gcc/testsuite/ChangeLog:
* gcc.target/powerpc/aes-builtin-1.c: New test.
* gcc.target/powerpc/aes-builtin-2.c: New test.
* gcc.target/powerpc/aes-builtin-3.c: New test.
Jonathan Wakely [Wed, 22 Apr 2026 14:37:16 +0000 (15:37 +0100)]
libstdc++: Constrain tuple(tuple&&) [PR78302]
Since C++20 the std::tuple move constructor should be constrained (as
modified by LWG 2899).
We already define the move constructor as defaulted, but it's not
implicitly defined as deleted for non-move-constructible element types
because the _Tuple_impl(_Tuple_impl&&) constructor is user-provided and
unconstrained. For C++20 and later we use a requires-clause to constrain
the defaulted tuple(tuple&&) constructor.
Ideally we'd make this change pre-C++20 as well, but that's harder to do
without using a requires-clause, so this change is only for C++20 and
later. I think that's OK, but if we need to change it for pre-C++20
later we can consider inheriting from _Enable_copy_move<..., tuple> to
make the defaulted move constructor defined as deleted.
Tomasz Kamiński [Wed, 7 Jan 2026 13:01:41 +0000 (14:01 +0100)]
libstdc++: Rework istreambuf_iterator::_M_sbuf handling to slice null-dereference warning [PR105580]
The warning was produced by following sequence, given an istream_iterator<char>
it, such that *it will result in hitting EoF in it->_M_get(), and thus clearing
_M_sbuf, the subsequent call to ++it, will result in _M_sbuf->sbumpc() call on
null pointer. This is however an false-positive, as in such situation
it == istream_iteator() returns true, and the iterator should not be
incremented in first place.
This patch addresses the above by clearing the _M_sbuf in operator++, instead
of _M_get(). This removes the need for making _M_sbuf mutable, and thus make
the implementation conforming with regards to C++11 [res.on.data.races] p3.
Also removes no longer needed "-Wnull-dereference" disabling pragmas from
streambuf (see r16-7844-gbfc2b87f8244a1).
This change should have zero or positive performance impact on the usual
iteration patterns, in form:
while (it != end) { process(*it); ++it; }
In case when it is end-of-stream iterator, the it != end returns in one call
of _M_sbuf->sgetc() both before and after the change. However we do not modify
_M_sbuf in this case. For non-empty range, we replace call to _M_sbuf->sbumpc()
with _M_sbuf->snextc() in pre-increment, and extract the check against EoF from
*it to ++it. However, as _M_sbuf is now cleared during increment, so last
it != end check avoids _M_sbuf->sgetc() call to check against EoF.
However, this change impact the behavior of the post-increment (*it++), as
we now load both current character (for return value) and next character (to
check against EoF). In consequence we call both sgetc() and snextc(),
in contrast to previous single sbumpc() call.
PR libstdc++/105580
libstdc++-v3/ChangeLog:
* include/bits/streambuf_iterator.h (istreambuf_iterator::_M_sbuf):
Remove mutable and adjust whitespace.
(istreambuf_iterator::_M_c): Adjust whitespace.
(istreambuf_iterator::operator++()): Clear _M_sbuf if next character
is EoF.
(istreambuf_iterator::operator++(int)): Use _M_sbuf->sgetc() to
load current character, and define in terms of ++*this.
(istreambuf_iterator::_M_get()): Do not clear _M_sbuf in case of EoF.
* include/std/streambuf (streambuf::gptr, streambuf::egptr)
(streambuf::gbump): Remove surrounding pragma disabling -Wnull-dereference.
* testsuite/24_iterators/istreambuf_iterator/2.cc: Test for using
multiple iterators to same rdbuf.
Reviewed-by: Jonathan Wakely <jwakely@redhat.com> Signed-off-by: Tomasz Kamiński <tkaminsk@redhat.com>
Paul Thomas [Thu, 7 May 2026 07:04:27 +0000 (08:04 +0100)]
Fortran: Fix complex associate-name with inferred kind [PR125172]
2026-05-07 Samir Ouchene <samirmath01@gmail.com
gcc/fortran
PR fortran/125172
* resolve.cc (gfc_fixup_inferred_type_refs): Update kind for
INQUIRY_RE and INQUIRY_IM references on inferred complex
associate-name.
(resolve_variable): For an inferred-type associate-name with
no subobject ref, refresh e->ts from sym->ts.
(resolve_assoc_var): For an inferred-type complex/character
associate-name, refresh sym->ts from the resolved target when
only the kind differs.
gcc/testsuite
PR fortran/125172
* gfortran.dg/associate_79.f90: New test.
Jakub Jelinek [Thu, 7 May 2026 06:54:21 +0000 (08:54 +0200)]
c++: Fix up extract_ref [PR125111]
https://eel.is/c++draft/meta.reflection.extract#5.2 requests that
is_convertible_v<remove_reference_t<U>(*)[], remove_reference_t<T>(*)[]>
is tested and if it not true, the function throws.
If U/T are references to function/method/array[], we try to build
array of types which are not valid in arrays and ICE shortly after that.
The following patch makes sure we don't create arrays in that case
and instead just throw the exception. We can't have references to void
or references to references, so I think the other problematic cases
of creating arrays can't trigger.
2026-05-07 Jakub Jelinek <jakub@redhat.com>
PR c++/125111
* reflect.cc (extract_ref): Throw instead of trying to build
arrays of functions, methods or arrays with NULL TYPE_DOMAIN.
Jakub Jelinek [Thu, 7 May 2026 06:45:32 +0000 (08:45 +0200)]
c++: Reflection vs. CLASSTYPE_TYPEINFO_VAR/ANON_AGGR_TYPE_FIELD sharing [PR124991]
typeinfo_var element of lang_type is used for 2 purposes,
CLASSTYPE_TYPEINFO_VAR and ANON_AGGR_TYPE_FIELD, a VAR_DECL for types
for which we need typeid etc. and FIELD_DECL for anonymous union/struct
types inside of classes.
Without reflection one can't ask for typeid of the anonymous union/struct
types, so sharing the same tree for both purposes is fine, but with
reflection we can ICE.
As anonymous unions are fairly rare and asking about typeid of those will be
even rarer, the following patch attempts to fix that without actually
growing the lang_type struct size by using the same tree for both. If it
is NULL_TREE, both CLASSTYPE_TYPEINFO_VAR and ANON_AGGR_TYPE_FIELD
are NULL, if it is a VAR_DECL, it is the former, if it is a FIELD_DECL,
it is the latter, in the really rare case we need both it is turned
into a TREE_LIST where TREE_VALUE is CLASSTYPE_TYPEINFO_VAR and
TREE_PURPOSE is ANON_AGGR_TYPE_FIELD.
Note, CWG3130 fortunately disallows attempts to create a different object
of ANON_AGGR_TYPE_P type (will need to implement that part), so the other
worries from PR124991 (that one can create a variable or member or parameter
etc. with the anon union type and get confused by ANON_AGGR_TYPE_FIELD on it
or trying to tweak lookup rules etc.) are gone.
2026-05-07 Jakub Jelinek <jakub@redhat.com>
PR c++/124991
* cp-tree.h (struct lang_type): Document typeinfo_var member.
(get_classtype_typeinfo_var): New inline function.
(CLASSTYPE_TYPEINFO_VAR): Use it.
(set_classtype_typeinfo_var): New inline function.
(SET_CLASSTYPE_TYPEINFO_VAR): Define.
(get_anon_aggr_type_field): New inline function.
(ANON_AGGR_TYPE_FIELD): Use it.
(set_anon_aggr_type_field): New inline function.
(SET_ANON_AGGR_TYPE_FIELD): Define.
* decl.cc (fixup_anonymous_aggr): Use SET_ANON_AGGR_TYPE_FIELD
instead of ANON_AGGR_TYPE_FIELD.
* module.cc (trees_in::read_class_def): Use
SET_CLASSTYPE_TYPEINFO_VAR instead of setting
CLASSTYPE_TYPEINFO_VAR and do it even for ANON_AGGR_TYPE_P
types. Use SET_ANON_AGGR_TYPE_FIELD instead of setting
ANON_AGGR_TYPE_FIELD.
* rtti.cc (get_tinfo_decl_direct): Use SET_CLASSTYPE_TYPEINFO_VAR
instead of setting CLASSTYPE_TYPEINFO_VAR.
* semantics.cc (finish_member_declaration): Use
SET_ANON_AGGR_TYPE_FIELD instead of setting ANON_AGGR_TYPE_FIELD.
Pan Li [Tue, 5 May 2026 05:44:46 +0000 (13:44 +0800)]
RISC-V: Combine vec_duplicate + vmsgt.vv to vmsgt.vx on GR2VR cost
This patch would like to combine the vec_duplicate + vmsgt.vv to the
vmsgt.vx. From example as below code. The related pattern will depend
on the cost of vec_duplicate from GR2VR. Then the late-combine will
take action if the cost of GR2VR is zero, and reject the combination
if the GR2VR cost is greater than zero.
Assume we have asm code like below, GR2VR cost is 0.
Harald Anlauf [Tue, 5 May 2026 20:00:43 +0000 (22:00 +0200)]
Fortran: fix namelist read for input with comments [PR125095]
Namelist input may contain comments (initiated with a "!") after a
separator or in the first nonblank position of a namelist input record.
Skip comments until end of line, and eat leading whitespace in a subsequent
input record.
Martin Uecker [Sat, 25 Apr 2026 18:14:13 +0000 (20:14 +0200)]
c: Fix use of variably-modified structure/union types in nested context [PR124985]
If a nested function uses a variably-modified structure or union type
that depends on the enclosing context, it needs the static chain.
My recent change missed this, because in this case no decl was used.
To address this, we now call mark_decl_used also on TYPE_STUB_DECLs.
PR c/124985
gcc/c/ChangeLog:
* c-decl.cc (pushtag): Update comment.
(declspecs_add_type): Mark TYPE_STUB_DECL as used.
* c-typeck.cc (function_to_pointer_conversion): Fix grammar in comment.
gcc/testsuite/ChangeLog:
* gcc.dg/Wreturn-nested-3.c: New test.
* gcc.dg/pr124985.c: New test.
David Malcolm [Wed, 6 May 2026 14:22:57 +0000 (10:22 -0400)]
analyzer: show value ranges in svalue::dump
This patch adds value_range info where available to the various nodes
in svalue dumps, such as:
(gdb) call rhs2_sval->dump ()
(27): ‘long long unsigned int’: binop_svalue(bit_and_expr: ‘&’) value range: {[irange] long long unsigned int [0, 0]}
├─ (24): ‘long long unsigned int’: unaryop_svalue(nop_expr) value range: {[irange] long long unsigned int [0, 4294967295] MASK 0xffffffff VALUE 0x0}
│ ╰─ (22): ‘unsigned int’: initial_svalue value range: {[irange] unsigned int VARYING}
│ ╰─ m_reg: (21): ‘unsigned int’: decl_region(‘m’)
│ ╰─ parent: (4): globals
│ ╰─ parent: (0): root region
╰─ (26): ‘long long unsigned int’: constant_svalue (‘5497558138880’) value range: {[irange] long long unsigned int [5497558138880, 5497558138880]}
where we can see that sval 27 has value range [0,0] and
where that comes from (due to being a bit_and_expr of non-overlapping
ranges from sval 24 and 26).
gcc/analyzer/ChangeLog:
* svalue.cc (svalue::make_dump_widget): Show value ranges in
svalue dumps.
gcc/ChangeLog:
* value-range.cc (value_range::print): New, based on
value_range::dump.
* value-range.h (value_range::print): New decl.
Signed-off-by: David Malcolm <dmalcolm@redhat.com>
Jonathan Wakely [Tue, 5 May 2026 12:54:02 +0000 (13:54 +0100)]
libstdc++: Simplify std::shared_ptr internals
Now that we don't use the EBO we can flatten the _Sp_counted_deleter and
_Sp_counted_ptr_inplace layouts by removing their _Impl classes.
libstdc++-v3/ChangeLog:
* include/bits/out_ptr.h (out_ptr_t::_Impl::~_Impl): Adjust
access to shared_ptr internals.
* include/bits/shared_ptr_base.h (_Sp_counted_deleter): Remove
_Impl class and replace _M_impl with the data members it
contained.
(_Sp_counted_ptr_inplace): Likewise.
Reviewed-by: Tomasz Kamiński <tkaminsk@redhat.com>
Jonathan Wakely [Tue, 5 May 2026 12:39:24 +0000 (13:39 +0100)]
libstdc++: Replace uses of EBO with [[no_unique_address]]
Clang 9 added support for [[__no_unique_address__]] and we don't support
Intel icc any longer, so we can remove the code in <tuple> that works
around the absence of that attribute. We can also address a FIXME in
<bits/shared_ptr_base.h> and replace uses of EBO with the attribute.
libstdc++-v3/ChangeLog:
* include/bits/shared_ptr_base.h (_Sp_ebo_helper): Simplify by
using [[__no_unique_address__]] instead of EBO. Use the
attribute unconditionally for the unstable ABI.
(_Sp_counted_deleter::_Impl): Adjust uses of _Sp_ebo_helper.
(_Sp_counted_ptr_inplace::_Impl): Likewise.
* include/std/tuple (_Head_base): Remove implementation for
compilers that don't support [[__no_unique_address__]]. Use the
attribute unconditionally for the unstable ABI.
Reviewed-by: Tomasz Kamiński <tkaminsk@redhat.com>
David Malcolm [Wed, 6 May 2026 13:57:07 +0000 (09:57 -0400)]
analyzer: generating raw state for rewinding data flow
The previous patch used the states of the exploded nodes at each end of
an exploded edge for rewinding state, but this doesn't always work when
state purging is active (the default) due to the state purging
eliminating pertinent information. This can be see in
gcc.dg/analyzer/divide-by-zero-{4,5,6}.c, which required
-fno-analyzer-state-purge to rewind the data flow to locate where the
zero values were coming from.
This patch extends diagnostic_manager::annotate_exploded_path so that
it performs an initial forward walk through the exploded path, building
region_model instances along the path without any state purging or
merging, and updates the rewind_context to use these states to rewind
pertinent state for a diagnostic.
Doing so allows us to drop -fno-analyzer-state-purge from the testcases
which needed them before.
gcc/analyzer/ChangeLog:
* analyzer-logging.h (class text_art::canvas): New forward decl.
(logger::log_canvas): New decl.
* diagnostic-manager.cc (path_builder::get_supergraph): New.
(logger::log_canvas): New.
(dump_to_logger): New.
(log_region_model): New.
(epath_rewind_context::epath_rewind_context): Add params
src_model and dst_model, using them to initialize m_src_model and
m_dst_model.
(epath_rewind_context::get_src_region_model): New.
(epath_rewind_context::get_dst_region_model): New.
(epath_rewind_context::m_src_model): New.
(epath_rewind_context::m_dst_model): New.
(make_raw_dst_region_model): New.
(diagnostic_manager::annotate_exploded_path): Walk EPATH forwards,
populating new vectors src_models and dst_models without state
purging or merging, so that we can reliably rewind state. Pass
these models to epath_rewind_context when rewinding state.
* engine.cc (interprocedural_call::try_to_rewind_data_flow): Get
src and dst region_model instances via vfuncs of ctxt, rather than
accessing the eedge.
* ops.cc (rewind_context::on_data_origin): Get src and dst
region_model instances via vfuncs of ctxt, rather than accessing
the eedge.
(greturn_op::try_to_rewind_data_flow): Likewise.
* ops.h (rewind_context::rewind_context): Drop param "eedge".
(rewind_context::get_src_region_model): New vfunc.
(rewind_context::get_dst_region_model): New vfunc.
(rewind_context::m_eedge): Drop field.
int
test (int flag, int flag_2, int flag_3)
{
struct foo f;
int a = 42;
int b = get_zero ();
init_foo (&f, a, b);
return do_divide (&f);
}
Before this patch, we emit:
demo.c: In function ‘do_divide’:
demo.c:24:15: warning: division by zero [-Wanalyzer-div-by-zero]
24 | return f->x / f->y;
| ~~~~~^~~~~~
‘test’: events 1-2
│
│ 28 | test (int flag, int flag_2, int flag_3)
│ | ^~~~
│ | |
│ | (1) entry to ‘test’
│......
│ 34 | return do_divide (&f);
│ | ~~~~~~~~~~~~~~
│ | |
│ | (2) calling ‘do_divide’ from ‘test’
│
└──> ‘do_divide’: events 3-4
│
│ 22 | do_divide (struct foo *f)
│ | ^~~~~~~~~
│ | |
│ | (3) entry to ‘do_divide’
│ 23 | {
│ 24 | return f->x / f->y;
│ | ~~~~~~~~~~~
│ | |
│ | (4) ⚠️ division by zero
│
which doesn't convey where the zero value came from.
This patch adds various wording and new events to tracking where the
problematic value comes from. diagnostic_manager::annotate_exploded_path walks
backwards from the final enode, building a chain of instances of a new
state_transition class hierarchy. These state_transition instances are
associated with checker_events where possible (e.g. at function entry),
otherwise, new state_transition_events are added for them, highlighting
e.g. where the pertinent zero value is passed as a parameter.
With the patch, we emit:
demo.c: In function ‘do_divide’:
demo.c:24:15: warning: division by zero [-Wanalyzer-div-by-zero]
24 | return f->x / f->y;
| ~~~~~^~~~~~
‘test’: events 1-2
│
│ 28 | test (int flag, int flag_2, int flag_3)
│ | ^~~~
│ | |
│ | (1) entry to ‘test’
│......
│ 32 | int b = get_zero ();
│ | ~~~~~~~~~~~
│ | |
│ | (2) calling ‘get_zero’ from ‘test’
│
└──> ‘get_zero’: events 3-4
│
│ 7 | get_zero (void)
│ | ^~~~~~~~
│ | |
│ | (3) entry to ‘get_zero’
│ 8 | {
│ 9 | return 0;
│ | ~
│ | |
│ | (4) zero value originates here
│
<──────┘
│
‘test’: events 5-6
│
│ 32 | int b = get_zero ();
│ | ^~~~~~~~~~~
│ | |
│ | (5) returning zero from (4) from ‘get_zero’ here
│ 33 | init_foo (&f, a, b);
│ | ~~~~~~~~~~~~~~~~~~~
│ | |
│ | (6) passing zero from (5) from ‘test’ to ‘init_foo’ via parameter 3
│
└──> ‘init_foo’: events 7-8
│
│ 15 | init_foo (struct foo *f, int x, int y)
│ | ~~~~^
│ | |
│ | (7) entry to ‘init_foo’ with zero from (5) for ‘y’
│......
│ 18 | f->y = y;
│ | ~~~~~~~~
│ | |
│ | (8) copying zero value from (7) from ‘y’ to ‘*f.y’
│
<──────┘
│
‘test’: events 9-10
│
│ 33 | init_foo (&f, a, b);
│ | ^~~~~~~~~~~~~~~~~~~
│ | |
│ | (9) returning to ‘test’ from ‘init_foo’
│ 34 | return do_divide (&f);
│ | ~~~~~~~~~~~~~~
│ | |
│ | (10) calling ‘do_divide’ from ‘test’
│
└──> ‘do_divide’: events 11-13
│
│ 22 | do_divide (struct foo *f)
│ | ^~~~~~~~~
│ | |
│ | (11) entry to ‘do_divide’
│ 23 | {
│ 24 | return f->x / f->y;
│ | ~~~~~~~~~~~
│ | | |
│ | | (12) using zero value from (8) from ‘*f.y’
│ | (13) ⚠️ division by zero
│
Note:
* the new "(4) zero value originates here" state transition event,
* the precision-of-wording for the return event at (5),
* the precision-of-wording for the call event at (6),
* the precision-of-wording for the function entry event at (7), and the
underlining of the pertinent parameter
* the above call/return events no longer get optimized away, due to...
* the new "(8) copying zero value from (7) from ‘y’ to ‘*f.y’" state
transition event
* the new "(12) using zero value from (8) from ‘*f.y’" state transition
event
gcc/ChangeLog:
* Makefile.in (ANALYZER_OBJS): Add analyzer/state-transition.o.
* digraph.cc (test_path::append_edge): New.
(test_path::reverse): New.
* shortest-paths.h (get_shortest_path): Use append_edge and
reverse.
* tree-diagnostic.h
(tree_dump_pretty_printer::~tree_dump_pretty_printer): Only flush
when the buffer's stream is non-null.
gcc/analyzer/ChangeLog:
* analyzer.cc (printable_expr_p): New.
* call-info.cc: Include "analyzer/state-transition.h".
(call_info::add_events_to_path): Add state_transition param.
* call-info.h (call_info::add_events_to_path): Likewise.
* callsite-expr.h: New file, based on material from supergraph.h.
(class callsite_expr_element): New.
* checker-event.cc: Include "analyzer/callsite-expr.h" and
"analyzer/state-transition.h".
(event_kind_to_string): Handle event_kind::state_transition.
(state_transition_event::print_desc): New.
(state_transition_event::prepare_for_emission): New.
(function_entry_event::function_entry_event): Drop.
(function_entry_event::print_desc): Use any m_state_trans.
(function_entry_event::prepare_for_emission): New.
(call_event::call_event): Add "state_trans" param and store it in
m_state_trans.
(call_event::print_desc): Use m_state_trans if present to call
describe_call_with_state, adding a fallback wording for
pending_diagnostic subclasses that don't implement it.
(call_event::prepare_for_emission): New, storing event id into
state_transition.
(return_event::return_event): Add "state_trans" param and store it
in m_state_trans.
(return_event::print_desc): Use m_state_trans if present to call
describe_return_of_state.
(return_event::prepare_for_emission): New, storing event id into
state_transition.
* checker-event.h (enum class event_kind): Add state_transition.
(class state_transition_event): New.
(function_entry_event::function_entry_event): Add "state_trans"
param and store it in m_state_trans. Drop 2nd ctor.
(function_entry_event::prepare_for_emission): New decl.
(function_entry_event::get_state_transition_at_call): New.
(function_entry_event::m_state_trans): New.
(call_event::call_event): Add "state_trans" param.
(call_event::prepare_for_emission): New decl.
(call_event::get_state_transition_at_call): New.
(call_event::m_state_trans): New.
(return_event::return_event): Add "state_trans" param.
(return_event::prepare_for_emission): New decl.
(return_event::m_state_trans): New.
* common.h: Define INCLUDE_ALGORITHM.
(class state_transition): New forward decl
(class state_transition_at_call): New forward decl
(class state_transition_at_return): New forward decl
(printable_expr_p): New decl.
(struct diagnostic_state): New.
(struct rewind_context): New forward decl.
(custom_edge_info::add_events_to_path): Add "state_trans" param.
(try_to_rewind_data_flow): New vfunc.
* diagnostic-manager.cc (compatible_epath_p): Update for change
from m_edges to m_elements.
(diagnostic_manager::emit_saved_diagnostic): Make "epath"
non-const. Call annotate_exploded_path on it and log before and
after. Update for new param to add_events_for_eedge.
(class epath_rewind_context): New.
(diagnostic_manager::annotate_exploded_path): New.
(diagnostic_manager::build_emission_path): Update for change from
m_edges to m_elements. Pass any state transition to
add_events_for_eedge.
(diagnostic_manager::add_events_for_eedge): Add "state_trans"
parameter. Pass it when creating events, and if we don't create
an event referencing it, make a state_transition_event for it.
(diagnostic_manager::prune_for_sm_diagnostic): Handl
event_kind::state_transition.
* diagnostic-manager.h (saved_diagnostic::get_best_epath): Drop
"const" from return value.
(diagnostic_manager::annotate_exploded_path): New decl.
(diagnostic_manager::add_events_for_eedge): Add "state_trans"
param.
* engine.cc: Include "pretty-print-markup.h".
(leak_ploc_fixer_for_epath::fixup_for_epath): Update for change
from m_edges to m_elements.
(throw_custom_edge::add_events_to_path): Add state_transition
param.
(unwind_custom_edge::add_events_to_path): Likewise.
(interprocedural_call::print): Use get_gcall.
(interprocedural_call::update_model): Likewise.
(interprocedural_call::add_events_to_path): Likewise. Pass
state_transition if of correct subclass.
(interprocedural_call::try_to_rewind_data_flow): New.
(interprocedural_call::get_gcall): New.
(interprocedural_return::add_events_to_path): Add state_transition
param and pass if of correct subclass.
(interprocedural_return::try_to_rewind_data_flow): New.
(tainted_args_function_info::add_events_to_path): Add
state_transition param.
(tainted_args_call_info::add_events_to_path): Likewise.
* event-loc-info.h (event_loc_info_for_function_entry): New decl.
* exploded-graph.h (interprocedural_call::interprocedural_call):
Pass and store call_and_return_op rather than gcall.
(interprocedural_call::add_events_to_path): Add state_trans param.
(interprocedural_call::try_to_rewind_data_flow): New.
(interprocedural_call::m_call_stmt): Replace with...
(interprocedural_call::m_op): ...this.
(interprocedural_return::add_events_to_path): Add state_trans
param.
(interprocedural_return::try_to_rewind_data_flow): New.
(rewind_info_t::add_events_to_path): New.
* exploded-path.cc (exploded_path::exploded_path): Drop explicit
copy ctor.
(diagnostic_state::dump_to_pp): New.
(diagnostic_state::dump): New.
(exploded_path::find_stmt_backwards): Update for change from
m_edges to m_elements.
(exploded_path::get_final_enode): Likewise.
(exploded_path::feasible_p): Likewise.
(exploded_path::dump_to_pp): Likewise. Dump state transitions.
(exploded_path::maybe_log): New.
(exploded_path::reverse): New.
* exploded-path.h: Include "analyzer/checker-event.h" and
"analyzer/state-transition.h".
(struct exploded_path::element_t): New.
(exploded_path::exploded_path): Replace ctors with "= default".
(exploded_path::length): Reimplement.
(exploded_path::maybe_log): New decl.
(exploded_path::append_edge): New.
(exploded_path::reverse): New.
(exploded_path::m_edges): Replace with...
(exploded_path::m_elements): ...this, using std::vector rather
than auto_vec.
* feasible-graph.cc (feasible_graph::make_epath): Update for
change from m_edges to m_elements.
* infinite-recursion.cc
(infinite_recursion_diagnostic::add_function_entry_event): Add
"state_trans" param and pass it to base class call.
(recursive_function_entry_event::recursive_function_entry_event):
Pass nullptr for state transition.
* ops.cc: Include "analyzer/callsite-expr.h" and
"analyzer/state-transition.h".
(event_loc_info_for_function_entry): New.
(rewind_context::on_data_origin): New.
(rewind_context::on_data_flow): New.
(gassign_op::try_to_rewind_data_flow): New.
(greturn_op::try_to_rewind_data_flow): New.
(call_and_return_op::execute): Update for change to
interprocedural_call.
(call_and_return_op::try_to_rewind_data_flow): New.
(phis_for_edge_op::try_to_rewind_data_flow): New.
* ops.h (struct rewind_context): New.
(operation::try_to_rewind_data_flow): New vfunc.
(gassign_op::try_to_rewind_data_flow): New.
(predict_op::try_to_rewind_data_flow): New.
(greturn_op::try_to_rewind_data_flow): New.
(call_and_return_op::try_to_rewind_data_flow): New.
(control_flow_op::try_to_rewind_data_flow): New.
(phis_for_edge_op::try_to_rewind_data_flow): New.
* pending-diagnostic.cc (interesting_t::add_read_region): New.
(interesting_t::dump_to_pp): Dump m_read_regions.
(pending_diagnostic::add_function_entry_event): Add "state_trans"
param and pass it to function_entry_event. Call
event_loc_info_for_function_entry.
(pending_diagnostic::add_call_event): Add "state_trans" param and
pass it to call_event.
* pending-diagnostic.h: Include "analyzer/state-transition.h".
(struct interesting_t): Update leading comment.
(interesting_t::add_read_region): New.
(interesting_t::m_read_regions): New.
(struct origin_of_state): New.
(call_with_state::call_with_state): Add state_trans param and use
it to initialize m_state_trans and m_src_event_id.
(call_with_state::m_state_trans): New field.
(call_with_state::m_src_event_id): New field.
(return_of_state::return_of_state): Add state_trans param and use
it to initialize m_state_trans and m_src_event_id.
(return_of_state::m_state_trans): New field.
(return_of_state::m_src_event_id): New field.
(struct copy_of_state): New.
(struct use_of_state): New.
(pending_diagnostic::describe_origin_of_state): New vfunc.
(pending_diagnostic::describe_copy_of_state): New vfunc.
(pending_diagnostic::describe_use_of_state): New vfunc.
(pending_diagnostic::add_function_entry_event): Add "state_trans"
param.
(pending_diagnostic::add_call_event): Likewise.
* poisoned-value-diagnostic.cc
(poisoned_value_diagnostic::mark_interesting_stuff): Add call to
add_read_region.
* region-model.cc: Include "analyzer/state-transition.h".
(callsite_expr::maybe_get_param_location): New.
(callsite_expr::get_param_tree): New.
(div_by_zero_diagnostic::div_by_zero_diagnostic): Add
"divisor_reg" param and use it to initialize m_divisor_reg.
(div_by_zero_diagnostic::mark_interesting_stuff): New.
(div_by_zero_diagnostic::add_function_entry_event): New.
(div_by_zero_diagnostic::describe_origin_of_state): New.
(div_by_zero_diagnostic::describe_call_with_state): New.
(div_by_zero_diagnostic::describe_return_of_state): New.
(div_by_zero_diagnostic::describe_copy_of_state): New.
(div_by_zero_diagnostic::describe_use_of_state): New.
(div_by_zero_diagnostic::m_divisor_reg): New field.
(region_model::get_gassign_result): Pass region to calls to
make_shift_count_negative_diagnostic,
make_shift_count_overflow_diagnostic, and
div_by_zero_diagnostic.
(exception_thrown_from_unrecognized_call::add_events_to_path): Add
state_transition param.
* region-model.h (make_shift_count_negative_diagnostic): Add
"src_region" param.
(make_shift_count_overflow_diagnostic): Likewise.
* region.h: Include "analyzer/store.h" and
"text-art/tree-widget.h".
* setjmp-longjmp.cc (rewind_info_t::add_events_to_path): Add
state_transition param.
* shift-diagnostics.cc
(shift_count_negative_diagnostic::shift_count_negative_diagnostic):
Add src_region param and use it to initialize m_src_region.
(shift_count_negative_diagnostic::mark_interesting_stuff): New.
(shift_count_negative_diagnostic::m_src_region): New.
(make_shift_count_negative_diagnostic): Add src_region param.
(shift_count_overflow_diagnostic::shift_count_overflow_diagnostic):
Add src_region param and use it to initialize m_src_region.
(shift_count_overflow_diagnostic::mark_interesting_stuff): New.
(shift_count_overflow_diagnostic::m_src_region): New field.
(make_shift_count_overflow_diagnostic): Add src_region param.
* sm-signal.cc (signal_delivery_edge_info_t::add_events_to_path):
Add state_transition param.
* state-transition.cc: New file.
* state-transition.h: New file.
* supergraph.h (class callsite_expr): Move to callsite-expr.h.
* varargs.cc (va_arg_diagnostic::add_call_event): Add state_trans
param.
gcc/testsuite/ChangeLog:
* c-c++-common/analyzer/divide-by-zero-1.c: Add expected message
for origin of zero value.
* c-c++-common/analyzer/divide-by-zero-2.c: New test.
* c-c++-common/analyzer/divide-by-zero-3.c: New test.
* c-c++-common/analyzer/invalid-shift-1.c: Add expected messages
about call to op3 and about pertinent param of op3.
* c-c++-common/analyzer/invalid-shift-2.c: New test.
* c-c++-common/analyzer/invalid-shift-3.c: New test.
* c-c++-common/analyzer/invalid-shift-4.c: New test.
* g++.dg/analyzer/divide-by-zero-7.C: New test.
* gcc.dg/analyzer/divide-by-zero-4.c: New test.
* gcc.dg/analyzer/divide-by-zero-5.c: New test.
* gcc.dg/analyzer/divide-by-zero-6.c: New test.
* gcc.dg/analyzer/divide-by-zero-float.c: Add expected message
for origin of zero value.
Signed-off-by: David Malcolm <dmalcolm@redhat.com>
Andrew MacLeod [Wed, 11 Feb 2026 15:57:24 +0000 (10:57 -0500)]
More memory efficient prange_storage.
* value-range-storage.cc (prange_storage::alloc): Use prange_format.
(prange_storage::prange_storage): Likewise.
(prange_format::prange_format): New.
(prange_storage::set_prange): Use prange_foramt and only write
required words to storage.
(prange_storage::get_prange): Only read required words.
(prange_storage::equal_p): Adjust for new enum.
(prange_storage::fits_p): Use prange_format to determine size.
* value-range-storage.h (enum prange_kind): New.
(class prange_format): New.
(get_low, get_high, get_value, get_mask): Replace with get_word.
(set_low, set_high, set_value, set_mask): Replace with set_word.
(get_word): New.
(set_word): New.
Tomasz Kamiński [Wed, 29 Apr 2026 14:06:16 +0000 (16:06 +0200)]
libstdc++: Format all contiguous ranges usign spoan.
We convert all contiguous ranges into span of the possibly-const qualified
_Tp (__format::__maybe_const<_Tp, _CharT>). The span object is const qualifed,
to trigger _M_format<const span<T>> specialization, that is already used by
formatter specialization for ranges.
This conversion is applied regardless if range is sized, and ranges::distance
to compute the size. Even for user-defined iterators, they will observe range
being iterated only once.
Finally, using raw pointers to iterate range during formatting guarantees,
that no stdio lock will be taken. In consequence it would be now possible
to enable_nonlocking_formatter_optimization for all contiguous ranges.
libstdc++-v3/ChangeLog:
* include/std/format (range_formatter::format): Format all
contiguous ranges as span<__format::__maybe_const<_Tp, _CharT>>.
Reviewed-by: Jonathan Wakely <jwakely@redhat.com> Signed-off-by: Tomasz Kamiński <tkaminsk@redhat.com>
Zhongyao Chen [Wed, 6 May 2026 13:04:25 +0000 (07:04 -0600)]
[PATCH v4] RISC-V: Apply LMUL cost scaling to vector operations
This patch introduces multiplicative cost scaling (x2/x4/x8) to model
the higher latency and register pressure of larger LMULs. The scaling
is applied uniformly in adjust_stmt_cost for all vector operations.
In addition to VLA, VLS should also get the same LMUL cost scaling,
but doing so causes too many testsuite regressions currently,
mostly because these tests also need expectation updates.
This is left for future work.
All failures displayed in CI should have been fixed. Changes here are
all expectation updates, except for slp_run-17.c which is pre-existing
— I will open a PR for it later.
PR target/122558
gcc/ChangeLog:
* config/riscv/riscv-vector-costs.cc (get_lmul_cost_scaling):
New function to calculate multiplicative scaling factors.
(costs::adjust_stmt_cost): Apply LMUL scaling uniformly to all
vector statements.
Tomasz Kamiński [Thu, 15 May 2025 15:04:22 +0000 (17:04 +0200)]
libstdc++: Avoid double indirection in function_ref when possible
This implements the P3961R1: Less double indirection in function_ref.
This patch uses provision provided by the paper for implementations, and
expands the set of the compatible signatures to include ParamType&& and
ParamType, and by value return types that differs only in cv-qualifiers.
This follows the move_only_function approach from the r16-617-g708d40ff109c6e.
Futhermore the optimization is also applied when function_ref<Ret(Args...) const>
is constructed from function_ref<Ret(Args...)>, even if the underyling target
is be mutated by the call.
The implementations moves the _M_ptrs members to newly defined base class
__polyfunc::_Ref_base. This allows us to reuse existing __base_of and
__invoker_of accessor in the implementation (after befriending them).
The accessors functions are also now marked as constexpr. Furthermore,
_Ref_base default constructor initializes the _M_ptrs._M_obj to nullptr,
and _M_init function is transfered to it, making it instantiations
independent from callback signature.
To check signature compatiblity required by standard for assignment, new
__is_funcref_assignable function is used, and _ArgsSignature and _TargetQuals
member typedef are defined in function_ref. To avoid confusion between adjusted
and specified signature, _Signature typedef is removed from all wrappers, and
__is_invoker_convertible is updated to use _Invoker::_Signature instead.
Per SG-10 guidance __cpp_lib_function_ref feature test macro is updated to
202604, differntiating from P3948R1 paper accepted at the same time.
PR libstdc++/119126
libstdc++-v3/ChangeLog:
* include/bits/funcwrap.h : (__polyfunc::__invoker_of):
Updated to use _Invoker::_Signature and mark as constexpr.
(__polyfunc::_base_of): Mark as constexpr.
(__std:::__is_function_ref_v, __polyfunc::_Ref_base)
(__polyfunc::__is_funcref_assignable): Define.
* include/bits/funcref_impl.h (std::function_ref): Add base class
of type__polyfunc::_Ref_base. Befriend __invoker_of, __base_of,
__is_invoker_convertible, __is_invoker_convertible.
(function_ref::_Base): Define.
(function_ref::_M_init, function_ref::_M_ptrs): Move to base class.
(function_ref::function_ref(_Fn&&), function_ref::operator=): Handle
specializations of function_ref with compatible signatures.
(function_ref::function_ref): Init base class before _M_invoke
consistently, and remove setting of _M_nullptr.
* include/bits/cpyfunc_impl.h (copyable_function): Udpdated friend
declarations.
(copyable_function::_Signature): Remove.
* include/bits/mofunc_impl.h (move_only_function): Udpdated friend
declarations.
(move_only_function::_Signature): Remove.
* include/bits/version.def (function_ref): Bump to 202604.
* include/bits/version.h: Regnerate.
* testsuite/20_util/function_ref/cons.cc: Updated checked FTM value.
* testsuite/20_util/function_ref/conv.cc: Updated test to illustrate
that double indirection is avoided.
* testsuite/20_util/function_ref/dangling.cc: Test for initializing
from function_ref with compatible signature.
* testsuite/20_util/function_ref/dangling_neg.cc: Test for
initializing from function_ref with incompatible signature.
Reviewed-by: Jonathan Wakely <jwakely@redhat.com> Signed-off-by: Tomasz Kamiński <tkaminsk@redhat.com>
Jonathan Wakely [Thu, 30 Apr 2026 15:06:11 +0000 (16:06 +0100)]
libstdc++: Use hardware_destructive_interference_size in atomic.cc
This code was moved from a header into the library, so is no longer
affected by compiler options used when including the headers. We can
just use std::hardware_destructive_interference_size now, and remove the
comment.
libstdc++-v3/ChangeLog:
* src/c++20/atomic.cc (__waitable_state::_S_align): Remove.
(__waitable_state::_M_waiters, __waitable_state::_M_ver): Use
std::hardware_destructive_interference_size for alignment.
Reviewed-by: Tomasz Kamiński <tkaminsk@redhat.com>
LoongArch: Add rtx_cost support for ORDERED comparison.
In commit 16-8400-g48c2ea1750efe4, VCOND_MASK is inverted
(if that would be an improvement). However, since the LoongArch
backend does not define the rtx_cost for the ORDERED RTX, the
calculated cost for UNORDERED becomes greater than that of ORDERED.
This triggers an inversion from UNORDERED to ORDERED, leading to
test failures in lasx-vcond-2.c and lsx-vcond-2.c.
Since the assembly sequences generated for ORDERED and UNORDERED
are identical on LoongArch, I have set the rtx_cost for ORDERED
to match that of UNORDERED. This ensures consistent cost
evaluation and allows the related test cases to pass.
gcc/ChangeLog:
* config/loongarch/loongarch.cc (loongarch_rtx_costs): Add
RTX cost handling for the ORDERED RTX code.
Robin Dapp [Fri, 27 Mar 2026 15:36:23 +0000 (16:36 +0100)]
RISC-V: Use more whole-reg loads/stores.
This patch allows pred_mov, which usually results in vle/vse insns to
split off whole-register loads and stores so we can emit more of them.
The advantage of whole-reg operations is that they don't require a vtype
and therefore allow more freedom in vsetvl placement.
gcc/ChangeLog:
* config/riscv/riscv-protos.h (whole_reg_to_reg_move_p):
Rename from this...
(whole_reg_move_p): ...to this.
(whole_reg_loadstore_p): Declare.
* config/riscv/riscv-v.cc (whole_reg_to_reg_move_p): Ditto.
(whole_reg_move_p): Ditto.
(whole_reg_loadstore_p): New function.
* config/riscv/thead-vector.md: Use renamed function.
* config/riscv/vector.md (@pred_store<mode>): Use new function.
gcc/testsuite/ChangeLog:
* gcc.target/riscv/rvv/autovec/reduc/reduc_call-4.c: Disable
instruction scheduling.
* gcc.target/riscv/rvv/base/vle-vl1r.c: New test.
Patrick Palka [Wed, 6 May 2026 00:30:50 +0000 (20:30 -0400)]
c++/reflection: rewrite and memoize consteval_only_p [PR125179]
The TU from this PR exhibits a 40x compile-time slowdown with -freflection
vs without, all due to consteval_only_p which happens to be quite slow on
large intertwined classes due to its recursive walking of TYPE_FIELDS.
This patch firstly rewrites the predicate to use direct recursion instead
of cp_walk_tree so that it's easier to reason about and more closely
mirrors its standard definition at [basic.types.general]/12.
This patch also makes the recursive part of the predicate tri-state, where
the third 'unknown' state corresponds to seeing an incomplete class type
whose consteval-only-ness we don't yet know.
Finally this patch caches the result of the predicate for class types
when the result is known. When the result is unknown (due to an
incomplete constituent type) then we don't cache so that a subsequent
call to the predicate can try again.
With this patch compile time for said TU is now 1.1x with -freflection
instead of 40x.
PR c++/125179
gcc/cp/ChangeLog:
* reflect.cc: (consteval_only_type_r): Remove this cp_walk_tree
callback and replace with ...
(consteval_only_walker): ... this recursive memoized
implementation.
(consteval_only_p): Define in terms of consteval_only_walker.
Reviewed-by: Jakub Jelinek <jakub@redhat.com> Reviewed-by: Jason Merrill <jason@redhat.com>
Iain Buclaw [Tue, 5 May 2026 20:00:28 +0000 (22:00 +0200)]
d: internal compiler error: in convert_move, at expr.cc:227
This was caused by a forward reference of a nested struct changing the
TYPE_MODE of its enclosing struct type to be incorrectly inferred as an
integer mode. Fixed by setting TREE_ADDRESSABLE early, and moving the
mode setting and propagation to finish_aggregate_mode and
finish_aggregate_type respectively, rather than at the end of the
visitor method for TypeStruct.
PR d/125089
gcc/d/ChangeLog:
* types.cc (finish_aggregate_mode): Explicitly set TYPE_MODE of
non-POD types here.
(finish_aggregate_type): Propagate TREE_ADDRESSABLE to all variants.
(TypeVisitor::visit (TypeStruct *)): Set TREE_ADDRESSABLE before
visiting struct members.
H.J. Lu [Sun, 3 May 2026 21:08:51 +0000 (05:08 +0800)]
or1k: Allow SImode for condition flag register
Commit
eb2ea476db2 emit-rtl: Allow extra checks for paradoxical subregs [PR119966]
changed validate_subreg to return false on the paradoxical SImode subreg
of the OpenRISC condition flag register (reg:BI sr_f), which triggered
internal compiler error: in emit_move_multi_word, at expr.cc:4497
c0694f95f59 or1k: Fix ICE in libgcc caused by recent validate_subreg changes
changed or1k_can_change_mode_class to allow changing flags mode from BI
to SI. But or1k_hard_regno_mode_ok still returns false for condition
flag register in SImode. Update or1k_hard_regno_mode_ok to also allow
condition flag register in SImode.
Tested with or1k Linux cross compiler for or1k glibc build.
gcc/
PR target/120587
PR target/125155
* config/or1k/or1k.cc (or1k_hard_regno_mode_ok): Allow condition
condition flag register in SImode.
gcc/testsuite/
PR target/120587
PR target/125155
* gcc.target/or1k/pr125155.c: New test.
H.J. Lu [Tue, 5 May 2026 20:56:32 +0000 (04:56 +0800)]
libssp: Change __stack_chk_guard to uintptr_t
Since the only test of __stack_chk_guard in GCC is declared as an integer:
#ifdef __LP64__
const unsigned long int __stack_chk_guard = 0x2d853605a4d9a09cUL;
#else
const unsigned long int __stack_chk_guard = 0xdd2cc927UL;
#endif
and it is natural to assign an integer to __stack_chk_guard,
Jeff Law [Tue, 5 May 2026 20:04:16 +0000 (14:04 -0600)]
[RISC-V] Adjust expected output after recent jump threader change
Richi's reversion of a jump threader change triggered a regression on
avl_single-26.c. Essentially we're doing less jump threading and consequently
less block duplication leading ultimately leading to one less vsetvl in the
code. This adjusts the testsuite to match current expectations.
Here x in _a.C is defined in terms of A, which has an abi_tag, so it
should inherit A's abi_tag. It turns out this abi_tag propagation
happens only during mangling via class.cc:check_abi_tags, and we happen
to never mangle x in this TU, so we stream out x with no abi_tag.
In _b.C we import and re-export x, and we also happen to mangle x (for
arbitrary reasons that I didn't question), which means when we stream it
out this time it has an abi_tag.
In _c.C we import both versions of x, merge them, during which we compare
their abi_tag, notice a mismatch, and diagnose. But the mismatch is
solely due to one version ('existing') being mangled, and therefore went
through class.cc:check_abi_tags, and the other ('decl') not.
Idiosyncracies of this testcase aside (like why x gets mangled in _b.C,
why we stream in two apparent x's in _c.C), it does seem like this
diagnostic routine should be robust to this situation. To that end this
patch makes the routine ignore such inherited tags during the comparison
if there's a mangled-ness mismatch, via a new flag ABI_TAG_INHERITED
that's set on all inherited tags. In passing, rename the existing flag
ABI_TAG_IMPLICIT to ABI_TAG_NOT_MANGLED to better describe and
differentiate it from the new flag.
PR c++/124957
gcc/cp/ChangeLog:
* class.cc (check_tag): Set ABI_TAG_INHERITED on the TREE_LIST
of an inherited tag. Adjust after ABI_TAG_IMPLICIT renaming.
* cp-tree.h (ABI_TAG_IMPLICIT): Rename to ...
(ABI_TAG_NOT_MANGLED): ... this.
(equal_abi_tags): Adjust forward declaration.
* mangle.cc (write_unqualified_name): Adjust equal_abi_tags call.
(sorted_abi_tags): New ignore_inherited_p parameter, for ignoring
ABI_TAG_INHERITED tags. Adjust after ABI_TAG_INHERITED renaming.
(write_abi_tags): Adjust sorted_abi_tags call.
(equal_abi_tags): New ignore_inherited_p parameter. Pass it to
sorted_abi_tags.
* module.cc (trees_in::check_abi_tags): Pass
ignore_inherited_p=true to equal_abi_tags iff there's a
mangled-ness mismatch.
gcc/testsuite/ChangeLog:
* g++.dg/modules/attrib-6_a.C: New test.
* g++.dg/modules/attrib-6_b.C: New test.
* g++.dg/modules/attrib-6_c.C: New test.
RISC-V: Make tuple vector not tieable to some modes.
This patch makes riscv tuple modes not tieable to non-tuple modes. Without
this patch some unnecessary type conversions may occur, especially when zvl
is specified.
E.g. RVVMF2x4HI and RVVM2DI are tieable in gcc trunk, and when extracting
an inner vector mode RVVMF2HI from RVVMF2x4HI and zvl is specified, it will
be converted to DI, which is not expected. But with same inner modes, e.g.
RVVM1x4QI and RVVM1QI, they should be tieable.
PR target/124448
gcc/ChangeLog:
* config/riscv/riscv.cc (riscv_modes_tieable_p): Make tuple modes
not tieable to some modes.
gcc/testsuite/ChangeLog:
* gcc.target/riscv/rvv/autovec/pr124448.c: New test.
Gaius Mulley [Tue, 5 May 2026 13:06:15 +0000 (14:06 +0100)]
PR modula2/120189: documented link command does not work
This is a tidyup for PR modula2/120189 to improve the description
and include all source code in the Building a shared library section.
gcc/ChangeLog:
PR modula2/120189
* doc/gm2.texi (Building a shared library): Rewrite the
description of the shared library and include complete code into
the example.
gcc/testsuite/ChangeLog:
PR modula2/120189
* gm2/examples/cppcallingm2/run/pass/README: New test.
* gm2/examples/cppcallingm2/run/pass/a.def: New test.
* gm2/examples/cppcallingm2/run/pass/a.mod: New test.
* gm2/examples/cppcallingm2/run/pass/b.def: New test.
* gm2/examples/cppcallingm2/run/pass/b.mod: New test.
* gm2/examples/cppcallingm2/run/pass/c.def: New test.
* gm2/examples/cppcallingm2/run/pass/c.mod: New test.
* gm2/examples/cppcallingm2/run/pass/test.cc: New test.
Jakub Jelinek [Tue, 5 May 2026 11:27:38 +0000 (13:27 +0200)]
analyzer: Fix up -Wunused-variable warning
I've noticed a new
../../gcc/analyzer/kf.cc: In member function ‘virtual void ana::kf_strcasecmp::impl_call_post(const ana::call_details&) const’:
../../gcc/analyzer/kf.cc:2882:12: warning: unused variable ‘lhs_type’ [-Wunused-variable]
warning.
The following patch fixes that.
Jonathan Wakely [Tue, 5 May 2026 09:16:36 +0000 (10:16 +0100)]
libstdc++: Fix mainpage.html link to Doxygen docs [PR109965]
Doxygen renamed the "Modules" documentation to "Topics" a few years ago
to avoid confusion with C++20 Modules:
https://github.com/doxygen/doxygen/issues/8772
This updates our internal link to 'modules.html' so that it refers to
'topics.html' instead.
libstdc++-v3/ChangeLog:
PR libstdc++/109965
* doc/doxygen/mainpage.html: Link to topics.html instead of
modules.html
Richard Biener [Tue, 5 May 2026 08:10:07 +0000 (10:10 +0200)]
tree-optimization/125185 - fix ICE with associating DOT_PROD_EXPR
When trying to discover a SLP reduction chain we eventually feed
non-binary associatable stmts to vect_slp_linearize_chain which
isn't prepared for that. Don't.
PR tree-optimization/125185
* tree-vect-slp.cc (vect_analyze_slp_reduc_chain): Guard
first vect_slp_linearize_chain call.
Jonathan Wakely [Thu, 30 Apr 2026 18:39:44 +0000 (19:39 +0100)]
libstdc++: Make std::unique_ptr<void>::operator* SFINAE-friendly
This implements LWG 4324, "unique_ptr<void>::operator* is not
SFINAE-friendly", approved in Croydon, 2026.
The noexcept-specifier added to C++23 by LWG 2762 is ill-formed if the
pointer type cannot be dereferenced, which means that code which was
checking whether the function exists (e.g. in a SFINAE context) no
longer works. Such code was always questionable, because the function
body was ill-formed if the pointer isn't dereferenceable, so the SFINAE
check was probably giving the wrong answer, but it was possible to ask
the question. Since LWG 2762 just asking the question can produce an
error outside the immediate context, so operator* is no longer
SFINAE-friendly.
LWG 4324 adds a constraint to the function, so that it doesn't
participate in overload resolution if it would be ill-formed. That's
easy to implement for C++20 because we can just add a requires-clause.
For C++11/14/17 we can't constrain it easily, so just adjust the
noexcept-specifier so that it's not ill-formed. This still means you get
the wrong answer (i.e. it looks like unique_ptr<void>::operator* is
callable) but there's no error outside the immediate context. This
restores the original semantics before the LWG 2762 change, for better
or worse.
libstdc++-v3/ChangeLog:
* include/bits/unique_ptr.h (unique_ptr::_Nothrow_deref): New
helper for pre-C++20.
(unique_ptr::operator*): Either constrain or use _Nothrow_deref.
* testsuite/20_util/unique_ptr/lwg4324.cc: New test.
Reviewed-by: Tomasz Kamiński <tkaminsk@redhat.com>