Jakub Jelinek [Thu, 23 Jan 2025 10:11:23 +0000 (11:11 +0100)]
builtins: Store unspecified value to *exp for inf/nan [PR114877]
The fold_builtin_frexp folding for NaN/Inf just returned the first argument
with evaluating second arguments side-effects, rather than storing something
to what the second argument points to.
The PR argues that the C standard requires the function to store something
there but what exactly is stored is unspecified, so not storing there
anything can result in UB if the value isn't initialized and is read later.
glibc and newlib store there 0, musl apparently doesn't store anything.
The following patch stores there zero (or would you prefer storing there
some other value, 42, INT_MAX, INT_MIN, etc.?; zero is cheapest to form
in assembly though) and adjusts the test so that it
doesn't rely on not storing there anything but instead checks for
-Wmaybe-uninitialized warning to find out that something has been stored
there.
Unfortunately I had to disable the NaN tests for -O0, while we can fold
__builtin_isnan (__builtin_nan ("")) at compile time, we can't fold
__builtin_isnan ((i = 0, __builtin_nan (""))) at compile time.
fold_builtin_classify uses just tree_expr_nan_p and if that isn't true
(because expr is a COMPOUND_EXPR with tree_expr_nan_p on the second arg),
it does
arg = builtin_save_expr (arg);
return fold_build2_loc (loc, UNORDERED_EXPR, type, arg, arg);
and that isn't folded at -O0 further, as we wrap it into SAVE_EXPR and
nothing propagates the NAN to the comparison.
I think perhaps tree_expr_nan_p etc. could have case COMPOUND_EXPR:
added and recurse on the second argument, but that feels like stage1
material to me if we want to do that at all.
2025-01-23 Jakub Jelinek <jakub@redhat.com>
PR middle-end/114877
* builtins.cc (fold_builtin_frexp): Handle rvc_nan and rvc_inf cases
like rvc_zero, return passed in arg and set *exp = 0.
* gcc.dg/torture/builtin-frexp-1.c: Add -Wmaybe-uninitialized as
dg-additional-options.
(bar): New function.
(TESTIT_FREXP2): Rework the macro so that it doesn't test whether
nothing has been stored to what the second argument points to, but
instead that something has been stored there, whatever it is.
(main): Temporarily don't enable the nan tests for -O0.
Jakub Jelinek [Fri, 17 Jan 2025 10:30:07 +0000 (11:30 +0100)]
match.pd: Fix (FTYPE) N CMP (FTYPE) M optimization for GENERIC [PR118522]
The last case of this optimization assumes that if 2 integral types
have same precision and TYPE_UNSIGNED, then they are uselessly convertible.
While that is very likely the case for GIMPLE, it is not the case for
GENERIC, so the following patch adds there a convert so that the
optimization produces also valid GENERIC. Without it we got
(int) p == b where b had _BitInt(32) type, so incompatible types.
2025-01-17 Jakub Jelinek <jakub@redhat.com>
PR tree-optimization/118522
* match.pd ((FTYPE) N CMP (FTYPE) M): Add convert, as in GENERIC
integral types with the same precision and sign might actually not
be compatible types.
Jakub Jelinek [Thu, 16 Jan 2025 08:17:50 +0000 (09:17 +0100)]
vec.h: Properly destruct elements in auto_vec auto storage [PR118400]
For T with non-trivial destructors, we were destructing objects in the
vector on release only when not using auto storage of auto_vec.
The following patch calls truncate (0) instead of m_vecpfx.m_num clearing,
and truncate takes care of that destruction:
unsigned l = length ();
gcc_checking_assert (l >= size);
if (!std::is_trivially_destructible <T>::value)
vec_destruct (address () + size, l - size);
m_vecpfx.m_num = size;
Dimitry Andric [Tue, 28 Jan 2025 17:36:16 +0000 (18:36 +0100)]
libgcc: On FreeBSD use GCC's crt objects for static linking
Add crtbeginT.o to extra_parts on FreeBSD. This ensures we use GCC's
crt objects for static linking. Otherwise it could mix crtbeginT.o
from the base system with libgcc's crtend.o, possibly leading to
segfaults.
libgcc:
PR target/118685
* config.host (*-*-freebsd*): Add crtbeginT.o to extra_parts.
Paul Thomas [Thu, 6 Feb 2025 16:40:19 +0000 (16:40 +0000)]
Fortran: FIx ICE in associate with elemental function [PR118750]
2025-02-06 Paul Thomas <pault@gcc.gnu.org>
gcc/fortran
PR fortran/118750
* resolve.cc (resolve_assoc_var): If the target expression has
a rank, do not use gfc_expression_rank, since it will return 0
if the function is elemental. Resolution will have produced the
correct rank.
gcc/testsuite/
PR fortran/118750
* gfortran.dg/associate_72.f90: New test.
Paul Thomas [Sat, 11 Jan 2025 08:23:48 +0000 (08:23 +0000)]
Fortran: Fix error recovery for bad component arrayspecs [PR108434]
2025-01-11 Paul Thomas <pault@gcc.gnu.org>
gcc/fortran/
PR fortran/108434
* class.cc (generate_finalization_wrapper): To avoid memory
leaks from callocs, return immediately if the derived type
error flag is set.
* decl.cc (build_struct): If the declaration of a derived type
or class component does not have a deferred arrayspec, correct,
set the error flag of the derived type and emit an immediate
error.
Harald Anlauf [Thu, 30 Jan 2025 21:21:19 +0000 (22:21 +0100)]
Fortran: host association issue with symbol in COMMON block [PR108454]
When resolving a flavorless symbol that is already registered with a COMMON
block, and which neither has the intrinsic, generic, or external attribute,
skip searching among interfaces to avoid false resolution to a derived type
of the same name.
PR fortran/108454
gcc/fortran/ChangeLog:
* resolve.cc (resolve_common_blocks): Initialize variable.
(resolve_symbol): If a symbol is already registered with a COMMON
block, do not search for an interface with the same name.
Lulu Cheng [Wed, 22 Jan 2025 09:57:21 +0000 (17:57 +0800)]
LoongArch: Fix ICE caused by illegal calls to builtin functions [PR118561].
PR target/118561
gcc/ChangeLog:
* config/loongarch/loongarch-builtins.cc
(loongarch_expand_builtin_lsx_test_branch):
NULL_RTX will not be returned when an error is detected.
(loongarch_expand_builtin): Likewise.
Paul Thomas [Wed, 6 Nov 2024 07:17:25 +0000 (07:17 +0000)]
Fortran: F2008 passing of internal procs to a proc pointer [PR117434]
2024-11-06 Paul Thomas <pault@gcc.gnu.org>
gcc/fortran
PR fortran/117434
* interface.cc (gfc_compare_actual_formal): Skip 'Expected a
procedure pointer error' if the formal argument typespec has an
interface and the type of the actual arg is BT_PROCEDURE.
gcc/testsuite/
PR fortran/117434
* gfortran.dg/proc_ptr_54.f90: New test. This is temporarily
compile-only until one one seven four five five is fixed.
* gfortran.dg/proc_ptr_55.f90: New test.
* gfortran.dg/proc_ptr_56.f90: New test.
Lewis Hyatt [Sun, 26 Jan 2025 23:57:00 +0000 (18:57 -0500)]
options: Adjust cl_optimization_compare to avoid checking ICE [PR115913]
At the end of a sequence like:
#pragma GCC push_options
...
#pragma GCC pop_options
the handler for pop_options calls cl_optimization_compare() (as generated by
optc-save-gen.awk) to make sure that all global state has been restored to
the value it had prior to the push_options call. The verification is
performed for almost all entries in the global_options struct. This leads to
unexpected checking asserts, as discussed in the PR, in case the state of
warnings-related options has been intentionally modified in between
push_options and pop_options via a call to #pragma GCC diagnostic. Address
that by skipping the verification for CL_WARNING-flagged options.
gcc/ChangeLog:
PR middle-end/115913
* optc-save-gen.awk (cl_optimization_compare): Skip options with
CL_WARNING flag.
gcc/testsuite/ChangeLog:
PR middle-end/115913
* c-c++-common/cpp/pr115913.c: New test.
Harald Anlauf [Sun, 26 Jan 2025 21:56:57 +0000 (22:56 +0100)]
Fortran: fix bogus diagnostics on renamed interface import [PR110993]
PR fortran/110993
gcc/fortran/ChangeLog:
* frontend-passes.cc (check_externals_procedure): Do not compare
interfaces of a non-bind(C) procedure against a bind(C) global one.
(check_against_globals): Use local name from rename-on-use in the
search for interfaces.
Harald Anlauf [Tue, 28 Jan 2025 20:21:40 +0000 (21:21 +0100)]
Fortran: fix passing of component ref to assumed-rank dummy [PR118683]
While the fix for pr117774 addressed the passing of an inquiry reference
to an assumed-rank dummy, it missed the similar case of passing a component
reference. The newer testcase gfortran.dg/pr81978.f90 uncovered this
latent issue with a UBSAN instrumented compiler.
PR fortran/118683
gcc/fortran/ChangeLog:
* trans-expr.cc (gfc_conv_procedure_call): The bounds update for
passing to assumed-rank dummies shall also handle component
references besides inquiry references.
The range adaptor perfect forwarding simplification mechanism is currently
only enabled for trivially copyable bound arguments, to prevent undesirable
copies of complex objects. But "trivially copyable" is the wrong property
to check for here, since a move-only type with a trivial move constructor
is considered trivially copyable, and after P2492R2 we can't assume copy
constructibility of the bound arguments. This patch makes the mechanism
more specifically check for trivial copy constructibility instead so
that it's properly disabled for move-only bound arguments.
PR libstdc++/118413
libstdc++-v3/ChangeLog:
* include/std/ranges (views::__adaptor::_Partial): Adjust
constraints on the "simple" partial specializations to require
is_trivially_copy_constructible_v instead of
is_trivially_copyable_v.
* testsuite/std/ranges/adaptors/adjacent_transform/1.cc (test04):
Extend P2494R2 test.
* testsuite/std/ranges/adaptors/transform.cc (test09): Likewise.
In c++/102990 we had a problem where massage_init_elt got {},
digest_nsdmi_init turned that {} into { .value = (int) 1.0e+0 },
and we crashed in the call to fold_non_dependent_init because
a FIX_TRUNC_EXPR/FLOAT_EXPR got into tsubst*. So we avoided
calling fold_non_dependent_init for a CONSTRUCTOR.
But that broke the following test, where we no longer fold the
CONST_DECL in
{ .type = ZERO }
to
{ .type = 0 }
and then process_init_constructor_array does:
if (next != error_mark_node
&& (initializer_constant_valid_p (next, TREE_TYPE (next))
!= null_pointer_node))
{
/* Use VEC_INIT_EXPR for non-constant initialization of
trailing elements with no explicit initializers. */
picflags |= PICFLAG_VEC_INIT;
because { .type = ZERO } isn't initializer_constant_valid_p. Then we
create a VEC_INIT_EXPR and say we can't convert the argument.
So we have to fold the elements of the CONSTRUCTOR. We just can't
instantiate the elements in a template.
This also fixes c++/118047.
PR c++/118047
PR c++/118355
gcc/cp/ChangeLog:
* typeck2.cc (massage_init_elt): Call fold_non_dependent_init
unless for a CONSTRUCTOR in a template.
gcc/testsuite/ChangeLog:
* g++.dg/cpp0x/nsdmi-list10.C: New test.
* g++.dg/cpp0x/nsdmi-list9.C: New test.
Patrick Palka [Tue, 28 Jan 2025 14:27:02 +0000 (09:27 -0500)]
c++: friend vs inherited guide confusion [PR117855]
We recently started using the lang_decl_fn::context field to track
inheritedness of a deduction guide (for C++23 inherited CTAD). This
new overloading of the field accidentally made DECL_FRIEND_CONTEXT
return non-NULL for inherited guides, which breaks the below testcase
during overload resolution with an inherited guide.
This patch fixes this by refining DECL_FRIEND_CONTEXT appropriately.
Tamar Christina [Thu, 16 Jan 2025 19:23:50 +0000 (19:23 +0000)]
AArch64: don't override march to assembler with mcpu if march is specified [PR110901]
When both -mcpu and -march are specified, the value of -march wins out.
This is done correctly for the calls to cc1 and for the assembler directives we
put out in assembly files.
However in the call to as we don't do this and instead use the arch from the
cpu. This leads to a situation that GCC cannot reliably be used to compile
assembly files which don't have a .arch directive.
This is quite common with .S files which use macros to selectively enable
codepath based on what the preprocessor sees.
The fix is to change MCPU_TO_MARCH_SPEC to not override the march if an march
is already specified.
gcc/ChangeLog:
PR target/110901
* config/aarch64/aarch64.h (MCPU_TO_MARCH_SPEC): Don't override if
march is set.
gcc/testsuite/ChangeLog:
PR target/110901
* gcc.target/aarch64/options_set_29.c: New test.
This has worked great but was only added for homogenous systems.
However the same thing works for big.LITTLE as in such system the cores must
have the same extensions otherwise it doesn't fundamentally work.
i.e. task migration from one core to the other wouldn't work.
This extends the same handling to non-homogenous systems.
gcc/ChangeLog:
PR target/113257
* config/aarch64/driver-aarch64.cc (get_cpu_from_id, DEFAULT_CPU): New.
(host_detect_local_cpu): Use it.
gcc/testsuite/ChangeLog:
PR target/113257
* gcc.target/aarch64/cpunative/info_34: New test.
* gcc.target/aarch64/cpunative/native_cpu_34.c: New test.
* gcc.target/aarch64/cpunative/info_35: New test.
* gcc.target/aarch64/cpunative/native_cpu_35.c: New test.
The FakeStack flag is not zeroed out when can_store_by_pieces()
returns false. Over time, this causes FakeStack::Allocate() to perform
the maximum number of loop iterations, significantly slowing down the
instrumented program.
As reported in PR118185, std::ranges::clamp does not correctly forward
the projected value to the comparator. Add the missing forward.
libstdc++-v3/ChangeLog:
PR libstdc++/118185
PR libstdc++/100249
* include/bits/ranges_algo.h (__clamp_fn): Correctly forward the
projected value to the comparator.
* testsuite/25_algorithms/clamp/118185.cc: New test.
Signed-off-by: Giuseppe D'Angelo <giuseppe.dangelo@kdab.com> Reviewed-by: Patrick Palka <ppalka@redhat.com> Reviewed-by: Jonathan Wakely <jwakely@redhat.com>
(cherry picked from commit b342614139c0a981b369176980663941b9c27f39)
Patrick Palka [Thu, 16 Jan 2025 21:40:08 +0000 (16:40 -0500)]
c++: explicit spec of constrained member tmpl [PR107522]
When defining a explicit specialization of a constrained member template
(of a class template) such as f and g in the below testcase, the
DECL_TEMPLATE_PARMS of the corresponding TEMPLATE_DECL are partially
instantiated, whereas its associated constraints are carried over
from the original template and thus are in terms of the original
DECL_TEMPLATE_PARMS. So during normalization for such an explicit
specialization we need to consider the (parameters of) the most general
template, since that's what the constraints are in terms of and since we
always use the full set of template arguments during satisfaction.
PR c++/107522
gcc/cp/ChangeLog:
* constraint.cc (get_normalized_constraints_from_decl): Use the
most general template for an explicit specialization of a
member template.
gcc/testsuite/ChangeLog:
* g++.dg/cpp2a/concepts-explicit-spec7.C: New test.
Harald Anlauf [Sun, 19 Jan 2025 20:06:56 +0000 (21:06 +0100)]
Fortran: do not copy back for parameter actual arguments [PR81978]
When an array is packed for passing as an actual argument, and the array
has the PARAMETER attribute (i.e., it is a named constant that can reside
in read-only memory), do not copy back (unpack) from the temporary.
PR fortran/81978
gcc/fortran/ChangeLog:
* trans-array.cc (gfc_conv_array_parameter): Do not copy back data
if actual array parameter has the PARAMETER attribute.
* trans-expr.cc (gfc_conv_subref_array_arg): Likewise.
Marek Polacek [Mon, 25 Nov 2024 14:45:13 +0000 (09:45 -0500)]
c++: ICE with nested anonymous union [PR117153]
In a template, for
union {
union {
T d;
};
};
build_anon_union_vars crates a malformed COMPONENT_REF: we have no
DECL_NAME for the nested anon union so we create something like "object.".
Most of the front end doesn't seem to care, but if such a tree gets to
potential_constant_expression, it can cause a crash.
We can use FIELD directly for the COMPONENT_REF's member. tsubst_stmt
should build up a proper one in:
if (VAR_P (decl) && !DECL_NAME (decl)
&& ANON_AGGR_TYPE_P (TREE_TYPE (decl)))
/* Anonymous aggregates are a special case. */
finish_anon_union (decl);
PR c++/117153
gcc/cp/ChangeLog:
* decl2.cc (build_anon_union_vars): Use FIELD for the second operand
of a COMPONENT_REF.
gcc/testsuite/ChangeLog:
* g++.dg/other/anon-union6.C: New test.
* g++.dg/other/anon-union7.C: New test.
Peter Bergner [Thu, 16 Jan 2025 16:49:45 +0000 (10:49 -0600)]
rs6000: Fix loop limit for built-in constant checking
The loop checking for built-in constant operand restrictions was missing
some operands due to the loop limit being too small. Fixing that exposed
a testsuite failure which is caused by a typo in the pmxvi4ger8pp definition
where we had made the PMASK field too small.
2025-01-16 Peter Bergner <bergner@linux.ibm.com>
gcc/
* config/rs6000/rs6000-builtin.cc (rs6000_expand_builtin): Use correct
array size for the loop limit.
* config/rs6000/rs6000-builtins.def: Fix field size for PMASK operand.
as a nop. This PR shows that that isn't always correct.
The compare in the set above is between two 0/1 booleans (at least
on STORE_FLAG_VALUE==1 targets), whereas the unknown comparison that
produced the incoming (reg:CC cc) is unconstrained; it could be between
arbitrary integers, or even floats. The fold is therefore replacing a
cc that is valid for both signed and unsigned comparisons with one that
is only known to be valid for signed comparisons.
(gt (compare (gt cc 0) (lt cc 0) 0)
does simplify to:
(gt cc 0)
but:
(gtu (compare (gt cc 0) (lt cc 0) 0)
does not simplify to:
(gtu cc 0)
The optimisation didn't come with a testcase, but it was added for
i386's cmpstrsi, now cmpstrnsi. That probably doesn't matter as much
as it once did, since it's now conditional on -minline-all-stringops.
But the patch is almost 25 years old, so whatever the original
motivation was, it seems likely that other things now rely on it.
It therefore seems better to try to preserve the optimisation on rtl
rather than get rid of it. To do that, we need to look at how the
result of the outer compare is used. We'd therefore be looking at four
instructions (the gt, the lt, the compare, and the use of the compare),
but combine already allows that for 3-instruction combinations thanks
to:
/* If the source is a COMPARE, look for the use of the comparison result
and try to simplify it unless we already have used undobuf.other_insn. */
When applied to boolean inputs, a comparison operator is
effectively a boolean logical operator (AND, ANDNOT, XOR, etc.).
simplify_logical_relational_operation already had code to simplify
logical operators between two comparison results, but:
* It only handled IOR, which doesn't cover all the cases needed here.
The others are easily added.
* It treated comparisons of integers as having an ORDERED/UNORDERED result.
Therefore:
* it would not treat "true for LT + EQ + GT" as "always true" for
comparisons between integers, because the mask excluded the UNORDERED
condition.
* it would try to convert "true for LT + GT" into LTGT even for comparisons
between integers. To prevent an ICE later, the code used:
/* Many comparison codes are only valid for certain mode classes. */
if (!comparison_code_valid_for_mode (code, mode))
return 0;
However, this used the wrong mode, since "mode" is here the integer
result of the comparisons (and the mode of the IOR), not the mode of
the things being compared. Thus the effect was to reject all
floating-point-only codes, even when comparing floats.
I think instead the code should detect whether the comparison is between
integer values and remove UNORDERED from consideration if so. It then
always produces a valid comparison (or an always true/false result),
and so comparison_code_valid_for_mode is not needed. In particular,
"true for LT + GT" becomes NE for comparisons between integers but
remains LTGT for comparisons between floats.
* There was a missing check for whether the comparison inputs had
side effects.
While there, it also seemed worth extending
simplify_logical_relational_operation to unsigned comparisons, since
that makes the testing easier.
As far as that testing goes: the patch exhaustively tests all
combinations of integer comparisons in:
(cmp1 (cmp2 X Y) (cmp3 X Y))
for the 10 integer comparisons, giving 1000 fold attempts in total.
It then tries all combinations of (X in {-1,0,1} x Y in {-1,0,1})
on the result of the fold, giving 9 checks per fold, or 9000 in total.
That's probably more than is typical for self-tests, but it seems to
complete in neglible time, even for -O0 builds.
gcc/
PR rtl-optimization/117186
* rtl.h (simplify_context::simplify_logical_relational_operation): Add
an invert0_p parameter.
* simplify-rtx.cc (unsigned_comparison_to_mask): New function.
(mask_to_unsigned_comparison): Likewise.
(comparison_code_valid_for_mode): Delete.
(simplify_context::simplify_logical_relational_operation): Add
an invert0_p parameter. Handle AND and XOR. Handle unsigned
comparisons. Handle always-false results. Ignore the low bit
of the mask if the operands are always ordered and remove the
then-redundant check of comparison_code_valid_for_mode. Check
for side-effects in the operands before simplifying them away.
(simplify_context::simplify_binary_operation_1): Remove
simplification of (compare (gt ...) (lt ...)) and instead...
(simplify_context::simplify_relational_operation_1): ...handle
comparisons of comparisons here.
(test_comparisons): New function.
(test_scalar_ops): Call it.
gcc/testsuite/
PR rtl-optimization/117186
* gcc.dg/torture/pr117186.c: New test.
* gcc.target/aarch64/pr117186.c: Likewise.
aarch64: Detect word-level modification in early-ra [PR118184]
REGMODE_NATURAL_SIZE is set to 64 bits for everything except
VLA SVE modes. This means that it's possible to modify (say)
the highpart of a TI pseudo or a V2DI pseudo independently
of the lowpart. Modifying such highparts requires a reload
if the highpart ends up in the upper 64 bits of an FPR,
since RTL semantics do not allow the highpart of a single
hard register to be modified independently of the lowpart.
early-ra missed a check for this case, which meant that it
effectively treated an assignment to (subreg:DI (reg:TI R) 0)
as an assignment to the whole of R.
gcc/
PR target/118184
* config/aarch64/aarch64-early-ra.cc (allocno_assignment_is_rmw):
New function.
(early_ra::record_insn_defs): Mark the live range information as
untrustworthy if an assignment would change part of an allocno
but preserve the rest.
gcc/testsuite/
* gcc.dg/torture/pr118184.c: New test.
Jakub Jelinek [Tue, 21 Jan 2025 23:18:24 +0000 (00:18 +0100)]
c++: Wrap force_target_expr in get_member_function_from_ptrfunc with save_expr [PR118509]
My October PR117259 fix to get_member_function_from_ptrfunc to use a
TARGET_EXPR rather than SAVE_EXPR unfortunately caused some regressions as
well as the following testcase shows.
What happens is that
get_member_function_from_ptrfunc -> build_base_path calls save_expr,
so since the PR117259 change in mnay cases it will call save_expr on
a TARGET_EXPR. And, for some strange reason a TARGET_EXPR is not considered
an invariant, so we get a SAVE_EXPR wrapped around the TARGET_EXPR.
That SAVE_EXPR <TARGET_EXPR <...>> gets initially added only to the second
operand of ?:, so at that point it would still work fine during expansion.
But unfortunately an expression with that subexpression is handed to the
caller also through *instance_ptrptr = instance_ptr; and gets evaluated
once again when computing the first argument to the method.
So, essentially, we end up with
(TARGET_EXPR <D.2907, ...>, (... ? ... SAVE_EXPR <TARGET_EXPR <D.2907, ...>
... : ...)) (... SAVE_EXPR <TARGET_EXPR <D.2907, ...> ..., ...);
and while D.2907 is initialized during gimplification in the code dominating
everything that uses it, the extra temporary created for the SAVE_EXPR
is initialized only conditionally (if the ?: condition is true) but then
used unconditionally, so we get
pmf-4.C: In function ‘void foo(C, B*)’:
pmf-4.C:12:11: warning: ‘<anonymous>’ may be used uninitialized [-Wmaybe-uninitialized]
12 | (y->*x) ();
| ~~~~~~~~^~
pmf-4.C:12:11: note: ‘<anonymous>’ was declared here
12 | (y->*x) ();
| ~~~~~~~~^~
diagnostic and wrong-code issue too.
As the trunk fix to just treat TARGET_EXPR as invariant seems a little bit risky
and I'd like to get it tested on the trunk for a while, for 14.2.1 this patch
instead wraps those TARGET_EXPRs into SAVE_EXPRs. Eventually that can be reverted
and the trunk fix backported.
2025-01-21 Jakub Jelinek <jakub@redhat.com>
PR c++/118509
* typeck.cc (get_member_function_from_ptrfunc): Wrap force_target_expr
with save_expr.
Nathaniel Shead [Fri, 17 Jan 2025 10:29:08 +0000 (21:29 +1100)]
c++/modules: Propagate FNDECL_USED_AUTO when propagating deduced return types [PR118049]
In the linked testcase, we're erroring because the declared return types
of the functions do not appear to match. This is because when merging
the deduced return types for 'foo' in 'auto-5_b.C', we overwrote the
return type for the declaration with the deduced return type from
'auto-5_a.C' but neglected to track that we were originally declared
with 'auto'.
As a drive-by improvement to QOI, also add checks for if the deduced
return types do not match; this is currently useful because we do not
check the equivalence of the bodies of functions yet.
PR c++/118049
gcc/cp/ChangeLog:
* module.cc (trees_in::is_matching_decl): Propagate
FNDECL_USED_AUTO as well.
gcc/testsuite/ChangeLog:
* g++.dg/modules/auto-5_a.C: New test.
* g++.dg/modules/auto-5_b.C: New test.
* g++.dg/modules/auto-5_c.C: New test.
* g++.dg/modules/auto-6_a.H: New test.
* g++.dg/modules/auto-6_b.C: New test.
Iain Buclaw [Mon, 20 Jan 2025 19:01:03 +0000 (20:01 +0100)]
d: Fix failing test with 32-bit compiler [PR114434]
Since the introduction of gdc.test/runnable/test23514.d, it's exposed an
incorrect compilation when adding a 64-bit constant to a link-time
address. The current cast to size_t causes a loss of precision, which
can result in incorrect compilation.
PR d/114434
gcc/d/ChangeLog:
* expr.cc (ExprVisitor::visit (PtrExp *)): Get the offset as a
dinteger_t rather than a size_t.
(ExprVisitor::visit (SymOffExp *)): Likewise.
Uros Bizjak [Fri, 20 Dec 2024 15:16:15 +0000 (16:16 +0100)]
i386: Disable SImode/DImode moves from/to mask regs without avx512bw [PR118067]
SImode and DImode moves from/to mask registers are valid only with AVX512BW,
so mark relevant alternatives in *movsi_internal and *movdi_internal as such.
Even with the patch, the testcase still fails, but now with:
pr118067.c: In function ‘foo’:
pr118067.c:13:1: internal compiler error: maximum number of generated reload insns per insn achieved (90)
13 | }
| ^
0x2c3b581 internal_error(char const*, ...)
../../git/gcc/gcc/diagnostic-global-context.cc:517
0xb68938 lra_constraints(bool)
../../git/gcc/gcc/lra-constraints.cc:5411
0xb51a0d lra(_IO_FILE*, int)
../../git/gcc/gcc/lra.cc:2449
0xaf9f4d do_reload
../../git/gcc/gcc/ira.cc:5977
0xafa462 execute
../../git/gcc/gcc/ira.cc:6165
Simon Martin [Sun, 5 Jan 2025 09:36:47 +0000 (10:36 +0100)]
c++: Friend classes don't shadow enclosing template class paramater [PR118255]
We currently reject the following code
=== code here ===
template <int non_template> struct S { friend class non_template; };
class non_template {};
S<0> s;
=== code here ===
While EDG agrees with the current behaviour, clang and MSVC don't (see
https://godbolt.org/z/69TGaabhd), and I believe that this code is valid,
since the friend clause does not actually declare a type, so it cannot
shadow anything. The fact that we didn't error out if the non_template
class was declared before S backs this up as well.
This patch fixes this by skipping the call to check_template_shadow for
hidden bindings.
PR c++/118255
gcc/cp/ChangeLog:
* name-lookup.cc (pushdecl): Don't call check_template_shadow
for hidden bindings.
gcc/testsuite/ChangeLog:
* g++.dg/lookup/pr99116-1.C: Adjust test expectation.
* g++.dg/template/friend84.C: New test.
Nathaniel Shead [Fri, 20 Dec 2024 11:09:39 +0000 (22:09 +1100)]
c++: Allow pragmas in NSDMIs [PR118147]
This patch removes the (unnecessary) CPP_PRAGMA_EOL case from
cp_parser_cache_defarg, which currently has the result that any pragmas
in the NSDMI cause an error.
PR c++/118147
gcc/cp/ChangeLog:
* parser.cc (cp_parser_cache_defarg): Don't error when
CPP_PRAGMA_EOL.
Simon Martin [Thu, 16 Jan 2025 15:27:06 +0000 (16:27 +0100)]
c++: Make sure fold_sizeof_expr returns the correct type [PR117775]
We currently ICE upon the following code, that is valid under
-Wno-pointer-arith:
=== cut here ===
int main() {
decltype( [](auto) { return sizeof(void); } ) x;
return x.operator()(0);
}
=== cut here ===
The problem is that "fold_sizeof_expr (sizeof(void))" returns
size_one_node, that has a different TREE_TYPE from that of the sizeof
expression, which later triggers an assert in cxx_eval_store_expression.
This patch makes sure that fold_sizeof_expr always returns a tree with
the size_type_node type.
PR c++/117775
gcc/cp/ChangeLog:
* decl.cc (fold_sizeof_expr): Make sure the folded result has
type size_type_node.
Eugene Rozenfeld [Sat, 11 Jan 2025 03:48:52 +0000 (19:48 -0800)]
Fix setting of call graph node AutoFDO count
We are initializing both the call graph node count and
the entry block count of the function with the head_count value
from the profile.
Count propagation algorithm may refine the entry block count
and we may end up with a case where the call graph node count
is set to zero but the entry block count is non-zero. That becomes
a problem because we have this code in execute_fixup_cfg:
profile_count num = node->count;
profile_count den = ENTRY_BLOCK_PTR_FOR_FN (cfun)->count;
bool scale = num.initialized_p () && !(num == den);
Here if num is 0 but den is not 0, scale becomes true and we
lose the counts in
if (scale)
bb->count = bb->count.apply_scale (num, den);
This is what happened in the issue reported in PR116743
(a 10% regression in MySQL HAMMERDB tests). 3d9e6767939e9658260e2506e81ec32b37cba041 made an improvement in
AutoFDO count propagation, which caused a mismatch between
the call graph node count (zero) and the entry block count (non-zero)
and subsequent loss of counts as described above.
The fix is to update the call graph node count once we've done count propagation.
Tested on x86_64-pc-linux-gnu.
gcc/ChangeLog:
PR gcov-profile/116743
* auto-profile.cc (afdo_annotate_cfg): Fix mismatch between the call graph node count
and the entry block count.
Iain Buclaw [Thu, 16 Jan 2025 23:23:45 +0000 (00:23 +0100)]
d: Fix record layout of compiler-generated TypeInfo_Class [PR115249]
In r14-8766, the layout of TypeInfo_Class changed in the runtime
library, but didn't get reflected in the compiler-generated data,
causing a corruption of runtime type introspection on BigEndian targets.
This adjusts the size of the `ClassFlags' field from uint to ushort, and
adds a new ushort `depth' field in the space where ClassFlags used to
occupy.
Jonathan Wakely [Fri, 27 Sep 2024 20:01:46 +0000 (21:01 +0100)]
libstdc++: Fix more pedwarns in headers for C++98
Some tests e.g. 17_intro/headers/c++1998/all_pedantic_errors.cc FAIL
with GLIBCXX_TESTSUITE_STDS=98 due to numerous C++11 extensions still in
use in the library headers. The recent changes to not make them system
headers means we get warnings now.
This change adds more diagnostic pragmas to suppress those warnings.
libstdc++-v3/ChangeLog:
* include/bits/istream.tcc: Add diagnostic pragmas around uses
of long long and extern template.
* include/bits/locale_facets.h: Likewise.
* include/bits/locale_facets.tcc: Likewise.
* include/bits/locale_facets_nonio.tcc: Likewise.
* include/bits/ostream.tcc: Likewise.
* include/bits/stl_algobase.h: Likewise.
* include/c_global/cstdlib: Likewise.
* include/ext/pb_ds/detail/resize_policy/hash_prime_size_policy_imp.hpp:
Likewise.
* include/ext/pointer.h: Likewise.
* include/ext/stdio_sync_filebuf.h: Likewise.
* include/std/istream: Likewise.
* include/std/ostream: Likewise.
* include/tr1/cmath: Likewise.
* include/tr1/type_traits: Likewise.
* include/tr1/functional_hash.h: Likewise. Remove semi-colons
at namespace scope that aren't needed after macro expansion.
* include/tr1/tuple: Remove semi-colon at namespace scope.
* include/bits/vector.tcc: Change LL suffix to just L.
We have several overloads of std::deque::_M_insert_aux, one of which is
variadic and called by std::deque::emplace. With a suitable set of
arguments to emplace, it's possible for one of the non-variadic
_M_insert_aux overloads to be selected by overload resolution, making
emplace ill-formed.
Rename the variadic _M_insert_aux to _M_emplace_aux so that calls to
emplace never select an _M_insert_aux overload. Also add an inline
_M_insert_aux for the const lvalue overload that is called from
insert(const_iterator, const value_type&).
Match-and-simplified .COND_IOR (_41, d_lsm.7_11, _46, d_lsm.7_11) to 1
when _46 == 1. This happens by removing the conditional and applying
a | 1 = 1. Normally we re-introduce the conditional and its else value
if needed but that does not happen here as we're not dealing with a
vector type. For correctness's sake, we must not remove the conditional
even for non-vector types.
This patch re-introduces a COND_EXPR in such cases. For PR118140 this
result in a non-vectorized loop.
PR middle-end/118140
gcc/ChangeLog:
* gimple-match-exports.cc (maybe_resimplify_conditional_op): Add
COND_EXPR when we simplified to a scalar gimple value but still
have an else value.
gcc/testsuite/ChangeLog:
* gcc.dg/vect/pr118140.c: New test.
* gcc.target/riscv/rvv/autovec/pr118140.c: New test.
testsuite: The expect framework might introduce CR in output
When running tests using the "sim" config, the command is launched in
non-readonly mode and the text retrieved from the expect command will
then replace all LF with CRLF. (The problem can be found in sim_load
where it calls remote_spawn without an input file).
libstdc++-v3/ChangeLog:
* testsuite/27_io/print/1.cc: Allow both LF and CRLF in test.
* testsuite/27_io/print/3.cc: Likewise.
Nathaniel Shead [Sat, 11 Jan 2025 17:35:08 +0000 (04:35 +1100)]
testsuite: Fix flag used for modules test
GCC14 doesn't have the new spelling '-fmodules' for enabling modules;
use the old '-fmodules-ts' spelling instead.
gcc/testsuite/ChangeLog:
* g++.dg/modules/pr114630_a.C: Use -fmodules-ts instead of
-fmodules in testcase.
* g++.dg/modules/pr114630_b.C: Likewise.
* g++.dg/modules/pr114630_c.C: Likewise.
Nathaniel Shead [Thu, 9 Jan 2025 14:06:37 +0000 (01:06 +1100)]
c++/modules: Handle chaining already-imported local types [PR114630]
In the linked testcase, an ICE occurs because when reading the
(duplicate) function definition for _M_do_parse from module Y, the local
type definitions have already been streamed from module X and setup as
regular backreferences, rather than being found with find_duplicate,
causing issues with managing DECL_CHAIN.
It is tempting to just skip setting up the DECL_CHAIN for this case.
However, for the future it would be best to ensure that the block vars
for the duplicate definition are accurate, so that we could implement
ODR checking on function definitions at some point.
So to solve this, this patch creates a copy of the streamed-in local
type and chains that; it will be discarded along with the rest of the
duplicate function after we've finished processing.
A couple of suggested implementations from the discussion on the PR that
don't work:
- Replacing the `DECL_CHAIN` assertion with `(*chain && *chain != decl)`
doesn't handle the case where type definitions are followed by regular
local variables, since those won't have been imported as separate
backreferences and so the chains will diverge.
- Correcting the purviewness of GMF template instantiations to force Y
to emit copies of the local types rather than backreferences into X is
insufficient, as it's still possible that the local types got streamed
in a separate cluster to the function definition, and so will be again
referred to via regular backreferences when importing.
- Likewise, preventing the emission of function definitions where an
import has already provided that same definition also is insufficient,
for much the same reason.
PR c++/114630
gcc/cp/ChangeLog:
* module.cc (trees_in::core_vals) <BLOCK>: Chain a new node if
DECL_CHAIN already is set.
gcc/testsuite/ChangeLog:
* g++.dg/modules/pr114630.h: New test.
* g++.dg/modules/pr114630_a.C: New test.
* g++.dg/modules/pr114630_b.C: New test.
* g++.dg/modules/pr114630_c.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>
In GCC 12 there was a ~40% regression in the performance of hashmap->find.
This regression came about accidentally:
Before GCC 12 the find function was small enough that IPA would inline it even
though it wasn't marked inline. In GCC-12 an optimization was added to perform
a linear search when the entries in the hashmap are small.
This increased the size of the function enough that IPA would no longer inline.
Inlining had two benefits:
1. The return value is a reference. so it has to be returned and dereferenced
even though the search loop may have already dereference it.
2. The pattern is a hard pattern to track for branch predictors. This causes
a large number of branch misses if the value is immediately checked and
branched on. i.e. if (a != m.end()) which is a common pattern.
The patch fixes both these issues by adding the inline keyword to _M_locate
to allow the inliner to consider inlining again.
This and the other patches have been ran through serveral benchmarks where
the size, number of elements searched for and type (reference vs value) etc
were tested.
The change shows no statistical regression, but an average find improvement of
~27% and a range between ~10-60% improvements.
testsuite: arm: Add pattern for armv8-m.base to cmse-15.c test
Since armv8-m.base uses thumb1 that does not suport sibcall/tailcall,
a pattern is needed that uses PUSH/BL/POP sequence instead of a single
B instruction to reuse an already existing function in the compile unit.
gcc/testsuite/ChangeLog:
* gcc.target/arm/cmse/cmse-15.c: Added pattern for armv8-m.base.
Andrew Carlotti [Tue, 7 Jan 2025 18:32:23 +0000 (18:32 +0000)]
Disable a broken multiversioning optimisation
This patch skips redirect_to_specific clone for aarch64 and riscv,
because the optimisation has two flaws:
1. It checks the value of the "target" attribute, even on targets that
don't use this attribute for multiversioning.
2. The algorithm used is too aggressive, and will eliminate the
indirection in some cases where the runtime choice of callee version
can't be determined statically at compile time. A correct would need to
verify that:
- if the current caller version were selected at runtime, then the
chosen callee version would be eligible for selection.
- if any higher priority callee version were selected at runtime, then
a higher priority caller version would have been eligble for
selection (and hence the current caller version wouldn't have been
selected).
The current checks only verify a more restrictive version of the first
condition, and don't check the second condition at all.
Fixing the optimisation properly would require implementing target hooks
to check for implications between version attributes, which is too
complicated for this stage. However, I would like to see this hook
implemented in the future, since it could also help deduplicate other
multiversioning code.
Since this behavior has existed for x86 and powerpc for a while, I
think it's best to preserve the existing behavior on those targets,
unless any maintainer for those targets disagrees.
gcc/ChangeLog:
* multiple_target.cc
(redirect_to_specific_clone): Assert that "target" attribute is
used for FMV before checking it.
(ipa_target_clone): Skip redirect_to_specific_clone on some
targets.
Richard Biener [Thu, 5 Dec 2024 09:47:13 +0000 (10:47 +0100)]
tree-optimization/117912 - bogus address equivalences for __builtin_object_size
VN again is the culprit for exploiting address equivalences before
__builtin_object_size got the chance to do its job. This time
it isn't about union members but adjacent structure fields where
an address to one after the last element of an array field can
spill over to the next field.
The following protects all out-of-bound accesses on the upper bound
side (singling out TYPE_MAX_VALUE + 1 is more expensive). It
ignores other out-of-bound addresses that would invoke UB.
Zero-sized arrays are a bit awkward because the C++ represents them
with a -1U upper bound.
There's a similar issue for zero-sized components whose address can
be the same as the adjacent field in C.
PR tree-optimization/117912
* tree-ssa-sccvn.cc (copy_reference_ops_from_ref): For addresses
of zero-sized components do not set ->off if the object size pass
didn't run.
For OOB ARRAY_REF accesses in address expressions avoid setting
->off if the object size pass didn't run.
(valueize_refs_1): Likewise.
* c-c++-common/torture/pr117912-1.c: New testcase.
* c-c++-common/torture/pr117912-2.c: Likewise.
* c-c++-common/torture/pr117912-3.c: Likewise.
This member function was previously deprecated, but that was reverted by
P2875R4, approved earlier this year in Tokyo. Since it's not going to be
deprecated in C++26, and so presumably not removed, there is no point in
giving deprecated warnings for C++23 mode.
Jonathan Wakely [Thu, 11 Apr 2024 18:12:48 +0000 (19:12 +0100)]
libstdc++: Give std::memory_order a fixed underlying type [PR89624]
Prior to C++20 this enum type doesn't have a fixed underlying type,
which means it can be modified by -fshort-enums, which then means the
HLE bits are outside the range of valid values for the type.
As it has a fixed type of int in C++20 and later, do the same for
earlier standards too. This is technically a change for C++17 down,
because the implicit underlying type (without -fshort-enums) was
unsigned before. I doubt it matters in practice. That incompatibility
already exists between C++17 and C++20 and nobody has noticed or
complained. Now at least the underlying type will be int for all -std
modes.
libstdc++-v3/ChangeLog:
PR libstdc++/89624
* include/bits/atomic_base.h (memory_order): Use int as
underlying type.
* testsuite/29_atomics/atomic/89624.cc: New test.