Marek Polacek [Mon, 9 Feb 2026 18:54:39 +0000 (13:54 -0500)]
c++: fix for saved_token_sentinel
In cp_parser_splice_spec_is_nns_p I didn't use saved_token_sentinel:
its rollback uses cp_lexer_previous_token so if we are the first token
in the file, there are no previous tokens so we crash.
It would be simple to just use the _safe variant of cp_lexer_previous_token
and be done with this. But that's not how this worked out: I saw a new
-fcompare-debug FAIL with pr104025.C. The problem is that at the end of
cp_parser_id_expression we have a saved_token_sentinel guarded by
warn_missing_template_keyword and in that spot lexer->buffer is NULL (so
cp_lexer_set_source_position_from_token would be skipped). pr104025.C
is compiled twice, the second time with "-w -fcompare-debug-second". So
the first time we don't _set_source_position back to where we were after the
_skip_entire_template_parameter_list (lexer->buffer is NULL) and the second
time we don't get to the saved_token_sentinel at all. That left us with
different columns in the location:
"pr104025.C":16:16 vs "pr104025.C":16:12
thus the -fcompare-debug FAIL. I assume we don't want -fcompare-debug
to ignore the column location. So we could just save input_location in
saved_token_sentinel instead of trying to recover it. And then
cp_parser_splice_spec_is_nns_p can be simplified.
gcc/cp/ChangeLog:
* parser.cc (struct saved_token_sentinel): Save input_location.
(saved_token_sentinel::rollback): Restore input_location.
(cp_parser_splice_spec_is_nns_p): Use saved_token_sentinel. Refactor.
When load/store with length is used and only QImode versions are
available, vectorizable_live_operation produces wrong results for
VEC_EXTRACT. Provide a flag to vect_get_loop_len to specify if
bias-adjusted length should be used or not.
Tomasz Kamiński [Thu, 29 Jan 2026 17:14:47 +0000 (18:14 +0100)]
libstdc++: Allow constant initialization of std::atomic of types with padding [PR123875]
Currently for the types T that contains padding bits, std::atomic<T>(T)
constructor was not usable at compile-time in C++14 or later modes. This
regression caused by use of __builtin_clear_padding introduced in r13-2548-g157236dbd62164.
This leads to two regressions when switching from C++11 to C++14
standard (or switching from GCC-12 to later version for C++14 standard),
where for type X that contains padding
* constexpr std::atomic<X> cx(X(...)) becomes ill-formed,
* std::atomic<X> gx(X(...)) with static storage duration, switch from
static to dynamic initialization.
The latter breakage is silent and may introduced very hard to localize
order of initialization issues.
This patch mitigates above issue by not invoking the __builtin_clear_padding,
during constant initialization (std::__is_constant_evaluated() is false).
This is considered to be safe, as:
* for objects with static storage duration, padding bits are already
cleared by zero-initialization
* for constexpr objects with non-static storage duration, there is no
API that would allow user to observe padding bits on const atomic objects
To elaborate on the second point, values of padding bits in atomic can
be observed by:
* The compare_exchange_weak/compare_exchange_strong operations are mutating,
so cannot be invoked on const objects.
* As atomic<X> is not required to store actual object of type X,
observing its object representation does (via bitcast, memcpy), does
not provide values of object representation of X. Furthermore, the
operations are defined only for trivially_copyable types, and atomic
specializations meets above requirement only due to bug in libstdc++
(see PR67572).
Note that above will no longer hold, and the solution will need to be
revisited during implementation of C++26 paper P3309R3: constexpr
atomic and atomic_ref (it will be possible to call compare_exchange
during constant evaluation).
PR libstdc++/123875
libstdc++-v3/ChangeLog:
* include/bits/atomic_base.h (__atomic_impl::__clear_padding):
Use if constexpr unconditionally.
(__atomic_float<_Fp>::__atomic_float(_Fp)): Skip __clear_padding
call for constant evaluation.
* include/std/atomic (atomic<_Tp>::atomic(_Tp)): Likewise.
* testsuite/29_atomics/atomic/cons/static_zero_padding.cc: New test.
Reviewed-by: Patrick Palka <ppalka@redhat.com> Reviewed-by: Jonathan Wakely <jwakely@redhat.com> Signed-off-by: Tomasz Kamiński <tkaminsk@redhat.com>
Kyrylo Tkachov [Fri, 6 Feb 2026 10:34:29 +0000 (02:34 -0800)]
aarch64: Adjust SVE vector costs for NVIDIA Olympus
After some more analysis, I'd like to adjust the SVE load
cost for NVIDIA Olympus to more accurately reflect the core SWOG.
This leads to more sensible Advanced SIMD vs SVE autovec decisions.
Bootstrapped and tested on aarch64-none-linux-gnu.
The following adds a heuristic to ifcombine that avoids turning
analyzable loop exits into unanalyzable ones. This allows vectorizing
the testcase in the PR again. I've refrained from actually
analyzing niters but instead used a cheaper heuristic. I believe
we'll only ever attempt to combine two ifs if they are in the same
loop and if either both exit the loop or stay within.
PR tree-optimization/107690
* tree-ssa-ifcombine.cc (ifcombine_ifandif): Do not merge
possibly analyzable exit conditions.
David Malcolm [Tue, 10 Feb 2026 04:14:22 +0000 (23:14 -0500)]
analyzer: fix assertion failure in bounded_ranges::cmp [PR113496]
gcc/analyzer/ChangeLog:
PR analyzer/113496
* constraint-manager.cc (cmp_types): New.
(bounded_range::cmp): Compare the types of the constants, as well
as their values.
gcc/testsuite/ChangeLog:
PR analyzer/113496
* gcc.dg/analyzer/ice-pr113496.c: New test.
Signed-off-by: David Malcolm <dmalcolm@redhat.com>
Patrick Palka [Tue, 10 Feb 2026 01:32:39 +0000 (20:32 -0500)]
c++: tf_partial and alias_ctad_tweaks [PR122621]
Like in r15-6740-g27d620d6769715 for instantiate_template with dependent
arguments, we also need to set tf_partial during the alias_ctad_tweaks
transformation mainly for benefit of properly handling extra-args trees.
In this testcase during alias_ctad_tweaks we substitute the dependent
ElemTs={Tuple<Us...>}, Ts={Ts...} into the requires-clause, which
tsubst_pack_expansion decides to defer via extra-args, and for the
subsequent add_extra_args (during guide overload resolution) to merge
the deferred dependent arguments correctly, tf_partial has to have been
set.
PR c++/122621
gcc/cp/ChangeLog:
* pt.cc (tsubst_pack_expansion): Use tf_partial instead of
tf_none, except when substituting outer (non-dependent) template
arguments.
gcc/testsuite/ChangeLog:
* g++.dg/cpp2a/class-deduction-alias26.C: New test.
Patrick Palka [Tue, 10 Feb 2026 01:04:12 +0000 (20:04 -0500)]
libstdc++/regex: Remove now unused __dfs_mode template parameter
This mechanical patch removes _Executor's __dfs_mode template parameter.
In passing we can also get rid of the _V2 inline namespace because this
removal alone achieve the goal of the inline namespace which is to make
all of _Executor's member function signatures different from the
previous (GCC < 16) recursive implementation, allowing for safe mixing
of the two incompatible implementations.
Patrick Palka [Tue, 10 Feb 2026 01:04:00 +0000 (20:04 -0500)]
libstdc++/regex: Replace __dfs_mode template parameter with run-time flag
That _Executor's __dfs_mode flag is a template parameter means
__regex_algo_impl has to instantiate two different (but largely the
same) versions of _Executor even though the BFS version is rarely used.
And it seems the compiler has trouble DCEing the unused version of
_Executor, which needlessly increases code size and burdens the optimizer.
This patch replaces the template parameter with a run-time data member
_M_search_mode. We in turn need to inline the _Executor::_State_info
member functions and data members into _Executor so that they depend on
the run-time instead of compile-time flag. This means _Executor is
three pointers bigger in DFS mode (due to the unused _M_match_queue and
_M_visited_states members), which we can reduce to one pointer if we
really want to, but that doesn't seem ver worthwhile.
The __dfs_mode template parameter is now unused but not yet removed,
that'll be done in the next patch.
After this patch, both code size and run time for the microbenchmark
for (int i = 0; i < 10000; i++)
regex_match(string(200, 'a'), regex("(a|b|c)*"));
decreases by about 15% each (with -O2). Compile time/memory use decreases
by 5-10%.
libstdc++-v3/ChangeLog:
* include/bits/regex.tcc (__regex_algo_impl): Pass __use_dfs
parameter to _Executor's constructor.
* include/bits/regex_executor.h (_Executor::_Search_mode): New.
(_Executor::_Executor): Add __use_dfs parameter and initialize
_M_search_mode. Adjust after inlining _State_info members into
_Executor.
(_Executor::~_Executor): Free _M_visted_states.
(_Executor::_M_main): Adjust after renaming _M_main_dispatch
overloads to _M_main_dfs and _M_main_bfs.
(_Executor::_State_info): Remove.
(_Executor::_M_visited): Inlined from _State_info.
(_Executor::_M_get_sol_pos): Likewise.
(_Executor::_M_states): Remove.
(_Executor::_M_start): Inlined from _State_info.
(_Executor::_M_sol_pos): Likewise.
(_Executor::_M_match_queue): Likewise.
(_Executor::_M_search_mode): New.
* include/bits/regex_executor.tcc (_Executor::_M_main_dispatch):
Renamed to...
(_Executor::_M_main_dfs, _Executor::_M_main_bfs): ... these.
(_Executor::_M_*): Adjust after _M_states removal.
(_Executor::_M_lookhead): Also adjust _Executor constructor
call.
Reviewed-by: Tomasz Kamiński <tkaminsk@redhat.com> Reviewed-by: Jonathan Wakely <jwakely@redhat.com>
David Malcolm [Mon, 9 Feb 2026 23:41:22 +0000 (18:41 -0500)]
sarif output: Fix ICE due to overzealous caching [PR124014]
PR diagnostics/124014 identifies an ICE in sarif output of
diagnostics that occur after free_lang_data has called
tree_diagnostics_defaults, which happens e.g. with lto.
The issue is that in r16-413-g8ab6899dce92e6 I introduced to sarif_sink
a cached pointer to the logical_locations::manager, which for tree-using
clients is part of the compiler_data_hooks. Hence for the case above, the
pointer is freed from under the sarif_sink, and any diagnostic
issued after that point with a current_function_decl will
trigger a use-after-free.
Fix by removing the cached pointer.
gcc/ChangeLog:
PR diagnostics/124014
* diagnostics/sarif-sink.cc
(sarif_builder::get_logical_location_manager): Reimplement, to
eliminate m_logical_loc_mgr.
(sarif_builder::m_logical_loc_mgr): Drop field.
(sarif_builder::sarif_builder): Update for removed field.
(sarif_builder::set_any_logical_locs_arr): Likewise.
(sarif_builder::ensure_sarif_logical_location_for): Likewise.
(sarif_builder::make_minimal_sarif_logical_location): Likewise.
gcc/testsuite/ChangeLog:
PR diagnostics/124014
* gcc.dg/sarif-output/ice-pr124014.c: New test.
Signed-off-by: David Malcolm <dmalcolm@redhat.com>
Signed-off-by: Jose E. Marchesi <jemarch@gnu.org>
gcc/algol68/ChangeLog
* a68-low-holes.cc (a68_wrap_formal_proc_hole): The wrapper is not
a top-level function.
* a68-low-units.cc (a68_lower_formal_hole): Reorder code and
remove spurious comment.
Jonathan Wakely [Mon, 9 Feb 2026 20:41:46 +0000 (20:41 +0000)]
libstdc++: Fix doxygen comment for std::out_ptr [PR124024]
libstdc++-v3/ChangeLog:
PR libstdc++/124024
* include/bits/out_ptr.h (out_ptr): Fix doxygen comment to refer
to the right function.
(inout_ptr): Improve markup in doxygen comment.
David Faust [Wed, 4 Feb 2026 20:13:45 +0000 (12:13 -0800)]
bpf: set SLOW_BYTE_ACCESS to 0 [PR123556]
In general, BPF programs are JIT-ed to various architectures, and we
cannot say for certain what memory access patterns are preferable.
But it is clear that for the sake of the BPF verifier smaller loads are
to be preferred when possible, so set SLOW_BYTE_ACCESS to zero.
Tested on x86_64-linux-gnu host for bpf-unknown-none, no regressions.
Also tested against Linux kernel bpf-next selftests, no changes.
PR target/123556
gcc/
* config/bpf/bpf.h (SLOW_BYTE_ACCESS): Set to 0, update comment.
gcc/testsuite/
* gcc.target/bpf/pr123556.c: New test.
Jakub Jelinek [Mon, 9 Feb 2026 16:54:10 +0000 (17:54 +0100)]
c++: Add self reference to define_aggregate created aggregates [PR123984]
We weren't adding the DECL_SELF_REFERENCE_P TYPE_DECL to TYPE_FIELDS of
eval_define_aggregate created aggregates, which resulted in ICE in
accessible_base_p which relies on DECL_SELF_REFERENCE_P TYPE_DECL to be
present in base classes of other classes.
2026-02-09 Jakub Jelinek <jakub@redhat.com>
PR c++/123984
* reflect.cc (eval_define_aggregate): Set TYPE_BEING_DEFINED on type
after pushclass, call build_self_reference, remove assertion that
TYPE_FIELDS (type) is NULL and instead set fields to
TYPE_FIELDS (type).
Pin those tests to z14. Strictly speaking those are mostly fine for
z13, too. However, vectors with 32-bit float elements are only natively
supported since z14.
gcc:
PR other/123841
PR target/123926
* acinclude.m4 (gcc_GAS_FLAGS): Handle non-Darwin/Solaris as cases
alike on x86 and SPARC.
* configure: Regenerate.
[PR123796, LRA]: Propagate pointer flag from the equivalence target
Some targets can use pointer (frame related) flag to generate the
correct code and improve the code. Substitution of equivalence in an
insn and reloading it resulted in loosing pointer flag of the original
equivalence target in the reload register. The patch solves this
problem by using set of equivalences whose original targets have the
pointer flags and propagating this flag to equivalence copies and
reload registers.
gcc/ChangeLog:
PR rtl-optimization/123796
* lra-int.h (lra_pointer_equiv_set_add): Add prototype.
(lra_pointer_equiv_set_in, lra_finish_equiv): Ditto.
* lra.cc (lra_emit_move): Set up pointer flag of the destination
if necessary.
(lra): Call lra_finish_equiv.
* lra-constraints.cc: Include hash-set.h.
(pointer_equiv_set, lra_pointer_equiv_set_add): New.
(lra_pointer_equiv_set_in, lra_finish_equiv): New.
(get_equiv_with_elimination): Propagate pointer flag by adding to
pointer_equiv_set.
(process_addr_reg, curr_insn_transform): Ditto.
Richard Biener [Fri, 6 Feb 2026 14:47:08 +0000 (15:47 +0100)]
tree-optimization/123225 - require iteration estimate for uncounted loops
The following makes uncounted loops not profitable to vectorize
unless there's an estimate on the number of iterations, either
from array sizes, overflow, or PGO, that indicates proftiability.
Or trivial profitability, but that's impossible to reach - Tamars
pending patch might change this in some cases.
I have verified that with PGO we do vectorize the testcase in the PR.
PR tree-optimization/123225
* tree-vect-loop.cc (vect_analyze_loop_costing): For uncounted
loops reject not trivially profitable loops that have no
estimate on the number of scalar iterations.
* gcc.dg/vect/costmodel/x86_64/costmodel-pr123225.c: New testcase.
Richard Biener [Mon, 9 Feb 2026 12:13:30 +0000 (13:13 +0100)]
Silence diagnostics on gcc.dg/torture/pr117567.c
The testcase now is diagnosed on s390x which has upped completely
peel times limits. It's clearly doing a bogus access at e[-63],
but it's a compile-time only test, so silence diagnostics.
Richard Biener [Mon, 9 Feb 2026 09:53:01 +0000 (10:53 +0100)]
tree-optimization/124034 - remove early-break special-casing of inductions
After recent improvements to how we deal with early-break requirements
of induction variable updates we no longer need to force induction
latch defs relevant. This in turn makes only-live defs visible to
SLP discovery, resolving the miscompilation in this PR.
PR tree-optimization/124034
* tree-vect-stmts.cc (process_use): Never force induction
latch defs relevant when doing early break vectorization.
* gcc.dg/vect/vect-early-break_142-pr124034.c: New testcase.
Martin Jambor [Mon, 9 Feb 2026 09:31:10 +0000 (10:31 +0100)]
tree-sra: Do not propagate bit-field accesses across assignments (PR 117217)
On master at least, this is a bug which no longer reproduces with the
provided test-cases because after r15-5747-gfd62fdc5e1b3c4:(Jakub
Jelinek: c++: Small initial fixes for zeroing of padding bits
[PR117256]), the input to SRA looks very different and SRA does not do
anything.
However, before that commit, SRA sees the following input and if it
encountered something similar now, it could still misbehave in the
same way:
D.2908.i = 0;
D.2908.b = 0;
e ={v} {CLOBBER(bob)};
e.b = MEM[(const struct B &)&D.2908];
D.2908 ={v} {CLOBBER(eos)};
(Where the "e" in "e.b" is actually a MEM_REF of the union type into
&e so that is why the "data" field is missing.)
Field D.2908.b is a SRA candidate of boolean type and has size 1 bit
because its decl has size 1 bit even though its type has size 8 bits.
The SRA access representing the store to D.2908.b is then propagated
across the assignment to e and in the process
build_user_friendly_ref_for_offset tries to find a nice expression for
it to possibly use in warnings. It finds types_compatible_p
e.data.a.b which however has size 8 bits and so the verifier screams
when it discovers the discrepancy from the copied-over size of 1 bit.
This patch avoids the situation by refusing to propagate
non-byte-sized accesses across assignments.
gcc/ChangeLog:
2026-02-06 Martin Jambor <mjambor@suse.cz>
PR tree-optimization/117217
* tree-sra.cc (propagate_subaccesses_from_rhs): Do not propagate
bit-field children.
(propagate_subaccesses_from_lhs): Likewise.
gcc/testsuite/ChangeLog:
2026-02-06 Martin Jambor <mjambor@suse.cz>
PR tree-optimization/117217
* g++.dg/torture/pr117217-1.C: New test.
* g++.dg/torture/pr117217-2.C: Likewise.
Jakub Jelinek [Mon, 9 Feb 2026 08:06:47 +0000 (09:06 +0100)]
c++: Fix up diagnostics of wrong constexpr bodies in C++11 in templates [PR123889]
We emit weird diagnostics on the following testcase in C++11.
If it is not a template, maybe_save_constexpr_fundef calls first
if (!is_valid_constexpr_fn (fun, complain))
return;
(which doesn't fail) and then
tree massaged = massage_constexpr_body (fun, DECL_SAVED_TREE (fun));
if (massaged == NULL_TREE || massaged == error_mark_node)
{
if (!DECL_CONSTRUCTOR_P (fun) && complain)
error ("body of %<constexpr%> function %qD not a return-statement",
fun);
return;
}
which diagnoses it and if even that would succeed, go on with
bool potential = potential_rvalue_constant_expression (massaged);
if (!potential && complain)
require_potential_rvalue_constant_expression_fncheck (massaged);
In templates, maybe_save_constexpr_fundef returns early:
if (processing_template_decl
|| cp_function_chain->invalid_constexpr
|| (DECL_CLONED_FUNCTION_P (fun) && !DECL_DELETING_DESTRUCTOR_P (fun)))
return;
and then it is called again during instantiation.
But in that case DECL_GENERATED_P (fun) is true and so we silently return
on errors without diagnosing them:
bool complain = !DECL_GENERATED_P (fun) && !implicit;
Now, when we actually try to constexpr evaluate those (if at all), we
emit an error and then
'constexpr ...' is not usable as a 'constexpr' function because:
message and then explain_invalid_constexpr_fn tries to diagnose
the errors by calling is_valid_constexpr_fn (fun, true) and
require_potential_rvalue_constant_expression (massaged). So it diagnoses
those 2 cases, but misses the one where massaged was NULL or error_mark_node
for a non-constructor, so after the because: there is no reason emitted.
The following patch diagnoses even that.
2026-02-09 Jakub Jelinek <jakub@redhat.com>
PR c++/123889
* constexpr.cc (explain_invalid_constexpr_fn): Diagnose
NULL or error_mark_node massaged on non-constructor.
Jeff Law [Sun, 8 Feb 2026 15:23:07 +0000 (08:23 -0700)]
[PR target/123911][RISC-V] Fix infinite recursion in riscv_legitimize_move
I kept hoping I'd see a better solution, perhaps one where chunks of this
routine just go away, but that hasn't materialized. So...
This patch avoids infinite recursion through riscv_legitimize_move.
Essentially we end up calling it recursively with arguments that are a nop-move
and those particular arguments trigger infinite recursion.
So this patch just recognizes and elides the nop move. Bootstrapped on
riscv64-linux-gnu and regression tested on riscv{32,64}-elf with no
regressions. Pushing to the trunk.
This is a regression present on the mainline and 15 branch: the compiler
gives a bogus "potentially unsynchronized barrier" when the condition of
an entry barrier requires the creation of a controlled temporary, because
it comes with a transient scope that fools the test on scopes done in the
Is_Global_Entity procedure.
gcc/ada/
PR ada/124025
* exp_ch9.adb (Expand_Entry_Barrier.Is_Global_Entity): Use
Scope_Within_Or_Same to test whether the object is local.
gcc/testsuite/
* gnat.dg/protected_type1.adb: New test.
Eric Botcazou [Sun, 8 Feb 2026 23:14:49 +0000 (00:14 +0100)]
Ada: Fix too small component size for fixed-point array incorrectly accepted
This plugs a loophole in the validation of component size aspects/clauses
specified for array types, by copying what is done for record types.
gcc/ada/
PR ada/121576
* freeze.adb (Freeze_Array_Type): When the component size is
specified, check that it is valid when the component type is
either a fixed-point type or a bit-packed array type.
gcc/testsuite/
* gnat.dg/specs/component_size1.ads: New test.
Harald Anlauf [Sun, 8 Feb 2026 20:00:49 +0000 (21:00 +0100)]
Fortran: fix string length for array constructors with type-spec [PR85547]
PR fortran/85547
gcc/fortran/ChangeLog:
* decl.cc (gfc_match_volatile): Fix frontend memleak.
(gfc_match_asynchronous): Likewise.
* dump-parse-tree.cc (show_expr): Show type-spec for character
array constructor when given.
* simplify.cc (gfc_simplify_len): Simplify LEN() when type-spec
is provided for character array constructor.
* trans-intrinsic.cc (gfc_conv_intrinsic_len): Likewise.
Iain Buclaw [Sun, 8 Feb 2026 19:50:39 +0000 (20:50 +0100)]
d: Add convenient overload for build_libcall
Most generated calls to build_libcall don't require any special
conversions from the generic type returned by the library. Add an
overload that calls the library function without doing any nop casts.
gcc/d/ChangeLog:
* d-tree.h (build_libcall): New declaration.
* runtime.cc (build_libcall_1): New function.
(build_libcall): New overload.
* d-codegen.cc (build_assert_call): Call build_libcall without Type
argument.
(build_array_bounds_call): Likewise.
(build_bounds_index_condition): Likewise.
(build_bounds_slice_condition): Likewise.
(build_closure): Likewise.
* expr.cc (ExprVisitor::visit): Likewise.
* toir.cc (IRVisitor::visit): Likewise.
Iain Buclaw [Sun, 8 Feb 2026 17:31:50 +0000 (18:31 +0100)]
d: Fix error when passing assert(0) as argument [PR123995]
Library routines that either throw or halt execution already have the
call flag ECF_NORETURN. Make their internal type `noreturn' as well, so
that they can be "passed" to functions accepting noreturn arguments.
testsuite: Fix ice-pr116228.C test for 32-bit targets
This test fails on 32-bit targets:
..../gcc/gcc/testsuite/g++.dg/analyzer/ice-pr116228.C:3:7: error: 'operator new' takes type 'size_t' ('unsigned int') as first parameter [-fpermissive]
Fix by using proper __SIZE_TYPE__ type.
Ensured that the test still passes with this patch. Also, reverted the
fix for r16-7383-gf3f7e7514a794f, and ensured that the test still can
expose the ICE on x86_64-pc-linux-gnu:
$ make check-gcc-c++ RUNTESTFLAGS="--target_board=unix/ analyzer.exp=ice-pr116228.C"
FAIL: g++.dg/analyzer/ice-pr116228.C -std=c++20 (internal compiler error: in get_or_create_null_ptr, at analyzer/region-model-manager.cc:257)
# of unexpected failures 6
$ make check-gcc-c++ RUNTESTFLAGS="--target_board=unix/-m32 analyzer.exp=ice-pr116228.C"
FAIL: g++.dg/analyzer/ice-pr116228.C -std=c++20 (internal compiler error: in get_or_create_null_ptr, at analyzer/region-model-manager.cc:257)
# of unexpected failures 6
gcc/testsuite/ChangeLog:
* g++.dg/analyzer/ice-pr116228.C: Use __SIZE_TYPE__ for "new"
operator declaration.
Paul Thomas [Sun, 8 Feb 2026 07:59:15 +0000 (07:59 +0000)]
Fortran: [PDT] Fix faults in fiats runtime [PR123545,PR123673,PR122949]
2026-02-08 Paul Thomas <pault@gcc.gnu.org>
gcc/fortran
PR fortran/123545
PR fortran/123673
* decl.cc (gfc_get_pdt_instance): If a pdt_type component is
allocatable or has allocatable components, mark it alloc_comp.
(gfc_match_decl_type_spec): Sometimes in compiling contained
functions, the symtree for the constructor points to the type
instead of the constructor symbol. This corrects itself later
in compilation so return MATCH_YES.
* trans-decl.cc (gfc_generate_function_code): Unconditionally
nullify allocatable components as well as applying the default
initializer.
* trans-expr.cc (gfc_trans_alloc_subarray_assign): Restrict the
freeing of the destination data to non-allocatable expressions
and, instead, add the se finalblock to the encompassing final_
block.
gcc/testsuite
PR fortran/123545
* gfortran.dg/pdt_82.f03: New test.
PR fortran/123673
* gfortran.dg/pdt_83.f03: New test.
PR fortran/122949
* gfortran.dg/pr122949.f90: New test.
Nathaniel Shead [Sat, 31 Jan 2026 10:45:39 +0000 (21:45 +1100)]
c++/modules: Fix ICE with multiple module declarations and -M [PR123738]
When only doing preprocessing, we do not call declare_module, and so we
do not check that a module has been declared multiple times. This means
we end up with multiple "primary modules" being passed to the dependency
producing logic, which asserts. Fixed by checking if we've already seen
a module declaration and complaining.
PR c++/123738
gcc/cp/ChangeLog:
* module.cc (preprocess_module): Complain for any non-imported
module declaration in a module purview.
gcc/testsuite/ChangeLog:
* g++.dg/modules/dep-5.C: New test.
Signed-off-by: Nathaniel Shead <nathanieloshead@gmail.com> Reviewed-by: Jason Merrill <jason@redhat.com>
Jonathan Yong [Sun, 8 Feb 2026 03:25:22 +0000 (03:25 +0000)]
gcc.dg/analyzer/null-deref-pr105755.c: fix llp64
Fix compile warnings with mingw-w64.
Signed-off-by: Jonathan Yong <10walls@gmail.com>
gcc/testsuite/ChangeLog:
* gcc.dg/analyzer/null-deref-pr105755.c:
(ptrdiff_t): Change from long int to __PTRDIFF_TYPE__.
(EMACS_INT): Change from long int to __UINTPTR_TYPE__.
(intmax_t): change from long int to __INTMAX_TYPE__.
Marek Polacek [Mon, 26 Jan 2026 19:51:02 +0000 (14:51 -0500)]
c++/reflection: splice parsing fixes [PR123823]
This patch fixes the problem that when cp_parser_splice_specifier sees
:]<, it always thinks it's a template-id. Consequently, this should compile
but does not:
int i;
constexpr auto r = ^^i;
bool b = [:r:] < 42;
because we think that a template argument list follows the splice.
Fixed by implementing [temp.names]/3 better: only attempt to parse
a template argument list if we saw template or typename. As an
extension, also parse a template argument list if the splice yielded
a TEMPLATE_DECL -- in that case, chances are that the user simply
forgot to specify 'template'. In that case we'll suggest adding
'template' in cp_parser_splice_expression.
We should accept the following given [temp.names]/3:
S<[:r:] < 43> s;
and we should also accept:
[:r:] < 42 > 0;
I also realized that my code to detect unparenthesized splice
expressions as template arguments is wrong. [expr.prim.splice] says that
constexpr auto i = e<[:^^h:]>;
is ill-formed, but "S<[:r:] >= 1>" is fine as per [temp.names]/6. I moved
the checking to cp_parser_template_argument while making sure that we
only complain when the splice-expression is the whole template-argument.
This patch also fixes 123640.
PR c++/123823
PR c++/123640
gcc/cp/ChangeLog:
* parser.cc (cp_parser_splice_specifier): New typename_p parameter.
Use cp_parser_nth_token_starts_template_argument_list_p instead of
checking CPP_LESS. Check for typename/template/TEMPLATE_DECL before
parsing a template-id.
(cp_parser_splice_type_specifier): Adjust the call to
cp_parser_splice_specifier.
(cp_parser_splice_expression): Don't detect unparenthesized splice
expressions here. Adjust the call to cp_parser_splice_specifier.
(cp_parser_splice_scope_specifier): Adjust the call to
cp_parser_splice_specifier.
(cp_parser_skip_entire_splice_expr): New, broken out of...
(cp_parser_splice_spec_is_nns_p): ...this.
(cp_parser_template_id): Call pop_deferring_access_checks.
(cp_parser_template_argument): Detect unparenthesized splice
expressions here.
gcc/testsuite/ChangeLog:
* g++.dg/reflect/crash6.C: Adjust expected diagnostic.
* g++.dg/reflect/expr3.C: Likewise. Test more cases.
* g++.dg/reflect/splice4.C: Adjust expected diagnostic.
* g++.dg/reflect/error12.C: New test.
* g++.dg/reflect/parse1.C: New test.
* g++.dg/reflect/parse2.C: New test.
* g++.dg/reflect/parse3.C: New test.
* g++.dg/reflect/parse4.C: New test.
* g++.dg/reflect/parse5.C: New test.
* g++.dg/reflect/parse6.C: New test.
Jeff Law [Sat, 7 Feb 2026 18:49:30 +0000 (11:49 -0700)]
Fix testsuite scan failure on loongarch64
Robin's patch to fix nonzero bits for the result of a popcount triggered a
minor testsuite scan failure for loongarch. Essentially it was expecting to
see an ANDI for a zero-extend, but after the change we get a slli with a count
0, which is used for sign extension on loongarch.
Both are likely equally performant. So this just adjusts the test to accept
both forms. Now one could argue that the result of the popcount is already
sign extended and you'd be right -- that's a separate missed optimization issue
and unrelated to this testsuite regression.
Anyway, pushing this to the trunk.
gcc/testsuite/
* gcc.dg/pr90838.c: Adjust expected output for loongarch.
Jakub Jelinek [Sat, 7 Feb 2026 17:45:13 +0000 (18:45 +0100)]
forwprop: Fix up calc_perm_vec_perm_simplify_seqs [PR123672]
Since r15-5563-g1c4d39ada we have an optimization to try to blend 2
sequences of 2xVEC_PERM_EXPR + 2x binop + 1x VEC_PERM where the first two
VEC_PERMs are permuting a single input and the last one permutes result from
those 2 binops into 2 VEC_PERM_EXPRs from 2 inputs, 2 binops and 2 final
VEC_PERMs.
On the following testcase, the intended change (i.e. after patch) is
(including DCE after it which the optimizations relies on):
a_7 = *x_6(D);
b_9 = *y_8(D);
- c_10 = VEC_PERM_EXPR <a_7, a_7, { 0, 2, 0, 2 }>;
- d_11 = VEC_PERM_EXPR <a_7, a_7, { 1, 3, 1, 3 }>;
- e_12 = VEC_PERM_EXPR <b_9, b_9, { 0, 2, 0, 2 }>;
- f_13 = VEC_PERM_EXPR <b_9, b_9, { 1, 3, 1, 3 }>;
+ c_10 = VEC_PERM_EXPR <a_7, b_9, { 0, 2, 4, 6 }>;
+ d_11 = VEC_PERM_EXPR <a_7, b_9, { 1, 3, 5, 7 }>;
_1 = c_10 + d_11;
_2 = c_10 - d_11;
g_14 = VEC_PERM_EXPR <_1, _2, { 0, 4, 1, 5 }>;
- _3 = e_12 + f_13;
- _4 = e_12 - f_13;
- h_15 = VEC_PERM_EXPR <_3, _4, { 0, 4, 1, 5 }>;
+ h_15 = VEC_PERM_EXPR <_1, _2, { 2, 6, 3, 7 }>;
*x_6(D) = g_14;
*y_8(D) = h_15;
This works by first identifying the two sequences, attempting to use vect
elem redundancies to only use at most half of the vector elements
(in this testcase a nop because 0, 4, 1, 5 perms already use only half of
the vector elts), remembering details of such sequences and later comparing
them if there are at least two (up to 8 I think) and trying to merge them.
The optimization is meant to improve SPEC x264.
Anyway, in r15-6387-geee289131 the optimization was changed to fix some
regressions but regressed this testcase, instead of the desirable
{ 0, 2, 4, 6 } and { 1, 3, 5, 7 } first 2 VEC_PERMs 15 branch and trunk
uses { 0, 2, 4, 4 } and { 1, 3, 5, 5 } and on this testcase that means
computing incorrect result.
On this testcase, it identified the two sequences (one ending with g_14
and one with h_15 with no changes (see above). The first one (it has
some code to attempt to swap them if needed, but here the first one remains
g_14) keeps using the final VEC_PERM_EXPR as is (or with whatever
simplification recognise_vec_perm_simplify_seq performed on just that to
reduce to at most half of nelts) and the second one is modified so that
it uses the other elts of the two vectors.
So, we have { 0, 4, 1, 5 } (i.e. twice first lanes and twice second lanes)
from the first sequence and look up unused lanes (third and fourth) to
transform the other { 0, 4, 1, 5 } to, and find that is { 2, 6, 3, 7 }.
So far good. But the next operation is to compute the new selectors
for the first 2 VEC_PERM_EXPRs, which are changed from single input to
two input ones. For that, the code correctly uses the VECTOR_CST elts
unmodified for the lanes used by the first sequence (in this
testcase first/second lanes), so { 0, 2, X, X } and { 1, 3, X, X }
and then need to find out what to use for the needs of the second sequence.
Here is what it does currently:
for (i = 0; i < nelts; i++)
{
bool use_seq1 = lane_assignment[i] != 2;
unsigned int l1, l2;
if (use_seq1)
{
/* Just reuse the selector indices. */
tree s1 = gimple_assign_rhs3 (seq1->v_1_stmt);
tree s2 = gimple_assign_rhs3 (seq1->v_2_stmt);
l1 = TREE_INT_CST_LOW (VECTOR_CST_ELT (s1, i));
l2 = TREE_INT_CST_LOW (VECTOR_CST_ELT (s2, i));
}
else
{
/* We moved the lanes for seq2, so we need to adjust for that. */
tree s1 = gimple_assign_rhs3 (seq2->v_1_stmt);
tree s2 = gimple_assign_rhs3 (seq2->v_2_stmt);
unsigned int j = 0;
for (; j < i; j++)
{
unsigned int sel_new;
sel_new = seq2_stmt_sel_perm[j].to_constant ();
sel_new %= nelts;
if (sel_new == i)
break;
}
/* This should not happen. Test anyway to guarantee correctness. */
if (j == i)
return false;
seq1_v_1_stmt_sel_perm.quick_push (l1 + (use_seq1 ? 0 : nelts));
seq1_v_2_stmt_sel_perm.quick_push (l2 + (use_seq1 ? 0 : nelts));
}
seq2_stmt_sel_perm is the newly computed { 2, 6, 3, 7 } selector and
seq1->v_{1,2}_stmt are def stmts of {c_10,d_11} and seq2->v_{1,2}_stmt
are def stmts of {e_12,f_13}. For i 0 and 1 it is use_seq1 and
correct, then for i 2 the loop checks first seq2_stmt_sel_perm[0],
it is 2 % 4, equal to i, so picks up VECTOR_CST_ELTS (s{1,2}, 2),
which happens to be correct in this case, for i 3 the loop loops until
seq2_stmt_sel_perm[2] which is 3 % 4, stops and picks the wrong
VECTOR_CST_ELTS (s{1,2}, 2) which has the same value as
VECTOR_CST_ELTS (s{1,2}, 0), when the correct value would be in this
case either 1 or 3 (due to the duplication).
What the loop should do for !use_seq1 is to take the lane transformations
into account, we've changed { 0, 4, 1, 5 } to { 2, 6, 3, 7 }, so instead
of using lanes 0, 0, 1, 1 we now use lanes 2, 2, 3, 3 (x / 4 is about
which input it is picked from, here + or -). So, for 2 which got remapped
from 0 we want to use 0 and for 3 which got remapped from 1 we want to use
1.
The function uses an auto_vec lane_assignment with values 0 (unused lane,
so far or altogether), 1 (used by first sequence) and 2 (used by second
sequence). When we store in there 2, we know exactly which lane we are
remapping to which lane, so instead of computing it again the following
patch stores there 2 + l_orig, such that value >= 2 means second lane
and lane_assignment[i] - 2 in that case is the lane that got remapped to i.
And then the last loop doesn't need to recompute anything and can just use
the remembered transformation.
The rest of the changes (hunks 1-5 and 7) are just random small fixes I've
noticed while trying to understand the code. The real fix is
- lane_assignment[lane] = 2;
+ lane_assignment[lane] = 2 + l_orig;
and
- bool use_seq1 = lane_assignment[i] != 2;
+ bool use_seq1 = lane_assignment[i] < 2;
and the rest of the last hunk. Also, the last loop was kind of assuming
VEC_PERM_EXPR canonicalization happened and for single input perm the
selector elts are never >= nelts, I've added %= nelts just to be sure.
2026-02-07 Jakub Jelinek <jakub@redhat.com>
PR tree-optimization/123672
* tree-ssa-forwprop.cc (recognise_vec_perm_simplify_seq): Use std::swap
instead of fetching gimple_assign_rhs{1,2} again. Change type of lanes
vector from auto_vec<unsigned int> to auto_vec<bool> and store true
instead of 1 into it. Fix comment typo and formatting fix.
(can_blend_vec_perm_simplify_seqs_p): Put end of comment on the same
line as the last sentence in it.
(calc_perm_vec_perm_simplify_seqs): Change lane_assignment type from
auto_vec<int> to auto_vec<unsigned> and store 2 + l_orig into it
instead of true. Fix comment typo and formatting fix. Set use_seq1
to line_assignment[i] < 2 instead of line_assignment[i] != 2. Replace
bogus computation of index for !use_seq with using
line_assignment[i] - 2. Set l1 to l1 % nelts and similarly for l2.
David Malcolm [Sat, 7 Feb 2026 15:21:00 +0000 (10:21 -0500)]
analyzer: fix ICE on operator new with discarded result [PR116228]
gcc/analyzer/ChangeLog:
PR analyzer/116228
* kf-lang-cp.cc (kf_operator_new::impl_call_post): Don't try to
add a constraint if the return value is discarded.
gcc/testsuite/ChangeLog:
PR analyzer/116228
* g++.dg/analyzer/ice-pr116228.C: New test.
Signed-off-by: David Malcolm <dmalcolm@redhat.com>
Jakub Jelinek [Sat, 7 Feb 2026 10:07:28 +0000 (11:07 +0100)]
c++: Handle SPLICE_SCOPE in cp_walk_subtrees [PR123659]
SPLICE_SCOPE is a TYPE_P, but didn't have its SPLICE_SCOPE_EXPR
walked by cp_walk_tree, so the following testcase has been rejected
because it didn't find a pack in it.
SPLICE_EXPR is fine, as it is tcc_expression and walk_tree by default
walks all the tcc_exception operands for unknown trees.
Jakub Jelinek [Sat, 7 Feb 2026 10:06:35 +0000 (11:06 +0100)]
c++: Fix error recovery of invalid splice during tsubst_splice_expr [PR123752]
splice can return error_mark_node, e.g. if the evaluation of the
constant expression throws without being caught, and the error_mark_node
later on causes ICEs in various asserts.
The following patch fixes it by returning early if error_mark_node is
returned.
2026-02-07 Jakub Jelinek <jakub@redhat.com>
PR c++/123752
* pt.cc (tsubst_splice_expr): Return error_mark_node if
splice returned it.
The following reverts part of the changes done by r16-869-ge3d3d6d7d2c8ab
which AFAICS was never posted on the mailing list. The hunk reverted
adds extra costs for vector construction of AVX or AVX512 vectors
because Honza thought we're only adding 1 conversion for all constructs,
but in fact we're costing each individual unique scalar source used.
Noticed when investigating PR120234, but this does not affect it
since there it's all SSE sized operations.
Still this is a regression, though reading r16-869-ge3d3d6d7d2c8ab
commit message indicating "correct numbers regress benchmarks" might
make this somewhat dangerous. Still r16-531-g37e61c793c1b22 already
made the constructor costs much more expensive for integers, so
this might compensate.
* config/i386/i386.cc (ix86_vector_costs::add_stmt_cost):
Remove double and triple accounting of GPR -> XMM moves
in construction of AVX and AVX512 vectors.
During cse1, in insn 12 pseudo 120 is substituted with hard register 33
rendering the resulting insn trivial which is why the insn gets removed
afterwards. Since hard register 33 has a use after insn 12, the
register is live before and after insn 10. This leaves us with the
non-trivial problem, during LRA, to also assign hard register 33 to
pseudo 124 which is coming from the constraint of insn 10. Since hard
registers are not tracked, except for liveness, this cannot be solved by
reloads which is why we end up with an error. Therefore, treat single
register constraints as clobbers of the respective hard registers.
For the sake of symmetry this should also be done for constraints
associated a single register class. However, since we are in stage 4,
there is no open PR, and I haven't done any extensive testing for single
register classes, I'm skipping this for the moment. Once we are back in
stage 1, something along the lines could be added:
else
{
enum reg_class cl
= reg_class_for_constraint (lookup_constraint (p));
if (cl == NO_REGS)
continue;
machine_mode mode = recog_data.operand_mode[nop];
int regno = ira_class_singleton[cl][mode];
if (regno >= 0)
invalidate_reg (gen_rtx_REG (mode, regno));
}
gcc/ChangeLog:
* cse.cc (invalidate_from_sets_and_clobbers): Consider any hard
register referred to by any single register constraint
potentially being clobbered.
Roger Sayle [Sat, 7 Feb 2026 08:04:40 +0000 (08:04 +0000)]
PR tree-optimization/123958: FMA vs pow(x,2.0) [vs errno]
This is my proposed solution to PR123958 (and PR124002) which is a
regression exposed by my recent change to avoid expanding pow(x,2.0)
to x*x with -fmath-errno (the default) when we can't guarantee that
errno shouldn't be updated. The problem is that the logic to convert
pow(x,2.0) was also duplicated (but unused) in tree-ssa-math-opts
where it's intended to perform this conversion in order to expose
fused-multiply-add instructions when supported by the target. The
issue is that this "vestigial" code has bit-rotten over the years,
and incorrectly updates vdefs when changing vops, tiggering an ICE.
My pragmatic solution to this is to simply delete the problematic
code; the decision of whether pow(x,2.0) should be expanded is left
to the earlier pow_expand pass (which is what it's designed for), and
the later FMA pass can make use of any resulting FP multiplications.
Not only does this avoid the PHI related ICE, but also fixes the
original PR (on updating errno) on targets with FMA, e.g. aarch64
and recent x86_64 architectures (such as -march=znver3).
2026-02-07 Roger Sayle <roger@nextmovesoftware.com>
gcc/ChangeLog
PR middle-end/123826
PR tree-optimization/123958
PR c++/124002
* tree-ssa-math-opts.cc (math_opts_dom_walker::after_dom_children):
Delete code that (mis)handled conversion of pow(x,2.0) to x*x.
gcc/testsuite/ChangeLog
PR middle-end/123826
PR tree-optimization/123958
PR c++/124002
* g++.target/i386/pr124002.C: New test case.
* gcc.target/i386/pr123958.c: Likewise.
* gcc.dg/errno-4.c: Likewise.
Roger Sayle [Sat, 7 Feb 2026 07:50:41 +0000 (07:50 +0000)]
PR rtl-optimization/123833: Use of insn attributes in insn_costs corrupts recog_data.
Thanks again to Jeff Law and Andrew Pinski. Here's a revised patch that
addresses the true underlying cause of PR 128333. recog.cc's cancel_changes
was not correctly updating the recog_data cache, which leads to strange
(incorrect) behavior in fwprop and ifcvt.
2026-02-07 Roger Sayle <roger@nextmovesoftware.com>
Andrew Pinski <andrew.pinski@oss.qualcomm.com>
Jeff Law <jeffrey.law@oss.qualcomm.com>
gcc/ChangeLog
PR rtl-optimization/123833
* recog.cc (cancel_changes): Update the recog_data cache if it
holds the instruction being changed.
gcc/testsuite
PR rtl-optimization/123833
* gcc.target/mips/pr123833.c: New test case.
Martin Jambor [Fri, 6 Feb 2026 21:49:43 +0000 (22:49 +0100)]
ipa-cp: Fix assert triggering with -fno-toplevel-reorder (PR 106260)
with -fno-toplevel-reorder (and -fwhole-program), there apparently can
be local functions without any callers. This is something that IPA-CP
does not like because its propagation verifier checks that local
functions do not end up with TOP in their lattices. Therefore there
is an assert checking that all call-less unreachable functions have
been removed, which tigers in PR 106260 with these two options.
This patch detects the situation and marks the lattices as variable,
thus avoiding both the assert trigger and the verification failure.
gcc/ChangeLog:
2022-07-13 Martin Jambor <mjambor@suse.cz>
PR ipa/106260
* ipa-cp.cc (initialize_node_lattices): Replace assert that there are
callers with handling that situation when -fno-toplevel_reorder.
1. The optimization for avoiding indirect calls while using
declarations like:
proc(string)int puts = nest C "_libga68_posixputs";
has been completed.
2. Algol 68 procedures getting strings as arguments can now
wrap corresponding C functions. Note this does not include
procedures yielding strings as for now.
3. Wrappers are now built for all formal holes having proc mode. This
allows for a more robust implementation.
Signed-off-by: Jose E. Marchesi <jemarch@gnu.org>
gcc/algol68/ChangeLog
* Make-lang.in (ALGOL68_OBJS): Add algol68/a68-low-holes.o.
* a68.h: Update prototypes.
* a68-types.h (struct TAG_T): New field nest_proc.
(NEST_PROC): Define.
* a68-parser.cc (a68_new_tag): Initialize NEST_PROC.
* a68-parser-extract.cc (extract_identities): Use NEST_PROC
instead of IN_PROC for taxes for defining-identifiers in identity
declarations of proc modes with formal holes as actual parameters.
* a68-moids-misc.cc (a68_is_c_mode): Modified to allow strings as
direct parameters.
* a68-low.cc (a68_make_proc_formal_hole_decl): Remove.
* a68-low-units.cc (a68_lower_identifier): Improve commentary.
(a68_lower_formal_hole): Factorize.
* a68-low-holes.cc: New file.
* a68-low-decls.cc (a68_lower_identity_declaration): Optimize
identity declarations of proc mode with formal holes as actual
parameters.
* a68-exports.cc (a68_add_identifier_to_moif): Honor NEST_PROC.
* ga68.texi (Communicating with C): Strings can now be passed as
parameters in formal holes.
gcc/testsuite/ChangeLog
* algol68/compile/error-nest-4.a68: Strings can now be passed as
arguments in formal holes.
build: Only use gas_flag/gnu_ld_flag internally [PR123841]
caused testsuite regressions on Linux/x86_64 in one configuration: if
configured without --with-gnu-as/--with-gnu-ld, taking as and ld from
PATH, the stage 1 gcc/auto-host.h differs:
gas_flag and gnu_ld_flag weren't set correctly in this case:
Without --with-gnu-ld, AC_ARG_WITH(gnu-ld) sets gnu_ld_flag to no. The
later check to determine gnu_ld_flag from $gcc_cv_ld --version isn't
even run because it is guarded by test -z "$gnu_ld_flag".
To avoid this, two things need to happen:
* The ld --version check needs to be done in the ACTION_IF_NOT case of
AC_ARG_WITH(gnu-ld), not afterwards.
* For this to work, gcc_cv_ld needs to be set at this point.
Therefore this patch does the first. In order for the second to work,
AC_ARG_WITH(gnu-ld) is moved later when gcc_cv_ld has already been set.
The same applies to gas_flag, too.
Tested on x86_64-pc-linux-gnu and sparc64-unknown-linux-gnu like so:
* Establish a baseline before my gas_flag/gnu_ld_flag patches:
gcc:
* configure.ac (gnu_ld_flag): Move $gcc_cv_ld --version check into
AC_ARG_WITH(gnu-ld).
(gcc_cv_ld): Set before gnu_ld_flag.
(gas_flag): Move $gcc_cv_ld --version check into AC_ARG_WITH(gnu-ld).
(gcc_cv_as): Set before gas_flag.
* configure: Regenerate.
Jakub Jelinek [Fri, 6 Feb 2026 19:26:01 +0000 (20:26 +0100)]
Allow TYPE_CANONICAL (TYPE_MAIN_VARIANT (t)) not to be its own TYPE_MAIN_VARIANT [PR101312]
I had to revert my r16-7102 patch
https://gcc.gnu.org/pipermail/gcc-patches/2026-January/706424.html
(first patch in
https://gcc.gnu.org/pipermail/gcc-patches/2025-December/704097.html )
in r16-7328 because it regressed the testcase added in r16-7331 for PR123882.
typedef int T;
void foo (unsigned long, T[]);
void foo (unsigned long x, T[restrict x]);
The ICE was on the array_as_string hack which used qualifiers on
ARRAY_TYPE for printing and then FE called get_aka_type and errored
that restrict is not allowed on ARRAY_TYPEs.
Anyway, guess that would be fixable with further hacks, but when looking
into that, I've noticed my approach was completely broken, my assumption
that TYPE_CANONICAL (volatile int) is int is not true, TYPE_CANONICAL
(volatile int) is itself. For volatile int[2], C/C++ pushes the cv quals
to the element type, so it is ARRAY_TYPE of volatile int, and this
modified ARRAY_TYPE is made a type variant of int[2], but its TYPE_CANONICAL
is again volatile int[2].
Furthermore, a lot of places including build_type_attribute_variant call
build_type_attribute_qual_variant like:
return build_type_attribute_qual_variant (ttype, attribute,
TYPE_QUALS (ttype));
so pass the quals of the type to it. If build_type_attribute_qual_variant
for ARRAY_TYPEs behaves differently between C/C++ (in that case it
pushes quals to the element type) and other languages, then this will
do unexpected changes, namely because the ARRAY_TYPE usually (except for
array_as_string hack) don't contain cv quals,
build_type_attribute_variant (volatile int[2], may_alias,
TYPE_QUALS (volatile int[2]))
would create int [2] with may_alias attribute for C/C++.
Now, the ICE on the testcases was in 2 spots, in get_alias_check
gcc_checking_assert and in verify_type -fchecking stuff, the assumption
was that
TYPE_MAIN_VARIANT (TYPE_CANONICAL (TYPE_MAIN_VARIANT (type)))
== TYPE_CANONICAL (TYPE_MAIN_VARIANT (type))
for any type where TYPE_CANONICAL is non-NULL. The reason why
this works e.g. for the C/C++ volatile int[2] is that the ARRAY_TYPE
is variant type of int[2], so the first TYPE_MAIN_VARIANT gets us
int[2] and its TYPE_CANONICAL is int[2] which is the main variant.
Now, if TYPE_CANONICAL (volatile int) needs to be itself (but sure with
typedef volatile int V; TYPE_CANONICAL (V) is volatile int) and I Richi
tried to change that and it broke everything, my change was wrong and
we really need
TYPE_CANONICAL (volatile int[2] __attribute__((may_alias))) to be
volatile int[2] and we create the attribute variants as distinct types,
using build_distinct_type_copy, so
TYPE_MAIN_VARIANT (volatile int[2] __attribute__((may_alias)))
is itself, then the alias/tree assumption that the
TYPE_MAIN_VARIANT (TYPE_CANONICAL (TYPE_MAIN_VARIANT (type)))
== TYPE_CANONICAL (TYPE_MAIN_VARIANT (type))
can't hold. We need one further hop, so just guarantee that
TYPE_CANONICAL (TYPE_MAIN_VARIANT (TYPE_CANONICAL (TYPE_MAIN_VARIANT (type))))
== TYPE_MAIN_VARIANT (TYPE_CANONICAL (TYPE_MAIN_VARIANT (type))).
The following patch changes get_alias_set and tree.cc to verify that
instead. For get_alias_set the checking checks more than before,
in particular that for both steps TYPE_CANONICAL is its own TYPE_CANONICAL
rather than just that !TYPE_STRUCTURAL_EQUALITY_P (i.e. TYPE_CANONICAL
is non-NULL). verify_type already checks that though.
I've tried even
typedef volatile int A[1] __attribute__((may_alias));
typedef A __attribute__((btf_type_tag ("foo"))) B;
B c;
i.e. cascading more than one type attribute on the ARRAY_TYPE and it
still works, TYPE_CANONICAL (A) will be volatile int A[1] without
attribute and TYPE_CANONICAL (B) the same.
2026-02-06 Jakub Jelinek <jakub@redhat.com>
PR c/101312
* alias.cc (get_alias_set): Allow TYPE_CANONICAL (mv) to be
not its own TYPE_MAIN_VARIANT, as long as its TYPE_MAIN_VARIANT
has TYPE_CANONICAL equal to itself.
* tree.cc (verify_type): Likewise.
* gcc.dg/pr101312-1.c: New test.
* gcc.dg/pr101312-2.c: New test.
Andrew Stubbs [Fri, 6 Feb 2026 16:09:57 +0000 (16:09 +0000)]
amdgcn: Clean up the mov insn definitions
This patch should not change anything functional; it just deletes some cruft
and converts the constraints to the new format. This is to make it easier
to edit later.
* The long-commented-out insns are now deleted.
* The vestigial support for unaligned register pairs has been removed (it
was disabled and removed elsewhere long ago).
gcc/ChangeLog:
* config/gcn/gcn-valu.md (*mov<mode>_exec_match): Delete.
(*mov<mode>_exec_match): Likewise.
(*mov<mode>): Delete unaligned register support, and convert to new
constraint syntax.
(mov<mode>_exec): Likewise.
(@mov<mode>_sgprbase): Likewise.
* config/gcn/gcn.md (*movbi): Likewise.
David Malcolm [Fri, 6 Feb 2026 15:54:52 +0000 (10:54 -0500)]
analyzer: use value_range and range_op in eval_condition [PR98447]
PR analyzer/98447 covers a false positive from -fanalyzer.
The root cause is that the analyzer's constraint-handling code
doesn't "know" that if X := Y % 64, then X < 64.
This patch adds some minimal usage of value_range and range_op to
-fanalyzer. It adds a new svalue::maybe_get_value_range vfunc, which
attempts to get a value_range for an svalue (but bails out for awkward
cases), and if value_ranges are available, uses them in eval_condition
to determine if the result is known based on range_op.
Doing so fixes the above false positive, improves a couple of other
tests in the DejaGnu testsuite, and eliminates 31 false +ves in the
analyzer integration testsuite (out of ~2200), along with a slight
speedup to the latter (albeit testing with a debug build of gcc).
A deeper integration with ranger could probably be made, but that is
clearly stage 1 material.
gcc/analyzer/ChangeLog:
PR analyzer/98447
* common.h: Include "value-range.h".
* region-model.cc: Include "value-relation.h" and "range-op.h".
(region_model::eval_condition): Try using range_op to see if we
can get a known boolean from the value_ranges of the operands.
* svalue.cc: Include "value-relation.h" and "range-op.h".
(type_can_have_value_range_p): New.
(svalue::maybe_get_value_range): New.
(constant_svalue::maybe_get_value_range): New.
(unknown_svalue::maybe_get_value_range): New.
(unaryop_svalue::maybe_get_value_range): New.
(binop_svalue::maybe_get_value_range): New.
* svalue.h (svalue::maybe_get_value_range): New vfunc decl.
(constant_svalue::maybe_get_value_range): New decl.
(unknown_svalue::maybe_get_value_range): New decl.
(unaryop_svalue::maybe_get_value_range): New decl.
(binop_svalue::maybe_get_value_range): New decl.
gcc/testsuite/ChangeLog:
PR analyzer/98447
* c-c++-common/analyzer/conditionals-pr98447-1.c: New test.
* c-c++-common/analyzer/conditionals-pr98447-2.c: New test.
* c-c++-common/analyzer/null-deref-pr108400-SoftEtherVPN-WebUi.c:
Updated for false positive being fixed for C.
* gcc.dg/analyzer/data-model-1.c: Update expected output to
reflect improved output.
Signed-off-by: David Malcolm <dmalcolm@redhat.com>
Tomasz Kamiński [Fri, 6 Feb 2026 11:03:37 +0000 (12:03 +0100)]
libstdc++: Update guards on __heterogeneous_hash_key and __heterogeneous_tree_key
The r16-7359-gae04c1afd1526a changed __heterogeneous_key to be
defined if __glibcxx_associative_heterogeneous_erasure, but missed
guards on derived __heterogeneous_hash_key and __heterogeneous_tree_key
concept.
libstdc++-v3/ChangeLog:
* include/bits/hashtable.h (std::__heterogeneous_hash_key)
[__glibcxx_associative_heterogeneous_erasure]: Changed guard.
* include/bits/stl_tree.h (std::__heterogeneous_tree_key)
[__glibcxx_associative_heterogeneous_erasure]: Likewise.
* include/bits/stl_function.h: Add comment with C++ version
for __glibcxx_associative_heterogeneous_erasure guard.
Richard Biener [Fri, 6 Feb 2026 10:03:54 +0000 (11:03 +0100)]
rtl-optimization/119982 - XFAIL part of gcc.target/i386/pr109362.c
This XFAILs the gcc.target/i386/pr109362.c testcase where we now
need an additional register for the address part of a sequence
of two atomic loads because TER no longer applies after we now
hoist the address computation out of a loop. In the PR I noted
how RTL propagation could handle this. In the end this restores
the state we had in GCC 12 and earlier where in GCC 13 the code
generation improved by accident.
Richard Biener [Fri, 6 Feb 2026 08:26:37 +0000 (09:26 +0100)]
tree-optimization/114274 - avoid stray BLOCK refrence from CSWTCH vars
The following removes the location from CSWTCH variables which are
DECL_IGNORED_P and have no DECL_CONTEXT. The location is currently
taken from the gswitch statement and thus includes a BLOCK reference
which can eventually be elided and GCd, causing later ICEs when
ICF decides to merge the variable with some other.
PR tree-optimization/114274
* tree-switch-conversion.cc (switch_conversion::build_one_array):
Use UNKNOWN_LOCATION for the CSWTCH decl.
Nathan Myers [Fri, 6 Feb 2026 08:56:42 +0000 (03:56 -0500)]
libstdc++: fix C++17 regression in concept __heterogeneous_key (2nd)
The commit 3f7905550483408a2c4c5096a1adc8d7e863eb12 defined a
concept __heterogeneous_key using a name not defined in C++17.
This is fixed by guarding the definition behind a name defined
in C++23 the earliest Standard that uses the definition.
Jakub Jelinek [Fri, 6 Feb 2026 10:27:52 +0000 (11:27 +0100)]
tree: Fix up build_function_type for (...) fntypes [PR123977]
The following testcase ICEs in -std=c++26 mode since my r16-4338 C++26
va_start changes.
The problem is that if we have anything non-canonical in a function
type with (...) in C++26 (or C23/C2Y) mode, in this case the R typedef
on return type rather than void, then we try to build TYPE_CANONICAL
for that, but weren't passing in the no_named_args_stdarg_p, so
a type with TYPE_NO_NAMED_ARGS_STDARG_P flag set got TYPE_CANONICAL
with TYPE_NO_NAMED_ARGS_STDARG_P flag cleared and comptypes then
didn't like that as those aren't really compatible types
(...) vs. the C89-ish () which even C++ uses for some type-generic
etc. builtins.
2026-02-05 Jakub Jelinek <jakub@redhat.com>
PR c++/123977
* tree.cc (build_function_type): Pass no_named_args_stdarg_p
as last argument to recursive call.
Jonathan Wakely [Tue, 9 Dec 2025 21:02:56 +0000 (21:02 +0000)]
libstdc++: Prevent std::stacktrace from using atomics on arm-eabi [PR120567]
The conftest.cc in GLIBCXX_ENABLE_BACKTRACE checks if calls to
__atomic_load and __atomic_store result in libatomic calls. For arm-eabi
those expand to normal loads with a call to __sync_synchronize to ensure
correct ordering. That means the generated assembly does not match the
grep pattern "__atomic_" and so configure incorrectly assumes we can use
atomics in libbacktrace.
The fix is to grep for "__atomic_|__sync_" instead of just "__atomic_".
As explained in the bug comments, the similar grep for "__atomic_" in
the GLIBCXX_ENABLE_ATOMIC_BUILTINS macro doesn't need the same change.
That conftest.cc program does emit a call to a libatomic function that
matches the grep pattern "__atomic_" so the test gives the right answer
for arm-eabi.
libstdc++-v3/ChangeLog:
PR libstdc++/120567
* acinclude.m4 (GLIBCXX_ENABLE_BACKTRACE): Include "__sync_" in
grep command to check for extern calls to libatomic.
* configure: Regenerate.
Reviewed-by: Tomasz Kamiński <tkaminsk@redhat.com>
Jonathan Wakely [Thu, 5 Feb 2026 16:52:46 +0000 (16:52 +0000)]
testsuite: Fix pr61053.c testsuite failure on mingw
This test expects an error for x32 where long has smaller alignment than
long long and double, but the same is also true for *-*-mingw* targets.
Add that triplet to the target selectors for the dg-error directives.
gcc/testsuite/ChangeLog:
* gcc.dg/pr61053.c: Add *-*-mingw* to the dg-error directives
that currently only match x32.
Jonathan Wakely [Wed, 7 Jan 2026 14:29:44 +0000 (14:29 +0000)]
libstdc++: Allow new-abi-baseline target to overwrite existing file
There doesn't seem to be much benefit to writing the symbols to
baseline_symbols.txt.new when an existing file is already present. It
just adds a manual step for maintainers to move the .txt.new file to
replace the .txt one. Overwriting the file directly allows you to use
git diff to see what changed immediately, and you can easly use git
commands to revert to the original file too.
David Malcolm [Thu, 5 Feb 2026 23:36:32 +0000 (18:36 -0500)]
value-range: update comments
One of the difficulties I ran into when familiarizing myself with
value-range.{h,cc} is that the comments and classes refer to
representations of "ranges", but the implementation has grown beyond
mere ranges of values (such as with bitmasks and NaN-tracking).
Arguably "range" could refer to the mathematical definition: the set
of possible outputs of a function, but I find it much clearer to think
of these classes as efficient representations of subsets of possible
values of a type.
This patch updates various leading comments in a way that clarifies
the intent of these classes (for me, at least).
gcc/ChangeLog:
* value-range.cc (irange_bitmask::irange_bitmask): Fix typo in
comment.
* value-range.h (class vrange): Update leading comment to refer
to "subsets" rather than "ranges". Allude to the available
subclasses. Warn that the classes can be over-approximations and
thus can introduce imprecision.
(class irange_bitmask): Updating leading comment to refer to
knowledge about a "value", rather than a "range". Reword
description of MASK and VALUE to clarify implementation, and
add an example.
(class irange): Update leading comment to refer to a
"subset of possible values" rather than a "range", and
that subclasses have responsibility for storage.
(class nan_state): Rewrite leading comment.
(class frange final): Update leading comment to refer to
subsets of possible values, rather than ranges, and to
consistently use "Nan" when capitalizing.
Signed-off-by: David Malcolm <dmalcolm@redhat.com>
Robert Dubner [Thu, 5 Feb 2026 15:45:40 +0000 (10:45 -0500)]
cobol: Use _perform_line_pairs instead of injecting encoded label names.
The gcobol front end has been communicating with GDB-COBOL by encoding
information into labels that are injected into the assembly language
with ASM_EXPR nodes. That behavior is, at best, questionable.
These changes replace the "proccall" and "procret" types of those labels
in favor of a static _perform_line_pairs table that contains the same
information and is accessible by GDB-COBOL by virtue of its known name.
That table allows GDB-COBOL to "NEXT over COBOL PERFORM" statements in a
way that is familiar to users who have used "NEXT over function call".
Eventually that information should find its way into the .debug_info
section, but at the present time I don't know how to do that on either
the compiler or debugger sides.
Most of these changes involve eliminating gg_insert_into_assembler calls
and replacing them with the perform_is_armed/perform_line_pairs logic.
Some COBOL variable initialization changes crept in here, as well.
gcc/cobol/ChangeLog:
* genapi.cc (DEFAULT_LINE_NUMBER): Remove unused #define.
(parser_statement_begin): Implement perform_is_armed logic.
(initialize_variable_internal): Handle both real and int types in
SHOW_PARSE tracing.
(section_label): Comment a renumbered insert_nop() for gdb-cobol
logic.
(paragraph_label): Likewise.
(leave_procedure): Eliminate call to gg_insert_into_assembler().
(parser_enter_section): Renumber insert_nop().
(parser_perform): Eliminate call to gg_insert_into_assembler().
(parser_perform_times): Likewise.
(internal_perform_through): Likewise.
(internal_perform_through_times): Likewise.
(parser_leave_file): Create the static _perform_line_pairs table.
(parser_sleep): Renumber insert_nop().
(parser_division): Remove calls to initialize_the_data().
(parser_perform_start): New call to insert_nop().
(parser_perform_conditional): Likewise.
(perform_outofline_before_until): Expanded comment.
(perform_outofline_after_until): Eliminate call to
gg_insert_into_assembler().
(perform_outofline_testafter_varying): Likewise.
(perform_outofline_before_varying): Likewise.
(perform_inline_testbefore_varying): New call to insert_nop().
(create_and_call): Change a comment.
* gengen.cc (gg_create_goto_pair): Change characteristics of a
label.
* parse.y: Change how data are initialized.
* parse_ante.h (field_type_update): Likewise.
* symbols.cc (cbl_field_t::set_signable): Likewise.
(cbl_field_t::encode): Likewise.
* symbols.h (struct cbl_field_t): Likewise.
* util.cc (symbol_field_type_update): Likewise.
(cbl_field_t::encode_numeric): Likewise.
Jonathan Wakely [Tue, 3 Feb 2026 15:57:47 +0000 (15:57 +0000)]
libstdc++: Fix ambiguity caused by new std::source_location constructor
The new constructor added for Contracts support was not explicit, so
caused ambiguities when arbitrary pointers were used in contexts which
could convert to std::source_location.
We don't actually need a constructor, the contract_violation::location()
function can just set the data member directly.
libstdc++-v3/ChangeLog:
* include/std/contracts (contract_violation::location): Use
source_location default constructor and then set _M_impl.
* include/std/source_location (source_location(const void*)):
Remove constructor.
* testsuite/18_support/contracts/includes.cc: Move to...
* testsuite/18_support/contracts/srcloc.cc: ...here. Test for
ambiguity caused by new constructor.
Reviewed-by: Tomasz Kamiński <tkaminsk@redhat.com>