Avinash Jayakar [Tue, 4 Aug 2026 04:37:18 +0000 (10:07 +0530)]
rs6000: Fix type size checks for __builtin_ppc_atomic_cas_local
Type checks for the first 3 operands of the
__builtin_ppc_atomic_cas_local were missed with its initial
implementation. This patch adds the following checks
c1. Make sure the size of first 3 operands is the same.
c2. Do not allow function pointers as arguments.
c3. Report error when -mno-quad-memory-atomic is used but 128 bit
operands are used as the first 3 operands.
c4. A separate issue was when no lhs was assigned to this builtin, ICE would
happen as a result of emit_cmp_and_jump_insns function dereferencing the
target rtx which would be null. Added the check in rs6000_expand_builtin
to allocate a reg_rtx if target is null or const0_rtx.
Tests have been added to check all the implemented checks described
above.
1. pr126513-acmp-tst-1.c: Checks c1 and c2.
2. pr126513-acmp-tst-2.c: Checks c3.
3. pr126513-acmp-tst-3.c: Checks the ICE in c4.
gcc/ChangeLog:
PR target/126513
* config/rs6000/rs6000-builtin.cc (rs6000_expand_builtin): Allocate reg
if target is null or const0_rtx.
* config/rs6000/rs6000-c.cc (altivec_resolve_overloaded_builtin): Add
error handling for c1, c2 and c3 described in this commit.
gcc/testsuite/ChangeLog:
PR target/126513
* gcc.target/powerpc/pr126513-acmp-tst-1.c: New test.
* gcc.target/powerpc/pr126513-acmp-tst-2.c: New test.
* gcc.target/powerpc/pr126513-acmp-tst-3.c: New test.
Jin Ma [Thu, 16 Jul 2026 11:21:25 +0000 (19:21 +0800)]
RISC-V: Improve macro-fusion dump output and comments
No new macro-fusion functionality is added. Include both
instruction UIDs in dump messages so consecutive matches can be
distinguished, and report ZEXTW and ZEXTWS with their actual fusion types.
Document existing fusion recognizers consistently to make their RTL
relationships and constraints easier to understand.
Keep each table entry tied to one fusion operation and use the common
enablement helper.
gcc/ChangeLog:
* config/riscv/riscv-fusion.cc (riscv_fuse_zext_common): New function.
(riscv_fuse_zextw): Likewise.
(riscv_fuse_zextws): Use riscv_fuse_zext_common and document RTL
relationships and constraints.
(riscv_fuse_zexth): Use riscv_fuse_zext_common.
(riscv_fuse_ldindexed): Document RTL relationships and constraints.
(riscv_fuse_expanded_ld): Likewise.
(riscv_fuse_ldpreincrement): Likewise.
(riscv_fuse_lui_addi): Likewise.
(riscv_fuse_auipc_addi): Likewise.
(riscv_fuse_lui_ld): Likewise.
(riscv_fuse_auipc_ld): Likewise.
(riscv_fuse_cache_aligned_std): Likewise.
(riscv_fuse_aligned_std): Likewise.
(riscv_fuse_bfext): Likewise.
(riscv_fuse_b_alui): Likewise.
(riscv_fusion_entry::op): Rename from op_flags and use an enum.
(riscv_fusion_table): Split ZEXTW and ZEXTWS entries.
(riscv_macro_fusion_pair_p): Use riscv_fusion_enabled_p and print
instruction UIDs.
gcc/testsuite/ChangeLog:
* gcc.target/riscv/fusion-zextw-2.c: Expect the ZEXTW dump name.
* gcc.target/riscv/fusion-zextw.c: Likewise.
Andrea Pinski [Fri, 7 Aug 2026 03:03:46 +0000 (20:03 -0700)]
Improve tree_expr_nonnegative_p by using the ranger [PR111959]
When I was looking into fixing tree_expr_nonnegative_p not to be recusive,
we should have tree_expr_nonnegative_p use the ranger.
I also didn't realize I wrote this patch before so this is
the updated version of the already approved:
https://gcc.gnu.org/pipermail/gcc-patches/2023-October/634205.html
Updated for the review comments.
Note testsuite/g++.dg/ipa/pure-const-3.C testcase will always fail as we can
use the fact the argument is always non-negative in many different places now.
Since there is no way to test it, let's remove the testcase.
Bootstrapped and tested on x86_64-linux-gnu.
Changes since v1:
* Use get_range_query instead of the global range.
Update the wording on pr80776-1.c testcase and add new testcase without dom.
PR tree-optimization/111959
gcc/ChangeLog:
* fold-const.cc (tree_single_nonnegative_p): Use the range to see
if the SSA_NAME was nonnegative.
gcc/testsuite/ChangeLog:
* gcc.dg/pr80776-1.c: xfail and update comment.
* gcc.dg/pr80776-1a.c: New test.
* gcc.dg/tree-ssa/forwprop-44.c: New test.
* g++.dg/ipa/pure-const-3.C: Remove.
Signed-off-by: Andrea Pinski <andrew.pinski@oss.qualcomm.com>
Andrea Pinski [Sat, 8 Aug 2026 18:22:49 +0000 (11:22 -0700)]
phiopt: Fix up factoring out loads for REF_REVERSE_STORAGE_ORDER [PR126729]
REF_REVERSE_STORAGE_ORDER is forgotten about when factor_out_conditional_load
was written up so if REF_REVERSE_STORAGE_ORDER was set, it would be lost.
If REF_REVERSE_STORAGE_ORDER was mismatched then it would mess up too.
This fixes that oversight.
Bootstrapped and tested on x86_64-linux-gnu.
PR tree-optimization/126729
gcc/ChangeLog:
* tree-ssa-phiopt.cc (factor_out_conditional_load): Handle
REF_REVERSE_STORAGE_ORDER being set correctly.
gcc/testsuite/ChangeLog:
* gcc.dg/sso/factor_load-1.c: New test.
Signed-off-by: Andrea Pinski <andrew.pinski@oss.qualcomm.com>
Andrea Pinski [Sat, 8 Aug 2026 18:03:55 +0000 (11:03 -0700)]
gimplefe: Add support for REF_REVERSE_STORAGE_ORDER on mem
While fixing PR 126729 and PR 126570, I found it was hard
to figure out if REF_REVERSE_STORAGE_ORDER was set on a MEM_REF.
Even for the gimple fe was able to set it.
This adds support to the gimple fe and also outputs
REF_REVERSE_STORAGE_ORDER for MEM_REF in gimple mode.
Bootstrapped and tested on x84_64-linux-gnu.
gcc/c/ChangeLog:
* gimple-parser.cc (c_parser_gimple_postfix_expression):
Allow for an optional `, 1/0` in front of the cb pair
for MEM_REF.
gcc/ChangeLog:
* tree-pretty-print.cc (dump_mem_ref): Dump REF_REVERSE_STORAGE_ORDER
if it was set.
gcc/testsuite/ChangeLog:
* gcc.dg/gimplefe-59.c: New test.
Signed-off-by: Andrea Pinski <andrew.pinski@oss.qualcomm.com>
Matt Turner [Sun, 9 Aug 2026 22:06:29 +0000 (16:06 -0600)]
[PATCH] alpha: round to odd before narrowing TFmode to SFmode
Alpha has no instruction converting TFmode to SFmode, so trunctfsf2 goes
through DFmode and has to avoid rounding twice.
It tried to, by setting a sticky bit at fraction bit 48 when the low word
of the TFmode value was nonzero: a DFmode value with that bit set cannot
sit exactly halfway between two SFmode values, leaving the second
rounding nothing to break a tie on. But the bit is set before the
conversion to DFmode, and the carry out of the bits that conversion
discards can propagate up through bit 48 and clear it, landing on the
halfway value it was there to avoid.
Round to odd at the last fraction bit DFmode keeps instead. The value is
then exactly representable in DFmode, so that conversion does not round
and the one to SFmode is the only rounding.
Over values constructed around SFmode halfway points the old sequence is
wrong for about a quarter of them and the new one for none. Uniformly
random values do not reach it: that needs the conversion to DFmode to
carry all the way to a halfway value.
Rounding twice also loses the underflow flag when the result is subnormal.
glibc's narrowing functions compute a round-to-odd value in the wider type
and convert it once, and that single conversion is what is meant to raise
underflow; splitting it in two can leave the intermediate DFmode value
exactly representable in SFmode, so the final step raises nothing.
Found through glibc's math testsuite, where three of the narrowing fma
tests returned a wrong result. Retested there on an EV67 with a glibc
built by a compiler carrying this patch: the wrong results are gone, every
test now reporting a maximum error of 0 ulp, and the six narrowing add and
subtract tests that had been failing on the lost underflow flag pass. The
narrowing tests that still fail there do so for an unrelated reason, Alpha
determining tininess from the delivered result rather than as IEEE 754
describes, which no change to the compiler can address.
gcc/
* config/alpha/alpha.md (trunctfsf2): Adjust sequence to avoid
conversion step landing at a halfway value.
middle-end: If supported, use __builtin_*. [PR126625]
hwint.cc reflect_hwi uses a naive for loop approach to
emulate __builtin_bitreverse64 ().
This is slow compared to using __builtin_bitreverse64 () plus bitshift.
This is useful for bootstrapping GCC since r17-523.
Also add assert on BITWIDTH <= 64.
For reflect_hwi and ira-color.cc, add STAGE0_CXX_HAS_BUILTIN
in system.h to test for specific builtins.
Bootstrapped and regtested on x86_64-pc-linux-gnu.
PR middle-end/126625
gcc/ChangeLog:
* hwint.cc (reflect_hwi): Use STAGE0_CXX_HAS_BUILTIN
for __builtin_bitreverse64.
* ira-color.cc (HAS_SMUL_OVERFLOW): Remove
and use STAGE0_CXX_HAS_BUILTIN instead.
* system.h (STAGE0_CXX_HAS_BUILTIN): New macro.
Signed-off-by: Kael Andrew Franco <kaelfandrew@gmail.com>
Paul Thomas [Sun, 9 Aug 2026 14:38:50 +0000 (15:38 +0100)]
Fortran: Fix missing vptrs for class allocations [PR98573]
2026-08-09 Paul Thomas <pault@gcc.gnu.org>
gcc/fortran
PR fortran/98573
* trans-array.cc (gfc_array_init_size): If the expr3_desc is an
array descriptor, use it for 'type'.
* trans-stmt.cc (gfc_trans_allocate): Use trans_assignment to
assign the source for class sources.
gcc/testsuite/
PR fortran/98573
* gfortran.dg/allocate_class_5.f90: New test.
Kyrylo Tkachov [Sun, 9 Aug 2026 10:14:30 +0000 (12:14 +0200)]
testsuite: enable vector MIN for vec-narrow-1.C on x86
The positive test only folds when the wide and narrow vector MIN operations
are available. Default x86_64 lowers the V2DI MIN before the narrowing rule
can see it, so the dump still contains the wide type.
Enable AVX512VL and AVX512DQ for x86 targets to enable the type.
Tested on x86_64-pc-linux-gnu.
gcc/testsuite/ChangeLog:
* g++.dg/tree-ssa/vec-narrow-1.C: Enable AVX512VL and AVX512DQ on
x86 targets.
match.pd: turn a product of two quotients into one division
(A / B) * (C / D) is (A * C) / (B * D), which replaces one of the two
divisions with a multiply. A division costs several multiplies on every
target.
double f (double a, double b, double c)
{ return (a / b) * (1.0 / c); }
AArch64 -Ofast before:
fdiv d0, d0, d1
fdiv d0, d0, d2
After:
fmul d1, d1, d2
fdiv d0, d0, d1
The rule needs infinities and NaNs excluded. It forms two products, and each
is a new place for the exponent to leave the range. It also needs
non-trapping math because it removes one division. A function option test
restores trapping math and verifies that both divisions remain.
Both quotients must be singly used. This excludes a shared reciprocal and
the X * X form of one reciprocal square root, where the rewrite can add a
division after its products fold. Complex values also require signed zeros
to be ignored because reassociation can change the sign of an imaginary zero.
Bootstrapped and tested on aarch64-none-linux-gnu.
gcc/ChangeLog:
* match.pd ((A / B) * (C / D)): New simplification.
gcc/testsuite/ChangeLog:
* gcc.dg/tree-ssa/recip-mult-div-1.c: New test.
* gcc.dg/tree-ssa/recip-mult-div-2.c: New test.
Roger Sayle [Sun, 9 Aug 2026 06:00:06 +0000 (08:00 +0200)]
PR tree-optimization/126467: 0.0-x -> -x vs. signed zeros in match.pd.
This is my proposed solution to PR tree-optimization/126467, where we're
inappropriately converting 0.0 - x to -x when we honor IEEE signed zeros.
This transformation is valid with -Ofast, but by default +0.0 - +0.0
should return +0.0, but -(+0.0) is -0.0. Likewise when x is NaN, 0.0 - x
may change the payload, but -x is guaranteed not to. My fix is to
separate the logic for this transformation from that for FP addition.
Technically, we could do slightly better by introducing a
tree_expr_negative_p (complementing and mutually recursive with the
existing tree_expr_nonnegative_p), but that's a bigger change and
less suitable for backporting to release branches, i.e. a follow-up.
I agree with Alexander Monakov that an alternate fix might be to
correctly reuse the existing fold_real_zero_addition_p functionality
by constructing and garbage collecting a NEGATE_EXPR tree on each call,
but this seems a little less efficient.
2026-08-09 Roger Sayle <roger@nextmovesofware.com>
Andrea Pinski <andrew.pinski@oss.qualcomm.com>
gcc/ChangeLog
PR tree-optimization/126467
* match.pd (0.0 - x -> -x): Update the conditions under which
the transformation is performed, disallowing x = +0.0 when we
honor signed zeros. This is still disallowed if x is a NaN.
gcc/testsuite/ChangeLog
PR tree-optimization/126467
* gcc.dg/pr126467-1.c: New test case.
* gcc.dg/pr126467-2.c: Likewise.
* gcc.dg/pr96392.c: Fix incorrect test case.
Kevin Stefanov [Sat, 8 Aug 2026 10:41:14 +0000 (13:41 +0300)]
OpenMP: Use VOID_TYPE_P to check for void return type in SIMD function clones.
This change fixes an issue where functions
decorated with:
pragma omp declare simd
that return void via a typedef would crash
GCC with an ICE while compiling a program
containing such a function, by using
VOID_TYPE_P instead of directly comparing
to void_type_node. New testcase added.
PR middle-end/111856
gcc/ChangeLog:
* omp-simd-clone.cc (simd_clone_adjust_return_type): Use VOID_TYPE_P
when checking for void return type in adjusted functions.
(simd_clone_adjust): Likewise.
gcc/testsuite/ChangeLog:
* gcc.dg/gomp/pr111856.c: New test.
Signed-off-by: Kevin Stefanov <kevinstefanov15@gmail.com>
Jerry DeLisle [Sat, 8 Aug 2026 15:59:16 +0000 (08:59 -0700)]
fortran: [PR47425] Array constructor fails with length type expr
Two separate problems are fixed here. The original test case is fixed
by the one-liner in trans-array.cc. Add check for INTEGER_CST. The
remaining problem starts with parsing and not keeping track of charlens
where some of the charlens are created and later left dangling. Code was
added to keep track of these and remove them as needed.
PR fortran/47425
gcc/fortran/ChangeLog:
* decl.cc (discard_pending_charlen): Use new helper
function.
(discard_pending_charlens): Likewise.
(build_struct): Likewise.
* gfortran.h (struct gfc_charlen): Add a namespace
pointer to track char len for undo.
(struct gfc_undo_change_set): Add cls
pointer to track charlens created during parsing.
(struct gfc_undo_change_set): Add vec<gfc_charlen *> cls.
(gfc_remove_saved_charlen): Declare new helper function.
* parse.cc (accept_statement): Adjust comment.
* symbol.cc (gfc_merge_new_implicit): Use new helper function
(free_undo_change_set_data): Release cls.
(gfc_drop_last_undo_checkpoint): Splice cls into parent
changeset.
(gfc_restore_last_undo_checkpoint): Remove and free charlens
tracked in cls.
(gfc_commit_symbols): Truncate cls.
(gfc_remove_saved_charlen): New function to remove
previously saved char len.
(gfc_free_namespace): Remove charlens from undo before freeing
to prevent double-free.
(gfc_enforce_clean_symbol_state): Clear cls instead of asserting
empty; non-tentative callers leave charlens in cls.
* trans-array.cc (trans_array_constructor): Add guard.
gcc/testsuite/ChangeLog:
* gfortran.dg/pr47425-1.f90: New test.
* gfortran.dg/pr47425-2.f90: New test.
Two reductions feeding the matching scalar operation are one reduction of
the elementwise operation:
REDUC (a) op REDUC (b) -> REDUC (a op b)
The two sides accumulate the same multiset of lanes, just grouped
differently, so for the associative and commutative reductions the result
is identical. This trades a lane-crossing reduction, which is the
expensive part, for an elementwise operation.
MIN, MAX, AND, IOR and XOR need no flag. The sum needs one only for
floating point, where the regrouping is a reassociation; the integer sum
is done in the unsigned type, since the reduction wraps while the signed
vector type has undefined overflow.
#include <arm_neon.h>
int f (int32x4_t a, int32x4_t b) { return vaddvq_s32 (a) + vaddvq_s32 (b); }
A pair of maxima goes from 8 instructions to 3. On a target without a
horizontal reduce instruction the reduction is open coded as a chain of
shuffles, so the saving is larger there, never smaller.
For integers, preserve trapping and sanitized scalar overflow. For
floating point, require reassociation, insignificant zero signs, and
non-trapping exceptions.
Restrict the reassociative alternative to floating-point types.
Floating-point options must not license fixed-point saturation changes.
Bootstrapped and tested on aarch64-none-linux-gnu.
gcc/ChangeLog:
* match.pd (REDUC (a) op REDUC (b)): New simplifications combining
two reductions into one.
gcc/testsuite/ChangeLog:
* gcc.dg/tree-ssa/vec-reduc-pair-1.c: New test.
* gcc.dg/tree-ssa/vec-reduc-pair-2.c: New test.
* gcc.dg/tree-ssa/vec-reduc-pair-3.c: New test.
* gcc.dg/tree-ssa/vec-reduc-pair-4.c: New test.
match.pd: extend the MIN/MAX narrowing through a cast to vectors
The rule folding (type) minmax ((wide_type) a, (wide_type) b) to
minmax (a, b) is restricted to scalars. Extension is monotone, so it
commutes with the comparison and the outer truncation is exact, and the
argument is lanewise, so it holds for vectors unchanged.
The vector case additionally needs the narrow operation to be available,
otherwise vector lowering would scalarise what used to be a single wide
instruction.
typedef int v2si __attribute__((vector_size (8)));
typedef long v2di __attribute__((vector_size (16)));
v2si h (v2si a, v2si b)
{
v2di x = __builtin_convertvector (a, v2di);
v2di y = __builtin_convertvector (b, v2di);
return __builtin_convertvector (x < y ? x : y, v2si);
}
Require the wide vector MIN or MAX to have one use. A shared wide
result would otherwise gain a second narrow operation.
Bootstrapped and tested on aarch64-none-linux-gnu.
gcc/ChangeLog:
* match.pd ((type) minmax ((wide_type) a, (wide_type) b)): Accept
vector types, using element_precision and requiring the narrow
operation to be supported.
gcc/testsuite/ChangeLog:
* g++.dg/tree-ssa/vec-narrow-1.C: New test.
* g++.dg/tree-ssa/vec-narrow-minmax-2.C: New test.
The minimum and the maximum of two values add up to the sum of those
values, so subtracting one of them from the sum yields the other one.
That identity holds in modular arithmetic. It also holds for floating
point when reassociation is enabled and signed zeros and traps are not
honoured.
int f (int a, int b) { int mn = a < b ? a : b; return (a + b) - mn; }
aarch64 -O2:
before after
cmp w1, w0 cmp w1, w0
add w2, w1, w0 csel w0, w1, w0, ge
csel w0, w1, w0, le
sub w0, w2, w0
The operands of PLUS_EXPR, MIN_EXPR, and MAX_EXPR have the same canonical
order, so no explicit commutation is needed on the MIN_EXPR or MAX_EXPR.
Bootstrapped and tested on aarch64-none-linux-gnu.
Kyrylo Tkachov [Sat, 8 Aug 2026 10:36:55 +0000 (12:36 +0200)]
testsuite: Remove unrelated checks from signbit-1.c
signbit-1.c tests the X + (X | -X) simplification. The test also
contains three expressions for the separate (X | -X) sign-bit fold.
That fold belongs to a separate patch, so the dump scans fail when this
patch is tested by itself.
Remove the unrelated functions and scan. The sign-bit fold patch has
its own tests.
fortran: Preserve host association for dummy procedures [PR125383]
A call statement marks an unresolved procedure as a subroutine before
its procedure kind is known. was_declared treated that provisional
attribute as a declaration, so resolution did not find an optional
dummy procedure in the host scope. Require a known procedure kind
before the subroutine attribute counts as a declaration.
Robert Dubner [Fri, 7 Aug 2026 20:03:26 +0000 (16:03 -0400)]
cobol: Refactor COMPUTE using Reverse Polish stack.
COBOL provides the COMPUTE statement, which evaluates an expression and
assigns the result to one or more target variables.
Our former implementation of COMPUTE z = a * b + c * d was profligate
with the creation of temporary variables. In that case, temporaries
were created for a*b and c*d, and another created for their sum, which
then became input to the assignment phase.
These changes change that implementation to a version using Reverse
Polish Notation. An RPN stack is created and passed to the libgcobol
library, where the stack is reduced and a result created. This is
computionally somewhat more efficient, and it greatly reduces the
computational load on the GCC middle end.
Co-authored-by: James K. Lowden <jklowden@cobolworx.com> Co-authored-by: Robert Dubner <rdubner@symas.com>
gcc/cobol/ChangeLog:
* genapi.cc (gg_array_of_field_pointers): Modified to return a
pointer to the first element of the array.
(gg_array_of_uchar_p): Formatting.
(parser_sort): Use updated gg_array_of_field_pointers().
(parser_file_sort): Likewise.
(parser_file_merge): Likewise.
* genapi.h (parser_compute): New declarations.
* gengen.h (gg_array_of_field_pointers): Modified declaration.
* genmath.cc (parser_compute): New declarations.
* genutil.h (gg_array_of_uchar_p): New declaration.
* move.cc (mh_binary_to_numdisp): Use new __gg__prohibited()
routine.
(parser_move): Formatting.
(parser_move_multi): Formatting.
* parse.y: RPN support.
* parse_ante.h (ast_op): Likewise.
(ast_relop): Likewise.
(struct ast_op_t): Likewise.
(struct refer_list_t): Likewise.
(struct vargs_t): Likewise.
* symbols.h (struct rpn_t): Likewise.
(struct expr_t): Likewise.
libgcobol/ChangeLog:
* gmath.cc (__gg__pow): Use exponentiation_helper().
(exponentiation_helper): New routine.
(__gg__process_compute_error): Formatting.
(multiply_int128_by_int128): Use new int128 structure.
(divide_int128_by_int128): Formatting.
(multiply_int256_by_int256): New routine.
(divide_int256_by_int256): New routine.
(compute_fixed_add): New routine to implement RPN COMPUTE.
(compute_fixed_subtract): Likewise.
(compute_fixed_multiply): Likewise.
(compute_fixed_divide): Likewise.
(compute_fixed_negate): Likewise.
(compute_float_add): Likewise.
(compute_float_subtract): Likewise.
(compute_float_multiply): Likewise.
(compute_float_divide): Likewise.
(compute_float_pow): Likewise.
(compute_float_negate): Likewise.
(__gg__compute_fixed): Likewise.
(__gg__compute_float): Likewise.
* libgcobol.cc (__gg__prohibited): New routine tests value and
target for ROUNDING MODE PROHIBITED compliance.
* libgcobol.h: Formatting.
Aldy Hernandez [Fri, 7 Aug 2026 14:32:40 +0000 (14:32 +0000)]
[frange] Guard sign-zero self test with HONOR_SIGNED_ZEROS [PR126714]
frange_add_zeros's multi-range conversion added a self-test that
assumes signed zeros exist, which is not the case on VAX. Guard such
test with HONOR_SIGNED_ZEROS.
gcc/ChangeLog:
PR tree-optimization/126714
* range-op-float.cc (range_op_float_tests): Guard the signed-zero
== op1_range self-test with HONOR_SIGNED_ZEROS.
Robert Dubner [Fri, 7 Aug 2026 19:01:17 +0000 (15:01 -0400)]
cobol: Refactored variable creation.
When I started work on code generation for COBOL <mumble> years ago,
creating variables was one of the very first things I had to figure out
how to do. That resulted in me doing things that I, now older and wiser
and more knowledgeable (well, older, anyway), realize were unnecessary
and unhelpful.
Mainly: I have a utility gg_define_variable(tree type). I originally
created many helper routines that this patch eliminates in favor of
calling that routine with the type explicitly mentioned.
Jakub Jelinek [Fri, 7 Aug 2026 19:20:35 +0000 (21:20 +0200)]
gimple-range-op: Use widen method even for sqrt reverse op [PR126534]
For glibc the target hook returns 0 for sqrt precision (i.e. 0.5ulp
precise), but we didn't apply the +-0.5ulp widening when doing
reverse op and so still came up with a wrong range, even with 0.5ulp
precision certain values around 25.0 result in sqrt (x) being 5.0.
Even if the hook returns non-zero, I'd say more reasonable handling
of it is that it is say worst case 1ulp (or 2ulps etc.) from the
correct result (i.e. half ulp precise), rather than just 1ulp from
mathematically exact result.
So, the following patch uses the newly added widen method to add
this 0.5ulp before we feed it into frange_arithmetic.
2026-08-07 Jakub Jelinek <jakub@redhat.com>
PR tree-optimization/126534
* gimple-range-op.cc (cfn_sqrt::op1_range): Widen lb or ub
by further 0.5ulp or 1ulp before squaring it.
PR target/120681 - allow -mcmodel=large with PC relative addressing
When I implemented the pc-relative support for power10 in GCC, I
disabled using pc-relative support for -mcmodel=large. At the time, I
didn't want to dig into the issues. It is now time to allow
-mcmodel=large to generate pc-relative code.
This patch allows -mcmodel=large to use prefixed addressing on power10,
power11, and possibly other future PowerPC processors in addition to
the current -mcmodel=medium support.
2026-08-07 Michael Meissner <meissner@linux.ibm.com>
gcc/
PR target/120681
* config/rs6000/linux64.h (PCREL_SUPPORTED_BY_OS): Allow large
code model as well as medium code model.
* config/rs6000/rs6000.cc (rs6000_option_override_internal):
Likewise.
(rs6000_elf_declare_function_name): Don't create the
local/non-local labels for large code model if we are using
PC-relative addressing.
gcc/testsuite/
PR target/120681
* gcc.target/powerpc/pr120681.c: New test.
Jakub Jelinek [Fri, 7 Aug 2026 15:33:53 +0000 (17:33 +0200)]
s390: Fix ICE in usubc5 [PR126667]
The following testcase ICEs on s390x-linux I believe since r15-6791
when usubc<mode>5 named pattern has been introduced.
It intentionally uses general_operand predicate for operands[4],
so that it can test it against const0_rtx and handle that differently,
but otherwise it uses xor<mode>3 insn with operands[4] as first input,
which has nonimmediate_operand. So we emit (xor:DI (const1_rtx) (const1_rtx))
and then fail to recognize it.
The following patch just forces it into a register in that case, cse or
combine can then simplify it. The other option would be
to check for CONSTANT_P, force into REG unless it is CONST_INT and if it
is CONST_INT, perform the xor at compile time, but then the compare
too and unsure what to pass to the subsequent insn.
The testcase is simplified from a larger botan real-world testcase (though
there isn't usubc with a constant 1 carry in visible in the source).
2026-08-07 Jakub Jelinek <jakub@redhat.com>
PR target/126667
* config/s390/s390.md (usubc<mode>5): If operands[4] is
an immediate operand other than const0_rtx, force it into reg
before using it in xor<mode>3 insn.
* gcc.dg/pr126667.c: New test.
* gcc.target/s390/pr126667.c: New test.
Reviewed-by: Andreas Krebbel <krebbel@linux.ibm.com>
PR target/120528 -- Simplify zero extend from memory to VSX register on power10
Previously GCC would zero extend a DImode value in memory to a TImode
target in a vector register by firt zero extending the DImode value
into a GPR TImode register pair, and then do a MTVSRDD to move this
value to a VSX register.
For example, consider the following code:
#ifndef TYPE
#define TYPE unsigned long long
#endif
The lxvr{b,h,w,d}x instructions were added in power10, and they load up
a vector register with a byte, half-word, word, or double-word value in
the right most bits, and fill the remaining bits to 0. I noticed this
code when working on PR target/108958 (which I just posted the patch).
This patch creates a peephole2 to catch this case, and it eliminates
creating the TImode variable. Instead it just does the LXVR{B,H,W,D}x
instruction directly.
2026-08-07 Michael Meissner <meissner@linux.ibm.com>
gcc/
PR target/120528
* config/rs6000/rs6000.md (zero_extend??ti2 peephole2): Add a
peephole2 to simplify zero extending a QI/HI/SI/DImode value in
memory to a TImode target in a vector register to use the
LXVR{B,H,W,D}X instructins.
gcc/testsuite/
PR target/120528
* gcc.target/powerpc/pr120528.c: New test.
Arthur Cohen [Tue, 23 Jun 2026 13:41:10 +0000 (15:41 +0200)]
gccrs: forever-stack: Add dfs_cache
We do a *lot* of depth-first-search during name resolution, so having a
temporary cache for the results speeds up the compilation of core by quite
a lot. This is just a simple version that can be improved.
On my machine, this shaves off almost 3 minutes from compiling core.
gcc/rust/ChangeLog:
* resolve/rust-forever-stack.h: Declare new cache API.
* resolve/rust-forever-stack.hxx: Implement it and use it within
dfs_cache.
gccrs: Separate argument and function body drop scopes
Create the argument scope before compiling function parameters, so their
drops are registered directly in that scope.
Compile the function body in a nested scope. Clean up the body scope
before the argument scope, so body locals are dropped before parameters.
gcc/rust/ChangeLog:
* backend/rust-compile-base.cc
(HIRCompileBase::compile_function): Create separate argument and
function body drop scopes. Register parameter drop candidates in
the argument scope and clean up the function body before the arguments.
* expand/rust-macro-builtins.cc: Made it more explicit that cfg_select! is
backported.
* rust-session-manager.h (Session::should_support_cfg_select): New function to
check whether cfg_select! should be compiled.
* resolve/rust-early-name-resolver-2.0.cc (Early::visit(MacroInvocation)):
Conditionally resolve cfg_select!.
* expand/rust-macro-expand.cc (MacroExpander::expand_invoc): Ditto.
This macro is used in newer versions of `core` to compile `c_char`, that is used to compile
`CStr` which has widespread use in Rust for Linux.
gcc/rust/ChangeLog:
* expand/rust-macro-builtins.h (BuiltinMacro::CfgSelect): New enum variant.
(MacroBuiltin::cfg_select_handler): New function definition.
* expand/rust-macro-builtins.cc (MacroBuiltin::builtins): New cfg_select entry.
(MacroBuiltin::builtin_transcribers): New cfg_select_handler entry.
* expand/rust-macro-builtins-utility.cc (MacroBuiltin::cfg_select_handler): Implement
parsing of compilation configuration predicates and expansion of block expressions based
on which predicate was matched.
This patch implements the 'unsafe_cell' lang item to the compilers.
Since, gccrs currently lacks niche-filling optimizations, this patch
does not include any changes related to type layout sizes.
gcc/rust/ChangeLog:
* backend/rust-compile-type.cc
(TyTyResolveCompile::visit): If type contains unsafe_cell type,
do not mark it as const.
* typecheck/rust-tyty.cc (ADTType::contains_unsafe_cell): New
function.
(TupleType::contains_unsafe_cell): Likewise.
(ArrayType::contains_unsafe_cell): Likewise.
(SliceType::contains_unsafe_cell): Likewise.
* typecheck/rust-tyty.h (contains_unsafe_cell): New declaration.
* util/rust-lang-item.cc (Rust::LangItem::lang_items): Add
unsafe_cell to the BiMap.
* util/rust-lang-item.h (class LangItem): Add UNSAFE_CELL to the
Kind enum.
Owen Avery [Sun, 2 Aug 2026 16:46:43 +0000 (12:46 -0400)]
gccrs: Move SlicePattern RestPattern handling
This allows the AST to represent SlicePattern instances with more than
one RestPattern child, which allows us to handle invalid SlicePattern
instances which would be cfg'd out and mostly avoid dealing with the
implications of a RestPattern until HIR lowering.
gcc/rust/ChangeLog:
* ast/rust-ast-collector.cc
(TokenCollector::visit (SlicePatternItemsNoRest)): Remove
function definition.
(TokenCollector::visit (SlicePatternItemsHasRest)): Likewise.
(TokenCollector::visit (SlicePattern)): Handle sub-patterns.
* ast/rust-ast-collector.h
(TokenCollector::visit (SlicePatternItemsNoRest)): Remove
function declaration.
(TokenCollector::visit (SlicePatternItemsHasRest)): Likewise.
* ast/rust-ast-full-decls.h (class SlicePatternItemsNoRest):
Remove forward declaration.
(class SlicePatternItemsHasRest): Likewise.
* ast/rust-ast-pointer-visitor.cc
(PointerVisitor::visit (SlicePatternItemsNoRest)): Remove
function definition.
(PointerVisitor::visit (SlicePatternItemsHasRest)): Likewise.
(PointerVisitor::visit (SlicePattern)): New function
definition.
* ast/rust-ast-pointer-visitor.h
(PointerVisitor::visit (SlicePatternItemsNoRest)): Remove
function declaration.
(PointerVisitor::visit (SlicePatternItemsHasRest)): Likewise.
(PointerVisitor::visit (SlicePattern)): New function
declaration.
* ast/rust-ast-visitor.cc
(DefaultASTVisitor::visit (SlicePatternItemsNoRest)): Remove
function definition.
(DefaultASTVisitor::visit (SlicePatternItemsHasRest)): Likewise.
(DefaultASTVisitor::visit (SlicePattern)): Handle sub-patterns.
* ast/rust-ast-visitor.h
(ASTVisitor::visit (SlicePatternItemsNoRest)): Remove function
declaration.
(ASTVisitor::visit (SlicePatternItemsHasRest)): Likewise.
(DefaultASTVisitor::visit (SlicePatternItemsNoRest)): Likewise.
(DefaultASTVisitor::visit (SlicePatternItemsHasRest)): Likewise.
* ast/rust-pattern.cc (SlicePatternItemsNoRest::as_string):
Remove function definition.
(SlicePatternItemsHasRest::as_string): Likewise.
(SlicePattern::as_string): Use as_string on sub patterns
directly.
(SlicePatternItemsNoRest::accept_vis): Remove function
definition.
(SlicePatternItemsHasRest::accept_vis): Likewise.
* ast/rust-pattern.h (class SlicePatternItems): Remove.
(class SlicePatternItemsNoRest): Remove.
(class SlicePatternItemsHasRest): Remove.
(SlicePattern::items): Remove member variable.
(SlicePattern::patterns): New member variable.
(SlicePattern::SlicePattern): Adjust to match member variable
adjustments.
(SlicePattern::get_items): Remove function.
(SlicePattern::get_patterns): New function.
(class CloneableDelegate<std::unique_ptr<SlicePatternItems>>):
Remove specialization.
* checks/errors/rust-ast-validation.cc
(ASTValidation::visit (SlicePattern)): New function to check for
too many RestPattern sub-patterns.
* checks/errors/rust-ast-validation.h
(ASTValidation::visit (SlicePattern)): New function declaration.
* expand/rust-cfg-strip.cc
(CfgStrip::visit (SlicePatternItemsNoRest)): Remove function
definition.
(CfgStrip::visit (SlicePatternItemsHasRest)): Likewise.
(CfgStrip::visit (SlicePattern)): Directly visit sub-patterns.
* expand/rust-cfg-strip.h
(CfgStrip::visit (SlicePatternItemsNoRest)): Remove function
declaration.
(CfgStrip::visit (SlicePatternItemsHasRest)): Likewise.
* expand/rust-derive.h
(DeriveVisitor::visit (SlicePatternItemsNoRest)): Remove
function.
(DeriveVisitor::visit (SlicePatternItemsHasRest)): Likewise.
* hir/rust-ast-lower-base.cc
(ASTLoweringBase::visit (SlicePatternItemsNoRest)): Remove
function definition.
(ASTLoweringBase::visit (SlicePatternItemsHasRest)): Likewise.
(ASTLoweringBase::lower_slice_pattern_no_rest): Likewise.
(ASTLoweringBase::lower_slice_pattern_has_rest): Likewise.
* hir/rust-ast-lower-base.h
(ASTLoweringBase::visit (SlicePatternItemsNoRest)): Remove
function declaration.
(ASTLoweringBase::visit (SlicePatternItemsHasRest)): Likewise.
(ASTLoweringBase::lower_slice_pattern_no_rest): Likewise.
(ASTLoweringBase::lower_slice_pattern_has_rest): Likewise.
* hir/rust-ast-lower-pattern.cc (lower_pattern_seq): New
function.
(ASTLoweringPattern::visit (SlicePattern)): Handle changes to
AST SlicePattern.
* parse/rust-parse-impl-pattern.hxx
(Parser::parse_slice_pattern): Likewise.
gcc/testsuite/ChangeLog:
* rust/compile/slice_rest_pattern.rs: Verify that too many rest
patterns in a slice pattern does not produce an error, if that
slice pattern is cfg'd out.
This slows down the testsuite a bit (4 minutes on my PC, without
parallelization, about 10 minutes on github CI runners), but we need
libcore to compile (and therefore need to be verifying that it does).
gcc/testsuite/ChangeLog:
* rust/core/core.exp: Compile until lowering phase, avoid
spamming the logs with debug messages in an attempt to speed up
compilation, and increase test timeout from 600 seconds to 1200
seconds.
This patch registers several lang items as stubs to progress towards
compiling the 'alloc' crate.
- 'oom', 'alloc_layout': Require no specific handling; symbol generation
is sufficient.
- 'box_free': Full implementation requires a mature drop infrastructure.
Registered as a stub for now.
- 'drop_in_place': Full implementation requires a mature drop
infrastructure. Registered as a stub for now.
- 'maybe_uninit': Requires layout engine maturity and niche-filling
mechanisms. Registered as a stub.
- 'future_trait', 'poll', 'Ready', 'Pending': Registered as stubs due
to lack of async support.
- 'generator', 'generator_state': Registered as stubs due to lack of
generator support.
The 'Ready' and 'Pending' lang items are excluded from the new test
cases because lang item attributes on enum variants are not currently
handled (see Rust-GCC/gccrs#4703).
gcc/rust/ChangeLog:
* hir/rust-ast-lower-base.cc (warn_if_stub_lang_item): New
function.
(ASTLoweringBase::handle_lang_item_attribute): Emit a warning
if lang item is stub.
* util/rust-lang-item.cc (Rust::LangItem::lang_items): Add new
lang items to the BiMap.
* util/rust-lang-item.h (class LangItem): Add new lang items
to Kind enum.
gcc/testsuite/ChangeLog:
* rust/compile/lang-items-stub.rs: New test.
* rust/compile/lang-items-symbol.rs: New test.
gccrs: Use canonical path for Clone trait within derive
Using the local path for the Clone trait cannot be used with the core
library. This broke most test that "emulate core" with a Clone trait
placed outside a "clone" module.
gcc/rust/ChangeLog:
* expand/rust-derive-clone.cc (DeriveClone::clone_call): Use the
canonical path to Clone.
gcc/testsuite/ChangeLog:
* rust/compile/derive_clone_enum2.rs: Fix test with a clone module
to mimic the core library.
* rust/compile/derive_clone_enum3.rs: Likewise.
* rust/compile/issue-3139-1.rs: Likewise.
* rust/compile/issue-3144.rs: Likewise.
* rust/execute/torture/derive_clone_enum1.rs: Likewise.
* rust/execute/torture/derive_macro3.rs: Likewise.
* rust/execute/torture/derive_macro4.rs: Likewise.
gccrs: Do not export indentation levels within metadata
Those metadata files are meant to be read by the parser and not by humans
Although it may help during compiler development, they could still get
expanded by any rust pretty printer.
gcc/rust/ChangeLog:
* ast/rust-ast-dump.cc (Dump::Dump): Add a default indentation level of
four and dump newlines.
* ast/rust-ast-dump.h: Add newline and indentation level configuration
options.
* metadata/rust-export-metadata.cc (ExportContext::emit_crate): Do not
export indentation and newlines.
* rust-session-manager.cc (Session::dump_ast_pretty_internal): Use an
indentation level of 4 and dump newlines.
The metadata format will likely change over the upcoming month and right
now it doesn't support trait impl. This commit simplifies metadata export
by dumping the whole AST within metadatas. This is slower but it should
be more complete and correct.
gcc/rust/ChangeLog:
* ast/rust-collect-lang-items.cc (CollectLangItems::visit): Visit
extern crate's content when collecting lang items.
* ast/rust-collect-lang-items.h: Add function protototype.
* metadata/rust-export-metadata.cc (ExportContext::push_module_scope):
Remove.
(ExportContext::emit_crate): Add a function to export the whole crate.
(ExportContext::pop_module_scope): Remove.
(ExportContext::emit_trait): Likewise.
(ExportContext::emit_use_declaration): Likewise.
(ExportContext::emit_function): Likewise.
(ExportContext::emit_extern_block): Likewise.
(ExportContext::emit_module): Likewise.
(class ExportVisItems): Likewise.
(PublicInterface::gather_export_data): Dump the AST.
* metadata/rust-export-metadata.h: Update prototypes.
Replace some ad-hoc handling of prelude imports with a glob import in
every module/crate.
gcc/rust/ChangeLog:
* resolve/rust-default-resolver.cc
(DefaultResolver::visit (Crate)): Call maybe_prelude_import.
(DefaultResolver::visit (Module)): Likewise.
* resolve/rust-default-resolver.h
(DefaultResolver::maybe_prelude_import): New virtual member
function.
* resolve/rust-early-name-resolver-2.0.cc
(Early::maybe_prelude_import): New member function definition.
(Early::finalize_glob_import): Mark visitor as dirty when
first setting ctx.prelude.
* resolve/rust-early-name-resolver-2.0.h
(Early::maybe_prelude_import): New member function declaration.
* resolve/rust-late-name-resolver-2.0.cc
(Late::visit (IdentifierExpr)): Remove ad-hoc prelude import
handling.
* resolve/rust-finalize-imports-2.0.cc
(GlobbingVisitor::glob_definitions): Offload details to
Rib::insert_globbed.
(GlobbingVisitor::glob_definition): Remove member function
definition.
* resolve/rust-finalize-imports-2.0.h
(GlobbingVisitor::glob_definition): Remove member function
declaration.
* resolve/rust-rib.cc (Rib::insert_globbed): New member function
definition.
* resolve/rust-rib.h (Rib::insert_globbed): New member function
declaration.
gcc/testsuite/ChangeLog:
* rust/compile/glob-import-ambiguous.rs: New test.
gccrs: Mark types used as generic arguments as live
MarkLive::visit_path_segment marked only the segment's own resolved
node, never the segment's generic arguments, so a type appearing solely
as a generic argument was never reached and the dead code lint reported
it as never constructed. Resolve each generic type argument in the
Types namespace and mark the corresponding HIR id live, before the
existing segment lookup so the arguments are still marked when the
segment itself does not resolve; an argument that fails to resolve is
skipped rather than asserted, since unlike a type alias target it need
not name a resolvable type.
Three existing tests carried dg-warning directives asserting this false
positive and have had them removed.
Fixes Rust-GCC/gccrs#4585
gcc/rust/ChangeLog:
* checks/lints/rust-lint-marklive.cc (MarkLive::visit_path_segment):
Mark types in generic arguments as live.
Also removes some dead code in flatten, since I saw it while working on
this PR and it's too small to be its own patch.
gcc/rust/ChangeLog:
* resolve/rust-early-name-resolver-2.0.cc
(Early::resolve_glob_import): Handle glob imports that appear
after other imports in a use declaration.
* resolve/rust-early-name-resolver-2.0.h
(Early::ImportMappings::insert): Remove member functions, as
they're both broken and unused.
* resolve/rust-toplevel-name-resolver-2.0.cc (flatten): Remove
redundant break statement.
gccrs: hir: Remove unnecessary HIR::RangeFromToInclExpr class
This patch removes the unnecessary HIR::RangeFromToInclExpr class and its
associated visitors across the compiler. Since inclusive ranges are now
directly desugared into a CallExpr targeting the 'range_inclusive_new'
lang item during AST-to-HIR lowering, this HIR node and its
codegen/typecheck implementations are dead code.
This patch introduces the 'range_inclusive_new' lang item to the compiler.
When the compiler encounters an inclusive range expression, it now
correctly desugars the operation into a function call targeting this
lang item instead of lowering it directly into a static struct.
gcc/rust/ChangeLog:
* hir/rust-ast-lower-expr.cc (ASTLoweringExpr::visit): Add
desugaring for range_inclusive_new lang item.
* util/rust-lang-item.cc (Rust::LangItem::lang_items): Add
range_inclusive_new to the BiMap.
* util/rust-lang-item.h (class LangItem): Add RANGE_INCLUSIVE_NEW
to the Kind enum.
gcc/testsuite/ChangeLog:
* rust/compile/torture/range-lang-item1.rs: Update test to use
the new lang item.
Lishin [Wed, 24 Jun 2026 18:46:19 +0000 (18:46 +0000)]
gccrs: Emit drops before explicit returns
Add the missing drop emission before returning from explicit return expressions.
Explicit returns can leave more than the current block scope, so emit drops for
all active block scopes before the return statement.
When the explicit return has a value, save it before running drops. When a
unit return has an explicit expression, emit that expression before running
drops and returning unit.
The new test covers `return;`, `return make_unit();`, `return make_value();`,
and nested explicit returns.
gcc/rust/ChangeLog:
* backend/rust-compile-drop-builder.cc
(DropBuilder::get_block_drop_candidate_stack): New function returning all
active block drop candidate scopes.
* backend/rust-compile-drop-builder.h
(DropBuilder::get_block_drop_candidate_stack): Declare.
* backend/rust-compile-drop.h:
(CompileDrop::emit_drop_candidate_calls): Declare.
* backend/rust-compile-expr.cc (CompileExpr::visit): Save return values and
emit drops before explicit return statements.
* typecheck/rust-hir-type-check-item.cc (TypeCheckItem::visit(StructStruct)): Update
E0690 error message to use the correct variable for number of fields.
* typecheck/rust-tyty.cc (ArrayType::is_zero_sized): Catch edge case of array's element
type being a ZST with capacity is more than 0.
gcc/testsuite/ChangeLog:
* rust/compile/repr_transparent_fields.rs: Add more test cases.
* resolve/rust-early-name-resolver-2.0.cc
(Early::finalize_glob_import): Check if the globbing visitor was
marked dirty.
* resolve/rust-finalize-imports-2.0.cc
(GlobbingVisitor::glob_definitions): Mark dirty if a definition
was inserted.
(GlobbingVisitor::glob_definition): Replace silent failure with
assertion.
* resolve/rust-finalize-imports-2.0.h
(GlobbingVisitor::GlobbingVisitor): Initialize dirty member
variable.
(GlobbingVisitor::is_dirty): New member function.
(GlobbingVisitor::dirty): New member variable.
gccrs: Improve resolution and compilation of control flow loops and labels
This batch fixes and improves the handling of loop expressions, particularly
focusing on `break` and `continue` statements within labeled and nested loops.
gcc/rust/ChangeLog:
* backend/rust-compile-context.h (RUST_COMPILE_CONTEXT): loop
labels context functions.
- insert_break_label
- lookup_break_label
- insert_continue_label
- lookup_continue_label
- push/pop/peek end_label (similar to begin_label).
* backend/rust-compile-expr.cc (CompileExpr::visit): handle loop
labels construction in WhileExpr, ForExpr, ContinueExpr and BreakExpr.
(CompileExpr::construct_block_label): construct break label
instead of normal label to unify handling break statement.
(CompileExpr::construct_loop_labels): construct while/for loops
labels (continue label before loop, break label after loop).
* backend/rust-compile-expr.h (RUST_COMPILE_EXPR):
construct_loop_labels function header.
* resolve/rust-default-resolver.cc (DefaultResolver::visit): Fix
labels.
* resolve/rust-default-resolver.h: Fix labels.
* resolve/rust-name-resolution-context.cc (NameResolutionContext::insert): Fix labels.
(NameResolutionContext::insert_shadowable): Fix labels.
(NameResolutionContext::insert_globbed): Fix labels.
(NameResolutionContext::scoped): Fix labels.
gcc/testsuite/ChangeLog:
* rust/execute/cf-break-continue.rs: New test.
* rust/execute/cf-label-shadowing.rs: New test.
* rust/execute/cf-labeled-break-nested.rs: New test.
* rust/execute/cf-labeled-continue-nested.rs: New test.
* rust/execute/cf-labeled-loops.rs: New test.
* rust/execute/cf-loop-break-continue.rs: New test.
* rust/execute/cf-mixed-labeled-unlabeled.rs: New test.
* rust/execute/cf-nested-loops.rs: New test.
gccrs: Apply try-finally cleanup for function-scope drops
Remove the individual drop-emission calls, and centralize
function-scope drop by building the cleanup and popping block.
Apply the same cleanup path to constant-item and closure function
bodies.
gcc/rust/ChangeLog:
* backend/rust-compile-base.cc (HIRCompileBase::compile_function_body):
Stop emitting drops directly in functions.
(HIRCompileBase::compile_function): Use try-finally drop cleanup.
(HIRCompileBase::compile_constant_item): Use try-finally drop cleanup.
* backend/rust-compile-drop.cc
(CompileDrop::emit_current_scope_drop_calls): Remove.
* backend/rust-compile-drop.h: Remove the unused function declaration.
* backend/rust-compile-expr.cc
(CompileExpr::generate_closure_function): Use try-finally drop cleanup.
Lucas Ly Ba [Tue, 18 Nov 2025 16:02:27 +0000 (16:02 +0000)]
gccrs: refactor dead code lint
This patch is simple, it only moves the check of unused static items
and unused const items into the dead-code scan visitor. The static
item naming lint stays in the unused checker.
gccrs: Support ZST type checking for `#[repr(transparent)]`
gcc/rust/ChangeLog:
* typecheck/rust-tyty.h (BaseType::is_zero_sized): New function.
(TupleType::is_zero_sized): New function.
(ArrayType::is_zero_sized): New function.
(ADTType::is_zero_sized): New function.
* typecheck/rust-tyty.cc (BaseType::is_zero_sized): Implement checking of
whether a type is zero-sized.
(TupleType::is_zero_sized): Ditto.
(ArrayType::is_zero_sized): Ditto.
(ADTType::is_zero_sized): Ditto.
* typecheck/rust-hir-type-check-item.cc (TypeCheckItem::visit (StructStruct)): Update
transparent repr type-checking to check for zero-sized members.
* backend/rust-compile-type.cc (TyTyResolveCompile::visit (TyTy::ADTType)): Support
compilation of transparent repr structs with more than 1 fields.
gcc/testsuite/ChangeLog:
* rust/compile/repr_transparent_fields.rs: Add new test case with PhantomData.
Egas Ribeiro [Tue, 19 May 2026 17:08:14 +0000 (18:08 +0100)]
gccrs: rust: Enforce irrefutability in let bindings and function parameters
Add diagnostics for refutable patterns appearing in positions that
require irrefutability: let bindings (without an else clause) and
function parameters. Uses the type-aware is_refutable(BaseType&)
introduced in the previous commit.
The existing syntactic check for the function parameters case done
during AST lowering is reduced to handle only bare literal patterns,
with the comprehensive check deferred to PatternChecker after the type
checker populates the necessary type information.
Add comprehensive tests that cover the implemented refutability checks.
Addresses: Rust-GCC#2082
gcc/rust/ChangeLog:
* checks/errors/rust-hir-pattern-analysis.cc
(PatternChecker::visit): Diagnose refutable patterns in Function
parameters and LetStmt bindings.
* hir/rust-ast-lower-item.cc (ASTLoweringItem::visit): Remove
pattern kind whitelist; only error on bare literal patterns at
lowering.
gcc/testsuite/ChangeLog:
* rust/compile/irrefutable-alt.rs: New test.
* rust/compile/irrefutable-basic.rs: New test.
* rust/compile/irrefutable-identifier-binding.rs: New test.
* rust/compile/irrefutable-nested.rs: New test.
* rust/compile/irrefutable-path.rs: New test.
* rust/compile/irrefutable-range.rs: New test.
* rust/compile/irrefutable-reference.rs: New test.
* rust/compile/irrefutable-slice.rs: New test.
* rust/compile/irrefutable-struct.rs: New test.
* rust/compile/irrefutable-tuple.rs: New test.
* rust/compile/refutable-alt.rs: New test.
* rust/compile/refutable-binding.rs: New test.
* rust/compile/refutable-literal-let.rs: New test.
* rust/compile/refutable-literal-parameter.rs: New test.
* rust/compile/refutable-path.rs: New test.
* rust/compile/refutable-range.rs: New test.
* rust/compile/refutable-reference.rs: New test.
* rust/compile/refutable-struct.rs: New test.
* rust/compile/refutable-tuple.rs: New test.
Co-authored-by: João Novo <joao.c.novo@tecnico.ulisboa.pt> Signed-off-by: Egas Ribeiro <egas.g.ribeiro@tecnico.ulisboa.pt>
Egas Ribeiro [Tue, 19 May 2026 17:06:51 +0000 (18:06 +0100)]
gccrs: rust: Add is_refutable methods to HIR pattern nodes
This adds the is_refutable() and is_refutable(BaseType&) virtual methods
to HIR pattern nodes, distinguishing patterns whose refutability can be
determined syntactically from those requiring type context.
The syntactic overload returns a definitive answer for wildcards and
literals. Other patterns that depend on type context to be checked for
refutability, or call is_refutable() recursively, implement the typed
overload and ICE if called via the syntactic overload.
Addresses: Rust-GCC#2082
gcc/rust/ChangeLog:
* Make-lang.in: Add rust-hir-pattern-abstract.o.
* hir/tree/rust-hir-path.h: Add is_refutable overrides.
* hir/tree/rust-hir-pattern-abstract.h (class BaseType): Add
typed is_refutable virtual method.
* hir/tree/rust-hir-pattern.h: Add is_refutable to all pattern
kinds.
* hir/tree/rust-hir-pattern-abstract.cc: New file. Implement
typed is_refutable for PathPattern, SlicePattern,
TupleStructPattern.
Co-authored-by: João Novo <joao.c.novo@tecnico.ulisboa.pt> Signed-off-by: Egas Ribeiro <egas.g.ribeiro@tecnico.ulisboa.pt>
gccrs: Fix duplicate "trailing semicolon in macro used" warnings
gcc/rust/ChangeLog:
* expand/rust-macro-expand.cc (transcribe_expression (Parser<MacroInvocLexer>)):
Prevent the same trailing semicolon warning from being generated at the same loc.
This patch registers the 'rustc_conversion_suggestion' attribute. This
attribute is needed for compiling the alloc crate, so we register it as
a stub and the compiler will emit a warning when it encounters this
attribute.
gcc/rust/ChangeLog:
* checks/errors/rust-builtin-attribute-checker.cc
(attribute_checking_handlers): Add rustc_conversion_suggestion
attribute to map.
(check_valid_attribute_for_item): Add warning for new attribute.
* util/rust-attribute-values.h (class Attributes): Add
RUSTC_CONVERSION_SUGGESTION constexpr.
* util/rust-attributes.cc (__definitions): Add
BuiltinAttrDefinition for new attribute.
gcc/testsuite/ChangeLog:
* rust/compile/rustc_conversion_suggestion.rs: New test.
This patch registers the 'needs_allocator' attribute, which is required
for compiling the 'alloc' crate.
Currently, it is implemented as a stub that emits a compiler warning
when encountered. The reoson for this temporary stub is that full
handling of 'needs_allocator' strictly depends on the 'global_allocator'
infrastructure and the 'core::alloc::GlobalAlloc' trait. Since gccrs
does not yet have full support for the 'core' crate, a complete
implementation is deferred.
gcc/rust/ChangeLog:
* checks/errors/rust-builtin-attribute-checker.cc
(check_inner_attribute): Add warning for needs_allocator.
* util/rust-attribute-values.h (class Attributes): Add
NEEDS_ALLOCATOR constexpr.
* util/rust-attributes.cc (__definitions): Add
BuiltinAttrDefinition for new attribute.
Tomasz Kamiński [Thu, 6 Aug 2026 11:46:06 +0000 (13:46 +0200)]
libstdc++: Deprecate std::errc constants related to UNIX STREAMS.
Add _GLIBCXX23_DEPRECATED attribute to no_message_available,
no_stream_resources, not_a_stream, stream_timeout, per LWG3869,
"Deprecate std::errc constants related to UNIX STREAMS".
The config/os/mingw32/error_constants.h does not define any
of above enumerators (they definitions are commented out).
This patch adds the 'assert_zero_valid' intrinsic to the compiler.
Properly implementing this intrinsic requires layout engine support to
detect types that cannot be safely zero-initialized (e.g., references
and NonNull types). Since gccrs currently lacks this capability, it is
implemented as a temporary stub that always returns unit `()`.
Normally, this intrinsic should inject a runtime panic during codegen
if the provided type does not permit zero-initialization.
gcc/rust/ChangeLog:
* backend/rust-compile-intrinsic.cc (generic_intrinsics): Add
assert_zero_valid to map.
* backend/rust-intrinsic-handlers.cc
(assert_zero_valid_handler): New function.
* backend/rust-intrinsic-handlers.h (assert_zero_valid_handler):
New declaration.
* typecheck/rust-hir-type-check-intrinsic.cc
(IntrinsicChecker::intrinsic_rules): Add new signature rule for
assert_zero_valid.
* util/rust-intrinsic-values.h (class Intrinsics): Add
ASSERT_ZERO_VALID constexpr.
* resolve/rust-forever-stack.hxx
(ForeverStack::find_starting_point): Handle a final super
segment and super segments after a lowercase self segment.
* resolve/rust-name-resolution-context.hxx
(NameResolutionContext::resolve_path): Handle cases where
find_starting_point resolves the final segment.
gccrs: Emit block scope drops through TRY_FINALLY_EXPR
Add Context::pop_block_with_cleanup for blocks that need cleanup.
Use it from CompileBlock so block-scope drops are emitted in a
TRY_FINALLY_EXPR cleanup instead of at the end of the block body.
gcc/rust/ChangeLog:
* backend/rust-compile-block.cc
(CompileBlock::visit): Build current scope drop cleanup and
pass it when popping the block.
* backend/rust-compile-context.h
(Context::pop_block): Use pop_block_impl.
(Context::pop_block_with_cleanup): New function for popping
a block with cleanup code.
(Context::pop_block_impl): New helper that adds the block
statements directly, or wraps them in TRY_FINALLY_EXPR when
cleanup is present.
Add CompileDrop::build_current_scope_drop_cleanup to build the drop
calls for the current scope as one statement tree.
This allows a follow-up patch to place the same cleanup tree in a
TRY_FINALLY_EXPR.
gcc/rust/ChangeLog:
* backend/rust-compile-drop.cc
(CompileDrop::build_current_scope_drop_cleanup): New function to
build current scope drop calls as a statement tree.
(CompileDrop::emit_current_scope_drop_calls): Use it.
* backend/rust-compile-drop.h
(CompileDrop::build_current_scope_drop_cleanup): Declare.
Lucas Ly Ba [Sat, 27 Jun 2026 21:12:31 +0000 (23:12 +0200)]
gccrs: add dyn drop lint
Warn on a trait object that carries a `Drop` bound, as values are
dropped automatically and the bound has no effect.
gcc/rust/ChangeLog:
* typecheck/rust-hir-type-check-type.cc (TypeCheckType::visit): Warn on
a trait object with a `Drop` bound.
* rust-lang.cc (grs_langhook_init_options_struct): Enable warn_unused.
gcc/testsuite/ChangeLog:
* rust/compile/dyn-drop_0.rs: New test.
Signed-off-by: Lucas Ly Ba <lucas.ly-ba@outlook.com>
* resolve/rust-toplevel-name-resolver-2.0.cc
(TopLevel::visit (ExternalTypeItem)): New function definition.
* resolve/rust-toplevel-name-resolver-2.0.h
(TopLevel::visit (ExternalTypeItem)): New function declaration.
gcc/testsuite/ChangeLog:
* rust/compile/extern_type_item_resolve.rs: New test.
gccrs: Add new checks for `#[repr(align)]` attribute
gcc/rust/ChangeLog:
* typecheck/rust-hir-type-check-base.cc (TypeCheckBase::parse_repr_options): New
check for `#[repr(align)]` to enforce having a parameter that is a power of 2.
gcc/testsuite/ChangeLog:
* rust/compile/invalid_repr_hint.rs: Update existing and add new `align` test cases.
gccrs: Implement compilation of #[repr(transparent)] structs
gcc/rust/ChangeLog:
* backend/rust-compile-expr.h (CompileExpr::compile_transparent_field_access): New
helper function.
* backend/rust-compile-expr.cc (CompileExpr::compile_transparent_field_access):
Implement helper function for accessing the field of #[repr(transparent)] ADTs.
(CompileExpr::visit (HIR::StructExprStructFields)): Support struct field construction
properly for #[repr(transparent)] structs.
(CompileExpr::visit (HIR::FieldAccessExpr)): Implement proper compilation of field
access for #[repr(transparent)] ADTs.
* backend/rust-compile-type.cc (TyTyResolveCompile::visit (TyTy::ADTType)): Implement
proper compilation of typing for #[repr(transparent)] ADTs.
Arthur Cohen [Wed, 3 Dec 2025 10:11:52 +0000 (11:11 +0100)]
gccrs: core: Detect whether we are compiling core or any other crate
When generating AST nodes for desugaring or deriving builtin traits, the compiler must be
aware of the crate it is currently compiling - and more precisely, whether it is compiling
`core` or any other crate. This is important mainly for the generation of canonicalized path
nodes during macro expansion. For example, when deriving `Copy` for a type in a regular crate,
the compiler should emit paths of the form `core::marker::Copy`. However, when the compiler
is compiling `core` itself, these paths should be of the form `crate::marker::Copy`, as we are
trying to refer to the `Copy` trait present in the current crate. While this isn't a problem
for most builtin derives as they are lang items, it still shows up in a few places and needs
to be handled properly.
GlobbingVisitor can copy definitions between ribs, instead of creating
new definitions from the AST.
gcc/rust/ChangeLog:
* resolve/rust-finalize-imports-2.0.cc (GlobbingVisitor::go):
Use visit_container.
(GlobbingVisitor::visit_crate_container)
(GlobbingVisitor::visit_module_container)
(GlobbingVisitor::visit_enum_container, GlobbingVisitor::visit):
Remove member functions.
(GlobbingVisitor::visit_container)
(GlobbingVisitor::glob_definitions)
(GlobbingVisitor::glob_definition): New member functions.
* resolve/rust-finalize-imports-2.0.h (class GlobbingVisitor):
Remove DefaultASTVisitor as base class.
(GlobbingVisitor::visit_crate_container)
(GlobbingVisitor::visit_module_container)
(GlobbingVisitor::visit_enum_container, GlobbingVisitor::visit):
Remove member functions.
(GlobbingVisitor::visit_container)
(GlobbingVisitor::glob_definitions)
(GlobbingVisitor::glob_definition): New member functions.
Owen Avery [Mon, 29 Jun 2026 02:50:06 +0000 (22:50 -0400)]
gccrs: Add compatible version option
GCCRS targets version 1.49 of rust. However, rust for linux expects rust
1.78 or later (soon 1.85 or later) and we will want to bump our main
target version from 1.49 eventually. This patch adds an option for the
user to specify a rust version to target for compatibility, so that
we can account for backwards incompatible behavior between rust
versions.
This should allow libcore 1.49 to compile without explicitly enabling
post-1.49 features.
gcc/rust/ChangeLog:
* checks/errors/feature/rust-feature-collector.cc: Include
"rust-session-manager.h".
(FeatureCollector::collect): Automatically enable
EXTENDED_KEY_VALUE_ATTRIBUTES when targeting compatibility with
rust versions before 1.50.
* expand/rust-macro-expand.cc: Include "rust-session-manager.h".
(MacroExpander::expand_invoc): Use Session to determine whether
offset_of is supported.
* lang.opt (frust-assume-builtin-offset-of): Remove option,
superseded by...
(frust-compat-version): ...new option.
* resolve/rust-early-name-resolver-2.0.cc: Include
"rust-session-manager.h".
(Early::visit (MacroInvocation)): Use Session to determine
whether offset_of is supported.
* rust-session-manager.cc (Session::handle_option): Handle
frust-compat-version.
* rust-session-manager.h (CompileOptions::compat_version): New
member variable.
(CompileOptions::set_compat_version): New member function.
(CompileOptions::get_compat_version): Likewise.
(Session::get_compat_version): Likewise.
(Session::should_support_offset_of): Likewise.
Owen Avery [Sun, 28 Jun 2026 20:45:36 +0000 (16:45 -0400)]
gccrs: Unify node trees
Each ForeverStack builds a tree of nodes. Since we already assume that
nodes in one ForeverStack map one-to-one with nodes in another
ForeverStack, we can have multiple ForeverStack instances share the same
set of nodes.
gcc/rust/ChangeLog:
* resolve/rust-forever-stack.h (ForeverStackBase::Node::Node):
Initialize all namespace ribs with a Rib::Kind.
(ForeverStackBase::Node::rib): Replace member variable with member
function taking namespace.
(ForeverStackBase::Node::rib_values): New member variable.
(ForeverStackBase::Node::rib_types): New member variable.
(ForeverStackBase::Node::rib_labels): New member variable.
(ForeverStackBase::Node::rib_macros): New member variable.
(ForeverStackBase::ForeverStackBase): New constructor taking
references to top-level nodes.
(ForeverStack::root): Move member variable to...
(ForeverStackBase::root): ...here and make it a reference.
(ForeverStack::lang_prelude): Move member variable to...
(ForeverStackBase::lang_prelude): ...here and make it a
reference.
(ForeverStack::extern_prelude): Move member variable to...
(ForeverStackBase::extern_prelude): ...here and make it a
reference.
(ForeverStack::ForeverStack): Initialize ForeverStackBase
and take top-level nodes as by-reference arguments.
(ForeverStack::push_inner): Take Rib::Kind instead of Rib.
* resolve/rust-forever-stack.hxx (ForeverStackBase::is_prelude):
Use value rib to get rib kind.
(ForeverStack::push_inner): Take Rib::Kind instead of Rib.
(ForeverStack::pop): Use namespace specific ribs.
(ForeverStack::insert_at_root): Likewise.
(ForeverStack::insert_lang_prelude): Likewise.
(ForeverStack::peek): Likewise.
(ForeverStack::get): Likewise.
(ForeverStack::get_lang_prelude): Likewise.
(ForeverStack::find_closest_module): Likewise.
(ForeverStack::dfs): Likewise.
(ForeverStack::dfs_rib): Likewise.
(ForeverStack::stream_node): Likewise.
* resolve/rust-name-resolution-context.cc
(NameResolutionContext::merge): Likewise.
(NameResolutionContext::NameResolutionContext): Initialize
top-level nodes and construct ForeverStack instances with
references.
* resolve/rust-name-resolution-context.h
(NameResolutionContext::Node): New type alias to
ForeverStackBase::Node.
(NameResolutionContext::root): New member variable.
(NameResolutionContext::lang_prelude): New member variable.
(NameResolutionContext::extern_prelude): New member variable.
* resolve/rust-name-resolution-context.hxx
(NameResolutionContext::should_search_prelude): Use namespace
specific rib.
(NameResolutionContext::resolve_path): Simplify mapping to and
from type namespace nodes (now a no-op). Also, use namespace
specific ribs for looking up final segments.
(NameResolutionContext::resolve_segments): Use namespace
specific ribs.
(NameResolutionContext::resolve_final_segment): Likewise.
* resolve/rust-identifier-path.cc
(IdentifierPathPass::reseat (Pattern)): Remember to visit a
pattern's sub-patterns, if we didn't convert it into a
PathInExpression.
This allows gccrs to recognize the global_allocator attribute and
perform some sanity checks on its usage, but does not implement proper
handling for the attribute.
gcc/rust/ChangeLog:
* checks/errors/rust-builtin-attribute-checker.cc (no_mangle):
Remove function.
(rustc_std_internal_symbol): Likewise.
(rustc_allocator): Likewise.
(rustc_allocator_nounwind): Likewise.
(expect_no_input): New function.
(attribute_checking_handlers): Use expect_no_input, new entry
for GLOBAL_ALLOCATOR.
(check_valid_attribute_for_item): Verify that GLOBAL_ALLOCATOR
attributes only appear on static items.
* util/rust-attribute-values.h (Attributes::GLOBAL_ALLOCATOR):
New static constexpr member variable.
* util/rust-attributes.cc (__definitions): New entry for
GLOBAL_ALLOCATOR.