aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog4
-rw-r--r--MAINTAINERS1
-rw-r--r--contrib/ChangeLog10
-rwxr-xr-xcontrib/check_GNU_style_lib.py3
-rwxr-xr-xcontrib/test_installed19
-rw-r--r--gcc/ChangeLog76
-rw-r--r--gcc/DATESTAMP2
-rw-r--r--gcc/ada/ChangeLog6
-rw-r--r--gcc/ada/rtfinal.c2
-rw-r--r--gcc/ada/rtinit.c3
-rw-r--r--gcc/cgraph.cc6
-rw-r--r--gcc/cgraphclones.cc4
-rw-r--r--gcc/config/aarch64/aarch64-cores.def5
-rw-r--r--gcc/config/aarch64/aarch64-simd.md12
-rw-r--r--gcc/config/aarch64/aarch64-tune.md2
-rw-r--r--gcc/config/mingw/winnt.cc10
-rw-r--r--gcc/cp/ChangeLog10
-rw-r--r--gcc/cp/decl.cc6
-rw-r--r--gcc/cp/decl2.cc5
-rw-r--r--gcc/cp/pt.cc7
-rw-r--r--gcc/cp/semantics.cc4
-rw-r--r--gcc/doc/invoke.texi3
-rw-r--r--gcc/fortran/ChangeLog9
-rw-r--r--gcc/fortran/decl.cc4
-rw-r--r--gcc/testsuite/ChangeLog55
-rw-r--r--gcc/testsuite/g++.dg/modules/tpl-friend-22.C24
-rw-r--r--gcc/testsuite/g++.dg/template/sfinae-deleted-pr119343.C31
-rw-r--r--gcc/testsuite/g++.dg/torture/pr123040.C61
-rw-r--r--gcc/testsuite/gcc.dg/tls/data-sections-1.c14
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/pr46555.c28
-rw-r--r--gcc/testsuite/gcc.dg/vect/pr123038.c8
-rw-r--r--gcc/testsuite/gcc.target/aarch64/pr123026.c21
-rw-r--r--gcc/testsuite/gcc.target/i386/avx2-vpcmpgtq-1.c2
-rw-r--r--gcc/testsuite/gfortran.dg/assumed_charlen_dummy.f901
-rw-r--r--gcc/testsuite/gfortran.dg/automatic_char_len_1.f901
-rw-r--r--gcc/testsuite/gfortran.dg/entry_23.f1
-rw-r--r--gcc/testsuite/gfortran.dg/finalize_59.f904
-rw-r--r--gcc/testsuite/gfortran.dg/g77/f90-intrinsic-bit.f1
-rw-r--r--gcc/testsuite/gfortran.dg/g77/f90-intrinsic-mathematical.f1
-rw-r--r--gcc/testsuite/gfortran.dg/g77/f90-intrinsic-numeric.f1
-rw-r--r--gcc/testsuite/gfortran.dg/g77/intrinsic-unix-bessel.f1
-rw-r--r--gcc/testsuite/gfortran.dg/g77/intrinsic-unix-erf.f1
-rw-r--r--gcc/testsuite/gfortran.dg/initialization_9.f901
-rw-r--r--gcc/testsuite/gfortran.dg/intrinsic_actual_4.f901
-rw-r--r--gcc/testsuite/gfortran.dg/namelist_assumed_char.f902
-rw-r--r--gcc/testsuite/gfortran.dg/pr15140.f901
-rw-r--r--gcc/tree-cfg.cc218
-rw-r--r--gcc/tree-cfg.h1
-rw-r--r--gcc/tree-cfgcleanup.cc9
-rw-r--r--gcc/tree-ssa-dce.cc212
-rw-r--r--gcc/tree-ssa-sccvn.cc5
-rw-r--r--gcc/tree-vect-patterns.cc14
-rw-r--r--gcc/tree-vect-stmts.cc49
-rw-r--r--libstdc++-v3/ChangeLog68
-rw-r--r--libstdc++-v3/include/Makefile.am1
-rw-r--r--libstdc++-v3/include/Makefile.in1
-rw-r--r--libstdc++-v3/include/bits/intcmp.h120
-rw-r--r--libstdc++-v3/include/bits/iterator_concepts.h4
-rw-r--r--libstdc++-v3/include/bits/max_size_type.h6
-rw-r--r--libstdc++-v3/include/bits/sat_arith.h12
-rw-r--r--libstdc++-v3/include/bits/version.def6
-rw-r--r--libstdc++-v3/include/bits/version.h4
-rw-r--r--libstdc++-v3/include/c_compatibility/stdckdint.h32
-rw-r--r--libstdc++-v3/include/ext/numeric_traits.h2
-rw-r--r--libstdc++-v3/include/std/charconv6
-rw-r--r--libstdc++-v3/include/std/concepts23
-rw-r--r--libstdc++-v3/include/std/latch2
-rw-r--r--libstdc++-v3/include/std/mdspan8
-rw-r--r--libstdc++-v3/include/std/type_traits13
-rw-r--r--libstdc++-v3/include/std/utility72
-rw-r--r--libstdc++-v3/include/std/variant34
-rw-r--r--libstdc++-v3/libsupc++/compare7
-rw-r--r--libstdc++-v3/testsuite/20_util/integer_comparisons/extended.cc60
-rw-r--r--libstdc++-v3/testsuite/20_util/variant/112591.cc32
-rw-r--r--libstdc++-v3/testsuite/20_util/variant/87619.cc2
-rw-r--r--libstdc++-v3/testsuite/23_containers/mdspan/extents/ctor_ints.cc7
-rw-r--r--libstdc++-v3/testsuite/23_containers/mdspan/submdspan/strided_slice.cc3
-rw-r--r--libstdc++-v3/testsuite/26_numerics/saturation/extended.cc55
-rw-r--r--libstdc++-v3/testsuite/26_numerics/stdckdint/extended.cc65
-rw-r--r--libstdc++-v3/testsuite/std/concepts/concepts.compare/move_only.cc28
80 files changed, 1249 insertions, 406 deletions
diff --git a/ChangeLog b/ChangeLog
index 6131707..b39348d 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,7 @@
+2025-12-08 Nathan Myers <ncm@cantrip.org>
+
+ * MAINTAINERS: add ncm
+
2025-11-30 Jose E. Marchesi <jose.marchesi@oracle.com>
* MAINTAINERS: Add Algol 68 subsystems.
diff --git a/MAINTAINERS b/MAINTAINERS
index 22d4172..53a35b9 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -706,6 +706,7 @@ Christoph Müllner cmuellner <christoph.muellner@vrull.eu>
Steven Munroe munroesj <munroesj52@gmail.com>
Philippe De Muyter - <phdm@macqel.be>
Joseph Myers jsm28 <josmyers@redhat.com>
+Nathan Myers ncm <ncm@cantrip.org>
Szabolcs Nagy nsz <nsz@gcc.gnu.org>
Victor Do Nascimento victorldn <victor.donascimento@arm.com>
Quentin Neill qneill <quentin.neill.gnu@gmail.com>
diff --git a/contrib/ChangeLog b/contrib/ChangeLog
index ea2d807..6683ddc 100644
--- a/contrib/ChangeLog
+++ b/contrib/ChangeLog
@@ -1,3 +1,13 @@
+2025-12-08 Joseph Myers <josmyers@redhat.com>
+
+ * test_installed (--with-alt-cc=, --with-alt-cxx=)
+ (--with-compat-options=, --with-libiconv=): New options.
+
+2025-12-08 Jonathan Wakely <jwakely@redhat.com>
+
+ * check_GNU_style_lib.py (check_GNU_style_file): Do not check
+ libstdc++ files.
+
2025-12-06 Mark Zhuang <mark.zhuang@spacemit.com>
* prepare-commit-msg: check --default-prefix
diff --git a/contrib/check_GNU_style_lib.py b/contrib/check_GNU_style_lib.py
index faf30c4..fccb3d6 100755
--- a/contrib/check_GNU_style_lib.py
+++ b/contrib/check_GNU_style_lib.py
@@ -285,6 +285,9 @@ def check_GNU_style_file(file, format):
# Skip testsuite files
if 'testsuite' in t or t.endswith('.py'):
continue
+ # Libstdc++ does not use GNU style
+ if t.startswith('libstdc++-v3/'):
+ continue
for hunk in pfile:
delta = 0
diff --git a/contrib/test_installed b/contrib/test_installed
index 77492ca..42c3f12 100755
--- a/contrib/test_installed
+++ b/contrib/test_installed
@@ -42,6 +42,7 @@ if test -f site.exp; then
exit 1
fi
+libiconv=-liconv
while true; do
case "$1" in
--with-testsuite=*) testsuite=`echo "$1" | sed 's/[^=]*=//'`; shift;;
@@ -51,6 +52,10 @@ while true; do
--with-gcc=*) GCC_UNDER_TEST=`echo "$1" | sed 's/[^=]*=//'`; shift;;
--with-g++=*) GXX_UNDER_TEST=`echo "$1" | sed 's/[^=]*=//'`; shift;;
--with-gfortran=*) GFORTRAN_UNDER_TEST=`echo "$1" | sed 's/[^=]*=//'`; shift;;
+ --with-alt-cc=*) ALT_CC_UNDER_TEST=`echo "$1" | sed 's/[^=]*=//'`; shift;;
+ --with-alt-cxx=*) ALT_CXX_UNDER_TEST=`echo "$1" | sed 's/[^=]*=//'`; shift;;
+ --with-compat-options=*) COMPAT_OPTIONS=`echo "$1" | sed 's/[^=]*=//'`; shift;;
+ --with-libiconv=*) libiconv=`echo "$1" | sed 's/[^=]*=//'`; shift;;
--without-gcc) GCC_UNDER_TEST=no; shift;;
--without-g++) GXX_UNDER_TEST=no; shift;;
--without-gfortran) GFORTRAN_UNDER_TEST=no; shift;;
@@ -78,6 +83,10 @@ Supported arguments:
--with-gcc=/some/dir/bin/gcc use specified gcc program [gcc]
--with-g++=/some/dir/bin/g++ use specified g++ program [g++]
--with-gfortran=/some/dir/bin/gfortran use specified gfortran program [gfortran]
+--with-alt-cc=/some/compiler use specified alternative compiler in compat tests
+--with-alt-cxx=/some/compiler use specified alternative compiler in compat tests
+--with-compat-options=opts use specified COMPAT_OPTIONS in compat tests
+--with-libiconv=linker-args use given arguments to link with iconv [-liconv]
--without-gcc do not run gcc testsuite
--without-g++ do not run g++ testsuite
--without-gfortran do not run gfortran testsuite
@@ -108,6 +117,7 @@ cat >site.exp <<EOF
set rootme "."
set tmpdir "${tmpdir-`${PWDCMD-pwd}`}"
set srcdir "${testsuite-${srcdir}/gcc/testsuite}"
+set libiconv "$libiconv"
set CFLAGS ""
set CXXFLAGS ""
set GCC_UNDER_TEST "${GCC_UNDER_TEST-${prefix}${prefix+/bin/}gcc}"
@@ -123,6 +133,15 @@ if test x${target} != x; then
echo "set target_triplet $target" >> site.exp
echo "set target_alias $target" >> site.exp
fi
+if test x"$ALT_CC_UNDER_TEST" != x; then
+ echo "set ALT_CC_UNDER_TEST \"${ALT_CC_UNDER_TEST}\"" >> site.exp
+fi
+if test x"$ALT_CXX_UNDER_TEST" != x; then
+ echo "set ALT_CXX_UNDER_TEST \"${ALT_CXX_UNDER_TEST}\"" >> site.exp
+fi
+if test x"$COMPAT_OPTIONS" != x; then
+ echo "set COMPAT_OPTIONS \"${COMPAT_OPTIONS}\"" >> site.exp
+fi
test x"${GCC_UNDER_TEST}" = x"no" || runtest --tool gcc ${1+"$@"}
test x"${GXX_UNDER_TEST}" = x"no" || runtest --tool g++ ${1+"$@"}
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 6c0c42e..e6da5b8 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,79 @@
+2025-12-08 Andrew Pinski <andrew.pinski@oss.qualcomm.com>
+
+ PR tree-optimization/46555
+ * tree-cfgcleanup.cc (execute_cleanup_cfg_post_optimizing):
+ Don't set todo to include cleanupcfg; do it manually.
+ Call make_forwarders_with_degenerate_phis if optimizing.
+
+2025-12-08 Andrew Pinski <andrew.pinski@oss.qualcomm.com>
+
+ * tree-cfg.cc (make_forwarders_with_degenerate_phis): Add debug
+ dump.
+
+2025-12-08 Andrew Pinski <andrew.pinski@oss.qualcomm.com>
+
+ * tree-ssa-dce.cc (sort_phi_args): Move to tree-cfg.cc.
+ (make_forwarders_with_degenerate_phis): Move to tree-cfg.cc.
+ (perform_tree_ssa_dce): Update for the updated return type
+ of make_forwarders_with_degenerate_phis.
+ * tree-cfg.cc (sort_phi_args): Moved from tree-ssa-dce.cc.
+ (make_forwarders_with_degenerate_phis): Moved from tree-ssa-dce.cc.
+ Update return type to bool and return true if an edge was split.
+ * tree-cfg.h (make_forwarders_with_degenerate_phis): New decl.
+
+2025-12-08 Eric Botcazou <ebotcazou@adacore.com>
+
+ PR target/80881
+ * config/mingw/winnt.cc (mingw_pe_unique_section): Put two dollar
+ signs for TLS sections after the prefix.
+ (mingw_pe_asm_named_section): Deal with all TLS sections uniformly.
+
+2025-12-08 Ezra Sitorus <Ezra.Sitorus@arm.com>
+
+ * config/aarch64/aarch64-cores.def (AARCH64_CORE): Add C1-Nano,
+ C1-Pro, C1-Premium and C1-Ultra.
+ * config/aarch64/aarch64-tune.md: Regenerate.
+ * doc/invoke.texi: Document C1 cores.
+
+2025-12-08 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/123040
+ * tree-ssa-sccvn.cc (vn_nary_build_or_lookup_1): Only insert
+ nary results.
+
+2025-12-08 Josef Melcr <josef.melcr@suse.com>
+
+ PR ipa/122798
+ * cgraph.cc (cgraph_edge::redirect_callee): Use
+ iterate_referring instead of referred_to_p.
+ * cgraphclones.cc (set_new_clone_decl_and_node_flags): Set local
+ to true iff the node does not have its address taken.
+
+2025-12-08 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/123038
+ * tree-vect-patterns.cc (vect_recog_ctz_ffs_pattern): Reject
+ pattern for reductions when the call argument is used multiple
+ times.
+
+2025-12-08 Tamar Christina <tamar.christina@arm.com>
+
+ PR target/123026
+ * config/aarch64/aarch64-simd.md (reduc_sbool_ior_scal_<mode>,
+ reduc_sbool_and_scal_<mode>): Fix tmp operands[1] override.
+
+2025-12-08 Tamar Christina <tamar.christina@arm.com>
+
+ PR tree-optimization/122868
+ * tree-vect-stmts.cc (vectorizable_load): Move check for invariant loads
+ down into the loop.
+
+2025-12-08 H.J. Lu <hjl.tools@gmail.com>
+
+ PR target/122343
+ * config/i386/sse.md (*<avx512>_cmp<mode>3_dup_op): Don't allow
+ 2 volatile memory references.
+
2025-12-07 Jason Merrill <jason@redhat.com>
* config/darwin-c.cc (find_subframework_header): Use
diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP
index f674ed1..4568345 100644
--- a/gcc/DATESTAMP
+++ b/gcc/DATESTAMP
@@ -1 +1 @@
-20251208
+20251209
diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog
index 2067233..8b19deb 100644
--- a/gcc/ada/ChangeLog
+++ b/gcc/ada/ChangeLog
@@ -1,3 +1,9 @@
+2025-12-08 Eric Botcazou <ebotcazou@adacore.com>
+
+ PR ada/123037
+ * rtinit.c [__MINGW32__]: Include <stdlib.h> and not <windows.h>.
+ * rtfinal.c [__MINGW32__]: Do not include <windows.h>.
+
2025-12-07 Eric Botcazou <ebotcazou@adacore.com>
PR ada/115349
diff --git a/gcc/ada/rtfinal.c b/gcc/ada/rtfinal.c
index 88bbb0e..0bd3ce4 100644
--- a/gcc/ada/rtfinal.c
+++ b/gcc/ada/rtfinal.c
@@ -46,9 +46,7 @@ extern int __gnat_rt_init_count;
/* see initialize.c */
#if defined (__MINGW32__)
-#define WIN32_LEAN_AND_MEAN
#include "mingw32.h"
-#include <windows.h>
extern CRITICAL_SECTION ProcListCS;
extern HANDLE ProcListEvt;
diff --git a/gcc/ada/rtinit.c b/gcc/ada/rtinit.c
index 598550c..3b5af0d 100644
--- a/gcc/ada/rtinit.c
+++ b/gcc/ada/rtinit.c
@@ -70,9 +70,8 @@ int __gnat_rt_init_count = 0;
and finalize properly the run-time. */
#if defined (__MINGW32__)
-#define WIN32_LEAN_AND_MEAN
+#include <stdlib.h>
#include "mingw32.h"
-#include <windows.h>
extern void __gnat_init_float (void);
diff --git a/gcc/cgraph.cc b/gcc/cgraph.cc
index 3c21e17..1a7d499 100644
--- a/gcc/cgraph.cc
+++ b/gcc/cgraph.cc
@@ -1696,8 +1696,12 @@ cgraph_edge::redirect_callee (cgraph_node *n)
old_ref->remove_reference ();
ipa_ref *new_ref = caller->create_reference (n, IPA_REF_ADDR, call_stmt);
new_ref->lto_stmt_uid = lto_stmt_uid;
- if (!old_callee->referred_to_p ())
+ /* If the last reference to OLD_CALLEE has been redirected, unset
+ address_taken. old_ref is only used as a placeholder when looking for
+ a different reference. */
+ if (!old_callee->iterate_referring (0, old_ref))
old_callee->address_taken = 0;
+ n->mark_address_taken ();
}
if (!inline_failed)
diff --git a/gcc/cgraphclones.cc b/gcc/cgraphclones.cc
index 49f0e58..816fc53 100644
--- a/gcc/cgraphclones.cc
+++ b/gcc/cgraphclones.cc
@@ -176,7 +176,9 @@ set_new_clone_decl_and_node_flags (cgraph_node *new_node)
DECL_IS_REPLACEABLE_OPERATOR (new_node->decl) = 0;
new_node->externally_visible = 0;
- new_node->local = 1;
+ /* Clones of callbacks might have their address taken, and thus cannot be
+ local. */
+ new_node->local = !new_node->address_taken;
new_node->lowered = true;
new_node->semantic_interposition = 0;
}
diff --git a/gcc/config/aarch64/aarch64-cores.def b/gcc/config/aarch64/aarch64-cores.def
index b86d80c..851594a 100644
--- a/gcc/config/aarch64/aarch64-cores.def
+++ b/gcc/config/aarch64/aarch64-cores.def
@@ -229,6 +229,11 @@ AARCH64_CORE("grace", grace, cortexa57, V9A, (I8MM, BF16, SVE2_BITPERM, SVE2_AES
AARCH64_CORE("neoverse-v3", neoversev3, cortexa57, V9_2A, (SVE2_BITPERM, RNG, LS64, MEMTAG, PROFILE), neoversev3, 0x41, 0xd84, -1)
AARCH64_CORE("neoverse-v3ae", neoversev3ae, cortexa57, V9_2A, (SVE2_BITPERM, RNG, LS64, MEMTAG, PROFILE), neoversev3ae, 0x41, 0xd83, -1)
+AARCH64_CORE("c1-nano", c1nano, cortexa53, V9_3A, (MEMTAG, SVE2_BITPERM, F16FML, SME2, RCPC3), cortexa53, 0x41, 0xd8a, -1)
+AARCH64_CORE("c1-pro", c1pro, cortexa57, V9_3A, (MEMTAG, SVE2_BITPERM, F16FML, PROFILE, SME2, RCPC3), neoversen3, 0x41, 0xd8b, -1)
+AARCH64_CORE("c1-premium", c1premium, cortexa57, V9_3A, (MEMTAG, SVE2_BITPERM, F16FML, PROFILE, SME2, RCPC3), neoversev3, 0x41, 0xd90, -1)
+AARCH64_CORE("c1-ultra", c1ultra, cortexa57, V9_3A, (MEMTAG, SVE2_BITPERM, F16FML, PROFILE, SME2, RCPC3), cortexx925, 0x41, 0xd8c, -1)
+
AARCH64_CORE("demeter", demeter, cortexa57, V9A, (I8MM, BF16, SVE2_BITPERM, RNG, MEMTAG, PROFILE), neoversev2, 0x41, 0xd4f, -1)
/* NVIDIA ('N') cores. */
diff --git a/gcc/config/aarch64/aarch64-simd.md b/gcc/config/aarch64/aarch64-simd.md
index 3f9d5f6..c02ffd6 100644
--- a/gcc/config/aarch64/aarch64-simd.md
+++ b/gcc/config/aarch64/aarch64-simd.md
@@ -3544,10 +3544,10 @@
rtx reduc = gen_lowpart (V4SImode, tmp);
rtx res = gen_reg_rtx (V4SImode);
emit_insn (gen_aarch64_uminpv4si (res, reduc, reduc));
- emit_move_insn (tmp, gen_lowpart (<MODE>mode, res));
+ tmp = gen_lowpart (<MODE>mode, res);
}
- rtx val = gen_reg_rtx (DImode);
- emit_move_insn (val, gen_lowpart (DImode, tmp));
+
+ rtx val = force_lowpart_subreg (DImode, tmp, <MODE>mode);
rtx cc_reg = aarch64_gen_compare_reg (EQ, val, constm1_rtx);
rtx cmp = gen_rtx_fmt_ee (EQ, SImode, cc_reg, constm1_rtx);
rtx tmp2 = gen_reg_rtx (SImode);
@@ -3607,10 +3607,10 @@
rtx reduc = gen_lowpart (V4SImode, tmp);
rtx res = gen_reg_rtx (V4SImode);
emit_insn (gen_aarch64_umaxpv4si (res, reduc, reduc));
- emit_move_insn (tmp, gen_lowpart (<MODE>mode, res));
+ tmp = gen_lowpart (<MODE>mode, res);
}
- rtx val = gen_reg_rtx (DImode);
- emit_move_insn (val, gen_lowpart (DImode, tmp));
+
+ rtx val = force_lowpart_subreg (DImode, tmp, <MODE>mode);
rtx cc_reg = aarch64_gen_compare_reg (NE, val, const0_rtx);
rtx cmp = gen_rtx_fmt_ee (NE, SImode, cc_reg, const0_rtx);
rtx tmp2 = gen_reg_rtx (SImode);
diff --git a/gcc/config/aarch64/aarch64-tune.md b/gcc/config/aarch64/aarch64-tune.md
index 292796c..d6f1bbc 100644
--- a/gcc/config/aarch64/aarch64-tune.md
+++ b/gcc/config/aarch64/aarch64-tune.md
@@ -1,5 +1,5 @@
;; -*- buffer-read-only: t -*-
;; Generated automatically by gentune.sh from aarch64-cores.def
(define_attr "tune"
- "cortexa34,cortexa35,cortexa53,cortexa57,cortexa72,cortexa73,thunderx,thunderxt88,thunderxt88p1,octeontx,octeontxt81,octeontxt83,thunderxt81,thunderxt83,ampere1,ampere1a,ampere1b,ampere1c,emag,xgene1,falkor,qdf24xx,exynosm1,phecda,thunderx2t99p1,vulcan,thunderx2t99,cortexa55,cortexa75,cortexa76,cortexa76ae,cortexa77,cortexa78,cortexa78ae,cortexa78c,cortexa65,cortexa65ae,cortexx1,cortexx1c,neoversen1,ares,neoversee1,octeontx2,octeontx2t98,octeontx2t96,octeontx2t93,octeontx2f95,octeontx2f95n,octeontx2f95mm,a64fx,fujitsu_monaka,tsv110,thunderx3t110,neoversev1,zeus,neoverse512tvb,saphira,oryon1,cortexa57cortexa53,cortexa72cortexa53,cortexa73cortexa35,cortexa73cortexa53,cortexa75cortexa55,cortexa76cortexa55,cortexr82,cortexr82ae,applea12,applem1_0,applem1_1,applem1_2,applem1_3,applem2_0,applem2_1,applem2_2,applem2_3,applem3_0,applem3_1,applem3_2,applem4_0,applem4_1,applem4_2,cortexa510,cortexa520,cortexa520ae,cortexa710,cortexa715,cortexa720,cortexa720ae,cortexa725,cortexx2,cortexx3,cortexx4,cortexx925,neoversen2,cobalt100,neoversen3,neoversev2,grace,neoversev3,neoversev3ae,demeter,olympus,gb10,generic,generic_armv8_a,generic_armv9_a"
+ "cortexa34,cortexa35,cortexa53,cortexa57,cortexa72,cortexa73,thunderx,thunderxt88,thunderxt88p1,octeontx,octeontxt81,octeontxt83,thunderxt81,thunderxt83,ampere1,ampere1a,ampere1b,ampere1c,emag,xgene1,falkor,qdf24xx,exynosm1,phecda,thunderx2t99p1,vulcan,thunderx2t99,cortexa55,cortexa75,cortexa76,cortexa76ae,cortexa77,cortexa78,cortexa78ae,cortexa78c,cortexa65,cortexa65ae,cortexx1,cortexx1c,neoversen1,ares,neoversee1,octeontx2,octeontx2t98,octeontx2t96,octeontx2t93,octeontx2f95,octeontx2f95n,octeontx2f95mm,a64fx,fujitsu_monaka,tsv110,thunderx3t110,neoversev1,zeus,neoverse512tvb,saphira,oryon1,cortexa57cortexa53,cortexa72cortexa53,cortexa73cortexa35,cortexa73cortexa53,cortexa75cortexa55,cortexa76cortexa55,cortexr82,cortexr82ae,applea12,applem1_0,applem1_1,applem1_2,applem1_3,applem2_0,applem2_1,applem2_2,applem2_3,applem3_0,applem3_1,applem3_2,applem4_0,applem4_1,applem4_2,cortexa510,cortexa520,cortexa520ae,cortexa710,cortexa715,cortexa720,cortexa720ae,cortexa725,cortexx2,cortexx3,cortexx4,cortexx925,neoversen2,cobalt100,neoversen3,neoversev2,grace,neoversev3,neoversev3ae,c1nano,c1pro,c1premium,c1ultra,demeter,olympus,gb10,generic,generic_armv8_a,generic_armv9_a"
(const (symbol_ref "((enum attr_tune) aarch64_tune)")))
diff --git a/gcc/config/mingw/winnt.cc b/gcc/config/mingw/winnt.cc
index b51fd8e..fe2fb4c 100644
--- a/gcc/config/mingw/winnt.cc
+++ b/gcc/config/mingw/winnt.cc
@@ -446,8 +446,11 @@ mingw_pe_unique_section (tree decl, int reloc)
prefix = ".text$";
else if (decl_readonly_section (decl, reloc))
prefix = ".rdata$";
+ /* Note that we need two dollar signs for TLS sections
+ because they need to be ASCII-sorted before .tls$ZZZ
+ to be properly laid out by the GNU linker. */
else if (DECL_THREAD_LOCAL_P (decl))
- prefix = ".tls$";
+ prefix = ".tls$$";
else
prefix = ".data$";
len = strlen (name) + strlen (prefix);
@@ -522,9 +525,6 @@ mingw_pe_asm_named_section (const char *name, unsigned int flags,
*f++ = 'e';
#endif
- if (strcmp (name, ".tls$") == 0)
- *f++ = 'd';
-
if ((flags & (SECTION_CODE | SECTION_WRITE)) == 0)
/* readonly data */
{
@@ -533,6 +533,8 @@ mingw_pe_asm_named_section (const char *name, unsigned int flags,
}
else
{
+ if (startswith (name, ".tls$"))
+ *f++ = 'd';
if (flags & SECTION_CODE)
*f++ = 'x';
if (flags & SECTION_WRITE)
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 3ad8d16..b4c2b70 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,13 @@
+2025-12-08 Egas Ribeiro <egas.g.ribeiro@tecnico.ulisboa.pt>
+
+ * pt.cc (tsubst_expr): Add TARGET_EXPR case with explanatory
+ comment and gcc_unreachable.
+
+2025-12-08 Egas Ribeiro <egas.g.ribeiro@tecnico.ulisboa.pt>
+
+ PR c++/119343
+ * pt.cc (resolve_nondeduced_context): Remove mark_used call.
+
2025-12-06 Jakub Jelinek <jakub@redhat.com>
* decl2.cc (is_late_template_attribute): Call lookup_attribute_spec
diff --git a/gcc/cp/decl.cc b/gcc/cp/decl.cc
index 74c862e..31081b3 100644
--- a/gcc/cp/decl.cc
+++ b/gcc/cp/decl.cc
@@ -19750,7 +19750,7 @@ start_preparsed_function (tree decl1, tree attrs, int flags)
}
}
- bool honor_interface = (!DECL_TEMPLATE_INSTANTIATION (decl1)
+ bool honor_interface = (!DECL_TEMPLOID_INSTANTIATION (decl1)
/* Implicitly-defined methods (like the
destructor for a class in which no destructor
is explicitly declared) must not be defined
@@ -19781,7 +19781,7 @@ start_preparsed_function (tree decl1, tree attrs, int flags)
else if (!finfo->interface_unknown && honor_interface)
{
if (DECL_DECLARED_INLINE_P (decl1)
- || DECL_TEMPLATE_INSTANTIATION (decl1))
+ || DECL_TEMPLOID_INSTANTIATION (decl1))
{
DECL_EXTERNAL (decl1)
= (finfo->interface_only
@@ -19823,7 +19823,7 @@ start_preparsed_function (tree decl1, tree attrs, int flags)
DECL_EXTERNAL (decl1) = 0;
if ((DECL_DECLARED_INLINE_P (decl1)
- || DECL_TEMPLATE_INSTANTIATION (decl1))
+ || DECL_TEMPLOID_INSTANTIATION (decl1))
&& ! DECL_INTERFACE_KNOWN (decl1))
DECL_DEFER_OUTPUT (decl1) = 1;
else
diff --git a/gcc/cp/decl2.cc b/gcc/cp/decl2.cc
index 8ec9740..01bf26b 100644
--- a/gcc/cp/decl2.cc
+++ b/gcc/cp/decl2.cc
@@ -2510,7 +2510,7 @@ vague_linkage_p (tree decl)
|| (TREE_CODE (decl) == FUNCTION_DECL
&& DECL_DECLARED_INLINE_P (decl))
|| (DECL_LANG_SPECIFIC (decl)
- && DECL_TEMPLATE_INSTANTIATION (decl))
+ && DECL_TEMPLOID_INSTANTIATION (decl))
|| (VAR_P (decl) && DECL_INLINE_VAR_P (decl)))
return true;
else if (DECL_FUNCTION_SCOPE_P (decl))
@@ -5850,8 +5850,7 @@ c_parse_final_cleanups (void)
&& !(header_module_p ()
&& (DECL_DEFAULTED_FN (decl) || decl_tls_wrapper_p (decl)))
/* Don't complain if the template was defined. */
- && !((DECL_TEMPLATE_INSTANTIATION (decl)
- || DECL_FRIEND_PSEUDO_TEMPLATE_INSTANTIATION (decl))
+ && !(DECL_TEMPLOID_INSTANTIATION (decl)
&& DECL_INITIAL (DECL_TEMPLATE_RESULT
(template_for_substitution (decl))))
&& warning_at (DECL_SOURCE_LOCATION (decl), 0,
diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc
index 8498730..ce30b52 100644
--- a/gcc/cp/pt.cc
+++ b/gcc/cp/pt.cc
@@ -22562,6 +22562,11 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl)
in response to the saved STMT_IS_FULL_EXPR_P setting. */
gcc_unreachable ();
+ case TARGET_EXPR:
+ /* TARGET_EXPR represents temporary objects and should not appear in
+ templated trees. */
+ gcc_unreachable ();
+
case OFFSET_REF:
{
/* We should only get here for an OFFSET_REF like A::m; a .* in a
@@ -24816,8 +24821,6 @@ resolve_nondeduced_context (tree orig_expr, tsubst_flags_t complain)
}
if (good == 1)
{
- if (!mark_used (goodfn, complain) && !(complain & tf_error))
- return error_mark_node;
expr = goodfn;
if (baselink)
expr = build_baselink (BASELINK_BINFO (baselink),
diff --git a/gcc/cp/semantics.cc b/gcc/cp/semantics.cc
index 331db16..b32ab2f 100644
--- a/gcc/cp/semantics.cc
+++ b/gcc/cp/semantics.cc
@@ -5537,7 +5537,9 @@ expand_or_defer_fn_1 (tree fn)
of the compilation. Until that point, we do not want the back
end to output them -- but we do want it to see the bodies of
these functions so that it can inline them as appropriate. */
- if (DECL_DECLARED_INLINE_P (fn) || DECL_IMPLICIT_INSTANTIATION (fn))
+ if (DECL_DECLARED_INLINE_P (fn)
+ || DECL_IMPLICIT_INSTANTIATION (fn)
+ || DECL_FRIEND_PSEUDO_TEMPLATE_INSTANTIATION (fn))
{
if (DECL_INTERFACE_KNOWN (fn))
/* We've already made a decision as to how this function will
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index ac36fda..b89fbf8 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -22761,7 +22761,8 @@ performance of the code. Permissible values for this option are:
@samp{cortex-a520}, @samp{cortex-a520ae}, @samp{cortex-a710}, @samp{cortex-a715},
@samp{cortex-a720}, @samp{cortex-a720ae}, @samp{ampere1}, @samp{ampere1a},
@samp{ampere1b}, @samp{ampere1c}, @samp{cobalt-100}, @samp{apple-m1},
-@samp{apple-m2}, @samp{apple-m3}, @samp{apple-m4} and @samp{native}.
+@samp{apple-m2}, @samp{apple-m3}, @samp{apple-m4}, @samp{c1-nano},
+@samp{c1-pro}, @samp{c1-premium} @samp{c1-ultra} and @samp{native}.
The values @samp{cortex-a57.cortex-a53}, @samp{cortex-a72.cortex-a53},
@samp{cortex-a73.cortex-a35}, @samp{cortex-a73.cortex-a53},
diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog
index 724da5b..4fd2183 100644
--- a/gcc/fortran/ChangeLog
+++ b/gcc/fortran/ChangeLog
@@ -1,3 +1,12 @@
+2025-12-08 Harald Anlauf <anlauf@gmx.de>
+ Steven G. Kargl <kargl@gcc.gnu.org>
+
+ PR fortran/123025
+ * decl.cc (match_char_length): Add a check for the
+ obsolete '*' style of character declarations in the
+ alternate branch of checking so we dont miss two
+ use cases:
+
2025-12-06 Paul Thomas <pault@gcc.gnu.org>
PR fortran/122693
diff --git a/gcc/fortran/decl.cc b/gcc/fortran/decl.cc
index dfedb96..0e55171 100644
--- a/gcc/fortran/decl.cc
+++ b/gcc/fortran/decl.cc
@@ -1217,6 +1217,10 @@ match_char_length (gfc_expr **expr, bool *deferred, bool obsolescent_check)
goto syntax;
}
+ if (obsolescent_check
+ && !gfc_notify_std (GFC_STD_F95_OBS, "Old-style character length at %C"))
+ return MATCH_ERROR;
+
return MATCH_YES;
syntax:
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index e6918d4..f8a8fba 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,58 @@
+2025-12-08 Andrew Pinski <andrew.pinski@oss.qualcomm.com>
+
+ PR tree-optimization/46555
+ * gcc.dg/tree-ssa/pr46555.c: New test.
+
+2025-12-08 Harald Anlauf <anlauf@gmx.de>
+ Steven G. Kargl <kargl@gcc.gnu.org>
+
+ PR fortran/123025
+ * gfortran.dg/assumed_charlen_dummy.f90: These tests failed
+ with the change because of the default -pedantic option
+ used by the dg.exp mechanisms. Overide this default.
+ * gfortran.dg/automatic_char_len_1.f90: Ditto.
+ * gfortran.dg/entry_23.f: Ditto.
+ * gfortran.dg/finalize_59.f90: Dito.
+ * gfortran.dg/g77/f90-intrinsic-bit.f: Ditto.
+ * gfortran.dg/g77/f90-intrinsic-mathematical.f: Ditto.
+ * gfortran.dg/g77/f90-intrinsic-numeric.f: Ditto.
+ * gfortran.dg/g77/intrinsic-unix-bessel.f: Ditto.
+ * gfortran.dg/g77/intrinsic-unix-erf.f: Ditto.
+ * gfortran.dg/initialization_9.f90: Ditto.
+ * gfortran.dg/intrinsic_actual_4.f90: Ditto.
+ * gfortran.dg/namelist_assumed_char.f90: Ditto.
+ * gfortran.dg/pr15140.f90: Ditto.
+
+2025-12-08 Egas Ribeiro <egas.g.ribeiro@tecnico.ulisboa.pt>
+
+ PR c++/119343
+ * g++.dg/template/sfinae-deleted-pr119343.C: New test.
+
+2025-12-08 Eric Botcazou <ebotcazou@adacore.com>
+
+ * gcc.dg/tls/data-sections-1.c: New test.
+
+2025-12-08 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/123040
+ * g++.dg/torture/pr123040.C: New testcase.
+
+2025-12-08 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/123038
+ * gcc.dg/vect/pr123038.c: New testcase.
+
+2025-12-08 Tamar Christina <tamar.christina@arm.com>
+
+ PR target/123026
+ * gcc.target/aarch64/pr123026.c: New test.
+
+2025-12-08 H.J. Lu <hjl.tools@gmail.com>
+
+ PR target/122343
+ * gcc.target/i386/avx2-vpcmpgtq-1.c: Compile with
+ -fno-fuse-ops-with-volatile-access.
+
2025-12-07 Eric Botcazou <ebotcazou@adacore.com>
* gnat.dg/reduce3.adb: New test.
diff --git a/gcc/testsuite/g++.dg/modules/tpl-friend-22.C b/gcc/testsuite/g++.dg/modules/tpl-friend-22.C
new file mode 100644
index 0000000..a77d1cb
--- /dev/null
+++ b/gcc/testsuite/g++.dg/modules/tpl-friend-22.C
@@ -0,0 +1,24 @@
+// PR c++/122819
+// { dg-do compile { target *-*-*gnu* } }
+// { dg-additional-options "-fmodules" }
+
+export module M;
+
+template <typename T> struct S;
+void foo(S<float>);
+
+template <typename T> struct S {
+ friend void foo(S) {}
+};
+
+void foo(S<double>);
+
+void use() {
+ foo(S<int>{});
+ foo(S<float>{});
+ foo(S<double>{});
+}
+
+// { dg-final { scan-assembler "_ZW1M3fooS_1SIiE,comdat" } }
+// { dg-final { scan-assembler "_ZW1M3fooS_1SIfE,comdat" } }
+// { dg-final { scan-assembler "_ZW1M3fooS_1SIdE,comdat" } }
diff --git a/gcc/testsuite/g++.dg/template/sfinae-deleted-pr119343.C b/gcc/testsuite/g++.dg/template/sfinae-deleted-pr119343.C
new file mode 100644
index 0000000..065ad60
--- /dev/null
+++ b/gcc/testsuite/g++.dg/template/sfinae-deleted-pr119343.C
@@ -0,0 +1,31 @@
+// { dg-do compile { target c++11 } }
+// PR c++/119343 - No SFINAE for deleted explicit specializations
+
+struct true_type { static constexpr bool value = true; };
+struct false_type { static constexpr bool value = false; };
+
+struct X {
+ static void f()=delete;
+ template<int> static void g();
+};
+template<> void X::g<0>()=delete;
+struct Y {
+ static void f();
+ template<int> static void g();
+};
+
+template<class T,class=void>
+struct has_f : false_type {};
+template<class T>
+struct has_f<T,decltype(void(T::f))> : true_type {};
+
+static_assert(!has_f<X>::value, "");
+static_assert(has_f<Y>::value, "");
+
+template<class T,class=void>
+struct has_g0 : false_type {};
+template<class T>
+struct has_g0<T,decltype(void(T::template g<0>))> : true_type {};
+
+static_assert(!has_g0<X>::value, "");
+static_assert(has_g0<Y>::value, "");
diff --git a/gcc/testsuite/g++.dg/torture/pr123040.C b/gcc/testsuite/g++.dg/torture/pr123040.C
new file mode 100644
index 0000000..3ba2d90
--- /dev/null
+++ b/gcc/testsuite/g++.dg/torture/pr123040.C
@@ -0,0 +1,61 @@
+// { dg-do compile }
+
+template <int kBytes, typename From, typename To>
+void CopyBytes(From from, To to) {
+ __builtin_memcpy(to, from, kBytes);
+}
+template <typename From, typename To> void CopySameSize(From *from, To to) {
+ CopyBytes<sizeof(From)>(from, to);
+}
+template <typename> using MakeUnsigned = char;
+template <typename Lane, int N> struct Simd {
+ using T = Lane;
+ static constexpr int kPrivateLanes = N;
+ template <typename NewT> using Rebind = Simd<NewT, 0>;
+};
+template <class D> using TFromD = D::T;
+template <class T, class D> using Rebind = D::template Rebind<T>;
+template <class D> using RebindToUnsigned = Rebind<MakeUnsigned<D>, D>;
+template <typename T, int> struct Vec128 {
+ using PrivateT = T;
+ static constexpr int kPrivateN = 6;
+ T raw[16];
+};
+template <class V> using DFromV = Simd<typename V::PrivateT, V::kPrivateN>;
+template <class D> Vec128<TFromD<D>, D::kPrivateLanes> Zero(D);
+template <class D> using VFromD = decltype(Zero(D()));
+template <class D, class VFrom> VFromD<D> BitCast(D, VFrom v) {
+ VFromD<D> to;
+ CopySameSize(&v, to.raw);
+ return to;
+}
+template <int N> Vec128<signed char, N> And(Vec128<signed char, N> b) {
+ Vec128<signed char, N> a;
+ DFromV<decltype(a)> d;
+ RebindToUnsigned<decltype(d)> du;
+ auto au(a);
+ auto bu = BitCast(du, b);
+ for (int i = 0; i < N; ++i)
+ au.raw[i] &= bu.raw[i];
+ return au;
+}
+void Or(Vec128<signed char, 16>);
+template <int N> void IfVecThenElse(Vec128<signed char, N> yes) {
+ Vec128 __trans_tmp_2 = And(yes);
+ Or(__trans_tmp_2);
+}
+template <int N> void IfThenElseZero(Vec128<signed char, N> yes) {
+ IfVecThenElse(yes);
+}
+Vec128<signed char, 16> Abs_a;
+char MaskedAbs___trans_tmp_5;
+void MaskedAbs() {
+ Vec128<signed char, 16> __trans_tmp_4;
+ for (int i = 0; i < 16; ++i) {
+ MaskedAbs___trans_tmp_5 = Abs_a.raw[i] ? -Abs_a.raw[i] : 0;
+ Abs_a.raw[i] = MaskedAbs___trans_tmp_5;
+ }
+ __trans_tmp_4 = Abs_a;
+ Vec128 __trans_tmp_3 = __trans_tmp_4;
+ IfThenElseZero(__trans_tmp_3);
+}
diff --git a/gcc/testsuite/gcc.dg/tls/data-sections-1.c b/gcc/testsuite/gcc.dg/tls/data-sections-1.c
new file mode 100644
index 0000000..c829256
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tls/data-sections-1.c
@@ -0,0 +1,14 @@
+/* { dg-do run } */
+/* { dg-require-effective-target tls_runtime } */
+/* { dg-options "-fdata-sections" } */
+/* { dg-add-options tls } */
+
+__thread int i = 1;
+
+int main (void)
+{
+ if (i != 1)
+ __builtin_abort ();
+
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr46555.c b/gcc/testsuite/gcc.dg/tree-ssa/pr46555.c
new file mode 100644
index 0000000..d4de7c2
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr46555.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-optimized-details -fdump-rtl-pro_and_epilogue" } */
+/* PR tree-optimization/46555 */
+/* Here should not remove the forwarder block (or rather recreate it and not
+ remove it again). This improves expansion to RTL as there is one less copy
+ (or constant formation) in some cases. In this case we also get the ability
+ to shrink wrap the function. */
+
+int h(void);
+int f(int a, int b, int c)
+{
+ if (a)
+ return 2;
+ h();
+ if (b)
+ return 2;
+ h();
+ if (c)
+ return 2;
+ h();
+ return 4;
+}
+
+/* { dg-final { scan-tree-dump-times "New forwarder block for edge" 1 "optimized" } } */
+/* Make sure we only have a PHI with 2 arguments here, 2 and 4. */
+/* { dg-final { scan-tree-dump "PHI <2..., 4...>|PHI <4..., 2...>" "optimized" } } */
+/* Make sure we can shrink wrap the function now too. */
+/* { dg-final { scan-rtl-dump "Performing shrink-wrapping" "pro_and_epilogue" { target { { { i?86-*-* x86_64-*-* } && { ! ia32 } } || { powerpc*-*-* aarch64*-*-* riscv*-*-* arm*-*-* } } } } } */
diff --git a/gcc/testsuite/gcc.dg/vect/pr123038.c b/gcc/testsuite/gcc.dg/vect/pr123038.c
new file mode 100644
index 0000000..bca831f
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/pr123038.c
@@ -0,0 +1,8 @@
+/* { dg-do compile } */
+
+unsigned char f(int b)
+{
+ for (int a = 0; a < 10; a += 1)
+ b = __builtin_ffs(b);
+ return b;
+}
diff --git a/gcc/testsuite/gcc.target/aarch64/pr123026.c b/gcc/testsuite/gcc.target/aarch64/pr123026.c
new file mode 100644
index 0000000..4dcce8a
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/pr123026.c
@@ -0,0 +1,21 @@
+/* { dg-do run } */
+/* { dg-additional-options "-O3 -march=armv8-a -std=c99" } */
+
+#include <stdbool.h>
+
+int g;
+
+__attribute__ ((noipa)) void
+foo(bool a) {
+ for (int i = 0; i < 4; i++)
+ if (!i || a)
+ g += 1;
+}
+
+int main()
+{
+ foo(0);
+ if (g != 1)
+ __builtin_abort();
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/avx2-vpcmpgtq-1.c b/gcc/testsuite/gcc.target/i386/avx2-vpcmpgtq-1.c
index 7a98380..5e6f431 100644
--- a/gcc/testsuite/gcc.target/i386/avx2-vpcmpgtq-1.c
+++ b/gcc/testsuite/gcc.target/i386/avx2-vpcmpgtq-1.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-options "-mavx2 -O2" } */
+/* { dg-options "-mavx2 -O2 -fno-fuse-ops-with-volatile-access" } */
/* { dg-final { scan-assembler "vpcmpgtq\[ \\t\]+\[^\n\]*%ymm\[0-9\]" } } */
#include <immintrin.h>
diff --git a/gcc/testsuite/gfortran.dg/assumed_charlen_dummy.f90 b/gcc/testsuite/gfortran.dg/assumed_charlen_dummy.f90
index 04f0b9f..2e0e77c 100644
--- a/gcc/testsuite/gfortran.dg/assumed_charlen_dummy.f90
+++ b/gcc/testsuite/gfortran.dg/assumed_charlen_dummy.f90
@@ -1,4 +1,5 @@
! { dg-do compile }
+! { dg-options " " }
! Test the fix for PR fortran/39893.
! Original testcase provided by Deji Akingunola.
! Reduced testcase provided by Dominique d'Humieres.
diff --git a/gcc/testsuite/gfortran.dg/automatic_char_len_1.f90 b/gcc/testsuite/gfortran.dg/automatic_char_len_1.f90
index 3ccfcb7..7f102b7 100644
--- a/gcc/testsuite/gfortran.dg/automatic_char_len_1.f90
+++ b/gcc/testsuite/gfortran.dg/automatic_char_len_1.f90
@@ -1,4 +1,5 @@
! { dg-do compile }
+! { dg-options " " }
! PR18082 - Compiler would get stuck in loop, whilst treating
! the assignments.
! Test is one of PR cases.
diff --git a/gcc/testsuite/gfortran.dg/entry_23.f b/gcc/testsuite/gfortran.dg/entry_23.f
index ebc5f66..d10ea92 100644
--- a/gcc/testsuite/gfortran.dg/entry_23.f
+++ b/gcc/testsuite/gfortran.dg/entry_23.f
@@ -1,4 +1,5 @@
! { dg-do run }
+! { dg-options " " }
! PR 97799 - this used to segfault intermittently.
! Test case by George Hockney.
PROGRAM MAIN
diff --git a/gcc/testsuite/gfortran.dg/finalize_59.f90 b/gcc/testsuite/gfortran.dg/finalize_59.f90
index 8be5f71..e9e68d4 100644
--- a/gcc/testsuite/gfortran.dg/finalize_59.f90
+++ b/gcc/testsuite/gfortran.dg/finalize_59.f90
@@ -187,7 +187,7 @@ Program Cds_Principal
Type(Uef_Vector) :: Cds_Mod_Les_materiaux
Type (Cds_Materiau_Acier_EC) :: acier_ec
Class (Cds_Materiau), pointer :: pt_materiau
- Character *(8) :: nom_materiau
+ Character(len=8) :: nom_materiau
!-------------------------------------------------------------------------------------------------
CaLL Cds_Mod_Les_materiaux%Add (acier_ec)
nom_materiau = "12345678"
@@ -199,7 +199,7 @@ Function Get_Pt_Materiau_nom (vecteur, nom_materiau)
! Fonction :
!--------------------
! Parametres en entree
- Character *(8), Intent (in) :: nom_materiau
+ Character(len=8), Intent (in) :: nom_materiau
Type (Uef_Vector) , Intent (inout) :: vecteur
! Parametres en sortie
diff --git a/gcc/testsuite/gfortran.dg/g77/f90-intrinsic-bit.f b/gcc/testsuite/gfortran.dg/g77/f90-intrinsic-bit.f
index 0ce45de..2f03db1 100644
--- a/gcc/testsuite/gfortran.dg/g77/f90-intrinsic-bit.f
+++ b/gcc/testsuite/gfortran.dg/g77/f90-intrinsic-bit.f
@@ -1,4 +1,5 @@
c { dg-do run }
+c { dg-options " " }
c f90-intrinsic-bit.f
c
c Test Fortran 90
diff --git a/gcc/testsuite/gfortran.dg/g77/f90-intrinsic-mathematical.f b/gcc/testsuite/gfortran.dg/g77/f90-intrinsic-mathematical.f
index d151fd0..f07336e 100644
--- a/gcc/testsuite/gfortran.dg/g77/f90-intrinsic-mathematical.f
+++ b/gcc/testsuite/gfortran.dg/g77/f90-intrinsic-mathematical.f
@@ -1,4 +1,5 @@
c { dg-do run }
+c { dg-options " " }
c f90-intrinsic-mathematical.f
c
c Test Fortran 90 intrinsic mathematical functions - Section 13.10.3 and
diff --git a/gcc/testsuite/gfortran.dg/g77/f90-intrinsic-numeric.f b/gcc/testsuite/gfortran.dg/g77/f90-intrinsic-numeric.f
index c8d7c56..c01efe6 100644
--- a/gcc/testsuite/gfortran.dg/g77/f90-intrinsic-numeric.f
+++ b/gcc/testsuite/gfortran.dg/g77/f90-intrinsic-numeric.f
@@ -1,4 +1,5 @@
c { dg-do run }
+c { dg-options " " }
c f90-intrinsic-numeric.f
c
c Test Fortran 90 intrinsic numeric functions - Section 13.10.2 and 13.13
diff --git a/gcc/testsuite/gfortran.dg/g77/intrinsic-unix-bessel.f b/gcc/testsuite/gfortran.dg/g77/intrinsic-unix-bessel.f
index b388806..406a8e4 100644
--- a/gcc/testsuite/gfortran.dg/g77/intrinsic-unix-bessel.f
+++ b/gcc/testsuite/gfortran.dg/g77/intrinsic-unix-bessel.f
@@ -1,4 +1,5 @@
c { dg-do run }
+c { dg-options " " }
c intrinsic-unix-bessel.f
c
c Test Bessel function intrinsics.
diff --git a/gcc/testsuite/gfortran.dg/g77/intrinsic-unix-erf.f b/gcc/testsuite/gfortran.dg/g77/intrinsic-unix-erf.f
index 250519a..6ed9590 100644
--- a/gcc/testsuite/gfortran.dg/g77/intrinsic-unix-erf.f
+++ b/gcc/testsuite/gfortran.dg/g77/intrinsic-unix-erf.f
@@ -1,4 +1,5 @@
c { dg-do run }
+c { dg-options " " }
c intrinsic-unix-erf.f
c
c Test Bessel function intrinsics.
diff --git a/gcc/testsuite/gfortran.dg/initialization_9.f90 b/gcc/testsuite/gfortran.dg/initialization_9.f90
index d904047..fe7ca63 100644
--- a/gcc/testsuite/gfortran.dg/initialization_9.f90
+++ b/gcc/testsuite/gfortran.dg/initialization_9.f90
@@ -1,4 +1,5 @@
! { dg-do compile }
+! { dg-options " " }
!
! PR fortran/31639
! Contributed by Martin Michlmayr <tbm AT cyrius DOT com>
diff --git a/gcc/testsuite/gfortran.dg/intrinsic_actual_4.f90 b/gcc/testsuite/gfortran.dg/intrinsic_actual_4.f90
index 4521c96..3358b4a 100644
--- a/gcc/testsuite/gfortran.dg/intrinsic_actual_4.f90
+++ b/gcc/testsuite/gfortran.dg/intrinsic_actual_4.f90
@@ -1,4 +1,5 @@
! { dg-do run }
+! { dg-options " " }
! Tests the fix for PR27900, in which an ICE would be caused because
! the actual argument LEN had no type.
!
diff --git a/gcc/testsuite/gfortran.dg/namelist_assumed_char.f90 b/gcc/testsuite/gfortran.dg/namelist_assumed_char.f90
index b7d063c..25edf64 100644
--- a/gcc/testsuite/gfortran.dg/namelist_assumed_char.f90
+++ b/gcc/testsuite/gfortran.dg/namelist_assumed_char.f90
@@ -8,7 +8,7 @@
! Add -std=f95, add bar()
!
subroutine foo(c)
- character*(*) c
+ character*(*) c ! { dg-warning "Old-style character length" }
namelist /abc/ c ! { dg-error "nonconstant character length in namelist" }
end subroutine
diff --git a/gcc/testsuite/gfortran.dg/pr15140.f90 b/gcc/testsuite/gfortran.dg/pr15140.f90
index 80c08dd..7f9af4f 100644
--- a/gcc/testsuite/gfortran.dg/pr15140.f90
+++ b/gcc/testsuite/gfortran.dg/pr15140.f90
@@ -1,4 +1,5 @@
! { dg-do run }
+! { dg-options "-std=legacy" }
! PR 15140: we used to fail an assertion, because we don't use the
! argument of the subroutine directly, but instead use a copy of it.
function M(NAMES)
diff --git a/gcc/tree-cfg.cc b/gcc/tree-cfg.cc
index 1d20e6a..f0a5e05 100644
--- a/gcc/tree-cfg.cc
+++ b/gcc/tree-cfg.cc
@@ -10173,6 +10173,224 @@ make_pass_fixup_cfg (gcc::context *ctxt)
return new pass_fixup_cfg (ctxt);
}
+
+/* Sort PHI argument values for make_forwarders_with_degenerate_phis. */
+
+static int
+sort_phi_args (const void *a_, const void *b_)
+{
+ auto *a = (const std::pair<edge, hashval_t> *) a_;
+ auto *b = (const std::pair<edge, hashval_t> *) b_;
+ hashval_t ha = a->second;
+ hashval_t hb = b->second;
+ if (ha < hb)
+ return -1;
+ else if (ha > hb)
+ return 1;
+ else if (a->first->dest_idx < b->first->dest_idx)
+ return -1;
+ else if (a->first->dest_idx > b->first->dest_idx)
+ return 1;
+ else
+ return 0;
+}
+
+/* Look for a non-virtual PHIs and make a forwarder block when all PHIs
+ have the same argument on a set of edges. This is to not consider
+ control dependences of individual edges for same values but only for
+ the common set. Returns true if changed the CFG. */
+
+bool
+make_forwarders_with_degenerate_phis (function *fn)
+{
+ bool didsomething = false;
+
+ basic_block bb;
+ FOR_EACH_BB_FN (bb, fn)
+ {
+ /* Only PHIs with three or more arguments have opportunities. */
+ if (EDGE_COUNT (bb->preds) < 3)
+ continue;
+ /* Do not touch loop headers or blocks with abnormal predecessors.
+ ??? This is to avoid creating valid loops here, see PR103458.
+ We might want to improve things to either explicitely add those
+ loops or at least consider blocks with no backedges. */
+ if (bb->loop_father->header == bb
+ || bb_has_abnormal_pred (bb))
+ continue;
+
+ /* Take one PHI node as template to look for identical
+ arguments. Build a vector of candidates forming sets
+ of argument edges with equal values. Note optimality
+ depends on the particular choice of the template PHI
+ since equal arguments are unordered leaving other PHIs
+ with more than one set of equal arguments within this
+ argument range unsorted. We'd have to break ties by
+ looking at other PHI nodes. */
+ gphi_iterator gsi = gsi_start_nonvirtual_phis (bb);
+ if (gsi_end_p (gsi))
+ continue;
+ gphi *phi = gsi.phi ();
+ auto_vec<std::pair<edge, hashval_t>, 8> args;
+ bool need_resort = false;
+ for (unsigned i = 0; i < gimple_phi_num_args (phi); ++i)
+ {
+ edge e = gimple_phi_arg_edge (phi, i);
+ /* Skip abnormal edges since we cannot redirect them. */
+ if (e->flags & EDGE_ABNORMAL)
+ continue;
+ /* Skip loop exit edges when we are in loop-closed SSA form
+ since the forwarder we'd create does not have a PHI node. */
+ if (loops_state_satisfies_p (LOOP_CLOSED_SSA)
+ && loop_exit_edge_p (e->src->loop_father, e))
+ continue;
+
+ tree arg = gimple_phi_arg_def (phi, i);
+ if (!CONSTANT_CLASS_P (arg) && TREE_CODE (arg) != SSA_NAME)
+ need_resort = true;
+ args.safe_push (std::make_pair (e, iterative_hash_expr (arg, 0)));
+ }
+ if (args.length () < 2)
+ continue;
+ args.qsort (sort_phi_args);
+ /* The above sorting can be different between -g and -g0, as e.g. decls
+ can have different uids (-g could have bigger gaps in between them).
+ So, only use that to determine which args are equal, then change
+ second from hash value to smallest dest_idx of the edges which have
+ equal argument and sort again. If all the phi arguments are
+ constants or SSA_NAME, there is no need for the second sort, the hash
+ values are stable in that case. */
+ hashval_t hash = args[0].second;
+ args[0].second = args[0].first->dest_idx;
+ bool any_equal = false;
+ for (unsigned i = 1; i < args.length (); ++i)
+ if (hash == args[i].second
+ && operand_equal_p (PHI_ARG_DEF_FROM_EDGE (phi, args[i - 1].first),
+ PHI_ARG_DEF_FROM_EDGE (phi, args[i].first)))
+ {
+ args[i].second = args[i - 1].second;
+ any_equal = true;
+ }
+ else
+ {
+ hash = args[i].second;
+ args[i].second = args[i].first->dest_idx;
+ }
+ if (!any_equal)
+ continue;
+ if (need_resort)
+ args.qsort (sort_phi_args);
+
+ /* From the candidates vector now verify true candidates for
+ forwarders and create them. */
+ gphi *vphi = get_virtual_phi (bb);
+ unsigned start = 0;
+ while (start < args.length () - 1)
+ {
+ unsigned i;
+ for (i = start + 1; i < args.length (); ++i)
+ if (args[start].second != args[i].second)
+ break;
+ /* args[start]..args[i-1] are equal. */
+ if (start != i - 1)
+ {
+ /* Check all PHI nodes for argument equality
+ except for vops. */
+ bool equal = true;
+ gphi_iterator gsi2 = gsi;
+ gsi_next (&gsi2);
+ for (; !gsi_end_p (gsi2); gsi_next (&gsi2))
+ {
+ gphi *phi2 = gsi2.phi ();
+ if (virtual_operand_p (gimple_phi_result (phi2)))
+ continue;
+ tree start_arg
+ = PHI_ARG_DEF_FROM_EDGE (phi2, args[start].first);
+ for (unsigned j = start + 1; j < i; ++j)
+ {
+ if (!operand_equal_p (start_arg,
+ PHI_ARG_DEF_FROM_EDGE
+ (phi2, args[j].first)))
+ {
+ /* Another PHI might have a shorter set of
+ equivalent args. Go for that. */
+ i = j;
+ if (j == start + 1)
+ equal = false;
+ break;
+ }
+ }
+ if (!equal)
+ break;
+ }
+ if (equal)
+ {
+ /* If we are asked to forward all edges the block
+ has all degenerate PHIs. Do nothing in that case. */
+ if (start == 0
+ && i == args.length ()
+ && args.length () == gimple_phi_num_args (phi))
+ break;
+ /* Instead of using make_forwarder_block we are
+ rolling our own variant knowing that the forwarder
+ does not need PHI nodes apart from eventually
+ a virtual one. */
+ auto_vec<tree, 8> vphi_args;
+ if (vphi)
+ {
+ vphi_args.reserve_exact (i - start);
+ for (unsigned j = start; j < i; ++j)
+ vphi_args.quick_push
+ (PHI_ARG_DEF_FROM_EDGE (vphi, args[j].first));
+ }
+ free_dominance_info (fn, CDI_DOMINATORS);
+ if (dump_file && (dump_flags & TDF_DETAILS))
+ {
+ fprintf (dump_file, "New forwarder block for edge ");
+ fprintf (dump_file, "%d -> %d.\n",
+ args[start].first->src->index,
+ args[start].first->dest->index);
+ }
+ basic_block forwarder = split_edge (args[start].first);
+ profile_count count = profile_count::zero ();
+ bool irr = false;
+ for (unsigned j = start + 1; j < i; ++j)
+ {
+ edge e = args[j].first;
+ if (e->flags & EDGE_IRREDUCIBLE_LOOP)
+ irr = true;
+ redirect_edge_and_branch_force (e, forwarder);
+ redirect_edge_var_map_clear (e);
+ count += e->count ();
+ }
+ forwarder->count = count;
+ if (irr)
+ {
+ forwarder->flags |= BB_IRREDUCIBLE_LOOP;
+ single_succ_edge (forwarder)->flags
+ |= EDGE_IRREDUCIBLE_LOOP;
+ }
+
+ if (vphi)
+ {
+ tree def = copy_ssa_name (vphi_args[0]);
+ gphi *vphi_copy = create_phi_node (def, forwarder);
+ for (unsigned j = start; j < i; ++j)
+ add_phi_arg (vphi_copy, vphi_args[j - start],
+ args[j].first, UNKNOWN_LOCATION);
+ SET_PHI_ARG_DEF
+ (vphi, single_succ_edge (forwarder)->dest_idx, def);
+ }
+ didsomething = true;
+ }
+ }
+ /* Continue searching for more opportunities. */
+ start = i;
+ }
+ }
+ return didsomething;
+}
+
/* Garbage collection support for edge_def. */
extern void gt_ggc_mx (tree&);
diff --git a/gcc/tree-cfg.h b/gcc/tree-cfg.h
index 520bb3a..2e01762 100644
--- a/gcc/tree-cfg.h
+++ b/gcc/tree-cfg.h
@@ -114,6 +114,7 @@ extern edge gimple_switch_edge (function *, gswitch *, unsigned);
extern edge gimple_switch_default_edge (function *, gswitch *);
extern bool cond_only_block_p (basic_block);
extern void copy_phi_arg_into_existing_phi (edge, edge, bool = false);
+extern bool make_forwarders_with_degenerate_phis (function *);
/* Return true if the LHS of a call should be removed. */
diff --git a/gcc/tree-cfgcleanup.cc b/gcc/tree-cfgcleanup.cc
index 872ded3..093fde9 100644
--- a/gcc/tree-cfgcleanup.cc
+++ b/gcc/tree-cfgcleanup.cc
@@ -1415,8 +1415,13 @@ execute_cleanup_cfg_post_optimizing (void)
}
maybe_remove_unreachable_handlers ();
cleanup_dead_labels ();
- if (group_case_labels ())
- todo |= TODO_cleanup_cfg;
+ if (group_case_labels () && cleanup_tree_cfg ())
+ todo |= TODO_update_ssa;
+
+ /* When optimizing undo the merging of forwarder blocks
+ that phis for better out of ssa expansion. */
+ if (optimize)
+ make_forwarders_with_degenerate_phis (cfun);
basic_block bb = single_succ (ENTRY_BLOCK_PTR_FOR_FN (cfun));
gimple_stmt_iterator gsi = gsi_start_nondebug_after_labels_bb (bb);
diff --git a/gcc/tree-ssa-dce.cc b/gcc/tree-ssa-dce.cc
index 317a0d6..9a9f6f9 100644
--- a/gcc/tree-ssa-dce.cc
+++ b/gcc/tree-ssa-dce.cc
@@ -1940,214 +1940,6 @@ tree_dce_done (bool aggressive)
worklist.release ();
}
-/* Sort PHI argument values for make_forwarders_with_degenerate_phis. */
-
-static int
-sort_phi_args (const void *a_, const void *b_)
-{
- auto *a = (const std::pair<edge, hashval_t> *) a_;
- auto *b = (const std::pair<edge, hashval_t> *) b_;
- hashval_t ha = a->second;
- hashval_t hb = b->second;
- if (ha < hb)
- return -1;
- else if (ha > hb)
- return 1;
- else if (a->first->dest_idx < b->first->dest_idx)
- return -1;
- else if (a->first->dest_idx > b->first->dest_idx)
- return 1;
- else
- return 0;
-}
-
-/* Look for a non-virtual PHIs and make a forwarder block when all PHIs
- have the same argument on a set of edges. This is to not consider
- control dependences of individual edges for same values but only for
- the common set. */
-
-static unsigned
-make_forwarders_with_degenerate_phis (function *fn)
-{
- unsigned todo = 0;
-
- basic_block bb;
- FOR_EACH_BB_FN (bb, fn)
- {
- /* Only PHIs with three or more arguments have opportunities. */
- if (EDGE_COUNT (bb->preds) < 3)
- continue;
- /* Do not touch loop headers or blocks with abnormal predecessors.
- ??? This is to avoid creating valid loops here, see PR103458.
- We might want to improve things to either explicitely add those
- loops or at least consider blocks with no backedges. */
- if (bb->loop_father->header == bb
- || bb_has_abnormal_pred (bb))
- continue;
-
- /* Take one PHI node as template to look for identical
- arguments. Build a vector of candidates forming sets
- of argument edges with equal values. Note optimality
- depends on the particular choice of the template PHI
- since equal arguments are unordered leaving other PHIs
- with more than one set of equal arguments within this
- argument range unsorted. We'd have to break ties by
- looking at other PHI nodes. */
- gphi_iterator gsi = gsi_start_nonvirtual_phis (bb);
- if (gsi_end_p (gsi))
- continue;
- gphi *phi = gsi.phi ();
- auto_vec<std::pair<edge, hashval_t>, 8> args;
- bool need_resort = false;
- for (unsigned i = 0; i < gimple_phi_num_args (phi); ++i)
- {
- edge e = gimple_phi_arg_edge (phi, i);
- /* Skip abnormal edges since we cannot redirect them. */
- if (e->flags & EDGE_ABNORMAL)
- continue;
- /* Skip loop exit edges when we are in loop-closed SSA form
- since the forwarder we'd create does not have a PHI node. */
- if (loops_state_satisfies_p (LOOP_CLOSED_SSA)
- && loop_exit_edge_p (e->src->loop_father, e))
- continue;
-
- tree arg = gimple_phi_arg_def (phi, i);
- if (!CONSTANT_CLASS_P (arg) && TREE_CODE (arg) != SSA_NAME)
- need_resort = true;
- args.safe_push (std::make_pair (e, iterative_hash_expr (arg, 0)));
- }
- if (args.length () < 2)
- continue;
- args.qsort (sort_phi_args);
- /* The above sorting can be different between -g and -g0, as e.g. decls
- can have different uids (-g could have bigger gaps in between them).
- So, only use that to determine which args are equal, then change
- second from hash value to smallest dest_idx of the edges which have
- equal argument and sort again. If all the phi arguments are
- constants or SSA_NAME, there is no need for the second sort, the hash
- values are stable in that case. */
- hashval_t hash = args[0].second;
- args[0].second = args[0].first->dest_idx;
- bool any_equal = false;
- for (unsigned i = 1; i < args.length (); ++i)
- if (hash == args[i].second
- && operand_equal_p (PHI_ARG_DEF_FROM_EDGE (phi, args[i - 1].first),
- PHI_ARG_DEF_FROM_EDGE (phi, args[i].first)))
- {
- args[i].second = args[i - 1].second;
- any_equal = true;
- }
- else
- {
- hash = args[i].second;
- args[i].second = args[i].first->dest_idx;
- }
- if (!any_equal)
- continue;
- if (need_resort)
- args.qsort (sort_phi_args);
-
- /* From the candidates vector now verify true candidates for
- forwarders and create them. */
- gphi *vphi = get_virtual_phi (bb);
- unsigned start = 0;
- while (start < args.length () - 1)
- {
- unsigned i;
- for (i = start + 1; i < args.length (); ++i)
- if (args[start].second != args[i].second)
- break;
- /* args[start]..args[i-1] are equal. */
- if (start != i - 1)
- {
- /* Check all PHI nodes for argument equality. */
- bool equal = true;
- gphi_iterator gsi2 = gsi;
- gsi_next (&gsi2);
- for (; !gsi_end_p (gsi2); gsi_next (&gsi2))
- {
- gphi *phi2 = gsi2.phi ();
- if (virtual_operand_p (gimple_phi_result (phi2)))
- continue;
- tree start_arg
- = PHI_ARG_DEF_FROM_EDGE (phi2, args[start].first);
- for (unsigned j = start + 1; j < i; ++j)
- {
- if (!operand_equal_p (start_arg,
- PHI_ARG_DEF_FROM_EDGE
- (phi2, args[j].first)))
- {
- /* Another PHI might have a shorter set of
- equivalent args. Go for that. */
- i = j;
- if (j == start + 1)
- equal = false;
- break;
- }
- }
- if (!equal)
- break;
- }
- if (equal)
- {
- /* If we are asked to forward all edges the block
- has all degenerate PHIs. Do nothing in that case. */
- if (start == 0
- && i == args.length ()
- && args.length () == gimple_phi_num_args (phi))
- break;
- /* Instead of using make_forwarder_block we are
- rolling our own variant knowing that the forwarder
- does not need PHI nodes apart from eventually
- a virtual one. */
- auto_vec<tree, 8> vphi_args;
- if (vphi)
- {
- vphi_args.reserve_exact (i - start);
- for (unsigned j = start; j < i; ++j)
- vphi_args.quick_push
- (PHI_ARG_DEF_FROM_EDGE (vphi, args[j].first));
- }
- free_dominance_info (fn, CDI_DOMINATORS);
- basic_block forwarder = split_edge (args[start].first);
- profile_count count = profile_count::zero ();
- bool irr = false;
- for (unsigned j = start + 1; j < i; ++j)
- {
- edge e = args[j].first;
- if (e->flags & EDGE_IRREDUCIBLE_LOOP)
- irr = true;
- redirect_edge_and_branch_force (e, forwarder);
- redirect_edge_var_map_clear (e);
- count += e->count ();
- }
- forwarder->count = count;
- if (irr)
- {
- forwarder->flags |= BB_IRREDUCIBLE_LOOP;
- single_succ_edge (forwarder)->flags
- |= EDGE_IRREDUCIBLE_LOOP;
- }
-
- if (vphi)
- {
- tree def = copy_ssa_name (vphi_args[0]);
- gphi *vphi_copy = create_phi_node (def, forwarder);
- for (unsigned j = start; j < i; ++j)
- add_phi_arg (vphi_copy, vphi_args[j - start],
- args[j].first, UNKNOWN_LOCATION);
- SET_PHI_ARG_DEF
- (vphi, single_succ_edge (forwarder)->dest_idx, def);
- }
- todo |= TODO_cleanup_cfg;
- }
- }
- /* Continue searching for more opportunities. */
- start = i;
- }
- }
- return todo;
-}
/* Main routine to eliminate dead code.
@@ -2174,8 +1966,8 @@ perform_tree_ssa_dce (bool aggressive)
scev_initialize ();
}
- if (aggressive)
- todo |= make_forwarders_with_degenerate_phis (cfun);
+ if (aggressive && make_forwarders_with_degenerate_phis (cfun))
+ todo |= TODO_cleanup_cfg;
calculate_dominance_info (CDI_DOMINATORS);
diff --git a/gcc/tree-ssa-sccvn.cc b/gcc/tree-ssa-sccvn.cc
index 09f92b2..0c519cf 100644
--- a/gcc/tree-ssa-sccvn.cc
+++ b/gcc/tree-ssa-sccvn.cc
@@ -2527,7 +2527,10 @@ vn_nary_build_or_lookup_1 (gimple_match_op *res_op, bool insert,
else
{
tree val = vn_lookup_simplify_result (res_op);
- if (!val && insert)
+ /* ??? In weird cases we can end up with internal-fn calls,
+ but this isn't expected so throw the result away. See
+ PR123040 for an example. */
+ if (!val && insert && res_op->code.is_tree_code ())
{
gimple_seq stmts = NULL;
result = maybe_push_res_to_seq (res_op, &stmts);
diff --git a/gcc/tree-vect-patterns.cc b/gcc/tree-vect-patterns.cc
index 555986b..af64cb8 100644
--- a/gcc/tree-vect-patterns.cc
+++ b/gcc/tree-vect-patterns.cc
@@ -1914,6 +1914,9 @@ vect_recog_ctz_ffs_pattern (vec_info *vinfo, stmt_vec_info stmt_vinfo,
&& val_new == prec)
|| (ifnnew == IFN_POPCOUNT && ifn == IFN_CTZ))
{
+ if (vect_is_reduction (stmt_vinfo))
+ return NULL;
+
/* .CTZ (X) = PREC - .CLZ ((X - 1) & ~X)
.CTZ (X) = .POPCOUNT ((X - 1) & ~X). */
if (ifnnew == IFN_CLZ)
@@ -1952,6 +1955,9 @@ vect_recog_ctz_ffs_pattern (vec_info *vinfo, stmt_vec_info stmt_vinfo,
}
else if (ifnnew == IFN_CLZ)
{
+ if (vect_is_reduction (stmt_vinfo))
+ return NULL;
+
/* .CTZ (X) = (PREC - 1) - .CLZ (X & -X)
.FFS (X) = PREC - .CLZ (X & -X). */
sub = prec - (ifn == IFN_CTZ);
@@ -1971,6 +1977,9 @@ vect_recog_ctz_ffs_pattern (vec_info *vinfo, stmt_vec_info stmt_vinfo,
}
else if (ifnnew == IFN_POPCOUNT)
{
+ if (vect_is_reduction (stmt_vinfo))
+ return NULL;
+
/* .CTZ (X) = PREC - .POPCOUNT (X | -X)
.FFS (X) = (PREC + 1) - .POPCOUNT (X | -X). */
sub = prec + (ifn == IFN_FFS);
@@ -1993,6 +2002,11 @@ vect_recog_ctz_ffs_pattern (vec_info *vinfo, stmt_vec_info stmt_vinfo,
/* .FFS (X) = .CTZ (X) + 1. */
add = 1;
val_cmp++;
+
+ if (vect_is_reduction (stmt_vinfo)
+ && defined_at_zero
+ && (!defined_at_zero_new || val != val_cmp))
+ return NULL;
}
/* Create B = .IFNNEW (A). */
diff --git a/gcc/tree-vect-stmts.cc b/gcc/tree-vect-stmts.cc
index dc155dc..95f015f 100644
--- a/gcc/tree-vect-stmts.cc
+++ b/gcc/tree-vect-stmts.cc
@@ -9920,36 +9920,35 @@ vectorizable_load (vec_info *vinfo,
bool hoist_p = (LOOP_VINFO_NO_DATA_DEPENDENCIES (loop_vinfo)
&& !nested_in_vect_loop);
- /* It is unsafe to hoist a conditional load over the conditions that make
- it valid. When early break this means that any invariant load can't be
- hoisted unless it's in the loop header or if we know something else has
- verified the load is valid to do. Alignment peeling would do this
- since getting through the prologue means the load was done at least
- once and so the vector main body is free to hoist it. However today
- GCC will hoist the load above the PFA loop. As such that makes it
- still invalid and so we can't allow it today. */
- auto stmt_bb
- = gimple_bb (STMT_VINFO_STMT (
- vect_orig_stmt (SLP_TREE_SCALAR_STMTS (slp_node)[0])));
- if (LOOP_VINFO_EARLY_BREAKS (loop_vinfo)
- && !DR_SCALAR_KNOWN_BOUNDS (dr_info)
- && stmt_bb != loop->header)
- {
- if (LOOP_VINFO_PEELING_FOR_ALIGNMENT (loop_vinfo)
- && dump_enabled_p ())
- dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+ bool uniform_p = true;
+ for (stmt_vec_info sinfo : SLP_TREE_SCALAR_STMTS (slp_node))
+ {
+ /* It is unsafe to hoist a conditional load over the conditions that
+ make it valid. When early break this means that any invariant load
+ can't be hoisted unless it's in the loop header or if we know
+ something else has verified the load is valid to do. Alignment
+ peeling would do this since getting through the prologue means the
+ load was done at least once and so the vector main body is free to
+ hoist it. However today GCC will hoist the load above the PFA
+ loop. As such that makes it still invalid and so we can't allow it
+ today. */
+ if (LOOP_VINFO_EARLY_BREAKS (loop_vinfo)
+ && !DR_SCALAR_KNOWN_BOUNDS (STMT_VINFO_DR_INFO (sinfo))
+ && gimple_bb (STMT_VINFO_STMT (vect_orig_stmt (sinfo)))
+ != loop->header)
+ {
+ if (LOOP_VINFO_PEELING_FOR_ALIGNMENT (loop_vinfo)
+ && dump_enabled_p ())
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
"not hoisting invariant load due to early break"
"constraints\n");
- else if (dump_enabled_p ())
- dump_printf_loc (MSG_NOTE, vect_location,
+ else if (dump_enabled_p ())
+ dump_printf_loc (MSG_NOTE, vect_location,
"not hoisting invariant load due to early break"
"constraints\n");
- hoist_p = false;
- }
+ hoist_p = false;
+ }
- bool uniform_p = true;
- for (stmt_vec_info sinfo : SLP_TREE_SCALAR_STMTS (slp_node))
- {
hoist_p = hoist_p && hoist_defs_of_uses (sinfo->stmt, loop, false);
if (sinfo != SLP_TREE_SCALAR_STMTS (slp_node)[0])
uniform_p = false;
diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog
index c01d044..c2a99de 100644
--- a/libstdc++-v3/ChangeLog
+++ b/libstdc++-v3/ChangeLog
@@ -1,3 +1,71 @@
+2025-12-08 Jonathan Wakely <jwakely@redhat.com>
+
+ PR libstdc++/122946
+ * include/bits/version.def (concepts): Set value to 202207.
+ * include/bits/version.h: Regenerate.
+ * include/std/concepts (__comparison_common_type_with_impl)
+ (__comparison_common_type_with): New helper concepts.
+ (equality_comparable_with): Use __comparison_common_type_with.
+ * libsupc++/compare (three_way_comparable_with): Likewise.
+ (__glibcxx_want_concepts): Define to get __cpp_lib_concepts
+ here.
+ * testsuite/std/concepts/concepts.compare/move_only.cc: New
+ test.
+
+2025-12-08 Jonathan Wakely <jwakely@redhat.com>
+
+ * include/bits/intcmp.h: Replace all uses of
+ __is_standard_integer with __is_signed_or_unsigned_integer.
+ * include/bits/max_size_type.h: Fix outdated comment.
+ * include/bits/sat_arith.h: Replace all uses of
+ __is_standard_integer with __is_signed_or_unsigned_integer.
+ * include/c_compatibility/stdckdint.h: Replace all uses of the
+ __cv_unqual_signed_or_unsigned_integer_type concept with
+ __is_signed_or_unsigned_integer.
+ (__cv_unqual_signed_or_unsigned_integer_type): Remove.
+ * include/ext/numeric_traits.h: Fix outdated comment.
+ * include/std/charconv (from_chars): Replace use of
+ __is_standard_integer with __is_signed_or_unsigned_integer.
+ Do not enable for cv-qualified char.
+ * include/std/mdspan: Likewise.
+ * include/std/type_traits (__is_unsigned_integer): Include
+ unsigned __int128 in type list.
+ (__is_signed_integer): Include signed __int128 in type list.
+ (__is_standard_integer): Rename to ...
+ (__is_signed_or_unsigned_integer): ... this.
+ * testsuite/23_containers/mdspan/extents/ctor_ints.cc: Test
+ with 128-bit integers.
+ * testsuite/23_containers/mdspan/submdspan/strided_slice.cc:
+ Likewise.
+ * testsuite/20_util/integer_comparisons/extended.cc: New test.
+ * testsuite/26_numerics/saturation/extended.cc: New test.
+ * testsuite/26_numerics/stdckdint/extended.cc: New test.
+
+2025-12-08 Tomasz Kamiński <tkaminsk@redhat.com>
+
+ PR libstdc++/112591
+ * include/std/variant (_Variadic_union): Separate specializations for
+ for union of only trivially destructible types (true as first template
+ argument). Unconditionally define destructor for _Variadic_union<false,
+ _First, _Rest...>.
+ * testsuite/20_util/variant/87619.cc: Add limit for the template depth.
+ * testsuite/20_util/variant/112591.cc: New test.
+
+2025-12-08 Jonathan Wakely <jwakely@redhat.com>
+
+ * include/bits/iterator_concepts.h: Remove diagnostic pragmas.
+
+2025-12-08 Jonathan Wakely <jwakely@redhat.com>
+
+ * include/Makefile.am: Add new header.
+ * include/Makefile.in: Regenerate.
+ * include/std/latch: Include <bits/intcmp.h> instead of
+ <utility>.
+ * include/std/utility: Include <bits/intcmp.h>.
+ (cmp_equal, cmp_not_equal, cmp_less, cmp_greater)
+ (cmp_less_equal, cmp_greater_equal, in_range): Move to ...
+ * include/bits/intcmp.h: New file.
+
2025-12-06 Jason Merrill <jason@redhat.com>
* src/c++23/std.cc.in: Add more #if.
diff --git a/libstdc++-v3/include/Makefile.am b/libstdc++-v3/include/Makefile.am
index 7d65c6f..847fc13 100644
--- a/libstdc++-v3/include/Makefile.am
+++ b/libstdc++-v3/include/Makefile.am
@@ -134,6 +134,7 @@ bits_freestanding = \
${bits_srcdir}/enable_special_members.h \
${bits_srcdir}/functexcept.h \
${bits_srcdir}/functional_hash.h \
+ ${bits_srcdir}/intcmp.h \
${bits_srcdir}/invoke.h \
${bits_srcdir}/iterator_concepts.h \
${bits_srcdir}/max_size_type.h \
diff --git a/libstdc++-v3/include/Makefile.in b/libstdc++-v3/include/Makefile.in
index acf8ae9..1d6171b 100644
--- a/libstdc++-v3/include/Makefile.in
+++ b/libstdc++-v3/include/Makefile.in
@@ -492,6 +492,7 @@ bits_freestanding = \
${bits_srcdir}/enable_special_members.h \
${bits_srcdir}/functexcept.h \
${bits_srcdir}/functional_hash.h \
+ ${bits_srcdir}/intcmp.h \
${bits_srcdir}/invoke.h \
${bits_srcdir}/iterator_concepts.h \
${bits_srcdir}/max_size_type.h \
diff --git a/libstdc++-v3/include/bits/intcmp.h b/libstdc++-v3/include/bits/intcmp.h
new file mode 100644
index 0000000..bb9c7f2
--- /dev/null
+++ b/libstdc++-v3/include/bits/intcmp.h
@@ -0,0 +1,120 @@
+// Integer comparison functions -*- C++ -*-
+
+// Copyright (C) 2020-2025 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// Under Section 7 of GPL version 3, you are granted additional
+// permissions described in the GCC Runtime Library Exception, version
+// 3.1, as published by the Free Software Foundation.
+
+// You should have received a copy of the GNU General Public License and
+// a copy of the GCC Runtime Library Exception along with this program;
+// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
+// <http://www.gnu.org/licenses/>.
+
+/** @file bits/intcmp.h
+ * This is an internal header file, included by other library headers.
+ * Do not attempt to use it directly. @headername{utility}
+ */
+
+#ifndef _GLIBCXX_INTCMP_H
+#define _GLIBCXX_INTCMP_H 1
+
+#ifdef _GLIBCXX_SYSHDR
+#pragma GCC system_header
+#endif
+
+#include <bits/version.h>
+
+#ifdef __glibcxx_integer_comparison_functions // C++ >= 20
+
+#include <type_traits>
+#include <ext/numeric_traits.h> // __int_traits
+
+namespace std _GLIBCXX_VISIBILITY(default)
+{
+_GLIBCXX_BEGIN_NAMESPACE_VERSION
+
+ template<typename _Tp, typename _Up>
+ constexpr bool
+ cmp_equal(_Tp __t, _Up __u) noexcept
+ {
+ static_assert(__is_signed_or_unsigned_integer<_Tp>::value);
+ static_assert(__is_signed_or_unsigned_integer<_Up>::value);
+
+ if constexpr (is_signed_v<_Tp> == is_signed_v<_Up>)
+ return __t == __u;
+ else if constexpr (is_signed_v<_Tp>)
+ return __t >= 0 && make_unsigned_t<_Tp>(__t) == __u;
+ else
+ return __u >= 0 && __t == make_unsigned_t<_Up>(__u);
+ }
+
+ template<typename _Tp, typename _Up>
+ constexpr bool
+ cmp_not_equal(_Tp __t, _Up __u) noexcept
+ { return !std::cmp_equal(__t, __u); }
+
+ template<typename _Tp, typename _Up>
+ constexpr bool
+ cmp_less(_Tp __t, _Up __u) noexcept
+ {
+ static_assert(__is_signed_or_unsigned_integer<_Tp>::value);
+ static_assert(__is_signed_or_unsigned_integer<_Up>::value);
+
+ if constexpr (is_signed_v<_Tp> == is_signed_v<_Up>)
+ return __t < __u;
+ else if constexpr (is_signed_v<_Tp>)
+ return __t < 0 || make_unsigned_t<_Tp>(__t) < __u;
+ else
+ return __u >= 0 && __t < make_unsigned_t<_Up>(__u);
+ }
+
+ template<typename _Tp, typename _Up>
+ constexpr bool
+ cmp_greater(_Tp __t, _Up __u) noexcept
+ { return std::cmp_less(__u, __t); }
+
+ template<typename _Tp, typename _Up>
+ constexpr bool
+ cmp_less_equal(_Tp __t, _Up __u) noexcept
+ { return !std::cmp_less(__u, __t); }
+
+ template<typename _Tp, typename _Up>
+ constexpr bool
+ cmp_greater_equal(_Tp __t, _Up __u) noexcept
+ { return !std::cmp_less(__t, __u); }
+
+ template<typename _Res, typename _Tp>
+ constexpr bool
+ in_range(_Tp __t) noexcept
+ {
+ static_assert(__is_signed_or_unsigned_integer<_Res>::value);
+ static_assert(__is_signed_or_unsigned_integer<_Tp>::value);
+ using __gnu_cxx::__int_traits;
+
+ if constexpr (is_signed_v<_Tp> == is_signed_v<_Res>)
+ return __int_traits<_Res>::__min <= __t
+ && __t <= __int_traits<_Res>::__max;
+ else if constexpr (is_signed_v<_Tp>)
+ return __t >= 0
+ && make_unsigned_t<_Tp>(__t) <= __int_traits<_Res>::__max;
+ else
+ return __t <= make_unsigned_t<_Res>(__int_traits<_Res>::__max);
+ }
+
+_GLIBCXX_END_NAMESPACE_VERSION
+} // namespace
+
+#endif // __glibcxx_integer_comparison_functions
+#endif // _GLIBCXX_INTCMP_H
diff --git a/libstdc++-v3/include/bits/iterator_concepts.h b/libstdc++-v3/include/bits/iterator_concepts.h
index fd91b22..40ac808 100644
--- a/libstdc++-v3/include/bits/iterator_concepts.h
+++ b/libstdc++-v3/include/bits/iterator_concepts.h
@@ -39,9 +39,6 @@
#include <bits/ptr_traits.h> // to_address
#include <bits/ranges_cmp.h> // identity, ranges::less
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wpedantic" // __int128
-
namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
@@ -1032,6 +1029,5 @@ namespace ranges
#endif // C++20 library concepts
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace std
-#pragma GCC diagnostic pop
#endif // C++20
#endif // _ITERATOR_CONCEPTS_H
diff --git a/libstdc++-v3/include/bits/max_size_type.h b/libstdc++-v3/include/bits/max_size_type.h
index a34b91a..537acee 100644
--- a/libstdc++-v3/include/bits/max_size_type.h
+++ b/libstdc++-v3/include/bits/max_size_type.h
@@ -44,10 +44,8 @@
// [iterator.concept.winc]) that are one bit wider than the widest supported
// integer type.
//
-// The set of integer types we consider includes __int128 and unsigned __int128
-// (when they exist), even though they are really integer types only in GNU
-// mode. This is to obtain a consistent ABI for these integer-class types
-// across strict mode and GNU mode.
+// The set of integer types we consider includes the extended integer types
+// __int128 and unsigned __int128 (when they exist).
namespace std _GLIBCXX_VISIBILITY(default)
{
diff --git a/libstdc++-v3/include/bits/sat_arith.h b/libstdc++-v3/include/bits/sat_arith.h
index e036fc8..bce86d9 100644
--- a/libstdc++-v3/include/bits/sat_arith.h
+++ b/libstdc++-v3/include/bits/sat_arith.h
@@ -46,7 +46,7 @@ namespace std _GLIBCXX_VISIBILITY(default)
_GLIBCXX_BEGIN_NAMESPACE_VERSION
/// Add two integers, with saturation in case of overflow.
- template<typename _Tp> requires __is_standard_integer<_Tp>::value
+ template<typename _Tp> requires __is_signed_or_unsigned_integer<_Tp>::value
constexpr _Tp
add_sat(_Tp __x, _Tp __y) noexcept
{
@@ -62,7 +62,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
}
/// Subtract one integer from another, with saturation in case of overflow.
- template<typename _Tp> requires __is_standard_integer<_Tp>::value
+ template<typename _Tp> requires __is_signed_or_unsigned_integer<_Tp>::value
constexpr _Tp
sub_sat(_Tp __x, _Tp __y) noexcept
{
@@ -78,7 +78,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
}
/// Multiply two integers, with saturation in case of overflow.
- template<typename _Tp> requires __is_standard_integer<_Tp>::value
+ template<typename _Tp> requires __is_signed_or_unsigned_integer<_Tp>::value
constexpr _Tp
mul_sat(_Tp __x, _Tp __y) noexcept
{
@@ -94,7 +94,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
}
/// Divide one integer by another, with saturation in case of overflow.
- template<typename _Tp> requires __is_standard_integer<_Tp>::value
+ template<typename _Tp> requires __is_signed_or_unsigned_integer<_Tp>::value
constexpr _Tp
div_sat(_Tp __x, _Tp __y) noexcept
{
@@ -107,8 +107,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
/// Divide one integer by another, with saturation in case of overflow.
template<typename _Res, typename _Tp>
- requires __is_standard_integer<_Res>::value
- && __is_standard_integer<_Tp>::value
+ requires __is_signed_or_unsigned_integer<_Res>::value
+ && __is_signed_or_unsigned_integer<_Tp>::value
constexpr _Res
saturate_cast(_Tp __x) noexcept
{
diff --git a/libstdc++-v3/include/bits/version.def b/libstdc++-v3/include/bits/version.def
index 412b9ce..bbc8d38 100644
--- a/libstdc++-v3/include/bits/version.def
+++ b/libstdc++-v3/include/bits/version.def
@@ -879,8 +879,12 @@ ftms = {
ftms = {
name = concepts;
+ // 201806 P0898R3 Standard Library Concepts
+ // 201907 P1754R1 Rename concepts to standard_case for C++20
+ // 202002 P1964R2 Wording for boolean-testable
+ // 202207 P2404R3 Move-only types for equality_comparable_with, etc.
values = {
- v = 202002;
+ v = 202207;
cxxmin = 20;
extra_cond = "__cpp_concepts >= 201907L";
};
diff --git a/libstdc++-v3/include/bits/version.h b/libstdc++-v3/include/bits/version.h
index 2b96934..7ee9ae8 100644
--- a/libstdc++-v3/include/bits/version.h
+++ b/libstdc++-v3/include/bits/version.h
@@ -985,9 +985,9 @@
#if !defined(__cpp_lib_concepts)
# if (__cplusplus >= 202002L) && (__cpp_concepts >= 201907L)
-# define __glibcxx_concepts 202002L
+# define __glibcxx_concepts 202207L
# if defined(__glibcxx_want_all) || defined(__glibcxx_want_concepts)
-# define __cpp_lib_concepts 202002L
+# define __cpp_lib_concepts 202207L
# endif
# endif
#endif /* !defined(__cpp_lib_concepts) */
diff --git a/libstdc++-v3/include/c_compatibility/stdckdint.h b/libstdc++-v3/include/c_compatibility/stdckdint.h
index 1de2d18..5bdf4dc 100644
--- a/libstdc++-v3/include/c_compatibility/stdckdint.h
+++ b/libstdc++-v3/include/c_compatibility/stdckdint.h
@@ -40,15 +40,6 @@
namespace __gnu_cxx _GLIBCXX_VISIBILITY(default)
{
#endif
-/// @cond undocumented
-namespace __detail
-{
- template<typename _Tp>
- concept __cv_unqual_signed_or_unsigned_integer_type
- = std::same_as<_Tp, std::remove_cv_t<_Tp>>
- && std::__is_standard_integer<_Tp>::value;
-}
-/// @endcond
/** Checked integer arithmetic
*
@@ -71,10 +62,9 @@ template<typename _Tp1, typename _Tp2, typename _Tp3>
inline bool
ckd_add(_Tp1* __result, _Tp2 __a, _Tp3 __b)
{
- using __gnu_cxx::__detail::__cv_unqual_signed_or_unsigned_integer_type;
- static_assert(__cv_unqual_signed_or_unsigned_integer_type<_Tp1>);
- static_assert(__cv_unqual_signed_or_unsigned_integer_type<_Tp2>);
- static_assert(__cv_unqual_signed_or_unsigned_integer_type<_Tp3>);
+ static_assert(std::__is_signed_or_unsigned_integer<_Tp1>::value);
+ static_assert(std::__is_signed_or_unsigned_integer<_Tp2>::value);
+ static_assert(std::__is_signed_or_unsigned_integer<_Tp3>::value);
return __builtin_add_overflow(__a, __b, __result);
}
@@ -82,10 +72,9 @@ template<typename _Tp1, typename _Tp2, typename _Tp3>
inline bool
ckd_sub(_Tp1* __result, _Tp2 __a, _Tp3 __b)
{
- using __gnu_cxx::__detail::__cv_unqual_signed_or_unsigned_integer_type;
- static_assert(__cv_unqual_signed_or_unsigned_integer_type<_Tp1>);
- static_assert(__cv_unqual_signed_or_unsigned_integer_type<_Tp2>);
- static_assert(__cv_unqual_signed_or_unsigned_integer_type<_Tp3>);
+ static_assert(std::__is_signed_or_unsigned_integer<_Tp1>::value);
+ static_assert(std::__is_signed_or_unsigned_integer<_Tp2>::value);
+ static_assert(std::__is_signed_or_unsigned_integer<_Tp3>::value);
return __builtin_sub_overflow(__a, __b, __result);
}
@@ -93,15 +82,14 @@ template<typename _Tp1, typename _Tp2, typename _Tp3>
inline bool
ckd_mul(_Tp1* __result, _Tp2 __a, _Tp3 __b)
{
- using __gnu_cxx::__detail::__cv_unqual_signed_or_unsigned_integer_type;
- static_assert(__cv_unqual_signed_or_unsigned_integer_type<_Tp1>);
- static_assert(__cv_unqual_signed_or_unsigned_integer_type<_Tp2>);
- static_assert(__cv_unqual_signed_or_unsigned_integer_type<_Tp3>);
+ static_assert(std::__is_signed_or_unsigned_integer<_Tp1>::value);
+ static_assert(std::__is_signed_or_unsigned_integer<_Tp2>::value);
+ static_assert(std::__is_signed_or_unsigned_integer<_Tp3>::value);
return __builtin_mul_overflow(__a, __b, __result);
}
/// @}
#ifndef _GLIBCXX_DOXYGEN
-}
+} // namespace __gnu_cxx
using __gnu_cxx::ckd_add;
using __gnu_cxx::ckd_sub;
diff --git a/libstdc++-v3/include/ext/numeric_traits.h b/libstdc++-v3/include/ext/numeric_traits.h
index 6786dc6..78cb8e3 100644
--- a/libstdc++-v3/include/ext/numeric_traits.h
+++ b/libstdc++-v3/include/ext/numeric_traits.h
@@ -48,7 +48,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
// or is_signed, digits10, max_digits10, or max_exponent10 for floats.
// Unlike __is_integer (and std::is_integral) this trait is true for
- // non-standard built-in integer types such as __int128 and __int20.
+ // non-standard built-in integer types such as __int20.
template<typename _Tp>
struct __is_integer_nonstrict
: public std::__is_integer<_Tp>
diff --git a/libstdc++-v3/include/std/charconv b/libstdc++-v3/include/std/charconv
index 8cf2c0b..47f5aaa 100644
--- a/libstdc++-v3/include/std/charconv
+++ b/libstdc++-v3/include/std/charconv
@@ -554,10 +554,10 @@ namespace __detail
} // namespace __detail
- /// std::from_chars for integral types.
+ /// std::from_chars for integer types.
template<typename _Tp,
- enable_if_t<__or_<__is_standard_integer<_Tp>,
- is_same<char, remove_cv_t<_Tp>>>::value, int> = 0>
+ enable_if_t<__or_<__is_signed_or_unsigned_integer<_Tp>,
+ is_same<char, _Tp>>::value, int> = 0>
_GLIBCXX23_CONSTEXPR from_chars_result
from_chars(const char* __first, const char* __last, _Tp& __value,
int __base = 10)
diff --git a/libstdc++-v3/include/std/concepts b/libstdc++-v3/include/std/concepts
index d9920a8..870b0a4 100644
--- a/libstdc++-v3/include/std/concepts
+++ b/libstdc++-v3/include/std/concepts
@@ -296,6 +296,27 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
{ { !static_cast<_Tp&&>(__t) } -> __boolean_testable_impl; };
} // namespace __detail
+ // [concept.comparisoncommontype], helpers for comparison common types
+ namespace __detail
+ {
+ template<typename _Tp, typename _Up,
+ typename _Cref = common_reference_t<const _Tp&, const _Up&>>
+ concept __comparison_common_type_with_impl
+ = same_as<common_reference_t<const _Tp&, const _Up&>,
+ common_reference_t<const _Up&, const _Tp&>>
+ && requires {
+ requires convertible_to<const _Tp&, const _Cref&>
+ || convertible_to<_Tp, const _Cref&>;
+ requires convertible_to<const _Up&, const _Cref&>
+ || convertible_to<_Up, const _Cref&>;
+ };
+
+ template<typename _Tp, typename _Up>
+ concept __comparison_common_type_with
+ = __comparison_common_type_with_impl<remove_cvref_t<_Tp>,
+ remove_cvref_t<_Up>>;
+ } // namespace __detail
+
// [concept.equalitycomparable], concept equality_comparable
namespace __detail
@@ -316,7 +337,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
template<typename _Tp, typename _Up>
concept equality_comparable_with
= equality_comparable<_Tp> && equality_comparable<_Up>
- && common_reference_with<__detail::__cref<_Tp>, __detail::__cref<_Up>>
+ && __detail::__comparison_common_type_with<_Tp, _Up>
&& equality_comparable<common_reference_t<__detail::__cref<_Tp>,
__detail::__cref<_Up>>>
&& __detail::__weakly_eq_cmp_with<_Tp, _Up>;
diff --git a/libstdc++-v3/include/std/latch b/libstdc++-v3/include/std/latch
index 9504df0..df126c6 100644
--- a/libstdc++-v3/include/std/latch
+++ b/libstdc++-v3/include/std/latch
@@ -41,7 +41,7 @@
#ifdef __cpp_lib_latch // C++ >= 20 && atomic_wait
#include <bits/atomic_base.h>
#include <ext/numeric_traits.h>
-#include <utility> // cmp_equal, cmp_less_equal, etc.
+#include <bits/intcmp.h> // cmp_equal, cmp_less_equal, etc.
namespace std _GLIBCXX_VISIBILITY(default)
{
diff --git a/libstdc++-v3/include/std/mdspan b/libstdc++-v3/include/std/mdspan
index 03cc4f0..981fa1c 100644
--- a/libstdc++-v3/include/std/mdspan
+++ b/libstdc++-v3/include/std/mdspan
@@ -352,11 +352,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
template<typename _OffsetType, typename _ExtentType, typename _StrideType>
struct strided_slice
{
- static_assert(__is_standard_integer<_OffsetType>::value
+ static_assert(__is_signed_or_unsigned_integer<_OffsetType>::value
|| __detail::__integral_constant_like<_OffsetType>);
- static_assert(__is_standard_integer<_ExtentType>::value
+ static_assert(__is_signed_or_unsigned_integer<_ExtentType>::value
|| __detail::__integral_constant_like<_ExtentType>);
- static_assert(__is_standard_integer<_StrideType>::value
+ static_assert(__is_signed_or_unsigned_integer<_StrideType>::value
|| __detail::__integral_constant_like<_StrideType>);
using offset_type = _OffsetType;
@@ -379,7 +379,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
template<typename _IndexType, size_t... _Extents>
class extents
{
- static_assert(__is_standard_integer<_IndexType>::value,
+ static_assert(__is_signed_or_unsigned_integer<_IndexType>::value,
"IndexType must be a signed or unsigned integer type");
static_assert(
(__mdspan::__valid_static_extent<_Extents, _IndexType> && ...),
diff --git a/libstdc++-v3/include/std/type_traits b/libstdc++-v3/include/std/type_traits
index 7c157ea..3f0bcc4e 100644
--- a/libstdc++-v3/include/std/type_traits
+++ b/libstdc++-v3/include/std/type_traits
@@ -826,7 +826,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
// Check if a type is one of the signed integer types.
__extension__
template<typename _Tp>
- using __is_signed_integer = __is_one_of<__remove_cv_t<_Tp>,
+ using __is_signed_integer = __is_one_of<_Tp,
signed char, signed short, signed int, signed long,
signed long long
#if defined(__GLIBCXX_TYPE_INT_N_0)
@@ -841,12 +841,15 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
#if defined(__GLIBCXX_TYPE_INT_N_3)
, signed __GLIBCXX_TYPE_INT_N_3
#endif
+#if defined __STRICT_ANSI__ && defined __SIZEOF_INT128__
+ , signed __int128
+#endif
>;
// Check if a type is one of the unsigned integer types.
__extension__
template<typename _Tp>
- using __is_unsigned_integer = __is_one_of<__remove_cv_t<_Tp>,
+ using __is_unsigned_integer = __is_one_of<_Tp,
unsigned char, unsigned short, unsigned int, unsigned long,
unsigned long long
#if defined(__GLIBCXX_TYPE_INT_N_0)
@@ -861,11 +864,15 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
#if defined(__GLIBCXX_TYPE_INT_N_3)
, unsigned __GLIBCXX_TYPE_INT_N_3
#endif
+#if defined __STRICT_ANSI__ && defined __SIZEOF_INT128__
+ , unsigned __int128
+#endif
>;
// Check if a type is one of the signed or unsigned integer types.
+ // i.e. an integral type except bool, char, wchar_t, and charN_t.
template<typename _Tp>
- using __is_standard_integer
+ using __is_signed_or_unsigned_integer
= __or_<__is_signed_integer<_Tp>, __is_unsigned_integer<_Tp>>;
// __void_t (std::void_t for C++11)
diff --git a/libstdc++-v3/include/std/utility b/libstdc++-v3/include/std/utility
index 3ae1852..0f6dd82 100644
--- a/libstdc++-v3/include/std/utility
+++ b/libstdc++-v3/include/std/utility
@@ -78,7 +78,7 @@
#include <bits/utility.h>
#if __cplusplus >= 202002L
-#include <ext/numeric_traits.h> // __is_standard_integer, __int_traits
+#include <bits/intcmp.h>
#endif
#if __cplusplus > 202302L
@@ -129,76 +129,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
void as_const(const _Tp&&) = delete;
#endif
-#ifdef __cpp_lib_integer_comparison_functions // C++ >= 20
- template<typename _Tp, typename _Up>
- constexpr bool
- cmp_equal(_Tp __t, _Up __u) noexcept
- {
- static_assert(__is_standard_integer<_Tp>::value);
- static_assert(__is_standard_integer<_Up>::value);
-
- if constexpr (is_signed_v<_Tp> == is_signed_v<_Up>)
- return __t == __u;
- else if constexpr (is_signed_v<_Tp>)
- return __t >= 0 && make_unsigned_t<_Tp>(__t) == __u;
- else
- return __u >= 0 && __t == make_unsigned_t<_Up>(__u);
- }
-
- template<typename _Tp, typename _Up>
- constexpr bool
- cmp_not_equal(_Tp __t, _Up __u) noexcept
- { return !std::cmp_equal(__t, __u); }
-
- template<typename _Tp, typename _Up>
- constexpr bool
- cmp_less(_Tp __t, _Up __u) noexcept
- {
- static_assert(__is_standard_integer<_Tp>::value);
- static_assert(__is_standard_integer<_Up>::value);
-
- if constexpr (is_signed_v<_Tp> == is_signed_v<_Up>)
- return __t < __u;
- else if constexpr (is_signed_v<_Tp>)
- return __t < 0 || make_unsigned_t<_Tp>(__t) < __u;
- else
- return __u >= 0 && __t < make_unsigned_t<_Up>(__u);
- }
-
- template<typename _Tp, typename _Up>
- constexpr bool
- cmp_greater(_Tp __t, _Up __u) noexcept
- { return std::cmp_less(__u, __t); }
-
- template<typename _Tp, typename _Up>
- constexpr bool
- cmp_less_equal(_Tp __t, _Up __u) noexcept
- { return !std::cmp_less(__u, __t); }
-
- template<typename _Tp, typename _Up>
- constexpr bool
- cmp_greater_equal(_Tp __t, _Up __u) noexcept
- { return !std::cmp_less(__t, __u); }
-
- template<typename _Res, typename _Tp>
- constexpr bool
- in_range(_Tp __t) noexcept
- {
- static_assert(__is_standard_integer<_Res>::value);
- static_assert(__is_standard_integer<_Tp>::value);
- using __gnu_cxx::__int_traits;
-
- if constexpr (is_signed_v<_Tp> == is_signed_v<_Res>)
- return __int_traits<_Res>::__min <= __t
- && __t <= __int_traits<_Res>::__max;
- else if constexpr (is_signed_v<_Tp>)
- return __t >= 0
- && make_unsigned_t<_Tp>(__t) <= __int_traits<_Res>::__max;
- else
- return __t <= make_unsigned_t<_Res>(__int_traits<_Res>::__max);
- }
-#endif // __cpp_lib_integer_comparison_functions
-
#ifdef __cpp_lib_to_underlying // C++ >= 23
/// Convert an object of enumeration type to its underlying type.
template<typename _Tp>
diff --git a/libstdc++-v3/include/std/variant b/libstdc++-v3/include/std/variant
index 2f44f97..f2f5583 100644
--- a/libstdc++-v3/include/std/variant
+++ b/libstdc++-v3/include/std/variant
@@ -393,8 +393,29 @@ namespace __variant
_Variadic_union(in_place_index_t<_Np>, _Args&&...) = delete;
};
- template<bool __trivially_destructible, typename _First, typename... _Rest>
- union _Variadic_union<__trivially_destructible, _First, _Rest...>
+ template<typename _First, typename... _Rest>
+ union _Variadic_union<true, _First, _Rest...>
+ {
+ constexpr _Variadic_union() : _M_rest() { }
+
+ template<typename... _Args>
+ constexpr
+ _Variadic_union(in_place_index_t<0>, _Args&&... __args)
+ : _M_first(in_place_index<0>, std::forward<_Args>(__args)...)
+ { }
+
+ template<size_t _Np, typename... _Args>
+ constexpr
+ _Variadic_union(in_place_index_t<_Np>, _Args&&... __args)
+ : _M_rest(in_place_index<_Np-1>, std::forward<_Args>(__args)...)
+ { }
+
+ _Uninitialized<_First> _M_first;
+ _Variadic_union<true, _Rest...> _M_rest;
+ };
+
+ template<typename _First, typename... _Rest>
+ union _Variadic_union<false, _First, _Rest...>
{
constexpr _Variadic_union() : _M_rest() { }
@@ -410,24 +431,19 @@ namespace __variant
: _M_rest(in_place_index<_Np-1>, std::forward<_Args>(__args)...)
{ }
-#if __cpp_lib_variant >= 202106L
_Variadic_union(const _Variadic_union&) = default;
_Variadic_union(_Variadic_union&&) = default;
_Variadic_union& operator=(const _Variadic_union&) = default;
_Variadic_union& operator=(_Variadic_union&&) = default;
- ~_Variadic_union() = default;
-
// If any alternative type is not trivially destructible then we need a
// user-provided destructor that does nothing. The active alternative
// will be destroyed by _Variant_storage::_M_reset() instead of here.
- constexpr ~_Variadic_union()
- requires (!__trivially_destructible)
+ _GLIBCXX20_CONSTEXPR ~_Variadic_union()
{ }
-#endif
_Uninitialized<_First> _M_first;
- _Variadic_union<__trivially_destructible, _Rest...> _M_rest;
+ _Variadic_union<(is_trivially_destructible_v<_Rest> && ...), _Rest...> _M_rest;
};
// _Never_valueless_alt is true for variant alternatives that can
diff --git a/libstdc++-v3/libsupc++/compare b/libstdc++-v3/libsupc++/compare
index 08f2b2b..5b4f47a 100644
--- a/libstdc++-v3/libsupc++/compare
+++ b/libstdc++-v3/libsupc++/compare
@@ -34,6 +34,7 @@
#pragma GCC system_header
#endif
+#define __glibcxx_want_concepts
#define __glibcxx_want_three_way_comparison
#define __glibcxx_want_type_order
#include <bits/version.h>
@@ -499,10 +500,8 @@ namespace std _GLIBCXX_VISIBILITY(default)
template<typename _Tp, typename _Up, typename _Cat = partial_ordering>
concept three_way_comparable_with
- = three_way_comparable<_Tp, _Cat>
- && three_way_comparable<_Up, _Cat>
- && common_reference_with<const remove_reference_t<_Tp>&,
- const remove_reference_t<_Up>&>
+ = three_way_comparable<_Tp, _Cat> && three_way_comparable<_Up, _Cat>
+ && __detail::__comparison_common_type_with<_Tp, _Up>
&& three_way_comparable<
common_reference_t<const remove_reference_t<_Tp>&,
const remove_reference_t<_Up>&>, _Cat>
diff --git a/libstdc++-v3/testsuite/20_util/integer_comparisons/extended.cc b/libstdc++-v3/testsuite/20_util/integer_comparisons/extended.cc
new file mode 100644
index 0000000..d862b16
--- /dev/null
+++ b/libstdc++-v3/testsuite/20_util/integer_comparisons/extended.cc
@@ -0,0 +1,60 @@
+// { dg-do compile { target c++20 } }
+
+#include <utility>
+
+template<typename T>
+constexpr bool
+test()
+{
+ using S = std::make_signed_t<T>;
+ using U = std::make_unsigned_t<T>;
+
+ static_assert( std::cmp_less((S)-1, (U)1));
+ static_assert( ! std::cmp_less((S)20, (U)10));
+ static_assert( ! std::cmp_less((U)20, (S)10));
+
+ static_assert( std::cmp_greater((S)100, (U)1) );
+ static_assert( std::cmp_greater((U)100, (S)1) );
+ static_assert( ! std::cmp_greater((S)-100, (U)1) );
+
+ static_assert( std::cmp_less_equal((S)-1, (U)1));
+ static_assert( std::cmp_less_equal((U)10, (S)10));
+ static_assert( ! std::cmp_less_equal((U)-100, (S)-100));
+
+ static_assert( std::cmp_greater_equal((S)200, (U)2) );
+ static_assert( std::cmp_greater_equal((U)2000, (S)2000) );
+ static_assert( ! std::cmp_greater_equal((S)-100, (U)100) );
+
+ static_assert( std::cmp_equal((S)1, (U)1) );
+ static_assert( ! std::cmp_equal((S)-2, (U)-2) );
+
+ static_assert( std::cmp_not_equal((S)-1, (U)-1) );
+ static_assert( ! std::cmp_not_equal((S)100, (U)100) );
+
+ static_assert( std::in_range<S>((U)5) );
+ static_assert( std::in_range<U>((S)5) );
+ static_assert( ! std::in_range<S>((U)-5) );
+ static_assert( ! std::in_range<U>((S)-5) );
+
+ return true;
+}
+
+#ifdef __SIZEOF_INT128__
+static_assert(test<__int128>());
+#endif
+
+#ifdef __GLIBCXX_TYPE_INT_N_0
+static_assert(test<__GLIBCXX_TYPE_INT_N_0>());
+#endif
+
+#ifdef __GLIBCXX_TYPE_INT_N_1
+static_assert(test<__GLIBCXX_TYPE_INT_N_1>());
+#endif
+
+#ifdef __GLIBCXX_TYPE_INT_N_2
+static_assert(test<__GLIBCXX_TYPE_INT_N_2>());
+#endif
+
+#ifdef __GLIBCXX_TYPE_INT_N_3
+static_assert(test<__GLIBCXX_TYPE_INT_N_3>());
+#endif
diff --git a/libstdc++-v3/testsuite/20_util/variant/112591.cc b/libstdc++-v3/testsuite/20_util/variant/112591.cc
new file mode 100644
index 0000000..b1b07c4
--- /dev/null
+++ b/libstdc++-v3/testsuite/20_util/variant/112591.cc
@@ -0,0 +1,32 @@
+// { dg-do run { target c++17 } }
+
+#include <variant>
+#include <testsuite_hooks.h>
+
+struct NonEmpty { int x; };
+struct TrivialEmpty {};
+struct NonTrivialEmpty { ~NonTrivialEmpty() {} };
+
+template<typename T>
+struct Compose : T
+{
+ std::variant<T, int> v;
+};
+
+template<typename T>
+bool testAlias()
+{
+ Compose<T> c;
+ return static_cast<T*>(&c) == &std::get<T>(c.v);
+}
+
+int main()
+{
+ VERIFY( !testAlias<NonEmpty>() );
+ VERIFY( !testAlias<TrivialEmpty>() );
+#if __cplusplus >= 202002L
+ VERIFY( !testAlias<NonTrivialEmpty>() );
+#else
+ VERIFY( testAlias<NonTrivialEmpty>() );
+#endif
+}
diff --git a/libstdc++-v3/testsuite/20_util/variant/87619.cc b/libstdc++-v3/testsuite/20_util/variant/87619.cc
index d988925..ac7dd46 100644
--- a/libstdc++-v3/testsuite/20_util/variant/87619.cc
+++ b/libstdc++-v3/testsuite/20_util/variant/87619.cc
@@ -16,6 +16,7 @@
// <http://www.gnu.org/licenses/>.
// { dg-do compile { target c++17 } }
+// { dg-options "-ftemplate-depth=270" }
#include <variant>
#include <utility>
@@ -23,6 +24,7 @@
template<std::size_t I>
struct S {
+ ~S() {}
};
template <std::size_t... Is>
diff --git a/libstdc++-v3/testsuite/23_containers/mdspan/extents/ctor_ints.cc b/libstdc++-v3/testsuite/23_containers/mdspan/extents/ctor_ints.cc
index d5f07c1..fdbcb70 100644
--- a/libstdc++-v3/testsuite/23_containers/mdspan/extents/ctor_ints.cc
+++ b/libstdc++-v3/testsuite/23_containers/mdspan/extents/ctor_ints.cc
@@ -16,6 +16,13 @@ static_assert(!std::is_constructible_v<std::extents<int, 1, dyn, 3>, int, int>);
// Not constructible from non integer-like objects.
static_assert(!std::is_constructible_v<std::extents<int, 1>, int, A>);
+#ifdef __SIZEOF_INT128__
+static_assert(std::is_constructible_v<std::extents<__int128, 1, 2>,
+ __int128, unsigned __int128>);
+static_assert(std::is_constructible_v<std::extents<unsigned __int128, 1, 2>,
+ unsigned int, int>);
+#endif
+
// No implicit conversion from integer-like objects.
template<typename Extent, typename... OExtents>
constexpr bool
diff --git a/libstdc++-v3/testsuite/23_containers/mdspan/submdspan/strided_slice.cc b/libstdc++-v3/testsuite/23_containers/mdspan/submdspan/strided_slice.cc
index c43a821..6fa5aaa 100644
--- a/libstdc++-v3/testsuite/23_containers/mdspan/submdspan/strided_slice.cc
+++ b/libstdc++-v3/testsuite/23_containers/mdspan/submdspan/strided_slice.cc
@@ -34,6 +34,9 @@ test_all()
test_initializers(0, 1, 2);
test_initializers(std::integral_constant<short, 0>{}, size_t{1}, std::cw<2>);
test_initializers(-1, 2, 2);
+#ifdef __SIZEOF_INT128__
+ test_initializers((__int128)1, (unsigned __int128)-2, std::cw<(__int128)3>);
+#endif
return true;
}
diff --git a/libstdc++-v3/testsuite/26_numerics/saturation/extended.cc b/libstdc++-v3/testsuite/26_numerics/saturation/extended.cc
new file mode 100644
index 0000000..fbef628
--- /dev/null
+++ b/libstdc++-v3/testsuite/26_numerics/saturation/extended.cc
@@ -0,0 +1,55 @@
+// { dg-do compile { target c++26 } }
+
+#include <numeric>
+#include <limits>
+
+template<typename T>
+constexpr bool
+test()
+{
+ using S = std::make_signed_t<T>;
+ using U = std::make_unsigned_t<T>;
+
+ constexpr S smax = std::numeric_limits<S>::max();
+ constexpr S smin = std::numeric_limits<S>::min();
+ constexpr U umax = std::numeric_limits<U>::max();
+
+ static_assert( std::add_sat(smax, (S)1) == smax );
+ static_assert( std::add_sat(smin, (S)-2) == smin );
+ static_assert( std::add_sat(umax, (U)3) == umax );
+
+ static_assert( std::sub_sat(smax, (S)-1) == smax );
+ static_assert( std::sub_sat(smin, (S)2) == smin );
+ static_assert( std::sub_sat((U)0, (U)3) == (U)0 );
+
+ static_assert( std::mul_sat((S)(smax >> 1), (S)3) == smax );
+ static_assert( std::mul_sat((S)(smin >> 1), (S)5) == smin );
+ static_assert( std::mul_sat((U)(umax >> 1), (U)7) == umax );
+
+ static_assert( std::div_sat(smax, (S)2) == (smax >> 1) );
+ static_assert( std::div_sat(smin, (S)4) == (smin >> 2) );
+ static_assert( std::div_sat(smin, (S)-1) == smax );
+ static_assert( std::div_sat(umax, (U)8) == (umax >> 3) );
+
+ return true;
+}
+
+#ifdef __SIZEOF_INT128__
+static_assert(test<__int128>());
+#endif
+
+#ifdef __GLIBCXX_TYPE_INT_N_0
+static_assert(test<__GLIBCXX_TYPE_INT_N_0>());
+#endif
+
+#ifdef __GLIBCXX_TYPE_INT_N_1
+static_assert(test<__GLIBCXX_TYPE_INT_N_1>());
+#endif
+
+#ifdef __GLIBCXX_TYPE_INT_N_2
+static_assert(test<__GLIBCXX_TYPE_INT_N_2>());
+#endif
+
+#ifdef __GLIBCXX_TYPE_INT_N_3
+static_assert(test<__GLIBCXX_TYPE_INT_N_3>());
+#endif
diff --git a/libstdc++-v3/testsuite/26_numerics/stdckdint/extended.cc b/libstdc++-v3/testsuite/26_numerics/stdckdint/extended.cc
new file mode 100644
index 0000000..efc0792
--- /dev/null
+++ b/libstdc++-v3/testsuite/26_numerics/stdckdint/extended.cc
@@ -0,0 +1,65 @@
+// { dg-do run { target c++26 } }
+
+#include <stdckdint.h>
+#include <limits>
+#include <testsuite_hooks.h>
+
+template<typename T>
+void
+test()
+{
+ using S = std::make_signed_t<T>;
+ using U = std::make_unsigned_t<T>;
+
+ constexpr S smax = std::numeric_limits<S>::max();
+ constexpr S smin = std::numeric_limits<S>::min();
+ constexpr U umax = std::numeric_limits<U>::max();
+ S sout{};
+ U uout{};
+
+ VERIFY( ckd_add(&sout, smax, (S)1) );
+ VERIFY( ! ckd_add(&uout, smax, (U)1) && uout == ((U)smax + (U)1) );
+ VERIFY( ! ckd_add(&sout, smin, (S)99) && sout == (smin + 99) );
+ VERIFY( ckd_add(&uout, smin, (S)99) );
+ VERIFY( ckd_add(&sout, smin, (S)-2) );
+ VERIFY( ckd_add(&uout, umax, (U)3) );
+ VERIFY( ! ckd_add(&sout, (U)9, (U)3) && sout == 12 );
+
+ VERIFY( ckd_sub(&sout, smax, (S)-1) );
+ VERIFY( ! ckd_sub(&uout, smax, (S)-1) && uout == ((U)smax + (U)1) );
+ VERIFY( ckd_sub(&sout, smin, (S)2) );
+ VERIFY( ! ckd_sub(&sout, smin, (S)-2) && sout == (smin + 2) );
+ VERIFY( ! ckd_sub(&sout, (U)0, (U)3) && sout == -3 );
+ VERIFY( ckd_sub(&uout, (U)0, (U)3) );
+
+ VERIFY( ! ckd_mul(&sout, (S)(smax >> 2), (S)3) && sout == (smax/4*3) );
+ VERIFY( ckd_mul(&sout, (S)(smax >> 1), (S)3) );
+ VERIFY( ! ckd_mul(&uout, (S)(smax >> 1), (S)3) );
+ VERIFY( ckd_mul(&sout, (S)(smin >> 1), (S)5) );
+ VERIFY( ! ckd_mul(&uout, (U)(umax >> 2), (U)3) );
+ VERIFY( ckd_mul(&sout, (U)(umax >> 2), (U)3) );
+ VERIFY( ckd_mul(&uout, (U)(umax >> 1), (U)7) );
+}
+
+int main()
+{
+#ifdef __SIZEOF_INT128__
+ test<__int128>();
+#endif
+
+#ifdef __GLIBCXX_TYPE_INT_N_0
+ test<__GLIBCXX_TYPE_INT_N_0>();
+#endif
+
+#ifdef __GLIBCXX_TYPE_INT_N_1
+ test<__GLIBCXX_TYPE_INT_N_1>();
+#endif
+
+#ifdef __GLIBCXX_TYPE_INT_N_2
+ test<__GLIBCXX_TYPE_INT_N_2>();
+#endif
+
+#ifdef __GLIBCXX_TYPE_INT_N_3
+ test<__GLIBCXX_TYPE_INT_N_3>();
+#endif
+}
diff --git a/libstdc++-v3/testsuite/std/concepts/concepts.compare/move_only.cc b/libstdc++-v3/testsuite/std/concepts/concepts.compare/move_only.cc
new file mode 100644
index 0000000..01870d8
--- /dev/null
+++ b/libstdc++-v3/testsuite/std/concepts/concepts.compare/move_only.cc
@@ -0,0 +1,28 @@
+// { dg-do compile { target c++20 } }
+
+#include <concepts>
+#include <compare>
+
+// P2404R3 Move-only types for equality_comparable_with,
+// totally_ordered_with, and three_way_comparable_with
+
+// This was approved for C++23 but we treat it as a DR for C++20.
+
+#ifndef __cpp_lib_concepts
+# error "Feature-test macro __cpp_lib_concepts is missing in <compare>"
+#elif __cpp_lib_concepts < 202207L
+# error "Feature-test macro __cpp_lib_concepts has wrong value in <compare>"
+#endif
+
+struct MoveOnly
+{
+ MoveOnly(int);
+ MoveOnly(MoveOnly&&) = default;
+ auto operator<=>(const MoveOnly&) const = default;
+ std::strong_ordering operator<=>(int) const;
+ bool operator==(const MoveOnly&) const;
+};
+
+static_assert(std::equality_comparable_with<MoveOnly, int>);
+static_assert(std::totally_ordered_with<MoveOnly, int>);
+static_assert(std::three_way_comparable_with<MoveOnly, int>);