Alex Coplan [Mon, 10 Mar 2025 16:44:15 +0000 (16:44 +0000)]
df: Treat partial defs as uses in df_simulate_defs [PR116564]
The PR shows us spinning in dce.cc:fast_dce at the start of combine.
This spinning appears to be because of a disagreement between the fast_dce code
and the code in df-problems.cc:df_lr_bb_local_compute. Specifically, they
disagree on the treatment of partial defs. For the testcase in the PR, we have
the following insn in bb 3:
i.e. it models partial defs as a RMW operation; thus for the def arising
from i10 above, it records a use of r104; hence it ends up in the
live-in set for bb 3.
However, as it stands, the code in dce.cc:fast_dce (and its callee
dce_process_block) has no such provision for DF_REF_PARTIAL defs. It
does not treat these as a RMW and does not compute r104 above as being
live-in to bb 3. At the end of dce_process_block we compute the
following "did something happen" condition used to decide termination of
the analysis:
because of the disagreement between df_lr_local_compute and the local
analysis done by fast_dce, we invariably have r104 in DF_LR_IN, but not
in local_live. Hence we always return true here, call
df_analyze_problem (which re-computes DF_LR_IN according to
df_lr_bb_local_compute, re-adding r104), and so the analysis never
terminates.
This patch therefore adjusts df_simulate_defs (called from
dce_process_block) to match the behaviour of df_lr_bb_local_compute in
this respect, namely we make it model partial defs as RMW operations by
setting the relevant register live. This fixes the spinning in fast_dce
for this testcase.
gcc/ChangeLog:
PR rtl-optimization/116564
* df-problems.cc (df_simulate_defs): For partial defs, mark the
register live (treat it as a RMW operation).
gcc/testsuite/ChangeLog:
PR rtl-optimization/116564
* gcc.target/aarch64/torture/pr116564.c: New test.
Jonathan Wakely [Tue, 25 Mar 2025 00:27:52 +0000 (00:27 +0000)]
libstdc++: Allow std::ranges::to to create unions
LWG 4229 points out that the std::ranges::to wording refers to class
types, but I added an assertion using std::is_class_v which only allows
non-union class types. LWG consensus is that unions should be allowed,
so this additionally uses std::is_union_v.
libstdc++-v3/ChangeLog:
* include/std/ranges (ranges::to): Allow unions as well as
non-union class types.
* testsuite/std/ranges/conv/lwg4229.cc: New test.
Jonathan Wakely [Thu, 27 Feb 2025 15:48:49 +0000 (15:48 +0000)]
libstdc++: Add static_assertions to ranges::to adaptor factory [PR112803]
The standard requires that we reject attempts to create a ranges::to
adaptor for cv-qualified types and non-class types. Currently we only
diagnose it once the adaptor is used in a pipeline.
This adds static assertions to diagnose it immediately.
libstdc++-v3/ChangeLog:
PR libstdc++/112803
* include/std/ranges (ranges::to): Add static assertions to
enforce Mandates conditions.
* testsuite/std/ranges/conv/112803.cc: New test.
Jonathan Wakely [Tue, 16 Jul 2024 08:43:06 +0000 (09:43 +0100)]
libstdc++: Define operator== for hash table iterators [PR115939]
Currently iterators for unordered containers do not directly define
operator== and operator!= overloads. Instead they rely on the base class
defining them, which is done so that iterator and const_iterator
comparisons work using the same overloads.
However this means a derived-to-base conversion is needed to call those
operators, and PR libstdc++/115939 shows that this can be ambiguous (for
-pedantic) when another overloaded operator could be used after an
implicit conversion.
This change defines operator== and operator!= directly for
_Node_iterator and _Node_const_iterator so that no derived-to-base
conversions are needed. The new overloads just forward to the base class
ones, so the implementation is still shared and doesn't need to be
duplicated.
libstdc++-v3/ChangeLog:
PR libstdc++/115939
* include/bits/hashtable_policy.h (_Node_iterator): Add
operator== and operator!=.
(_Node_const_iterator): Likewise.
* testsuite/23_containers/unordered_map/115939.cc: New test.
Martin Jambor [Fri, 7 Mar 2025 16:17:24 +0000 (17:17 +0100)]
ipa-cp: Avoid ICE when redistributing nodes among edges to recursive clones (PR 118318)
PR 118318 reported an ICE during PGO build of Firefox when IPA-CP, in
the final stages of update_counts_for_self_gen_clones where it
attempts to guess how to distribute profile count among clones created
for recursive edges and the various edges that are created in the
process. If one such edge has profile count of kind GUESSED_GLOBAL0,
the compatibility check in the operator+ will lead to an ICE. After
discussing the situation with Honza, we concluded that there is little
more we can do other than check for this situation before touching the
edge count, so this is what this patch does.
gcc/ChangeLog:
2025-02-28 Martin Jambor <mjambor@suse.cz>
PR ipa/118318
* ipa-cp.cc (adjust_clone_incoming_counts): Add a compatible_p check.
Patrick Palka [Thu, 13 Mar 2025 13:15:21 +0000 (09:15 -0400)]
libstdc++: Fix ref_view branch of views::as_const [PR119135]
Unlike for span<X> and empty_view<X>, the range_reference_t of
ref_view<X> doesn't correspond to X. This patch fixes the ref_view
branch of views::as_const to correctly query its underlying range
type X.
PR libstdc++/119135
libstdc++-v3/ChangeLog:
* include/std/ranges: Include <utility>.
(views::__detail::__is_ref_view): Replace with ...
(views::__detail::__is_constable_ref_view): ... this.
(views::_AsConst::operator()): Replace bogus use of element_type
in the ref_view branch.
* testsuite/std/ranges/adaptors/as_const/1.cc (test03): Extend
test.
Reviewed-by: Tomasz Kamiński <tkaminsk@redhat.com> Reviewed-by: Jonathan Wakely <jwakely@redhat.com>
(cherry picked from commit 50359c0a44381edb6dbd9359ef2ebdadbcc3ed42)
=== cut here ===
struct span {
span (const int (&__first)[1]) : _M_ptr (__first) {}
int operator[] (long __i) { return _M_ptr[__i]; }
const int *_M_ptr;
};
void foo () {
constexpr int a_vec[]{1};
auto vec{[&a_vec]() -> span { return a_vec; }()};
}
=== cut here ===
The problem is that perform_implicit_conversion_flags (via
mark_rvalue_use) replaces "a_vec" in the return statement by a
CONSTRUCTOR representing a_vec's constant value, and then takes its
address when invoking span's constructor. So we end up with an instance
that points to garbage instead of a_vec's storage.
As per Jason's suggestion, this patch simply removes the calls to
mark_*_use from perform_implicit_conversion_flags, which fixes the PR.
Haochen Jiang [Mon, 24 Mar 2025 07:51:16 +0000 (15:51 +0800)]
i386: Add -mavx10.1 back with 512 bit alias
When AVX10.1 options are added into GCC 14, E-core is supposed to
support up to 256 bit vector width, while P-core up to 512 bit vector
width. Therefore, we added avx10.1-256 and avx10.1-512 options into
compiler and alias avx10.1 to 256 bit for compatibility since there
will be real platforms with 256 bit only support.
However, all the future platforms will now support 512 bit vector width,
including P-core and E-core. Therefore, we could alias avx10.1 directly
to 512 bit. However, avx10.1 alias to 256 bit has been there in GCC 14.1
and GCC 14.2, so we have to raise a warning since GCC 14.3 for this
behavior change.
While backporting the patch from GCC 15, we choose to only warn when
users use -mavx10.1 option in order not to interrupt the usage of other
options since -mavx10.1-256/512 and -mevex512 will be dropped in GCC 16.
There is no need to warn them this early in GCC 14 to overwhelm users.
Simon Martin [Mon, 24 Mar 2025 07:15:54 +0000 (08:15 +0100)]
c++: Don't mix timevar_start and auto_cond_timevar for TV_NAME_LOOKUP [PR116681]
We currently ICE upon the following testcase when using -ftime-report
=== cut here ===
template < int> using __conditional_t = int;
template < typename _Iter >
concept random_access_iterator = requires { new _Iter; };
template < typename _Iterator >
struct reverse_iterator {
using iterator_concept =
__conditional_t< random_access_iterator< _Iterator>>;
};
void RemoveBottom() {
int iter;
for (reverse_iterator< int > iter;;)
;
}
=== cut here ===
The problem is that qualified_namespace_lookup does a plain start() of
the TV_NAME_LOOKUP timer (that asserts that the timer is not already
started). However this timer has already been cond_start()'d in the call
stack - by pushdecl - so the assert fails.
This patch simply ensures that we always conditionally start this timer
(which is done in all other places that use it).
PR c++/116681
gcc/cp/ChangeLog:
* name-lookup.cc (qualified_namespace_lookup): Use an
auto_cond_timer instead of using timevar_start and timevar_stop.
Iain Buclaw [Sun, 23 Mar 2025 11:57:27 +0000 (12:57 +0100)]
d: Fix ICE type variant differs by TYPE_PACKED [PR117621]
Introduced by r13-1104-gf4c3ce32fa54c1, which had an accidental self
assignment of TYPE_PACKED when it should have been assigned to the
type's variants.
PR d/117621
gcc/d/ChangeLog:
* types.cc (finish_aggregate_type): Propagate TYPE_PACKED to variants.
Martin Uecker [Sat, 22 Mar 2025 16:05:51 +0000 (17:05 +0100)]
c: minor fixes related to arrays of unspecified size
The patch for PR117145 and PR117245 also fixed PR100420 and PR116284 which
are bugs related to arrays of unspecified size. Those are now represented
as variable size arrays with size (0, 0). There are still some loose ends,
which are resolved here by
1. adding a testcase for PR116284,
2. moving code related to creation and detection of arrays of unspecified
sizes in their own functions,
3. preferring a specified size over an unspecified size when forming
a composite type as required by C99 (PR118391)
4. removing useless code in comptypes_internal and composite_type_internal.
This fixes two cases where variably-modified types were not recognized as
such. The first is when building composite types and the other when a type
is reconstructed for the 'vector' attribute. Construction of types in
the C FE is reorganized to use c_build_* functions which are responsible for
setting C_TYPE_VARIABLE_SIZE, C_TYPE_VARIABLY_MODIFIED and TYPE_TYPELESS_STORAGE
based on the properties of the type itself and these replace all other logic
elsewhere (e.g. in grokdeclarator). A new 'c_reconstruct_complex_type' based
on these functions is introduced which is called via a language hook when the
'vector' attribute is processed (as for C++).
One problem is are arrays of unspecified size 'T[*]' which were represented
identically to zero-sized arrays but with C_TYPE_VARIABLE_SIZE set. To avoid
having to create distinct type copies for this, the representation was changed
to make it a natural VLA by giving it an upper bound of '(0, 0)'. This also
then allows fixing of PR100420 where such arrays were printed as 'T[0]'.
Finally, a new function 'c_verify_type' checks consistency of properties
specific to C FE and is called when checking is on.
Here we ICE during instantiation of the dependently scoped template
friend
template<int N>
struct<class T>
friend class A<N>::B;
ultimately because processing_template_decl isn't set during
substitution into the A<N> scope. Since it's naturally a partial
substitution, we need to make sure the flag is set.
For GCC 15, this is already fixed similarly by r15-123.
PR c++/119378
gcc/cp/ChangeLog:
* pt.cc (tsubst) <case UNBOUND_CLASS_TEMPLATE>: Set
processing_template_decl when substituting the context.
Jason Merrill [Thu, 20 Mar 2025 16:57:15 +0000 (12:57 -0400)]
ipa: target clone and mangling alias [PR114992]
Since the mangling of the second lambda changed (previously we counted all
lambdas, now we only count lambdas with the same signature), we
generate_mangling_alias for handler<lambda2> for backward compatibility.
Since handler is COMDAT, resolve_alias puts the alias in the same comdat
group as handler itself. Then create_dispatcher_calls tries to add the
alias to the same comdat group as the dispatcher, but it's already in a
same_comdat_group, so we ICE.
It seems like we're just missing a remove_from_same_comdat_group before
add_to_same_comdat_group.
PR c++/114992
gcc/ChangeLog:
* multiple_target.cc (create_dispatcher_calls):
remove_from_same_comdat_group before add_to_same_comdat_group.
Filip Kastl [Thu, 20 Mar 2025 10:54:59 +0000 (11:54 +0100)]
gimple: sccopy: Don't increment i after vec::unordered_remove()
I increment the index variable in a loop even when I do
vec::unordered_remove() which causes the vector traversal to miss some
elements. Mikael notified me of this mistake I made in my last patch.
gcc/ChangeLog:
* gimple-ssa-sccopy.cc (scc_copy_prop::propagate): Don't
increment after vec::unordered_remove().
Simon Martin [Thu, 20 Mar 2025 19:36:26 +0000 (20:36 +0100)]
c++: Don't prune constant capture proxies only used in array dimensions [PR114292]
We currently ICE upon the following valid (under -Wno-vla) code
=== cut here ===
void f(int c) {
constexpr int r = 4;
[&](auto) { int t[r * c]; }(0);
}
=== cut here ===
When parsing the lambda body, and more specifically the multiplication,
we mark the lambda as LAMBDA_EXPR_CAPTURE_OPTIMIZED, which indicates to
prune_lambda_captures that it might be possible to optimize out some
captures.
The problem is that prune_lambda_captures then misses the use of the r
capture (because neither walk_tree_1 nor cp_walk_subtrees walks the
dimensions of array types - here "r * c"), hence believes the capture
can be pruned... and we trip on an assert when instantiating the lambda.
This patch changes cp_walk_subtrees so that (1) when walking a
DECL_EXPR, it also walks the DECL's type, and (2) when walking an
INTEGER_TYPE and processing a template declaration, it also walks its
TYPE_{MIN,MAX}_VALUE.
PR c++/114292
gcc/cp/ChangeLog:
* tree.cc (cp_walk_subtrees): Walk the type of DECL_EXPR
declarations, as well as the TYPE_{MIN,MAX}_VALUE of
INTEGER_TYPEs for template declarations.
Jason Merrill [Wed, 19 Mar 2025 09:15:00 +0000 (05:15 -0400)]
c++: mangling of array new [PR119316]
Because we build an array type to represent an array new, we hit a VLA
error in compute_array_index_type for a variable length array new. To avoid
this, let's build the MINUS_EXPR and index type directly.
I also noticed that the non-constant case in write_array_type was assuming
MINUS_EXPR without verifying it, so I added a checking_assert.
I also noticed that Clang doesn't mangle the length of an array new at all,
so I opened https://github.com/itanium-cxx-abi/cxx-abi/issues/199 to clarify
this.
PR c++/119316
gcc/cp/ChangeLog:
* mangle.cc (write_expression) [NEW_EXPR]: Avoid using
compute_array_index_type.
(write_array_type): Add checking_assert.
Patrick Palka [Tue, 18 Mar 2025 15:38:33 +0000 (11:38 -0400)]
c++: memfn pointer as NTTP argument considered unused [PR119233]
This is just the member function pointer version of PR c++/105848,
in which our non-dependent call pruning may cause us to not mark an
otherwise unused function pointer template argument as used.
PR c++/119233
gcc/cp/ChangeLog:
* pt.cc (mark_template_arguments_used): Also handle member
function pointers.
Eric Botcazou [Wed, 19 Mar 2025 07:55:04 +0000 (08:55 +0100)]
Fix misoptimization at -O2 in LTO mode
This is a regression in recent releases. The problem is that the IPA mod/ref
pass looks through the (nominal) type of a pointer-to-discriminated-type
parameter in a call to a subprogram in order to see the (actual) type used
for the dereferences of the parameter in the callee, which is a
pointer-to-constrained-subtype.
Historically the discriminated type is marked with the may_alias attribute
because of the symmetric effect for the argument in the caller, so we mark
the constrained subtype with the attribute now for the sake of the callee.
gcc/ada/
* gcc-interface/decl.cc (gnat_to_gnu_entity) <E_Record_Subtype>: Set
the may_alias attribute if a specific GCC type is built.
Eric Botcazou [Wed, 19 Mar 2025 07:22:33 +0000 (08:22 +0100)]
Fix spurious visibility error with partially parameterized formal package
This is not a regression but the issue is quite annoying and the fix is
trivial. The problem is that a formal parameter covered by a box in the
formal package is not visible in the instance when it comes after another
formal parameter that is also a formal package.
It comes from a discrepancy internal to Instantiate_Formal_Package, where
a specific construct (the abbreviated instance) built for the nested formal
package discombobulates the processing done for the outer formal package.
gcc/ada/
* gen_il-gen-gen_nodes.adb (N_Formal_Package_Declaration): Use
N_Declaration instead of Node_Kind as ancestor.
* sem_ch12.adb (Get_Formal_Entity): Remove obsolete alternative.
(Instantiate_Formal_Package): Take into account the abbreviated
instances in the main loop running over the actuals of the local
package created for the formal package.
gcc/testsuite/
* gnat.dg/generic_inst14.adb: New test.
* gnat.dg/generic_inst14_pkg.ads: New helper.
* gnat.dg/generic_inst14_pkg-child.ads: Likewise.
Jason Merrill [Tue, 18 Mar 2025 18:44:08 +0000 (14:44 -0400)]
c++: constexpr ref template arg [PR119194]
Here we were assuming that a constant variable appearing in a template
argument is used for its value. We also need to handle seeing its address
taken.
PR c++/119194
gcc/cp/ChangeLog:
* decl2.cc (min_vis_expr_r) [ADDR_EXPR]: New case.
Marek Polacek [Mon, 17 Mar 2025 21:46:02 +0000 (17:46 -0400)]
c++: ICE with ptr-to-member-fn [PR119344]
This ICE appeared with the removal of NON_DEPENDENT_EXPR. Previously
skip_simple_arithmetic would get NON_DEPENDENT_EXPR<CAST_EXPR<>> and
since NON_DEPENDENT_EXPR is neither BINARY_CLASS_P nor UNARY_CLASS_P,
there was no problem. But now we pass just CAST_EXPR<> and a CAST_EXPR
is a tcc_unary, so we extract its null operand and crash.
skip_simple_arithmetic is called from save_expr. cp_save_expr already
avoids calling save_expr in a template, so that seems like an appropriate
way to fix this.
PR c++/119344
gcc/cp/ChangeLog:
* typeck.cc (cp_build_binary_op): Use cp_save_expr instead of save_expr.
gcc/testsuite/ChangeLog:
* g++.dg/conversion/ptrmem10.C: New test.
Reviewed-by: Patrick Palka <ppalka@redhat.com> Reviewed-by: Jason Merrill <jason@redhat.com>
(cherry picked from commit 6fc1f70f0b7b50fd85aa58a0f29dd1e17f2113d1)
Marek Polacek [Mon, 17 Mar 2025 16:56:40 +0000 (12:56 -0400)]
c++: ICE when substituting packs into type aliases [PR118104]
r12-1094 mentions that adding the assert didn't lead to any regressions
in the testsuite, but this test case demonstrates that we can reach it
with valid code.
Here we arrive in use_pack_expansion_extra_args_p with t which is an
expansion whose pattern is void(Ts, Us) and tparm packs are {Us, Ts},
and parm_packs is { Ts -> <int, int>, Us -> <A, P...> }. We want to
expand the pack into void(int, A) and void(int, P...). We compare
int to A, which is fine, but then int to P... which crashes. But
the code is valid so this patch removes the assert.
PR c++/118104
gcc/cp/ChangeLog:
* pt.cc (use_pack_expansion_extra_args_p): Remove an assert.
Patrick Palka [Fri, 28 Feb 2025 14:39:57 +0000 (09:39 -0500)]
libstdc++: Fix constraint recursion in basic_const_iterator relops [PR112490]
Here for
using RCI = reverse_iterator<basic_const_iterator<vector<int>::iterator>>
static_assert(std::totally_ordered<RCI>);
we effectively need to check the requirement
requires (RCI x) { x RELOP x; } for each RELOP in {<, >, <=, >=}
which we expect to be straightforwardly satisfied by reverse_iterator's
namespace-scope relops. But due to ADL we find ourselves also
considering the basic_const_iterator relop friends, which before CWG
2369 would be quickly discarded since RCI clearly isn't convertible to
basic_const_iterator. After CWG 2369 though we must first check these
relops' constraints (with _It = vector<int>::iterator and _It2 = RCI),
which entails checking totally_ordered<RCI> recursively.
This patch fixes this by turning the problematic non-dependent function
parameters of type basic_const_iterator<_It> into dependent ones of
type basic_const_iterator<_It3> where _It3 is constrained to match _It.
Thus the basic_const_iterator relop friends now get quickly discarded
during deduction and before the constraint check if the second operand
isn't a specialization of basic_const_iterator (or derived from one)
like before CWG 2369.
PR libstdc++/112490
libstdc++-v3/ChangeLog:
* include/bits/stl_iterator.h (basic_const_iterator::operator<):
Replace non-dependent basic_const_iterator function parameter with
a dependent one of type basic_const_iterator<_It3> where _It3
matches _It.
(basic_const_iterator::operator>): Likewise.
(basic_const_iterator::operator<=): Likewise.
(basic_const_iterator::operator>=): Likewise.
* testsuite/24_iterators/const_iterator/112490.cc: New test.
d = MEM <unsigned char[4]> [(struct A *)&TARGET_EXPR <D.2894, foo()]
= MEM <unsigned char[4]> [(struct A *)(const struct A &) &e],
TARGET_EXPR <D.2894, foo()>
that is, a COMPOUND_EXPR where a TARGET_EXPR is used twice, and its
address is taken in the left-hand side operand, so it can't be elided.
But set_target_expr_eliding simply recurses on the second operand of
a COMPOUND_EXPR and marks the TARGET_EXPR as eliding. This then causes
a crash.
cp_build_indirect_ref_1 should not be changing the value category.
While *&TARGET_EXPR is an lvalue, folding it into TARGET_EXPR would
render is a prvalue of class type.
PR c++/117512
gcc/cp/ChangeLog:
* typeck.cc (cp_build_indirect_ref_1): Only do the *&e -> e
folding if the result would be an lvalue.
gcc/testsuite/ChangeLog:
* g++.dg/cpp0x/alignas23.C: New test.
* g++.dg/ext/align3.C: New test.
* g++.dg/ext/align4.C: New test.
* g++.dg/ext/align5.C: New test.
Marek Polacek [Fri, 7 Mar 2025 16:26:46 +0000 (11:26 -0500)]
c++: ICE with lambda in fold expression in requires [PR119134]
The r12-8258 fix assumes that DECL_CONTEXT of 'pack' in
check_for_bare_parameter_packs is going to be an operator()
but as this test shows, it can be empty.
Richard Earnshaw [Tue, 11 Mar 2025 10:48:54 +0000 (10:48 +0000)]
arm: testsuite: fix arm_neon_h checks with conflicting cpu/arch
GCC will complain if the -mcpu flag specifies a different architecture
to that specified in -march, but if the floating-point ABI is "soft",
then differences in the floating-point architecture features are
ignored.
However, the arm_libc_fp_abi checks whether we change the FP ABI by
adding -mfloat-abi=hard/softfp to override the defaults. If that
fails it won't add anything.
Unfortunately arm_neon_h_ok wasn't correctly checking whether the libc
check had worked and just assumed that it would always add something
to enable FP. That's insufficient and we need to consider this failure.
We simply mark tests as unsupported in this case.
gcc/testsuite/ChangeLog:
* lib/target-supports.exp
(check_effective_target_arm_neon_h_ok_nocache): Return zero if
check_effective_target_arm_libc_fp_abi_ok reports failure.
arm: testsuite: improve guard checks for arm_neon.h
The header file arm_neon.h provides the Advanced SIMD intrinsics that
are available on armv7 or later A & R profile cores. However, they
are not compatible with M-profile and we also need to ensure that the
FP instructions are enabled (with -mfloat-abi=softfp/hard). That
leads to some complicated checking as arm_neon.h includes stdint.h
and, at least on linux, that can require that the appropriate ABI
bits/ headers are also installed.
This patch adds a new check to target-supports.exp to establish the
minimal set of option overrides needed to enable use of this header in
a test.
gcc/testsuite:
* lib/target-supports.exp
(check_effective_target_arm_neon_h_ok_nocache): New function.
(check_effective_target_arm_neon_h_ok): Likewise.
(add_options_for_arm_neon_h): Likewise.
(check_effective_target_arm_libc_fp_abi_ok_nocache): Allow any
Arm target, not just arm32.
* gcc.target/arm/attr-neon-builtin-fail.c: Use it.
* gcc.target/arm/attr-neon-builtin-fail2.c: Likewise.
* gcc.target/arm/attr-neon-fp16.c: Likewise.
* gcc.target/arm/attr-neon2.c: Likewise.
Iain Buclaw [Tue, 11 Mar 2025 16:56:18 +0000 (17:56 +0100)]
d: Fix regression returning from function with invariants [PR119139]
An optimization was added in GDC-12 which sets the TREE_READONLY flag on
all local variables with the storage class `const' assigned. For some
reason, const is also being added by the front-end to `__result'
variables in non-virtual functions, which ends up getting wrong code by
the gimplify pass promoting the local to static storage.
A bug has been raised upstream, as this looks like an error in the AST.
For now, turn off setting TREE_READONLY on all result variables.
PR d/119139
gcc/d/ChangeLog:
* decl.cc (get_symbol_decl): Don't set TREE_READONLY for __result
declarations.
Iain Buclaw [Mon, 10 Mar 2025 19:52:49 +0000 (20:52 +0100)]
libphobos: Default to libc closefrom in spawnProcessPosix [PR119112]
This is a backport of two changes in upstream Phobos.
- The current implementation of spawnProcessPosix is broken on systems
with a large `ulimit -n' because it always OOMs making it impossible to
spawn processes. Using the libc implementation, when available, for
doing file descriptor operations en-mass solves this problem.
- The fallback code now reads the list of file descriptors in use from
/dev/fd or /proc/this/fd, avoiding the need to scroll through the entire
list of possible file descriptors. This fixes the fork process being
very slow and memory intensive when RLIMIT_NOFILE is too high.
Paul Thomas [Mon, 27 Jan 2025 09:55:26 +0000 (09:55 +0000)]
Fortran: ICE in gfc_conv_expr_present w. defined assignment [PR118640]
2025-01-27 Paul Thomas <pault@gcc.gnu.org>
gcc/fortran
PR fortran/118640
* resolve.cc (generate_component_assignments): Make sure that
the rhs temporary does not pick up the optional attribute from
the lhs.
gcc/testsuite/
PR fortran/118640
* gfortran.dg/pr118640.f90: New test.
Paul Thomas [Sat, 16 Nov 2024 15:56:10 +0000 (15:56 +0000)]
Fortran: Fix segmentation fault in defined assignment [PR109066]
2024-11-16 Paul Thomas <pault@gcc.gnu.org>
gcc/fortran
PR fortran/109066
* resolve.cc (generate_component_assignments): If the temporary
for 'var' is a pointer and 'expr' is neither a constant or
a variable, change its attribute from pointer to allocatable.
This avoids assignment to a temporary point that has neither
been allocated or associated.
gcc/testsuite/
PR fortran/109066
* gfortran.dg/defined_assignment_12.f90: New test.
Jerry DeLisle [Sat, 8 Mar 2025 02:33:29 +0000 (18:33 -0800)]
Fortran: Fix ICE in resolve.cc with -pedantic
Fixes an ICE in gfc_resolve_code when passing an
optional array to an elemental procedure with `-pedantic` enabled.
PR95446 added the original check, this patch fixes the case where the
other actual argument is an array literal (or something else other
than a variable).
PR fortran/119054
gcc/fortran/ChangeLog:
* resolve.cc (resolve_elemental_actual): When checking other
actual arguments to elemental procedures, don't check
attributes of literals and function calls.
gcc/testsuite/ChangeLog:
* gfortran.dg/pr95446.f90: Expand test case to literals and
function calls.
Christophe Lyon [Mon, 3 Mar 2025 11:12:18 +0000 (11:12 +0000)]
arm: Handle fixed PIC register in require_pic_register (PR target/115485)
Commit r9-4307-g89d7557202d25a forgot to accept a fixed PIC register
when extending the assert in require_pic_register.
arm_pic_register can be set explicitly by the user
(e.g. -mpic-register=r9) or implicitly as the default value with
-fpic/-fPIC/-fPIE and -mno-pic-data-is-text-relative -mlong-calls, and
we want to use/accept it when recording cfun->machine->pic_reg as used
to be the case.
Xi Ruoyao [Sun, 2 Mar 2025 11:02:50 +0000 (19:02 +0800)]
LoongArch: Fix incorrect reorder of __lsx_vldx and __lasx_xvldx [PR119084]
They could be incorrectly reordered with store instructions like st.b
because the RTL expression does not have a memory_operand or a (mem)
expression. The incorrect reorder has been observed in openh264 LTO
build.
Expand them to a (mem) expression instead of unspec to fix the issue.
aarch64: Check for invalid use arrays in ldp_fusion [PR118320]
As Andrew says in the bugzilla comments, this PR is about a case where
we tried to fuse two stores of x0, one in which x0 was defined and one
in which it was undefined. merge_access_arrays failed on the conflict,
but the failure wasn't caught.
Normally the hazard detection code would fail if the instructions
had incompatible uses. However, an undefined use doesn't impose
many restrictions on movements. I think this is likely to be the
only case where hazard detection isn't enough.
As Andrew notes in bugzilla, it might be possible to allow uses
of defined and undefined values to be merged to the defined value.
But that sounds dangerous in the general case, as an rtl-ssa-level
decision. We might run the risk of turning conditional UB into
unconditional UB. And LLVM proves that the definition of "undef"
isn't simple.
gcc/
PR rtl-optimization/118320
* config/aarch64/aarch64-ldp-fusion.cc (ldp_bb_info::fuse_pair):
Commonize the merge of input_uses and return early if it
fails.
gcc/testsuite/
PR rtl-optimization/118320
* g++.dg/torture/pr118320.C: New test.
Hannes Braun [Thu, 20 Feb 2025 14:09:41 +0000 (15:09 +0100)]
arm: Fix signedness of vld1q intrinsic parms [PR118942]
vld1q_s8_x3, vld1q_s16_x3, vld1q_s8_x4 and vld1q_s16_x4 were expecting
pointers to unsigned integers. These parameters should be pointers to
signed integers.
gcc/ChangeLog:
PR target/118942
* config/arm/arm_neon.h (vld1q_s8_x3): Use int8_t instead of
uint16_t.
(vld1q_s16_x3): Use int16_t instead of uint16_t.
(vld1q_s8_x4): Likewise.
(vld1q_s16_x4): Likewise.
* include/bits/ranges_util.h (__detail::__pair_like_convertible_from):
Use `_Tp` in `is_reference_v` check
* testsuite/std/ranges/subrange/tuple_like.cc: New tests for
pair-like conversion
When a generic lambda calls an overload set containing an iobj member
function we speculatively capture 'this'. We need to do the same
for an xobj member function.
PR c++/119038
gcc/cp/ChangeLog:
* lambda.cc (maybe_generic_this_capture): Consider xobj
member functions as well, not just iobj. Update function
comment.
Fix folding of BIT_NOT_EXPR for POLY_INT_CST [PR118976]
There was an embarrassing typo in the folding of BIT_NOT_EXPR for
POLY_INT_CSTs: it used - rather than ~ on the poly_int. Not sure
how that happened, but it might have been due to the way that
~x is implemented as -1 - x internally.
gcc/
PR tree-optimization/118976
* fold-const.cc (const_unop): Use ~ rather than - for BIT_NOT_EXPR.
* config/aarch64/aarch64.cc (aarch64_test_sve_folding): New function.
(aarch64_run_selftests): Run it.
--cut here--
/* Otherwise, if this register is used by I3, then this register
now dies here, so we must put a REG_DEAD note here unless there
is one already. */
else if (reg_referenced_p (XEXP (note, 0), PATTERN (i3))
&& ! (REG_P (XEXP (note, 0))
? find_regno_note (i3, REG_DEAD,
REGNO (XEXP (note, 0)))
: find_reg_note (i3, REG_DEAD, XEXP (note, 0))))
{
PUT_REG_NOTE_KIND (note, REG_DEAD);
place = i3;
}
--cut here--
Flags register is used in I3, but there already is a REG_DEAD note in I3.
The above condition doesn't trigger and continues in the "else" part where
REG_DEAD note is put to I2. The proposed solution corrects the above
logic to trigger every time the register is referenced in I3, avoiding the
"else" part.
PR rtl-optimization/118739
gcc/ChangeLog:
* combine.cc (distribute_notes) <case REG_UNUSED>: Correct the
logic when the register is used by I3.
Martin Jambor [Tue, 4 Mar 2025 13:53:41 +0000 (14:53 +0100)]
ipa-sra: Avoid clashes with ipa-cp when pulling accesses across calls (PR 118243)
Among other things, IPA-SRA checks whether splitting out a bit of an
aggregate or something passed by reference would lead into a clash
with an already known IPA-CP constant a way which would cause problems
later on. Unfortunately the test is done only in
adjust_parameter_descriptions and is missing when accesses are
propagated from callees to callers, which leads to miscompilation
reported as PR 118243 (where the callee is a function created by
ipa-split).
The matter is then further complicated by the fact that we consider
complex numbers as scalars even though they can be modified piecemeal
(IPA-CP can detect and propagate the pieces separately too) which then
confuses the parameter manipulation machinery furter.
This patch simply adds the missing check to avoid the IPA-SRA
transform in these cases too, which should be suitable for backporting
to all affected release branches. It is a bit of a shame as in the PR
testcase we do propagate both components of the complex number in
question and the transformation phase could recover. I have some
prototype patches in this direction but that is something for (a)
stage 1.
gcc/ChangeLog:
2025-02-10 Martin Jambor <mjambor@suse.cz>
PR ipa/118243
* ipa-sra.cc (pull_accesses_from_callee): New parameters
caller_ipcp_ts and param_idx. Check that scalar pulled accesses would
not clash with a known IPA-CP aggregate constant.
(param_splitting_across_edge): Pass IPA-CP transformation summary and
caller parameter index to pull_accesses_from_callee.
Filip Kastl [Sun, 2 Mar 2025 05:39:17 +0000 (06:39 +0100)]
gimple: sccopy: Prune removed statements from SCCs [PR117919]
While writing the sccopy pass I didn't realize that 'replace_uses_by ()' can
remove portions of the CFG. This happens when replacing arguments of some
statement results in the removal of an EH edge. Because of this sccopy can
then work with GIMPLE statements that aren't part of the IR anymore. In
PR117919 this triggered an assertion within the pass which assumes that
statements the pass works with are reachable.
This patch tells the pass to notice when a statement isn't in the IR anymore
and remove it from it's worklist.
PR tree-optimization/117919
gcc/ChangeLog:
* gimple-ssa-sccopy.cc (scc_copy_prop::propagate): Prune
statements that 'replace_uses_by ()' removed.
Jeff Law [Sun, 29 Dec 2024 15:27:30 +0000 (08:27 -0700)]
[PR target/116720] Fix test for valid mempair operands
So this BZ is a case where we incorrectly indicated that the operand array was
suitable for the t-head load/store pair instructions.
In particular there's a test which checks alignment, but that happens *before*
we know if the operands are going to be reversed. So the routine reported the
operands are suitable.
At a later point the operands have been reversed into the proper order and we
realize the alignment test should have failed, resulting in the unrecognized
insn.
This fixes the code by moving the reversal check earlier and actually swapping
the local variables with the operands. That in turn allows for simpler testing
of alignments, ordering, etc.
I've tested this on rv32 and rv64 in my tester. I don't offhand know if the
patch from Filip that's been causing headaches for the RISC-V port has been
reverted/fixed. So there's a nonzero chance the pre-commit CI tester will
fail. I'll keep an eye on it and act appropriately.
PR target/116720
gcc/
* config/riscv/thead.cc (th_mempair_operands_p): Test for
aligned memory after swapping operands. Simplify test for
first memory access as well.
gcc/testsuite/
* gcc.target/riscv/pr116720.c: New test.
Iain Buclaw [Fri, 28 Feb 2025 18:22:36 +0000 (19:22 +0100)]
d: Fix comparing uninitialized memory in dstruct.d [PR116961]
Floating-point emulation in the D front-end is done via a type named
`struct longdouble`, which in GDC is a small interface around the
real_value type. Because the D code cannot include gcc/real.h directly,
a big enough buffer is used for the data instead.
On x86_64, this buffer is actually bigger than real_value itself, so
when a new longdouble object is created with
there is uninitialized padding at the end of `r`. This was never a
problem when D was implemented in C++ (until GCC 12) as comparing two
longdouble objects with `==' would be forwarded to the relevant
operator== overload that extracted the underlying real_value.
However when the front-end was translated to D, such conditions were
instead rewritten into identity comparisons
return exp.toReal() is CTFloat.zero
The `is` operator gets lowered as a call to `memcmp() == 0', which is
where the read of uninitialized memory occurs, as seen by valgrind.
==26778== Conditional jump or move depends on uninitialised value(s)
==26778== at 0x911F41: dmd.dstruct._isZeroInit(dmd.expression.Expression) (dstruct.d:635)
==26778== by 0x9123BE: StructDeclaration::finalizeSize() (dstruct.d:373)
==26778== by 0x86747C: dmd.aggregate.AggregateDeclaration.determineSize(ref const(dmd.location.Loc)) (aggregate.d:226)
[...]
To avoid accidentally reading uninitialized data, explicitly initialize
all `longdouble` variables with an empty constructor on C++ side of the
implementation before initializing underlying real_value type it holds.
Jonathan Wakely [Wed, 12 Feb 2025 17:29:59 +0000 (17:29 +0000)]
libstdc++: Use init_priority attribute for tzdb globals [PR118811]
When linking statically to libstdc++.a (or to libstdc++_nonshared.a in
the RHEL devtoolset compiler) there's a static initialization order
problem where user code might be constructed before the
std::chrono::tzdb_list globals, and so might try to use them after
they've already been destroyed.
Use the init_priority attribute on those globals so that they are
initialized early. Since r15-7511-g4e7f74225116e7 we can disable the
warnings for using a reserved priority using a diagnostic pragma.
However, for the backport to the release branch the warnings can only be
suppressed by defining the objects in a system header. Move them to a
new file that uses '#pragma GCC system_header' and then include that in
tzdb.cc.
libstdc++-v3/ChangeLog:
PR libstdc++/118811
* src/c++20/tzdb.cc (tzdb_list::_Node): Move definitions of
static data members to new header.
* src/c++20/tzdb_globals.h: New header. Use init_priority
attribute on static data members.
* testsuite/std/time/tzdb_list/pr118811.cc: New test.
Jonathan Wakely [Sat, 1 Jun 2024 09:45:55 +0000 (10:45 +0100)]
libstdc++: Reuse temporary buffer utils in <stacktrace>
The non-throwing allocation logic in std::stacktrace duplicates the
logic in <bits/stl_tempbuf.h>, so we can just reuse those utilities.
libstdc++-v3/ChangeLog:
* include/std/stacktrace (basic_stacktrace::_Impl::_M_allocate):
Use __detail::__get_temporary_buffer.
(basic_stacktrace::_Impl::_M_deallocate): Use
__detail::__return_temporary_buffer.
We get smaller code at all optimization levels by not creating a
temporary object, just comparing lengths first and then using
traits_type::compare. This does less work than calling substr then
operator==.
libstdc++-v3/ChangeLog:
* include/std/string_view (starts_with(basic_string_view)):
Compare lengths first and then call traits_type::compare
directly.
Jonathan Wakely [Wed, 26 Jun 2024 13:09:07 +0000 (14:09 +0100)]
libstdc++: Do not use C++11 alignof in C++98 mode [PR104395]
When -faligned-new (or Clang's -faligned-allocation) is used our
allocators try to support extended alignments, gated on the
__cpp_aligned_new macro. However, because they use alignof(_Tp) which is
not a keyword in C++98 mode, using -std=c++98 -faligned-new results in
errors from <memory> and other headers.
We could change them to use __alignof__ instead of alignof, but that
would potentially alter the result of the conditions, because e.g.
alignof(long long) != __alignof__(long long) on some targets. That's
probably not an issue for any types with extended alignment, so maybe it
would be a safe change.
For now, it seems acceptable to just disable the extended alignment
support in C++98 mode, so that -faligned-new enables std::align_val_t
and the corresponding operator new overloads, but doesn't affect
std::allocator, __gnu_cxx::__bitmap_allocator etc.
libstdc++-v3/ChangeLog:
PR libstdc++/104395
* include/bits/new_allocator.h: Disable extended alignment
support in C++98 mode.
* include/bits/stl_tempbuf.h: Likewise.
* include/ext/bitmap_allocator.h: Likewise.
* include/ext/malloc_allocator.h: Likewise.
* include/ext/mt_allocator.h: Likewise.
* include/ext/pool_allocator.h: Likewise.
* testsuite/ext/104395.cc: New test.
Jonathan Wakely [Tue, 18 Jun 2024 19:53:53 +0000 (20:53 +0100)]
libstdc++: Fix warning regressions in <bits/stl_tempbuf.h>
I caused some new warnings with -Wsystem-headers with my recent changes
to std::get_temporary_buffer and std::_Temporary_buffer. There's a
-Wsign-compare warning which can be avoided by casting the ptrdiff_t
argument to size_t (which also conveniently rejects negative values).
There's also a -Wdeprecated-declarations warning because I moved where
std::get_temporary_buffer is called, but didn't move the diagnostic
pragmas that suppress the warning for calling it.
libstdc++-v3/ChangeLog:
* include/bits/stl_tempbuf.h (__get_temporary_buffer): Cast
argument to size_t to handle negative values and suppress
-Wsign-compare warning.
(_Temporary_buffer): Move diagnostic pragmas to new location of
call to std::get_temporary_buffer.
Jonathan Wakely [Wed, 13 Apr 2022 12:03:44 +0000 (13:03 +0100)]
libstdc++: Handle extended alignment in std::get_temporary_buffer [PR105258]
This adds extended alignment support to std::get_temporary_buffer etc.
so that when std::stable_sort uses a temporary buffer it works for
overaligned types.
Also simplify the _Temporary_buffer type by using RAII for the
allocation, via a new data member. This simplifies the _Temporary_buffer
constructor and destructor by makingthem only responsible for
constructing and destroying the elements, not managing the memory.
libstdc++-v3/ChangeLog:
PR libstdc++/105258
* include/bits/stl_tempbuf.h (__detail::__get_temporary_buffer):
New function to do allocation for get_temporary_buffer, with
extended alignment support.
(__detail::__return_temporary_buffer): Support extended
alignment.
(get_temporary_buffer): Use __get_temporary_buffer.
(return_temporary_buffer): Support extended alignment. Add
deprecated attribute.
(_Temporary_buffer): Move allocation and deallocation into a
subobject and remove try-catch block in constructor.
(__uninitialized_construct_buf): Use argument deduction for
value type.
* testsuite/20_util/temporary_buffer.cc: Add dg-warning for new
deprecated warning.
* testsuite/25_algorithms/stable_sort/overaligned.cc: New test.
libstdc++: fix a dangling reference crash in ranges::is_permutation [PR118160]
The code was caching the result of `invoke(proj, *it)` in a local
`auto &&` variable. The problem is that this may create dangling
references, for instance in case `proj` is `std::identity` (the common
case) and `*it` produces a prvalue: lifetime extension does not
apply here due to the expressions involved.
Instead, store (and lifetime-extend) the result of `*it` in a separate
variable, then project that variable. While at it, also forward the
result of the projection to the predicate, so that the predicate can
act on the proper value category.
libstdc++-v3/ChangeLog:
PR libstdc++/118160
PR libstdc++/100249
* include/bits/ranges_algo.h (__is_permutation_fn): Avoid a
dangling reference by storing the result of the iterator
dereference and the result of the projection in two distinct
variables, in order to lifetime-extend each one.
Forward the projected value to the predicate.
* testsuite/25_algorithms/is_permutation/constrained.cc: Add a
test with a range returning prvalues. Test it in a constexpr
context, in order to rely on the compiler to catch UB.