benwu25 [Wed, 17 Dec 2025 11:59:05 +0000 (18:59 +0700)]
c++: clear in_declarator_p before parsing a lambda [PR121443]
We should set parser->in_declarator_p to false when parsing a lambda.
In this testcase, for example, a lambda in a function declarator
could contain a constructor, which would be disallowed in
cp_parser_decl_specifier_seq since in_declarator_p was true.
Nathaniel Shead [Sat, 13 Dec 2025 22:32:50 +0000 (09:32 +1100)]
c++: Don't record lambdas in concept evaluations [PR123075]
When evaluating a concept definition in a template, any lambdas in the
definition of the concept get instantiated in the context of where the
evaluation occurred.
This causes two issues:
- Any lambdas declared later in the body of the function get the wrong
discriminator, which causes ABI divergences with Clang.
- Modules streaming gets confused, because the lambda is keyed to an
unrelated declaration. Keying the lambda to the concept also doesn't
work because we'd really want to key it to a concept instantiation
(that doesn't exist) so that merging works correctly.
I think really we just want to throw away these lambdas declarations
after evaluating the concept. They can (and will) be recreated in
importers re-evaluating the concept with the given args regardless.
This patch implements this by disabling scope recording for an
instantiation of a lambda keyed to a concept, and pushing into an
unrelated context so that the lambda's type is not mistakenly added
into the scope it was instantiated from.
PR c++/123075
gcc/cp/ChangeLog:
* constraint.cc (evaluate_concept_check): Push to an unrelated
scope, but keep the same access context.
* pt.cc (tsubst_lambda_expr): Don't record lambda scopes for
lambdas attached to a concept.
gcc/testsuite/ChangeLog:
* g++.dg/cpp2a/concepts-lambda25.C: New test.
* g++.dg/modules/lambda-13.h: New test.
* g++.dg/modules/lambda-13_a.H: New test.
* g++.dg/modules/lambda-13_b.C: New test.
Signed-off-by: Nathaniel Shead <nathanieloshead@gmail.com> Reviewed-by: Jason Merrill <jason@redhat.com> Reviewed-by: Patrick Palka <ppalka@redhat.com>
Tomasz Kamiński [Wed, 17 Dec 2025 09:32:54 +0000 (10:32 +0100)]
libstdc++: Make declaration and definition of generate_canonical consistent.
The r16-6177-g866bc8a9214b1d introduced type-constraint on _Urbg template
parameter in __glibcxx_concepts, with was inconsistent with declaration in
bits/random.h and definition in bits/random.tcc causing the missing symbol
errors in tests.
Furthermore, this made the mangled name of generate_canonical in C++20
mode different from older standard and previous versions of GCC.
libstdc++-v3/ChangeLog:
* include/bits/random.tcc (generate_canonical)
[!_GLIBCXX_USE_OLD_GENERATE_CANONICAL]: Use static_assert
instead of type-constraint on template parameter.
* testsuite/26_numerics/random/pr60037-neg.cc: Updated line
of error.
Reviewed-by: Jonathan Wakely <jwakely@redhat.com> Signed-off-by: Tomasz Kamiński <tkaminsk@redhat.com>
Tomasz Kamiński [Wed, 17 Dec 2025 09:32:54 +0000 (10:32 +0100)]
libstdc++: Fixed failing dg-error in random/pr60037-neg.cc tests.
libstdc++-v3/ChangeLog:
* include/bits/random.tcc (generate_canonical): Update
error message to match pre-existing one in random.h.
* testsuite/26_numerics/random/pr60037-neg.cc: Updated
line for error message.
Jakub Jelinek [Wed, 17 Dec 2025 08:16:46 +0000 (09:16 +0100)]
libstdc++: Fix up all_pedantic_errors.cc
On x86_64-linux I see
On x86_64-linux
FAIL: 17_intro/headers/c++1998/all_pedantic_errors.cc -std=gnu++17 (test for excess errors)
Excess errors:
/home/jakub/src/gcc/obj20/x86_64-pc-linux-gnu/libstdc++-v3/include/bits/random.tcc:3681: error: ISO C++ does not support '__int128' for 'type name' [-Wpedantic]
/home/jakub/src/gcc/obj20/x86_64-pc-linux-gnu/libstdc++-v3/include/bits/random.tcc:3698: error: ISO C++ does not support '__int128' for 'type name' [-Wpedantic]
This fixes it by adding __extension__.
2025-12-17 Jakub Jelinek <jakub@redhat.com>
* include/bits/random.tcc (std::generate_canonical): Use
__extension__ before __generate_canonical_{pow2,any} calls with
unsigned __int128 template arguments.
We have a few more template implementation files within the rust frontend
that use the hxx extension to make their content clear and highlight the
missing header guards.
* ast/rust-ast-collector.cc (TokenCollector::begin_describe_node):
Remove function.
(TokenCollector::end_describe_node): Likewise.
(TokenCollector::describe_node): Remove calls to begin/end.
* ast/rust-ast-collector.h: Specialize begin and end collect items. Add
more constructors to begin/end description.
* ast/rust-ast-dump.cc (Dump::Dump): Adapt to new configuration
options.
* ast/rust-ast-dump.h: Add new configuration options.
* rust-session-manager.cc (Session::dump_ast_pretty_internal): Use new
configuration options.
Rename the functions and split internal comments from node description.
gcc/rust/ChangeLog:
* ast/rust-ast-collector.cc (TokenCollector::comment): Use comment kind
(TokenCollector::begin_internal_comment): Rename from this...
(TokenCollector::begin_describe_node): ... to this.
(TokenCollector::end_internal_comment): Rename from this...
(TokenCollector::end_describe_node): ... to this.
(TokenCollector::internal_comment): Rename from this...
(TokenCollector::describe_node): ... to this.
(TokenCollector::visit): Change name in function calls.
(TokenCollector::visit_closure_common): Likewise.
(TokenCollector::visit_loop_common): Likewise.
* ast/rust-ast-collector.h: Adapt function prototypes, add a new
collect item kind for node description.
Benjamin Thos [Thu, 12 Dec 2024 13:51:53 +0000 (14:51 +0100)]
gccrs: Rework code to call one function when add comment
When we want to add an internal comment we know call one function that
wrap the code instead of calling two function, one at the beginning one
at the end.
gcc/rust/ChangeLog:
* ast/rust-ast-collector.cc (TokenCollector::internal_comment):
Wrapper function to add both comment.
(TokenCollector::visit): call of the wrapper function.
(TokenCollector::visit_closure_common): Same.
(TokenCollector::visit_loop_common): Same.
* ast/rust-ast-collector.h: Prototype of the wrapper function
Signed-off-by: Benjamin Thos <benjamin.thos@epita.fr>
Benjamin Thos [Tue, 22 Oct 2024 13:06:36 +0000 (13:06 +0000)]
gccrs: Add dump option to show node
Add a new dump option to show node node as
internal comment with a blacklist to ignore some
node.
gcc/rust/ChangeLog:
* ast/rust-ast-collector.cc (TokenCollector::begin_internal_comment):
Add internal comment to print node beginning.
(TokenCollector::end_internal_comment): Add internal comment to print
node end.
(TokenCollector::visit): Add the comments of the node visited.
(TokenCollector::visit_closure_common): Likewise.
(TokenCollector::visit_loop_common): Likewise.
* ast/rust-ast-collector.h: Add internal comment as a nes Kind.
* ast/rust-ast-dump.cc (Dump::Dump): add a Dump constructor to enable
internal.
* ast/rust-ast-dump.h: Add printing of internal comment in the dump
* rust-session-manager.cc (Session::enable_dump): Activate ast dump
and fill the blacklist.
(Session::handle_internal_blacklist): Parse the flag to get node to
be blacklisted.
(Session::compile_crate): Launch ast dump internal when asked.
(Session::dump_ast_pretty_internal): Call the visitor to dump
the internals.
* rust-session-manager.h (struct CompileOptions): add Interal in
Dump option enum.
Signed-off-by: Benjamin Thos <benjamin.thos@epita.fr>
Previously we aborted when querying the location on a MetaItemPathExpr,
the location should start on the path and continue over the expr but we
do not support that kind of location range yet.
gccrs: Use tl::expected in the parser to avoid error state
We made heavy use of error state within some AST node and it was the
source of multiple errors, and caused confusion with (null) pointers.
This commit removes some error state use within our parser in an attempt
to remove those error states later.
gcc/rust/ChangeLog:
* parse/rust-parse-impl.h (Parser::parse_inner_attributes): Change
return type to avoid empty/error values that may break invariants in
the AST.
(Parser::parse_inner_attribute): Likewise.
(Parser::parse_outer_attribute): Likewise.
(Parser::parse_outer_attributes): Likewise.
(Parser::parse_attribute_body): Likewise.
(Parser::parse_simple_path): Likewise.
(Parser::parse_macro_invocation): Likewise.
(Parser::parse_visibility): Likewise.
(Parser::parse_use_tree): Likewise.
(Parser::parse_delim_token_tree): Likewise.
(Parser::parse_identifier_or_keyword_token): Likewise.
(Parser::parse_token_tree): Likewise.
(Parser::parse_macro_rules_def): Likewise.
(Parser::parse_decl_macro_def): Likewise.
(Parser::parse_macro_invocation): Likewise.
(Parser::parse_macro_rule): Likewise.
(Parser::parse_macro_matcher): Likewise.
(Parser::parse_type_path_segment): Likewise.
(Parser::parse_path_expr_segment): Likewise.
(Parser::parse_type): Likewise.
(Parser::parse_type_no_bounds): Likewise.
(Parser::parse_items): Circumvent GCC 5 to 7 bug.
(is_simple_path_segment): Move to utility file.
(token_id_matches_delims): Likewise.
(is_likely_path_next): Remove unused function.
(Parser::parse_attr_input): Return a structure instead of a tuple.
* expand/rust-macro-builtins-offset-of.cc: Adapt call to expected.
* ast/rust-ast.cc (AttributeParser::parse_path_meta_item): Use empty
vector when an error is encountered.
* expand/rust-macro-builtins-include.cc: Likewise.
* parse/rust-parse.h: Update prototypes.
* parse/rust-parse-impl-proc-macro.cc: Likewise.
* ast/rust-ast.h: Remove error state from Visibility.
* ast/rust-item.h: Use private visibility instead of error.
* ast/rust-macro.h: Likewise.
* expand/rust-macro-expand.cc: Likewise.
* hir/rust-ast-lower.cc: Remove error case.
* rust-session-manager.cc: Use private visibility
* parse/rust-parse-utils.h: New file.
* parse/rust-parse-error.h: New file.
Tomasz Kamiński [Wed, 3 Dec 2025 13:06:59 +0000 (14:06 +0100)]
libstdc++: Provide conversion between atomic_ref of similar types.
This patch implements the P3860R1 (accepted as DR against C++20) and LWG4472.
The two constraints on the constructor (that T and U are similar types and
is_convertible_v<U*, T*>) are combined into a single check:
is_convertible_v<_Up(*)[1], _Tp(*)[1]>. While this check is not equivalent
for array of known bound to array of unknown bound conversions (T[N] to T[]),
this is irrelevant for atomic_ref, since instantiation with an array type is
ill-formed (due to the return type of load and other members).
The __atomic_ref_base constructor is modified to accept _Tp* instead of _Tp&.
This allows both the atomic_ref(atomic_ref<_Up> __other) and atomic_ref(_Tp& __t)
constructors to delegate to it. Furthermore, such approach does not require
dereferencing *__other._M_ptr, and thus avoid ADL-lookup for operator* and
issues related to it. The precondition check on alignment is moved specifically
to the atomic_ref(_Tp&) constructor, preventing redundant checks during atomic_ref
conversion.
A deleted atomic_ref(_Tp&&) constructor is introduced (per LWG4472).
This prevents the construction of atomic_ref<T> from atomic_ref<volatile T>
via the conversion operator.
libstdc++-v3/ChangeLog:
* include/bits/atomic_base.h
(__atomic_ref_base<const _Tp>::__atomic_ref_base): Accept
pointer instead of reference. Remove precondition check and
mark as noexcept.
(__atomic_ref_base<_Tp>::__atomic_ref_base): Accept pointer
insted of reference, and mark as noexcept.
* include/std/atomic (atomic_ref::atomic_ref(_Tp&)): Add
precondition check and take address of argument.
(atomic_ref::atomic_ref(_Tp&&)): Define as deleted.
(atomic_ref::atomic_ref(atomic_ref<_Up>)): Define.
* include/bits/shared_ptr_atomic.h (_Sp_atomic::_Atomic_count):
Pass address to __atomic_ref constructor.
* include/std/barrier (__tree_barrier_base::_M_arrive)
(__tree_barrier::arrive): Pass address to __atomic_ref constructor.
* testsuite/29_atomics/atomic_ref/ctor.cc: New test.
Reviewed-by: Jonathan Wakely <jwakely@redhat.com> Signed-off-by: Tomasz Kamiński <tkaminsk@redhat.com>
Jonathan Wakely [Wed, 10 Dec 2025 14:26:17 +0000 (14:26 +0000)]
libstdc++: Optimize compilation time for signed/unsigned integer traits
Replace the O(n) definitions using __is_one_of with constant-time
checks that look for a static member in the __is_integral_helper class
template. That class template is already specialized for every signed
and unsigned integer type, so we don't need to define any additional
specializations. We can just add a static data member that says whether
the type is a signed integer type, an unsigned integer type, or neither.
The __is_signed_integer and __is_unsigned_integer traits can then
inspect that value.
The new enum type could be extended in future to distinguish the
character types (char, wchar_t, char8_t, char16_t, and char32_t) and
bool from non-integer types, but that isn't needed for now.
libstdc++-v3/ChangeLog:
* include/std/type_traits (_Integer_kind): New enum type.
(__is_integral_helper::_S_kind): New static data member in
primary template and each explicit specialization.
(__is_signed_integer, __is_unsigned_integer): Use _S_kind
instead of O(n) disjunction with is_same.
Reviewed-by: Patrick Palka <ppalka@redhat.com> Reviewed-by: Tomasz Kamiński <tkaminsk@redhat.com>
Jonathan Wakely [Tue, 2 Dec 2025 15:26:31 +0000 (15:26 +0000)]
libstdc++: Do not optimize std::copy to memcpy for bool output [PR122907]
Copying narrow characters to a range of bool using std::copy cannot be
optimized to use std::memcpy. Assignment of an arbitrary integer to a
bool needs to convert all non-zero values to true, so is not a simple
memcpy-like or bit_cast-like operation. We currently get this wrong and
optimize it to memcpy, producing invalid bool values.
By making __memcpyable_integer<bool> false we disable memcpy
optimizations for heterogeneous std::copy and std::move calls where
either the source or destination type is bool. Copies where both types
are bool can still optimize to memcpy, because we don't check
__memcpyable_integer in that case.
This disables the memcpy optimization for bool as the source type,
which isn't actually necessary (the representation of bool in GCC is
0x00 or 0x01 and so copying bool to char is just a bit_cast). We don't
currently have a straightforward way to allow memcpy for bool to char
but disallow the inverse. This seems acceptable as using std::copy with
bool inputs and narrow character outputs is probably not common enough
for this to be an important optimization to do in the library code.
libstdc++-v3/ChangeLog:
PR libstdc++/122907
* include/bits/cpp_type_traits.h (__memcpyable_integer<bool>):
Define as false.
* testsuite/25_algorithms/copy/122907.cc: New test.
Reviewed-by: Tomasz Kamiński <tkaminsk@redhat.com> Reviewed-by: Patrick Palka <ppalka@redhat.com>
Jose E. Marchesi [Tue, 16 Dec 2025 21:50:15 +0000 (22:50 +0100)]
a68: fix modules testsuite to not include flags in test name [PR algol68/123131]
Signed-off-by: Jose E. Marchesi <jemarch@gnu.org>
gcc/testsuite/ChangeLog
PR algol68/123131
* algol68/compile/modules/compile.exp: Pass module include path
via extra_flags to algol68-dg-runtest.
* algol68/execute/modules/execute.exp: Pass module include path
via algol68_compile_args.
* lib/algol68-dg.exp (MODULES_OPTIONS): Delete.
(algol68-dg-runtest): Do not use MODULE_OPTIONS.
* lib/algol68-torture.exp (BUILT_MODULES_DIR): Delete.
(algol68-torture-execute): Do not use BUILT_MODULES_DIR.
Nathan Myers [Thu, 7 Aug 2025 02:38:44 +0000 (22:38 -0400)]
libstdc++: New generate_canonical impl (P0952, LWG2524) [PR119739]
Implement P0952R2 "A new specification for
std::generate_canonical", fixing issue LWG 2524.
It has us start over, using new entropy, if the naïve generation
of a value in [0..1) comes up equal to 1.0, which occurs too
rarely for the change to measurably affect performance, but
does affect the number of calls to the underlying random bit
generator.
The old implementation is preserved, guarded by preprocessor
macro _GLIBCXX_USE_OLD_GENERATE_CANONICAL, for use where behavior
exactly matching previous runs is required.
The fix is extended to all of C++11 to 26. The public function
dispatches to variations optimized for requested bit depth `d`,
using minimal integer sizes for exact intermediate calculations.
It is faster than the old implementation, which computed a
floating-point logarithm, and performs all intermediate
calculations on integer types. It does not allow the IEEE half-
precision type `float16_t`, as its range is not large enough to
represent intermediate integer values specified, but does allow
`bfloat16_t`.
This implementation varies from the Standard in retaining in the
output mantissa as much as possible of the entropy obtained from
the provided random bit generator, not just the leading `d` bits
of randomness as specified, and in permitting use on floating
point types beyond float, double, and long double. The macro
_GLIBCXX_GENERATE_CANONICAL_STRICT may be defined to obtain the
exact Standard behavior.
This patch also adds tests for statistical properties, and adds
new static asserts on template argument requirements where
supported. It adds tests using non-optimal RNGs that yield
values 0..999999 and 0..0x7ffffffe.
A test for the case addressed in LWG 2524 already appeared in
64351.cc. This change amounts to a different resolution for
bugzilla PR64351 and LWG 2524.
libstdc++-v3/ChangeLog:
PR libstdc++/119739
* include/bits/random.tcc: Add generate_canonical impl for C++26.
* testsuite/26_numerics/random/uniform_real_distribution/operators/64351.cc:
Adapt test for both pre- and post- C++26.
* testsuite/26_numerics/random/uniform_real_distribution/operators/gencanon.cc:
Test for float and double from 32-bit RNG, including 1.0 do-over.
Jose E. Marchesi [Tue, 16 Dec 2025 17:17:37 +0000 (18:17 +0100)]
a68: support only one definition module per prelude packet
At this point we only support having a single definition module in
each prelude packet. It is planned to change this, and also to
support local not-toplevel modules, but not in the next GCC release.
So until that gets fully implemented, it is pointless to support
parsing multiple contracted module definitions.
This commit removes this support from the parser and adjusts several
tests that were making use of it.
Signed-off-by: Jose E. Marchesi <jemarch@gnu.org>
gcc/algol68/ChangeLog
* a68-parser-bottom-up.cc (reduce_prelude_packet): Do not support
multiple module definitions per packet.
gcc/testsuite/ChangeLog
* algol68/compile/error-compile-unknown-tag-1.a68: Use a single
module per packet.
* algol68/compile/error-module-coercions-1.a68: Likewise.
* algol68/compile/error-module-ranges-1.a68: Likewise.
* algol68/compile/module-2.a68: Likewise.
* algol68/compile/module-pub-mangling-1.a68: Likewise.
* algol68/compile/module-pub-mangling-2.a68: Likewise.
* algol68/compile/module-pub-mangling-3.a68: Likewise.
* algol68/compile/module-pub-mangling-4.a68: Likewise.
* algol68/compile/module-pub-mangling-5.a68: Likewise.
* algol68/compile/module-pub-mangling-6.a68: Likewise.
* algol68/compile/warning-module-hidding-1.a68: Likewise.
David Malcolm [Tue, 16 Dec 2025 17:10:26 +0000 (12:10 -0500)]
analyzer: fix state dumps for return_event [PR122003]
In the reimplementation of supergraph (r16-6063-g0b786d961d4426) the
class return_event moved from being a subclass of superedge_event to
a subclass of checker_event, thus using checker_event::get_program_state
which returns null.
This stopped e.g. HTML state-graph output showing state at return events
in e.g. event (8) of
https://dmalcolm.fedorapeople.org/gcc/2025-12-15/state-diagram-1.c.html
Fixed by implementing return_event::get_program_state.
Patrick Palka [Tue, 16 Dec 2025 16:22:58 +0000 (11:22 -0500)]
libstdc++: Implement P2408R5 C++20 iterators as inputs to STL algos
From the paper's abstract:
Change the iterator requirements for non-Ranges algorithms. For
forward iterators and above that are constant iterators, instead of
requiring that iterators meet certain Cpp17...Iterator requirements,
require that the iterators model certain iterator concepts. This makes
iterators from several standard views usable with non-Ranges
algorithms that require forward iterators or above, such as the
parallel overloads of most algorithms.
This patch narrowly implements P2408R5 in C++23 mode and C++20 mode
(as an extension). "Narrowly" because just as in the paper, we don't
attempt to relax the requirements of mutable iterators even though it's
possible in theory. Note that the PSTL algorithm requirements have
already been relaxed in r15-3650. And we don't bother touching the
deprecated parallel mode algorithms under ./include/parallel.
The main workhorse of this paper is a new helper
__iterator_concept_or_category that replaces eligible uses of
__iterator_category and iterator_traits::iterator_category. This new
helper considers both the iterator_concept and iterator_category of the
given iterator and returns the former if it's at least as strong as the
latter. It's implemented in terms of the __promotable_iterator concept
added in r16-2588 that made std::advance etc aware of C++20 iterators.
Note that this helper doesn't check the actual C++20 iterator concepts
(which check syntactic requirements along with iterator_concept if it's
defined) and instead just checks for, and fully trusts, the
iterator_concept defined by the iterator type. This is a slight
deviation from the paper but IMHO it's consistent with the existing
trusting of iterator_category and should be good enough in practice,
though it means C++20 iterators that don't define iterator_concept will
not be recognized as such by this helper even if they otherwise model
the std::foo_iterator concept. (An undefined iterator_concept
effectively defaults to random_access_iterator_tag.)
Most of the changes made here are effectively optimizations that don't
have a semantic impact, e.g. for std::reduce. I added tests for a
couple of algorithms where these changes are observable.
The new __iterator_concept_or_category helper can probably also be used
to fix PR100070 "Standard library container iterator-pair constructors
should check C++20 iterator concepts".
As a follow-up to this patch we should either remove the Boost-style
concept checks, or relax them accordingly. It seems we're leaning
towards removing them outright; see this thread:
https://gcc.gnu.org/pipermail/libstdc++/2025-May/061568.html
As suggested by Tomasz, this patch also introduces a _GLIBCXX_ITER_MOVE
wrapper around ranges::iter_move that also converts to the iterator's
value type (and is usable before C++20 as well).
PR libstdc++/113299
libstdc++-v3/ChangeLog:
* include/bits/deque.tcc (__copy_move_a1): Constrain with
__is_any_random_access_iter instead of __is_random_access_iter.
(__copy_move_backward_a1): Likewise.
(__equal_aux1): Likewise.
* include/bits/stl_algo.h (__search_n): Use
__iter_concept_or_category instead of __iterator_category
or iterator_traits::iterator_category.
(find_end): Likewise.
(__is_permutation): Likewise.
(for_each_n): Likewise.
(unique_copy): Likewise, for constant iterators.
(sample): Likewise, for constant iterators.
* include/bits/stl_algobase.h (__copy_move_a1): Adjust
deque-based forward declaration accordingly.
(__copy_move_backward_a1): Likewise.
(__equal_aux1): Likewise.
(__lexicographical_compare_impl): Use
__iter_concept_or_category instead of __iterator_category or
iterator_traits::iterator_category.
(__equal4): Likewise.
* include/bits/stl_iterator_base_funcs.h
(__iter_concept_or_category): New.
(__is_any_random_access_iter): New.
(_GLIBCXX_ITER_MOVE): New.
* include/bits/stl_uninitialized.h (uninitialized_copy_n):
Use __iterator_concept_or_category instead of
__iterator_category for the constant iterator __first.
(__uninitialized_copy_n_pair): Likewise.
* include/bits/version.def (algorithm_iterator_requirements):
Define.
* include/bits/version.h: Regenerate.
* include/std/algorithm: Provide the FTM
__cpp_lib_algorithm_iterator_requirements.
* include/std/memory: Likewise.
* include/std/numeric: Likewise. Include
<bits/stl_iterator_base_funcs.h>.
(reduce): Use __is_any_random_access_iter instead of
__is_random_access_iter.
(transform_reduce): Likewise.
(inclusive_scan): Use _GLIBCXX_ITER_MOVE instead of std::move.
* testsuite/25_algorithms/find_end/c++20_iter.cc: New test.
* testsuite/25_algorithms/sample/c++20_iter.cc: New test.
* testsuite/25_algorithms/search_n/c++20_iter.cc: New test.
* testsuite/25_algorithms/unique_copy/c++20_iter.cc: New test.
* testsuite/26_numerics/inclusive_scan/c++20_iter.cc: New test.
Reviewed-by: Tomasz Kamiński <tkaminsk@redhat.com> Reviewed-by: Jonathan Wakely <jwakely@redhat.com>
Iain Sandoe [Sun, 14 Dec 2025 11:24:40 +0000 (11:24 +0000)]
aarch64: Make the test for available cached PCS data more robust.
When we are emitting MI thunks, it can be the case that the
target function of the thunk has already been compiled, and
considered complete, with at least part of the relevant data
freed.
The deal with this, we amend the test for the availability
of the cached PCS value to check for the presence of both the
cfun and the machine content.
Since these functions are in a hot code path, use
gcc_checking_assert().
gcc/ChangeLog:
* config/aarch64/aarch64.cc
(aarch64_function_abi): Use checking assert.
(aarch64_fndecl_abi): Test for the availability of the
machine content before trying to look up the cached PCS.
Use a checking assert.
These options are used in order to specify a mapping from module
indicants to file basenames. The compiler will base its search for
the modules on these basenames rather on the default schema of
deriving the basename from the module indicant.
Signed-off-by: Jose E. Marchesi <jemarch@gnu.org>
gcc/algol68/ChangeLog
* lang.opt (-fmodules-map): New option.
(-fmodules-map-file): Likewise.
* a68.h: Add prototype for a68_process_module_map.
* a68-imports.cc (SKIP_WHITESPACES): Define.
(PARSE_BASENAME): Likewise.
(PARSE_INDICANT): Likewise.
(a68_process_module_map): New function.
* a68-lang.cc: (a68_init): Move initialization of
A68_MODULE_FILES from there...
(a68_init_options): to here.
(a68_handle_option): Handle OPT_fmodules_map and
OPT_fmodules_map_.
* a68-parser-pragmat.cc (handle_access_in_pragmat): Normalize
module indicants to upper case.
* ga68.texi (Module search options): New section.
Jose E. Marchesi [Mon, 15 Dec 2025 13:03:01 +0000 (14:03 +0100)]
a68: introduce a68_file_size and a68_file_read
This commit introduces two new utility functions that replace some
ad-hoc infrastructure in the scanner.
Signed-off-by: Jose E. Marchesi <jemarch@gnu.org>
gcc/algol68/ChangeLog
* a68.h: Prototypes for a68_get_file_size and a68_file_read.
* a68-parser-scanner.cc (a68_file_size): New function.
(a68_file_read): Renamed from io_read.
(get_source_size): Deleted function.
(include_files): Use a68_file_size and a68_file_read.
In the expansion of cstoresi4 insn patterns, LT[U] comparisons where the
second operand is an integer constant are canonicalized to LE[U] ones with
one less than the original.
/* example */
int test0(int a) {
return a < 100;
}
unsigned int test1(unsigned int a) {
return a <= 100u;
}
void test2(int a[], int b) {
int i;
for (i = 0; i < 16; ++i)
a[i] = (a[i] <= b);
}
This patch reverts such canonicalization by adding 1 to the comparison value
and then converting it back from LE[U] to LT[U], which better matches the
output machine instructions. This patch also makes it easier to benefit
from other optimizations such as CSE, constant propagation, or loop-invariant
hoisting by XORing the result with a register that has a value of 1, rather
than subtracting 1 and then negating the sign to invert the truth of the
result.
* config/xtensa/xtensa.cc (xtensa_expand_scc_SALT):
New sub-function that emits the SALT/SALTU instructions.
(xtensa_expand_scc): Change the part related to the SALT/SALTU
instructions to a call to the above sub-function.
xtensa: Remove variables only used to pass the return of end_sequence()
As a result of the automatic replacement by commit 4dd13988c93c24ba3605f4b9cafc97515c34f2ac,
there are several code fragments that receive the return value of
end_sequence() and immediately use it as the return value of the function
itself.
It is clear that in such cases, it would be more natural to pass the return
value of end_sequence() directly to the return statement without passing it
through a variable.
Applying this patch naturally does not change any functionality.
gcc/ChangeLog:
* config/xtensa/xtensa.cc
(xtensa_expand_block_set_libcall,
xtensa_expand_block_set_unrolled_loop,
xtensa_expand_block_set_small_loop, xtensa_call_tls_desc):
Change the return statement to pass the return value of
end_sequence() directly without going through a variable, and
remove the definition of that variable.
Richard Biener [Tue, 16 Dec 2025 12:08:19 +0000 (13:08 +0100)]
testsuite/123137 - fix FAIL of g++.dg/vect/pr64410.cc on i?86
The following works around SRA not being able to decompose an
aggregate copy of std::complex because with x87 math ld/st pairs
are not bit-preserving by adding -msse -mfpmath=sse. This avoids
spurious failures of the testcase.
PR testsuite/123137
* g++.dg/vect/pr64410.cc: Add -mfpmath=sse -msse on x86.
Rainer Orth [Tue, 16 Dec 2025 12:02:04 +0000 (13:02 +0100)]
testsuite: i386: Skip gcc.target/i386/shift-gf2p8affine-2.c on Solaris with as
The gcc.target/i386/shift-gf2p8affine-2.c test FAILs on Solaris with the
native assembler:
FAIL: gcc.target/i386/shift-gf2p8affine-2.c (test for excess errors)
UNRESOLVED: gcc.target/i386/shift-gf2p8affine-2.c compilation failed to produce executable
Excess errors:
Assembler: shift-gf2p8affine-2.c
"/var/tmp//ccZMQ1Ad.s", line 30 : Illegal mnemonic
Near line: " vgf2p8affineqb $0, %zmm1, %zmm0, %zmm0"
"/var/tmp//ccZMQ1Ad.s", line 30 : Syntax error
Thus this patch only runs the test when gas is in use.
Tested on i386-pc-solaris2.11 (as and gas) and x86_64-pc-linux-gnu.
Add basic tests for memtag-stack sanitizer. Memtag stack sanitizer
uses target hooks to emit AArch64 specific MTE instructions.
gcc/testsuite:
* gcc.target/aarch64/memtag/alloca-1.c: New test.
* gcc.target/aarch64/memtag/alloca-2.c: New test.
* gcc.target/aarch64/memtag/alloca-3.c: New test.
* gcc.target/aarch64/memtag/arguments-1.c: New test.
* gcc.target/aarch64/memtag/arguments-2.c: New test.
* gcc.target/aarch64/memtag/arguments-3.c: New test.
* gcc.target/aarch64/memtag/arguments-4.c: New test.
* gcc.target/aarch64/memtag/arguments.c: New test.
* gcc.target/aarch64/memtag/basic-1.c: New test.
* gcc.target/aarch64/memtag/basic-3.c: New test.
* gcc.target/aarch64/memtag/basic-struct.c: New test.
* gcc.target/aarch64/memtag/large-array.c: New test.
* gcc.target/aarch64/memtag/local-no-escape.c: New test.
* gcc.target/aarch64/memtag/memtag.exp: New file.
* gcc.target/aarch64/memtag/no-sanitize-attribute.c: New test.
* gcc.target/aarch64/memtag/value-init.c: New test.
* gcc.target/aarch64/memtag/vararray-gimple.c: New test.
* gcc.target/aarch64/memtag/vararray.c: New test.
* gcc.target/aarch64/memtag/zero-init.c: New test.
* gcc.target/aarch64/memtag/texec-1.c: New test.
* gcc.target/aarch64/memtag/texec-2.c: New test.
* gcc.target/aarch64/memtag/texec-3.c: New test.
* gcc.target/aarch64/memtag/vla-1.c: New test.
* gcc.target/aarch64/memtag/vla-2.c: New test.
* lib/target-supports.exp (check_effective_target_aarch64_mte):
New function.
aarch64: Add support for memetag-stack sanitizer using MTE insns
MEMTAG sanitizer, which is based on the HWASAN sanitizer, will invoke
the target-specific hooks to create a random tag, add tag to memory
address, and finally tag and untag memory.
Implement the target hooks to emit MTE instructions if MEMTAG sanitizer
is in effect. Continue to use the default target hook if HWASAN is
being used. Following target hooks are implemented:
- TARGET_MEMTAG_INSERT_RANDOM_TAG
- TARGET_MEMTAG_ADD_TAG
- TARGET_MEMTAG_EXTRACT_TAG
Apart from the target-specific hooks, set the following to values
defined by the Memory Tagging Extension (MTE) in aarch64:
- TARGET_MEMTAG_TAG_BITSIZE
- TARGET_MEMTAG_GRANULE_SIZE
The next instructions were (re-)defined:
- addg/subg (used by TARGET_MEMTAG_ADD_TAG and
TARGET_MEMTAG_COMPOSE_OFFSET_TAG hooks)
- stg/st2g Used to tag/untag a memory granule.
- tag_memory A target specific instruction, it will will emit MTE
instructions to tag/untag memory of a given size.
- compose_tag A target specific instruction that computes a tagged
address as an offset from a base (tagged) address.
- gmi Used for randomizing the inserting tag.
- irg Likewise.
gcc/
* config/aarch64/aarch64.md (addg): Update pattern to use
addg/subg instructions.
(stg): Update pattern.
(st2g): New pattern.
(tag_memory): Likewise.
(compose_tag): Likewise.
(irq): Update pattern to accept xzr register.
(gmi): Likewise.
(UNSPECV_TAG_SPACE): Define.
* config/aarch64/aarch64.cc (AARCH64_MEMTAG_GRANULE_SIZE):
Define.
(AARCH64_MEMTAG_TAG_BITSIZE): Likewise.
(aarch64_override_options_internal): Error out if MTE instructions
are not available.
(aarch64_post_cfi_startproc): Emit .cfi_mte_tagged_frame.
(aarch64_can_tag_addresses): Add MEMTAG specific handling.
(aarch64_memtag_tag_bitsize): New function
(aarch64_memtag_granule_size): Likewise.
(aarch64_memtag_insert_random_tag): Likwise.
(aarch64_memtag_add_tag): Likewise.
(aarch64_memtag_extract_tag): Likewise.
(aarch64_granule16_memory_address_p): Likewise.
(aarch64_emit_stxg_insn): Likewise.
(aarch64_memtag_tag_memory_via_loop): New definition.
(aarch64_expand_tag_memory): Likewise.
(aarch64_check_memtag_ops): Likewise.
(TARGET_MEMTAG_TAG_BITSIZE): Likewise.
(TARGET_MEMTAG_GRANULE_SIZE): Likewise.
(TARGET_MEMTAG_INSERT_RANDOM_TAG): Likewise.
(TARGET_MEMTAG_ADD_TAG): Likewise.
(TARGET_MEMTAG_EXTRACT_TAG): Likewise.
* config/aarch64/aarch64-builtins.cc
(aarch64_expand_builtin_memtag): Update set tag builtin logic.
* config/aarch64/aarch64-linux.h: Pass memtag-stack sanitizer
specific options to the linker.
* config/aarch64/aarch64-protos.h
(aarch64_granule16_memory_address_p): New prototype.
(aarch64_check_memtag_ops): Likewise.
(aarch64_expand_tag_memory): Likewise.
* config/aarch64/constraints.md (Umg): New memory constraint.
(Uag): New constraint.
(Ung): Likewise.
* config/aarch64/predicates.md (aarch64_memtag_tag_offset):
Refactor it.
(aarch64_granule16_imm6): Rename from aarch64_granule16_uimm6 and
refactor it.
(aarch64_granule16_memory_operand): New constraint.
* config/aarch64/iterators.md (MTE_PP): New code iterator to be
used for mte instructions.
(stg_ops): New code attributes.
(st2g_ops): Likewise.
(mte_name): Likewise.
* config/aarch64/aarch64.opt (aarch64-tag-memory-loop-threshold):
New parameter.
* doc/invoke.texi: Update documentation.
asan: memtag-stack add support for MTE instructions
Memory tagging is used for detecting memory safety bugs. On AArch64, the
memory tagging extension (MTE) helps in reducing the overheads of memory
tagging:
- CPU: MTE instructions for efficiently tagging and untagging memory.
- Memory: New memory type, Normal Tagged Memory, added to the Arm
Architecture.
The MEMory TAGging (MEMTAG) sanitizer uses the same infrastructure as
HWASAN. MEMTAG and HWASAN are both hardware-assisted solutions, and
rely on the same sanitizer machinery in parts. So, define new
constructs that allow MEMTAG and HWASAN to share the infrastructure:
- hwassist_sanitize_p () is true when either SANITIZE_MEMTAG or
SANITIZE_HWASAN is true.
- hwassist_sanitize_stack_p () is when hwassist_sanitize_p () and
stack variables are to be sanitized.
MEMTAG and HWASAN do have differences, however, and hence, the need to
conditionalize using memtag_sanitize_p () in the relevant places. E.g.,
- Instead of generating the libcall __hwasan_tag_memory, MEMTAG needs
to invoke the target-specific hook TARGET_MEMTAG_TAG_MEMORY to tag
memory. Similar approach can be seen for handling
handle_builtin_alloca, where instead of doing the gimple
transformations, target hooks are used.
- Add a new internal function HWASAN_ALLOCA_POISON to handle
dynamically allocated stack when MEMTAG sanitizer is enabled. At
expansion, this allows to, in turn, invoke target-hooks to increment
tag, and use the generated tag to finally tag the dynamically allocated
memory.
The usual pattern:
irg x0, x0, x0
subg x0, x0, #16, #0
creates a tag in x0 and so on. For alloca, we need to apply the
generated tag to the new sp. In absense of an extract tag insn, the
implemenation in expand_HWASAN_ALLOCA_POISON resorts to invoking irg
again.
gcc/
* asan.cc (handle_builtin_stack_restore): Accommodate MEMTAG
sanitizer.
(handle_builtin_alloca): Expand differently if MEMTAG sanitizer.
(get_mem_refs_of_builtin_call): Include MEMTAG along with
HWASAN.
(memtag_sanitize_stack_p): New definition.
(memtag_sanitize_allocas_p): Likewise.
(memtag_memintrin): Likewise.
(hwassist_sanitize_p): Likewise.
(hwassist_sanitize_stack_p): Likewise.
(report_error_func): Include MEMTAG along with HWASAN.
(build_check_stmt): Likewise.
(instrument_derefs): MEMTAG too does not deal with globals yet.
(instrument_builtin_call): Include MEMTAG along with HWASAN.
(maybe_instrument_call): Likewise.
(asan_expand_mark_ifn): Likewise.
(asan_expand_check_ifn): Likewise.
(asan_expand_poison_ifn): Expand differently if MEMTAG sanitizer.
(asan_instrument): Include MEMTAG along with HWASAN.
(hwasan_emit_prologue): Expand differently if MEMTAG sanitizer.
(hwasan_emit_untag_frame): Likewise.
* asan.h (memtag_sanitize_stack_p): New declaration.
(memtag_sanitize_allocas_p): Likewise.
(hwassist_sanitize_p): Likewise.
(hwassist_sanitize_stack_p): Likewise.
(asan_sanitize_use_after_scope): Include MEMTAG along with
HWASAN.
* cfgexpand.cc (align_local_variable): Likewise.
(expand_one_stack_var_at): Likewise.
(expand_stack_vars): Likewise.
(expand_one_stack_var_1): Likewise.
(init_vars_expansion): Likewise.
(expand_used_vars): Likewise.
(pass_expand::execute): Likewise.
* gimplify.cc (asan_poison_variable): Likewise.
* internal-fn.cc (expand_HWASAN_ALLOCA_POISON): New definition.
(expand_HWASAN_ALLOCA_UNPOISON): Expand differently if MEMTAG
sanitizer.
(expand_HWASAN_MARK): Likewise.
* internal-fn.def (HWASAN_ALLOCA_POISON): Define new.
* params.opt: Document new param.
* sanopt.cc (pass_sanopt::execute): Include MEMTAG along with
HWASAN.
* gcc.cc (sanitize_spec_function): Add check for memtag-stack.
* doc/tm.texi: Regenerate.
* target.def (extract_tag): Update documentation.
(add_tag): Likewise.
(insert_random_tag): Likewise.
Add new command line option -fsanitize=memtag-stack with the following
new params:
--param memtag-instrument-alloca [0,1] (default 1) to use MTE insns
for enabling dynamic checking of stack allocas.
Along with the new SANITIZE_MEMTAG_STACK, define a SANITIZE_MEMTAG
which will be set if any kind of memtag sanitizer is in effect (e.g.,
later we may add -fsanitize=memtag-globals). Add errors to convey
that memtag sanitizer does not work with hwaddress and address
sanitizers. Also error out if memtag ISA extension is not enabled.
MEMTAG sanitizer will use the HWASAN machinery, but with a few
differences:
- The tags are always generated at runtime by the hardware, so
-fsanitize=memtag-stack enforces a --param hwasan-random-frame-tag=1
Add documentation in gcc/doc/invoke.texi.
gcc/
* builtins.def: Adjust the macro to include the new
SANTIZIE_MEMTAG_STACK.
* flag-types.h (enum sanitize_code): Add new enumerator for
SANITIZE_MEMTAG and SANITIZE_MEMTAG_STACK.
* opts.cc (finish_options): memtag-stack sanitizer conflicts with
hwaddress and address sanitizers.
(sanitizer_opts): Add new memtag-stack sanitizer.
(parse_sanitizer_options): memtag-stack sanitizer cannot recover.
* params.opt: Add new params for memtag-stack sanitizer.
* doc/invoke.texi: Update documentation.
Add a new target instruction used by hardware-assisted sanitizers on
architectures providing memory-tagging instructions. This instruction
is used to compute assign tags at a fixed offset from a tagged address
base. For example, in AArch64 case, this pattern instantiate `addg`
instruction.
Add a new target instruction. Hardware-assisted sanitizers on
architectures providing instructions to tag/untag memory can then
make use of this new instruction pattern. For example, the
memtag-stack sanitizer uses these instructions to tag and untag a
memory granule.
Jennifer Schmitz [Tue, 21 Oct 2025 07:33:00 +0000 (00:33 -0700)]
AArch64: Enable dispatch scheduling for Olympus core.
This patch enables dispatch scheduling for the NVIDIA Olympus core.
The dispatch constraints are based on the Olympus CPU Core Software
Optimization Guide
(https://docs.nvidia.com/olympus-cpu-core-software-optimization-guide-dp12531-001v0-7.pdf).
The patch was bootstrapped and tested on aarch64-linux-gnu, no regression.
OK for trunk?
Signed-off-by: Jennifer Schmitz <jschmitz@nvidia.com>
gcc/
* config/aarch64/aarch64.md: Include olympus.md.
* config/aarch64/olympus.md: New file.
* config/aarch64/tuning_models/olympus.h: Add dispatch
constraints and enable dispatch scheduling.
Richard Biener [Mon, 8 Dec 2025 09:25:21 +0000 (10:25 +0100)]
ipa/122456 - fix ICE during LTO profiledbootstrap
When we have a speculated edge but we folded the call to
__builtin_unreachable () then trying to update the cgraph ICEs
in resolve_speculation because there's no symtab node for
__builtin_unreachable (). Reject this resolving attempt similar
as to when the callees decl were NULL or it were not semantically
equivalent.
I only have a LTRANS unit as testcase.
PR ipa/122456
* cgraph.cc (cgraph_edge::resolve_speculation): Handle
a NULL symtab_node::get (callee_decl).
Andrew Pinski [Sun, 14 Dec 2025 00:23:33 +0000 (16:23 -0800)]
cleanupcfg: Reject forwarder blocks where dest is eh landing pad or a non-local dest [PR123110]
r16-5250-g88db06d7da393f901 changed which block was doing the
check on the label being a non-local dest or an eh landing pad.
Which is fine except then when we move labels we moved them to
before the label for the non-local dest/eh landing pad.
This can be fixed a few different ways.
Add back the check for the dest block or change where the other
labels are placed.
Since this case does not happen enough to care either way, I added
back the check for the dest block. This means there is no changes
from GCC 15 to now.
Bootstrapped and tested on x86_64-linux-gnu.
PR tree-optimization/123110
gcc/ChangeLog:
* tree-cfgcleanup.cc (maybe_remove_forwarder_block): Add back
check for eh landing pad or non-local dest on the dest.
gcc/testsuite/ChangeLog:
* gcc.dg/pr123110-1.c: New test.
Signed-off-by: Andrew Pinski <andrew.pinski@oss.qualcomm.com>
Andrew Pinski [Sun, 14 Dec 2025 04:48:51 +0000 (20:48 -0800)]
final_cleanup: Don't create forwarder blocks for degenerate_phis that are ifconvertable [PR123111]
So it turns out creating a forwarder block in some cases causes a regression.
The rtl ifcvt does like the case were the middle bb does not have a single predecessor.
So in some cases ifcvt does not happen any more. So the way to fix this
is not to create a forwarder block for those edges which causes out of ssa to
create a middle bb which has the constant or the copy in it.
I tried to do a simple ifcvt on the gimple level with the last phiopt but
that introduces regressions as then `v += cmp - 43;` is not optimized
and produces an extra subtraction. This is the best workaround I could come up
with until that is fixed. I filed PR 123116 for that issue.
Bootstrapped and tested on x86_64-linux-gnu.
PR tree-optimization/123111
gcc/ChangeLog:
* tree-cfg.cc (ifconvertable_edge): New function.
(make_forwarders_with_degenerate_phis): Add skip_ifcvtable argument,
check ifconvertable_edge if skip_ifcvtable is true.
* tree-cfg.h (make_forwarders_with_degenerate_phis): New argument
with default of false.
* tree-cfgcleanup.cc (execute_cleanup_cfg_post_optimizing): Update
argument to make_forwarders_with_degenerate_phis.
Signed-off-by: Andrew Pinski <andrew.pinski@oss.qualcomm.com>
Martin Jambor [Mon, 15 Dec 2025 23:44:45 +0000 (00:44 +0100)]
ipa-devirt: Add speculative direct calls based on stores to structures
This patch extends the ipa-devirt pass with the ability to add
speculative calls for indirect calls where the target was loaded from
a record_type data structure and we have seen writes of address of
only one particular function to the same offset of that record
type (including static initializers).
The idea is basically taken from Christoph Müllner's patch from 2022
(https://gcc.gnu.org/pipermail/gcc-patches/2022-November/605934.html)
but I have re-worked it so that it stores the required information in
GC memory (which I belive is necessary) and does not require an
additional pass through gimple statements of all functions because it
uses the analysis phase of ipa-cp/ipa-fnsummary (which was an approach
we agreed on with Honza).
It also performs simple verification that the collected types match
the type of the record field. We could verify that the function
determined as the likely target matches the call statement
expectations, but for that we would need to stream both types which is
something I decided not to do.
Co-authored by: Christoph Müllner <christoph.muellner@vrull.eu>
gcc/ChangeLog:
2025-11-28 Martin Jambor <mjambor@suse.cz>
PR ipa/107666
* common.opt (fspeculatively-call-stored-functions): New.
* cgraph.h (cgraph_simple_indirect_info): New fields rec_type and
fld_offset.
* ipa-prop.h (ipa_analyze_var_static_initializer): Declare.
(ipa_dump_noted_record_fnptrs): Likewise.
(ipa_debug_noted_record_fnptrs): Likewise.
(ipa_single_noted_fnptr_in_record): Likewise.
(ipa_free_noted_fnptr_calls): Likewise.
* ipa-cp.cc (ipcp_generate_summary): Call
ipa_analyze_var_static_initializer on each varbool node with a static
initializer.
* ipa-devirt.cc (struct devirt_stats): New type.
(devirt_target_ok_p): New function.
(ipa_devirt): Move statistics counters to the new structure. dump
noted function pointers stored in records. Check for edge hotness
first and for odr_types only for polymorphic edges. Moved a number of
checks to devirt_target_ok_p. Also add speculative direct calls for
non-polymorphic indirect ones when ipa_single_noted_fnptr_in_record
finds a likely target. Call ipa_free_noted_fnptr_calls.
(pass_ipa_devirt::gate): Also check the new flag.
* ipa-prop.cc (noted_fnptr_store): New type.
(struct noted_fnptr_hasher): Likewise.
(noted_fnptr_hasher::hash): New function.
(noted_fnptr_hasher::equal): Likewise.
(noted_fnptrs_in_records): New.
(is_func_ptr_from_record): New function.
(ipa_analyze_indirect_call_uses): Also simple create indirect info
structures with fnptr_loaded_from_record set.
(note_fnptr_in_record): New function.
(ipa_dump_noted_record_fnptrs): Likewise.
(ipa_debug_noted_record_fnptrs): Likewise.
(ipa_single_noted_fnptr_in_record): Likewise.
(ipa_free_noted_fnptr_calls): Likewise.
(ipa_analyze_stmt_uses): Also look for stroes of function pointers to
record structures.
(ipa_analyze_var_static_initializer): New function.
(ipa_write_indirect_edge_info): Also stream fnptr_loaded_from_record
indirec infos.
(ipa_read_indirect_edge_info): Likewise.
(ipa_prop_write_jump_functions): Also stream the contents of
noted_fnptrs_in_records.
(ipa_prop_read_section): Likewise.
* opts.cc (default_options_table): Also turn on
OPT_fspeculatively_call_stored_functions at -O2.
(common_handle_option): Turn flag_speculatively_call_stored_functions
when using profile feedback.
* doc/invoke.texi (-fspeculatively-call-stored-functions): New.
Martin Jambor [Mon, 15 Dec 2025 23:44:45 +0000 (00:44 +0100)]
cgraph: cgraph_indirect_call_info into a class hierachy
Currently, an instance of cgraph_indirect_call_info is allocated for
each indirect call and it contains fields which are only usable for
some kinds of calls. The most special are polymorphic calls
representing calls of virtual methods through an OBJ_TYPE_REF and
which need the ipa_polymorphic_context structure, among other data from
the O_T_R itself for devirtualization, which are not needed for other
types of calls.
This patch splits the class into three. A common base which is also
used for calls which we know we cannot do anything about (when the
call statement is not known or when it is a constant integer or
something like that), a (simple) type for calls of SSA_NAMEs and a
type for polymorphic calls. This means we no longer allocate memory
for members which we do not need in a particular situation. Part of
the motivation to write this is also that I have a patch adding fields
to the simple variant and this reorganization makes it doable in a
clean fashion.
The base class retains the param_index field even though it really only
is meaningful in the derived classes. This made conversion of some of
the functions operating on it easier (and I expect that vast majority
of actual instances will fall into one of the two categories anyway).
We already stream information stored in indirect information at two
places, once in call graph streaming and once in ipa-prop streaming.
I am not sure what the reason is (call graph streaming cannot do trees
so we need the ipa-prop one) but this patch preserves this.
The patch also removes a part of the comment in
ipa_make_edge_direct_to_target which said the check for member_ptr was
not necessary. We even have a test in our testsuite showing it is and
we produce wrong code without it.
gcc/ChangeLog:
2025-10-17 Martin Jambor <mjambor@suse.cz>
* cgraph.h (cgraph_node): Adjust the comment of member function
create_indirect_edge.
(enum cgraph_indirect_info_kind): New.
(cgraph_indirect_call_info): Convert into a base class.
(cgraph_simple_indirect_info): New.
(cgraph_polymorphic_indirect_info): Likewise.
(usable_polymorphic_info_p): Likewise.
(is_a_helper <cgraph_simple_indirect_info *>::test): Likewise.
(is_a_helper <cgraph_polymorphic_indirect_info *>::test): Likewise.
(cgraph_allocate_init_indirect_info): Remove declaration.
(ipa_polymorphic_call_context::ipa_polymorphic_call_context): Use the
appropriate derived type of indirect info.
* cgraph.cc (cgraph_allocate_init_indirect_info): Removed.
(cgraph_node::create_indirect_edge): Create an appropriate type of
indirect_info.
(cgraph_node::dump): Dump indirect info using its dump function.
(cgraph_indirect_call_info::dump): New function.
(cgraph_indirect_call_info::debug): Likewise.
* cgraphclones.cc (cgraph_edge::clone): Create an appropriate type of
indirect_info.
* cgraphunit.cc (analyze_functions): Use the appropriate derived type
of indirect info.
* ipa-cp.cc (initialize_node_lattices): Adjust the check for
polymorphic indirect info.
(ipa_get_indirect_edge_target_1): Use the appropriate derived types of
indirect info.
(ipcp_discover_new_direct_edges): Likewise.
* ipa-devirt.cc (ipa_devirt): Use the polymorphis derived type of
indirect info and check that it is usable.
* ipa-inline.cc (dump_inline_stats): Adjust the check for polymorphic
indirect info.
* ipa-profile.cc (ipa_profile): Likewise and check usability.
* ipa-prop.cc (ipa_print_node_jump_functions): Dump indirect info
using its dumping member function.
(ipa_note_param_call): Removed.
(ipa_analyze_indirect_call_uses): Use the appropriate derived type of
indirect info, set all fields of indirect info separately rather than
relying on ipa_note_param_call.
(ipa_analyze_virtual_call_uses): Use the polymorphis derived type of
indirect info and check that it is usable, set all fields of indirect
info separately rather than relying on ipa_note_param_call.
(ipa_analyze_call_uses): Use the appropriate derived type of indirect
info.
(ipa_make_edge_direct_to_target): Use the appropriate derived type of
indirect info. Remove wrong note that member_ptr check was not
needed. Adjust check for polymorphic call when dumping.
(try_make_edge_direct_simple_call): Use the appropriate derived type
of indirect info.
(try_make_edge_direct_virtual_call): Use the polymorphis derived type
of indirect info and check that it is usable.
(update_indirect_edges_after_inlining): Use the appropriate derived
type of indirect info. Define local variables only before their first
use.
(ipa_write_indirect_edge_info): Also stream indirect info kind. Use
the appropriate derived type of indirect info.
(ipa_read_indirect_edge_info): Check that the streamed in indirect
info kind matches rthe structure at hand. Use the appropriate derived
type of indirect info.
* ipa-utils.h (possible_polymorphic_call_targets): Use the
polymorphis derived type of indirect info. Assert it is usable.
(dump_possible_polymorphic_call_targets): Use the polymorphis
derived type of indirect info and check it is usable.
(possible_polymorphic_call_target_p): Likewise.
* ipa.cc (symbol_table::remove_unreachable_nodes): Use
usable_polymorphic_info_p.
* lto-cgraph.cc (lto_output_edge): Stream indirect info kind.
(compute_ltrans_boundary): Use usable_polymorphic_info_p.
(input_edge): Move definition of ecf_flags before its first use.
Pass true as the last parameter to create_indirect_edge. Stream
indirect info kind and create a corresponding type to hold the
information.
* trans-mem.cc (ipa_tm_insert_gettmclone_call): Use the
polymorphis derived type of indirect info.
Martin Jambor [Mon, 15 Dec 2025 23:44:44 +0000 (00:44 +0100)]
gengtype: Avoid Werror bootstrap fail when a subclass has no GTY fields
In a follow-up patch, I have created a GTYed subclass which does not
have any garbage collectible fields, just integers (a "sibling"
subclass does). This leads to gengtype outputting code like this to
gtype-desc.cc:
Eric Botcazou [Mon, 15 Dec 2025 23:23:56 +0000 (00:23 +0100)]
Ada: Fix ICE when comparing reduction expression with integer constant
This a regression present on the mainline, 15 and 14 branches: the compiler
aborts on the comparison of the result of a reduction expression, whose
prefix is an aggregate, and an integer constant, because of a type mismatch
created by the resolution of the reduction expression, which unduly forces
Integer on the expression.
gcc/ada/
PR ada/123138
* sem_attr.adb (Resolve_Attribute) <Attribute_Reduce>: Override a
universal numeric type only if the prefix is not an aggregate.
gcc/testsuite/
* gnat.dg/reduce4.adb: New test.
* gnat.dg/reduce5.adb: Likewise.
Patrick Palka [Mon, 15 Dec 2025 20:03:43 +0000 (15:03 -0500)]
c++: avoid in-place modification of TYPENAME_TYPE
Since we have a TYPENAME_TYPE cache, through which equivalent
TYPENAME_TYPEs are reused, in-place modification of a TYPENAME_TYPE is
generally unsafe. This is a latent issue noticed when attempting a
different approach to fix PR122752.
gcc/cp/ChangeLog:
* parser.cc (cp_parser_template_id): Rebuild instead of modifying
a TYPENAME_TYPE corresponding to a dependently-scoped template.
Patrick Palka [Mon, 15 Dec 2025 20:03:39 +0000 (15:03 -0500)]
c++: losslessly encode TYPENAME_TYPE tag
We currently have 7 distinct tag_types, but our TYPENAME_TYPE
representation effectively only differentiates between 4 of them at the
expense of struct_type (which gets conflated with class_type),
none_type and scope_type (which get conflated with typename_type).
struct_type / class_type conflation is mostly harmless, but it
probably affects -Wmismatched-tags. none_type / typename_type too
should be harmless. But scope_type / typename_type conflation is
problematic because scope_type indicates a type-only lookup unlike
typename_type.
This patch makes our representation of TYPENAME_TYPE encode the numeric
tag type value losslessly using the first three adjacent tree flag bits.
We already use three flag bits for the tag encoding (but inefficiently)
so no additional space is needed.
gcc/cp/ChangeLog:
* cp-tree.h (TYPENAME_TYPE_TAG_BIT_0): New.
(TYPENAME_TYPE_TAG_BIT_1): New.
(TYPENAME_TYPE_TAG_BIT_2): New.
(TYPENAME_IS_ENUM_P): Use get_typename_tag.
(TYPENAME_IS_CLASS_P): Rename to ...
(TYPENAME_IS_CLASS_OR_STRUCT_P): ... this, and use
get_typename_tag.
(TYPENAME_IS_UNION_P): Use get_typename_tag.
(TYPENAME_IS_RESOLVING_P): Use TREE_LANG_FLAG_3
instead of _2.
(get_typename_tag): New.
(set_typename_tag): New.
(tag_name): Declare.
* decl.cc (typename_info): Replace bool fields with a single
tag_types field.
(typename_hasher::equal): Adjust.
(build_typename_type): Adjust.
(tag_name): Handle none_type and scope_type.
* error.cc (dump_type) <case TYPENAME_TYPE>: Use tag_name.
* module.cc (trees_out::type_node) <case TYPENAME_TYPE>: Use
get_typename_tag.
* pt.cc (tsubst) <case TYPENAME_TYPE>: Likewise.
Patrick Palka [Mon, 15 Dec 2025 20:03:36 +0000 (15:03 -0500)]
c++: restrict TYPE_POLYMORPHIC_P to class types
Since TYPE_POLYMORPHIC_P shares the same storage as other flags for
TYPENAME_TYPE and DECLTYPE_TYPE, we should avoid accidentally using
this accessor on those tree codes. This patch restricts the accessor
to RECORD/UNION_TYPE which allows callers to conveniently guard any
uses with CLASS_TYPE_P. Otherwise with the next patch applied that
rearranges TYPENAME_TYPE flags, noexcept_override_late_checks would
not skip over a TYPENAME_TYPE base for which TYPE_POLYMORPHIC_P
nonsensically returns true, leading to an eventual ICE.
gcc/cp/ChangeLog:
* cp-tree.h (CLASSTYPE_LAMBDA_EXPR): Check CLASS_TYPE_P before
inspecting TYPE_POLYMORPHIC_P.
(TYPE_POLYMORPHIC_P): Restrict to RECORD_TYPE or UNION_TYPE.
Document its use of TREE_LANG_FLAG_2.
* parser.cc (noexcept_override_late_checks): Only
check TYPE_POLYMORPHIC_P on CLASS_TYPE_P types.
* rtti.cc (build_headof): Likewise.
(get_tinfo_ptr_dynamic): Likewise.
(build_typeid): Likewise.
Jerry DeLisle [Sun, 14 Dec 2025 21:23:36 +0000 (13:23 -0800)]
Fortran: Fix bad read involving extra input text.
The problem here involved DTIO mixed with non-DTIO
variables in list formatted reads. The previous fix to
PR105361 broke the test case here by mis-handling the
end of file conditions. It was found that the code could
be significantly reduced as well.
PR libfortran/122936
libgfortran/ChangeLog:
* io/list_read.c (finish_list_read): Remove the use of hit_eof
and free_line. Simplify the logic. Add comments to clarify.
Patrick Palka [Mon, 15 Dec 2025 19:30:53 +0000 (14:30 -0500)]
c++: nested typename type resolving to wildcard type [PR122752]
Here typename A<S>::VertexSet::size_type within the out-of-line
declaration is initially parsed at namespace scope, so the LHS
A<S>::VertexSet is treated as a dependent name and represented as a
TYPENAME_TYPE with tag_type as class_type.[1]
Once we realize we're parsing a member declarator we call
maybe_update_decl_type to reprocess the TYPENAME_TYPE relative to the
class template scope, during which make_typename_type succeeds in
resolving the lookup and returns the member typedef VertexSet (to the
TEMPLATE_TYPE_PARM S). But then the caller tsubst complains that this
result isn't a class type as per the tag_type.
This patch just relaxes tsubst to allow TYPENAME_TYPE getting resolved
to a wildcard type regardless of the tag_type. This does mean we lose
information about the tag_type during a subsequent tsubst, but that's
probably harmless (famous last words).
[1]: The tag_type should probably be scope_type. Changing this seems
to be a matter of changing cp_parser_qualifying_entity to pass
scope_type instead of class_type, but I don't feel confident about that
and it seems risky. I then got confused as to why that function passes
none_type in the !type_p case; to me it should use scope_type
unconditionally, but doing so breaks things. This approach seems safer
to backport.
PR c++/122752
gcc/cp/ChangeLog:
* pt.cc (tsubst) <case TYPENAME_TYPE>: Allow TYPENAME_TYPE
resolving to another wildcard type.
Patrick Palka [Mon, 15 Dec 2025 19:23:52 +0000 (14:23 -0500)]
c++: delay noexcept parsing for templated friends [PR122668]
The r16-5425 workaround to delay current-instantiation name lookup
within a friend's noexcept-spec is unsound because it considers the
flag cp_noexcept_operand but that indicates a noexcept-expr, not a
noexcept-spec. We don't currently have a flag for indicating a
noexcept-spec context (and I don't think we really want one).
This patch reverts that workaround and instead makes us properly
delay noexcept-spec parsing of templated friends, which should fully
address the regression since it's applicable only to ahead of time
name lookup at class template scope. Delaying noexcept-spec parsing
of non-templated friends is trickier since it means we need to defer
declaration matching of such friends until after delayed parsing rather
than immediately matching. In contrast, for templated friends we
naturally defer declaration matching until instantiation time, i.e.
well after delayed parsing.
PR c++/122668
PR c++/114764
gcc/cp/ChangeLog:
* parser.cc (cp_parser_class_specifier): Adjust after
changing the element type of unparsed_noexcepts. Pass
the class type to noexcept_override_late_checks.
(cp_parser_member_declaration): Set
CP_PARSER_FLAGS_DELAY_NOEXCEPT also for templated friends.
(noexcept_override_late_checks): Add class_type parameter.
(cp_parser_single_declaration): Set
CP_PARSER_FLAGS_DELAY_NOEXCEPT also for template friends
at class template scope.
(cp_parser_save_default_args): Push current_class_type
to unparsed_noexcepts.
* parser.h (cp_unparsed_functions_entry::noexcepts):
Change element type to cp_default_arg_entry.
* pt.cc (dependentish_scope_p): Revert r16-5425 change.
Jakub Jelinek [Mon, 15 Dec 2025 18:08:06 +0000 (19:08 +0100)]
libgomp: Avoid -Waddress warning
The function has assert (htab_find) with a comment that that is to
avoid -Wunused-function warning. The problem is that it triggers
a different warning,
../../../libgomp/plugin/build-target-indirect-htab.h:68:3: warning: the address of ‘htab_find’ will always evaluate as ‘true’
(or error depending on exact flags).
This uses (void) htab_find instead to avoid any diagnostics.
2025-12-15 Jakub Jelinek <jakub@redhat.com>
* plugin/build-target-indirect-htab.h (create_target_indirect_map):
Use (void) htab_find instead of assert (htab_find) to silence
-Werror=unused-function because the latter triggers -Werror=address.
Joseph Myers [Mon, 15 Dec 2025 17:58:20 +0000 (17:58 +0000)]
testsuite: Support plugin testing for installed compiler
Plugin tests are currently only enabled for build-tree testing.
Enable them for installed testing as well, using
-print-file-name=plugin/include to locate the installed headers in
that case.
Support is also added to contrib/test_installed for the associated
site.exp settings. Installed testing also shows up that some plugin
tests are using text-art/*.h headers that aren't currently installed,
so add those to PLUGIN_HEADERS.
Bootstrapped with no regressions for x86_64-pc-linux-gnu, and also ran
plugin tests for an installed compiler with contrib/test_installed.
contrib/
* test_installed (--enable-plugin, --with-plugincc=)
(--with-plugincflags=, --with-gmpinc=): New options.
gcc/testsuite/
* lib/plugin-support.exp (plugin-test-execute): Support installed
testing.
* g++.dg/plugin/plugin.exp, gcc.dg/plugin/plugin.exp,
obj-c++.dg/plugin/plugin.exp, objc.dg/plugin/plugin.exp: Do not
disable for installed testing.
At present we reject uncounted loops outright when doing initial loop
analysis in `vect_analyze_loop_form'.
We have the following gating condition that causes rejection of a
given loop:
if (integer_zerop (info->assumptions)
|| !info->number_of_iterations
|| chrec_contains_undetermined (info->number_of_iterations))
We can do away with this check altogether, but not without problems,
allowing many malformed loops through which ought to be rejected as
early as possible.
We observe that a common thread running through these malformed loops
is the absence of any scalar evolution between iterations.
We have therefore adjusted the analysis replacing the checks on
`niters' for a test for the presence of scalar evolution in the loop,
which can be detected via the presence of phi nodes in the loop.
The categorization of uncounted loops as
LOOP_VINFO_EARLY_BREAKS_VECT_PEELED disables prolog peeling by
default. This is due to the assumption that you have early break
exits following the IV counting main exit. For such loops, prolog
peeling is indeed problematic.
For enabling prolog peeling in uncounted loops it is sufficient, when
duplicating the loop for the prolog, to convert the prolog loop into a
counted loop, inserting a counting IV exit at the end, thus resulting
in the kind of early-break loop already supported by the compiler.
The pre-existing exits will continue to point to the exit node, while
the new exit will point to the vectorized loop, directing control flow
there once the number of iterations required for alignment are
completed.
In order to achieve this, we note that `vect_set_loop_condition'
replaces the condition in the main exit of a counted loop, all the
while inserting the prolog IV and its update statement. The design
strategy is thus:
- Have `slpeel_tree_duplicate_loop_to_edge_cfg' add a dummy main
exit to the loop in the non-exiting branch of the original "main"
exit in the loop, between the condition-containing BB and the latch
BB. For the original exit, if the exit condition is true, the
edge->dest will remain unchanged. The dummy exit will replicate
this control-flow, with the exiting branch of the if statement
initially leading to the same exit BB as the preceding exit.
- As this new basic block will contain the IV-counting exit
condition, its exit edge will be used for the control flow when
alignment is achieved and thus we mark it as the new `new_exit'.
This exit is then used in `redirect_edge_and_branch_force (new_exit,
preheader)' and its basic block passed to `vect_set_loop_condition',
wherein its condition will be replaced accordingly, correctly
completing the setting up of our prolog loop.
- In order to control this new functionality in
slpeel_tree_duplicate_loop_to_edge_cfg we are, however, required to
add a new parameter to the function. This is to be set to true when
we have an uncounted loop AND we're generating its prolog. This is
done via the `bool duplicate_main_e' parameter, defaulting to false,
allowing existing calls to the function to remain unchanged.
vect: Reject uncounted loop vectorization where alias analysis may fail
Issues with alias list pruning for uncounted loops was found to cause
as-of-yet unresolved issues in the execution of SpecV6. Disable this
while a reduced testcase is developed and a solution implemented.
Test derived from "omp_get_partition_place_nums" from libgomp "icv.c":
unsigned len = 8;
void
alias_fail (int n[8])
{
unsigned int i;
for (i = 0; i < len; i++)
*n++ = i;
}
gcc/ChangeLog:
* tree-vect-data-refs.cc (vect_prune_runtime_alias_test_list):
Reject when !operand_equal_p for any data ref pair.
vect: Disable use of partial vectors for uncounted loops
Given the current reliance of masking on niters and the fact this is
undetermined for uncounted loops, we circumvent this limitation by
disabling the use of partial vectors when vectorizing loops with an
unkown upper bound.
gcc/ChangeLog:
* tree-vect-loop.cc (vect_analyze_loop_2): Disable partial
vector use for uncounted loops.
vect: Fix uncounted PHI handling of `slpeel_tree_duplicate_loop_to_edge_cfg'
Given how present requirements for loops, early-break or otherwise, to
have a known iteration count, there is currently no need for
single-exit loops to reset induction variables and accumulators prior
to entering the exit loop.
For multiple-exit uncounted loops, there are provisions in the code
for resetting IVs and accumulators on exiting the loop via early
exits. This is extended to the main exit (though only in
multiple-exit loops) if `peeled_iters' is set to `true', wherein the
definition of `peeled_iters' is equivalent to that of
LOOP_VINFO_EARLY_BREAKS_VECT_PEELED, but is evaluated independently as
the function does not have access to loop_vinfo.
Therefore, the first fix is to ensure that, just as for
LOOP_VINFO_EARLY_BREAKS_VECT_PEELED, `peeled_iters' also evaluates to
true for uncounted loops.
The second fix implemented here is: given the relevant logic is
currently hidden behind the `multiple_exits_p', we enable relevant
logic via use of the new function argument `uncounted_p'.
gcc/ChangeLog:
* tree-vect-loop-manip.cc (slpeel_tree_duplicate_loop_to_edge_cfg):
reset IVs and accumulators for all exits for uncounted loops.
* tree-vectorizer.h (slpeel_tree_duplicate_loop_to_edge_cfg):
add boolean `uncounted_p' argument.
vect: Disable niters-based skipping of uncounted vectorized loops
The iteration count profitability check is irrelevant for uncounted
loops given that, even at runtime, the number of iterations is unknown
at the start of loop execution.
Likewise, the test for skipping the vectorized version of the loop is
based on whether the number of iterations that will be run for the
loop and whether it is smaller than the vectorization factor. As this
is undetermined, the check can never be run for uncounted loops.
vect: guard niters manipulation with `LOOP_VINFO_NITERS_UNCOUNTED_P'
In `vect_do_peeling' and `vect_transform_loop', there are several bits
of logic reliant on niters that need to be handled differently in the
case of uncounted loops.
Firstly When we peel the loop, adding a prolog, we subtract the
prolog peeling factor from the original number of iterations for the
main loop.
Then, upon vectorization of the main loop, we need to update the
iteration upper-bound to reflect the fact that each iteration now acts
on VF elements, such that less iterations will be needed.
Both of these updates become unnecessary when we don't have an IV
counting exit. Therefore, it is sufficient to guard these
manipulations behind a check for whether the loop we're dealing with
is uncounted.
vect: Extend `vec_init_loop_exit_info' to handle uncounted loops
In its current implementation, the loop vectorizer requires the main
exit be the counting IV exit. With uncounted loops we no longer need
to have any counting IV exits. Furthermore, it is possible to have
reached this stage with malformed loops with no exits at all.
Consequently, we need an approach to handle malformed loops and some
logic to follow when choosing the main exit, when counting IV is no
longer a valid criterion.
For malformed loops, it is sufficient to return NULL, so that we can
reject such loops upon the function return.
In the case of multiple exits and no counting IV exit, we choose the
last one in the loop. This is done so that we continue to have an
empty effective latch.
As a consequence of allowing the main exit to no longer be associated
with IV counting, the old nomenclature of `LOOP_VINFO_IV_EXIT' and
`vec_loop_iv_exit' no longer fully cover the usage of such fields and
accessors. With that in mind, these are modified to replace "IV" for
"MAIN" for these.
vect: Make all exit conditions early breaks for uncounted loops
For uncounted loops, given how no information can be derived from the
max number of iterations, we wish to make no distinction between the
"main" exit and any additional exits.
That is, an epilogue is required across all exits to establish when
the exit condition was met within the final vectorized loop iteration.
This can be accomplished via a two-fold approach:
1. The need for all exits to go to the epilogue is shared with
counted loops with early-break exits after the IV-counting exit.
Such counted loops have the `LOOP_VINFO_EARLY_BREAKS_VECT_PEELED'
flag set. By modifying the flag's definition to encompass
uncounted loops, we can make considerable use of the code written
for this category of counted loops.
2. Currently, when populating the `loop_vinfo' struct for a given
loop, there is an assumption that the first exit condition in the
`vect_loop_form_info' struct is the IV condition and any
subsequent conditions are early break conditions. This
assumption breaks down for uncounted loops where _all_ exits
should be treated as being "early break" exits.
This is fixed by populating `LOOP_VINFO_LOOP_IV_COND (loop_vinfo)'
conditionally on the false evaluation of the
`LOOP_VINFO_NITERS_UNCOUNTED_P (loop_vinfo)' predicate, such that
if we do have an uncounted loop we leave this field unpopulated,
storing all conditions in `LOOP_VINFO_LOOP_CONDS (loop_vinfo)'.
This approach has a further benefit in that, give how
`LOOP_VINFO_EARLY_BREAKS' is defined by a non-empty list of early
break exit conditions (`LOOP_VINFO_LOOP_CONDS (loop_vinfo)'),
having LOOP_VINFO_LOOP_CONDS populated even for single-exit
uncounted loops means that `LOOP_VINFO_EARLY_BREAKS' evaluates to
true for all uncounted loops, irrespective of the number of exits
it has.
gcc/ChangeLog:
* tree-vectorizer.h (LOOP_VINFO_EARLY_BREAKS_VECT_PEELED): OR
its current definition with `LOOP_VINFO_NITERS_UNCOUNTED_P(L)'
* tree-vect-loop.cc (vect_create_loop_vinfo): Don't populate
`LOOP_VINFO_LOOP_IV_COND' for uncounted loops.
Given that scalar evolution analysis of uncounted loops sets
`loop_vec_info->num_iters' to `chrec_dont_know', we use this as the
criterion for probing whether a loop is uncounted or not.
Consequently, we introduce a new access function on `loop_vec_info' to
conveniently test whether a loop in question is uncounted or not, in
the form of `LOOP_VINFO_NITERS_UNCOUNTED_P(L)'.
Default types:
--------------
While the primary exit condition for loops is no longer tied to some
upper limit in the number of executed iterations, similar limits are
still required for vectorization. One example of this is with prolog
peeling. The prolog will always have an IV exit associated with the
misalignment of data accesses within the loop.
Historically, the assumption held that the data-type that this counter
should have could be derived from the type of the niters limit for the
original loop, so we could get the type from `TREE_TYPE (niters)'.
Moving forward, we provide a backup type to be used for iteration
counters when the maximum number of iterations to be run is unknown.
We take this to be `sizetype', given its role in storing the maximum
size of a theoretically possible object of any type (including array).
Default return values:
----------------------
To avoid having to gate all calls to functions that query a loop's
niters value it is better to "teach" such functions how to handle
uncounted loops and have them return a sensible value that can be
handled upon a function's return.
We therefore prevent functions operating on niters from segfaulting by
adding a default `SCEV_NOT_KNOWN' return value when niters information
absent.
Peter Damianov [Thu, 11 Dec 2025 01:52:43 +0000 (01:52 +0000)]
Driver: Implement --with-windres= argument to configure script [PR108866]
To align with the rest of the options (--with-ld, --with-as, --with-dsymutil),
implement --with-windres for overriding the windres binary the driver invokes
with an absolute path to a windres binary.
Peter Damianov [Thu, 11 Dec 2025 01:52:42 +0000 (01:52 +0000)]
Driver: Add support for Windows resource files (.rc, .res) [PR108866]
This patch adds support for compiling Windows resource files
(.rc) and pre-compiled resource files (.res) directly through the
GCC driver on PECOFF targets.
Previously, users had to manually invoke windres to compile resource
files before linking:
If any of -E -M or -MM were passed, do nothing. No object files are output.
"%{!E:%{!M:%{!MM:windres
Add -J so that windres does not perform autodetection of input type
Add -O so that the output type is always COFF
-J rc -O coff \
For multilib configurations, tell windres to write out the correct COFF format.
- If -m32 is specified, use pe-i386 format
- If -m64 is specified, use pe-x86_64 format
- If neither are specified, use the correct default for the target
This is defined in WINDRES_FORMAT_SPEC which expands to:
For 64-bit: "%{m32:-F pe-i386;m64|!m32:-F pe-x86-64}"
For 32-bit: "%{m64:-F pe-x86-64;m32|!m64:-F pe-i386}"
Pass through -I -D -U on to windres, because it supports them.
%{I*:-I%*} %{D*:-D%*} %{U*:-U%*} \
If -c is passed, pass through -o to windres, if it was specified. Otherwise,
output to the input basename with .o suffix. Else, output to a
temp file that will be deleted after linking.
%{c:%W{o*}%{!o*:-o %w%b%O}}%{!c:-o %d%w%u%O} %i}}}",
gcc/ChangeLog:
PR driver/108866
* gcc.cc (default_compilers): Add EXTRA_DEFAULT_COMPILERS so the config
of a target can add an extra compiler spec to default_compilers.
* config/i386/cygming.h (WINDRES_FORMAT_SPEC): New macro to handle
PE format selection based on TARGET_64BIT_DEFAULT and -m32/-m64 flags.
(EXTRA_DEFAULT_COMPILERS): Add spec for windres.
* config/aarch64/cygming.h (EXTRA_DEFAULT_COMPILERS): Likewise.
Signed-off-by: Peter Damianov <peter0x44@disroot.org> Signed-off-by: Jonathan Yong <10walls@gmail.com>
Jakub Jelinek [Mon, 15 Dec 2025 12:44:20 +0000 (13:44 +0100)]
openmp: Fix next variable initialization in cp_parser_omp_clause_linear [PR123128]
Apparently clang++ emits error on int *p = ((unsigned long) 0); while g++
accepts it without any diagnostics even with -pedantic-errors -W -Wall.
Dunno which is right, anyway, I meant to initialize with NULL, not
UNKNOWN_LOCATION.
2025-12-15 Jakub Jelinek <jakub@redhat.com>
PR c++/123128
* parser.cc (cp_parser_omp_clause_linear): Initialize next to NULL
rather than UNKNOWN_LOCATION.
Eric Botcazou [Mon, 15 Dec 2025 08:09:13 +0000 (09:09 +0100)]
Ada: Fix ICE in fld_incomplete_type_of when building GtkAda with LTO
This is a regression from GCC 9 present on mainline and all active branches:
the compilation of GtkAda in LTO mode trips on the assertion present in the
fld_incomplete_type_of function about the TYPE_CANONICAL of types pointed to
by pointer (or reference) types. The problem comes from an oversight in the
update_pointer_to function on gcc-interface, which correctly propagates the
TYPE_CANONICAL of the new pointer type to the old one when there is a new
pointer type, but fails to synthesize it when there is no new pointer type.
gcc/ada/
PR ada/123060
* gcc-interface/utils.cc (update_pointer_to): Synthesize a new
TYPE_CANONICAL for the old pointer type in the case where there
is no new pointer type. Likewise for references.
gcc/testsuite/
* gnat.dg/lto30.ads, gnat.dg/lto30.adb: New test.
* ga68-exports.pk (ga68_text_reloc_64): Renamed and
adapted from ga68_text_reloc.
(ga68_data_reloc_64): Renamed and adapted from ga68_data_reloc.
(ga68_mode_64): Renamed and adapted from ga68_mode.
(ga68_extract_64): Renamed and adapted from ga68_extract.
(ga68_module_64): Renamed and adapted from ga68_module.
(ga68_text_reloc_32): New type.
(ga68_data_reloc_32): Likewise.
(ga68_mode_32): Likewise.
(ga68_extract_32): Likewise.
(ga68_module_32): Likewise.
Lewis Hyatt [Sun, 14 Dec 2025 14:51:12 +0000 (09:51 -0500)]
middle-end: Fix spurious -Walloc-size-larger-than warning during LTO [PR106409]
The implementation of -Walloc-size-larger-than has logic to avoid issuing
the warning for ::operator new[] calls emitted by the C++ front end, which
otherwise produce known false positives. The logic for suppressing the
warning only activates in the C++ front end, and so it does not prevent the
LTO front end from issuing the warning. Fix by applying the logic in all
cases.
gcc/ChangeLog:
PR tree-optimization/106409
* gimple-ssa-warn-access.cc (maybe_warn_alloc_args_overflow): Adjust
comment for clarity, and augment check to work in LTO as well.
gcc/testsuite/ChangeLog:
PR tree-optimization/106409
* g++.dg/lto/pr106409_0.C: New test.
cprop_hardreg: Prevent copy propagation from a non-frame related insn to a frame related insn
The pass 'cprop_hardreg' should not propagate a value from a
non-frame-related insn to a frame-related one. This can lead to
incorrect dwarf information as noted in PR122274.
cprop_hardreg uses 'struct value_data' to hold lists of registers that
contain the same value. However, the value data does not have any
information about the instruction that sets the values in the register.
In this patch, a new field is added to 'struct value_data_entry'
which indicates if the instruction that created this
value is frame related or not. Then during copy propagation, we do not
replace registers if the copy is happening from a non-frame related insn
to a frame related insn.