diff options
author | Thomas Schwinge <tschwinge@baylibre.com> | 2024-04-10 10:20:22 +0200 |
---|---|---|
committer | Thomas Schwinge <tschwinge@baylibre.com> | 2024-04-10 10:20:22 +0200 |
commit | 0ba53bfa815ad64c834ad726a8cf81d7acf1c49f (patch) | |
tree | 24022ee13edfd7804bb28fd9502960f91a7a1d6e | |
parent | edd018d8c7b7a0229e10430ee61ac50f390670c2 (diff) | |
parent | ee0717da1eb5dc5d17dcd0b35c88c99281385280 (diff) | |
download | gcc-0ba53bfa815ad64c834ad726a8cf81d7acf1c49f.zip gcc-0ba53bfa815ad64c834ad726a8cf81d7acf1c49f.tar.gz gcc-0ba53bfa815ad64c834ad726a8cf81d7acf1c49f.tar.bz2 |
Merge commit 'fc59a3995cb46c190c0efb0431ad204e399975c4^' into HEAD
828 files changed, 25582 insertions, 3767 deletions
@@ -1,3 +1,18 @@ +2024-01-15 Andrew Pinski <quic_apinski@quicinc.com> + + * MAINTAINERS (DCO): Add myself. + +2024-01-09 Siddhesh Poyarekar <siddhesh@gotplt.org> + + * SECURITY.txt: Drop "exploitable" in the hardening section. + +2024-01-09 Tom Tromey <tom@tromey.com> + + * Makefile.in: Rebuild. + * Makefile.tpl (BASE_EXPORTS): Add GUILE. + (GUILE): New variable. + * Makefile.def (flags_to_pass): Add GUILE. + 2024-01-08 Joseph Myers <josmyers@redhat.com> * MAINTAINERS: Update my email address. diff --git a/MAINTAINERS b/MAINTAINERS index 882694c..cb5a425 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -766,6 +766,7 @@ Jeff Law <jlaw@tachyum.com> Jeff Law <jlaw@ventanamicro.com> Immad Mir <mir@sourceware.org> Gaius Mulley <gaiusmod2@gmail.com> +Andrew Pinski <quic_apinski@quicinc.com> Siddhesh Poyarekar <siddhesh@gotplt.org> Navid Rahimi <navidrahimi@microsoft.com> Rishi Raj <rishiraj45035@gmail.com> diff --git a/config/ChangeLog b/config/ChangeLog index d4234c9..5998f09 100644 --- a/config/ChangeLog +++ b/config/ChangeLog @@ -1,3 +1,7 @@ +2024-01-11 Mike Frysinger <vapier@gentoo.org> + + * acinclude.m4 (CYG_AC_PATH_LIBERTY): Delete. + 2023-11-30 Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE> * hwcaps.m4 (GCC_CHECK_ASSEMBLER_HWCAP): Require diff --git a/config/acinclude.m4 b/config/acinclude.m4 index 0abccafa..f18f0d6 100644 --- a/config/acinclude.m4 +++ b/config/acinclude.m4 @@ -239,28 +239,6 @@ AC_SUBST(BFDLIB) ]) dnl ==================================================================== -dnl Find the libiberty library. This defines many commonly used C -dnl functions that exists in various states based on the underlying OS. -AC_DEFUN([CYG_AC_PATH_LIBERTY], [ -AC_MSG_CHECKING(for the liberty library in the build tree) -dirlist=".. ../../ ../../../ ../../../../ ../../../../../ ../../../../../../ ../../../../../../.. ../../../../../../../.. ../../../../../../../../.. ../../../../../../../../../.." -AC_CACHE_VAL(ac_cv_c_liberty,[ -for i in $dirlist; do - if test -f "$i/libiberty/Makefile" ; then - ac_cv_c_liberty=`(cd $i/libiberty; ${PWDCMD-pwd})` - fi -done -]) -if test x"${ac_cv_c_liberty}" != x; then - LIBERTY="-L${ac_cv_c_liberty}" - AC_MSG_RESULT(${ac_cv_c_liberty}) -else - AC_MSG_RESULT(none) -fi -AC_SUBST(LIBERTY) -]) - -dnl ==================================================================== dnl Find the opcodes library. This is used to do dissasemblies. AC_DEFUN([CYG_AC_PATH_OPCODES], [ AC_MSG_CHECKING(for the opcodes library in the build tree) diff --git a/contrib/ChangeLog b/contrib/ChangeLog index 569b889..0d94109 100644 --- a/contrib/ChangeLog +++ b/contrib/ChangeLog @@ -1,3 +1,13 @@ +2024-01-11 Paul Iannetta <piannetta@kalrayinc.com> + + * dg-extract-results.py: Make the test_run regex case + insensitive. + +2024-01-09 Jonathan Wakely <jwakely@redhat.com> + + * unicode/gen_libstdcxx_unicode_data.py: Print out Gcb_property + enumerators in the order they're seen, not alphabetical order. + 2024-01-08 Jonathan Wakely <jwakely@redhat.com> * unicode/README: Add notes about generating libstdc++ tables. diff --git a/contrib/dg-extract-results.py b/contrib/dg-extract-results.py index d67ce4f..0fe3c5f 100644 --- a/contrib/dg-extract-results.py +++ b/contrib/dg-extract-results.py @@ -113,7 +113,8 @@ class Prog: # Whether to create .sum rather than .log output. self.do_sum = True # Regexps used while parsing. - self.test_run_re = re.compile (r'^Test run by (\S+) on (.*)$') + self.test_run_re = re.compile (r'^Test run by (\S+) on (.*)$', + re.IGNORECASE) self.tool_re = re.compile (r'^\t\t=== (.*) tests ===$') self.result_re = re.compile (r'^(PASS|XPASS|FAIL|XFAIL|UNRESOLVED' r'|WARNING|ERROR|UNSUPPORTED|UNTESTED' diff --git a/contrib/unicode/gen_libstdcxx_unicode_data.py b/contrib/unicode/gen_libstdcxx_unicode_data.py index 1449145..f2f2f8a 100755 --- a/contrib/unicode/gen_libstdcxx_unicode_data.py +++ b/contrib/unicode/gen_libstdcxx_unicode_data.py @@ -122,7 +122,10 @@ for line in open("GraphemeBreakProperty.txt", "r"): process_code_points(code_points, grapheme_property.strip()) edges = find_edges(all_code_points) -gcb_props = {p:i+1 for i,p in enumerate(sorted(set([x[1] for x in edges])))} +gcb_props = {"Other":0} +for c, p in edges: + if p not in gcb_props: + gcb_props[p] = len(gcb_props) shift_bits = int(math.ceil(math.log2(len(gcb_props)))) # Enum definition for std::__unicode::_Gcb_property diff --git a/gcc/BASE-VER b/gcc/BASE-VER index 4b964e9..63dba86 100644 --- a/gcc/BASE-VER +++ b/gcc/BASE-VER @@ -1 +1 @@ -14.0.0 +14.0.1 diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 5d5cf71..9fd99c0 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,1128 @@ +2024-01-15 Georg-Johann Lay <avr@gjlay.de> + + * doc/invoke.texi (AVR Options) [-mskip-bug]: Add documentation. + +2024-01-15 Liao Shihua <shihua@iscas.ac.cn> + + * config.gcc: Include riscv_bitmanip.h. + * config/riscv/bitmanip.md: Changed mode form X to GPR in orcb and clmul pattern. + * config/riscv/crypto.md: Changed mode form X to GPR in brev8 pattern. + * config/riscv/riscv-builtins.cc (AVAIL): Adding new bitmanip builtins. + (RISCV_BUILTIN_NO_PREFIX): New helper macro. + * config/riscv/riscv-cmo.def (RISCV_BUILTIN): Add '_32'/'_64' postfix to builtins. + * config/riscv/riscv-ftypes.def (2): New ftypes. + * config/riscv/riscv-scalar-crypto.def (RISCV_BUILTIN): New builtins. + (RISCV_BUILTIN_NO_PREFIX): Likewise. + * config/riscv/riscv_bitmanip.h: New file. + +2024-01-15 Liao Shihua <shihua@iscas.ac.cn> + + * config.gcc: Include riscv_crypto.h. + * config/riscv/riscv_crypto.h: New file. + +2024-01-15 Vladimir N. Makarov <vmakarov@redhat.com> + + PR middle-end/113354 + * lra-constraints.cc (curr_insn_transform): Spill pseudo only used + in the insn if the corresponding operand does not require hard + register anymore. + +2024-01-15 Georg-Johann Lay <avr@gjlay.de> + + PR target/107201 + * config/avr/avr.h (EXTRA_SPEC_FUNCTIONS): Add no-devlib, avr_no_devlib. + * config/avr/driver-avr.cc (avr_no_devlib): New function. + (avr_devicespecs_file): Use it to remove -nodevicelib from the + options for cores only. + * config/avr/avr-arch.h (avr_get_parch): New prototype. + * config/avr/avr-devices.cc (avr_get_parch): New function. + +2024-01-15 Juzhe-Zhong <juzhe.zhong@rivai.ai> + + PR target/113247 + * config/riscv/riscv-protos.h (struct regmove_vector_cost): Add vector to scalar regmove. + * config/riscv/riscv-vector-costs.cc (adjust_stmt_cost): Ditto. + * config/riscv/riscv.cc (riscv_builtin_vectorization_cost): Adjust vec_construct cost. + +2024-01-15 Juzhe-Zhong <juzhe.zhong@rivai.ai> + + PR target/113281 + * config/riscv/riscv-vector-costs.cc (costs::adjust_vect_cost_per_loop): New function. + (costs::finish_cost): Adjust cost for LOOP LEN with NITERS < VF. + * config/riscv/riscv-vector-costs.h: New function. + +2024-01-15 Richard Biener <rguenther@suse.de> + + PR tree-optimization/113385 + * tree-vect-loop-manip.cc (slpeel_tree_duplicate_loop_to_edge_cfg): + First redirect, then split the exit edge. + +2024-01-15 Juzhe-Zhong <juzhe.zhong@rivai.ai> + + * config/riscv/riscv-vector-costs.cc (costs::analyze_loop_vinfo): + Remove m_num_vector_iterations. + * config/riscv/riscv-vector-costs.h: Ditto. + +2024-01-15 Andrew Pinski <quic_apinski@quicinc.com> + + PR target/113156 + * config/avr/avr.opt (-mdouble, -mlong-double): Add "Save" flag. + (-mbranch-cost): Set "Optimization" flag. + +2024-01-15 Jakub Jelinek <jakub@redhat.com> + + PR tree-optimization/113370 + * gimple-lower-bitint.cc (bitint_large_huge::handle_operand): Only + set rem to prec % (2 * limb_prec) if m_upwards_2limb, otherwise + set it to just prec % limb_prec. + +2024-01-15 Juzhe-Zhong <juzhe.zhong@rivai.ai> + + PR target/113393 + * config/riscv/vector.md: Fix ternary attributes. + +2024-01-14 Georg-Johann Lay <avr@gjlay.de> + + PR target/112944 + * configure.ac [target=avr]: Check availability of emulations + avrxmega2_flmap and avrxmega4_flmap, resulting in new config vars + HAVE_LD_AVR_AVRXMEGA2_FLMAP and HAVE_LD_AVR_AVRXMEGA4_FLMAP. + * configure: Regenerate. + * config.in: Regenerate. + * doc/invoke.texi (AVR Options): Document -mflmap, -mrodata-in-ram, + __AVR_HAVE_FLMAP__, __AVR_RODATA_IN_RAM__. + * config/avr/avr.opt (-mflmap, -mrodata-in-ram): New options. + * config/avr/avr-arch.h (enum avr_device_specific_features): + Add AVR_ISA_FLMAP. + * config/avr/avr-mcus.def (AVR_MCU) [avr64*, avr128*]: Set isa flag + AVR_ISA_FLMAP. + * config/avr/avr.cc (avr_arch_index, avr_has_rodata_p): New vars. + (avr_set_core_architecture): Set avr_arch_index. + (have_avrxmega2_flmap, have_avrxmega4_flmap) + (have_avrxmega3_rodata_in_flash): Set new static const bool according + to configure results. + (avr_rodata_in_flash_p): New function using them. + (avr_asm_init_sections): Let readonly_data_section->unnamed.callback + track avr_need_copy_data_p only if not avr_rodata_in_flash_p(). + (avr_asm_named_section): Track avr_has_rodata_p. + (avr_file_end): Emit __do_copy_data also when avr_has_rodata_p + and not avr_rodata_in_flash_p (). + * config/avr/specs.h (CC1_SPEC): Add %(cc1_rodata_in_ram). + (LINK_SPEC): Add %(link_rodata_in_ram). + (LINK_ARCH_SPEC): Remove. + * config/avr/gen-avr-mmcu-specs.cc (have_avrxmega3_rodata_in_flash) + (have_avrxmega2_flmap, have_avrxmega4_flmap): Set new static + const bool according to configure results. + (diagnose_mrodata_in_ram): New function. + (print_mcu): Generate specs with the following changes: + <*cc1_misc, *asm_misc, *link_misc>: New specs so that we don't + need to extend avr/specs.h each time we add a new bell or whistle. + <*cc1_rodata_in_ram, *link_rodata_in_ram>: New specs to diagnose + -m[no-]rodata-in-ram. + <*cpp_rodata_in_ram>: New. Does -D__AVR_RODATA_IN_RAM__=0/1. + <*cpp_mcu>: Add -D__AVR_AVR_FLMAP__ if it applies. + <*cpp>: Add %(cpp_rodata_in_ram). + <*link_arch>: Use emulation avrxmega2_flmap, avrxmega4_flmap as + requested. + <*self_spec>: Add -mflmap or %<mflmap as needed. + +2024-01-14 Jeff Law <jlaw@ventanamicro.com> + + * config/mips/mips.md (ior<mode>3_mips16_asmacro): Use SImode, + not the GPR iterator. Adjust pattern name and mode attribute + accordingly. + +2024-01-13 Jakub Jelinek <jakub@redhat.com> + + PR tree-optimization/113361 + * gimple-lower-bitint.cc (bitint_large_huge::handle_operand_addr): + Fix up determination of the type for > limb_prec constants. + +2024-01-12 Georg-Johann Lay <avr@gjlay.de> + + * doc/extend.texi (AVR Named Address Spaces, Limitations and Caveats): + Add web-link to the avr-gcc wiki. + +2024-01-12 Georg-Johann Lay <avr@gjlay.de> + + * doc/extend.texi (AVR Variable Attributes) [address]: Remove + documentation for a version without argument, which is not supported. + +2024-01-12 Ezra Sitorus <ezra.sitorus@arm.com> + + * config/arm/arm_neon.h + (vld1_u8_x4, vld1_u16_x4, vld1_u32_x4, vld1_u64_x4): New. + (vld1_s8_x4, vld1_s16_x4, vld1_s32_x4, vld1_s64_x4): New. + (vld1_f16_x4, vld1_f32_x4): New. + (vld1_p8_x4, vld1_p16_x4, vld1_p64_x4): New. + (vld1_bf16_x4): New. + (vld1q_types_x4): Updated to use vld1q_x4 + from arm_neon_builtins.def + * config/arm/arm_neon_builtins.def + (vld1_x4): Updated entries. + (vld1q_x4): New entries, but comes from the old vld1_x4 + * config/arm/neon.md + (neon_vld1q_x4<mode>): Updated from neon_vld1_x4<mode>. + +2024-01-12 Ezra Sitorus <ezra.sitorus@arm.com> + + * config/arm/arm_neon.h + (vld1_u8_x3, vld1_u16_x3, vld1_u32_x3, vld1_u64_x3): New. + (vld1_s8_x3, vld1_s16_x3, vld1_s32_x3, vld1_s64_x3): New. + (vld1_f16_x3, vld1_f32_x3): New. + (vld1_p8_x3, vld1_p16_x3, vld1_p64_x3): New. + (vld1_bf16_x3): New. + (vld1q_types_x3): Updated to use vld1q_x3 from + arm_neon_builtins.def + * config/arm/arm_neon_builtins.def + (vld1_x3): Updated entries. + (vld1q_x3): New entries, but comes from the old vld1_x2 + * config/arm/neon.md + (neon_vld1q_x3<mode>): Updated from neon_vld1_x3<mode>. + +2024-01-12 Ezra Sitorus <ezra.sitorus@arm.com> + + * config/arm/arm_neon.h + (vld1_u8_x2, vld1_u16_x2, vld1_u32_x2, vld1_u64_x2): New. + (vld1_s8_x2, vld1_s16_x2, vld1_s32_x2, vld1_s64_x2): New. + (vld1_f16_x2, vld1_f32_x2): New. + (vld1_p8_x2, vld1_p16_x2, vld1_p64_x2): New. + (vld1_bf16_x2): New. + (vld1q_types_x2): Updated to use vld1q_x2 from + arm_neon_builtins.def + * config/arm/arm_neon_builtins.def + (vld1_x2): Updated entries. + (vld1q_x2): New entries, but comes from the old vld1_x2 + * config/arm/neon.md + (neon_vld1<VMEMX2_q>_x2<VDQX:mode>): Updated from + neon_vld1_x2<mode>. + +2024-01-12 Ezra Sitorus <ezra.sitorus@arm.com> + + * config/arm/arm_neon.h + (vst1q_u8_x4, vst1q_u16_x4, vst1q_u32_x4, vst1q_u64_x4): New. + (vst1q_s8_x4, vst1q_s16_x4, vst1q_s32_x4, vst1q_s64_x4): New. + (vst1q_f16_x4, vst1q_f32_x4): New. + (vst1q_p8_x4, vst1q_p16_x4, vst1q_p64_x4): New. + (vst1q_bf16_x4): New. + * config/arm/arm_neon_builtins.def (vst1q_x4): New entries. + * config/arm/neon.md + (neon_vst1q_x4<mode>): New. + (neon_vst1x4qa<mode>, neon_vst1x4qb<mode>): New. + * config/arm/unspecs.md + (UNSPEC_VST1X4A, UNSPEC_VST1X4B): New. + +2024-01-12 Ezra Sitorus <ezra.sitorus@arm.com> + + * config/arm/arm_neon.h + (vst1q_u8_x3, vst1q_u16_x3, vst1q_u32_x3, vst1q_u64_x3): New. + (vst1q_s8_x3, vst1q_s16_x3, vst1q_s32_x3, vst1q_s64_x3): New. + (vst1q_f16_x3, vst1q_f32_x3): New. + (vst1q_p8_x3, vst1q_p16_x3, vst1q_p64_x3): New. + (vst1q_bf16_x3): New. + * config/arm/arm_neon_builtins.def (vst1q_x3): New entries. + * config/arm/neon.md + (neon_vst1q_x3<mode>): New. + (neon_vld1x3qa<mode>, neon_vst1x3qb<mode>): New. + * config/arm/unspecs.md + (UNSPEC_VST1X3A, UNSPEC_VST1X3B): New. + +2024-01-12 Ezra Sitorus <ezra.sitorus@arm.com> + + * config/arm/arm_neon.h + (vst1q_u8_x2, vst1q_u16_x2, vst1q_u32_x2, vst1q_u64_x2): New. + (vst1q_s8_x2, vst1q_s16_x2, vst1q_s32_x2, vst1q_s64_x2): New. + (vst1q_f16_x2, vst1q_f32_x2): New. + (vst1q_p8_x2, vst1q_p16_x2, vst1q_p64_x2): New. + (vst1q_bf16_x2): New. + * config/arm/arm_neon_builtins.def (vst1<_x2): New entries. + * config/arm/neon.md + (neon_vst1<VMEMX2_q>_x2<VDQX:mode>): Updated from + neon_vst1_x2<mode>. + * config/arm/iterators.md + (VMEMX2): New mode iterator. + (VMEMX2_q): New mode attribute. + +2024-01-12 Ezra Sitorus <ezra.sitorus@arm.com> + + * config/arm/arm_neon.h + (vst1_u8_x4, vst1_u16_x4, vst1_u32_x4, vst1_u64_x4): New. + (vst1_s8_x4, vst1_s16_x4, vst1_s32_x4, vst1_s64_x4): New. + (vst1_f16_x4, vst1_f32_x4): New. + (vst1_p8_x4, vst1_p16_x4, vst1_p64_x4): New. + (vst1_bf16_x4): New. + * config/arm/arm_neon_builtins.def (vst1_x4): New entries. + * config/arm/neon.md (vst1_x4<mode>): New. + +2024-01-12 Ezra Sitorus <ezra.sitorus@arm.com> + + * config/arm/arm_neon.h + (vst1_u8_x3, vst1_u16_x3, vst1_u32_x3, vst1_u64_x3): New. + (vst1_s8_x3, vst1_s16_x3, vst1_s32_x3, vst1_s64_x3): New. + (vst1_f16_x3, vst1_f32_x3): New. + (vst1_p8_x3, vst1_p16_x3, vst1_p64_x3): New. + (vst1_bf16_x3): New. + * config/arm/arm_neon_builtins.def (vst1_x3): New entries. + * config/arm/neon.md (vst1_x3<mode>): New. + +2024-01-12 Ezra Sitorus <ezra.sitorus@arm.com> + + * config/arm/arm_neon.h + (vst1_u8_x2, vst1_u16_x2, vst1_u32_x2, vst1_u64_x2): New. + (vst1_s8_x2, vst1_s16_x2, vst1_s32_x2, vst1_s64_x2): New. + (vst1_f16_x2, vst1_f32_x2): New. + (vst1_p8_x2, vst1_p16_x2, vst1_p64_x2): New. + (vst1_bf16_x2): New. + * config/arm/arm_neon_builtins.def (vst1_x2): New entries. + * config/arm/neon.md (vst1_x2<mode>): New. + +2024-01-12 Ezra Sitorus <ezra.sitorus@arm.com> + + * config/arm/arm_neon.h + (vld1q_u8_x4, vld1q_u16_x4, vld1q_u32_x4, vld1q_u64_x4): New. + (vld1q_s8_x4, vld1q_s16_x4, vld1q_s32_x4, vld1q_s64_x4): New. + (vld1q_f16_x4, vld1q_f32_x4): New. + (vld1q_p8_x4, vld1q_p16_x4, vld1q_p64_x4): New. + (vld1q_bf16_x4): New. + * config/arm/arm_neon_builtins.def (vld1_x4): New entries. + * config/arm/neon.md + (neon_vld1_x4<mode>): New. + (neon_vld1x4qa<mode>, neon_vld1x4qb<mode>): New + * config/arm/unspecs.md + (UNSPEC_VLD1X4A, UNSPEC_VLD1X4B): New. + +2024-01-12 Ezra Sitorus <ezra.sitorus@arm.com> + + * config/arm/arm_neon.h + (vld1q_u8_x3, vld1q_u16_x3, vld1q_u32_x3, vld1q_u64_x3): New. + (vld1q_s8_x3, vld1q_s16_x3, vld1q_s32_x3, vld1q_s64_x3): New. + (vld1q_f16_x3, vld1q_f32_x3): New. + (vld1q_p8_x3, vld1q_p16_x3, vld1q_p64_x3): New. + (vld1q_bf16_x3): New. + * config/arm/arm_neon_builtins.def (vld1_x3): New entries. + * config/arm/neon.md + (neon_vld1_x3<mode>): New. + (neon_vld1x3qa<mode>, neon_vld1x3qb<mode>): New. + * config/arm/unspecs.md + (UNSPEC_VLD1X3A, UNSPEC_VLD1X3B): New. + +2024-01-12 Ezra Sitorus <ezra.sitorus@arm.com> + + * config/arm/arm_neon.h + (vld1q_u8_x2, vld1q_u16_x2, vld1q_u32_x2, vld1q_u64_x2): New. + (vld1q_s8_x2, vld1q_s16_x2, vld1q_s32_x2, vld1q_s64_x2): New. + (vld1q_f16_x2, vld1q_f32_x2): New. + (vld1q_p8_x2, vld1q_p16_x2, vld1q_p64_x2): New. + (vld1q_bf16_x2): New. + * config/arm/arm_neon_builtins.def (vld1_x2): New entries. + * config/arm/neon.md (vld1_x2<mode>): New. + +2024-01-12 Tamar Christina <tamar.christina@arm.com> + + PR tree-optimization/113287 + * doc/sourcebuild.texi (check_effective_target_bitint65535): New. + +2024-01-12 Tamar Christina <tamar.christina@arm.com> + + * tree-vect-loop-manip.cc (vect_loop_versioning): Replace single_exit. + * tree-vect-loop.cc (vect_transform_loop): Likewise. + +2024-01-12 Tamar Christina <tamar.christina@arm.com> + + PR tree-optimization/113178 + * tree-vect-loop.cc (vect_create_epilog_for_reduction): Fill in all + alternate exits. + +2024-01-12 Tamar Christina <tamar.christina@arm.com> + + PR tree-optimization/113237 + * tree-vect-loop-manip.cc (slpeel_tree_duplicate_loop_to_edge_cfg): Use + existing LCSSA variable for exit when all exits are early break. + +2024-01-12 Tamar Christina <tamar.christina@arm.com> + + PR tree-optimization/113137 + PR tree-optimization/113136 + PR tree-optimization/113172 + PR tree-optimization/113178 + * tree-vect-loop-manip.cc (slpeel_tree_duplicate_loop_to_edge_cfg): + Maintain PHIs on inverted loops. + (vect_do_peeling): Maintain virtual PHIs on inverted loops. + * tree-vect-loop.cc (vec_init_loop_exit_info): Pick exit closes to + latch. + (vect_create_loop_vinfo): Record all conds instead of only alt ones. + +2024-01-12 Tamar Christina <tamar.christina@arm.com> + + PR tree-optimization/113135 + * tree-vect-data-refs.cc (vect_analyze_early_break_dependences): Rework + dependency analysis. + +2024-01-12 Iain Sandoe <iain@sandoe.co.uk> + + * config/rs6000/host-darwin.cc (segv_handler): Use the revised + diagnostics class member name for abort of error. + +2024-01-12 Georg-Johann Lay <avr@gjlay.de> + + * config/avr/avr.cc (avr_handle_addr_attribute): Move "..." from + format string to %s argument. + +2024-01-12 John David Anglin <danglin@gcc.gnu.org> + Jakub Jelinek <jakub@redhat.com> + + PR middle-end/113182 + * varasm.cc (process_pending_assemble_externals, + assemble_external_libcall): Use targetm.strip_name_encoding + before calling get_identifier. + +2024-01-12 Richard Sandiford <richard.sandiford@arm.com> + + PR target/113196 + * config/aarch64/aarch64.h (machine_function::advsimd_zero_insn): + New member variable. + * config/aarch64/aarch64-protos.h (aarch64_split_simd_shift_p): + Declare. + * config/aarch64/iterators.md (Vnarrowq2): New mode attribute. + * config/aarch64/aarch64-simd.md + (vec_unpacku_hi_<mode>, vec_unpacks_hi_<mode>): Recombine into... + (vec_unpack<su>_hi_<mode>): ...this. Move the generation of + zip2 for zero-extends to... + (aarch64_simd_vec_unpack<su>_hi_<mode>): ...a split of this + instruction. Fix big-endian handling. + (vec_unpacku_lo_<mode>, vec_unpacks_lo_<mode>): Recombine into... + (vec_unpack<su>_lo_<mode>): ...this. Move the generation of + zip1 for zero-extends to... + (<optab><Vnarrowq><mode>2): ...a split of this instruction. + Fix big-endian handling. + (*aarch64_zip1_uxtl): New pattern. + (aarch64_usubw<mode>_lo_zip, aarch64_uaddw<mode>_lo_zip): Delete + (aarch64_usubw<mode>_hi_zip, aarch64_uaddw<mode>_hi_zip): Likewise. + * config/aarch64/aarch64.cc (aarch64_get_shareable_reg): New function. + (aarch64_gen_shareable_zero): Use it. + (aarch64_split_simd_shift_p): New function. + +2024-01-12 Richard Sandiford <richard.sandiford@arm.com> + + * emit-rtl.h (rtl_data::x_function_beg_note): New member variable. + (function_beg_insn): New macro. + * function.cc (expand_function_start): Initialize function_beg_insn. + +2024-01-12 Richard Sandiford <richard.sandiford@arm.com> + + PR target/112989 + * config/aarch64/aarch64-sve-builtins.h + (function_builder::m_overload_names): Replace with... + * config/aarch64/aarch64-sve-builtins.cc (overload_names): ...this + new global. + (add_overloaded_function): Update accordingly, using get_identifier + to get a GGC-friendly record of the name. + +2024-01-12 Richard Sandiford <richard.sandiford@arm.com> + + PR target/112989 + * config/aarch64/aarch64-sve-builtins.def: Don't include + aarch64-sve-builtins-sme.def. + (DEF_SME_ZA_FUNCTION_GS, DEF_SME_ZA_FUNCTION): Move to... + * config/aarch64/aarch64-sve-builtins-sme.def: ...here. + (DEF_SME_FUNCTION): New macro. Use it and DEF_SME_FUNCTION_GS + instead of DEF_SVE_*. Add AARCH64_FL_SME to anything that + requires AARCH64_FL_SME2. + * config/aarch64/aarch64-sve-builtins-sve2.def: Make same + AARCH64_FL_SME adjustment here. + * config/aarch64/aarch64-sve-builtins.cc (function_groups): Don't + include SME intrinsics. + (sme_function_groups): New array. + (handle_arm_sve_h): Remove check for AARCH64_FL_SME. + (handle_arm_sme_h): Use sme_function_groups instead of function_groups. + +2024-01-12 Juzhe-Zhong <juzhe.zhong@rivai.ai> + + PR target/113281 + * config/riscv/riscv-protos.h (struct regmove_vector_cost): New struct. + (struct cpu_vector_cost): Add regmove struct. + (get_vector_costs): Export as global. + * config/riscv/riscv-vector-costs.cc (adjust_stmt_cost): Adjust scalar_to_vec cost. + (costs::add_stmt_cost): Ditto. + * config/riscv/riscv.cc (get_common_costs): Export global function. + +2024-01-12 Jakub Jelinek <jakub@redhat.com> + + PR tree-optimization/113334 + * gimple-lower-bitint.cc (bitint_large_huge::handle_operand): Use + wi::neg_p (wi::to_wide (op)) instead of tree_int_cst_sgn (op) < 0 + to determine if number should be extended by all ones rather than zero + extended. + +2024-01-12 Jakub Jelinek <jakub@redhat.com> + + PR tree-optimization/113330 + * tree-sra.cc (create_access): Punt for BITINT_TYPE accesses with + too large size. + +2024-01-12 Jakub Jelinek <jakub@redhat.com> + + PR tree-optimization/113323 + * gimple-lower-bitint.cc (bitint_dom_walker::before_dom_children): Fix + check for lhs being large/huge _BitInt not in m_names. + +2024-01-12 Jakub Jelinek <jakub@redhat.com> + + PR tree-optimization/113316 + * gimple-lower-bitint.cc (bitint_large_huge::lower_call): Handle + uninitialized large/huge _BitInt arguments to calls. + +2024-01-12 Jakub Jelinek <jakub@redhat.com> + + * gimple-lower-bitint.cc (mergeable_op): Instead of comparing + TYPE_SIZE (t) of large/huge BITINT_TYPEs, compare + CEIL (TYPE_PRECISION (t), limb_prec). + (bitint_large_huge::handle_cast): Likewise. + +2024-01-12 Ilya Leoshkevich <iii@linux.ibm.com> + + PR sanitizer/113284 + * config/rs6000/rs6000.cc (rs6000_elf_declare_function_name): + Use assemble_function_label_final () for Power ELF V1 ABI. + * output.h (assemble_function_label_final): New function. + * varasm.cc (assemble_function_label_raw): Use + assemble_function_label_final (). + (assemble_function_label_final): New function. + +2024-01-12 Richard Biener <rguenther@suse.de> + + PR middle-end/113344 + * match.pd ((double)float CMP (double)float -> float CMP float): + Perform result type check only for vectors. + * fold-const.cc (fold_binary_loc): Likewise. + +2024-01-12 Haochen Jiang <haochen.jiang@intel.com> + + * config/i386/sse.md (sdot_prod<mode>): Remove redundant SET. + (usdot_prod<mode>): Ditto. + (sdot_prod<mode>): Ditto. + (udot_prod<mode>): Ditto. + +2024-01-12 Haochen Jiang <haochen.jiang@intel.com> + + PR target/113288 + * config/i386/i386-c.cc (ix86_target_macros_internal): + Add __AVX10_1__, __AVX10_1_256__ and __AVX10_1_512__. + +2024-01-12 Richard Biener <rguenther@suse.de> + + PR target/112280 + * config/s390/s390.cc (expand_perm_as_a_vlbr_vstbr_candidate): + Do not generate code when d.testing_p. + +2024-01-12 liuhongt <hongtao.liu@intel.com> + + PR target/113039 + * doc/invoke.texi (fcf-protection=): Update documents. + +2024-01-12 Pan Li <pan2.li@intel.com> + + * config/riscv/riscv.cc (riscv_v_ext_mode_p): Update the + comments of predicate func riscv_v_ext_mode_p. + +2024-01-12 Feng Wang <wangfeng@eswincomputing.com> + + * config/riscv/riscv-vector-builtins.def (vfloat16m8_t): + Modify ABI-name length of vfloat16m8_t + +2024-01-12 Li Wei <liwei@loongson.cn> + + * config/loongarch/loongarch.cc (loongarch_expand_conditional_move): + Adjust. + +2024-01-12 Li Wei <liwei@loongson.cn> + + * config/loongarch/loongarch.md (add<mode>3): Removed. + (*addsi3): New. + (addsi3): Ditto. + (adddi3): Ditto. + (*addsi3_extended): Removed. + (addsi3_extended): New. + +2024-01-11 Jin Ma <jinma@linux.alibaba.com> + + * config/riscv/thead.md: Add limits for splits. + +2024-01-11 Andrew Pinski <quic_apinski@quicinc.com> + + PR middle-end/113322 + * expr.cc (do_store_flag): Don't try single bit tests with + comparison on vector types. + +2024-01-11 Andrew Pinski <quic_apinski@quicinc.com> + + PR tree-optimization/113301 + * match.pd (`1/x`): Delay signed case until late. + +2024-01-11 Georg-Johann Lay <avr@gjlay.de> + + * doc/invoke.texi (AVR Options): Move -mrmw, -mn-flash, -mshort-calls + and -msp8 to... + (AVR Internal Options): ...this new @subsubsection. + +2024-01-11 Vladimir N. Makarov <vmakarov@redhat.com> + + PR rtl-optimization/112918 + * lra-constraints.cc (SMALL_REGISTER_CLASS_P): Move before in_class_p. + (in_class_p): Restrict condition for narrowing class in case of + allow_all_reload_class_changes_p. + (process_alt_operands): Try to match operand without and with + narrowing reg class. Discourage narrowing the class. Finish insn + matching only if there is no class narrowing. + (curr_insn_transform): Pass true to in_class_p for reg operand win. + +2024-01-11 Richard Biener <rguenther@suse.de> + + PR tree-optimization/112505 + * tree-vect-loop.cc (vectorizable_induction): Reject + bit-precision induction. + +2024-01-11 Richard Biener <rguenther@suse.de> + + PR tree-optimization/113126 + * match.pd ((double)float CMP (double)float -> float CMP float): + Make sure the boolean type is the same. + * fold-const.cc (fold_binary_loc): Likewise. + +2024-01-11 Richard Biener <rguenther@suse.de> + + PR tree-optimization/112636 + * tree-ssa-loop-ch.cc (ch_base::copy_headers): Call + estimate_numbers_of_iterations before querying + get_max_loop_iterations_int. + (pass_ch::execute): Initialize SCEV and loops appropriately. + +2024-01-11 Georg-Johann Lay <avr@gjlay.de> + + * config/avr/avr-devices.cc (avr_texinfo): Adjust documentation for + Reduced Tiny. + * config/avr/gen-avr-mmcu-texi.cc (main): Add @anchor for each core. + * doc/extend.texi (AVR Variable Attributes): Improve documentation + of io, io_low and address attributes. + * doc/invoke.texi (AVR Options): Add some anchors for external refs. + * doc/avr-mmcu.texi: Rebuild. + +2024-01-11 Yang Yujie <yangyujie@loongson.cn> + + PR target/113233 + * config/loongarch/genopts/loongarch.opt.in: Mark options with + the "Save" property. + * config/loongarch/loongarch.opt: Same. + * config/loongarch/loongarch-opts.cc: Refresh -mcmodel= state + according to la_target. + * config/loongarch/loongarch.cc: Implement TARGET_OPTION_{SAVE, + RESTORE} for the la_target structure; Rename option conditions + to have the same "la_" prefix. + * config/loongarch/loongarch.h: Same. + +2024-01-11 Pan Li <pan2.li@intel.com> + + * loop-unroll.cc (insert_var_expansion_initialization): Leverage + MODE_HAS_SIGNED_ZEROS for expansion variable initialization. + +2024-01-11 Alex Coplan <alex.coplan@arm.com> + + PR target/113077 + * config/aarch64/aarch64-ldp-fusion.cc (filter_notes): Add + fr_expr param to extract REG_FRAME_RELATED_EXPR notes. + (combine_reg_notes): Handle REG_FRAME_RELATED_EXPR notes, and + synthesize these if needed. Update caller ... + (ldp_bb_info::fuse_pair): ... here. + (ldp_bb_info::try_fuse_pair): Punt if either insn has writeback + and either insn is frame-related. + (find_trailing_add): Punt on frame-related insns. + * config/aarch64/aarch64.cc (aarch64_save_callee_saves): Use + REG_FRAME_RELATED_EXPR instead of REG_CFA_OFFSET. + +2024-01-11 YunQiang Su <syq@gcc.gnu.org> + + * config/mips/mips.cc (mips_start_function_definition): + Add ATTRIBUTE_UNUSED. + +2024-01-11 Richard Biener <rguenther@suse.de> + + PR middle-end/112740 + * expr.cc (store_constructor): Check the integer vector + mask has a single bit per element before using sign-extension + to expand an uniform vector. + +2024-01-11 Juzhe-Zhong <juzhe.zhong@rivai.ai> + + * config/riscv/riscv-vector-costs.cc (costs::better_main_loop_than_p): VLA + preempt VLS on unknown NITERS loop. + +2024-01-11 Haochen Jiang <haochen.jiang@intel.com> + + * doc/invoke.texi: Add -mevex512. + +2024-01-11 Lulu Cheng <chenglulu@loongson.cn> + + * config/loongarch/loongarch.md (one_cmpl<mode>2): Replace GPR with X. + (*nor<mode>3): Likewise. + (nor<mode>3): Likewise. + (*negsi2_extended): New template. + (*<optab>si3_internal): Likewise. + (*one_cmplsi2_internal): Likewise. + (*norsi3_internal): Likewise. + (*<optab>nsi_internal): Likewise. + (bytepick_w_<bytepick_imm>_extend): Modify this template according to the + modified bit operation to make the optimization work. + +2024-01-11 liuhongt <hongtao.liu@intel.com> + + PR target/104401 + * match.pd (VEC_COND_EXPR: A < B ? A : B -> MIN_EXPR): New patten match. + +2024-01-10 Juzhe-Zhong <juzhe.zhong@rivai.ai> + + * config/riscv/riscv.cc (get_common_costs): Switch RVV cost model. + (get_vector_costs): Ditto. + (riscv_builtin_vectorization_cost): Ditto. + +2024-01-10 Juzhe-Zhong <juzhe.zhong@rivai.ai> + + * config/riscv/riscv-vector-costs.cc (costs::better_main_loop_than_p): Minior tweak. + +2024-01-10 Antoni Boucher <bouanto@zoho.com> + + PR jit/111396 + * ipa-fnsummary.cc (ipa_fnsummary_cc_finalize): Call + ipa_free_size_summary. + * ipa-icf.cc (ipa_icf_cc_finalize): New function. + * ipa-profile.cc (ipa_profile_cc_finalize): New function. + * ipa-prop.cc (ipa_prop_cc_finalize): New function. + * ipa-prop.h (ipa_prop_cc_finalize): New function. + * ipa-sra.cc (ipa_sra_cc_finalize): New function. + * ipa-utils.h (ipa_profile_cc_finalize, ipa_icf_cc_finalize, + ipa_sra_cc_finalize): New functions. + * toplev.cc (toplev::finalize): Call ipa_icf_cc_finalize, + ipa_prop_cc_finalize, ipa_profile_cc_finalize and + ipa_sra_cc_finalize + Include ipa-utils.h. + +2024-01-10 Jin Ma <jinma@linux.alibaba.com> + + * config/riscv/riscv-protos.h (th_int_get_mask): New prototype. + (th_int_get_save_adjustment): Likewise. + (th_int_adjust_cfi_prologue): Likewise. + * config/riscv/riscv.cc (BITSET_P): Moved away from here. + (TH_INT_INTERRUPT): New macro. + (riscv_expand_prologue): Add the processing of XTheadInt. + (riscv_expand_epilogue): Likewise. + * config/riscv/riscv.h (BITSET_P): Moved to here. + * config/riscv/riscv.md: New unspec. + * config/riscv/thead.cc (th_int_get_mask): New function. + (th_int_get_save_adjustment): Likewise. + (th_int_adjust_cfi_prologue): Likewise. + * config/riscv/thead.md (th_int_push): New pattern. + (th_int_pop): new pattern. + +2024-01-10 Tamar Christina <tamar.christina@arm.com> + + PR tree-optimization/112468 + * doc/sourcebuild.texi: Document ifn_copysign. + * match.pd: Only apply transformation if target supports the IFN. + +2024-01-10 Andrew Pinski <quic_apinski@quicinc.com> + + PR tree-optimization/112581 + * gimple-if-to-switch.cc (pass_if_to_switch::execute): Call + mark_ssa_maybe_undefs. + * tree-ssa-reassoc.cc (can_reassociate_op_p): Uninitialized + variables can not be reassociated. + (init_range_entry): Check for uninitialized variables too. + (init_reassoc): Call mark_ssa_maybe_undefs. + +2024-01-10 Maciej W. Rozycki <macro@embecosm.com> + + * config/riscv/riscv.cc (riscv_noce_conversion_profitable_p): + Also handle sign extension. + +2024-01-10 Alex Coplan <alex.coplan@arm.com> + + * config/aarch64/aarch64.opt (-mearly-ldp-fusion): Set default + to 0. + (-mlate-ldp-fusion): Likewise. + +2024-01-10 Tamar Christina <tamar.christina@arm.com> + + PR tree-optimization/113287 + * tree-vect-stmts.cc (vectorizable_early_exit): Check the flags on edge + instead of using BRANCH_EDGE to determine true edge. + +2024-01-10 Richard Biener <rguenther@suse.de> + + PR tree-optimization/113078 + * tree-vect-loop.cc (check_reduction_path): Canonicalize + .COND_SUB to .COND_ADD. + +2024-01-10 David Malcolm <dmalcolm@redhat.com> + + * gcc-urlifier.cc (gcc_urlifier::get_url_suffix_for_option): + Handle prefix mappings before calling find_opt. + (selftest::gcc_urlifier_cc_tests): Add example of urlifying a + "-fno-"-prefixed command-line option. + * opts-common.cc (get_option_prefix_remapping): New. + * opts.h (get_option_prefix_remapping): New decl. + +2024-01-10 David Malcolm <dmalcolm@redhat.com> + + * diagnostic.cc (diagnostic_context::report_diagnostic): Pass + m_urlifier to pp_output_formatted_text. + * pretty-print.cc: Add #define of INCLUDE_VECTOR. + (obstack_append_string): New overload, taking a length. + (urlify_quoted_string): Pass in an obstack ptr, rather than using + that of the pp's buffer. Generalize to handle trailing text in + the buffer beyond the run of quoted text. + (class quoting_info): New. + (on_begin_quote): New. + (on_end_quote): New. + (pp_format): Refactor phase 1 and phase 2 quoting support, moving + it to calls to on_begin_quote and on_end_quote. + (struct auto_obstack): New. + (quoting_info::handle_phase_3): New. + (pp_output_formatted_text): Add urlifier param. Use it if there + is deferred urlification. Delete m_quotes. + (selftest::pp_printf_with_urlifier): Pass urlifier to + pp_output_formatted_text. + (selftest::test_urlification): Update results for the existing + case of quoted text stradding chunks; add more such test cases. + * pretty-print.h (class quoting_info): New forward decl. + (chunk_info::m_quotes): New field. + (pp_output_formatted_text): Add optional urlifier param. + +2024-01-10 David Malcolm <dmalcolm@redhat.com> + + * pretty-print.cc (selftest::test_pp_format): Add selftest + coverage for numbered args. + +2024-01-10 Tamar Christina <tamar.christina@arm.com> + + PR tree-optimization/113144 + PR tree-optimization/113145 + * tree-vect-loop-manip.cc (slpeel_tree_duplicate_loop_to_edge_cfg): + Update all BB that the original exits dominated. + +2024-01-10 Eric Botcazou <ebotcazou@adacore.com> + + * dwarf2out.cc (modified_type_die): Extend the support of reverse + storage order to enumeration types if -gstrict-dwarf is not passed. + (gen_enumeration_type_die): Add REVERSE parameter and generate the + DIE immediately after the existing one if it is true. + (gen_tagged_type_die): Add REVERSE parameter and pass it in the + call to gen_enumeration_type_die. + (gen_type_die_with_usage): Add REVERSE parameter and pass it in the + first recursive call as well as the call to gen_tagged_type_die. + (gen_type_die): Add REVERSE parameter and pass it in the call to + gen_type_die_with_usage. + +2024-01-10 Jakub Jelinek <jakub@redhat.com> + + PR tree-optimization/113120 + * tree-sra.cc (analyze_access_subtree): For BITINT_TYPE + with root->size TYPE_PRECISION don't build anything new. + Otherwise, if root->type is a BITINT_TYPE, use build_bitint_type + rather than build_nonstandard_integer_type. + +2024-01-10 Hongyu Wang <hongyu.wang@intel.com> + + * config/i386/i386.opt: Adjust document. + * doc/invoke.texi: Add description for + -mapx-inline-asm-use-gpr32. + +2024-01-10 Juzhe-Zhong <juzhe.zhong@rivai.ai> + + * config/riscv/autovec.md (<u>avg<v_double_trunc>3_floor): Remove. + (avg<v_double_trunc>3_floor): New pattern. + (<u>avg<v_double_trunc>3_ceil): Remove. + (avg<v_double_trunc>3_ceil): New pattern. + (uavg<mode>3_floor): Ditto. + (uavg<mode>3_ceil): Ditto. + * config/riscv/riscv-protos.h (enum insn_flags): Add for average addition. + (enum insn_type): Ditto. + * config/riscv/riscv-v.cc: Ditto. + * config/riscv/vector-iterators.md (ashiftrt): Remove. + (ASHIFTRT): Ditto. + * config/riscv/vector.md: Add VLS modes. + +2024-01-10 Kewen Lin <linkw@linux.ibm.com> + + PR target/111480 + * config/rs6000/vsx.md (VCZLSBB): New int iterator. + (vczlsbb_char): New int attribute. + (vclzlsbb_<mode>, vctzlsbb_<mode>): Merge to ... + (vc<vczlsbb_char>zlsbb_<mode>): ... this. + (*vctzlsbb_zext_<mode>): Rename to ... + (*vc<vczlsbb_char>zlsbb_zext_<mode>): ... this, and extend it to + cover vclzlsbb. + +2024-01-10 Kewen Lin <linkw@linux.ibm.com> + + PR target/112606 + * config/rs6000/rs6000.md (copysign<mode>3 IEEE128): Change predicate + of the last argument from altivec_register_operand to any_operand. If + operands[2] is CONST_DOUBLE, emit abs or neg abs depending on its sign + otherwise if it doesn't satisfy altivec_register_operand, force it to + REG using copy_to_mode_reg. + +2024-01-10 Kewen Lin <linkw@linux.ibm.com> + + PR middle-end/113100 + * builtins.cc (expand_builtin_stack_address): Guard stack point + adjustment with SPARC_STACK_BOUNDARY_HACK. + +2024-01-10 Yang Yujie <yangyujie@loongson.cn> + + * config/loongarch/genopts/loongarch-strings: Remove explicit-reloc + argument string definitions. + * config/loongarch/loongarch-str.h: Same. + * config/loongarch/genopts/loongarch.opt.in: Mark -m[no-]explicit-relocs + as aliases to -mexplicit-relocs={always,none} + * config/loongarch/loongarch.opt: Regenerate. + * config/loongarch/loongarch.cc: Same. + +2024-01-10 Yang Yujie <yangyujie@loongson.cn> + + * config/loongarch/loongarch-def.h: Define constants with + enums instead of Macros. + +2024-01-10 Yang Yujie <yangyujie@loongson.cn> + + * config/loongarch/genopts/loongarch-strings: Rename. + * config/loongarch/genopts/loongarch.opt.in: Same. + * config/loongarch/loongarch-cpu.cc: Same. + * config/loongarch/loongarch-def.cc: Same. + * config/loongarch/loongarch-def.h: Same. + * config/loongarch/loongarch-opts.cc: Same. + * config/loongarch/loongarch-opts.h: Same. + * config/loongarch/loongarch-str.h: Same. + * config/loongarch/loongarch.opt: Same. + +2024-01-10 Yang Yujie <yangyujie@loongson.cn> + + * config/loongarch/genopts/genstr.sh: Prepend the isa_evolution + variable with the common la_ prefix. + * config/loongarch/genopts/loongarch.opt.in: Mark ISA evolution + flags as saved using TargetVariable. + * config/loongarch/loongarch.opt: Same. + * config/loongarch/loongarch-def.h: Define evolution_set to + mark changes to the -march default. + * config/loongarch/loongarch-driver.cc: Same. + * config/loongarch/loongarch-opts.cc: Same. + * config/loongarch/loongarch-opts.h: Define and use ISA evolution + conditions around the la_target structure. + * config/loongarch/loongarch.cc: Same. + * config/loongarch/loongarch.md: Same. + * config/loongarch/loongarch-builtins.cc: Same. + * config/loongarch/loongarch-c.cc: Same. + * config/loongarch/lasx.md: Same. + * config/loongarch/lsx.md: Same. + * config/loongarch/sync.md: Same. + +2024-01-09 Jeff Law <jlaw@ventanamicro.com> + + * config/epiphany/constraints.md (Car): Allow -1024..1023, no more, + no less. + +2024-01-09 Richard Sandiford <richard.sandiford@arm.com> + + * config/mn10300/mn10300.md (subdi3_degenerate): Add isa attribute. + +2024-01-09 Tamar Christina <tamar.christina@arm.com> + + * tree-vect-loop.cc (vectorizable_live_operation_1): Drop unused + restart_loop. + (vectorizable_live_operation): Likewise. + +2024-01-09 Tamar Christina <tamar.christina@arm.com> + + PR tree-optimization/113199 + * tree-vect-loop.cc (vectorizable_live_operation_1): Use + BIT_FIELD_REF. + +2024-01-09 Jakub Jelinek <jakub@redhat.com> + + PR target/113270 + * config.gcc (aarch64*-*-*): Add aarch64-builtins.h to target_gtfiles. + * config/aarch64/aarch64-builtins.cc (aarch64_simd_types): Add extern + GTY(()) declaration before the definition, drop GTY(()) drom the + definition. + +2024-01-09 Richard Biener <rguenther@suse.de> + + PR tree-optimization/113026 + * tree-vect-loop-manip.cc (vect_do_peeling): Remove + redundant and wrong niter bound setting. Move niter + bound adjustment down. + +2024-01-09 Tamar Christina <tamar.christina@arm.com> + + PR middle-end/113163 + * tree-vect-loop-manip.cc (vect_can_peel_nonlinear_iv_p): + Reject non-linear inductions that aren't supported. + +2024-01-09 Roger Sayle <roger@nextmovesoftware.com> + + * config/arc/arc.cc (arc_shift_alg): New enumerated type for + left shift implementation strategies. + (arc_shift_info): Type for each entry of the shift strategy table. + (arc_shift_context_idx): Return a integer value for each code + generation context, used as an index + (arc_ashl_alg): Table indexed by context and shifted bit count. + (arc_split_ashl): Use the arc_ashl_alg table to select SImode + left shift implementation. + (arc_rtx_costs) <case ASHIFT>: Use the arc_ashl_alg table to + provide accurate costs, when optimizing for speed or size. + +2024-01-09 Juzhe-Zhong <juzhe.zhong@rivai.ai> + + * config/riscv/riscv-vector-costs.cc (loop_invariant_op_p): Fix loop invariant check. + +2024-01-09 Julian Brown <julian@codesourcery.com> + + * gimplify.cc (gimplify_expr): Ensure OMP_ARRAY_SECTION has been + processed out before gimplification. + * tree-pretty-print.cc (dump_generic_node): Support OMP_ARRAY_SECTION. + * tree.def (OMP_ARRAY_SECTION): New tree code. + +2024-01-09 Jakub Jelinek <jakub@redhat.com> + + PR tree-optimization/113210 + * tree-vect-loop.cc (vect_get_loop_niters): If non-INTEGER_CST + value in *number_of_iterationsm1 PLUS_EXPR 1 is folded into + INTEGER_CST, recompute *number_of_iterationsm1 as the INTEGER_CST + minus 1. + +2024-01-09 Eric Botcazou <ebotcazou@adacore.com> + + PR rtl-optimization/113140 + * reorg.cc (fill_slots_from_thread): If we are to branch after the + last instruction of the function, create an end label. + +2024-01-09 Roger Sayle <roger@nextmovesoftware.com> + Hongtao Liu <hongtao.liu@intel.com> + + PR target/112992 + * config/i386/i386-expand.cc + (ix86_convert_const_wide_int_to_broadcast): Allow call to + ix86_expand_vector_init_duplicate to fail, and return NULL_RTX. + (ix86_broadcast_from_constant): Revert recent change; Return a + suitable MEMREF independently of mode/target combinations. + (ix86_expand_vector_move): Allow ix86_expand_vector_init_duplicate + to decide whether expansion is possible/preferrable. Only try + forcing DImode constants to memory (and trying again) if calling + ix86_expand_vector_init_duplicate fails with an DImode immediate + constant. + (ix86_expand_vector_init_duplicate) <case E_V2DImode>: Try using + V4SImode for suitable immediate constants. + <case E_V4DImode>: Try using V8SImode for suitable constants. + <case E_V4HImode>: Fail for CONST_INT_P, i.e. use constant pool. + <case E_V2HImode>: Likewise. + <case E_V8HImode>: For CONST_INT_P try using V4SImode via widen. + <case E_V16QImode>: For CONT_INT_P try using V8HImode via widen. + <label widen>: Handle CONT_INTs via simplify_binary_operation. + Allow recursive calls to ix86_expand_vector_init_duplicate to fail. + <case E_V16HImode>: For CONST_INT_P try V8SImode via widen. + <case E_V32QImode>: For CONST_INT_P try V16HImode via widen. + (ix86_expand_vector_init): Move try using a broadcast for all_same + with ix86_expand_vector_init_duplicate before using constant pool. + +2024-01-09 Chung-Ju Wu <jasonwucj@gmail.com> + + * doc/invoke.texi (Arm Options): Document Cortex-M52 options. + +2024-01-09 Chung-Ju Wu <jasonwucj@gmail.com> + + * config/arm/arm-cpus.in (cortex-m52): New cpu. + * config/arm/arm-tables.opt: Regenerate. + * config/arm/arm-tune.md: Regenerate. + +2024-01-09 Jiahao Xu <xujiahao@loongson.cn> + + * config/loongarch/lasx.md (vec_initv32qiv16qi): Rename to .. + (vec_init<mode><lasxhalf>): .. this, and extend to mode. + (@vec_concatz<mode>): New insn pattern. + * config/loongarch/loongarch.cc (loongarch_expand_vector_group_init): + Handle VALS containing two vectors. + +2024-01-09 Juzhe-Zhong <juzhe.zhong@rivai.ai> + + * config/riscv/riscv-vector-builtins-functions.def (vleff): Move comments. + (vundefined): Ditto. + +2024-01-09 Feng Wang <wangfeng@eswincomputing.com> + + * config/riscv/riscv-vector-builtins-bases.cc (class vandn): + Add new function_base for crypto vector. + (class bitmanip): Ditto. + (class b_reverse):Ditto. + (class vwsll): Ditto. + (class clmul): Ditto. + (class vg_nhab): Ditto. + (class crypto_vv):Ditto. + (class crypto_vi):Ditto. + (class vaeskf2_vsm3c):Ditto. + (class vsm3me): Ditto. + (BASE): Add BASE declaration for crypto vector. + * config/riscv/riscv-vector-builtins-bases.h: Ditto. + * config/riscv/riscv-vector-builtins-functions.def (REQUIRED_EXTENSIONS): + Add crypto vector intrinsic definition. + (vbrev): Ditto. + (vclz): Ditto. + (vctz): Ditto. + (vwsll): Ditto. + (vandn): Ditto. + (vbrev8): Ditto. + (vrev8): Ditto. + (vrol): Ditto. + (vror): Ditto. + (vclmul): Ditto. + (vclmulh): Ditto. + (vghsh): Ditto. + (vgmul): Ditto. + (vaesef): Ditto. + (vaesem): Ditto. + (vaesdf): Ditto. + (vaesdm): Ditto. + (vaesz): Ditto. + (vaeskf1): Ditto. + (vaeskf2): Ditto. + (vsha2ms): Ditto. + (vsha2ch): Ditto. + (vsha2cl): Ditto. + (vsm4k): Ditto. + (vsm4r): Ditto. + (vsm3me): Ditto. + (vsm3c): Ditto. + * config/riscv/riscv-vector-builtins-shapes.cc (struct crypto_vv_def): + Add new function_shape for crypto vector. + (struct crypto_vi_def): Ditto. + (struct crypto_vv_no_op_type_def): Ditto. + (SHAPE): Add SHAPE declaration of crypto vector. + * config/riscv/riscv-vector-builtins-shapes.h: Ditto. + * config/riscv/riscv-vector-builtins-types.def (DEF_RVV_CRYPTO_SEW32_OPS): + Add new data type for crypto vector. + (DEF_RVV_CRYPTO_SEW64_OPS): Ditto. + (vuint32mf2_t): Ditto. + (vuint32m1_t): Ditto. + (vuint32m2_t): Ditto. + (vuint32m4_t): Ditto. + (vuint32m8_t): Ditto. + (vuint64m1_t): Ditto. + (vuint64m2_t): Ditto. + (vuint64m4_t): Ditto. + (vuint64m8_t): Ditto. + * config/riscv/riscv-vector-builtins.cc (DEF_RVV_CRYPTO_SEW32_OPS): + Add new data struct for crypto vector. + (DEF_RVV_CRYPTO_SEW64_OPS): Ditto. + (registered_function::overloaded_hash): Processing size_t uimm for C overloaded func. + * config/riscv/riscv-vector-builtins.def (vi): Add vi OP_TYPE. + 2024-01-08 Ilya Leoshkevich <iii@linux.ibm.com> PR sanitizer/113251 diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP index e55f042..9952a5e 100644 --- a/gcc/DATESTAMP +++ b/gcc/DATESTAMP @@ -1 +1 @@ -20240109 +20240116 diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog index 9d96560..3ca92dc 100644 --- a/gcc/ada/ChangeLog +++ b/gcc/ada/ChangeLog @@ -1,3 +1,204 @@ +2024-01-09 Eric Botcazou <ebotcazou@adacore.com> + + * gcc-interface/decl.cc (gnat_to_gnu_entity) <E_Array_Type>: Use the + TYPE_CANONICAL of types when it comes to aliasing. + * gcc-interface/utils.cc (relate_alias_sets): Likewise. + +2024-01-09 Eric Botcazou <ebotcazou@adacore.com> + + * gcc-interface/decl.cc (gnat_to_gnu_entity) <E_Array_Type>: Use a + separate FLD local variable to hold the first field of the fat + pointer type being built. + * gcc-interface/gigi.h (relate_alias_sets): Remove GNU_ prefix on + the first two parameters. + * gcc-interface/utils.cc (relate_alias_sets): Likewise and adjust. + +2024-01-09 Viljar Indus <indus@adacore.com> + + * sem_attr.adb: avoid marking a use of the Address attribute + as a modification of its prefix. + +2024-01-09 Gary Dismukes <dismukes@adacore.com> + + * exp_aggr.adb (Expand_Container_Aggregate): Change "not Present" + tests to tests using "No" (in two places). + +2024-01-09 Bob Duff <duff@adacore.com> + + * sem_ch12.adb (Instantiate_Type): Make the relevant error message + conditional upon "Ekind (A_Gen_T) /= E_Incomplete_Type". Misc + cleanup. + +2024-01-09 Gary Dismukes <dismukes@adacore.com> + + * exp_aggr.adb (Expand_Container_Aggregate): Add code to determine + whether the aggregate is an indexed aggregate, setting a flag + (Is_Indexed_Aggregate), which is tested to have proper separation + of treatment for the Add_Unnamed + (for positional aggregates) and New_Indexed (for indexed + aggregates) cases. In the code generating associations for indexed + aggregates, remove the code for Expressions cases entirely, since + the code for indexed aggregates is governed by the presence of + Component_Associations, and add an assertion that Expressions must + be Empty. Also, exclude empty aggregates from entering that code. + +2024-01-09 Eric Botcazou <ebotcazou@adacore.com> + + * rtsfind.ads (RE_Id): Remove RE_Attach. + (RE_Unit_Table): Likewise. + * libgnat/s-finmas.ads (Attach): Delete. + * libgnat/s-finmas.adb (Attach): Likewise. + +2024-01-09 Tucker Taft <taft@adacore.com> + + * pprint.adb (List_Name): Check for "Box_Present" when displaying + a list, and emit "<>" if returns True. + * sem_scil.adb (Check_SCIL_Node): Handle case when the type of a + parameter is from a package that was mentioned in a limited with + clause, and make no further checks, since this check routine does + not have all the logic to check such a usage. + +2024-01-09 Eric Botcazou <ebotcazou@adacore.com> + + * freeze.adb (Freeze_Expression.Has_Decl_In_List): Deal specifically + with itypes that are class-wide subtypes. + +2024-01-09 Eric Botcazou <ebotcazou@adacore.com> + + * libgnat/s-atopri.ads (Atomic_Store): New generic procedure. + (Atomic_Store_8): New instantiated procedure. + (Atomic_Store_16): Likewise. + (Atomic_Store_32): Likewise. + (Atomic_Store_64): Likewise. + * libgnat/s-atopri__32.ads (Atomic_Store): New generic procedure. + (Atomic_Store_8): New instantiated procedure. + (Atomic_Store_16): Likewise. + (Atomic_Store_32): Likewise. + * gcc-interface/decl.cc (gnat_to_gnu_subprog_type): Implement the + support for __atomic_store_n and __sync_bool_compare_and_swap_n. + * gcc-interface/gigi.h (list_second): New inline function. + +2024-01-09 Javier Miranda <miranda@adacore.com> + + * sem_ch6.adb (Analyze_Subprogram_Specification): Do not replace + the type of the formals with its corresponding record in + init-procs. + * sem_ch9.adb (Analyze_Requeue): Add missing support to requeue to + a procedure that denotes a renaming of an entry. + +2024-01-09 Piotr Trojanek <trojanek@adacore.com> + + * exp_util.adb (Possible_Side_Effect_In_SPARK): Refine handling of + itype declarations. + +2024-01-09 Piotr Trojanek <trojanek@adacore.com> + + * sem_ch6.adb (Analyze_Subprogram_Specification): Set Is_Inlined + flag by default in GNATprove mode. + * sem_res.adb (Resolve_Call): Only look at flag which is cleared + when inlined subprogram is detected to be recursive. + +2024-01-09 Piotr Trojanek <trojanek@adacore.com> + + * inline.adb (Establish_Actual_Mapping_For_Inlined_Call): + Remove detection of recursive calls. + +2024-01-09 Piotr Trojanek <trojanek@adacore.com> + + * inline.adb (Cannot_Inline): Cleanup use of 'Length; remove + dead code. + +2024-01-09 Piotr Trojanek <trojanek@adacore.com> + + * sem_aggr.adb (Resolve_Container_Aggregate): Use "No". + * sem_ch8.adb (Find_Direct_Name): Likewise. + +2024-01-09 Steve Baird <baird@adacore.com> + + * sem_util.adb (Enclosing_Declaration): Instead of returning a + subprogram specification node, return its parent (which is + presumably a subprogram declaration). + * contracts.adb (Insert_Stable_Property_Check): Remove code + formerly needed to compensate for incorrect behavior of + Sem_Util.Enclosing_Declaration. + * exp_attr.adb (In_Available_Context): Remove code formerly needed + to compensate for incorrect behavior of + Sem_Util.Enclosing_Declaration. + * sem_ch8.adb (Is_Actual_Subp_Of_Inst): Remove code formerly + needed to compensate for incorrect behavior of + Sem_Util.Enclosing_Declaration. + +2024-01-09 Steve Baird <baird@adacore.com> + + * sem_ch8.adb (Check_Constrained_Object): Before updating the + subtype mark of an object renaming declaration by calling Rewrite, + first check whether the destination of the Rewrite call exists. + * atree.adb (Copy_Slots): Return without performing any updates if + Destination equals Empty or Error, or if Source equals Empty. Any + of those conditions indicates an error case. + * sem_ch12.adb (Analyze_Formal_Derived_Type): Avoid cascading + errors. + * sem_ch3.adb (Analyze_Number_Declaration): In an error case, do + not pass Error as destination in a call to Rewrite. + (Find_Type_Of_Subtype_Indic): In an error case, do not pass Error + or Empty as destination in a call to Rewrite. + +2024-01-09 Joffrey Huguet <huguet@adacore.com> + + * libgnat/i-cstrin.ads (Update): Fix precondition. + +2024-01-09 Eric Botcazou <ebotcazou@adacore.com> + + * sem_aggr.adb (Resolve_Extension_Aggregate): Remove the unreachable + call to Transform_BIP_Assignment as well as the procedure. + +2024-01-09 Bob Duff <duff@adacore.com> + + * lib-xref.adb (Generate_Reference): Do not count it as a read + reference if we're calling a TSS. + +2024-01-09 Piotr Trojanek <trojanek@adacore.com> + + * doc/gnat_rm/implementation_defined_aspects.rst, + doc/gnat_rm/implementation_defined_pragmas.rst: Add sections for + Always_Terminates. + * gnat-style.texi: Regenerate. + * gnat_rm.texi: Regenerate. + * gnat_ugn.texi: Regenerate. + +2024-01-09 Eric Botcazou <ebotcazou@adacore.com> + + PR ada/78207 + * libgnat/g-regexp.ads: Fix outdated comment. + +2024-01-09 Eric Botcazou <ebotcazou@adacore.com> + + PR ada/112781 + * exp_ch6.ads (Is_Build_In_Place_Function): Adjust description. + * exp_ch6.adb (Is_True_Build_In_Place_Function_Call): Delete. + (Is_Function_Call_With_BIP_Formals): New predicate. + (Is_Build_In_Place_Function_Call): Restore original semantics. + (Expand_Call_Helper): Adjust conditions guarding the calls to + Add_Dummy_Build_In_Place_Actuals to above renaming. + (Expand_N_Extended_Return_Statement): Adjust to above renaming. + (Expand_Simple_Function_Return): Likewise. Move the assertion + to after the transformation into an extended return statement. + (Make_Build_In_Place_Call_In_Allocator): Remove unreachable code. + (Make_Build_In_Place_Call_In_Assignment): Likewise. + +2024-01-09 Eric Botcazou <ebotcazou@adacore.com> + + PR ada/112781 + * sem_ch12.adb (Instantiate_Type): Use Etype instead of Base_Type + consistently to retrieve the ancestor for a derived type. + * sem_ch4.adb (Analyze_Explicit_Dereference): Test Is_Access_Type + consistently before accessing Designated_Type. + +2024-01-09 Eric Botcazou <ebotcazou@adacore.com> + + * gcc-interface/utils2.cc (build_binary_op) <EQ_EXPR>: Relax + assertion for regular pointer types. + 2024-01-04 David Malcolm <dmalcolm@redhat.com> * gcc-interface/lang.opt.urls: New file, autogenerated by diff --git a/gcc/analyzer/ChangeLog b/gcc/analyzer/ChangeLog index 1cd5126..2d2d217 100644 --- a/gcc/analyzer/ChangeLog +++ b/gcc/analyzer/ChangeLog @@ -1,3 +1,23 @@ +2024-01-16 David Malcolm <dmalcolm@redhat.com> + + PR analyzer/106229 + * analyzer.h (compare_constants): New decl. + * constraint-manager.cc (compare_constants): Make non-static. + * sm-taint.cc: Add include "fold-const.h". + (class concrete_range): New. + (get_possible_range): New. + (index_can_be_out_of_bounds_p): New. + (region_model::check_region_for_taint): Reject + -Wanalyzer-tainted-array-index if the type of the value makes it + impossible for it to be out-of-bounds of the array. + +2024-01-16 David Malcolm <dmalcolm@redhat.com> + + PR analyzer/113333 + * region-model-manager.cc + (region_model_manager::maybe_fold_unaryop): Casting all zeroes + should give all zeroes. + 2024-01-04 David Malcolm <dmalcolm@redhat.com> * analyzer.opt.urls: New file, autogenerated by diff --git a/gcc/analyzer/analyzer.h b/gcc/analyzer/analyzer.h index 8dec964..23e3f71 100644 --- a/gcc/analyzer/analyzer.h +++ b/gcc/analyzer/analyzer.h @@ -427,6 +427,9 @@ bit_offset_to_json (const bit_offset_t &offset); extern json::value * byte_offset_to_json (const byte_offset_t &offset); +extern tristate +compare_constants (tree lhs_const, enum tree_code op, tree rhs_const); + } // namespace ana extern bool is_special_named_call_p (const gcall *call, const char *funcname, diff --git a/gcc/analyzer/constraint-manager.cc b/gcc/analyzer/constraint-manager.cc index 2db6c17..e8bcabe 100644 --- a/gcc/analyzer/constraint-manager.cc +++ b/gcc/analyzer/constraint-manager.cc @@ -54,7 +54,7 @@ along with GCC; see the file COPYING3. If not see namespace ana { -static tristate +tristate compare_constants (tree lhs_const, enum tree_code op, tree rhs_const) { tree comparison diff --git a/gcc/analyzer/region-model-manager.cc b/gcc/analyzer/region-model-manager.cc index fc3523f..62f808a 100644 --- a/gcc/analyzer/region-model-manager.cc +++ b/gcc/analyzer/region-model-manager.cc @@ -457,6 +457,12 @@ region_model_manager::maybe_fold_unaryop (tree type, enum tree_code op, && region_sval->get_type () && POINTER_TYPE_P (region_sval->get_type ())) return get_ptr_svalue (type, region_sval->get_pointee ()); + + /* Casting all zeroes should give all zeroes. */ + if (type + && arg->all_zeroes_p () + && (INTEGRAL_TYPE_P (type) || POINTER_TYPE_P (type))) + return get_or_create_int_cst (type, 0); } break; case TRUTH_NOT_EXPR: diff --git a/gcc/analyzer/sm-taint.cc b/gcc/analyzer/sm-taint.cc index 3f7e5cd..dc4b078 100644 --- a/gcc/analyzer/sm-taint.cc +++ b/gcc/analyzer/sm-taint.cc @@ -40,6 +40,7 @@ along with GCC; see the file COPYING3. If not see #include "digraph.h" #include "stringpool.h" #include "attribs.h" +#include "fold-const.h" #include "analyzer/supergraph.h" #include "analyzer/call-string.h" #include "analyzer/program-point.h" @@ -1369,6 +1370,104 @@ make_taint_state_machine (logger *logger) return new taint_state_machine (logger); } +/* A closed concrete range. */ + +class concrete_range +{ +public: + /* Return true iff THIS is fully within OTHER + i.e. + - m_min must be >= OTHER.m_min + - m_max must be <= OTHER.m_max. */ + bool within_p (const concrete_range &other) const + { + if (compare_constants (m_min, GE_EXPR, other.m_min).is_true ()) + if (compare_constants (m_max, LE_EXPR, other.m_max).is_true ()) + return true; + return false; + } + + tree m_min; + tree m_max; +}; + +/* Attempt to get a closed concrete range for SVAL based on types. + If found, write to *OUT and return true. + Otherwise return false. */ + +static bool +get_possible_range (const svalue *sval, concrete_range *out) +{ + if (const svalue *inner = sval->maybe_undo_cast ()) + { + concrete_range inner_range; + if (!get_possible_range (inner, &inner_range)) + return false; + + if (sval->get_type () + && inner->get_type () + && INTEGRAL_TYPE_P (sval->get_type ()) + && INTEGRAL_TYPE_P (inner->get_type ()) + && TYPE_UNSIGNED (inner->get_type ()) + && (TYPE_PRECISION (sval->get_type ()) + > TYPE_PRECISION (inner->get_type ()))) + { + /* We have a cast from an unsigned type to a wider integral type. + Assuming this is zero-extension, we can inherit the range from + the inner type. */ + enum tree_code op = ((const unaryop_svalue *)sval)->get_op (); + out->m_min = fold_unary (op, sval->get_type (), inner_range.m_min); + out->m_max = fold_unary (op, sval->get_type (), inner_range.m_max); + return true; + } + } + + if (sval->get_type () + && INTEGRAL_TYPE_P (sval->get_type ())) + { + out->m_min = TYPE_MIN_VALUE (sval->get_type ()); + out->m_max = TYPE_MAX_VALUE (sval->get_type ()); + return true; + } + + return false; +} + +/* Determine if it's possible for tainted array access ELEMENT_REG to + actually be a problem. + + Check here for index being from e.g. unsigned char when the array + contains >= 255 elements. + + Return true if out-of-bounds is possible, false if it's impossible + (for suppressing false positives). */ + +static bool +index_can_be_out_of_bounds_p (const element_region *element_reg) +{ + const svalue *index = element_reg->get_index (); + const region *array_reg = element_reg->get_parent_region (); + + if (array_reg->get_type () + && TREE_CODE (array_reg->get_type ()) == ARRAY_TYPE + && TYPE_DOMAIN (array_reg->get_type ()) + && INTEGRAL_TYPE_P (TYPE_DOMAIN (array_reg->get_type ()))) + { + concrete_range valid_index_range; + valid_index_range.m_min + = TYPE_MIN_VALUE (TYPE_DOMAIN (array_reg->get_type ())); + valid_index_range.m_max + = TYPE_MAX_VALUE (TYPE_DOMAIN (array_reg->get_type ())); + + concrete_range possible_index_range; + if (get_possible_range (index, &possible_index_range)) + if (possible_index_range.within_p (valid_index_range)) + return false; + } + + return true; +} + /* Complain to CTXT if accessing REG leads could lead to arbitrary memory access under an attacker's control (due to taint). */ @@ -1415,10 +1514,17 @@ region_model::check_region_for_taint (const region *reg, gcc_assert (state); enum bounds b; if (taint_sm.get_taint (state, index->get_type (), &b)) - { - tree arg = get_representative_tree (index); - ctxt->warn (make_unique<tainted_array_index> (taint_sm, arg, b)); - } + { + if (index_can_be_out_of_bounds_p (element_reg)) + { + tree arg = get_representative_tree (index); + ctxt->warn (make_unique<tainted_array_index> (taint_sm, + arg, b)); + } + else if (ctxt->get_logger ()) + ctxt->get_logger ()->log ("rejecting tainted_array_index as" + " out of bounds is not possible"); + } } break; diff --git a/gcc/builtins.cc b/gcc/builtins.cc index d176759..09f2354 100644 --- a/gcc/builtins.cc +++ b/gcc/builtins.cc @@ -5450,6 +5450,7 @@ expand_builtin_stack_address () rtx ret = convert_to_mode (ptr_mode, copy_to_reg (stack_pointer_rtx), STACK_UNSIGNED); +#ifdef SPARC_STACK_BOUNDARY_HACK /* Unbias the stack pointer, bringing it to the boundary between the stack area claimed by the active function calling this builtin, and stack ranges that could get clobbered if it called another @@ -5476,7 +5477,9 @@ expand_builtin_stack_address () (caller) function's active area as well, whereas those pushed or allocated temporarily for a call are regarded as part of the callee's stack range, rather than the caller's. */ - ret = plus_constant (ptr_mode, ret, STACK_POINTER_OFFSET); + if (SPARC_STACK_BOUNDARY_HACK) + ret = plus_constant (ptr_mode, ret, STACK_POINTER_OFFSET); +#endif return force_reg (ptr_mode, ret); } diff --git a/gcc/c-family/ChangeLog b/gcc/c-family/ChangeLog index 3f8c3d6..47019bd 100644 --- a/gcc/c-family/ChangeLog +++ b/gcc/c-family/ChangeLog @@ -1,3 +1,33 @@ +2024-01-11 Julian Brown <julian@codesourcery.com> + + * c-pretty-print.cc (c_pretty_printer::postfix_expression, + c_pretty_printer::expression): Add OMP_ARRAY_SECTION support. + +2024-01-09 waffl3x <waffl3x@protonmail.com> + + PR c++/102609 + PR c++/102609 + C++23 P0847R7 (deducing this) - diagnostics. + * c-cppbuiltin.cc (c_cpp_builtins): Define + __cpp_explicit_this_parameter=202110L feature test macro. + +2024-01-09 Jakub Jelinek <jakub@redhat.com> + + PR c/113262 + * c-attribs.cc (handle_copy_attribute): Don't use + DECL_SOURCE_LOCATION (decl) if decl is not DECL_P, use input_location + instead. Formatting fixes. + +2024-01-09 Julian Brown <julian@codesourcery.com> + + * c-common.h (c_omp_address_inspector): Remove static from get_origin + and maybe_unconvert_ref methods. + * c-omp.cc (c_omp_split_clauses): Support OMP_ARRAY_SECTION. + (c_omp_address_inspector::map_supported_p): Handle OMP_ARRAY_SECTION. + (c_omp_address_inspector::get_origin): Avoid dereferencing possibly + NULL type when processing template decls. + (c_omp_address_inspector::maybe_unconvert_ref): Likewise. + 2024-01-04 David Malcolm <dmalcolm@redhat.com> * c.opt.urls: New file, autogenerated by regenerate-opt-urls.py. diff --git a/gcc/c-family/c-ada-spec.cc b/gcc/c-family/c-ada-spec.cc index 7d886c0..4b245ed 100644 --- a/gcc/c-family/c-ada-spec.cc +++ b/gcc/c-family/c-ada-spec.cc @@ -1566,6 +1566,8 @@ check_type_name_conflict (pretty_printer *buffer, tree t) s = ""; else if (TREE_CODE (TYPE_NAME (tmp)) == IDENTIFIER_NODE) s = IDENTIFIER_POINTER (TYPE_NAME (tmp)); + else if (!DECL_NAME (TYPE_NAME (tmp))) + s = ""; else s = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (tmp))); diff --git a/gcc/c-family/c-cppbuiltin.cc b/gcc/c-family/c-cppbuiltin.cc index 9553b13..38f3203 100644 --- a/gcc/c-family/c-cppbuiltin.cc +++ b/gcc/c-family/c-cppbuiltin.cc @@ -1082,6 +1082,7 @@ c_cpp_builtins (cpp_reader *pfile) cpp_define (pfile, "__cpp_named_character_escapes=202207L"); cpp_define (pfile, "__cpp_static_call_operator=202207L"); cpp_define (pfile, "__cpp_implicit_move=202207L"); + cpp_define (pfile, "__cpp_explicit_this_parameter=202110L"); } if (cxx_dialect > cxx23) { diff --git a/gcc/c-family/c-pretty-print.cc b/gcc/c-family/c-pretty-print.cc index 51c8856..45045fb 100644 --- a/gcc/c-family/c-pretty-print.cc +++ b/gcc/c-family/c-pretty-print.cc @@ -1650,6 +1650,17 @@ c_pretty_printer::postfix_expression (tree e) pp_c_right_bracket (this); break; + case OMP_ARRAY_SECTION: + postfix_expression (TREE_OPERAND (e, 0)); + pp_c_left_bracket (this); + if (TREE_OPERAND (e, 1)) + expression (TREE_OPERAND (e, 1)); + pp_colon (this); + if (TREE_OPERAND (e, 2)) + expression (TREE_OPERAND (e, 2)); + pp_c_right_bracket (this); + break; + case CALL_EXPR: { call_expr_arg_iterator iter; @@ -2699,6 +2710,7 @@ c_pretty_printer::expression (tree e) case POSTINCREMENT_EXPR: case POSTDECREMENT_EXPR: case ARRAY_REF: + case OMP_ARRAY_SECTION: case CALL_EXPR: case COMPONENT_REF: case BIT_FIELD_REF: diff --git a/gcc/c/ChangeLog b/gcc/c/ChangeLog index 3e2b5b2..e7bcd95 100644 --- a/gcc/c/ChangeLog +++ b/gcc/c/ChangeLog @@ -1,3 +1,46 @@ +2024-01-12 Jakub Jelinek <jakub@redhat.com> + + PR c/113315 + * c-typeck.cc (build_array_ref): If index has BITINT_TYPE type with + precision larger than sizetype precision, convert it to sizetype. + +2024-01-11 Julian Brown <julian@codesourcery.com> + + * c-parser.cc (c_parser_braced_init, c_parser_conditional_expression): + Don't allow OpenMP array section. + (c_parser_postfix_expression): Don't allow array section in statement + expression. + (c_parser_postfix_expression_after_primary): Add support for OpenMP + array section parsing. + (c_parser_expr_list): Don't allow OpenMP array section here. + (c_parser_omp_variable_list): Change ALLOW_DEREF parameter to + MAP_LVALUE. Support parsing of general lvalues in "map", "to" and + "from" clauses. + (c_parser_omp_var_list_parens): Change ALLOW_DEREF parameter to + MAP_LVALUE. Update call to c_parser_omp_variable_list. + (c_parser_oacc_data_clause): Update calls to + c_parser_omp_var_list_parens. + (c_parser_omp_clause_reduction): Use OMP_ARRAY_SECTION tree node + instead of TREE_LIST for array sections. + (c_parser_omp_target): Allow GOMP_MAP_ATTACH. + * c-tree.h (c_omp_array_section_p): Add extern declaration. + (build_omp_array_section): Add prototype. + * c-typeck.cc (c_omp_array_section_p): Add flag. + (mark_exp_read): Support OMP_ARRAY_SECTION. + (build_omp_array_section): Add function. + (build_external_ref): Tweak error path for OpenMP array sections. + (handle_omp_array_sections_1): Use OMP_ARRAY_SECTION tree code instead + of TREE_LIST. Handle more kinds of expressions. + (c_oacc_check_attachments): Use OMP_ARRAY_SECTION instead of TREE_LIST + for array sections. + (c_finish_omp_clauses): Use OMP_ARRAY_SECTION instead of TREE_LIST. + Check for supported expression types. + +2024-01-09 Tamar Christina <tamar.christina@arm.com> + + PR c/113267 + * c-parser.cc (c_parser_for_statement): Skip the pragma is no cond. + 2024-01-03 Kwok Cheung Yeung <kcy@codesourcery.com> * c-parser.cc (c_parser_omp_clause_name): Move handling of indirect diff --git a/gcc/c/c-parser.cc b/gcc/c/c-parser.cc index 878f323..c31349d 100644 --- a/gcc/c/c-parser.cc +++ b/gcc/c/c-parser.cc @@ -6146,6 +6146,8 @@ c_parser_braced_init (c_parser *parser, tree type, bool nested_p, location_t brace_loc = c_parser_peek_token (parser)->location; gcc_obstack_init (&braced_init_obstack); gcc_assert (c_parser_next_token_is (parser, CPP_OPEN_BRACE)); + bool save_c_omp_array_section_p = c_omp_array_section_p; + c_omp_array_section_p = false; matching_braces braces; braces.consume_open (parser); if (nested_p) @@ -6184,6 +6186,7 @@ c_parser_braced_init (c_parser *parser, tree type, bool nested_p, break; } } + c_omp_array_section_p = save_c_omp_array_section_p; c_token *next_tok = c_parser_peek_token (parser); if (next_tok->type != CPP_CLOSE_BRACE) { @@ -9149,6 +9152,7 @@ c_parser_conditional_expression (c_parser *parser, struct c_expr *after, { struct c_expr cond, exp1, exp2, ret; location_t start, cond_loc, colon_loc; + bool save_c_omp_array_section_p = c_omp_array_section_p; gcc_assert (!after || c_dialect_objc ()); @@ -9156,6 +9160,7 @@ c_parser_conditional_expression (c_parser *parser, struct c_expr *after, if (c_parser_next_token_is_not (parser, CPP_QUERY)) return cond; + c_omp_array_section_p = false; if (cond.value != error_mark_node) start = cond.get_start (); else @@ -9208,6 +9213,7 @@ c_parser_conditional_expression (c_parser *parser, struct c_expr *after, ret.set_error (); ret.original_code = ERROR_MARK; ret.original_type = NULL; + c_omp_array_section_p = save_c_omp_array_section_p; return ret; } { @@ -9254,6 +9260,7 @@ c_parser_conditional_expression (c_parser *parser, struct c_expr *after, } set_c_expr_source_range (&ret, start, exp2.get_finish ()); ret.m_decimal = 0; + c_omp_array_section_p = save_c_omp_array_section_p; return ret; } @@ -10705,6 +10712,7 @@ c_parser_postfix_expression (c_parser *parser) /* A statement expression. */ tree stmt; location_t brace_loc; + bool save_c_omp_array_section_p = c_omp_array_section_p; c_parser_consume_token (parser); brace_loc = c_parser_peek_token (parser)->location; c_parser_consume_token (parser); @@ -10721,6 +10729,7 @@ c_parser_postfix_expression (c_parser *parser) expr.set_error (); break; } + c_omp_array_section_p = false; stmt = c_begin_stmt_expr (); c_parser_compound_statement_nostart (parser); location_t close_loc = c_parser_peek_token (parser)->location; @@ -10731,6 +10740,7 @@ c_parser_postfix_expression (c_parser *parser) expr.value = c_finish_stmt_expr (brace_loc, stmt); set_c_expr_source_range (&expr, loc, close_loc); mark_exp_read (expr.value); + c_omp_array_section_p = save_c_omp_array_section_p; } else { @@ -12480,7 +12490,7 @@ c_parser_postfix_expression_after_primary (c_parser *parser, struct c_expr expr) { struct c_expr orig_expr; - tree ident, idx; + tree ident, idx, len; location_t sizeof_arg_loc[6], comp_loc; tree sizeof_arg[6]; unsigned int literal_zero_mask; @@ -12499,12 +12509,29 @@ c_parser_postfix_expression_after_primary (c_parser *parser, case CPP_OPEN_SQUARE: /* Array reference. */ c_parser_consume_token (parser); - idx = c_parser_expression (parser).value; + idx = len = NULL_TREE; + if (!c_omp_array_section_p + || c_parser_next_token_is_not (parser, CPP_COLON)) + idx = c_parser_expression (parser).value; + + if (c_omp_array_section_p + && c_parser_next_token_is (parser, CPP_COLON)) + { + c_parser_consume_token (parser); + if (c_parser_next_token_is_not (parser, CPP_CLOSE_SQUARE)) + len = c_parser_expression (parser).value; + + expr.value = build_omp_array_section (op_loc, expr.value, idx, + len); + } + else + expr.value = build_array_ref (op_loc, expr.value, idx); + c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE, "expected %<]%>"); + start = expr.get_start (); finish = parser->tokens_buf[0].location; - expr.value = build_array_ref (op_loc, expr.value, idx); set_c_expr_source_range (&expr, start, finish); expr.original_code = ERROR_MARK; expr.original_type = NULL; @@ -12829,6 +12856,8 @@ c_parser_expr_list (c_parser *parser, bool convert_p, bool fold_p, vec<tree, va_gc> *orig_types; struct c_expr expr; unsigned int idx = 0; + bool save_c_omp_array_section_p = c_omp_array_section_p; + c_omp_array_section_p = false; ret = make_tree_vector (); if (p_orig_types == NULL) @@ -12882,6 +12911,7 @@ c_parser_expr_list (c_parser *parser, bool convert_p, bool fold_p, } if (orig_types) *p_orig_types = orig_types; + c_omp_array_section_p = save_c_omp_array_section_p; return ret; } @@ -15126,7 +15156,7 @@ static tree c_parser_omp_variable_list (c_parser *parser, location_t clause_loc, enum omp_clause_code kind, tree list, - bool allow_deref = false) + bool map_lvalue = false) { auto_vec<omp_dim> dims; bool array_section_p; @@ -15137,6 +15167,8 @@ c_parser_omp_variable_list (c_parser *parser, while (1) { + tree t = NULL_TREE; + if (kind == OMP_CLAUSE_DEPEND || kind == OMP_CLAUSE_AFFINITY) { if (c_parser_next_token_is_not (parser, CPP_NAME) @@ -15217,8 +15249,96 @@ c_parser_omp_variable_list (c_parser *parser, parser->tokens = tokens.address (); parser->tokens_avail = tokens.length (); } + else if (map_lvalue + && (kind == OMP_CLAUSE_MAP + || kind == OMP_CLAUSE_TO + || kind == OMP_CLAUSE_FROM)) + { + location_t loc = c_parser_peek_token (parser)->location; + bool save_c_omp_array_section_p = c_omp_array_section_p; + c_omp_array_section_p = true; + c_expr expr = c_parser_expr_no_commas (parser, NULL); + if (expr.value != error_mark_node) + mark_exp_read (expr.value); + c_omp_array_section_p = save_c_omp_array_section_p; + tree decl = expr.value; + + /* This code rewrites a parsed expression containing various tree + codes used to represent array accesses into a more uniform nest of + OMP_ARRAY_SECTION nodes before it is processed by + c-typeck.cc:handle_omp_array_sections_1. It might be more + efficient to move this logic to that function instead, analysing + the parsed expression directly rather than this preprocessed + form. (See also equivalent code in cp/parser.cc, + cp/semantics.cc). */ + dims.truncate (0); + if (TREE_CODE (decl) == OMP_ARRAY_SECTION) + { + while (TREE_CODE (decl) == OMP_ARRAY_SECTION) + { + tree low_bound = TREE_OPERAND (decl, 1); + tree length = TREE_OPERAND (decl, 2); + dims.safe_push (omp_dim (low_bound, length, loc, false)); + decl = TREE_OPERAND (decl, 0); + } - tree t = NULL_TREE; + while (TREE_CODE (decl) == ARRAY_REF + || TREE_CODE (decl) == INDIRECT_REF + || TREE_CODE (decl) == COMPOUND_EXPR) + { + if (TREE_CODE (decl) == COMPOUND_EXPR) + { + decl = TREE_OPERAND (decl, 1); + STRIP_NOPS (decl); + } + else if (TREE_CODE (decl) == INDIRECT_REF) + { + dims.safe_push (omp_dim (integer_zero_node, + integer_one_node, loc, true)); + decl = TREE_OPERAND (decl, 0); + } + else /* ARRAY_REF. */ + { + tree index = TREE_OPERAND (decl, 1); + dims.safe_push (omp_dim (index, integer_one_node, loc, + true)); + decl = TREE_OPERAND (decl, 0); + } + } + + for (int i = dims.length () - 1; i >= 0; i--) + decl = build_omp_array_section (loc, decl, dims[i].low_bound, + dims[i].length); + } + else if (TREE_CODE (decl) == INDIRECT_REF) + { + /* Turn indirection of a pointer "*foo" into "foo[0:1]". */ + decl = TREE_OPERAND (decl, 0); + STRIP_NOPS (decl); + + decl = build_omp_array_section (loc, decl, integer_zero_node, + integer_one_node); + } + else if (TREE_CODE (decl) == ARRAY_REF) + { + tree idx = TREE_OPERAND (decl, 1); + + decl = TREE_OPERAND (decl, 0); + STRIP_NOPS (decl); + + decl = build_omp_array_section (loc, decl, idx, integer_one_node); + } + else if (TREE_CODE (decl) == NON_LVALUE_EXPR + || CONVERT_EXPR_P (decl)) + decl = TREE_OPERAND (decl, 0); + + tree u = build_omp_clause (clause_loc, kind); + OMP_CLAUSE_DECL (u) = decl; + OMP_CLAUSE_CHAIN (u) = list; + list = u; + + goto next_item; + } if (c_parser_next_token_is (parser, CPP_NAME) && c_parser_peek_token (parser)->id_kind == C_ID_ID) @@ -15269,8 +15389,7 @@ c_parser_omp_variable_list (c_parser *parser, case OMP_CLAUSE_TO: start_component_ref: while (c_parser_next_token_is (parser, CPP_DOT) - || (allow_deref - && c_parser_next_token_is (parser, CPP_DEREF))) + || c_parser_next_token_is (parser, CPP_DEREF)) { location_t op_loc = c_parser_peek_token (parser)->location; location_t arrow_loc = UNKNOWN_LOCATION; @@ -15371,9 +15490,7 @@ c_parser_omp_variable_list (c_parser *parser, || kind == OMP_CLAUSE_TO) && !array_section_p && (c_parser_next_token_is (parser, CPP_DOT) - || (allow_deref - && c_parser_next_token_is (parser, - CPP_DEREF)))) + || c_parser_next_token_is (parser, CPP_DEREF))) { for (unsigned i = 0; i < dims.length (); i++) { @@ -15385,7 +15502,9 @@ c_parser_omp_variable_list (c_parser *parser, } else for (unsigned i = 0; i < dims.length (); i++) - t = tree_cons (dims[i].low_bound, dims[i].length, t); + t = build_omp_array_section (clause_loc, t, + dims[i].low_bound, + dims[i].length); } if ((kind == OMP_CLAUSE_DEPEND || kind == OMP_CLAUSE_AFFINITY) @@ -15433,6 +15552,8 @@ c_parser_omp_variable_list (c_parser *parser, parser->tokens = saved_tokens; parser->tokens_avail = tokens_avail; } + + next_item: if (c_parser_next_token_is_not (parser, CPP_COMMA)) break; @@ -15449,7 +15570,7 @@ c_parser_omp_variable_list (c_parser *parser, static tree c_parser_omp_var_list_parens (c_parser *parser, enum omp_clause_code kind, - tree list, bool allow_deref = false) + tree list, bool map_lvalue = false) { /* The clauses location. */ location_t loc = c_parser_peek_token (parser)->location; @@ -15470,7 +15591,7 @@ c_parser_omp_var_list_parens (c_parser *parser, enum omp_clause_code kind, matching_parens parens; if (parens.require_open (parser)) { - list = c_parser_omp_variable_list (parser, loc, kind, list, allow_deref); + list = c_parser_omp_variable_list (parser, loc, kind, list, map_lvalue); parens.skip_until_found_close (parser); } return list; @@ -15541,7 +15662,7 @@ c_parser_oacc_data_clause (c_parser *parser, pragma_omp_clause c_kind, gcc_unreachable (); } tree nl, c; - nl = c_parser_omp_var_list_parens (parser, OMP_CLAUSE_MAP, list, true); + nl = c_parser_omp_var_list_parens (parser, OMP_CLAUSE_MAP, list, false); for (c = nl; c != list; c = OMP_CLAUSE_CHAIN (c)) OMP_CLAUSE_SET_MAP_KIND (c, kind); @@ -17221,13 +17342,15 @@ c_parser_omp_clause_reduction (c_parser *parser, enum omp_clause_code kind, for (c = nl; c != list; c = OMP_CLAUSE_CHAIN (c)) { tree d = OMP_CLAUSE_DECL (c), type; - if (TREE_CODE (d) != TREE_LIST) + if (TREE_CODE (d) != OMP_ARRAY_SECTION) type = TREE_TYPE (d); else { int cnt = 0; tree t; - for (t = d; TREE_CODE (t) == TREE_LIST; t = TREE_CHAIN (t)) + for (t = d; + TREE_CODE (t) == OMP_ARRAY_SECTION; + t = TREE_OPERAND (t, 0)) cnt++; type = TREE_TYPE (t); while (cnt > 0) diff --git a/gcc/c/c-tree.h b/gcc/c/c-tree.h index 1823151..cf29534 100644 --- a/gcc/c/c-tree.h +++ b/gcc/c/c-tree.h @@ -737,6 +737,7 @@ extern int in_alignof; extern int in_sizeof; extern int in_typeof; extern bool c_in_omp_for; +extern bool c_omp_array_section_p; extern tree c_last_sizeof_arg; extern location_t c_last_sizeof_loc; @@ -777,6 +778,7 @@ extern tree composite_type (tree, tree); extern tree build_component_ref (location_t, tree, tree, location_t, location_t); extern tree build_array_ref (location_t, tree, tree); +extern tree build_omp_array_section (location_t, tree, tree, tree); extern tree build_external_ref (location_t, tree, bool, tree *); extern void pop_maybe_used (bool); extern struct c_expr c_expr_sizeof_expr (location_t, struct c_expr); diff --git a/gcc/c/c-typeck.cc b/gcc/c/c-typeck.cc index 2b90fa7..66c6abc 100644 --- a/gcc/c/c-typeck.cc +++ b/gcc/c/c-typeck.cc @@ -76,6 +76,9 @@ int in_typeof; /* True when parsing OpenMP loop expressions. */ bool c_in_omp_for; +/* True when parsing OpenMP map clause. */ +bool c_omp_array_section_p; + /* The argument of last parsed sizeof expression, only to be tested if expr.original_code == SIZEOF_EXPR. */ tree c_last_sizeof_arg; @@ -1987,6 +1990,13 @@ mark_exp_read (tree exp) case C_MAYBE_CONST_EXPR: mark_exp_read (TREE_OPERAND (exp, 1)); break; + case OMP_ARRAY_SECTION: + mark_exp_read (TREE_OPERAND (exp, 0)); + if (TREE_OPERAND (exp, 1)) + mark_exp_read (TREE_OPERAND (exp, 1)); + if (TREE_OPERAND (exp, 2)) + mark_exp_read (TREE_OPERAND (exp, 2)); + break; default: break; } @@ -2858,6 +2868,10 @@ build_array_ref (location_t loc, tree array, tree index) "array"); } + if (TREE_CODE (TREE_TYPE (index)) == BITINT_TYPE + && TYPE_PRECISION (TREE_TYPE (index)) > TYPE_PRECISION (sizetype)) + index = fold_convert (sizetype, index); + type = TREE_TYPE (TREE_TYPE (array)); rval = build4 (ARRAY_REF, type, array, index, NULL_TREE, NULL_TREE); /* Array ref is const/volatile if the array elements are @@ -2899,6 +2913,53 @@ build_array_ref (location_t loc, tree array, tree index) return ret; } } + +/* Build an OpenMP array section reference, creating an exact type for the + resulting expression based on the element type and bounds if possible. If + we have variable bounds, create an incomplete array type for the result + instead. */ + +tree +build_omp_array_section (location_t loc, tree array, tree index, tree length) +{ + tree type = TREE_TYPE (array); + gcc_assert (type); + + tree sectype, eltype = TREE_TYPE (type); + + /* It's not an array or pointer type. Just reuse the type of the original + expression as the type of the array section (an error will be raised + anyway, later). */ + if (eltype == NULL_TREE || error_operand_p (eltype)) + sectype = TREE_TYPE (array); + else + { + tree idxtype = NULL_TREE; + + if (index != NULL_TREE + && length != NULL_TREE + && INTEGRAL_TYPE_P (TREE_TYPE (index)) + && INTEGRAL_TYPE_P (TREE_TYPE (length))) + { + tree low = fold_convert (sizetype, index); + tree high = fold_convert (sizetype, length); + high = size_binop (PLUS_EXPR, low, high); + high = size_binop (MINUS_EXPR, high, size_one_node); + idxtype = build_range_type (sizetype, low, high); + } + else if ((index == NULL_TREE || integer_zerop (index)) + && length != NULL_TREE + && INTEGRAL_TYPE_P (TREE_TYPE (length))) + idxtype = build_index_type (length); + + gcc_assert (!error_operand_p (idxtype)); + + sectype = build_array_type (eltype, idxtype); + } + + return build3_loc (loc, OMP_ARRAY_SECTION, sectype, array, index, length); +} + /* Build an external reference to identifier ID. FUN indicates whether this will be used for a function call. LOC is the source @@ -2938,7 +2999,11 @@ build_external_ref (location_t loc, tree id, bool fun, tree *type) return error_mark_node; } - if (TREE_TYPE (ref) == error_mark_node) + /* For an OpenMP map clause, we can get better diagnostics for decls with + unmappable types if we return the decl with an error_mark_node type, + rather than returning error_mark_node for the decl itself. */ + if (TREE_TYPE (ref) == error_mark_node + && !c_omp_array_section_p) return error_mark_node; if (TREE_UNAVAILABLE (ref)) @@ -13762,7 +13827,7 @@ handle_omp_array_sections_1 (tree c, tree t, vec<tree> &types, { tree ret, low_bound, length, type; bool openacc = (ort & C_ORT_ACC) != 0; - if (TREE_CODE (t) != TREE_LIST) + if (TREE_CODE (t) != OMP_ARRAY_SECTION) { if (error_operand_p (t)) return error_mark_node; @@ -13787,7 +13852,9 @@ handle_omp_array_sections_1 (tree c, tree t, vec<tree> &types, t = ai.unconverted_ref_origin (); if (t == error_mark_node) return error_mark_node; - if (!VAR_P (t) && TREE_CODE (t) != PARM_DECL) + if (!VAR_P (t) + && (ort == C_ORT_ACC || !EXPR_P (t)) + && TREE_CODE (t) != PARM_DECL) { if (DECL_P (t)) error_at (OMP_CLAUSE_LOCATION (c), @@ -13835,14 +13902,14 @@ handle_omp_array_sections_1 (tree c, tree t, vec<tree> &types, return ret; } - ret = handle_omp_array_sections_1 (c, TREE_CHAIN (t), types, + ret = handle_omp_array_sections_1 (c, TREE_OPERAND (t, 0), types, maybe_zero_len, first_non_one, ort); if (ret == error_mark_node || ret == NULL_TREE) return ret; type = TREE_TYPE (ret); - low_bound = TREE_PURPOSE (t); - length = TREE_VALUE (t); + low_bound = TREE_OPERAND (t, 1); + length = TREE_OPERAND (t, 2); if (low_bound == error_mark_node || length == error_mark_node) return error_mark_node; @@ -14035,7 +14102,7 @@ handle_omp_array_sections_1 (tree c, tree t, vec<tree> &types, tree lb = save_expr (low_bound); if (lb != low_bound) { - TREE_PURPOSE (t) = lb; + TREE_OPERAND (t, 1) = lb; low_bound = lb; } } @@ -14066,14 +14133,15 @@ handle_omp_array_sections_1 (tree c, tree t, vec<tree> &types, array-section-subscript, the array section could be non-contiguous. */ if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_DEPEND && OMP_CLAUSE_CODE (c) != OMP_CLAUSE_AFFINITY - && TREE_CODE (TREE_CHAIN (t)) == TREE_LIST) + && TREE_CODE (TREE_OPERAND (t, 0)) == OMP_ARRAY_SECTION) { /* If any prior dimension has a non-one length, then deem this array section as non-contiguous. */ - for (tree d = TREE_CHAIN (t); TREE_CODE (d) == TREE_LIST; - d = TREE_CHAIN (d)) + for (tree d = TREE_OPERAND (t, 0); + TREE_CODE (d) == OMP_ARRAY_SECTION; + d = TREE_OPERAND (d, 0)) { - tree d_length = TREE_VALUE (d); + tree d_length = TREE_OPERAND (d, 2); if (d_length == NULL_TREE || !integer_onep (d_length)) { error_at (OMP_CLAUSE_LOCATION (c), @@ -14096,7 +14164,7 @@ handle_omp_array_sections_1 (tree c, tree t, vec<tree> &types, tree lb = save_expr (low_bound); if (lb != low_bound) { - TREE_PURPOSE (t) = lb; + TREE_OPERAND (t, 1) = lb; low_bound = lb; } ret = build_array_ref (OMP_CLAUSE_LOCATION (c), ret, low_bound); @@ -14159,10 +14227,10 @@ handle_omp_array_sections (tree &c, enum c_omp_region_type ort) maybe_zero_len = true; for (i = num, t = OMP_CLAUSE_DECL (c); i > 0; - t = TREE_CHAIN (t)) + t = TREE_OPERAND (t, 0)) { - tree low_bound = TREE_PURPOSE (t); - tree length = TREE_VALUE (t); + tree low_bound = TREE_OPERAND (t, 1); + tree length = TREE_OPERAND (t, 2); i--; if (low_bound @@ -14587,8 +14655,8 @@ c_oacc_check_attachments (tree c) { tree t = OMP_CLAUSE_DECL (c); - while (TREE_CODE (t) == TREE_LIST) - t = TREE_CHAIN (t); + while (TREE_CODE (t) == OMP_ARRAY_SECTION) + t = TREE_OPERAND (t, 0); if (TREE_CODE (TREE_TYPE (t)) != POINTER_TYPE) { @@ -14696,7 +14764,7 @@ c_finish_omp_clauses (tree clauses, enum c_omp_region_type ort) case OMP_CLAUSE_TASK_REDUCTION: need_implicitly_determined = true; t = OMP_CLAUSE_DECL (c); - if (TREE_CODE (t) == TREE_LIST) + if (TREE_CODE (t) == OMP_ARRAY_SECTION) { if (handle_omp_array_sections (c, ort)) { @@ -15317,7 +15385,7 @@ c_finish_omp_clauses (tree clauses, enum c_omp_region_type ort) } else last_iterators = NULL_TREE; - if (TREE_CODE (t) == TREE_LIST) + if (TREE_CODE (t) == OMP_ARRAY_SECTION) { if (handle_omp_array_sections (c, ort)) remove = true; @@ -15427,7 +15495,7 @@ c_finish_omp_clauses (tree clauses, enum c_omp_region_type ort) auto_vec<omp_addr_token *, 10> addr_tokens; t = OMP_CLAUSE_DECL (c); - if (TREE_CODE (t) == TREE_LIST) + if (TREE_CODE (t) == OMP_ARRAY_SECTION) { grp_start_p = pc; grp_sentinel = OMP_CLAUSE_CHAIN (c); @@ -15597,6 +15665,9 @@ c_finish_omp_clauses (tree clauses, enum c_omp_region_type ort) if (!VAR_P (t) && TREE_CODE (t) != PARM_DECL) { + if (ort != C_ORT_ACC && EXPR_P (t)) + break; + error_at (OMP_CLAUSE_LOCATION (c), "%qE is not a variable in %qs clause", t, omp_clause_code_name[OMP_CLAUSE_CODE (c)]); @@ -15827,7 +15898,7 @@ c_finish_omp_clauses (tree clauses, enum c_omp_region_type ort) case OMP_CLAUSE_HAS_DEVICE_ADDR: t = OMP_CLAUSE_DECL (c); - if (TREE_CODE (t) == TREE_LIST) + if (TREE_CODE (t) == OMP_ARRAY_SECTION) { if (handle_omp_array_sections (c, ort)) remove = true; diff --git a/gcc/cfgexpand.cc b/gcc/cfgexpand.cc index 1db22f0..9ce0118 100644 --- a/gcc/cfgexpand.cc +++ b/gcc/cfgexpand.cc @@ -571,6 +571,26 @@ visit_conflict (gimple *, tree op, tree, void *data) return false; } +/* Helper function for add_scope_conflicts_1. For USE on + a stmt, if it is a SSA_NAME and in its SSA_NAME_DEF_STMT is known to be + based on some ADDR_EXPR, invoke VISIT on that ADDR_EXPR. */ + +static inline void +add_scope_conflicts_2 (tree use, bitmap work, + walk_stmt_load_store_addr_fn visit) +{ + if (TREE_CODE (use) == SSA_NAME + && (POINTER_TYPE_P (TREE_TYPE (use)) + || INTEGRAL_TYPE_P (TREE_TYPE (use)))) + { + gimple *g = SSA_NAME_DEF_STMT (use); + if (is_gimple_assign (g)) + if (tree op = gimple_assign_rhs1 (g)) + if (TREE_CODE (op) == ADDR_EXPR) + visit (g, TREE_OPERAND (op, 0), op, work); + } +} + /* Helper routine for add_scope_conflicts, calculating the active partitions at the end of BB, leaving the result in WORK. We're called to generate conflicts when FOR_CONFLICT is true, otherwise we're just tracking @@ -583,6 +603,8 @@ add_scope_conflicts_1 (basic_block bb, bitmap work, bool for_conflict) edge_iterator ei; gimple_stmt_iterator gsi; walk_stmt_load_store_addr_fn visit; + use_operand_p use_p; + ssa_op_iter iter; bitmap_clear (work); FOR_EACH_EDGE (e, ei, bb->preds) @@ -593,7 +615,10 @@ add_scope_conflicts_1 (basic_block bb, bitmap work, bool for_conflict) for (gsi = gsi_start_phis (bb); !gsi_end_p (gsi); gsi_next (&gsi)) { gimple *stmt = gsi_stmt (gsi); + gphi *phi = as_a <gphi *> (stmt); walk_stmt_load_store_addr_ops (stmt, work, NULL, NULL, visit); + FOR_EACH_PHI_ARG (use_p, phi, iter, SSA_OP_USE) + add_scope_conflicts_2 (USE_FROM_PTR (use_p), work, visit); } for (gsi = gsi_after_labels (bb); !gsi_end_p (gsi); gsi_next (&gsi)) { @@ -613,8 +638,7 @@ add_scope_conflicts_1 (basic_block bb, bitmap work, bool for_conflict) } else if (!is_gimple_debug (stmt)) { - if (for_conflict - && visit == visit_op) + if (for_conflict && visit == visit_op) { /* If this is the first real instruction in this BB we need to add conflicts for everything live at this point now. @@ -634,6 +658,8 @@ add_scope_conflicts_1 (basic_block bb, bitmap work, bool for_conflict) visit = visit_conflict; } walk_stmt_load_store_addr_ops (stmt, work, visit, visit, visit); + FOR_EACH_SSA_USE_OPERAND (use_p, stmt, iter, SSA_OP_USE) + add_scope_conflicts_2 (USE_FROM_PTR (use_p), work, visit); } } } diff --git a/gcc/config.gcc b/gcc/config.gcc index d17787b..0035550 100644 --- a/gcc/config.gcc +++ b/gcc/config.gcc @@ -549,7 +549,7 @@ riscv*) extra_objs="${extra_objs} riscv-vector-builtins.o riscv-vector-builtins-shapes.o riscv-vector-builtins-bases.o" extra_objs="${extra_objs} thead.o riscv-target-attr.o" d_target_objs="riscv-d.o" - extra_headers="riscv_vector.h" + extra_headers="riscv_vector.h riscv_crypto.h riscv_bitmanip.h" target_gtfiles="$target_gtfiles \$(srcdir)/config/riscv/riscv-vector-builtins.cc" target_gtfiles="$target_gtfiles \$(srcdir)/config/riscv/riscv-vector-builtins.h" ;; diff --git a/gcc/config.in b/gcc/config.in index b499bbf..99fd2d8 100644 --- a/gcc/config.in +++ b/gcc/config.in @@ -1679,6 +1679,12 @@ #endif +/* Define if your linker supports emulation avrxmega2_flmap. */ +#ifndef USED_FOR_TARGET +#undef HAVE_LD_AVR_AVRXMEGA2_FLMAP +#endif + + /* Define if your default avr linker script for avrxmega3 leaves .rodata in flash. */ #ifndef USED_FOR_TARGET @@ -1686,6 +1692,12 @@ #endif +/* Define if your linker supports emulation avrxmega4_flmap. */ +#ifndef USED_FOR_TARGET +#undef HAVE_LD_AVR_AVRXMEGA4_FLMAP +#endif + + /* Define if your linker supports -z bndplt */ #ifndef USED_FOR_TARGET #undef HAVE_LD_BNDPLT_SUPPORT diff --git a/gcc/config/aarch64/aarch64-ldp-fusion.cc b/gcc/config/aarch64/aarch64-ldp-fusion.cc index 2fe1b1d..689a8c8 100644 --- a/gcc/config/aarch64/aarch64-ldp-fusion.cc +++ b/gcc/config/aarch64/aarch64-ldp-fusion.cc @@ -904,9 +904,11 @@ aarch64_operand_mode_for_pair_mode (machine_mode mode) // Go through the reg notes rooted at NOTE, dropping those that we should drop, // and preserving those that we want to keep by prepending them to (and // returning) RESULT. EH_REGION is used to make sure we have at most one -// REG_EH_REGION note in the resulting list. +// REG_EH_REGION note in the resulting list. FR_EXPR is used to return any +// REG_FRAME_RELATED_EXPR note we find, as these can need special handling in +// combine_reg_notes. static rtx -filter_notes (rtx note, rtx result, bool *eh_region) +filter_notes (rtx note, rtx result, bool *eh_region, rtx *fr_expr) { for (; note; note = XEXP (note, 1)) { @@ -940,6 +942,10 @@ filter_notes (rtx note, rtx result, bool *eh_region) copy_rtx (XEXP (note, 0)), result); break; + case REG_FRAME_RELATED_EXPR: + gcc_assert (!*fr_expr); + *fr_expr = copy_rtx (XEXP (note, 0)); + break; default: // Unexpected REG_NOTE kind. gcc_unreachable (); @@ -950,14 +956,49 @@ filter_notes (rtx note, rtx result, bool *eh_region) } // Return the notes that should be attached to a combination of I1 and I2, where -// *I1 < *I2. +// *I1 < *I2. LOAD_P is true for loads. static rtx -combine_reg_notes (insn_info *i1, insn_info *i2) +combine_reg_notes (insn_info *i1, insn_info *i2, bool load_p) { + // Temporary storage for REG_FRAME_RELATED_EXPR notes. + rtx fr_expr[2] = {}; + bool found_eh_region = false; rtx result = NULL_RTX; - result = filter_notes (REG_NOTES (i2->rtl ()), result, &found_eh_region); - return filter_notes (REG_NOTES (i1->rtl ()), result, &found_eh_region); + result = filter_notes (REG_NOTES (i2->rtl ()), result, + &found_eh_region, fr_expr); + result = filter_notes (REG_NOTES (i1->rtl ()), result, + &found_eh_region, fr_expr + 1); + + if (!load_p) + { + // Simple frame-related sp-relative saves don't need CFI notes, but when + // we combine them into an stp we will need a CFI note as dwarf2cfi can't + // interpret the unspec pair representation directly. + if (RTX_FRAME_RELATED_P (i1->rtl ()) && !fr_expr[0]) + fr_expr[0] = copy_rtx (PATTERN (i1->rtl ())); + if (RTX_FRAME_RELATED_P (i2->rtl ()) && !fr_expr[1]) + fr_expr[1] = copy_rtx (PATTERN (i2->rtl ())); + } + + rtx fr_pat = NULL_RTX; + if (fr_expr[0] && fr_expr[1]) + { + // Combining two frame-related insns, need to construct + // a REG_FRAME_RELATED_EXPR note which represents the combined + // operation. + RTX_FRAME_RELATED_P (fr_expr[1]) = 1; + fr_pat = gen_rtx_PARALLEL (VOIDmode, + gen_rtvec (2, fr_expr[0], fr_expr[1])); + } + else + fr_pat = fr_expr[0] ? fr_expr[0] : fr_expr[1]; + + if (fr_pat) + result = alloc_reg_note (REG_FRAME_RELATED_EXPR, + fr_pat, result); + + return result; } // Given two memory accesses in PATS, at least one of which is of a @@ -1049,6 +1090,14 @@ find_trailing_add (insn_info *insns[2], poly_int64 initial_offset, unsigned access_size) { + // Punt on frame-related insns, it is better to be conservative and + // not try to form writeback pairs here, and means we don't have to + // worry about the writeback case in forming REG_FRAME_RELATED_EXPR + // notes (see combine_reg_notes). + if ((insns[0] && RTX_FRAME_RELATED_P (insns[0]->rtl ())) + || RTX_FRAME_RELATED_P (insns[1]->rtl ())) + return nullptr; + insn_info *pair_dst = pair_range.singleton (); gcc_assert (pair_dst); @@ -1380,7 +1429,7 @@ ldp_bb_info::fuse_pair (bool load_p, return false; } - rtx reg_notes = combine_reg_notes (first, second); + rtx reg_notes = combine_reg_notes (first, second, load_p); rtx pair_pat; if (writeback_effect) @@ -1987,6 +2036,19 @@ ldp_bb_info::try_fuse_pair (bool load_p, unsigned access_size, return false; } + // Punt on frame-related insns with writeback. We probably won't see + // these in practice, but this is conservative and ensures we don't + // have to worry about these later on. + if (writeback && (RTX_FRAME_RELATED_P (i1->rtl ()) + || RTX_FRAME_RELATED_P (i2->rtl ()))) + { + if (dump_file) + fprintf (dump_file, + "rejecting pair (%d,%d): frame-related insn with writeback\n", + i1->uid (), i2->uid ()); + return false; + } + rtx *ignore = &XEXP (pats[1], load_p); for (auto use : insns[1]->uses ()) if (!use->is_mem () diff --git a/gcc/config/aarch64/aarch64-protos.h b/gcc/config/aarch64/aarch64-protos.h index ce9bec7..4c70e8a 100644 --- a/gcc/config/aarch64/aarch64-protos.h +++ b/gcc/config/aarch64/aarch64-protos.h @@ -880,6 +880,7 @@ rtx aarch64_return_addr_rtx (void); rtx aarch64_return_addr (int, rtx); rtx aarch64_simd_gen_const_vector_dup (machine_mode, HOST_WIDE_INT); rtx aarch64_gen_shareable_zero (machine_mode); +bool aarch64_split_simd_shift_p (rtx_insn *); bool aarch64_simd_mem_operand_p (rtx); bool aarch64_sve_ld1r_operand_p (rtx); bool aarch64_sve_ld1rq_operand_p (rtx); diff --git a/gcc/config/aarch64/aarch64-simd.md b/gcc/config/aarch64/aarch64-simd.md index 3cd184f..6f48b4d 100644 --- a/gcc/config/aarch64/aarch64-simd.md +++ b/gcc/config/aarch64/aarch64-simd.md @@ -1958,7 +1958,7 @@ [(set_attr "type" "neon_shift_imm_long")] ) -(define_insn "aarch64_simd_vec_unpack<su>_hi_<mode>" +(define_insn_and_split "aarch64_simd_vec_unpack<su>_hi_<mode>" [(set (match_operand:<VWIDE> 0 "register_operand" "=w") (ANY_EXTEND:<VWIDE> (vec_select:<VHALF> (match_operand:VQW 1 "register_operand" "w") @@ -1966,63 +1966,42 @@ )))] "TARGET_SIMD" "<su>xtl2\t%0.<Vwtype>, %1.<Vtype>" - [(set_attr "type" "neon_shift_imm_long")] -) - -(define_expand "vec_unpacku_hi_<mode>" - [(match_operand:<VWIDE> 0 "register_operand") - (match_operand:VQW 1 "register_operand")] - "TARGET_SIMD" + "&& <CODE> == ZERO_EXTEND + && aarch64_split_simd_shift_p (insn)" + [(const_int 0)] { - rtx res = gen_reg_rtx (<MODE>mode); - rtx tmp = aarch64_gen_shareable_zero (<MODE>mode); - if (BYTES_BIG_ENDIAN) - emit_insn (gen_aarch64_zip2<mode> (res, tmp, operands[1])); - else - emit_insn (gen_aarch64_zip2<mode> (res, operands[1], tmp)); - emit_move_insn (operands[0], - simplify_gen_subreg (<VWIDE>mode, res, <MODE>mode, 0)); + /* On many cores, it is cheaper to implement UXTL2 using a ZIP2 with zero, + provided that the cost of the zero can be amortized over several + operations. We'll later recombine the zero and zip if there are + not sufficient uses of the zero to make the split worthwhile. */ + rtx res = simplify_gen_subreg (<MODE>mode, operands[0], <VWIDE>mode, 0); + rtx zero = aarch64_gen_shareable_zero (<MODE>mode); + emit_insn (gen_aarch64_zip2<mode> (res, operands[1], zero)); DONE; } + [(set_attr "type" "neon_shift_imm_long")] ) -(define_expand "vec_unpacks_hi_<mode>" +(define_expand "vec_unpack<su>_hi_<mode>" [(match_operand:<VWIDE> 0 "register_operand") - (match_operand:VQW 1 "register_operand")] + (ANY_EXTEND:<VWIDE> (match_operand:VQW 1 "register_operand"))] "TARGET_SIMD" { rtx p = aarch64_simd_vect_par_cnst_half (<MODE>mode, <nunits>, true); - emit_insn (gen_aarch64_simd_vec_unpacks_hi_<mode> (operands[0], - operands[1], p)); + emit_insn (gen_aarch64_simd_vec_unpack<su>_hi_<mode> (operands[0], + operands[1], p)); DONE; } ) -(define_expand "vec_unpacku_lo_<mode>" +(define_expand "vec_unpack<su>_lo_<mode>" [(match_operand:<VWIDE> 0 "register_operand") - (match_operand:VQW 1 "register_operand")] - "TARGET_SIMD" - { - rtx res = gen_reg_rtx (<MODE>mode); - rtx tmp = aarch64_gen_shareable_zero (<MODE>mode); - if (BYTES_BIG_ENDIAN) - emit_insn (gen_aarch64_zip1<mode> (res, tmp, operands[1])); - else - emit_insn (gen_aarch64_zip1<mode> (res, operands[1], tmp)); - emit_move_insn (operands[0], - simplify_gen_subreg (<VWIDE>mode, res, <MODE>mode, 0)); - DONE; - } -) - -(define_expand "vec_unpacks_lo_<mode>" - [(match_operand:<VWIDE> 0 "register_operand") - (match_operand:VQW 1 "register_operand")] + (ANY_EXTEND:<VWIDE> (match_operand:VQW 1 "register_operand"))] "TARGET_SIMD" { rtx p = aarch64_simd_vect_par_cnst_half (<MODE>mode, <nunits>, false); - emit_insn (gen_aarch64_simd_vec_unpacks_lo_<mode> (operands[0], - operands[1], p)); + emit_insn (gen_aarch64_simd_vec_unpack<su>_lo_<mode> (operands[0], + operands[1], p)); DONE; } ) @@ -4792,62 +4771,6 @@ [(set_attr "type" "neon_sub_widen")] ) -(define_insn "aarch64_usubw<mode>_lo_zip" - [(set (match_operand:<VWIDE> 0 "register_operand" "=w") - (minus:<VWIDE> - (match_operand:<VWIDE> 1 "register_operand" "w") - (subreg:<VWIDE> - (unspec:<MODE> [ - (match_operand:VQW 2 "register_operand" "w") - (match_operand:VQW 3 "aarch64_simd_imm_zero") - ] UNSPEC_ZIP1) 0)))] - "TARGET_SIMD" - "usubw\\t%0.<Vwtype>, %1.<Vwtype>, %2.<Vhalftype>" - [(set_attr "type" "neon_sub_widen")] -) - -(define_insn "aarch64_uaddw<mode>_lo_zip" - [(set (match_operand:<VWIDE> 0 "register_operand" "=w") - (plus:<VWIDE> - (subreg:<VWIDE> - (unspec:<MODE> [ - (match_operand:VQW 2 "register_operand" "w") - (match_operand:VQW 3 "aarch64_simd_imm_zero") - ] UNSPEC_ZIP1) 0) - (match_operand:<VWIDE> 1 "register_operand" "w")))] - "TARGET_SIMD" - "uaddw\\t%0.<Vwtype>, %1.<Vwtype>, %2.<Vhalftype>" - [(set_attr "type" "neon_add_widen")] -) - -(define_insn "aarch64_usubw<mode>_hi_zip" - [(set (match_operand:<VWIDE> 0 "register_operand" "=w") - (minus:<VWIDE> - (match_operand:<VWIDE> 1 "register_operand" "w") - (subreg:<VWIDE> - (unspec:<MODE> [ - (match_operand:VQW 2 "register_operand" "w") - (match_operand:VQW 3 "aarch64_simd_imm_zero") - ] UNSPEC_ZIP2) 0)))] - "TARGET_SIMD" - "usubw2\\t%0.<Vwtype>, %1.<Vwtype>, %2.<Vtype>" - [(set_attr "type" "neon_sub_widen")] -) - -(define_insn "aarch64_uaddw<mode>_hi_zip" - [(set (match_operand:<VWIDE> 0 "register_operand" "=w") - (plus:<VWIDE> - (subreg:<VWIDE> - (unspec:<MODE> [ - (match_operand:VQW 2 "register_operand" "w") - (match_operand:VQW 3 "aarch64_simd_imm_zero") - ] UNSPEC_ZIP2) 0) - (match_operand:<VWIDE> 1 "register_operand" "w")))] - "TARGET_SIMD" - "uaddw2\\t%0.<Vwtype>, %1.<Vwtype>, %2.<Vtype>" - [(set_attr "type" "neon_add_widen")] -) - (define_insn "aarch64_<ANY_EXTEND:su>addw<mode>" [(set (match_operand:<VWIDE> 0 "register_operand" "=w") (plus:<VWIDE> @@ -9788,11 +9711,26 @@ ) ;; Sign- or zero-extend a 64-bit integer vector to a 128-bit vector. -(define_insn "<optab><Vnarrowq><mode>2" +(define_insn_and_split "<optab><Vnarrowq><mode>2" [(set (match_operand:VQN 0 "register_operand" "=w") (ANY_EXTEND:VQN (match_operand:<VNARROWQ> 1 "register_operand" "w")))] "TARGET_SIMD" "<su>xtl\t%0.<Vtype>, %1.<Vntype>" + "&& <CODE> == ZERO_EXTEND + && aarch64_split_simd_shift_p (insn)" + [(const_int 0)] + { + /* On many cores, it is cheaper to implement UXTL using a ZIP1 with zero, + provided that the cost of the zero can be amortized over several + operations. We'll later recombine the zero and zip if there are + not sufficient uses of the zero to make the split worthwhile. */ + rtx res = simplify_gen_subreg (<VNARROWQ2>mode, operands[0], + <MODE>mode, 0); + rtx zero = aarch64_gen_shareable_zero (<VNARROWQ2>mode); + rtx op = lowpart_subreg (<VNARROWQ2>mode, operands[1], <VNARROWQ>mode); + emit_insn (gen_aarch64_zip1<Vnarrowq2> (res, op, zero)); + DONE; + } [(set_attr "type" "neon_shift_imm_long")] ) diff --git a/gcc/config/aarch64/aarch64-sve-builtins-sme.def b/gcc/config/aarch64/aarch64-sve-builtins-sme.def index 5109c5e..416df0b 100644 --- a/gcc/config/aarch64/aarch64-sve-builtins-sme.def +++ b/gcc/config/aarch64/aarch64-sve-builtins-sme.def @@ -17,16 +17,31 @@ along with GCC; see the file COPYING3. If not see <http://www.gnu.org/licenses/>. */ +#ifndef DEF_SME_FUNCTION +#define DEF_SME_FUNCTION(NAME, SHAPE, TYPES, PREDS) \ + DEF_SME_FUNCTION_GS (NAME, SHAPE, TYPES, none, PREDS) +#endif + +#ifndef DEF_SME_ZA_FUNCTION_GS +#define DEF_SME_ZA_FUNCTION_GS(NAME, SHAPE, TYPES, GROUP, PREDS) \ + DEF_SME_FUNCTION_GS (NAME, SHAPE, TYPES, GROUP, PREDS) +#endif + +#ifndef DEF_SME_ZA_FUNCTION +#define DEF_SME_ZA_FUNCTION(NAME, SHAPE, TYPES, PREDS) \ + DEF_SME_ZA_FUNCTION_GS (NAME, SHAPE, TYPES, none, PREDS) +#endif + #define REQUIRED_EXTENSIONS 0 -DEF_SVE_FUNCTION (arm_has_sme, bool_inherent, none, none) -DEF_SVE_FUNCTION (arm_in_streaming_mode, bool_inherent, none, none) +DEF_SME_FUNCTION (arm_has_sme, bool_inherent, none, none) +DEF_SME_FUNCTION (arm_in_streaming_mode, bool_inherent, none, none) #undef REQUIRED_EXTENSIONS #define REQUIRED_EXTENSIONS AARCH64_FL_SME -DEF_SVE_FUNCTION (svcntsb, count_inherent, none, none) -DEF_SVE_FUNCTION (svcntsd, count_inherent, none, none) -DEF_SVE_FUNCTION (svcntsh, count_inherent, none, none) -DEF_SVE_FUNCTION (svcntsw, count_inherent, none, none) +DEF_SME_FUNCTION (svcntsb, count_inherent, none, none) +DEF_SME_FUNCTION (svcntsd, count_inherent, none, none) +DEF_SME_FUNCTION (svcntsh, count_inherent, none, none) +DEF_SME_FUNCTION (svcntsw, count_inherent, none, none) DEF_SME_ZA_FUNCTION (svldr, ldr_za, za, none) DEF_SME_ZA_FUNCTION (svstr, str_za, za, none) DEF_SME_ZA_FUNCTION (svundef, inherent_za, za, none) @@ -75,17 +90,17 @@ DEF_SME_ZA_FUNCTION (svmopa, binary_za_m, za_d_float, za_m) DEF_SME_ZA_FUNCTION (svmops, binary_za_m, za_d_float, za_m) #undef REQUIRED_EXTENSIONS -#define REQUIRED_EXTENSIONS AARCH64_FL_SME2 -DEF_SVE_FUNCTION (svldr_zt, ldr_zt, none, none) -DEF_SVE_FUNCTION (svstr_zt, str_zt, none, none) -DEF_SVE_FUNCTION (svzero_zt, inherent_zt, none, none) +#define REQUIRED_EXTENSIONS AARCH64_FL_SME | AARCH64_FL_SME2 +DEF_SME_FUNCTION (svldr_zt, ldr_zt, none, none) +DEF_SME_FUNCTION (svstr_zt, str_zt, none, none) +DEF_SME_FUNCTION (svzero_zt, inherent_zt, none, none) #undef REQUIRED_EXTENSIONS /* The d_za entries in this section just declare C _za64 overloads, which will then be resolved to either an integer function or a floating-point function. They are needed because the integer and floating-point functions have different architecture requirements. */ -#define REQUIRED_EXTENSIONS AARCH64_FL_SME2 | AARCH64_FL_SM_ON +#define REQUIRED_EXTENSIONS AARCH64_FL_SME | AARCH64_FL_SME2 | AARCH64_FL_SM_ON DEF_SME_ZA_FUNCTION_GS (svadd, unary_za_slice, za_s_data, vg1x24, none) DEF_SME_ZA_FUNCTION_GS (svadd, unary_za_slice, d_za, vg1x24, none) DEF_SME_ZA_FUNCTION_GS (svadd_write, binary_za_slice_opt_single, za_s_integer, @@ -100,9 +115,9 @@ DEF_SME_ZA_FUNCTION_GS (svdot_lane, dot_za_slice_lane, za_s_h_data, vg1x24, none) DEF_SME_ZA_FUNCTION_GS (svdot_lane, dot_za_slice_lane, za_s_b_integer, vg1x24, none) -DEF_SVE_FUNCTION_GS (svluti2_lane_zt, luti2_lane_zt, bhs_data, x124, none) -DEF_SVE_FUNCTION_GS (svluti4_lane_zt, luti4_lane_zt, bhs_data, x12, none) -DEF_SVE_FUNCTION_GS (svluti4_lane_zt, luti4_lane_zt, hs_data, x4, none) +DEF_SME_FUNCTION_GS (svluti2_lane_zt, luti2_lane_zt, bhs_data, x124, none) +DEF_SME_FUNCTION_GS (svluti4_lane_zt, luti4_lane_zt, bhs_data, x12, none) +DEF_SME_FUNCTION_GS (svluti4_lane_zt, luti4_lane_zt, hs_data, x4, none) DEF_SME_ZA_FUNCTION_GS (svmla, binary_za_slice_opt_single, za_s_float, vg1x24, none) DEF_SME_ZA_FUNCTION_GS (svmla, binary_za_slice_opt_single, za_s_h_data, @@ -157,7 +172,8 @@ DEF_SME_ZA_FUNCTION_GS (svwrite_hor, write_za, za_bhsd_data, vg24, none) DEF_SME_ZA_FUNCTION_GS (svwrite_ver, write_za, za_bhsd_data, vg24, none) #undef REQUIRED_EXTENSIONS -#define REQUIRED_EXTENSIONS (AARCH64_FL_SME2 \ +#define REQUIRED_EXTENSIONS (AARCH64_FL_SME \ + | AARCH64_FL_SME2 \ | AARCH64_FL_SME_I16I64 \ | AARCH64_FL_SM_ON) DEF_SME_ZA_FUNCTION_GS (svadd, unary_za_slice, za_d_integer, vg1x24, none) @@ -182,7 +198,8 @@ DEF_SME_ZA_FUNCTION_GS (svvdot_lane, dot_za_slice_lane, za_d_h_integer, vg1x4, none) #undef REQUIRED_EXTENSIONS -#define REQUIRED_EXTENSIONS (AARCH64_FL_SME2 \ +#define REQUIRED_EXTENSIONS (AARCH64_FL_SME \ + | AARCH64_FL_SME2 \ | AARCH64_FL_SME_F64F64 \ | AARCH64_FL_SM_ON) DEF_SME_ZA_FUNCTION_GS (svadd, unary_za_slice, za_d_float, vg1x24, none) @@ -196,3 +213,7 @@ DEF_SME_ZA_FUNCTION_GS (svmls_lane, binary_za_slice_lane, za_d_float, vg1x24, none) DEF_SME_ZA_FUNCTION_GS (svsub, unary_za_slice, za_d_float, vg1x24, none) #undef REQUIRED_EXTENSIONS + +#undef DEF_SME_ZA_FUNCTION +#undef DEF_SME_ZA_FUNCTION_GS +#undef DEF_SME_FUNCTION diff --git a/gcc/config/aarch64/aarch64-sve-builtins-sve2.def b/gcc/config/aarch64/aarch64-sve-builtins-sve2.def index 89bb134..4366925 100644 --- a/gcc/config/aarch64/aarch64-sve-builtins-sve2.def +++ b/gcc/config/aarch64/aarch64-sve-builtins-sve2.def @@ -241,6 +241,7 @@ DEF_SVE_FUNCTION (svrevd, unary, all_data, mxz) #define REQUIRED_EXTENSIONS (AARCH64_FL_SVE \ | AARCH64_FL_SVE2 \ + | AARCH64_FL_SME \ | AARCH64_FL_SME2 \ | AARCH64_FL_SM_ON) DEF_SVE_FUNCTION_GS (svadd, binary_single, all_integer, x24, none) diff --git a/gcc/config/aarch64/aarch64-sve-builtins.cc b/gcc/config/aarch64/aarch64-sve-builtins.cc index cd8d3bd..c2f1486 100644 --- a/gcc/config/aarch64/aarch64-sve-builtins.cc +++ b/gcc/config/aarch64/aarch64-sve-builtins.cc @@ -882,18 +882,15 @@ static const predication_index preds_z[] = { PRED_z, NUM_PREDS }; /* Used by SME instructions that always merge into ZA. */ static const predication_index preds_za_m[] = { PRED_za_m, NUM_PREDS }; -/* A list of all SVE ACLE functions. */ +/* A list of all arm_sve.h functions. */ static CONSTEXPR const function_group_info function_groups[] = { #define DEF_SVE_FUNCTION_GS(NAME, SHAPE, TYPES, GROUPS, PREDS) \ { #NAME, &functions::NAME, &shapes::SHAPE, types_##TYPES, groups_##GROUPS, \ preds_##PREDS, REQUIRED_EXTENSIONS }, -#define DEF_SME_ZA_FUNCTION_GS(NAME, SHAPE, TYPES, GROUPS, PREDS) \ - { #NAME, &functions::NAME##_za, &shapes::SHAPE, types_##TYPES, \ - groups_##GROUPS, preds_##PREDS, (REQUIRED_EXTENSIONS | AARCH64_FL_ZA_ON) }, #include "aarch64-sve-builtins.def" }; -/* A list of all NEON-SVE-Bridge ACLE functions. */ +/* A list of all arm_neon_sve_bridge.h ACLE functions. */ static CONSTEXPR const function_group_info neon_sve_function_groups[] = { #define DEF_NEON_SVE_FUNCTION(NAME, SHAPE, TYPES, GROUPS, PREDS) \ { #NAME, &neon_sve_bridge_functions::NAME, &shapes::SHAPE, types_##TYPES, \ @@ -901,6 +898,17 @@ static CONSTEXPR const function_group_info neon_sve_function_groups[] = { #include "aarch64-neon-sve-bridge-builtins.def" }; +/* A list of all arm_sme.h functions. */ +static CONSTEXPR const function_group_info sme_function_groups[] = { +#define DEF_SME_FUNCTION_GS(NAME, SHAPE, TYPES, GROUPS, PREDS) \ + { #NAME, &functions::NAME, &shapes::SHAPE, types_##TYPES, groups_##GROUPS, \ + preds_##PREDS, REQUIRED_EXTENSIONS }, +#define DEF_SME_ZA_FUNCTION_GS(NAME, SHAPE, TYPES, GROUPS, PREDS) \ + { #NAME, &functions::NAME##_za, &shapes::SHAPE, types_##TYPES, \ + groups_##GROUPS, preds_##PREDS, (REQUIRED_EXTENSIONS | AARCH64_FL_ZA_ON) }, +#include "aarch64-sve-builtins-sme.def" +}; + /* The scalar type associated with each vector type. */ extern GTY(()) tree scalar_types[NUM_VECTOR_TYPES + 1]; tree scalar_types[NUM_VECTOR_TYPES + 1]; @@ -930,6 +938,10 @@ static GTY(()) vec<registered_function *, va_gc> *registered_functions; overloaded functions. */ static hash_table<registered_function_hasher> *function_table; +/* Maps all overloaded function names that we've registered so far to + their associated function_instances. The map keys are IDENTIFIER_NODEs. */ +static GTY(()) hash_map<tree, registered_function *> *overload_names; + /* True if we've already complained about attempts to use functions when the required extension is disabled. */ static bool reported_missing_extension_p; @@ -1577,21 +1589,23 @@ function_builder:: add_overloaded_function (const function_instance &instance, aarch64_feature_flags required_extensions) { + if (!overload_names) + overload_names = hash_map<tree, registered_function *>::create_ggc (); + char *name = get_name (instance, true); - if (registered_function **map_value = m_overload_names.get (name)) - { - gcc_assert ((*map_value)->instance == instance - && ((*map_value)->required_extensions - & ~required_extensions) == 0); - obstack_free (&m_string_obstack, name); - } + tree id = get_identifier (name); + if (registered_function **map_value = overload_names->get (id)) + gcc_assert ((*map_value)->instance == instance + && ((*map_value)->required_extensions + & ~required_extensions) == 0); else { registered_function &rfn = add_function (instance, name, m_overload_type, NULL_TREE, required_extensions, true, m_direct_overloads); - m_overload_names.put (name, &rfn); + overload_names->put (id, &rfn); } + obstack_free (&m_string_obstack, name); } /* If we are using manual overload resolution, add one function decl @@ -4629,8 +4643,7 @@ handle_arm_sve_h () function_table = new hash_table<registered_function_hasher> (1023); function_builder builder; for (unsigned int i = 0; i < ARRAY_SIZE (function_groups); ++i) - if (!(function_groups[i].required_extensions & AARCH64_FL_SME)) - builder.register_function_group (function_groups[i]); + builder.register_function_group (function_groups[i]); } /* Implement #pragma GCC aarch64 "arm_neon_sve_bridge.h". */ @@ -4675,9 +4688,8 @@ handle_arm_sme_h () sme_switcher sme; function_builder builder; - for (unsigned int i = 0; i < ARRAY_SIZE (function_groups); ++i) - if (function_groups[i].required_extensions & AARCH64_FL_SME) - builder.register_function_group (function_groups[i]); + for (unsigned int i = 0; i < ARRAY_SIZE (sme_function_groups); ++i) + builder.register_function_group (sme_function_groups[i]); } /* If we're implementing manual overloading, check whether the SVE diff --git a/gcc/config/aarch64/aarch64-sve-builtins.def b/gcc/config/aarch64/aarch64-sve-builtins.def index 61593b4..a9243c4 100644 --- a/gcc/config/aarch64/aarch64-sve-builtins.def +++ b/gcc/config/aarch64/aarch64-sve-builtins.def @@ -51,16 +51,6 @@ DEF_SVE_FUNCTION_GS (NAME, SHAPE, TYPES, none, PREDS) #endif -#ifndef DEF_SME_ZA_FUNCTION_GS -#define DEF_SME_ZA_FUNCTION_GS(NAME, SHAPE, TYPES, GROUP, PREDS) \ - DEF_SVE_FUNCTION_GS(NAME, SHAPE, TYPES, GROUP, PREDS) -#endif - -#ifndef DEF_SME_ZA_FUNCTION -#define DEF_SME_ZA_FUNCTION(NAME, SHAPE, TYPES, PREDS) \ - DEF_SME_ZA_FUNCTION_GS (NAME, SHAPE, TYPES, none, PREDS) -#endif - DEF_SVE_MODE (n, none, none, none) DEF_SVE_MODE (single, none, none, none) DEF_SVE_MODE (index, none, none, elements) @@ -168,11 +158,8 @@ DEF_SVE_GROUP_SUFFIX (vg4x4, 4, 4) #include "aarch64-sve-builtins-base.def" #include "aarch64-sve-builtins-sve2.def" -#include "aarch64-sve-builtins-sme.def" -#undef DEF_SME_ZA_FUNCTION #undef DEF_SVE_FUNCTION -#undef DEF_SME_ZA_FUNCTION_GS #undef DEF_SVE_FUNCTION_GS #undef DEF_SVE_GROUP_SUFFIX #undef DEF_SME_ZA_SUFFIX diff --git a/gcc/config/aarch64/aarch64-sve-builtins.h b/gcc/config/aarch64/aarch64-sve-builtins.h index 2bb893a..e66729e 100644 --- a/gcc/config/aarch64/aarch64-sve-builtins.h +++ b/gcc/config/aarch64/aarch64-sve-builtins.h @@ -453,10 +453,6 @@ private: /* Used for building up function names. */ obstack m_string_obstack; - - /* Maps all overloaded function names that we've registered so far - to their associated function_instances. */ - hash_map<nofree_string_hash, registered_function *> m_overload_names; }; /* A base class for handling calls to built-in functions. */ diff --git a/gcc/config/aarch64/aarch64.cc b/gcc/config/aarch64/aarch64.cc index a5a6b52..7d1f8c6 100644 --- a/gcc/config/aarch64/aarch64.cc +++ b/gcc/config/aarch64/aarch64.cc @@ -8465,7 +8465,7 @@ aarch64_save_callee_saves (poly_int64 bytes_below_sp, emit_move_insn (move_src, gen_int_mode (aarch64_sve_vg, DImode)); } rtx base_rtx = stack_pointer_rtx; - poly_int64 cfa_offset = offset; + poly_int64 sp_offset = offset; HOST_WIDE_INT const_offset; if (mode == VNx2DImode && BYTES_BIG_ENDIAN) @@ -8490,17 +8490,12 @@ aarch64_save_callee_saves (poly_int64 bytes_below_sp, offset -= fp_offset; } rtx mem = gen_frame_mem (mode, plus_constant (Pmode, base_rtx, offset)); + rtx cfi_mem = gen_frame_mem (mode, plus_constant (Pmode, + stack_pointer_rtx, + sp_offset)); + rtx cfi_set = gen_rtx_SET (cfi_mem, reg); + bool need_cfi_note_p = (base_rtx != stack_pointer_rtx); - rtx cfa_base = stack_pointer_rtx; - if (hard_fp_valid_p && frame_pointer_needed) - { - cfa_base = hard_frame_pointer_rtx; - cfa_offset += (bytes_below_sp - frame.bytes_below_hard_fp); - } - - rtx cfa_mem = gen_frame_mem (mode, - plus_constant (Pmode, - cfa_base, cfa_offset)); unsigned int regno2; if (!aarch64_sve_mode_p (mode) && reg == move_src @@ -8514,34 +8509,48 @@ aarch64_save_callee_saves (poly_int64 bytes_below_sp, offset += GET_MODE_SIZE (mode); insn = emit_insn (aarch64_gen_store_pair (mem, reg, reg2)); - /* The first part of a frame-related parallel insn is - always assumed to be relevant to the frame - calculations; subsequent parts, are only - frame-related if explicitly marked. */ + rtx cfi_mem2 + = gen_frame_mem (mode, + plus_constant (Pmode, + stack_pointer_rtx, + sp_offset + GET_MODE_SIZE (mode))); + rtx cfi_set2 = gen_rtx_SET (cfi_mem2, reg2); + + /* The first part of a frame-related parallel insn is always + assumed to be relevant to the frame calculations; + subsequent parts, are only frame-related if + explicitly marked. */ if (aarch64_emit_cfi_for_reg_p (regno2)) - { - const auto off = cfa_offset + GET_MODE_SIZE (mode); - rtx cfa_mem2 = gen_frame_mem (mode, - plus_constant (Pmode, - cfa_base, - off)); - add_reg_note (insn, REG_CFA_OFFSET, - gen_rtx_SET (cfa_mem2, reg2)); - } + RTX_FRAME_RELATED_P (cfi_set2) = 1; + + /* Add a REG_FRAME_RELATED_EXPR note since the unspec + representation of stp cannot be understood directly by + dwarf2cfi. */ + rtx par = gen_rtx_PARALLEL (VOIDmode, + gen_rtvec (2, cfi_set, cfi_set2)); + add_reg_note (insn, REG_FRAME_RELATED_EXPR, par); regno = regno2; ++i; } - else if (mode == VNx2DImode && BYTES_BIG_ENDIAN) - insn = emit_insn (gen_aarch64_pred_mov (mode, mem, ptrue, move_src)); - else if (aarch64_sve_mode_p (mode)) - insn = emit_insn (gen_rtx_SET (mem, move_src)); else - insn = emit_move_insn (mem, move_src); + { + if (mode == VNx2DImode && BYTES_BIG_ENDIAN) + { + insn = emit_insn (gen_aarch64_pred_mov (mode, mem, + ptrue, move_src)); + need_cfi_note_p = true; + } + else if (aarch64_sve_mode_p (mode)) + insn = emit_insn (gen_rtx_SET (mem, move_src)); + else + insn = emit_move_insn (mem, move_src); + + if (frame_related_p && (need_cfi_note_p || move_src != reg)) + add_reg_note (insn, REG_FRAME_RELATED_EXPR, cfi_set); + } RTX_FRAME_RELATED_P (insn) = frame_related_p; - if (frame_related_p) - add_reg_note (insn, REG_CFA_OFFSET, gen_rtx_SET (cfa_mem, reg)); /* Emit a fake instruction to indicate that the VG save slot has been initialized. */ @@ -22873,16 +22882,61 @@ aarch64_mov_operand_p (rtx x, machine_mode mode) == SYMBOL_TINY_ABSOLUTE; } +/* Return a function-invariant register that contains VALUE. *CACHED_INSN + caches instructions that set up such registers, so that they can be + reused by future calls. */ + +static rtx +aarch64_get_shareable_reg (rtx_insn **cached_insn, rtx value) +{ + rtx_insn *insn = *cached_insn; + if (insn && INSN_P (insn) && !insn->deleted ()) + { + rtx pat = PATTERN (insn); + if (GET_CODE (pat) == SET) + { + rtx dest = SET_DEST (pat); + if (REG_P (dest) + && !HARD_REGISTER_P (dest) + && rtx_equal_p (SET_SRC (pat), value)) + return dest; + } + } + rtx reg = gen_reg_rtx (GET_MODE (value)); + *cached_insn = emit_insn_before (gen_rtx_SET (reg, value), + function_beg_insn); + return reg; +} + /* Create a 0 constant that is based on V4SI to allow CSE to optimally share the constant creation. */ rtx aarch64_gen_shareable_zero (machine_mode mode) { - machine_mode zmode = V4SImode; - rtx tmp = gen_reg_rtx (zmode); - emit_move_insn (tmp, CONST0_RTX (zmode)); - return lowpart_subreg (mode, tmp, zmode); + rtx reg = aarch64_get_shareable_reg (&cfun->machine->advsimd_zero_insn, + CONST0_RTX (V4SImode)); + return lowpart_subreg (mode, reg, GET_MODE (reg)); +} + +/* INSN is some form of extension or shift that can be split into a + permutation involving a shared zero. Return true if we should + perform such a split. + + ??? For now, make sure that the split instruction executes more + frequently than the zero that feeds it. In future it would be good + to split without that restriction and instead recombine shared zeros + if they turn out not to be worthwhile. This would allow splits in + single-block functions and would also cope more naturally with + rematerialization. */ + +bool +aarch64_split_simd_shift_p (rtx_insn *insn) +{ + return (can_create_pseudo_p () + && optimize_bb_for_speed_p (BLOCK_FOR_INSN (insn)) + && (ENTRY_BLOCK_PTR_FOR_FN (cfun)->count + < BLOCK_FOR_INSN (insn)->count)); } /* Return a const_int vector of VAL. */ diff --git a/gcc/config/aarch64/aarch64.h b/gcc/config/aarch64/aarch64.h index 0a4e152..157a0b9 100644 --- a/gcc/config/aarch64/aarch64.h +++ b/gcc/config/aarch64/aarch64.h @@ -1056,6 +1056,12 @@ typedef struct GTY (()) machine_function /* A set of all decls that have been passed to a vld1 intrinsic in the current function. This is used to help guide the vector cost model. */ hash_set<tree> *vector_load_decls; + + /* An instruction that was emitted at the start of the function to + set an Advanced SIMD pseudo register to zero. If the instruction + still exists and still fulfils its original purpose. the same register + can be reused by other code. */ + rtx_insn *advsimd_zero_insn; } machine_function; #endif #endif diff --git a/gcc/config/aarch64/aarch64.opt b/gcc/config/aarch64/aarch64.opt index ceed5cd..c495cb3 100644 --- a/gcc/config/aarch64/aarch64.opt +++ b/gcc/config/aarch64/aarch64.opt @@ -290,12 +290,12 @@ Target Var(aarch64_track_speculation) Generate code to track when the CPU might be speculating incorrectly. mearly-ldp-fusion -Target Var(flag_aarch64_early_ldp_fusion) Optimization Init(1) +Target Var(flag_aarch64_early_ldp_fusion) Optimization Init(0) Enable the copy of the AArch64 load/store pair fusion pass that runs before register allocation. mlate-ldp-fusion -Target Var(flag_aarch64_late_ldp_fusion) Optimization Init(1) +Target Var(flag_aarch64_late_ldp_fusion) Optimization Init(0) Enable the copy of the AArch64 load/store pair fusion pass that runs after register allocation. diff --git a/gcc/config/aarch64/iterators.md b/gcc/config/aarch64/iterators.md index 89767ee..942270e 100644 --- a/gcc/config/aarch64/iterators.md +++ b/gcc/config/aarch64/iterators.md @@ -1656,6 +1656,8 @@ ;; Narrowed quad-modes for VQN (Used for XTN2). (define_mode_attr VNARROWQ2 [(V8HI "V16QI") (V4SI "V8HI") (V2DI "V4SI")]) +(define_mode_attr Vnarrowq2 [(V8HI "v16qi") (V4SI "v8hi") + (V2DI "v4si")]) ;; Narrowed modes of vector modes. (define_mode_attr VNARROW [(VNx8HI "VNx16QI") diff --git a/gcc/config/arm/arm_neon.h b/gcc/config/arm/arm_neon.h index 7d491b6..8e70c71 100644 --- a/gcc/config/arm/arm_neon.h +++ b/gcc/config/arm/arm_neon.h @@ -10307,6 +10307,33 @@ vld1_p64 (const poly64_t * __a) return (poly64x1_t) { *__a }; } +__extension__ extern __inline poly64x1x2_t +__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) +vld1_p64_x2 (const poly64_t * __a) +{ + union { poly64x1x2_t __i; __builtin_neon_ti __o; } __rv; + __rv.__o = __builtin_neon_vld1_x2di ((const __builtin_neon_di *) __a); + return __rv.__i; +} + +__extension__ extern __inline poly64x1x3_t +__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) +vld1_p64_x3 (const poly64_t * __a) +{ + union { poly64x1x3_t __i; __builtin_neon_ei __o; } __rv; + __rv.__o = __builtin_neon_vld1_x3di ((const __builtin_neon_di *) __a); + return __rv.__i; +} + +__extension__ extern __inline poly64x1x4_t +__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) +vld1_p64_x4 (const poly64_t * __a) +{ + union { poly64x1x4_t __i; __builtin_neon_oi __o; } __rv; + __rv.__o = __builtin_neon_vld1_x4di ((const __builtin_neon_di *) __a); + return __rv.__i; +} + #pragma GCC pop_options __extension__ extern __inline int8x8_t __attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) @@ -10336,6 +10363,114 @@ vld1_s64 (const int64_t * __a) return (int64x1_t) { *__a }; } +__extension__ extern __inline int8x8x2_t +__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) +vld1_s8_x2 (const int8_t * __a) +{ + union { int8x8x2_t __i; __builtin_neon_ti __o; } __rv; + __rv.__o = __builtin_neon_vld1_x2v8qi ((const __builtin_neon_qi *) __a); + return __rv.__i; +} + +__extension__ extern __inline int16x4x2_t +__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) +vld1_s16_x2 (const int16_t * __a) +{ + union { int16x4x2_t __i; __builtin_neon_ti __o; } __rv; + __rv.__o = __builtin_neon_vld1_x2v4hi ((const __builtin_neon_hi *) __a); + return __rv.__i; +} + +__extension__ extern __inline int32x2x2_t +__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) +vld1_s32_x2 (const int32_t * __a) +{ + union { int32x2x2_t __i; __builtin_neon_ti __o; } __rv; + __rv.__o = __builtin_neon_vld1_x2v2si ((const __builtin_neon_si *) __a); + return __rv.__i; +} + +__extension__ extern __inline int64x1x2_t +__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) +vld1_s64_x2 (const int64_t * __a) +{ + union { int64x1x2_t __i; __builtin_neon_ti __o; } __rv; + __rv.__o = __builtin_neon_vld1_x2di ((const __builtin_neon_di *) __a); + return __rv.__i; +} + +__extension__ extern __inline int8x8x3_t +__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) +vld1_s8_x3 (const int8_t * __a) +{ + union { int8x8x3_t __i; __builtin_neon_ei __o; } __rv; + __rv.__o = __builtin_neon_vld1_x3v8qi ((const __builtin_neon_qi *) __a); + return __rv.__i; +} + +__extension__ extern __inline int16x4x3_t +__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) +vld1_s16_x3 (const int16_t * __a) +{ + union { int16x4x3_t __i; __builtin_neon_ei __o; } __rv; + __rv.__o = __builtin_neon_vld1_x3v4hi ((const __builtin_neon_hi *) __a); + return __rv.__i; +} + +__extension__ extern __inline int32x2x3_t +__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) +vld1_s32_x3 (const int32_t * __a) +{ + union { int32x2x3_t __i; __builtin_neon_ei __o; } __rv; + __rv.__o = __builtin_neon_vld1_x3v2si ((const __builtin_neon_si *) __a); + return __rv.__i; +} + +__extension__ extern __inline int64x1x3_t +__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) +vld1_s64_x3 (const int64_t * __a) +{ + union { int64x1x3_t __i; __builtin_neon_ei __o; } __rv; + __rv.__o = __builtin_neon_vld1_x3di ((const __builtin_neon_di *) __a); + return __rv.__i; +} + +__extension__ extern __inline int8x8x4_t +__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) +vld1_s8_x4 (const int8_t * __a) +{ + union { int8x8x4_t __i; __builtin_neon_oi __o; } __rv; + __rv.__o = __builtin_neon_vld1_x4v8qi ((const __builtin_neon_qi *) __a); + return __rv.__i; +} + +__extension__ extern __inline int16x4x4_t +__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) +vld1_s16_x4 (const int16_t * __a) +{ + union { int16x4x4_t __i; __builtin_neon_oi __o; } __rv; + __rv.__o = __builtin_neon_vld1_x4v4hi ((const __builtin_neon_hi *) __a); + return __rv.__i; +} + +__extension__ extern __inline int32x2x4_t +__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) +vld1_s32_x4 (const int32_t * __a) +{ + union { int32x2x4_t __i; __builtin_neon_oi __o; } __rv; + __rv.__o = __builtin_neon_vld1_x4v2si ((const __builtin_neon_si *) __a); + return __rv.__i; +} + +__extension__ extern __inline int64x1x4_t +__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) +vld1_s64_x4 (const int64_t * __a) +{ + union { int64x1x4_t __i; __builtin_neon_oi __o; } __rv; + __rv.__o = __builtin_neon_vld1_x4di ((const __builtin_neon_di *) __a); + return __rv.__i; +} + #if defined (__ARM_FP16_FORMAT_IEEE) || defined (__ARM_FP16_FORMAT_ALTERNATIVE) __extension__ extern __inline float16x4_t __attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) @@ -10352,6 +10487,66 @@ vld1_f32 (const float32_t * __a) return (float32x2_t)__builtin_neon_vld1v2sf ((const __builtin_neon_sf *) __a); } +#if defined (__ARM_FP16_FORMAT_IEEE) || defined (__ARM_FP16_FORMAT_ALTERNATIVE) +__extension__ extern __inline float16x4x2_t +__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) +vld1_f16_x2 (const float16_t * __a) +{ + union { float16x4x2_t __i; __builtin_neon_ti __o; } __rv; + __rv.__o = __builtin_neon_vld1_x2v4hf (__a); + return __rv.__i; +} +#endif + +__extension__ extern __inline float32x2x2_t +__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) +vld1_f32_x2 (const float32_t * __a) +{ + union { float32x2x2_t __i; __builtin_neon_ti __o; } __rv; + __rv.__o = __builtin_neon_vld1_x2v2sf ((const __builtin_neon_sf *) __a); + return __rv.__i; +} + +#if defined (__ARM_FP16_FORMAT_IEEE) || defined (__ARM_FP16_FORMAT_ALTERNATIVE) +__extension__ extern __inline float16x4x3_t +__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) +vld1_f16_x3 (const float16_t * __a) +{ + union { float16x4x3_t __i; __builtin_neon_ei __o; } __rv; + __rv.__o = __builtin_neon_vld1_x3v4hf (__a); + return __rv.__i; +} +#endif + +__extension__ extern __inline float32x2x3_t +__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) +vld1_f32_x3 (const float32_t * __a) +{ + union { float32x2x3_t __i; __builtin_neon_ei __o; } __rv; + __rv.__o = __builtin_neon_vld1_x3v2sf ((const __builtin_neon_sf *) __a); + return __rv.__i; +} + +#if defined (__ARM_FP16_FORMAT_IEEE) || defined (__ARM_FP16_FORMAT_ALTERNATIVE) +__extension__ extern __inline float16x4x4_t +__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) +vld1_f16_x4 (const float16_t * __a) +{ + union { float16x4x4_t __i; __builtin_neon_oi __o; } __rv; + __rv.__o = __builtin_neon_vld1_x4v4hf (__a); + return __rv.__i; +} +#endif + +__extension__ extern __inline float32x2x4_t +__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) +vld1_f32_x4 (const float32_t * __a) +{ + union { float32x2x4_t __i; __builtin_neon_oi __o; } __rv; + __rv.__o = __builtin_neon_vld1_x4v2sf ((const __builtin_neon_sf *) __a); + return __rv.__i; +} + __extension__ extern __inline uint8x8_t __attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) vld1_u8 (const uint8_t * __a) @@ -10380,6 +10575,114 @@ vld1_u64 (const uint64_t * __a) return (uint64x1_t) { *__a }; } +__extension__ extern __inline uint8x8x2_t +__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) +vld1_u8_x2 (const uint8_t * __a) +{ + union { uint8x8x2_t __i; __builtin_neon_ti __o; } __rv; + __rv.__o = __builtin_neon_vld1_x2v8qi ((const __builtin_neon_qi *) __a); + return __rv.__i; +} + +__extension__ extern __inline uint16x4x2_t +__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) +vld1_u16_x2 (const uint16_t * __a) +{ + union { uint16x4x2_t __i; __builtin_neon_ti __o; } __rv; + __rv.__o = __builtin_neon_vld1_x2v4hi ((const __builtin_neon_hi *) __a); + return __rv.__i; +} + +__extension__ extern __inline uint32x2x2_t +__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) +vld1_u32_x2 (const uint32_t * __a) +{ + union { uint32x2x2_t __i; __builtin_neon_ti __o; } __rv; + __rv.__o = __builtin_neon_vld1_x2v2si ((const __builtin_neon_si *) __a); + return __rv.__i; +} + +__extension__ extern __inline uint64x1x2_t +__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) +vld1_u64_x2 (const uint64_t * __a) +{ + union { uint64x1x2_t __i; __builtin_neon_ti __o; } __rv; + __rv.__o = __builtin_neon_vld1_x2di ((const __builtin_neon_di *) __a); + return __rv.__i; +} + +__extension__ extern __inline uint8x8x3_t +__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) +vld1_u8_x3 (const uint8_t * __a) +{ + union { uint8x8x3_t __i; __builtin_neon_ei __o; } __rv; + __rv.__o = __builtin_neon_vld1_x3v8qi ((const __builtin_neon_qi *) __a); + return __rv.__i; +} + +__extension__ extern __inline uint16x4x3_t +__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) +vld1_u16_x3 (const uint16_t * __a) +{ + union { uint16x4x3_t __i; __builtin_neon_ei __o; } __rv; + __rv.__o = __builtin_neon_vld1_x3v4hi ((const __builtin_neon_hi *) __a); + return __rv.__i; +} + +__extension__ extern __inline uint32x2x3_t +__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) +vld1_u32_x3 (const uint32_t * __a) +{ + union { uint32x2x3_t __i; __builtin_neon_ei __o; } __rv; + __rv.__o = __builtin_neon_vld1_x3v2si ((const __builtin_neon_si *) __a); + return __rv.__i; +} + +__extension__ extern __inline uint64x1x3_t +__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) +vld1_u64_x3 (const uint64_t * __a) +{ + union { uint64x1x3_t __i; __builtin_neon_ei __o; } __rv; + __rv.__o = __builtin_neon_vld1_x3di ((const __builtin_neon_di *) __a); + return __rv.__i; +} + +__extension__ extern __inline uint8x8x4_t +__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) +vld1_u8_x4 (const uint8_t * __a) +{ + union { uint8x8x4_t __i; __builtin_neon_oi __o; } __rv; + __rv.__o = __builtin_neon_vld1_x4v8qi ((const __builtin_neon_qi *) __a); + return __rv.__i; +} + +__extension__ extern __inline uint16x4x4_t +__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) +vld1_u16_x4 (const uint16_t * __a) +{ + union { uint16x4x4_t __i; __builtin_neon_oi __o; } __rv; + __rv.__o = __builtin_neon_vld1_x4v4hi ((const __builtin_neon_hi *) __a); + return __rv.__i; +} + +__extension__ extern __inline uint32x2x4_t +__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) +vld1_u32_x4 (const uint32_t * __a) +{ + union { uint32x2x4_t __i; __builtin_neon_oi __o; } __rv; + __rv.__o = __builtin_neon_vld1_x4v2si ((const __builtin_neon_si *) __a); + return __rv.__i; +} + +__extension__ extern __inline uint64x1x4_t +__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) +vld1_u64_x4 (const uint64_t * __a) +{ + union { uint64x1x4_t __i; __builtin_neon_oi __o; } __rv; + __rv.__o = __builtin_neon_vld1_x4di ((const __builtin_neon_di *) __a); + return __rv.__i; +} + __extension__ extern __inline poly8x8_t __attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) vld1_p8 (const poly8_t * __a) @@ -10394,6 +10697,60 @@ vld1_p16 (const poly16_t * __a) return (poly16x4_t)__builtin_neon_vld1v4hi ((const __builtin_neon_hi *) __a); } +__extension__ extern __inline poly8x8x2_t +__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) +vld1_p8_x2 (const poly8_t * __a) +{ + union { poly8x8x2_t __i; __builtin_neon_ti __o; } __rv; + __rv.__o = __builtin_neon_vld1_x2v8qi ((const __builtin_neon_qi *) __a); + return __rv.__i; +} + +__extension__ extern __inline poly16x4x2_t +__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) +vld1_p16_x2 (const poly16_t * __a) +{ + union { poly16x4x2_t __i; __builtin_neon_ti __o; } __rv; + __rv.__o = __builtin_neon_vld1_x2v4hi ((const __builtin_neon_hi *) __a); + return __rv.__i; +} + +__extension__ extern __inline poly8x8x3_t +__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) +vld1_p8_x3 (const poly8_t * __a) +{ + union { poly8x8x3_t __i; __builtin_neon_ei __o; } __rv; + __rv.__o = __builtin_neon_vld1_x3v8qi ((const __builtin_neon_qi *) __a); + return __rv.__i; +} + +__extension__ extern __inline poly16x4x3_t +__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) +vld1_p16_x3 (const poly16_t * __a) +{ + union { poly16x4x3_t __i; __builtin_neon_ei __o; } __rv; + __rv.__o = __builtin_neon_vld1_x3v4hi ((const __builtin_neon_hi *) __a); + return __rv.__i; +} + +__extension__ extern __inline poly8x8x4_t +__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) +vld1_p8_x4 (const poly8_t * __a) +{ + union { poly8x8x4_t __i; __builtin_neon_oi __o; } __rv; + __rv.__o = __builtin_neon_vld1_x4v8qi ((const __builtin_neon_qi *) __a); + return __rv.__i; +} + +__extension__ extern __inline poly16x4x4_t +__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) +vld1_p16_x4 (const poly16_t * __a) +{ + union { poly16x4x4_t __i; __builtin_neon_oi __o; } __rv; + __rv.__o = __builtin_neon_vld1_x4v4hi ((const __builtin_neon_hi *) __a); + return __rv.__i; +} + #pragma GCC push_options #pragma GCC target ("fpu=crypto-neon-fp-armv8") __extension__ extern __inline poly64x2_t @@ -10403,6 +10760,33 @@ vld1q_p64 (const poly64_t * __a) return (poly64x2_t)__builtin_neon_vld1v2di ((const __builtin_neon_di *) __a); } +__extension__ extern __inline poly64x2x2_t +__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) +vld1q_p64_x2 (const poly64_t * __a) +{ + union { poly64x2x2_t __i; __builtin_neon_oi __o; } __rv; + __rv.__o = __builtin_neon_vld1q_x2v2di ((const __builtin_neon_di *) __a); + return __rv.__i; +} + +__extension__ extern __inline poly64x2x3_t +__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) +vld1q_p64_x3 (const poly64_t * __a) +{ + union { poly64x2x3_t __i; __builtin_neon_ci __o; } __rv; + __rv.__o = __builtin_neon_vld1q_x3v2di ((const __builtin_neon_di *) __a); + return __rv.__i; +} + +__extension__ extern __inline poly64x2x4_t +__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) +vld1q_p64_x4 (const poly64_t * __a) +{ + union { poly64x2x4_t __i; __builtin_neon_xi __o; } __rv; + __rv.__o = __builtin_neon_vld1q_x4v2di ((const __builtin_neon_di *) __a); + return __rv.__i; +} + #pragma GCC pop_options __extension__ extern __inline int8x16_t __attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) @@ -10432,6 +10816,114 @@ vld1q_s64 (const int64_t * __a) return (int64x2_t)__builtin_neon_vld1v2di ((const __builtin_neon_di *) __a); } +__extension__ extern __inline int8x16x2_t +__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) +vld1q_s8_x2 (const int8_t * __a) +{ + union { int8x16x2_t __i; __builtin_neon_oi __o; } __rv; + __rv.__o = __builtin_neon_vld1q_x2v16qi ((const __builtin_neon_qi *) __a); + return __rv.__i; +} + +__extension__ extern __inline int16x8x2_t +__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) +vld1q_s16_x2 (const int16_t * __a) +{ + union { int16x8x2_t __i; __builtin_neon_oi __o; } __rv; + __rv.__o = __builtin_neon_vld1q_x2v8hi ((const __builtin_neon_hi *) __a); + return __rv.__i; +} + +__extension__ extern __inline int32x4x2_t +__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) +vld1q_s32_x2 (const int32_t * __a) +{ + union { int32x4x2_t __i; __builtin_neon_oi __o; } __rv; + __rv.__o = __builtin_neon_vld1q_x2v4si ((const __builtin_neon_si *) __a); + return __rv.__i; +} + +__extension__ extern __inline int64x2x2_t +__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) +vld1q_s64_x2 (const int64_t * __a) +{ + union { int64x2x2_t __i; __builtin_neon_oi __o; } __rv; + __rv.__o = __builtin_neon_vld1q_x2v2di ((const __builtin_neon_di *) __a); + return __rv.__i; +} + +__extension__ extern __inline int8x16x3_t +__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) +vld1q_s8_x3 (const uint8_t * __a) +{ + union { int8x16x3_t __i; __builtin_neon_ci __o; } __rv; + __rv.__o = __builtin_neon_vld1q_x3v16qi ((const __builtin_neon_qi *) __a); + return __rv.__i; +} + +__extension__ extern __inline int16x8x3_t +__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) +vld1q_s16_x3 (const uint16_t * __a) +{ + union { int16x8x3_t __i; __builtin_neon_ci __o; } __rv; + __rv.__o = __builtin_neon_vld1q_x3v8hi ((const __builtin_neon_hi *) __a); + return __rv.__i; +} + +__extension__ extern __inline int32x4x3_t +__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) +vld1q_s32_x3 (const int32_t * __a) +{ + union { int32x4x3_t __i; __builtin_neon_ci __o; } __rv; + __rv.__o = __builtin_neon_vld1q_x3v4si ((const __builtin_neon_si *) __a); + return __rv.__i; +} + +__extension__ extern __inline int64x2x3_t +__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) +vld1q_s64_x3 (const int64_t * __a) +{ + union { int64x2x3_t __i; __builtin_neon_ci __o; } __rv; + __rv.__o = __builtin_neon_vld1q_x3v2di ((const __builtin_neon_di *) __a); + return __rv.__i; +} + +__extension__ extern __inline int8x16x4_t +__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) +vld1q_s8_x4 (const uint8_t * __a) +{ + union { int8x16x4_t __i; __builtin_neon_xi __o; } __rv; + __rv.__o = __builtin_neon_vld1q_x4v16qi ((const __builtin_neon_qi *) __a); + return __rv.__i; +} + +__extension__ extern __inline int16x8x4_t +__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) +vld1q_s16_x4 (const uint16_t * __a) +{ + union { int16x8x4_t __i; __builtin_neon_xi __o; } __rv; + __rv.__o = __builtin_neon_vld1q_x4v8hi ((const __builtin_neon_hi *) __a); + return __rv.__i; +} + +__extension__ extern __inline int32x4x4_t +__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) +vld1q_s32_x4 (const int32_t * __a) +{ + union { int32x4x4_t __i; __builtin_neon_xi __o; } __rv; + __rv.__o = __builtin_neon_vld1q_x4v4si ((const __builtin_neon_si *) __a); + return __rv.__i; +} + +__extension__ extern __inline int64x2x4_t +__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) +vld1q_s64_x4 (const int64_t * __a) +{ + union { int64x2x4_t __i; __builtin_neon_xi __o; } __rv; + __rv.__o = __builtin_neon_vld1q_x4v2di ((const __builtin_neon_di *) __a); + return __rv.__i; +} + #if defined (__ARM_FP16_FORMAT_IEEE) || defined (__ARM_FP16_FORMAT_ALTERNATIVE) __extension__ extern __inline float16x8_t __attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) @@ -10448,6 +10940,66 @@ vld1q_f32 (const float32_t * __a) return (float32x4_t)__builtin_neon_vld1v4sf ((const __builtin_neon_sf *) __a); } +#if defined (__ARM_FP16_FORMAT_IEEE) || defined (__ARM_FP16_FORMAT_ALTERNATIVE) +__extension__ extern __inline float16x8x2_t +__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) +vld1q_f16_x2 (const float16_t * __a) +{ + union { float16x8x2_t __i; __builtin_neon_oi __o; } __rv; + __rv.__o = __builtin_neon_vld1q_x2v8hf (__a); + return __rv.__i; +} +#endif + +__extension__ extern __inline float32x4x2_t +__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) +vld1q_f32_x2 (const float32_t * __a) +{ + union { float32x4x2_t __i; __builtin_neon_oi __o; } __rv; + __rv.__o = __builtin_neon_vld1q_x2v4sf ((const __builtin_neon_sf *) __a); + return __rv.__i; +} + +#if defined (__ARM_FP16_FORMAT_IEEE) || defined (__ARM_FP16_FORMAT_ALTERNATIVE) +__extension__ extern __inline float16x8x3_t +__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) +vld1q_f16_x3 (const float16_t * __a) +{ + union { float16x8x3_t __i; __builtin_neon_ci __o; } __rv; + __rv.__o = __builtin_neon_vld1q_x3v8hf (__a); + return __rv.__i; +} +#endif + +__extension__ extern __inline float32x4x3_t +__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) +vld1q_f32_x3 (const float32_t * __a) +{ + union { float32x4x3_t __i; __builtin_neon_ci __o; } __rv; + __rv.__o = __builtin_neon_vld1q_x3v4sf ((const __builtin_neon_sf *) __a); + return __rv.__i; +} + +#if defined (__ARM_FP16_FORMAT_IEEE) || defined (__ARM_FP16_FORMAT_ALTERNATIVE) +__extension__ extern __inline float16x8x4_t +__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) +vld1q_f16_x4 (const float16_t * __a) +{ + union { float16x8x4_t __i; __builtin_neon_xi __o; } __rv; + __rv.__o = __builtin_neon_vld1q_x4v8hf (__a); + return __rv.__i; +} +#endif + +__extension__ extern __inline float32x4x4_t +__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) +vld1q_f32_x4 (const float32_t * __a) +{ + union { float32x4x4_t __i; __builtin_neon_xi __o; } __rv; + __rv.__o = __builtin_neon_vld1q_x4v4sf ((const __builtin_neon_sf *) __a); + return __rv.__i; +} + __extension__ extern __inline uint8x16_t __attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) vld1q_u8 (const uint8_t * __a) @@ -10476,6 +11028,114 @@ vld1q_u64 (const uint64_t * __a) return (uint64x2_t)__builtin_neon_vld1v2di ((const __builtin_neon_di *) __a); } +__extension__ extern __inline uint8x16x2_t +__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) +vld1q_u8_x2 (const uint8_t * __a) +{ + union { uint8x16x2_t __i; __builtin_neon_oi __o; } __rv; + __rv.__o = __builtin_neon_vld1q_x2v16qi ((const __builtin_neon_qi *) __a); + return __rv.__i; +} + +__extension__ extern __inline uint16x8x2_t +__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) +vld1q_u16_x2 (const uint16_t * __a) +{ + union { uint16x8x2_t __i; __builtin_neon_oi __o; } __rv; + __rv.__o = __builtin_neon_vld1q_x2v8hi ((const __builtin_neon_hi *) __a); + return __rv.__i; +} + +__extension__ extern __inline uint32x4x2_t +__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) +vld1q_u32_x2 (const uint32_t * __a) +{ + union { uint32x4x2_t __i; __builtin_neon_oi __o; } __rv; + __rv.__o = __builtin_neon_vld1q_x2v4si ((const __builtin_neon_si *) __a); + return __rv.__i; +} + +__extension__ extern __inline uint64x2x2_t +__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) +vld1q_u64_x2 (const uint64_t * __a) +{ + union { uint64x2x2_t __i; __builtin_neon_oi __o; } __rv; + __rv.__o = __builtin_neon_vld1q_x2v2di ((const __builtin_neon_di *) __a); + return __rv.__i; +} + +__extension__ extern __inline uint8x16x3_t +__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) +vld1q_u8_x3 (const uint8_t * __a) +{ + union { uint8x16x3_t __i; __builtin_neon_ci __o; } __rv; + __rv.__o = __builtin_neon_vld1q_x3v16qi ((const __builtin_neon_qi *) __a); + return __rv.__i; +} + +__extension__ extern __inline uint16x8x3_t +__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) +vld1q_u16_x3 (const uint16_t * __a) +{ + union { uint16x8x3_t __i; __builtin_neon_ci __o; } __rv; + __rv.__o = __builtin_neon_vld1q_x3v8hi ((const __builtin_neon_hi *) __a); + return __rv.__i; +} + +__extension__ extern __inline uint32x4x3_t +__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) +vld1q_u32_x3 (const uint32_t * __a) +{ + union { uint32x4x3_t __i; __builtin_neon_ci __o; } __rv; + __rv.__o = __builtin_neon_vld1q_x3v4si ((const __builtin_neon_si *) __a); + return __rv.__i; +} + +__extension__ extern __inline uint64x2x3_t +__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) +vld1q_u64_x3 (const uint64_t * __a) +{ + union { uint64x2x3_t __i; __builtin_neon_ci __o; } __rv; + __rv.__o = __builtin_neon_vld1q_x3v2di ((const __builtin_neon_di *) __a); + return __rv.__i; +} + +__extension__ extern __inline uint8x16x4_t +__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) +vld1q_u8_x4 (const uint8_t * __a) +{ + union { uint8x16x4_t __i; __builtin_neon_xi __o; } __rv; + __rv.__o = __builtin_neon_vld1q_x4v16qi ((const __builtin_neon_qi *) __a); + return __rv.__i; +} + +__extension__ extern __inline uint16x8x4_t +__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) +vld1q_u16_x4 (const uint16_t * __a) +{ + union { uint16x8x4_t __i; __builtin_neon_xi __o; } __rv; + __rv.__o = __builtin_neon_vld1q_x4v8hi ((const __builtin_neon_hi *) __a); + return __rv.__i; +} + +__extension__ extern __inline uint32x4x4_t +__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) +vld1q_u32_x4 (const uint32_t * __a) +{ + union { uint32x4x4_t __i; __builtin_neon_xi __o; } __rv; + __rv.__o = __builtin_neon_vld1q_x4v4si ((const __builtin_neon_si *) __a); + return __rv.__i; +} + +__extension__ extern __inline uint64x2x4_t +__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) +vld1q_u64_x4 (const uint64_t * __a) +{ + union { uint64x2x4_t __i; __builtin_neon_xi __o; } __rv; + __rv.__o = __builtin_neon_vld1q_x4v2di ((const __builtin_neon_di *) __a); + return __rv.__i; +} + __extension__ extern __inline poly8x16_t __attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) vld1q_p8 (const poly8_t * __a) @@ -10490,6 +11150,60 @@ vld1q_p16 (const poly16_t * __a) return (poly16x8_t)__builtin_neon_vld1v8hi ((const __builtin_neon_hi *) __a); } +__extension__ extern __inline poly8x16x2_t +__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) +vld1q_p8_x2 (const poly8_t * __a) +{ + union { poly8x16x2_t __i; __builtin_neon_oi __o; } __rv; + __rv.__o = __builtin_neon_vld1q_x2v16qi ((const __builtin_neon_qi *) __a); + return __rv.__i; +} + +__extension__ extern __inline poly16x8x2_t +__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) +vld1q_p16_x2 (const poly16_t * __a) +{ + union { poly16x8x2_t __i; __builtin_neon_oi __o; } __rv; + __rv.__o = __builtin_neon_vld1q_x2v8hi ((const __builtin_neon_hi *) __a); + return __rv.__i; +} + +__extension__ extern __inline poly8x16x3_t +__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) +vld1q_p8_x3 (const poly8_t * __a) +{ + union { poly8x16x3_t __i; __builtin_neon_ci __o; } __rv; + __rv.__o = __builtin_neon_vld1q_x3v16qi ((const __builtin_neon_qi *) __a); + return __rv.__i; +} + +__extension__ extern __inline poly16x8x3_t +__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) +vld1q_p16_x3 (const poly16_t * __a) +{ + union { poly16x8x3_t __i; __builtin_neon_ci __o; } __rv; + __rv.__o = __builtin_neon_vld1q_x3v8hi ((const __builtin_neon_hi *) __a); + return __rv.__i; +} + +__extension__ extern __inline poly8x16x4_t +__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) +vld1q_p8_x4 (const poly8_t * __a) +{ + union { poly8x16x4_t __i; __builtin_neon_xi __o; } __rv; + __rv.__o = __builtin_neon_vld1q_x4v16qi ((const __builtin_neon_qi *) __a); + return __rv.__i; +} + +__extension__ extern __inline poly16x8x4_t +__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) +vld1q_p16_x4 (const poly16_t * __a) +{ + union { poly16x8x4_t __i; __builtin_neon_xi __o; } __rv; + __rv.__o = __builtin_neon_vld1q_x4v8hi ((const __builtin_neon_hi *) __a); + return __rv.__i; +} + __extension__ extern __inline int8x8_t __attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) vld1_lane_s8 (const int8_t * __a, int8x8_t __b, const int __c) @@ -10885,6 +11599,30 @@ vst1_p64 (poly64_t * __a, poly64x1_t __b) __builtin_neon_vst1di ((__builtin_neon_di *) __a, __b); } +__extension__ extern __inline void +__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) +vst1_p64_x2 (poly64_t * __a, poly64x1x2_t __b) +{ + union { poly64x1x2_t __i; __builtin_neon_ti __o; } __bu = { __b }; + __builtin_neon_vst1_x2di ((__builtin_neon_di *) __a, __bu.__o); +} + +__extension__ extern __inline void +__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) +vst1_p64_x3 (poly64_t * __a, poly64x1x3_t __b) +{ + union { poly64x1x3_t __i; __builtin_neon_ei __o; } __bu = { __b }; + __builtin_neon_vst1_x3di ((__builtin_neon_di *) __a, __bu.__o); +} + +__extension__ extern __inline void +__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) +vst1_p64_x4 (poly64_t * __a, poly64x1x4_t __b) +{ + union { poly64x1x4_t __i; __builtin_neon_oi __o; } __bu = { __b }; + __builtin_neon_vst1_x3di ((__builtin_neon_di *) __a, __bu.__o); +} + #pragma GCC pop_options __extension__ extern __inline void __attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) @@ -10914,6 +11652,198 @@ vst1_s64 (int64_t * __a, int64x1_t __b) __builtin_neon_vst1di ((__builtin_neon_di *) __a, __b); } +__extension__ extern __inline void +__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) +vst1_s8_x2 (int8_t * __a, int8x8x2_t __b) +{ + union { int8x8x2_t __i; __builtin_neon_ti __o; } __bu = { __b }; + __builtin_neon_vst1_x2v8qi ((__builtin_neon_qi *) __a, __bu.__o); +} + +__extension__ extern __inline void +__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) +vst1_s16_x2 (int16_t * __a, int16x4x2_t __b) +{ + union { int16x4x2_t __i; __builtin_neon_ti __o; } __bu = { __b }; + __builtin_neon_vst1_x2v4hi ((__builtin_neon_hi *) __a, __bu.__o); +} + +__extension__ extern __inline void +__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) +vst1_s32_x2 (int32_t * __a, int32x2x2_t __b) +{ + union { int32x2x2_t __i; __builtin_neon_ti __o; } __bu = { __b }; + __builtin_neon_vst1_x2v2si ((__builtin_neon_si *) __a, __bu.__o); +} + +__extension__ extern __inline void +__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) +vst1_s64_x2 (int64_t * __a, int64x1x2_t __b) +{ + union { int64x1x2_t __i; __builtin_neon_ti __o; } __bu = { __b }; + __builtin_neon_vst1_x2di ((__builtin_neon_di *) __a, __bu.__o); +} + +__extension__ extern __inline void +__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) +vst1q_s8_x2 (int8_t * __a, int8x16x2_t __b) +{ + union { int8x16x2_t __i; __builtin_neon_oi __o; } __bu = { __b }; + __builtin_neon_vst1q_x2v16qi ((__builtin_neon_qi *) __a, __bu.__o); +} + +__extension__ extern __inline void +__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) +vst1q_s16_x2 (int16_t * __a, int16x8x2_t __b) +{ + union { int16x8x2_t __i; __builtin_neon_oi __o; } __bu = { __b }; + __builtin_neon_vst1q_x2v8hi ((__builtin_neon_hi *) __a, __bu.__o); +} + +__extension__ extern __inline void +__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) +vst1q_s32_x2 (int32_t * __a, int32x4x2_t __b) +{ + union { int32x4x2_t __i; __builtin_neon_oi __o; } __bu = { __b }; + __builtin_neon_vst1q_x2v4si ((__builtin_neon_si *) __a, __bu.__o); +} + +__extension__ extern __inline void +__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) +vst1q_s64_x2 (int64_t * __a, int64x2x2_t __b) +{ + union { int64x2x2_t __i; __builtin_neon_oi __o; } __bu = { __b }; + __builtin_neon_vst1q_x2v2di ((__builtin_neon_di *) __a, __bu.__o); +} + +__extension__ extern __inline void +__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) +vst1q_s8_x3 (int8_t * __a, int8x16x3_t __b) +{ + union { int8x16x3_t __i; __builtin_neon_ci __o; } __bu = { __b }; + __builtin_neon_vst1q_x3v16qi ((__builtin_neon_qi *) __a, __bu.__o); +} + +__extension__ extern __inline void +__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) +vst1q_s16_x3 (int16_t * __a, int16x8x3_t __b) +{ + union { int16x8x3_t __i; __builtin_neon_ci __o; } __bu = { __b }; + __builtin_neon_vst1q_x3v8hi ((__builtin_neon_hi *) __a, __bu.__o); +} + +__extension__ extern __inline void +__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) +vst1q_s32_x3 (int32_t * __a, int32x4x3_t __b) +{ + union { int32x4x3_t __i; __builtin_neon_ci __o; } __bu = { __b }; + __builtin_neon_vst1q_x3v4si ((__builtin_neon_si *) __a, __bu.__o); +} + +__extension__ extern __inline void +__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) +vst1q_s64_x3 (int64_t * __a, int64x2x3_t __b) +{ + union { int64x2x3_t __i; __builtin_neon_ci __o; } __bu = { __b }; + __builtin_neon_vst1q_x3v2di ((__builtin_neon_di *) __a, __bu.__o); +} + +__extension__ extern __inline void +__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) +vst1q_s8_x4 (int8_t * __a, int8x16x4_t __b) +{ + union { int8x16x4_t __i; __builtin_neon_xi __o; } __bu = { __b }; + __builtin_neon_vst1q_x4v16qi ((__builtin_neon_qi *) __a, __bu.__o); +} + +__extension__ extern __inline void +__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) +vst1q_s16_x4 (int16_t * __a, int16x8x4_t __b) +{ + union { int16x8x4_t __i; __builtin_neon_xi __o; } __bu = { __b }; + __builtin_neon_vst1q_x4v8hi ((__builtin_neon_hi *) __a, __bu.__o); +} + +__extension__ extern __inline void +__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) +vst1q_s32_x4 (int32_t * __a, int32x4x4_t __b) +{ + union { int32x4x4_t __i; __builtin_neon_xi __o; } __bu = { __b }; + __builtin_neon_vst1q_x4v4si ((__builtin_neon_si *) __a, __bu.__o); +} + +__extension__ extern __inline void +__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) +vst1q_s64_x4 (int64_t * __a, int64x2x4_t __b) +{ + union { int64x2x4_t __i; __builtin_neon_xi __o; } __bu = { __b }; + __builtin_neon_vst1q_x4v2di ((__builtin_neon_di *) __a, __bu.__o); +} + +__extension__ extern __inline void +__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) +vst1_s8_x3 (int8_t * __a, int8x8x3_t __b) +{ + union { int8x8x3_t __i; __builtin_neon_ei __o; } __bu = { __b }; + __builtin_neon_vst1_x3v8qi ((__builtin_neon_qi *) __a, __bu.__o); +} + +__extension__ extern __inline void +__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) +vst1_s16_x3 (int16_t * __a, int16x4x3_t __b) +{ + union { int16x4x3_t __i; __builtin_neon_ei __o; } __bu = { __b }; + __builtin_neon_vst1_x3v4hi ((__builtin_neon_hi *) __a, __bu.__o); +} + +__extension__ extern __inline void +__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) +vst1_s32_x3 (int32_t * __a, int32x2x3_t __b) +{ + union { int32x2x3_t __i; __builtin_neon_ei __o; } __bu = { __b }; + __builtin_neon_vst1_x3v2si ((__builtin_neon_si *) __a, __bu.__o); +} + +__extension__ extern __inline void +__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) +vst1_s64_x3 (int64_t * __a, int64x1x3_t __b) +{ + union { int64x1x3_t __i; __builtin_neon_ei __o; } __bu = { __b }; + __builtin_neon_vst1_x3di ((__builtin_neon_di *) __a, __bu.__o); +} + +__extension__ extern __inline void +__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) +vst1_s8_x4 (int8_t * __a, int8x8x4_t __b) +{ + union { int8x8x4_t __i; __builtin_neon_oi __o; } __bu = { __b }; + __builtin_neon_vst1_x4v8qi ((__builtin_neon_qi *) __a, __bu.__o); +} + +__extension__ extern __inline void +__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) +vst1_s16_x4 (int16_t * __a, int16x4x4_t __b) +{ + union { int16x4x4_t __i; __builtin_neon_oi __o; } __bu = { __b }; + __builtin_neon_vst1_x4v4hi ((__builtin_neon_hi *) __a, __bu.__o); +} + +__extension__ extern __inline void +__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) +vst1_s32_x4 (int32_t * __a, int32x2x4_t __b) +{ + union { int32x2x4_t __i; __builtin_neon_oi __o; } __bu = { __b }; + __builtin_neon_vst1_x4v2si ((__builtin_neon_si *) __a, __bu.__o); +} + +__extension__ extern __inline void +__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) +vst1_s64_x4 (int64_t * __a, int64x1x4_t __b) +{ + union { int64x1x4_t __i; __builtin_neon_oi __o; } __bu = { __b }; + __builtin_neon_vst1_x4di ((__builtin_neon_di *) __a, __bu.__o); +} + #if defined (__ARM_FP16_FORMAT_IEEE) || defined (__ARM_FP16_FORMAT_ALTERNATIVE) __extension__ extern __inline void __attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) @@ -10930,6 +11860,60 @@ vst1_f32 (float32_t * __a, float32x2_t __b) __builtin_neon_vst1v2sf ((__builtin_neon_sf *) __a, __b); } +#if defined (__ARM_FP16_FORMAT_IEEE) || defined (__ARM_FP16_FORMAT_ALTERNATIVE) +__extension__ extern __inline void +__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) +vst1_f16_x2 (float16_t * __a, float16x4x2_t __b) +{ + union { float16x4x2_t __i; __builtin_neon_ti __o; } __bu = { __b }; + __builtin_neon_vst1_x2v4hf (__a, __bu.__o); +} +#endif + +__extension__ extern __inline void +__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) +vst1_f32_x2 (float32_t * __a, float32x2x2_t __b) +{ + union { float32x2x2_t __i; __builtin_neon_ti __o; } __bu = { __b }; + __builtin_neon_vst1_x2v2sf ((__builtin_neon_sf *) __a, __bu.__o); +} + +#if defined (__ARM_FP16_FORMAT_IEEE) || defined (__ARM_FP16_FORMAT_ALTERNATIVE) +__extension__ extern __inline void +__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) +vst1_f16_x3 (float16_t * __a, float16x4x3_t __b) +{ + union { float16x4x3_t __i; __builtin_neon_ei __o; } __bu = { __b }; + __builtin_neon_vst1_x3v4hf (__a, __bu.__o); +} +#endif + +__extension__ extern __inline void +__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) +vst1_f32_x3 (float32_t * __a, float32x2x3_t __b) +{ + union { float32x2x3_t __i; __builtin_neon_ei __o; } __bu = { __b }; + __builtin_neon_vst1_x3v2sf ((__builtin_neon_sf *) __a, __bu.__o); +} + +#if defined (__ARM_FP16_FORMAT_IEEE) || defined (__ARM_FP16_FORMAT_ALTERNATIVE) +__extension__ extern __inline void +__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) +vst1_f16_x4 (float16_t * __a, float16x4x4_t __b) +{ + union { float16x4x4_t __i; __builtin_neon_oi __o; } __bu = { __b }; + __builtin_neon_vst1_x4v4hf (__a, __bu.__o); +} +#endif + +__extension__ extern __inline void +__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) +vst1_f32_x4 (float32_t * __a, float32x2x4_t __b) +{ + union { float32x2x4_t __i; __builtin_neon_oi __o; } __bu = { __b }; + __builtin_neon_vst1_x4v2sf ((__builtin_neon_sf *) __a, __bu.__o); +} + __extension__ extern __inline void __attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) vst1_u8 (uint8_t * __a, uint8x8_t __b) @@ -10960,6 +11944,102 @@ vst1_u64 (uint64_t * __a, uint64x1_t __b) __extension__ extern __inline void __attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) +vst1_u8_x2 (uint8_t * __a, uint8x8x2_t __b) +{ + union { uint8x8x2_t __i; __builtin_neon_ti __o; } __bu = { __b }; + __builtin_neon_vst1_x2v8qi ((__builtin_neon_qi *) __a, __bu.__o); +} + +__extension__ extern __inline void +__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) +vst1_u16_x2 (uint16_t * __a, uint16x4x2_t __b) +{ + union { uint16x4x2_t __i; __builtin_neon_ti __o; } __bu = { __b }; + __builtin_neon_vst1_x2v4hi ((__builtin_neon_hi *) __a, __bu.__o); +} + +__extension__ extern __inline void +__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) +vst1_u32_x2 (uint32_t * __a, uint32x2x2_t __b) +{ + union { uint32x2x2_t __i; __builtin_neon_ti __o; } __bu = { __b }; + __builtin_neon_vst1_x2v2si ((__builtin_neon_si *) __a, __bu.__o); +} + +__extension__ extern __inline void +__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) +vst1_u64_x2 (uint64_t * __a, uint64x1x2_t __b) +{ + union { uint64x1x2_t __i; __builtin_neon_ti __o; } __bu = { __b }; + __builtin_neon_vst1_x2di ((__builtin_neon_di *) __a, __bu.__o); +} + +__extension__ extern __inline void +__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) +vst1_u8_x3 (uint8_t * __a, uint8x8x3_t __b) +{ + union { uint8x8x3_t __i; __builtin_neon_ei __o; } __bu = { __b }; + __builtin_neon_vst1_x3v8qi ((__builtin_neon_qi *) __a, __bu.__o); +} + +__extension__ extern __inline void +__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) +vst1_u16_x3 (uint16_t * __a, uint16x4x3_t __b) +{ + union { uint16x4x3_t __i; __builtin_neon_ei __o; } __bu = { __b }; + __builtin_neon_vst1_x3v4hi ((__builtin_neon_hi *) __a, __bu.__o); +} + +__extension__ extern __inline void +__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) +vst1_u32_x3 (uint32_t * __a, uint32x2x3_t __b) +{ + union { uint32x2x3_t __i; __builtin_neon_ei __o; } __bu = { __b }; + __builtin_neon_vst1_x3v2si ((__builtin_neon_si *) __a, __bu.__o); +} + +__extension__ extern __inline void +__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) +vst1_u64_x3 (uint64_t * __a, uint64x1x3_t __b) +{ + union { uint64x1x3_t __i; __builtin_neon_ei __o; } __bu = { __b }; + __builtin_neon_vst1_x3di ((__builtin_neon_di *) __a, __bu.__o); +} + +__extension__ extern __inline void +__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) +vst1_u8_x4 (uint8_t * __a, uint8x8x4_t __b) +{ + union { uint8x8x4_t __i; __builtin_neon_oi __o; } __bu = { __b }; + __builtin_neon_vst1_x4v8qi ((__builtin_neon_qi *) __a, __bu.__o); +} + +__extension__ extern __inline void +__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) +vst1_u16_x4 (uint16_t * __a, uint16x4x4_t __b) +{ + union { uint16x4x4_t __i; __builtin_neon_oi __o; } __bu = { __b }; + __builtin_neon_vst1_x4v4hi ((__builtin_neon_hi *) __a, __bu.__o); +} + +__extension__ extern __inline void +__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) +vst1_u32_x4 (uint32_t * __a, uint32x2x4_t __b) +{ + union { uint32x2x4_t __i; __builtin_neon_oi __o; } __bu = { __b }; + __builtin_neon_vst1_x4v2si ((__builtin_neon_si *) __a, __bu.__o); +} + +__extension__ extern __inline void +__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) +vst1_u64_x4 (uint64_t * __a, uint64x1x4_t __b) +{ + union { uint64x1x4_t __i; __builtin_neon_oi __o; } __bu = { __b }; + __builtin_neon_vst1_x4di ((__builtin_neon_di *) __a, __bu.__o); +} + +__extension__ extern __inline void +__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) vst1_p8 (poly8_t * __a, poly8x8_t __b) { __builtin_neon_vst1v8qi ((__builtin_neon_qi *) __a, (int8x8_t) __b); @@ -10972,6 +12052,54 @@ vst1_p16 (poly16_t * __a, poly16x4_t __b) __builtin_neon_vst1v4hi ((__builtin_neon_hi *) __a, (int16x4_t) __b); } +__extension__ extern __inline void +__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) +vst1_p8_x2 (poly8_t * __a, poly8x8x2_t __b) +{ + union { poly8x8x2_t __i; __builtin_neon_ti __o; } __bu = { __b }; + __builtin_neon_vst1_x2v8qi ((__builtin_neon_qi *) __a, __bu.__o); +} + +__extension__ extern __inline void +__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) +vst1_p16_x2 (poly16_t * __a, poly16x4x2_t __b) +{ + union { poly16x4x2_t __i; __builtin_neon_ti __o; } __bu = { __b }; + __builtin_neon_vst1_x2v4hi ((__builtin_neon_hi *) __a, __bu.__o); +} + +__extension__ extern __inline void +__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) +vst1_p8_x3 (poly8_t * __a, poly8x8x3_t __b) +{ + union { poly8x8x3_t __i; __builtin_neon_ei __o; } __bu = { __b }; + __builtin_neon_vst1_x3v8qi ((__builtin_neon_qi *) __a, __bu.__o); +} + +__extension__ extern __inline void +__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) +vst1_p16_x3 (poly16_t * __a, poly16x4x3_t __b) +{ + union { poly16x4x3_t __i; __builtin_neon_ei __o; } __bu = { __b }; + __builtin_neon_vst1_x3v4hi ((__builtin_neon_hi *) __a, __bu.__o); +} + +__extension__ extern __inline void +__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) +vst1_p8_x4 (poly8_t * __a, poly8x8x4_t __b) +{ + union { poly8x8x4_t __i; __builtin_neon_oi __o; } __bu = { __b }; + __builtin_neon_vst1_x4v8qi ((__builtin_neon_qi *) __a, __bu.__o); +} + +__extension__ extern __inline void +__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) +vst1_p16_x4 (poly16_t * __a, poly16x4x4_t __b) +{ + union { poly16x4x4_t __i; __builtin_neon_oi __o; } __bu = { __b }; + __builtin_neon_vst1_x4v4hi ((__builtin_neon_hi *) __a, __bu.__o); +} + #pragma GCC push_options #pragma GCC target ("fpu=crypto-neon-fp-armv8") __extension__ extern __inline void @@ -10981,6 +12109,30 @@ vst1q_p64 (poly64_t * __a, poly64x2_t __b) __builtin_neon_vst1v2di ((__builtin_neon_di *) __a, (int64x2_t) __b); } +__extension__ extern __inline void +__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) +vst1q_p64_x2 (poly64_t * __a, poly64x2x2_t __b) +{ + union { poly64x2x2_t __i; __builtin_neon_oi __o; } __bu = { __b }; + __builtin_neon_vst1q_x2v2di ((__builtin_neon_di *) __a, __bu.__o); +} + +__extension__ extern __inline void +__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) +vst1q_p64_x3 (poly64_t * __a, poly64x2x3_t __b) +{ + union { poly64x2x3_t __i; __builtin_neon_ci __o; } __bu = { __b }; + __builtin_neon_vst1q_x3v2di ((__builtin_neon_di *) __a, __bu.__o); +} + +__extension__ extern __inline void +__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) +vst1q_p64_x4 (poly64_t * __a, poly64x2x4_t __b) +{ + union { poly64x2x4_t __i; __builtin_neon_xi __o; } __bu = { __b }; + __builtin_neon_vst1q_x4v2di ((__builtin_neon_di *) __a, __bu.__o); +} + #pragma GCC pop_options __extension__ extern __inline void __attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) @@ -11026,6 +12178,60 @@ vst1q_f32 (float32_t * __a, float32x4_t __b) __builtin_neon_vst1v4sf ((__builtin_neon_sf *) __a, __b); } +#if defined (__ARM_FP16_FORMAT_IEEE) || defined (__ARM_FP16_FORMAT_ALTERNATIVE) +__extension__ extern __inline void +__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) +vst1q_f16_x2 (float16_t * __a, float16x8x2_t __b) +{ + union { float16x8x2_t __i; __builtin_neon_oi __o; } __bu = { __b }; + __builtin_neon_vst1q_x2v8hf (__a, __bu.__o); +} +#endif + +__extension__ extern __inline void +__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) +vst1q_f32_x2 (float32_t * __a, float32x4x2_t __b) +{ + union { float32x4x2_t __i; __builtin_neon_oi __o; } __bu = { __b }; + __builtin_neon_vst1q_x2v4sf (__a, __bu.__o); +} + +#if defined (__ARM_FP16_FORMAT_IEEE) || defined (__ARM_FP16_FORMAT_ALTERNATIVE) +__extension__ extern __inline void +__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) +vst1q_f16_x3 (float16_t * __a, float16x8x3_t __b) +{ + union { float16x8x3_t __i; __builtin_neon_ci __o; } __bu = { __b }; + __builtin_neon_vst1q_x3v8hf (__a, __bu.__o); +} +#endif + +__extension__ extern __inline void +__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) +vst1q_f32_x3 (float32_t * __a, float32x4x3_t __b) +{ + union { float32x4x3_t __i; __builtin_neon_ci __o; } __bu = { __b }; + __builtin_neon_vst1q_x3v4sf (__a, __bu.__o); +} + +#if defined (__ARM_FP16_FORMAT_IEEE) || defined (__ARM_FP16_FORMAT_ALTERNATIVE) +__extension__ extern __inline void +__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) +vst1q_f16_x4 (float16_t * __a, float16x8x4_t __b) +{ + union { float16x8x4_t __i; __builtin_neon_xi __o; } __bu = { __b }; + __builtin_neon_vst1q_x4v8hf (__a, __bu.__o); +} +#endif + +__extension__ extern __inline void +__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) +vst1q_f32_x4 (float32_t * __a, float32x4x4_t __b) +{ + union { float32x4x4_t __i; __builtin_neon_xi __o; } __bu = { __b }; + __builtin_neon_vst1q_x4v4sf (__a, __bu.__o); +} + __extension__ extern __inline void __attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) vst1q_u8 (uint8_t * __a, uint8x16_t __b) @@ -11056,6 +12262,102 @@ vst1q_u64 (uint64_t * __a, uint64x2_t __b) __extension__ extern __inline void __attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) +vst1q_u8_x2 (uint8_t * __a, uint8x16x2_t __b) +{ + union { uint8x16x2_t __i; __builtin_neon_oi __o; } __bu = { __b }; + __builtin_neon_vst1q_x2v16qi ((__builtin_neon_qi *) __a, __bu.__o); +} + +__extension__ extern __inline void +__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) +vst1q_u16_x2 (uint16_t * __a, uint16x8x2_t __b) +{ + union { uint16x8x2_t __i; __builtin_neon_oi __o; } __bu = { __b }; + __builtin_neon_vst1q_x2v8hi ((__builtin_neon_hi *) __a, __bu.__o); +} + +__extension__ extern __inline void +__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) +vst1q_u32_x2 (uint32_t * __a, uint32x4x2_t __b) +{ + union { uint32x4x2_t __i; __builtin_neon_oi __o; } __bu = { __b }; + __builtin_neon_vst1q_x2v4si ((__builtin_neon_si *) __a, __bu.__o); +} + +__extension__ extern __inline void +__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) +vst1q_u64_x2 (uint64_t * __a, uint64x2x2_t __b) +{ + union { uint64x2x2_t __i; __builtin_neon_oi __o; } __bu = { __b }; + __builtin_neon_vst1q_x2v2di ((__builtin_neon_di *) __a, __bu.__o); +} + +__extension__ extern __inline void +__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) +vst1q_u8_x3 (uint8_t * __a, uint8x16x3_t __b) +{ + union { uint8x16x3_t __i; __builtin_neon_ci __o; } __bu = { __b }; + __builtin_neon_vst1q_x3v16qi ((__builtin_neon_qi *) __a, __bu.__o); +} + +__extension__ extern __inline void +__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) +vst1q_u16_x3 (uint16_t * __a, uint16x8x3_t __b) +{ + union { uint16x8x3_t __i; __builtin_neon_ci __o; } __bu = { __b }; + __builtin_neon_vst1q_x3v8hi ((__builtin_neon_hi *) __a, __bu.__o); +} + +__extension__ extern __inline void +__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) +vst1q_u32_x3 (uint32_t * __a, uint32x4x3_t __b) +{ + union { uint32x4x3_t __i; __builtin_neon_ci __o; } __bu = { __b }; + __builtin_neon_vst1q_x3v4si ((__builtin_neon_si *) __a, __bu.__o); +} + +__extension__ extern __inline void +__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) +vst1q_u64_x3 (uint64_t * __a, uint64x2x3_t __b) +{ + union { uint64x2x3_t __i; __builtin_neon_ci __o; } __bu = { __b }; + __builtin_neon_vst1q_x3v2di ((__builtin_neon_di *) __a, __bu.__o); +} + +__extension__ extern __inline void +__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) +vst1q_u8_x4 (uint8_t * __a, uint8x16x4_t __b) +{ + union { uint8x16x4_t __i; __builtin_neon_xi __o; } __bu = { __b }; + __builtin_neon_vst1q_x4v16qi ((__builtin_neon_qi *) __a, __bu.__o); +} + +__extension__ extern __inline void +__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) +vst1q_u16_x4 (uint16_t * __a, uint16x8x4_t __b) +{ + union { uint16x8x4_t __i; __builtin_neon_xi __o; } __bu = { __b }; + __builtin_neon_vst1q_x4v8hi ((__builtin_neon_hi *) __a, __bu.__o); +} + +__extension__ extern __inline void +__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) +vst1q_u32_x4 (uint32_t * __a, uint32x4x4_t __b) +{ + union { uint32x4x4_t __i; __builtin_neon_xi __o; } __bu = { __b }; + __builtin_neon_vst1q_x4v4si ((__builtin_neon_si *) __a, __bu.__o); +} + +__extension__ extern __inline void +__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) +vst1q_u64_x4 (uint64_t * __a, uint64x2x4_t __b) +{ + union { uint64x2x4_t __i; __builtin_neon_xi __o; } __bu = { __b }; + __builtin_neon_vst1q_x4v2di ((__builtin_neon_di *) __a, __bu.__o); +} + +__extension__ extern __inline void +__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) vst1q_p8 (poly8_t * __a, poly8x16_t __b) { __builtin_neon_vst1v16qi ((__builtin_neon_qi *) __a, (int8x16_t) __b); @@ -11070,6 +12372,54 @@ vst1q_p16 (poly16_t * __a, poly16x8_t __b) __extension__ extern __inline void __attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) +vst1q_p8_x2 (poly8_t * __a, poly8x16x2_t __b) +{ + union { poly8x16x2_t __i; __builtin_neon_oi __o; } __bu = { __b }; + __builtin_neon_vst1q_x2v16qi ((__builtin_neon_qi *) __a, __bu.__o); +} + +__extension__ extern __inline void +__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) +vst1q_p16_x2 (poly16_t * __a, poly16x8x2_t __b) +{ + union { poly16x8x2_t __i; __builtin_neon_oi __o; } __bu = { __b }; + __builtin_neon_vst1q_x2v8hi ((__builtin_neon_hi *) __a, __bu.__o); +} + +__extension__ extern __inline void +__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) +vst1q_p8_x3 (poly8_t * __a, poly8x16x3_t __b) +{ + union { poly8x16x3_t __i; __builtin_neon_ci __o; } __bu = { __b }; + __builtin_neon_vst1q_x3v16qi ((__builtin_neon_qi *) __a, __bu.__o); +} + +__extension__ extern __inline void +__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) +vst1q_p16_x3 (poly16_t * __a, poly16x8x3_t __b) +{ + union { poly16x8x3_t __i; __builtin_neon_ci __o; } __bu = { __b }; + __builtin_neon_vst1q_x3v8hi ((__builtin_neon_hi *) __a, __bu.__o); +} + +__extension__ extern __inline void +__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) +vst1q_p8_x4 (poly8_t * __a, poly8x16x4_t __b) +{ + union { poly8x16x4_t __i; __builtin_neon_xi __o; } __bu = { __b }; + __builtin_neon_vst1q_x4v16qi ((__builtin_neon_qi *) __a, __bu.__o); +} + +__extension__ extern __inline void +__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) +vst1q_p16_x4 (poly16_t * __a, poly16x8x4_t __b) +{ + union { poly16x8x4_t __i; __builtin_neon_xi __o; } __bu = { __b }; + __builtin_neon_vst1q_x4v8hi ((__builtin_neon_hi *) __a, __bu.__o); +} + +__extension__ extern __inline void +__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) vst1_lane_s8 (int8_t * __a, int8x8_t __b, const int __c) { __builtin_neon_vst1_lanev8qi ((__builtin_neon_qi *) __a, __b, __c); @@ -19715,12 +21065,60 @@ vst1_bf16 (bfloat16_t * __a, bfloat16x4_t __b) __extension__ extern __inline void __attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) +vst1_bf16_x2 (bfloat16_t * __a, bfloat16x4x2_t __b) +{ + union { bfloat16x4x2_t __i; __builtin_neon_ti __o; } __bu = { __b }; + __builtin_neon_vst1_x2v4bf ((__builtin_neon_bf *) __a, __bu.__o); +} + +__extension__ extern __inline void +__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) +vst1_bf16_x3 (bfloat16_t * __a, bfloat16x4x3_t __b) +{ + union { bfloat16x4x3_t __i; __builtin_neon_ei __o; } __bu = { __b }; + __builtin_neon_vst1_x3v4bf ((__builtin_neon_bf *) __a, __bu.__o); +} + +__extension__ extern __inline void +__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) +vst1_bf16_x4 (bfloat16_t * __a, bfloat16x4x4_t __b) +{ + union { bfloat16x4x4_t __i; __builtin_neon_oi __o; } __bu = { __b }; + __builtin_neon_vst1_x4v4bf ((__builtin_neon_bf *) __a, __bu.__o); +} + +__extension__ extern __inline void +__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) vst1q_bf16 (bfloat16_t * __a, bfloat16x8_t __b) { __builtin_neon_vst1v8bf (__a, __b); } __extension__ extern __inline void +__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) +vst1q_bf16_x2 (bfloat16_t * __a, bfloat16x8x2_t __b) +{ + union { bfloat16x8x2_t __i; __builtin_neon_oi __o; } __bu = { __b }; + __builtin_neon_vst1q_x2v8bf (__a, __bu.__o); +} + +__extension__ extern __inline void +__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) +vst1q_bf16_x3 (bfloat16_t * __a, bfloat16x8x3_t __b) +{ + union { bfloat16x8x3_t __i; __builtin_neon_ci __o; } __bu = { __b }; + __builtin_neon_vst1q_x3v8bf (__a, __bu.__o); +} + +__extension__ extern __inline void +__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) +vst1q_bf16_x4 (bfloat16_t * __a, bfloat16x8x4_t __b) +{ + union { bfloat16x8x4_t __i; __builtin_neon_xi __o; } __bu = { __b }; + __builtin_neon_vst1q_x4v8bf (__a, __bu.__o); +} + +__extension__ extern __inline void __attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) vst2_bf16 (bfloat16_t * __ptr, bfloat16x4x2_t __val) { @@ -19775,6 +21173,33 @@ vld1_bf16 (bfloat16_t const * __ptr) return __builtin_neon_vld1v4bf (__ptr); } +__extension__ extern __inline bfloat16x4x2_t +__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) +vld1_bf16_x2 (const bfloat16_t * __ptr) +{ + union { bfloat16x4x2_t __i; __builtin_neon_ti __o; } __rv; + __rv.__o = __builtin_neon_vld1_x2v4bf ((const __builtin_neon_bf *) __ptr); + return __rv.__i; +} + +__extension__ extern __inline bfloat16x4x3_t +__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) +vld1_bf16_x3 (const bfloat16_t * __ptr) +{ + union { bfloat16x4x3_t __i; __builtin_neon_ei __o; } __rv; + __rv.__o = __builtin_neon_vld1_x3v4bf ((const __builtin_neon_bf *) __ptr); + return __rv.__i; +} + +__extension__ extern __inline bfloat16x4x4_t +__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) +vld1_bf16_x4 (const bfloat16_t * __ptr) +{ + union { bfloat16x4x4_t __i; __builtin_neon_oi __o; } __rv; + __rv.__o = __builtin_neon_vld1_x4v4bf ((const __builtin_neon_bf *) __ptr); + return __rv.__i; +} + __extension__ extern __inline bfloat16x8_t __attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) vld1q_bf16 (const bfloat16_t * __ptr) @@ -19782,6 +21207,33 @@ vld1q_bf16 (const bfloat16_t * __ptr) return __builtin_neon_vld1v8bf (__ptr); } +__extension__ extern __inline bfloat16x8x2_t +__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) +vld1q_bf16_x2 (const bfloat16_t * __ptr) +{ + union { bfloat16x8x2_t __i; __builtin_neon_oi __o; } __rv; + __rv.__o = __builtin_neon_vld1q_x2v8bf ((const __builtin_neon_bf *) __ptr); + return __rv.__i; +} + +__extension__ extern __inline bfloat16x8x3_t +__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) +vld1q_bf16_x3 (const bfloat16_t * __ptr) +{ + union { bfloat16x8x3_t __i; __builtin_neon_oi __o; } __rv; + __rv.__o = __builtin_neon_vld1q_x3v8bf ((const __builtin_neon_bf *) __ptr); + return __rv.__i; +} + +__extension__ extern __inline bfloat16x8x4_t +__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) +vld1q_bf16_x4 (const bfloat16_t * __ptr) +{ + union { bfloat16x8x4_t __i; __builtin_neon_xi __o; } __rv; + __rv.__o = __builtin_neon_vld1q_x4v8bf ((const __builtin_neon_bf *) __ptr); + return __rv.__i; +} + __extension__ extern __inline bfloat16x4x2_t __attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) vld2_bf16 (bfloat16_t const * __ptr) diff --git a/gcc/config/arm/arm_neon_builtins.def b/gcc/config/arm/arm_neon_builtins.def index 9cdd5e5..0c5d40b 100644 --- a/gcc/config/arm/arm_neon_builtins.def +++ b/gcc/config/arm/arm_neon_builtins.def @@ -301,6 +301,12 @@ VAR1 (TERNOP, vtbx4, v8qi) VAR13 (LOAD1, vld1, v8qi, v4hi, v4hf, v2si, v2sf, v16qi, v8hi, v8hf, v4si, v4sf, v2di, v4bf, v8bf) +VAR7 (LOAD1, vld1_x2, v8qi, v4hi, v2si, di, v4hf, v2sf, v4bf) +VAR7 (LOAD1, vld1q_x2, v16qi, v8hi, v4si, v2di, v8hf, v4sf, v8bf) +VAR7 (LOAD1, vld1_x3, v8qi, v4hi, v2si, di, v4hf, v2sf, v4bf) +VAR7 (LOAD1, vld1q_x3, v16qi, v8hi, v4si, v2di, v8hf, v4sf, v8bf) +VAR7 (LOAD1, vld1_x4, v8qi, v4hi, v2si, di, v4hf, v2sf, v4bf) +VAR7 (LOAD1, vld1q_x4, v16qi, v8hi, v4si, v2di, v8hf, v4sf, v8bf) VAR12 (LOAD1LANE, vld1_lane, v8qi, v4hi, v2si, v2sf, di, v16qi, v8hi, v4si, v4sf, v2di, v4bf, v8bf) VAR10 (LOAD1, vld1_dup, @@ -308,6 +314,12 @@ VAR10 (LOAD1, vld1_dup, VAR14 (STORE1, vst1, v8qi, v4hi, v4hf, v2si, v2sf, di, v16qi, v8hi, v8hf, v4si, v4sf, v2di, v4bf, v8bf) +VAR7 (STORE1, vst1_x2, v8qi, v4hi, v2si, di, v4hf, v2sf, v4bf) +VAR7 (STORE1, vst1q_x2, v16qi, v8hi, v4si, v2di, v8hf, v4sf, v8bf) +VAR7 (STORE1, vst1_x3, v8qi, v4hi, v2si, di, v4hf, v2sf, v4bf) +VAR7 (STORE1, vst1q_x3, v16qi, v8hi, v4si, v2di, v8hf, v4sf, v8bf) +VAR7 (STORE1, vst1_x4, v8qi, v4hi, v2si, di, v4hf, v2sf, v4bf) +VAR7 (STORE1, vst1q_x4, v16qi, v8hi, v4si, v2di, v8hf, v4sf, v8bf) VAR14 (STORE1LANE, vst1_lane, v8qi, v4hi, v4hf, v2si, v2sf, di, v16qi, v8hi, v8hf, v4si, v4sf, v2di, v4bf, v8bf) VAR13 (LOAD1, vld2, diff --git a/gcc/config/arm/iterators.md b/gcc/config/arm/iterators.md index d3ec0ad..547d87f 100644 --- a/gcc/config/arm/iterators.md +++ b/gcc/config/arm/iterators.md @@ -141,6 +141,9 @@ ;; Opaque structure types used in table lookups (except vtbl1/vtbx1). (define_mode_iterator VTAB [TI EI OI]) +;; Opaque structure types for x2 variants of VSTR1/VSTR1Q or VLD1/VLD1Q. +(define_mode_iterator VMEMX2 [TI OI]) + ;; Widenable modes. (define_mode_iterator VW [V8QI V4HI V2SI]) @@ -1533,6 +1536,9 @@ ;; vtbl<n> suffix for NEON vector modes. (define_mode_attr VTAB_n [(TI "2") (EI "3") (OI "4")]) +;; Suffix for x2 variants of vld1 and vst1. +(define_mode_attr VMEMX2_q [(TI "") (OI "q")]) + ;; fp16 or bf16 marker for 16-bit float modes. (define_mode_attr fporbf [(HF "fp16") (BF "bf16")]) diff --git a/gcc/config/arm/neon.md b/gcc/config/arm/neon.md index bb6e28f..17c90f4 100644 --- a/gcc/config/arm/neon.md +++ b/gcc/config/arm/neon.md @@ -5006,6 +5006,131 @@ if (BYTES_BIG_ENDIAN) [(set_attr "type" "neon_load1_1reg<q>")] ) +(define_insn "neon_vld1<VMEMX2_q>_x2<VDQX:mode>" + [(set (match_operand:VMEMX2 0 "s_register_operand" "=w") + (unspec:VMEMX2 [(match_operand:VMEMX2 1 "neon_struct_operand" "Um") + (unspec:VDQX [(const_int 0)] UNSPEC_VSTRUCTDUMMY)] + UNSPEC_VLD1))] + "TARGET_NEON" + "vld1.<V_sz_elem>\t%h0, %A1" + [(set_attr "type" "neon_load1_2reg<q>")] +) + +(define_insn "neon_vld1_x3<mode>" + [(set (match_operand:EI 0 "s_register_operand" "=w") + (unspec:EI [(match_operand:EI 1 "neon_struct_operand" "Um") + (unspec:VDQX [(const_int 0)] UNSPEC_VSTRUCTDUMMY)] + UNSPEC_VLD1))] + "TARGET_NEON" + "vld1.<V_sz_elem>\t%h0, %A1" + [(set_attr "type" "neon_load1_3reg<q>")] +) + +(define_expand "neon_vld1q_x3<mode>" + [(match_operand:CI 0 "s_register_operand") + (match_operand:CI 1 "neon_struct_operand") + (unspec:VQXBF [(const_int 0)] UNSPEC_VSTRUCTDUMMY)] + "TARGET_NEON" +{ + rtx mem = adjust_address (operands[1], EImode, 0); + emit_insn (gen_neon_vld1x3qa<mode> (operands[0], mem)); + mem = adjust_address (mem, EImode, GET_MODE_SIZE (EImode)); + emit_insn (gen_neon_vld1x3qb<mode> (operands[0], mem, operands[0])); + DONE; +}) + +(define_insn "neon_vld1x3qa<mode>" + [(set (match_operand:CI 0 "s_register_operand" "=w") + (unspec:CI [(match_operand:EI 1 "neon_struct_operand" "Um") + (unspec:VQXBF [(const_int 0)] UNSPEC_VSTRUCTDUMMY)] + UNSPEC_VLD1X3A))] + "TARGET_NEON" +{ + rtx ops[2]; + ops[0] = gen_rtx_REG (EImode, REGNO (operands[0])); + ops[1] = operands[1]; + + output_asm_insn ("vld1.<V_sz_elem>\t%h0, %A1", ops); + return ""; +} + [(set_attr "type" "neon_load1_3reg<q>")] +) + +(define_insn "neon_vld1x3qb<mode>" + [(set (match_operand:CI 0 "s_register_operand" "=w") + (unspec:CI [(match_operand:EI 1 "neon_struct_operand" "Um") + (match_operand:CI 2 "s_register_operand" "0") + (unspec:VQXBF [(const_int 0)] UNSPEC_VSTRUCTDUMMY)] + UNSPEC_VLD1X3B))] + "TARGET_NEON" +{ + rtx ops[2]; + ops[0] = gen_rtx_REG (EImode, REGNO (operands[0]) + 6); + ops[1] = operands[1]; + + output_asm_insn ("vld1.<V_sz_elem>\t%h0, %A1", ops); + return ""; +} + [(set_attr "type" "neon_load1_3reg<q>")] +) + +(define_insn "neon_vld1_x4<mode>" + [(set (match_operand:OI 0 "s_register_operand" "=w") + (unspec:OI [(match_operand:OI 1 "neon_struct_operand" "Um") + (unspec:VDQX [(const_int 0)] UNSPEC_VSTRUCTDUMMY)] + UNSPEC_VLD1))] + "TARGET_NEON" + "vld1.<V_sz_elem>\t%h0, %A1" + [(set_attr "type" "neon_load1_4reg<q>")] +) +(define_expand "neon_vld1q_x4<mode>" + [(match_operand:XI 0 "s_register_operand") + (match_operand:XI 1 "neon_struct_operand") + (unspec:VQXBF [(const_int 0)] UNSPEC_VSTRUCTDUMMY)] + "TARGET_NEON" +{ + rtx mem = adjust_address (operands[1], OImode, 0); + emit_insn (gen_neon_vld1x4qa<mode> (operands[0], mem)); + mem = adjust_address (mem, OImode, GET_MODE_SIZE (OImode)); + emit_insn (gen_neon_vld1x4qb<mode> (operands[0], mem, operands[0])); + DONE; +}) + +(define_insn "neon_vld1x4qa<mode>" + [(set (match_operand:XI 0 "s_register_operand" "=w") + (unspec:XI [(match_operand:OI 1 "neon_struct_operand" "Um") + (unspec:VQXBF [(const_int 0)] UNSPEC_VSTRUCTDUMMY)] + UNSPEC_VLD1X4A))] + "TARGET_NEON" +{ + rtx ops[2]; + ops[0] = gen_rtx_REG (OImode, REGNO (operands[0])); + ops[1] = operands[1]; + + output_asm_insn ("vld1.<V_sz_elem>\t%h0, %A1", ops); + return ""; +} + [(set_attr "type" "neon_load1_4reg<q>")] +) + +(define_insn "neon_vld1x4qb<mode>" + [(set (match_operand:XI 0 "s_register_operand" "=w") + (unspec:XI [(match_operand:OI 1 "neon_struct_operand" "Um") + (match_operand:XI 2 "s_register_operand" "0") + (unspec:VQXBF [(const_int 0)] UNSPEC_VSTRUCTDUMMY)] + UNSPEC_VLD1X4B))] + "TARGET_NEON" +{ + rtx ops[2]; + ops[0] = gen_rtx_REG (OImode, REGNO (operands[0]) + 8); + ops[1] = operands[1]; + + output_asm_insn ("vld1.<V_sz_elem>\t%h0, %A1", ops); + return ""; +} + [(set_attr "type" "neon_load1_4reg<q>")] +) + ;; The lane numbers in the RTL are in GCC lane order, having been flipped ;; in arm_expand_neon_args. The lane numbers are restored to architectural ;; lane order here. @@ -5115,6 +5240,130 @@ if (BYTES_BIG_ENDIAN) "vst1.<V_sz_elem>\t%h1, %A0" [(set_attr "type" "neon_store1_1reg<q>")]) +(define_insn "neon_vst1<VMEMX2_q>_x2<VDQX:mode>" + [(set (match_operand:VMEMX2 0 "neon_struct_operand" "=Um") + (unspec:VMEMX2 [(match_operand:VMEMX2 1 "s_register_operand" "w") + (unspec:VDQX [(const_int 0)] UNSPEC_VSTRUCTDUMMY)] + UNSPEC_VST1))] + "TARGET_NEON" + "vst1.<V_sz_elem>\t%h1, %A0" + [(set_attr "type" "neon_store1_2reg<q>")] +) + +(define_insn "neon_vst1_x3<mode>" + [(set (match_operand:EI 0 "neon_struct_operand" "=Um") + (unspec:EI [(match_operand:EI 1 "s_register_operand" "w") + (unspec:VDQX [(const_int 0)] UNSPEC_VSTRUCTDUMMY)] + UNSPEC_VST1))] + "TARGET_NEON" + "vst1.<V_sz_elem>\t%h1, %A0" + [(set_attr "type" "neon_store1_3reg<q>")] +) + +(define_expand "neon_vst1q_x3<mode>" + [(match_operand:CI 0 "neon_struct_operand") + (match_operand:CI 1 "s_register_operand") + (unspec:VDQX [(const_int 0)] UNSPEC_VSTRUCTDUMMY)] + "TARGET_NEON" +{ + rtx mem = adjust_address (operands[0], EImode, 0); + emit_insn (gen_neon_vst1x3qa<mode> (mem, operands[1])); + mem = adjust_address (mem, EImode, GET_MODE_SIZE (EImode)); + emit_insn (gen_neon_vst1x3qb<mode> (mem, operands[1])); + DONE; +}) + +(define_insn "neon_vst1x3qa<mode>" + [(set (match_operand:EI 0 "neon_struct_operand" "=Um") + (unspec:EI [(match_operand:CI 1 "s_register_operand" "w") + (unspec:VDQX [(const_int 0)] UNSPEC_VSTRUCTDUMMY)] + UNSPEC_VST1X3A))] + "TARGET_NEON" +{ + rtx ops[2]; + ops[0] = operands[0]; + ops[1] = gen_rtx_REG (EImode, REGNO (operands[1])); + + output_asm_insn ("vst1.<V_sz_elem>\t%h1, %A0", ops); + return ""; +} + [(set_attr "type" "neon_store1_3reg<q>")] +) + +(define_insn "neon_vst1x3qb<mode>" + [(set (match_operand:EI 0 "neon_struct_operand" "=Um") + (unspec:EI [(match_operand:CI 1 "s_register_operand" "w") + (unspec:VDQX [(const_int 0)] UNSPEC_VSTRUCTDUMMY)] + UNSPEC_VST1X3B))] + "TARGET_NEON" +{ + rtx ops[2]; + ops[0] = operands[0]; + ops[1] = gen_rtx_REG (EImode, REGNO (operands[1]) + 6); + + output_asm_insn ("vst1.<V_sz_elem>\t%h1, %A0", ops); + return ""; +} + [(set_attr "type" "neon_store1_3reg<q>")] +) + +(define_insn "neon_vst1_x4<mode>" + [(set (match_operand:OI 0 "neon_struct_operand" "=Um") + (unspec:OI [(match_operand:OI 1 "s_register_operand" "w") + (unspec:VDQX [(const_int 0)] UNSPEC_VSTRUCTDUMMY)] + UNSPEC_VST1))] + "TARGET_NEON" + "vst1.<V_sz_elem>\t%h1, %A0" + [(set_attr "type" "neon_store1_4reg<q>")] +) + +(define_expand "neon_vst1q_x4<mode>" + [(match_operand:XI 0 "neon_struct_operand") + (match_operand:XI 1 "s_register_operand") + (unspec:VQXBF [(const_int 0)] UNSPEC_VSTRUCTDUMMY)] + "TARGET_NEON" +{ + rtx mem = adjust_address (operands[0], OImode, 0); + emit_insn (gen_neon_vst1x4qa<mode> (mem, operands[1])); + mem = adjust_address (mem, OImode, GET_MODE_SIZE (OImode)); + emit_insn (gen_neon_vst1x4qb<mode> (mem, operands[1])); + DONE; +}) + +(define_insn "neon_vst1x4qa<mode>" + [(set (match_operand:OI 0 "neon_struct_operand" "=Um") + (unspec:OI [(match_operand:XI 1 "s_register_operand" "w") + (unspec:VQXBF [(const_int 0)] UNSPEC_VSTRUCTDUMMY)] + UNSPEC_VST1X4A))] + "TARGET_NEON" +{ + rtx ops[2]; + ops[0] = operands[0]; + ops[1] = gen_rtx_REG (OImode, REGNO (operands[1])); + + output_asm_insn ("vst1.<V_sz_elem>\t%h1, %A0", ops); + return ""; +} + [(set_attr "type" "neon_store1_4reg<q>")] +) + +(define_insn "neon_vst1x4qb<mode>" + [(set (match_operand:OI 0 "neon_struct_operand" "=Um") + (unspec:OI [(match_operand:XI 1 "s_register_operand" "w") + (unspec:VQXBF [(const_int 0)] UNSPEC_VSTRUCTDUMMY)] + UNSPEC_VST1X4B))] + "TARGET_NEON" +{ + rtx ops[2]; + ops[0] = operands[0]; + ops[1] = gen_rtx_REG (OImode, REGNO (operands[1]) + 8); + + output_asm_insn ("vst1.<V_sz_elem>\t%h1, %A0", ops); + return ""; +} + [(set_attr "type" "neon_store1_4reg<q>")] +) + ;; see comment on neon_vld1_lane for reason why the lane numbers are reversed ;; here on big endian targets. (define_insn "neon_vst1_lane<mode>" diff --git a/gcc/config/arm/unspecs.md b/gcc/config/arm/unspecs.md index 98082d2..b9db306 100644 --- a/gcc/config/arm/unspecs.md +++ b/gcc/config/arm/unspecs.md @@ -342,6 +342,10 @@ UNSPEC_VHSUB_S UNSPEC_VHSUB_U UNSPEC_VLD1 + UNSPEC_VLD1X3A + UNSPEC_VLD1X3B + UNSPEC_VLD1X4A + UNSPEC_VLD1X4B UNSPEC_VLD1_LANE UNSPEC_VLD2 UNSPEC_VLD2_DUP @@ -459,6 +463,10 @@ UNSPEC_VRSRA_U_N UNSPEC_VSRI UNSPEC_VST1 + UNSPEC_VST1X3A + UNSPEC_VST1X3B + UNSPEC_VST1X4A + UNSPEC_VST1X4B UNSPEC_VST1_LANE UNSPEC_VST2 UNSPEC_VST2_LANE diff --git a/gcc/config/avr/avr-arch.h b/gcc/config/avr/avr-arch.h index 03b3263..69e8db1 100644 --- a/gcc/config/avr/avr-arch.h +++ b/gcc/config/avr/avr-arch.h @@ -166,7 +166,35 @@ AVR_ISA_RCALL assume these instructions are not available and we set the built-in macro __AVR_HAVE_JMP_CALL__ accordingly. This macro is used to determine a rough estimate of flash size in libgcc, and AVR-LibC uses - this macro to determine vector sizes. */ + this macro to determine vector sizes. + +AVR_ISA_FLMAP + The device has the NVMCTRL_CTRLB.FLMAP bitfield. The value of FLMAP + determines which 32 KiB segment of the program memory (flash) is visible + in the RAM address space at 0x8000. + + If Binutils support emulations avrxmega2_flmap resp. avrxmega4_flmap + (PR31124), then the location of the .rodata section can be determined + by means of option -m[no-]rodata-in-ram. If .rodata is located in flash, + the user can chose which 32 KiB flash block is visible in RAM space by + means of defining symbol __flmap. + + The startup code from AVR-LibC initializes FLMAP according to __flmap + provided one of the avrxmega*_flmap emulations is used. If avrxmega2/4 + is used, then the startup code does not initialize FLMAP. + + __AVR_HAVE_FLMAP__ is a macro defined in device-specs and supposed to be + consumed by code that sets FLMAP, like the startup code for example. + The macro is defined when all of the following conditions are met: + * The device is AVR_ISA_FLMAP. + * It's not known at compile time / assembler time whether or not .rodata + will be located in flash or in RAM. This implies Binutils PR31124. + * The definition of the macro is independent of -m[no-]rodata-in-ram. + + AVR_ISA_FLMAP does not affect multilib layout or selection in any way. + + For details on which symbols are defined in which way depending on the + emulation, see <Binutils>/ld/scripttempl/avr.sc. */ enum avr_device_specific_features { @@ -175,9 +203,12 @@ enum avr_device_specific_features AVR_SHORT_SP = 0x2, /* Stack Pointer has 8 bits width. */ AVR_ERRATA_SKIP = 0x4, /* device has a core erratum. */ AVR_ISA_LDS = 0x8, /* whether LDS / STS is valid for all data in static - storage. Only useful for reduced Tiny. */ - AVR_ISA_RCALL = 0x10 /* Use RJMP / RCALL even though JMP / CALL - are available (-mshort-calls). */ + storage. Only useful for reduced Tiny. */ + AVR_ISA_RCALL = 0x10, /* Use RJMP / RCALL even though JMP / CALL + are available (-mshort-calls). */ + AVR_ISA_FLMAP = 0x20 /* Has NVMCTRL_CTRLB.FLMAP to select which 32 KiB + block of program memory is visible in the RAM + address space. */ }; /* Map architecture to its texinfo string. */ @@ -195,6 +226,7 @@ typedef struct extern const avr_arch_t avr_arch_types[]; extern const avr_arch_t *avr_arch; +extern const avr_arch_t *avr_get_parch (const char *mcu); extern const avr_mcu_t avr_mcu_types[]; diff --git a/gcc/config/avr/avr-devices.cc b/gcc/config/avr/avr-devices.cc index 627a7db..43d38eb 100644 --- a/gcc/config/avr/avr-devices.cc +++ b/gcc/config/avr/avr-devices.cc @@ -93,8 +93,8 @@ avr_texinfo[] = "``Enhanced'' devices with 3-byte PC, i.e.@: with more than 128@tie{}KiB " "of program memory." }, { ARCH_AVRTINY, - "``TINY'' Tiny core devices with 512@tie{}B up to 4@tie{}KiB of " - "program memory." }, + "``Reduced Tiny'' Tiny core devices with only 16 general purpose " + "registers and 512@tie{}B up to 4@tie{}KiB of program memory." }, { ARCH_AVRXMEGA2, "``XMEGA'' devices with more than 8@tie{}KiB and up to 64@tie{}KiB " "of program memory." }, @@ -153,4 +153,20 @@ avr_inform_core_architectures (void) free (archs); } + +/* When MCU names a core arch like "avr5", then return a pointer to the + respective entry in avr_arch_types[]. Otherwise, return NULL. */ + +const avr_arch_t * +avr_get_parch (const char *mcu) +{ + for (size_t i = 0; i < ARRAY_SIZE (avr_arch_types); ++i) + { + if (strcmp (mcu, avr_arch_types[i].name) == 0) + return & avr_arch_types[i]; + } + + return NULL; +} + #endif // IN_GEN_AVR_MMCU_TEXI diff --git a/gcc/config/avr/avr-mcus.def b/gcc/config/avr/avr-mcus.def index 87b5924..ecdf7fb 100644 --- a/gcc/config/avr/avr-mcus.def +++ b/gcc/config/avr/avr-mcus.def @@ -306,21 +306,21 @@ AVR_MCU ("atxmega16c4", ARCH_AVRXMEGA2, AVR_ISA_RMW, "__AVR_ATxmega16C4__" AVR_MCU ("atxmega32a4u", ARCH_AVRXMEGA2, AVR_ISA_RMW, "__AVR_ATxmega32A4U__", 0x2000, 0x0, 0x9000, 0) AVR_MCU ("atxmega32c4", ARCH_AVRXMEGA2, AVR_ISA_RMW, "__AVR_ATxmega32C4__", 0x2000, 0x0, 0x9000, 0) AVR_MCU ("atxmega32e5", ARCH_AVRXMEGA2, AVR_ISA_NONE, "__AVR_ATxmega32E5__", 0x2000, 0x0, 0x9000, 0) -AVR_MCU ("avr64da28", ARCH_AVRXMEGA2, AVR_ISA_NONE, "__AVR_AVR64DA28__", 0x6000, 0x0, 0x10000, 0) -AVR_MCU ("avr64da32", ARCH_AVRXMEGA2, AVR_ISA_NONE, "__AVR_AVR64DA32__", 0x6000, 0x0, 0x10000, 0) -AVR_MCU ("avr64da48", ARCH_AVRXMEGA2, AVR_ISA_NONE, "__AVR_AVR64DA48__", 0x6000, 0x0, 0x10000, 0) -AVR_MCU ("avr64da64", ARCH_AVRXMEGA2, AVR_ISA_NONE, "__AVR_AVR64DA64__", 0x6000, 0x0, 0x10000, 0) -AVR_MCU ("avr64db28", ARCH_AVRXMEGA2, AVR_ISA_NONE, "__AVR_AVR64DB28__", 0x6000, 0x0, 0x10000, 0) -AVR_MCU ("avr64db32", ARCH_AVRXMEGA2, AVR_ISA_NONE, "__AVR_AVR64DB32__", 0x6000, 0x0, 0x10000, 0) -AVR_MCU ("avr64db48", ARCH_AVRXMEGA2, AVR_ISA_NONE, "__AVR_AVR64DB48__", 0x6000, 0x0, 0x10000, 0) -AVR_MCU ("avr64db64", ARCH_AVRXMEGA2, AVR_ISA_NONE, "__AVR_AVR64DB64__", 0x6000, 0x0, 0x10000, 0) -AVR_MCU ("avr64dd14", ARCH_AVRXMEGA2, AVR_ISA_NONE, "__AVR_AVR64DD14__", 0x6000, 0x0, 0x10000, 0) -AVR_MCU ("avr64dd20", ARCH_AVRXMEGA2, AVR_ISA_NONE, "__AVR_AVR64DD20__", 0x6000, 0x0, 0x10000, 0) -AVR_MCU ("avr64dd28", ARCH_AVRXMEGA2, AVR_ISA_NONE, "__AVR_AVR64DD28__", 0x6000, 0x0, 0x10000, 0) -AVR_MCU ("avr64dd32", ARCH_AVRXMEGA2, AVR_ISA_NONE, "__AVR_AVR64DD32__", 0x6000, 0x0, 0x10000, 0) -AVR_MCU ("avr64ea28", ARCH_AVRXMEGA2, AVR_ISA_NONE, "__AVR_AVR64EA28__", 0x6800, 0x0, 0x10000, 0) -AVR_MCU ("avr64ea32", ARCH_AVRXMEGA2, AVR_ISA_NONE, "__AVR_AVR64EA32__", 0x6800, 0x0, 0x10000, 0) -AVR_MCU ("avr64ea48", ARCH_AVRXMEGA2, AVR_ISA_NONE, "__AVR_AVR64EA48__", 0x6800, 0x0, 0x10000, 0) +AVR_MCU ("avr64da28", ARCH_AVRXMEGA2, AVR_ISA_FLMAP, "__AVR_AVR64DA28__", 0x6000, 0x0, 0x10000, 0) +AVR_MCU ("avr64da32", ARCH_AVRXMEGA2, AVR_ISA_FLMAP, "__AVR_AVR64DA32__", 0x6000, 0x0, 0x10000, 0) +AVR_MCU ("avr64da48", ARCH_AVRXMEGA2, AVR_ISA_FLMAP, "__AVR_AVR64DA48__", 0x6000, 0x0, 0x10000, 0) +AVR_MCU ("avr64da64", ARCH_AVRXMEGA2, AVR_ISA_FLMAP, "__AVR_AVR64DA64__", 0x6000, 0x0, 0x10000, 0) +AVR_MCU ("avr64db28", ARCH_AVRXMEGA2, AVR_ISA_FLMAP, "__AVR_AVR64DB28__", 0x6000, 0x0, 0x10000, 0) +AVR_MCU ("avr64db32", ARCH_AVRXMEGA2, AVR_ISA_FLMAP, "__AVR_AVR64DB32__", 0x6000, 0x0, 0x10000, 0) +AVR_MCU ("avr64db48", ARCH_AVRXMEGA2, AVR_ISA_FLMAP, "__AVR_AVR64DB48__", 0x6000, 0x0, 0x10000, 0) +AVR_MCU ("avr64db64", ARCH_AVRXMEGA2, AVR_ISA_FLMAP, "__AVR_AVR64DB64__", 0x6000, 0x0, 0x10000, 0) +AVR_MCU ("avr64dd14", ARCH_AVRXMEGA2, AVR_ISA_FLMAP, "__AVR_AVR64DD14__", 0x6000, 0x0, 0x10000, 0) +AVR_MCU ("avr64dd20", ARCH_AVRXMEGA2, AVR_ISA_FLMAP, "__AVR_AVR64DD20__", 0x6000, 0x0, 0x10000, 0) +AVR_MCU ("avr64dd28", ARCH_AVRXMEGA2, AVR_ISA_FLMAP, "__AVR_AVR64DD28__", 0x6000, 0x0, 0x10000, 0) +AVR_MCU ("avr64dd32", ARCH_AVRXMEGA2, AVR_ISA_FLMAP, "__AVR_AVR64DD32__", 0x6000, 0x0, 0x10000, 0) +AVR_MCU ("avr64ea28", ARCH_AVRXMEGA2, AVR_ISA_FLMAP, "__AVR_AVR64EA28__", 0x6800, 0x0, 0x10000, 0) +AVR_MCU ("avr64ea32", ARCH_AVRXMEGA2, AVR_ISA_FLMAP, "__AVR_AVR64EA32__", 0x6800, 0x0, 0x10000, 0) +AVR_MCU ("avr64ea48", ARCH_AVRXMEGA2, AVR_ISA_FLMAP, "__AVR_AVR64EA48__", 0x6800, 0x0, 0x10000, 0) /* Xmega, Flash + RAM < 64K, flash visible in RAM address space */ AVR_MCU ("avrxmega3", ARCH_AVRXMEGA3, AVR_ISA_NONE, NULL, 0x3f00, 0x0, 0x8000, 0) AVR_MCU ("attiny202", ARCH_AVRXMEGA3, AVR_ISA_RCALL, "__AVR_ATtiny202__", 0x3f80, 0x0, 0x800, 0x8000) @@ -383,6 +383,16 @@ AVR_MCU ("avr32dd14", ARCH_AVRXMEGA3, AVR_ISA_NONE, "__AVR_AVR32DD14__", AVR_MCU ("avr32dd20", ARCH_AVRXMEGA3, AVR_ISA_NONE, "__AVR_AVR32DD20__", 0x7000, 0x0, 0x8000, 0x8000) AVR_MCU ("avr32dd28", ARCH_AVRXMEGA3, AVR_ISA_NONE, "__AVR_AVR32DD28__", 0x7000, 0x0, 0x8000, 0x8000) AVR_MCU ("avr32dd32", ARCH_AVRXMEGA3, AVR_ISA_NONE, "__AVR_AVR32DD32__", 0x7000, 0x0, 0x8000, 0x8000) +AVR_MCU ("avr16eb14", ARCH_AVRXMEGA3, AVR_ISA_NONE, "__AVR_AVR16EB14__", 0x7800, 0x0, 0x4000, 0x8000) +AVR_MCU ("avr16eb20", ARCH_AVRXMEGA3, AVR_ISA_NONE, "__AVR_AVR16EB20__", 0x7800, 0x0, 0x4000, 0x8000) +AVR_MCU ("avr16eb28", ARCH_AVRXMEGA3, AVR_ISA_NONE, "__AVR_AVR16EB28__", 0x7800, 0x0, 0x4000, 0x8000) +AVR_MCU ("avr16eb32", ARCH_AVRXMEGA3, AVR_ISA_NONE, "__AVR_AVR16EB32__", 0x7800, 0x0, 0x4000, 0x8000) +AVR_MCU ("avr16ea28", ARCH_AVRXMEGA3, AVR_ISA_NONE, "__AVR_AVR16EA28__", 0x7800, 0x0, 0x4000, 0x8000) +AVR_MCU ("avr16ea32", ARCH_AVRXMEGA3, AVR_ISA_NONE, "__AVR_AVR16EA32__", 0x7800, 0x0, 0x4000, 0x8000) +AVR_MCU ("avr16ea48", ARCH_AVRXMEGA3, AVR_ISA_NONE, "__AVR_AVR16EA48__", 0x7800, 0x0, 0x4000, 0x8000) +AVR_MCU ("avr32ea28", ARCH_AVRXMEGA3, AVR_ISA_NONE, "__AVR_AVR32EA28__", 0x7000, 0x0, 0x8000, 0x8000) +AVR_MCU ("avr32ea32", ARCH_AVRXMEGA3, AVR_ISA_NONE, "__AVR_AVR32EA32__", 0x7000, 0x0, 0x8000, 0x8000) +AVR_MCU ("avr32ea48", ARCH_AVRXMEGA3, AVR_ISA_NONE, "__AVR_AVR32EA48__", 0x7000, 0x0, 0x8000, 0x8000) /* Xmega, 64K < Flash <= 128K, RAM <= 64K */ AVR_MCU ("avrxmega4", ARCH_AVRXMEGA4, AVR_ISA_NONE, NULL, 0x2000, 0x0, 0x11000, 0) AVR_MCU ("atxmega64a3", ARCH_AVRXMEGA4, AVR_ISA_NONE, "__AVR_ATxmega64A3__", 0x2000, 0x0, 0x11000, 0) @@ -393,14 +403,14 @@ AVR_MCU ("atxmega64b1", ARCH_AVRXMEGA4, AVR_ISA_RMW, "__AVR_ATxmega64B1__" AVR_MCU ("atxmega64b3", ARCH_AVRXMEGA4, AVR_ISA_RMW, "__AVR_ATxmega64B3__", 0x2000, 0x0, 0x11000, 0) AVR_MCU ("atxmega64c3", ARCH_AVRXMEGA4, AVR_ISA_RMW, "__AVR_ATxmega64C3__", 0x2000, 0x0, 0x11000, 0) AVR_MCU ("atxmega64d4", ARCH_AVRXMEGA4, AVR_ISA_NONE, "__AVR_ATxmega64D4__", 0x2000, 0x0, 0x11000, 0) -AVR_MCU ("avr128da28", ARCH_AVRXMEGA4, AVR_ISA_NONE, "__AVR_AVR128DA28__", 0x4000, 0x0, 0x20000, 0) -AVR_MCU ("avr128da32", ARCH_AVRXMEGA4, AVR_ISA_NONE, "__AVR_AVR128DA32__", 0x4000, 0x0, 0x20000, 0) -AVR_MCU ("avr128da48", ARCH_AVRXMEGA4, AVR_ISA_NONE, "__AVR_AVR128DA48__", 0x4000, 0x0, 0x20000, 0) -AVR_MCU ("avr128da64", ARCH_AVRXMEGA4, AVR_ISA_NONE, "__AVR_AVR128DA64__", 0x4000, 0x0, 0x20000, 0) -AVR_MCU ("avr128db28", ARCH_AVRXMEGA4, AVR_ISA_NONE, "__AVR_AVR128DB28__", 0x4000, 0x0, 0x20000, 0) -AVR_MCU ("avr128db32", ARCH_AVRXMEGA4, AVR_ISA_NONE, "__AVR_AVR128DB32__", 0x4000, 0x0, 0x20000, 0) -AVR_MCU ("avr128db48", ARCH_AVRXMEGA4, AVR_ISA_NONE, "__AVR_AVR128DB48__", 0x4000, 0x0, 0x20000, 0) -AVR_MCU ("avr128db64", ARCH_AVRXMEGA4, AVR_ISA_NONE, "__AVR_AVR128DB64__", 0x4000, 0x0, 0x20000, 0) +AVR_MCU ("avr128da28", ARCH_AVRXMEGA4, AVR_ISA_FLMAP, "__AVR_AVR128DA28__", 0x4000, 0x0, 0x20000, 0) +AVR_MCU ("avr128da32", ARCH_AVRXMEGA4, AVR_ISA_FLMAP, "__AVR_AVR128DA32__", 0x4000, 0x0, 0x20000, 0) +AVR_MCU ("avr128da48", ARCH_AVRXMEGA4, AVR_ISA_FLMAP, "__AVR_AVR128DA48__", 0x4000, 0x0, 0x20000, 0) +AVR_MCU ("avr128da64", ARCH_AVRXMEGA4, AVR_ISA_FLMAP, "__AVR_AVR128DA64__", 0x4000, 0x0, 0x20000, 0) +AVR_MCU ("avr128db28", ARCH_AVRXMEGA4, AVR_ISA_FLMAP, "__AVR_AVR128DB28__", 0x4000, 0x0, 0x20000, 0) +AVR_MCU ("avr128db32", ARCH_AVRXMEGA4, AVR_ISA_FLMAP, "__AVR_AVR128DB32__", 0x4000, 0x0, 0x20000, 0) +AVR_MCU ("avr128db48", ARCH_AVRXMEGA4, AVR_ISA_FLMAP, "__AVR_AVR128DB48__", 0x4000, 0x0, 0x20000, 0) +AVR_MCU ("avr128db64", ARCH_AVRXMEGA4, AVR_ISA_FLMAP, "__AVR_AVR128DB64__", 0x4000, 0x0, 0x20000, 0) /* Xmega, 64K < Flash <= 128K, RAM > 64K */ AVR_MCU ("avrxmega5", ARCH_AVRXMEGA5, AVR_ISA_NONE, NULL, 0x2000, 0x0, 0x11000, 0) AVR_MCU ("atxmega64a1", ARCH_AVRXMEGA5, AVR_ISA_NONE, "__AVR_ATxmega64A1__", 0x2000, 0x0, 0x11000, 0) diff --git a/gcc/config/avr/avr.cc b/gcc/config/avr/avr.cc index 0cdd035..d77e1aad 100644 --- a/gcc/config/avr/avr.cc +++ b/gcc/config/avr/avr.cc @@ -220,6 +220,7 @@ static GTY(()) rtx xstring_e; /* Current architecture. */ const avr_arch_t *avr_arch; +enum avr_arch_id avr_arch_index; /* Unnamed sections associated to __attribute__((progmem)) aka. PROGMEM or to address space __flash* or __memx. Only used as singletons inside @@ -229,9 +230,10 @@ static GTY(()) section *progmem_section[ADDR_SPACE_COUNT]; /* Condition for insns/expanders from avr-dimode.md. */ bool avr_have_dimode = true; -/* To track if code will use .bss and/or .data. */ +/* To track if code will use .bss, .data, .rodata. */ bool avr_need_clear_bss_p = false; bool avr_need_copy_data_p = false; +bool avr_has_rodata_p = false; /* Transform UP into lowercase and write the result to LO. @@ -1059,6 +1061,7 @@ avr_set_core_architecture (void) && mcu->macro == NULL) { avr_arch = &avr_arch_types[mcu->arch_id]; + avr_arch_index = mcu->arch_id; if (avr_n_flash < 0) avr_n_flash = 1 + (mcu->flash_size - 1) / 0x10000; @@ -10388,8 +10391,8 @@ avr_handle_addr_attribute (tree *node, tree name, tree args, && (!tree_fits_shwi_p (arg) || ! IN_RANGE (TREE_INT_CST_LOW (arg), io_start, io_end))) { - warning_at (loc, OPT_Wattributes, "%qE attribute address out of " - "range 0x%x...0x%x", name, (int) io_start, (int) io_end); + warning_at (loc, OPT_Wattributes, "%qE attribute address out of range" + " 0x%x%s0x%x", name, (int) io_start, "...", (int) io_end); *no_add = true; } else @@ -10758,6 +10761,49 @@ avr_insert_attributes (tree node, tree *attributes) } } +#ifdef HAVE_LD_AVR_AVRXMEGA2_FLMAP +static const bool have_avrxmega2_flmap = true; +#else +static const bool have_avrxmega2_flmap = false; +#endif + +#ifdef HAVE_LD_AVR_AVRXMEGA4_FLMAP +static const bool have_avrxmega4_flmap = true; +#else +static const bool have_avrxmega4_flmap = false; +#endif + +#ifdef HAVE_LD_AVR_AVRXMEGA3_RODATA_IN_FLASH +static const bool have_avrxmega3_rodata_in_flash = true; +#else +static const bool have_avrxmega3_rodata_in_flash = false; +#endif + + +static bool +avr_rodata_in_flash_p () +{ + switch (avr_arch_index) + { + default: + break; + + case ARCH_AVRTINY: + return true; + + case ARCH_AVRXMEGA3: + return have_avrxmega3_rodata_in_flash; + + case ARCH_AVRXMEGA2: + return avr_flmap && have_avrxmega2_flmap && avr_rodata_in_ram != 1; + + case ARCH_AVRXMEGA4: + return avr_flmap && have_avrxmega4_flmap && avr_rodata_in_ram != 1; + } + + return false; +} + /* Implement `ASM_OUTPUT_ALIGNED_DECL_LOCAL'. */ /* Implement `ASM_OUTPUT_ALIGNED_DECL_COMMON'. */ @@ -10890,13 +10936,11 @@ avr_output_addr_attrib (tree decl, const char *name, static void avr_asm_init_sections (void) { - /* Override section callbacks to keep track of `avr_need_clear_bss_p' - resp. `avr_need_copy_data_p'. If flash is not mapped to RAM then - we have also to track .rodata because it is located in RAM then. */ + /* Override section callbacks to keep track of `avr_need_clear_bss_p', + `avr_need_copy_data_p' and `avr_has_rodata_p'. + Track also .rodata for the case when .rodata is located in RAM. */ -#if defined HAVE_LD_AVR_AVRXMEGA3_RODATA_IN_FLASH - if (avr_arch->flash_pm_offset == 0) -#endif + if (! avr_rodata_in_flash_p ()) readonly_data_section->unnamed.callback = avr_output_data_section_asm_op; data_section->unnamed.callback = avr_output_data_section_asm_op; bss_section->unnamed.callback = avr_output_bss_section_asm_op; @@ -10937,13 +10981,9 @@ avr_asm_named_section (const char *name, unsigned int flags, tree decl) avr_need_copy_data_p = (startswith (name, ".data") || startswith (name, ".gnu.linkonce.d")); - if (!avr_need_copy_data_p -#if defined HAVE_LD_AVR_AVRXMEGA3_RODATA_IN_FLASH - && avr_arch->flash_pm_offset == 0 -#endif - ) - avr_need_copy_data_p = (startswith (name, ".rodata") - || startswith (name, ".gnu.linkonce.r")); + if (!avr_has_rodata_p) + avr_has_rodata_p = (startswith (name, ".rodata") + || startswith (name, ".gnu.linkonce.r")); if (!avr_need_clear_bss_p) avr_need_clear_bss_p = startswith (name, ".bss"); @@ -11273,7 +11313,8 @@ avr_file_end (void) linking in the initialization code from libgcc if resp. sections are empty, see PR18145. */ - if (avr_need_copy_data_p) + if (avr_need_copy_data_p + || (avr_has_rodata_p && ! avr_rodata_in_flash_p ())) fputs (".global __do_copy_data\n", asm_out_file); if (avr_need_clear_bss_p) diff --git a/gcc/config/avr/avr.h b/gcc/config/avr/avr.h index 3ef60b9..7f7e231 100644 --- a/gcc/config/avr/avr.h +++ b/gcc/config/avr/avr.h @@ -500,9 +500,11 @@ typedef struct avr_args extern const char *avr_devicespecs_file (int, const char**); extern const char *avr_double_lib (int, const char**); +extern const char *avr_no_devlib (int, const char**); #define EXTRA_SPEC_FUNCTIONS \ { "double-lib", avr_double_lib }, \ + { "no-devlib", avr_no_devlib }, \ { "device-specs-file", avr_devicespecs_file }, /* Driver self specs has lmited functionality w.r.t. '%s' for dynamic specs. diff --git a/gcc/config/avr/avr.opt b/gcc/config/avr/avr.opt index e757308..c9f2b4d 100644 --- a/gcc/config/avr/avr.opt +++ b/gcc/config/avr/avr.opt @@ -27,7 +27,7 @@ Target RejectNegative Joined Var(avr_mmcu) MissingArgError(missing device or arc -mmcu=MCU Select the target MCU. mgas-isr-prologues -Target Var(avr_gasisr_prologues) UInteger Init(0) Optimization +Target Var(avr_gasisr_prologues) UInteger Init(0) Optimization Allow usage of __gcc_isr pseudo instructions in ISR prologues and epilogues. mn-flash= @@ -61,7 +61,7 @@ Target RejectNegative Mask(NO_INTERRUPTS) Change the stack pointer without disabling interrupts. mbranch-cost= -Target Joined RejectNegative UInteger Var(avr_branch_cost) Init(0) +Target Joined RejectNegative UInteger Var(avr_branch_cost) Init(0) Optimization Set the branch costs for conditional branch instructions. Reasonable values are small, non-negative integers. The default branch cost is 0. mmain-is-OS_task @@ -94,6 +94,14 @@ mstrict-X Target Var(avr_strict_X) Init(0) When accessing RAM, use X as imposed by the hardware, i.e. just use pre-decrement, post-increment and indirect addressing with the X register. Without this option, the compiler may assume that there is an addressing mode X+const similar to Y+const and Z+const and emit instructions to emulate such an addressing mode for X. +mflmap +Target Var(avr_flmap) Init(0) +The device has the bitfield NVMCTRL_CTRLB.FLMAP. This option is used internally. + +mrodata-in-ram +Target Var(avr_rodata_in_ram) Init(-1) +The device has the .rodata section located in the RAM area. + ;; For rationale behind -msp8 see explanation in avr.h. msp8 Target RejectNegative Var(avr_sp8) Init(0) @@ -116,11 +124,11 @@ Target Mask(ABSDATA) Assume that all data in static storage can be accessed by LDS / STS. This option is only useful for reduced Tiny devices. mdouble= -Target Joined RejectNegative Var(avr_double) Init(0) Enum(avr_bits_e) +Target Joined RejectNegative Var(avr_double) Init(0) Enum(avr_bits_e) Save -mdouble=<BITS> Use <BITS> bits wide double type. mlong-double= -Target Joined RejectNegative Var(avr_long_double) Init(0) Enum(avr_bits_e) +Target Joined RejectNegative Var(avr_long_double) Init(0) Enum(avr_bits_e) Save -mlong-double=<BITS> Use <BITS> bits wide long double type. nodevicelib diff --git a/gcc/config/avr/driver-avr.cc b/gcc/config/avr/driver-avr.cc index 2512c2c..727f7f0 100644 --- a/gcc/config/avr/driver-avr.cc +++ b/gcc/config/avr/driver-avr.cc @@ -103,9 +103,14 @@ avr_devicespecs_file (int argc, const char **argv) } return concat ("%{!nodevicespecs:-specs=device-specs", dir_separator_str, - "specs-", mmcu, "%s} %<nodevicespecs" + "specs-", mmcu, "%s} %<nodevicespecs" #if defined (WITH_AVRLIBC) - " %{mmcu=avr*:" X_NODEVLIB "} %{!mmcu=*:" X_NODEVLIB "}", + // Return X_NODEVLIB when we are compiling for a core. As + // there are devices like AVR128DA32, a simple mmcu=avr* to + // discriminate between cores and devices ceased to work, + // hence use spec function no-devlib=avr_no_devlib from below. + // See also PR107201. + " %{mmcu=avr*:%:no-devlib(avr%*)} %{!mmcu=*:" X_NODEVLIB "}", #else " " X_NODEVLIB, #endif @@ -113,10 +118,26 @@ avr_devicespecs_file (int argc, const char **argv) } +/* Return X_NODEVLIB when ARGV[] contains a core like "avr5", + otherwise return "". */ + +const char * +avr_no_devlib (int argc, const char **argv) +{ + for (int i = 0; i < argc; ++i) + { + if (avr_get_parch (argv[i])) + return X_NODEVLIB; + } + + return ""; +} + + /* Re-build the -mdouble= and -mlong-double= options. This is needed because these options are not independent of each other. */ -const char* +const char * avr_double_lib (int argc, const char **argv) { #if defined (WITH_DOUBLE64) diff --git a/gcc/config/avr/gen-avr-mmcu-specs.cc b/gcc/config/avr/gen-avr-mmcu-specs.cc index 89f8680..eb9ab88 100644 --- a/gcc/config/avr/gen-avr-mmcu-specs.cc +++ b/gcc/config/avr/gen-avr-mmcu-specs.cc @@ -50,6 +50,8 @@ #define SPECFILE_USAGE_URL \ "https://gcc.gnu.org/gcc-5/changes.html" +#define WIKI_URL \ + "https://gcc.gnu.org/wiki/avr-gcc#spec-files" static const char header[] = "#\n" @@ -68,9 +70,13 @@ static const char header[] = static const char help_copy_paste[] = "# If you intend to use an existing device specs file as a starting point\n" - "# for a new device spec file, make sure you are copying from a specs\n" - "# file for a device from the same core architecture and SP width.\n" - "# See <" SPECFILE_USAGE_URL "> for a description\n" + "# for a new device spec file, make sure you are copying from a specs file\n" + "# for a device from the same or compatible:\n" + "# compiler version, compiler vendor, core architecture, SP width,\n" + "# short-calls and FLMAP.\n" + "# Otherwise, errors and wrong or sub-optimal code may likely occur.\n" + "# See <" WIKI_URL ">\n" + "# and <" SPECFILE_USAGE_URL "> for a description\n" "# of how to use such own spec files.\n"; #if defined (WITH_AVRLIBC) @@ -103,6 +109,60 @@ static const char help_dev_lib_name[] = "\n"; #endif // WITH_AVRLIBC + +#ifdef HAVE_LD_AVR_AVRXMEGA2_FLMAP +static const bool have_avrxmega2_flmap = true; +#else +static const bool have_avrxmega2_flmap = false; +#endif + +#ifdef HAVE_LD_AVR_AVRXMEGA4_FLMAP +static const bool have_avrxmega4_flmap = true; +#else +static const bool have_avrxmega4_flmap = false; +#endif + +#ifdef HAVE_LD_AVR_AVRXMEGA3_RODATA_IN_FLASH +static const bool have_avrxmega3_rodata_in_flash = true; +#else +static const bool have_avrxmega3_rodata_in_flash = false; +#endif + + +static void +diagnose_mrodata_in_ram (FILE *f, const char *spec, const avr_mcu_t *mcu) +{ + enum avr_arch_id arch_id = mcu->arch_id; + const avr_arch_t *arch = &avr_arch_types[arch_id]; + const bool is_arch = mcu->macro == NULL; + const bool flmap = (mcu->dev_attribute & AVR_ISA_FLMAP); + const bool have_flmap2 = have_avrxmega2_flmap && arch_id == ARCH_AVRXMEGA2; + const bool have_flmap4 = have_avrxmega4_flmap && arch_id == ARCH_AVRXMEGA4; + const bool have_flmap = flmap && (have_flmap2 || have_flmap4); + + const bool rodata_in_flash = (arch_id == ARCH_AVRTINY + || (arch_id == ARCH_AVRXMEGA3 + && have_avrxmega3_rodata_in_flash)); + fprintf (f, "%s:\n", spec); + if (rodata_in_flash && is_arch) + fprintf (f, "\t%%{mrodata-in-ram: %%e-mrodata-in-ram not supported" + " for %s}", mcu->name); + else if (rodata_in_flash) + fprintf (f, "\t%%{mrodata-in-ram: %%e-mrodata-in-ram not supported" + " for %s (arch=%s)}", mcu->name, arch->name); + else if (is_arch) + { + if (! have_flmap2 && ! have_flmap4) + fprintf (f, "\t%%{mno-rodata-in-ram: %%e-mno-rodata-in-ram not" + " supported for %s}", mcu->name); + } + else if (! have_flmap) + fprintf (f, "\t%%{mno-rodata-in-ram: %%e-mno-rodata-in-ram not supported" + " for %s (arch=%s)}", mcu->name, arch->name); + fprintf (f, "\n\n"); +} + + static void print_mcu (const avr_mcu_t *mcu) { @@ -130,6 +190,7 @@ print_mcu (const avr_mcu_t *mcu) bool rmw = (mcu->dev_attribute & AVR_ISA_RMW) != 0; bool sp8 = (mcu->dev_attribute & AVR_SHORT_SP) != 0; bool rcall = (mcu->dev_attribute & AVR_ISA_RCALL); + bool flmap = (mcu->dev_attribute & AVR_ISA_FLMAP); bool is_arch = mcu->macro == NULL; bool is_device = ! is_arch; int flash_pm_offset = 0; @@ -166,13 +227,24 @@ print_mcu (const avr_mcu_t *mcu) rcall_spec = rcall ? "-mshort-calls" : "%<mshort-calls"; } + const char *flmap_spec = flmap ? "-mflmap" : "%<mflmap"; + const char *link_arch_spec = "%{mmcu=*:-m%*}"; + const char *link_arch_flmap_spec = "%{mmcu=*:-m%*%{!mrodata-in-ram:_flmap}}"; + const bool have_flmap2 = have_avrxmega2_flmap && arch_id == ARCH_AVRXMEGA2; + const bool have_flmap4 = have_avrxmega4_flmap && arch_id == ARCH_AVRXMEGA4; + const bool have_flmap = flmap && (have_flmap2 || have_flmap4); + + if (have_flmap) + link_arch_spec = link_arch_flmap_spec; + fprintf (f, "#\n" "# Auto-generated specs for AVR "); if (is_arch) fprintf (f, "core architecture %s\n", arch->name); else - fprintf (f, "device %s (core %s, %d-bit SP%s)\n", mcu->name, - arch->name, sp8 ? 8 : 16, rcall ? ", short-calls" : ""); + fprintf (f, "device %s (core %s, %d-bit SP%s%s)\n", mcu->name, + arch->name, sp8 ? 8 : 16, rcall ? ", short-calls" : "", + have_flmap ? ", FLMAP" : ""); fprintf (f, "%s\n", header); if (is_device) @@ -212,6 +284,11 @@ print_mcu (const avr_mcu_t *mcu) ? "\t%{!mno-absdata: -mabsdata}" : "\t%{mabsdata}"); + // -m[no-]rodata-in-ram basically affects linking, but sanity-check early. + diagnose_mrodata_in_ram (f, "*cc1_rodata_in_ram", mcu); + + fprintf (f, "*cc1_misc:\n\t%%(cc1_rodata_in_ram)\n\n"); + // avr-gcc specific specs for assembling / the assembler. fprintf (f, "*asm_arch:\n\t-mmcu=%s\n\n", arch->name); @@ -235,6 +312,8 @@ print_mcu (const avr_mcu_t *mcu) ? "\t%{mno-skip-bug}" : "\t%{!mskip-bug: -mno-skip-bug}"); + fprintf (f, "*asm_misc:\n" /* empty */ "\n\n"); + // avr-specific specs for linking / the linker. int wrap_k = @@ -253,7 +332,10 @@ print_mcu (const avr_mcu_t *mcu) fprintf (f, "*link_relax:\n\t%s\n\n", LINK_RELAX_SPEC); - fprintf (f, "*link_arch:\n\t%s", LINK_ARCH_SPEC); + // -m[no-]rodata-in-ram affects linking. Sanity check its usage. + diagnose_mrodata_in_ram (f, "*link_rodata_in_ram", mcu); + + fprintf (f, "*link_arch:\n\t%s", link_arch_spec); if (is_device && flash_pm_offset) fprintf (f, " --defsym=__RODATA_PM_OFFSET__=0x%x", flash_pm_offset); @@ -274,12 +356,15 @@ print_mcu (const avr_mcu_t *mcu) fprintf (f, "\n\n"); } + fprintf (f, "*link_misc:\n\t%%(link_rodata_in_ram)\n\n"); + // Specs known to GCC. if (is_device) { fprintf (f, "*self_spec:\n"); fprintf (f, "\t%%<mmcu=* -mmcu=%s ", arch->name); + fprintf (f, "%s ", flmap_spec); fprintf (f, "%s ", rcall_spec); fprintf (f, "%s\n\n", sp8_spec); @@ -298,10 +383,26 @@ print_mcu (const avr_mcu_t *mcu) fprintf (f, " -U__AVR_PM_BASE_ADDRESS__"); fprintf (f, " -D__AVR_PM_BASE_ADDRESS__=0x%x", flash_pm_offset); } + if (have_flmap) + fprintf (f, " -D__AVR_HAVE_FLMAP__"); + + fprintf (f, "\n\n"); // *cpp_mcu + + const bool rodata_in_flash = (arch_id == ARCH_AVRTINY + || (arch_id == ARCH_AVRXMEGA3 + && have_avrxmega3_rodata_in_flash)); + fprintf (f, "*cpp_rodata_in_ram:\n\t-D__AVR_RODATA_IN_RAM__="); + if (rodata_in_flash) + fprintf (f, "0"); + else if (! have_flmap) + fprintf (f, "1"); + else + fprintf (f, "%%{!mrodata-in-ram:%%{!mno-rodata-in-ram:0}}" + "%%{mrodata-in-ram:1}" "%%{mno-rodata-in-ram:0}"); fprintf (f, "\n\n"); fprintf (f, "*cpp:\n"); - fprintf (f, "\t%%(cpp_mcu)"); + fprintf (f, "\t%%(cpp_mcu) %%(cpp_rodata_in_ram)"); #if defined (WITH_AVRLIBC) fprintf (f, " %%(cpp_avrlibc)"); #endif // WITH_AVRLIBC diff --git a/gcc/config/avr/gen-avr-mmcu-texi.cc b/gcc/config/avr/gen-avr-mmcu-texi.cc index c756d69..d928236 100644 --- a/gcc/config/avr/gen-avr-mmcu-texi.cc +++ b/gcc/config/avr/gen-avr-mmcu-texi.cc @@ -189,7 +189,8 @@ int main (void) for (i = 0; i < ARRAY_SIZE (avr_texinfo); i++) if (arch_id == avr_texinfo[i].arch_id) - printf ("@item %s\n%s\n", mcu->name, avr_texinfo[i].texinfo); + printf ("@item @anchor{%s}%s\n%s\n", mcu->name, mcu->name, + avr_texinfo[i].texinfo); } else if (arch_id == (enum avr_arch_id) mcu->arch_id) { diff --git a/gcc/config/avr/specs.h b/gcc/config/avr/specs.h index 433231f..5744020 100644 --- a/gcc/config/avr/specs.h +++ b/gcc/config/avr/specs.h @@ -35,7 +35,8 @@ along with GCC; see the file COPYING3. If not see "%(cc1_n_flash) " \ "%(cc1_errata_skip) " \ "%(cc1_rmw) " \ - "%(cc1_absdata) " + "%(cc1_absdata) " \ + "%(cc1_misc) " #undef CC1PLUS_SPEC #define CC1PLUS_SPEC \ @@ -53,10 +54,8 @@ along with GCC; see the file COPYING3. If not see "%(asm_relax) " \ "%(asm_rmw) " \ "%(asm_gccisr) " \ - "%(asm_errata_skip) " - -#define LINK_ARCH_SPEC \ - "%{mmcu=*:-m%*} " + "%(asm_errata_skip) " \ + "%(asm_misc) " #define LINK_RELAX_SPEC \ "%{mrelax:--relax} " @@ -68,6 +67,7 @@ along with GCC; see the file COPYING3. If not see "%(link_text_start) " \ "%(link_relax) " \ "%(link_pmem_wrap) " \ + "%(link_misc) " \ "%{shared:%eshared is not supported} " #undef LIB_SPEC diff --git a/gcc/config/i386/i386-c.cc b/gcc/config/i386/i386-c.cc index c3ae984..366b560 100644 --- a/gcc/config/i386/i386-c.cc +++ b/gcc/config/i386/i386-c.cc @@ -735,6 +735,13 @@ ix86_target_macros_internal (HOST_WIDE_INT isa_flag, def_or_undef (parse_in, "__EVEX512__"); if (isa_flag2 & OPTION_MASK_ISA2_USER_MSR) def_or_undef (parse_in, "__USER_MSR__"); + if (isa_flag2 & OPTION_MASK_ISA2_AVX10_1_256) + { + def_or_undef (parse_in, "__AVX10_1_256__"); + def_or_undef (parse_in, "__AVX10_1__"); + } + if (isa_flag2 & OPTION_MASK_ISA2_AVX10_1_512) + def_or_undef (parse_in, "__AVX10_1_512__"); if (TARGET_IAMCU) { def_or_undef (parse_in, "__iamcu"); diff --git a/gcc/config/i386/i386.opt b/gcc/config/i386/i386.opt index a38e92b..5b4f1bf 100644 --- a/gcc/config/i386/i386.opt +++ b/gcc/config/i386/i386.opt @@ -1357,8 +1357,7 @@ Enum(apx_features) String(all) Value(apx_all) Set(1) mapx-inline-asm-use-gpr32 Target Var(ix86_apx_inline_asm_use_gpr32) Init(0) -Enable GPR32 in inline asm when APX_EGPR enabled, do not -hook reg or mem constraint in inline asm to GPR16. +Enable GPR32 in inline asm when APX_F enabled. mevex512 Target Mask(ISA2_EVEX512) Var(ix86_isa_flags2) Save diff --git a/gcc/config/i386/sse.md b/gcc/config/i386/sse.md index 532738d..acd1090 100644 --- a/gcc/config/i386/sse.md +++ b/gcc/config/i386/sse.md @@ -16174,7 +16174,6 @@ operands[2] = lowpart_subreg (<sseunpackmode>mode, force_reg (<MODE>mode, operands[2]), <MODE>mode); - emit_insn (gen_rtx_SET (operands[0], operands[3])); emit_insn (gen_vpdpwssd_<SDOT_VPDP_SUF> (operands[0], operands[3], operands[1], operands[2])); } @@ -29963,7 +29962,6 @@ operands[2] = lowpart_subreg (<ssedvecmode>mode, force_reg (<MODE>mode, operands[2]), <MODE>mode); - emit_insn (gen_rtx_SET (operands[0], operands[3])); emit_insn (gen_vpdpbusd_<ssedvecmodelower> (operands[0], operands[3], operands[1], operands[2])); DONE; @@ -30780,7 +30778,6 @@ operands[2] = lowpart_subreg (<ssedvecmode>mode, force_reg (<MODE>mode, operands[2]), <MODE>mode); - emit_insn (gen_rtx_SET (operands[0], operands[3])); emit_insn (gen_vpdpbssd_<ssedvecmodelower> (operands[0], operands[3], operands[1], operands[2])); } @@ -30857,7 +30854,6 @@ operands[2] = lowpart_subreg (<ssedvecmode>mode, force_reg (<MODE>mode, operands[2]), <MODE>mode); - emit_insn (gen_rtx_SET (operands[0], operands[3])); emit_insn (gen_vpdpbuud_<ssedvecmodelower> (operands[0], operands[3], operands[1], operands[2])); } diff --git a/gcc/config/loongarch/genopts/genstr.sh b/gcc/config/loongarch/genopts/genstr.sh index 5865b87d..724c9aa 100755 --- a/gcc/config/loongarch/genopts/genstr.sh +++ b/gcc/config/loongarch/genopts/genstr.sh @@ -107,7 +107,7 @@ EOF print("") print("m"$3) gsub(/-/, "_", $3) - print("Target Mask(ISA_"toupper($3)") Var(isa_evolution)") + print("Target Mask(ISA_"toupper($3)") Var(la_isa_evolution)") $1=""; $2=""; $3="" sub(/^ */, "", $0) print($0) diff --git a/gcc/config/loongarch/genopts/loongarch-strings b/gcc/config/loongarch/genopts/loongarch-strings index f40b014..e434a89 100644 --- a/gcc/config/loongarch/genopts/loongarch-strings +++ b/gcc/config/loongarch/genopts/loongarch-strings @@ -29,7 +29,7 @@ STR_CPU_LA464 la464 STR_CPU_LA664 la664 # Base architecture -STR_ISA_BASE_LA64V100 la64 +STR_ISA_BASE_LA64 la64 # -mfpu OPTSTR_ISA_EXT_FPU fpu @@ -64,9 +64,3 @@ STR_CMODEL_TS tiny-static STR_CMODEL_MEDIUM medium STR_CMODEL_LARGE large STR_CMODEL_EXTREME extreme - -# -mexplicit-relocs -OPTSTR_EXPLICIT_RELOCS explicit-relocs -STR_EXPLICIT_RELOCS_AUTO auto -STR_EXPLICIT_RELOCS_NONE none -STR_EXPLICIT_RELOCS_ALWAYS always diff --git a/gcc/config/loongarch/genopts/loongarch.opt.in b/gcc/config/loongarch/genopts/loongarch.opt.in index f2e7ea2..02f9180 100644 --- a/gcc/config/loongarch/genopts/loongarch.opt.in +++ b/gcc/config/loongarch/genopts/loongarch.opt.in @@ -33,7 +33,7 @@ Name(isa_base) Type(int) Basic ISAs of LoongArch: EnumValue -Enum(isa_base) String(@@STR_ISA_BASE_LA64V100@@) Value(ISA_BASE_LA64V100) +Enum(isa_base) String(@@STR_ISA_BASE_LA64@@) Value(ISA_BASE_LA64) ;; ISA extensions / adjustments Enum @@ -50,7 +50,7 @@ EnumValue Enum(isa_ext_fpu) String(@@STR_ISA_EXT_FPU64@@) Value(ISA_EXT_FPU64) m@@OPTSTR_ISA_EXT_FPU@@= -Target RejectNegative Joined ToLower Enum(isa_ext_fpu) Var(la_opt_fpu) Init(M_OPT_UNSET) +Target RejectNegative Joined ToLower Enum(isa_ext_fpu) Var(la_opt_fpu) Init(M_OPT_UNSET) Save -m@@OPTSTR_ISA_EXT_FPU@@=FPU Generate code for the given FPU. m@@OPTSTR_ISA_EXT_FPU@@=@@STR_ISA_EXT_FPU0@@ @@ -82,7 +82,7 @@ EnumValue Enum(isa_ext_simd) String(@@STR_ISA_EXT_LASX@@) Value(ISA_EXT_SIMD_LASX) m@@OPTSTR_ISA_EXT_SIMD@@= -Target RejectNegative Joined ToLower Enum(isa_ext_simd) Var(la_opt_simd) Init(M_OPT_UNSET) +Target RejectNegative Joined ToLower Enum(isa_ext_simd) Var(la_opt_simd) Init(M_OPT_UNSET) Save -m@@OPTSTR_ISA_EXT_SIMD@@=SIMD Generate code for the given SIMD extension. m@@STR_ISA_EXT_LSX@@ @@ -114,11 +114,11 @@ EnumValue Enum(cpu_type) String(@@STR_CPU_LA664@@) Value(CPU_LA664) m@@OPTSTR_ARCH@@= -Target RejectNegative Joined Enum(cpu_type) Var(la_opt_cpu_arch) Init(M_OPT_UNSET) +Target RejectNegative Joined Enum(cpu_type) Var(la_opt_cpu_arch) Init(M_OPT_UNSET) Save -m@@OPTSTR_ARCH@@=PROCESSOR Generate code for the given PROCESSOR ISA. m@@OPTSTR_TUNE@@= -Target RejectNegative Joined Enum(cpu_type) Var(la_opt_cpu_tune) Init(M_OPT_UNSET) +Target RejectNegative Joined Enum(cpu_type) Var(la_opt_cpu_tune) Init(M_OPT_UNSET) Save -m@@OPTSTR_TUNE@@=PROCESSOR Generate optimized code for PROCESSOR. @@ -149,31 +149,31 @@ Variable int la_opt_abi_ext = M_OPT_UNSET mbranch-cost= -Target RejectNegative Joined UInteger Var(loongarch_branch_cost) +Target RejectNegative Joined UInteger Var(la_branch_cost) Save -mbranch-cost=COST Set the cost of branches to roughly COST instructions. mcheck-zero-division -Target Mask(CHECK_ZERO_DIV) +Target Mask(CHECK_ZERO_DIV) Save Trap on integer divide by zero. mcond-move-int -Target Var(TARGET_COND_MOVE_INT) Init(1) +Target Mask(COND_MOVE_INT) Save Conditional moves for integral are enabled. mcond-move-float -Target Var(TARGET_COND_MOVE_FLOAT) Init(1) +Target Mask(COND_MOVE_FLOAT) Save Conditional moves for float are enabled. mmemcpy -Target Mask(MEMCPY) +Target Mask(MEMCPY) Save Prevent optimizing block moves, which is also the default behavior of -Os. mstrict-align -Target Var(TARGET_STRICT_ALIGN) Init(0) +Target Mask(STRICT_ALIGN) Save Do not generate unaligned memory accesses. mmax-inline-memcpy-size= -Target Joined RejectNegative UInteger Var(loongarch_max_inline_memcpy_size) Init(1024) +Target Joined RejectNegative UInteger Var(la_max_inline_memcpy_size) Init(1024) Save -mmax-inline-memcpy-size=SIZE Set the max size of memcpy to inline, default is 1024. Enum @@ -181,28 +181,28 @@ Name(explicit_relocs) Type(int) The code model option names for -mexplicit-relocs: EnumValue -Enum(explicit_relocs) String(@@STR_EXPLICIT_RELOCS_AUTO@@) Value(EXPLICIT_RELOCS_AUTO) +Enum(explicit_relocs) String(auto) Value(EXPLICIT_RELOCS_AUTO) EnumValue -Enum(explicit_relocs) String(@@STR_EXPLICIT_RELOCS_NONE@@) Value(EXPLICIT_RELOCS_NONE) +Enum(explicit_relocs) String(none) Value(EXPLICIT_RELOCS_NONE) EnumValue -Enum(explicit_relocs) String(@@STR_EXPLICIT_RELOCS_ALWAYS@@) Value(EXPLICIT_RELOCS_ALWAYS) +Enum(explicit_relocs) String(always) Value(EXPLICIT_RELOCS_ALWAYS) mexplicit-relocs= Target RejectNegative Joined Enum(explicit_relocs) Var(la_opt_explicit_relocs) Init(M_OPT_UNSET) Use %reloc() assembly operators. mexplicit-relocs -Target Var(la_opt_explicit_relocs_backward) Init(M_OPT_UNSET) +Target Alias(mexplicit-relocs=, always, none) Use %reloc() assembly operators (for backward compatibility). mrecip -Target RejectNegative Var(loongarch_recip) +Target RejectNegative Var(la_recip) Save Generate approximate reciprocal divide and square root for better throughput. mrecip= -Target RejectNegative Joined Var(loongarch_recip_name) +Target RejectNegative Joined Var(la_recip_name) Save Control generation of reciprocal estimates. ; The code model option names for -mcmodel. @@ -229,29 +229,29 @@ EnumValue Enum(cmodel) String(@@STR_CMODEL_EXTREME@@) Value(CMODEL_EXTREME) mcmodel= -Target RejectNegative Joined Enum(cmodel) Var(la_opt_cmodel) Init(M_OPT_UNSET) +Target RejectNegative Joined Enum(cmodel) Var(la_opt_cmodel) Init(M_OPT_UNSET) Save Specify the code model. mdirect-extern-access -Target Var(TARGET_DIRECT_EXTERN_ACCESS) Init(0) +Target Mask(DIRECT_EXTERN_ACCESS) Save Avoid using the GOT to access external symbols. mrelax -Target Var(loongarch_mrelax) Init(HAVE_AS_MRELAX_OPTION && HAVE_AS_COND_BRANCH_RELAXATION) +Target Mask(LINKER_RELAXATION) Take advantage of linker relaxations to reduce the number of instructions required to materialize symbol addresses. mpass-mrelax-to-as -Target Var(loongarch_pass_mrelax_to_as) Init(HAVE_AS_MRELAX_OPTION) +Driver Var(la_pass_mrelax_to_as) Init(HAVE_AS_MRELAX_OPTION) Pass -mrelax or -mno-relax option to the assembler. -param=loongarch-vect-unroll-limit= -Target Joined UInteger Var(loongarch_vect_unroll_limit) Init(6) IntegerRange(1, 64) Param +Target Joined UInteger Var(la_vect_unroll_limit) Init(6) IntegerRange(1, 64) Param Used to limit unroll factor which indicates how much the autovectorizer may unroll a loop. The default value is 6. -param=loongarch-vect-issue-info= -Target Undocumented Joined UInteger Var(loongarch_vect_issue_info) Init(4) IntegerRange(1, 64) Param +Target Undocumented Joined UInteger Var(la_vect_issue_info) Init(4) IntegerRange(1, 64) Param Indicate how many non memory access vector instructions can be issued per cycle, it's used in unroll factor determination for autovectorizer. The default value is 4. @@ -259,6 +259,6 @@ default value is 4. ; Features added during ISA evolution. This concept is different from ISA ; extension, read Section 1.5 of LoongArch v1.10 Volume 1 for the ; explanation. These features may be implemented and enumerated with -; CPUCFG independantly, so we use bit flags to specify them. -Variable -HOST_WIDE_INT isa_evolution = 0 +; CPUCFG independently, so we use bit flags to specify them. +TargetVariable +HOST_WIDE_INT la_isa_evolution = 0 diff --git a/gcc/config/loongarch/lasx.md b/gcc/config/loongarch/lasx.md index c2bde4d..72f7161 100644 --- a/gcc/config/loongarch/lasx.md +++ b/gcc/config/loongarch/lasx.md @@ -1540,7 +1540,7 @@ [(set (match_operand:FLASX 0 "register_operand" "=f") (unspec:FLASX [(match_operand:FLASX 1 "register_operand" "f")] UNSPEC_LASX_XVFRECIPE))] - "ISA_HAS_LASX && TARGET_FRECIPE" + "ISA_HAS_LASX && ISA_HAS_FRECIPE" "xvfrecipe.<flasxfmt>\t%u0,%u1" [(set_attr "type" "simd_fdiv") (set_attr "mode" "<MODE>")]) @@ -1573,7 +1573,7 @@ [(set (match_operand:FLASX 0 "register_operand" "=f") (unspec:FLASX [(match_operand:FLASX 1 "register_operand" "f")] UNSPEC_LASX_XVFRSQRTE))] - "ISA_HAS_LASX && TARGET_FRECIPE" + "ISA_HAS_LASX && ISA_HAS_FRECIPE" "xvfrsqrte.<flasxfmt>\t%u0,%u1" [(set_attr "type" "simd_fdiv") (set_attr "mode" "<MODE>")]) diff --git a/gcc/config/loongarch/loongarch-builtins.cc b/gcc/config/loongarch/loongarch-builtins.cc index 45ec6ac..efe7e5e 100644 --- a/gcc/config/loongarch/loongarch-builtins.cc +++ b/gcc/config/loongarch/loongarch-builtins.cc @@ -120,9 +120,9 @@ struct loongarch_builtin_description AVAIL_ALL (hard_float, TARGET_HARD_FLOAT_ABI) AVAIL_ALL (lsx, ISA_HAS_LSX) AVAIL_ALL (lasx, ISA_HAS_LASX) -AVAIL_ALL (frecipe, TARGET_FRECIPE && TARGET_HARD_FLOAT_ABI) -AVAIL_ALL (lsx_frecipe, ISA_HAS_LSX && TARGET_FRECIPE) -AVAIL_ALL (lasx_frecipe, ISA_HAS_LASX && TARGET_FRECIPE) +AVAIL_ALL (frecipe, ISA_HAS_FRECIPE && TARGET_HARD_FLOAT_ABI) +AVAIL_ALL (lsx_frecipe, ISA_HAS_LSX && ISA_HAS_FRECIPE) +AVAIL_ALL (lasx_frecipe, ISA_HAS_LASX && ISA_HAS_FRECIPE) /* Construct a loongarch_builtin_description from the given arguments. diff --git a/gcc/config/loongarch/loongarch-c.cc b/gcc/config/loongarch/loongarch-c.cc index 118b151..4d88c17 100644 --- a/gcc/config/loongarch/loongarch-c.cc +++ b/gcc/config/loongarch/loongarch-c.cc @@ -102,7 +102,7 @@ loongarch_cpu_cpp_builtins (cpp_reader *pfile) else builtin_define ("__loongarch_frlen=0"); - if (TARGET_HARD_FLOAT && TARGET_FRECIPE) + if (TARGET_HARD_FLOAT && ISA_HAS_FRECIPE) builtin_define ("__loongarch_frecipe"); if (ISA_HAS_LSX) diff --git a/gcc/config/loongarch/loongarch-cpu.cc b/gcc/config/loongarch/loongarch-cpu.cc index e1771fc..97ac5fe 100644 --- a/gcc/config/loongarch/loongarch-cpu.cc +++ b/gcc/config/loongarch/loongarch-cpu.cc @@ -133,7 +133,7 @@ fill_native_cpu_config (struct loongarch_target *tgt) switch (cpucfg_cache[1] & 0x3) { case 0x02: - tmp = ISA_BASE_LA64V100; + tmp = ISA_BASE_LA64; break; default: diff --git a/gcc/config/loongarch/loongarch-def.cc b/gcc/config/loongarch/loongarch-def.cc index 48d2831..e8c129c 100644 --- a/gcc/config/loongarch/loongarch-def.cc +++ b/gcc/config/loongarch/loongarch-def.cc @@ -48,16 +48,16 @@ array_arch<loongarch_isa> loongarch_cpu_default_isa = array_arch<loongarch_isa> () .set (CPU_LOONGARCH64, loongarch_isa () - .base_ (ISA_BASE_LA64V100) + .base_ (ISA_BASE_LA64) .fpu_ (ISA_EXT_FPU64)) .set (CPU_LA464, loongarch_isa () - .base_ (ISA_BASE_LA64V100) + .base_ (ISA_BASE_LA64) .fpu_ (ISA_EXT_FPU64) .simd_ (ISA_EXT_SIMD_LASX)) .set (CPU_LA664, loongarch_isa () - .base_ (ISA_BASE_LA64V100) + .base_ (ISA_BASE_LA64) .fpu_ (ISA_EXT_FPU64) .simd_ (ISA_EXT_SIMD_LASX) .evolution_ (OPTION_MASK_ISA_DIV32 | OPTION_MASK_ISA_LD_SEQ_SA @@ -153,7 +153,7 @@ array_tune<int> loongarch_cpu_multipass_dfa_lookahead = array_tune<int> () array<const char *, N_ISA_BASE_TYPES> loongarch_isa_base_strings = array<const char *, N_ISA_BASE_TYPES> () - .set (ISA_BASE_LA64V100, STR_ISA_BASE_LA64V100); + .set (ISA_BASE_LA64, STR_ISA_BASE_LA64); array<const char *, N_ISA_EXT_TYPES> loongarch_isa_ext_strings = array<const char *, N_ISA_EXT_TYPES> () @@ -189,15 +189,15 @@ array<array<loongarch_isa, N_ABI_EXT_TYPES>, N_ABI_BASE_TYPES> array<loongarch_isa, N_ABI_EXT_TYPES> () .set (ABI_EXT_BASE, loongarch_isa () - .base_ (ISA_BASE_LA64V100) + .base_ (ISA_BASE_LA64) .fpu_ (ISA_EXT_FPU64))) .set (ABI_BASE_LP64F, array<loongarch_isa, N_ABI_EXT_TYPES> () .set (ABI_EXT_BASE, loongarch_isa () - .base_ (ISA_BASE_LA64V100) + .base_ (ISA_BASE_LA64) .fpu_ (ISA_EXT_FPU32))) .set (ABI_BASE_LP64S, array<loongarch_isa, N_ABI_EXT_TYPES> () .set (ABI_EXT_BASE, - loongarch_isa ().base_ (ISA_BASE_LA64V100))); + loongarch_isa ().base_ (ISA_BASE_LA64))); diff --git a/gcc/config/loongarch/loongarch-def.h b/gcc/config/loongarch/loongarch-def.h index 403b024..a1237ec 100644 --- a/gcc/config/loongarch/loongarch-def.h +++ b/gcc/config/loongarch/loongarch-def.h @@ -23,12 +23,10 @@ along with GCC; see the file COPYING3. If not see - ISA extensions (isa_ext), - base ABI types (abi_base), - ABI extension types (abi_ext). - - - code models (cmodel) - - other command-line switches (switch) + - code models (cmodel) These values are primarily used for implementing option handling - logic in "loongarch.opt", "loongarch-driver.c" and "loongarch-opt.c". + logic in "loongarch.opt", "loongarch-driver.cc" and "loongarch-opt.cc". As for the result of this option handling process, the following scheme is adopted to represent the final configuration: @@ -53,30 +51,40 @@ along with GCC; see the file COPYING3. If not see #include "loongarch-def-array.h" #include "loongarch-tune.h" -/* enum isa_base */ -/* LoongArch V1.00. */ -#define ISA_BASE_LA64V100 0 -#define N_ISA_BASE_TYPES 1 +/* ISA base */ +enum { + ISA_BASE_LA64 = 0, /* LoongArch64 */ + N_ISA_BASE_TYPES = 1 +}; + extern loongarch_def_array<const char *, N_ISA_BASE_TYPES> loongarch_isa_base_strings; -/* enum isa_ext_* */ -#define ISA_EXT_NONE 0 -#define ISA_EXT_FPU32 1 -#define ISA_EXT_FPU64 2 -#define N_ISA_EXT_FPU_TYPES 3 -#define ISA_EXT_SIMD_LSX 3 -#define ISA_EXT_SIMD_LASX 4 -#define N_ISA_EXT_TYPES 5 + +/* ISA extensions */ +enum { + ISA_EXT_NONE = 0, + ISA_EXT_FPU32 = 1, + ISA_EXT_FPU64 = 2, + N_ISA_EXT_FPU_TYPES = 3, + ISA_EXT_SIMD_LSX = 3, + ISA_EXT_SIMD_LASX = 4, + N_ISA_EXT_TYPES = 5 +}; + extern loongarch_def_array<const char *, N_ISA_EXT_TYPES> loongarch_isa_ext_strings; -/* enum abi_base */ -#define ABI_BASE_LP64D 0 -#define ABI_BASE_LP64F 1 -#define ABI_BASE_LP64S 2 -#define N_ABI_BASE_TYPES 3 + +/* Base ABI */ +enum { + ABI_BASE_LP64D = 0, + ABI_BASE_LP64F = 1, + ABI_BASE_LP64S = 2, + N_ABI_BASE_TYPES = 3 +}; + extern loongarch_def_array<const char *, N_ABI_BASE_TYPES> loongarch_abi_base_strings; @@ -90,28 +98,38 @@ extern loongarch_def_array<const char *, N_ABI_BASE_TYPES> (abi_base == ABI_BASE_LP64S) -/* enum abi_ext */ -#define ABI_EXT_BASE 0 -#define N_ABI_EXT_TYPES 1 +/* ABI Extension */ +enum { + ABI_EXT_BASE = 0, + N_ABI_EXT_TYPES = 1 +}; + extern loongarch_def_array<const char *, N_ABI_EXT_TYPES> loongarch_abi_ext_strings; -/* enum cmodel */ -#define CMODEL_NORMAL 0 -#define CMODEL_TINY 1 -#define CMODEL_TINY_STATIC 2 -#define CMODEL_MEDIUM 3 -#define CMODEL_LARGE 4 -#define CMODEL_EXTREME 5 -#define N_CMODEL_TYPES 6 + +/* Code Model */ +enum { + CMODEL_NORMAL = 0, + CMODEL_TINY = 1, + CMODEL_TINY_STATIC = 2, + CMODEL_MEDIUM = 3, + CMODEL_LARGE = 4, + CMODEL_EXTREME = 5, + N_CMODEL_TYPES = 6 +}; + extern loongarch_def_array<const char *, N_CMODEL_TYPES> loongarch_cmodel_strings; -/* enum explicit_relocs */ -#define EXPLICIT_RELOCS_AUTO 0 -#define EXPLICIT_RELOCS_NONE 1 -#define EXPLICIT_RELOCS_ALWAYS 2 -#define N_EXPLICIT_RELOCS_TYPES 3 + +/* Explicit Reloc Type */ +enum { + EXPLICIT_RELOCS_AUTO = 0, + EXPLICIT_RELOCS_NONE = 1, + EXPLICIT_RELOCS_ALWAYS = 2, + N_EXPLICIT_RELOCS_TYPES = 3 +}; /* The common default value for variables whose assignments are triggered by command-line options. */ @@ -132,8 +150,11 @@ struct loongarch_isa Using int64_t instead of HOST_WIDE_INT for C compatibility. */ int64_t evolution; + int64_t evolution_set; - loongarch_isa () : base (0), fpu (0), simd (0), evolution (0) {} + loongarch_isa () : + base (0), fpu (0), simd (0), evolution (0), evolution_set (0) + {} loongarch_isa base_ (int _base) { base = _base; return *this; } loongarch_isa fpu_ (int _fpu) { fpu = _fpu; return *this; } loongarch_isa simd_ (int _simd) { simd = _simd; return *this; } @@ -156,17 +177,18 @@ struct loongarch_target int cmodel; /* CMODEL_ */ }; -/* CPU properties. */ -/* index */ -#define CPU_NATIVE 0 -#define CPU_ABI_DEFAULT 1 -#define CPU_LOONGARCH64 2 -#define CPU_LA464 3 -#define CPU_LA664 4 -#define N_ARCH_TYPES 5 -#define N_TUNE_TYPES 5 - -/* parallel tables. */ +/* CPU model */ +enum { + CPU_NATIVE = 0, + CPU_ABI_DEFAULT = 1, + CPU_LOONGARCH64 = 2, + CPU_LA464 = 3, + CPU_LA664 = 4, + N_ARCH_TYPES = 5, + N_TUNE_TYPES = 5 +}; + +/* CPU model properties */ extern loongarch_def_array<const char *, N_ARCH_TYPES> loongarch_cpu_strings; extern loongarch_def_array<loongarch_isa, N_ARCH_TYPES> diff --git a/gcc/config/loongarch/loongarch-driver.cc b/gcc/config/loongarch/loongarch-driver.cc index ef1db31..62658f5 100644 --- a/gcc/config/loongarch/loongarch-driver.cc +++ b/gcc/config/loongarch/loongarch-driver.cc @@ -42,9 +42,10 @@ extern struct obstack opts_obstack; const char* la_driver_init (int argc ATTRIBUTE_UNUSED, const char **argv ATTRIBUTE_UNUSED) { - /* Initialize all fields of la_target to -1 */ + /* Initialize all fields of la_target. */ loongarch_init_target (&la_target, M_OPT_UNSET, M_OPT_UNSET, M_OPT_UNSET, - M_OPT_UNSET, M_OPT_UNSET, M_OPT_UNSET, M_OPT_UNSET); + M_OPT_UNSET, M_OPT_UNSET, M_OPT_UNSET, M_OPT_UNSET, + 0, 0); return ""; } diff --git a/gcc/config/loongarch/loongarch-opts.cc b/gcc/config/loongarch/loongarch-opts.cc index d28b436..b872995 100644 --- a/gcc/config/loongarch/loongarch-opts.cc +++ b/gcc/config/loongarch/loongarch-opts.cc @@ -140,7 +140,9 @@ static int with_default_simd = 0; void loongarch_init_target (struct loongarch_target *target, int cpu_arch, int cpu_tune, int fpu, int simd, - int abi_base, int abi_ext, int cmodel) + int abi_base, int abi_ext, int cmodel, + HOST_WIDE_INT isa_evolution, + HOST_WIDE_INT isa_evolution_set) { if (!target) return; @@ -148,6 +150,8 @@ loongarch_init_target (struct loongarch_target *target, target->cpu_tune = cpu_tune; target->isa.fpu = fpu; target->isa.simd = simd; + target->isa.evolution = isa_evolution; + target->isa.evolution_set = isa_evolution_set; target->abi.base = abi_base; target->abi.ext = abi_ext; target->cmodel = cmodel; @@ -184,6 +188,9 @@ loongarch_config_target (struct loongarch_target *target, M_OPT_ABSENT (target->abi.base) ? 0 : 1, }; + int64_t isa_evolution = target->isa.evolution; + int64_t isa_evolution_set = target->isa.evolution_set; + /* 1. Target ABI */ if (constrained.abi_base) t.abi.base = target->abi.base; @@ -394,6 +401,13 @@ config_target_isa: } } + /* Apply the ISA evolution feature switches from the user. */ + HOST_WIDE_INT isa_evolution_orig = t.isa.evolution; + t.isa.evolution &= ~(~isa_evolution & isa_evolution_set); + t.isa.evolution |= isa_evolution & isa_evolution_set; + + /* evolution_set means "what's different from the -march default". */ + t.isa.evolution_set = isa_evolution_orig ^ t.isa.evolution; /* 4. ABI-ISA compatibility */ /* Note: @@ -553,17 +567,17 @@ isa_default_abi (const struct loongarch_isa *isa) switch (isa->fpu) { case ISA_EXT_FPU64: - if (isa->base >= ISA_BASE_LA64V100) + if (isa->base >= ISA_BASE_LA64) abi.base = ABI_BASE_LP64D; break; case ISA_EXT_FPU32: - if (isa->base >= ISA_BASE_LA64V100) + if (isa->base >= ISA_BASE_LA64) abi.base = ABI_BASE_LP64F; break; case ISA_EXT_NONE: - if (isa->base >= ISA_BASE_LA64V100) + if (isa->base >= ISA_BASE_LA64) abi.base = ABI_BASE_LP64S; break; @@ -582,8 +596,8 @@ isa_base_compat_p (const struct loongarch_isa *set1, { switch (set2->base) { - case ISA_BASE_LA64V100: - return (set1->base >= ISA_BASE_LA64V100); + case ISA_BASE_LA64: + return (set1->base >= ISA_BASE_LA64); default: gcc_unreachable (); @@ -771,7 +785,15 @@ loongarch_update_gcc_opt_status (struct loongarch_target *target, opts->x_la_opt_cpu_arch = target->cpu_arch; opts->x_la_opt_cpu_tune = target->cpu_tune; + /* status of -mcmodel */ + opts->x_la_opt_cmodel = target->cmodel; + /* status of -mfpu */ opts->x_la_opt_fpu = target->isa.fpu; + + /* status of -msimd */ opts->x_la_opt_simd = target->isa.simd; + + /* ISA evolution features */ + opts->x_la_isa_evolution = target->isa.evolution; } diff --git a/gcc/config/loongarch/loongarch-opts.h b/gcc/config/loongarch/loongarch-opts.h index b28dcbf..586e67e 100644 --- a/gcc/config/loongarch/loongarch-opts.h +++ b/gcc/config/loongarch/loongarch-opts.h @@ -34,7 +34,9 @@ extern struct loongarch_target la_target; void loongarch_init_target (struct loongarch_target *target, int cpu_arch, int cpu_tune, int fpu, int simd, - int abi_base, int abi_ext, int cmodel); + int abi_base, int abi_ext, int cmodel, + HOST_WIDE_INT isa_evolutions, + HOST_WIDE_INT isa_evolutions_set); /* Handler for "-m" option combinations, @@ -77,14 +79,28 @@ struct loongarch_flags { #define TARGET_DOUBLE_FLOAT (la_target.isa.fpu == ISA_EXT_FPU64) #define TARGET_DOUBLE_FLOAT_ABI (la_target.abi.base == ABI_BASE_LP64D) -#define TARGET_64BIT (la_target.isa.base == ISA_BASE_LA64V100) +#define TARGET_64BIT (la_target.isa.base == ISA_BASE_LA64) #define TARGET_ABI_LP64 (la_target.abi.base == ABI_BASE_LP64D \ || la_target.abi.base == ABI_BASE_LP64F \ || la_target.abi.base == ABI_BASE_LP64S) -#define ISA_HAS_LSX (la_target.isa.simd == ISA_EXT_SIMD_LSX \ - || la_target.isa.simd == ISA_EXT_SIMD_LASX) -#define ISA_HAS_LASX (la_target.isa.simd == ISA_EXT_SIMD_LASX) +#define ISA_HAS_LSX \ + (la_target.isa.simd == ISA_EXT_SIMD_LSX \ + || la_target.isa.simd == ISA_EXT_SIMD_LASX) + +#define ISA_HAS_LASX \ + (la_target.isa.simd == ISA_EXT_SIMD_LASX) + +#define ISA_HAS_FRECIPE \ + (la_target.isa.evolution & OPTION_MASK_ISA_FRECIPE) +#define ISA_HAS_DIV32 \ + (la_target.isa.evolution & OPTION_MASK_ISA_DIV32) +#define ISA_HAS_LAM_BH \ + (la_target.isa.evolution & OPTION_MASK_ISA_LAM_BH) +#define ISA_HAS_LAMCAS \ + (la_target.isa.evolution & OPTION_MASK_ISA_LAMCAS) +#define ISA_HAS_LD_SEQ_SA \ + (la_target.isa.evolution & OPTION_MASK_ISA_LD_SEQ_SA) /* TARGET_ macros for use in *.md template conditionals */ #define TARGET_uARCH_LA464 (la_target.cpu_tune == CPU_LA464) diff --git a/gcc/config/loongarch/loongarch-str.h b/gcc/config/loongarch/loongarch-str.h index 2221c57..20da2b1 100644 --- a/gcc/config/loongarch/loongarch-str.h +++ b/gcc/config/loongarch/loongarch-str.h @@ -32,7 +32,7 @@ along with GCC; see the file COPYING3. If not see #define STR_CPU_LA464 "la464" #define STR_CPU_LA664 "la664" -#define STR_ISA_BASE_LA64V100 "la64" +#define STR_ISA_BASE_LA64 "la64" #define OPTSTR_ISA_EXT_FPU "fpu" #define STR_NONE "none" @@ -63,11 +63,6 @@ along with GCC; see the file COPYING3. If not see #define STR_CMODEL_LARGE "large" #define STR_CMODEL_EXTREME "extreme" -#define OPTSTR_EXPLICIT_RELOCS "explicit-relocs" -#define STR_EXPLICIT_RELOCS_AUTO "auto" -#define STR_EXPLICIT_RELOCS_NONE "none" -#define STR_EXPLICIT_RELOCS_ALWAYS "always" - #define OPTSTR_FRECIPE "frecipe" #define OPTSTR_DIV32 "div32" #define OPTSTR_LAM_BH "lam-bh" diff --git a/gcc/config/loongarch/loongarch.cc b/gcc/config/loongarch/loongarch.cc index 1c90afc..3b8559b 100644 --- a/gcc/config/loongarch/loongarch.cc +++ b/gcc/config/loongarch/loongarch.cc @@ -3863,7 +3863,7 @@ loongarch_rtx_costs (rtx x, machine_mode mode, int outer_code, else { *total = loongarch_cost->int_div_si; - if (TARGET_64BIT && !TARGET_DIV32) + if (TARGET_64BIT && !ISA_HAS_DIV32) *total += COSTS_N_INSNS (2); } @@ -4083,10 +4083,10 @@ loongarch_vector_costs::determine_suggested_unroll_factor (loop_vec_info loop_vi /* Use this simple hardware resource model that how many non vld/vst vector instructions can be issued per cycle. */ - unsigned int issue_info = loongarch_vect_issue_info; + unsigned int issue_info = la_vect_issue_info; unsigned int reduc_factor = m_reduc_factor > 1 ? m_reduc_factor : 1; unsigned int uf = CEIL (reduc_factor * issue_info, nstmts_nonldst); - uf = MIN ((unsigned int) loongarch_vect_unroll_limit, uf); + uf = MIN ((unsigned int) la_vect_unroll_limit, uf); return 1 << ceil_log2 (uf); } @@ -5371,6 +5371,12 @@ loongarch_expand_conditional_move (rtx *operands) rtx temp3 = gen_reg_rtx (mode); emit_insn (gen_rtx_SET (temp3, gen_rtx_IOR (mode, temp, temp2))); temp3 = gen_lowpart (GET_MODE (operands[0]), temp3); + /* Nonzero in a subreg if it was made when accessing an object that + was promoted to a wider mode in accord with the PROMOTED_MODE + machine description macro. */ + SUBREG_PROMOTED_VAR_P (temp3) = 1; + /* Sets promoted mode for SUBREG_PROMOTED_VAR_P. */ + SUBREG_PROMOTED_SET (temp3, SRP_SIGNED); loongarch_emit_move (operands[0], temp3); } else @@ -5544,7 +5550,7 @@ loongarch_expand_block_move (rtx dest, rtx src, rtx r_length, rtx r_align) return false; HOST_WIDE_INT length = INTVAL (r_length); - if (length > loongarch_max_inline_memcpy_size) + if (length > la_max_inline_memcpy_size) return false; HOST_WIDE_INT align = INTVAL (r_align); @@ -6111,7 +6117,7 @@ loongarch_print_operand (FILE *file, rtx op, int letter) if (loongarch_cas_failure_memorder_needs_acquire ( memmodel_from_int (INTVAL (op)))) fputs ("dbar\t0b10100", file); - else if (!TARGET_LD_SEQ_SA) + else if (!ISA_HAS_LD_SEQ_SA) fputs ("dbar\t0x700", file); break; @@ -7513,7 +7519,8 @@ loongarch_option_override_internal (struct gcc_options *opts, loongarch_init_target (&la_target, la_opt_cpu_arch, la_opt_cpu_tune, la_opt_fpu, la_opt_simd, la_opt_abi_base, la_opt_abi_ext, - la_opt_cmodel); + la_opt_cmodel, opts->x_la_isa_evolution, + opts_set->x_la_isa_evolution); /* Handle target-specific options: compute defaults/conflicts etc. */ loongarch_config_target (&la_target, NULL, 0); @@ -7521,25 +7528,6 @@ loongarch_option_override_internal (struct gcc_options *opts, loongarch_update_gcc_opt_status (&la_target, opts, opts_set); loongarch_cpu_option_override (&la_target, opts, opts_set); - if (la_opt_explicit_relocs != M_OPT_UNSET - && la_opt_explicit_relocs_backward != M_OPT_UNSET) - error ("do not use %qs (with %qs) and %qs (without %qs) together", - "-mexplicit-relocs=", "=", - la_opt_explicit_relocs_backward ? "-mexplicit-relocs" - : "-mno-explicit-relocs", "="); - - if (la_opt_explicit_relocs_backward != M_OPT_UNSET) - la_opt_explicit_relocs = (la_opt_explicit_relocs_backward - ? EXPLICIT_RELOCS_ALWAYS - : EXPLICIT_RELOCS_NONE); - - if (la_opt_explicit_relocs == M_OPT_UNSET) - la_opt_explicit_relocs = (HAVE_AS_EXPLICIT_RELOCS - ? (loongarch_mrelax - ? EXPLICIT_RELOCS_AUTO - : EXPLICIT_RELOCS_ALWAYS) - : EXPLICIT_RELOCS_NONE); - if (TARGET_ABI_LP64) flag_pcc_struct_return = 0; @@ -7551,13 +7539,8 @@ loongarch_option_override_internal (struct gcc_options *opts, /* If the user hasn't specified a branch cost, use the processor's default. */ - if (loongarch_branch_cost == 0) - loongarch_branch_cost = loongarch_cost->branch_cost; - - /* If the user hasn't disabled a feature added during ISA evolution, - use the processor's default. */ - isa_evolution |= (la_target.isa.evolution & - ~global_options_set.x_isa_evolution); + if (la_branch_cost == 0) + la_branch_cost = loongarch_cost->branch_cost; /* Enable sw prefetching at -O3 and higher. */ if (opts->x_flag_prefetch_loop_arrays < 0 @@ -7644,9 +7627,9 @@ loongarch_option_override_internal (struct gcc_options *opts, { "vec-rsqrt", RECIP_MASK_VEC_RSQRT }, }; - if (loongarch_recip_name) + if (la_recip_name) { - char *p = ASTRDUP (loongarch_recip_name); + char *p = ASTRDUP (la_recip_name); char *q; unsigned int mask, i; bool invert; @@ -7687,10 +7670,38 @@ loongarch_option_override_internal (struct gcc_options *opts, recip_mask |= mask; } } - if (loongarch_recip) + if (la_recip) recip_mask |= RECIP_MASK_ALL; - if (!TARGET_FRECIPE) + if (!ISA_HAS_FRECIPE) recip_mask = RECIP_MASK_NONE; + +#define INIT_TARGET_FLAG(NAME, INIT) \ + { \ + if (!(target_flags_explicit & MASK_##NAME)) \ + { \ + if (INIT) \ + target_flags |= MASK_##NAME; \ + else \ + target_flags &= ~MASK_##NAME; \ + } \ + } + + /* Enable conditional moves for int and float by default. */ + INIT_TARGET_FLAG (COND_MOVE_INT, 1) + INIT_TARGET_FLAG (COND_MOVE_FLOAT, 1) + + /* Set mrelax default. */ + INIT_TARGET_FLAG (LINKER_RELAXATION, + HAVE_AS_MRELAX_OPTION && HAVE_AS_COND_BRANCH_RELAXATION) + +#undef INIT_TARGET_FLAG + + if (la_opt_explicit_relocs == M_OPT_UNSET) + la_opt_explicit_relocs = (HAVE_AS_EXPLICIT_RELOCS + ? (TARGET_LINKER_RELAXATION + ? EXPLICIT_RELOCS_AUTO + : EXPLICIT_RELOCS_ALWAYS) + : EXPLICIT_RELOCS_NONE); } @@ -7702,6 +7713,31 @@ loongarch_option_override (void) loongarch_option_override_internal (&global_options, &global_options_set); } +/* Implement TARGET_OPTION_SAVE. */ +static void +loongarch_option_save (struct cl_target_option *, + struct gcc_options *opts, + struct gcc_options *opts_set) +{ + loongarch_update_gcc_opt_status (&la_target, opts, opts_set); +} + +/* Implement TARGET_OPTION_RESTORE. */ +static void +loongarch_option_restore (struct gcc_options *, + struct gcc_options *, + struct cl_target_option *ptr) +{ + la_target.cpu_arch = ptr->x_la_opt_cpu_arch; + la_target.cpu_tune = ptr->x_la_opt_cpu_tune; + + la_target.isa.fpu = ptr->x_la_opt_fpu; + la_target.isa.simd = ptr->x_la_opt_simd; + la_target.isa.evolution = ptr->x_la_isa_evolution; + + la_target.cmodel = ptr->x_la_opt_cmodel; +} + /* Implement TARGET_CONDITIONAL_REGISTER_USAGE. */ static void @@ -10880,11 +10916,11 @@ loongarch_asm_code_end (void) loongarch_cpu_strings [la_target.cpu_tune]); fprintf (asm_out_file, "%s Base ISA: %s\n", ASM_COMMENT_START, loongarch_isa_base_strings [la_target.isa.base]); - DUMP_FEATURE (TARGET_FRECIPE); - DUMP_FEATURE (TARGET_DIV32); - DUMP_FEATURE (TARGET_LAM_BH); - DUMP_FEATURE (TARGET_LAMCAS); - DUMP_FEATURE (TARGET_LD_SEQ_SA); + DUMP_FEATURE (ISA_HAS_FRECIPE); + DUMP_FEATURE (ISA_HAS_DIV32); + DUMP_FEATURE (ISA_HAS_LAM_BH); + DUMP_FEATURE (ISA_HAS_LAMCAS); + DUMP_FEATURE (ISA_HAS_LD_SEQ_SA); } fputs ("\n\n", asm_out_file); @@ -10901,6 +10937,10 @@ loongarch_asm_code_end (void) #undef TARGET_OPTION_OVERRIDE #define TARGET_OPTION_OVERRIDE loongarch_option_override +#undef TARGET_OPTION_SAVE +#define TARGET_OPTION_SAVE loongarch_option_save +#undef TARGET_OPTION_RESTORE +#define TARGET_OPTION_RESTORE loongarch_option_restore #undef TARGET_LEGITIMIZE_ADDRESS #define TARGET_LEGITIMIZE_ADDRESS loongarch_legitimize_address diff --git a/gcc/config/loongarch/loongarch.h b/gcc/config/loongarch/loongarch.h index aee334b..4e6ede9 100644 --- a/gcc/config/loongarch/loongarch.h +++ b/gcc/config/loongarch/loongarch.h @@ -868,7 +868,7 @@ typedef struct { /* A C expression for the cost of a branch instruction. A value of 1 is the default; other values are interpreted relative to that. */ -#define BRANCH_COST(speed_p, predictable_p) loongarch_branch_cost +#define BRANCH_COST(speed_p, predictable_p) la_branch_cost /* Return the asm template for a conditional branch instruction. OPCODE is the opcode's mnemonic and OPERANDS is the asm template for diff --git a/gcc/config/loongarch/loongarch.md b/gcc/config/loongarch/loongarch.md index d1f5b94..ebc0476 100644 --- a/gcc/config/loongarch/loongarch.md +++ b/gcc/config/loongarch/loongarch.md @@ -425,7 +425,7 @@ ;; A mode for anything legal as a input of a div or mod instruction. (define_mode_iterator DIV [(DI "TARGET_64BIT") - (SI "!TARGET_64BIT || TARGET_DIV32")]) + (SI "!TARGET_64BIT || ISA_HAS_DIV32")]) ;; In GPR templates, a string like "mul.<d>" will expand to "mul.w" in the ;; 32-bit version and "mul.d" in the 64-bit version. @@ -657,42 +657,87 @@ [(set_attr "type" "fadd") (set_attr "mode" "<UNITMODE>")]) -(define_insn_and_split "add<mode>3" - [(set (match_operand:GPR 0 "register_operand" "=r,r,r,r,r,r,r") - (plus:GPR (match_operand:GPR 1 "register_operand" "r,r,r,r,r,r,r") - (match_operand:GPR 2 "plus_<mode>_operand" - "r,I,La,Lb,Lc,Ld,Le")))] +(define_insn_and_split "*addsi3" + [(set (match_operand:SI 0 "register_operand" "=r,r,r,r,r") + (plus:SI (match_operand:SI 1 "register_operand" "r,r,r,r,r") + (match_operand:SI 2 "plus_si_operand" + "r,I,La,Lb,Le")))] "" "@ - add.<d>\t%0,%1,%2 - addi.<d>\t%0,%1,%2 + add.w\t%0,%1,%2 + addi.w\t%0,%1,%2 # * operands[2] = GEN_INT (INTVAL (operands[2]) / 65536); \ return \"addu16i.d\t%0,%1,%2\"; + #" + "CONST_INT_P (operands[2]) && !IMM12_INT (operands[2]) \ + && !ADDU16I_OPERAND (INTVAL (operands[2]))" + [(set (match_dup 0) (plus:SI (match_dup 1) (match_dup 3))) + (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 4)))] + { + loongarch_split_plus_constant (&operands[2], SImode); + } + [(set_attr "alu_type" "add") + (set_attr "mode" "SI") + (set_attr "insn_count" "1,1,2,1,2")]) + +(define_expand "addsi3" + [(set (match_operand:SI 0 "register_operand" "=r,r,r,r,r") + (plus:SI (match_operand:SI 1 "register_operand" "r,r,r,r,r") + (match_operand:SI 2 "plus_si_operand" "r,I,La,Le,Lb")))] + "TARGET_64BIT" +{ + if (CONST_INT_P (operands[2]) && !IMM12_INT (operands[2]) + && ADDU16I_OPERAND (INTVAL (operands[2]))) + { + rtx t1 = gen_reg_rtx (DImode); + rtx t2 = gen_reg_rtx (DImode); + rtx t3 = gen_reg_rtx (DImode); + emit_insn (gen_extend_insn (t1, operands[1], DImode, SImode, 0)); + t2 = operands[2]; + emit_insn (gen_adddi3 (t3, t1, t2)); + t3 = gen_lowpart (SImode, t3); + emit_move_insn (operands[0], t3); + DONE; + } + else + { + rtx t = gen_reg_rtx (DImode); + emit_insn (gen_addsi3_extended (t, operands[1], operands[2])); + t = gen_lowpart (SImode, t); + SUBREG_PROMOTED_VAR_P (t) = 1; + SUBREG_PROMOTED_SET (t, SRP_SIGNED); + emit_move_insn (operands[0], t); + DONE; + } +}) + +(define_insn_and_split "adddi3" + [(set (match_operand:DI 0 "register_operand" "=r,r,r,r,r,r") + (plus:DI (match_operand:DI 1 "register_operand" "r,r,r,r,r,r") + (match_operand:DI 2 "plus_di_operand" + "r,I,La,Lb,Lc,Ld")))] + "TARGET_64BIT" + "@ + add.d\t%0,%1,%2 + addi.d\t%0,%1,%2 # + * operands[2] = GEN_INT (INTVAL (operands[2]) / 65536); \ + return \"addu16i.d\t%0,%1,%2\"; # #" - "CONST_INT_P (operands[2]) && !IMM12_INT (operands[2]) \ + "&& CONST_INT_P (operands[2]) && !IMM12_INT (operands[2]) \ && !ADDU16I_OPERAND (INTVAL (operands[2]))" - [(set (match_dup 0) (plus:GPR (match_dup 1) (match_dup 3))) - (set (match_dup 0) (plus:GPR (match_dup 0) (match_dup 4)))] + [(set (match_dup 0) (plus:DI (match_dup 1) (match_dup 3))) + (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 4)))] { - loongarch_split_plus_constant (&operands[2], <MODE>mode); + loongarch_split_plus_constant (&operands[2], DImode); } [(set_attr "alu_type" "add") - (set_attr "mode" "<MODE>") - (set_attr "insn_count" "1,1,2,1,2,2,2") - (set (attr "enabled") - (cond - [(match_test "<MODE>mode != DImode && which_alternative == 4") - (const_string "no") - (match_test "<MODE>mode != DImode && which_alternative == 5") - (const_string "no") - (match_test "<MODE>mode != SImode && which_alternative == 6") - (const_string "no")] - (const_string "yes")))]) - -(define_insn_and_split "*addsi3_extended" + (set_attr "mode" "DI") + (set_attr "insn_count" "1,1,2,1,2,2")]) + +(define_insn_and_split "addsi3_extended" [(set (match_operand:DI 0 "register_operand" "=r,r,r,r") (sign_extend:DI (plus:SI (match_operand:SI 1 "register_operand" "r,r,r,r") @@ -736,7 +781,7 @@ (define_insn "sub<mode>3" [(set (match_operand:GPR 0 "register_operand" "=r") - (minus:GPR (match_operand:GPR 1 "register_operand" "rJ") + (minus:GPR (match_operand:GPR 1 "register_operand" "r") (match_operand:GPR 2 "register_operand" "r")))] "" "sub.<d>\t%0,%z1,%2" @@ -941,7 +986,7 @@ [(set (match_operand:ANYF 0 "register_operand" "=f") (unspec:ANYF [(match_operand:ANYF 1 "register_operand" "f")] UNSPEC_RECIPE))] - "TARGET_FRECIPE" + "ISA_HAS_FRECIPE" "frecipe.<fmt>\t%0,%1" [(set_attr "type" "frecipe") (set_attr "mode" "<UNITMODE>") @@ -954,7 +999,7 @@ (match_operand:GPR 2 "register_operand")))] "" { - if (GET_MODE (operands[0]) == SImode && TARGET_64BIT && !TARGET_DIV32) + if (GET_MODE (operands[0]) == SImode && TARGET_64BIT && !ISA_HAS_DIV32) { rtx reg1 = gen_reg_rtx (DImode); rtx reg2 = gen_reg_rtx (DImode); @@ -994,7 +1039,7 @@ (sign_extend (any_div:SI (match_operand:SI 1 "register_operand" "r,r,0") (match_operand:SI 2 "register_operand" "r,r,r"))))] - "TARGET_64BIT && TARGET_DIV32" + "TARGET_64BIT && ISA_HAS_DIV32" { return loongarch_output_division ("<insn>.w<u>\t%0,%1,%2", operands); } @@ -1014,7 +1059,7 @@ (any_div:DI (match_operand:DI 1 "register_operand" "r,r,0") (match_operand:DI 2 "register_operand" "r,r,r")) 0)] UNSPEC_FAKE_ANY_DIV)))] - "TARGET_64BIT && !TARGET_DIV32" + "TARGET_64BIT && !ISA_HAS_DIV32" { return loongarch_output_division ("<insn>.w<u>\t%0,%1,%2", operands); } @@ -1197,7 +1242,7 @@ [(set (match_operand:ANYF 0 "register_operand" "=f") (unspec:ANYF [(match_operand:ANYF 1 "register_operand" "f")] UNSPEC_RSQRTE))] - "TARGET_FRECIPE" + "ISA_HAS_FRECIPE" "frsqrte.<fmt>\t%0,%1" [(set_attr "type" "frsqrte") (set_attr "mode" "<UNITMODE>")]) @@ -1412,13 +1457,13 @@ [(set_attr "alu_type" "sub") (set_attr "mode" "<MODE>")]) -(define_insn "one_cmpl<mode>2" - [(set (match_operand:GPR 0 "register_operand" "=r") - (not:GPR (match_operand:GPR 1 "register_operand" "r")))] - "" - "nor\t%0,%.,%1" - [(set_attr "alu_type" "not") - (set_attr "mode" "<MODE>")]) +(define_insn "*negsi2_extended" + [(set (match_operand:DI 0 "register_operand" "=r") + (sign_extend:DI (neg:SI (match_operand:SI 1 "register_operand" "r"))))] + "TARGET_64BIT" + "sub.w\t%0,%.,%1" + [(set_attr "alu_type" "sub") + (set_attr "mode" "SI")]) (define_insn "neg<mode>2" [(set (match_operand:ANYF 0 "register_operand" "=f") @@ -1438,14 +1483,39 @@ ;; (define_insn "<optab><mode>3" - [(set (match_operand:GPR 0 "register_operand" "=r,r") - (any_bitwise:GPR (match_operand:GPR 1 "register_operand" "%r,r") - (match_operand:GPR 2 "uns_arith_operand" "r,K")))] + [(set (match_operand:X 0 "register_operand" "=r,r") + (any_bitwise:X (match_operand:X 1 "register_operand" "%r,r") + (match_operand:X 2 "uns_arith_operand" "r,K")))] "" "<insn>%i2\t%0,%1,%2" [(set_attr "type" "logical") (set_attr "mode" "<MODE>")]) +(define_insn "*<optab>si3_internal" + [(set (match_operand:SI 0 "register_operand" "=r,r") + (any_bitwise:SI (match_operand:SI 1 "register_operand" "%r,r") + (match_operand:SI 2 "uns_arith_operand" " r,K")))] + "TARGET_64BIT" + "<insn>%i2\t%0,%1,%2" + [(set_attr "type" "logical") + (set_attr "mode" "SI")]) + +(define_insn "one_cmpl<mode>2" + [(set (match_operand:X 0 "register_operand" "=r") + (not:X (match_operand:X 1 "register_operand" "r")))] + "" + "nor\t%0,%.,%1" + [(set_attr "alu_type" "not") + (set_attr "mode" "<MODE>")]) + +(define_insn "*one_cmplsi2_internal" + [(set (match_operand:SI 0 "register_operand" "=r") + (not:SI (match_operand:SI 1 "register_operand" " r")))] + "TARGET_64BIT" + "nor\t%0,%.,%1" + [(set_attr "type" "logical") + (set_attr "mode" "SI")]) + (define_insn "and<mode>3_extended" [(set (match_operand:GPR 0 "register_operand" "=r") (and:GPR (match_operand:GPR 1 "nonimmediate_operand" "r") @@ -1561,25 +1631,43 @@ [(set_attr "type" "logical") (set_attr "mode" "HI")]) -(define_insn "*nor<mode>3" - [(set (match_operand:GPR 0 "register_operand" "=r") - (and:GPR (not:GPR (match_operand:GPR 1 "register_operand" "%r")) - (not:GPR (match_operand:GPR 2 "register_operand" "r"))))] +(define_insn "nor<mode>3" + [(set (match_operand:X 0 "register_operand" "=r") + (and:X (not:X (match_operand:X 1 "register_operand" "%r")) + (not:X (match_operand:X 2 "register_operand" "r"))))] "" "nor\t%0,%1,%2" [(set_attr "type" "logical") (set_attr "mode" "<MODE>")]) +(define_insn "*norsi3_internal" + [(set (match_operand:SI 0 "register_operand" "=r") + (and:SI (not:SI (match_operand:SI 1 "register_operand" "%r")) + (not:SI (match_operand:SI 2 "register_operand" "r"))))] + "TARGET_64BIT" + "nor\t%0,%1,%2" + [(set_attr "type" "logical") + (set_attr "mode" "SI")]) + (define_insn "<optab>n<mode>" - [(set (match_operand:GPR 0 "register_operand" "=r") - (neg_bitwise:GPR - (not:GPR (match_operand:GPR 1 "register_operand" "r")) - (match_operand:GPR 2 "register_operand" "r")))] + [(set (match_operand:X 0 "register_operand" "=r") + (neg_bitwise:X + (not:X (match_operand:X 1 "register_operand" "r")) + (match_operand:X 2 "register_operand" "r")))] "" "<insn>n\t%0,%2,%1" [(set_attr "type" "logical") (set_attr "mode" "<MODE>")]) +(define_insn "*<optab>nsi_internal" + [(set (match_operand:SI 0 "register_operand" "=r") + (neg_bitwise:SI + (not:SI (match_operand:SI 1 "register_operand" "r")) + (match_operand:SI 2 "register_operand" "r")))] + "TARGET_64BIT" + "<insn>n\t%0,%2,%1" + [(set_attr "type" "logical") + (set_attr "mode" "SI")]) ;; ;; .................... @@ -3167,7 +3255,6 @@ (label_ref (match_operand 1)) (pc)))]) - ;; ;; .................... @@ -3967,10 +4054,13 @@ (define_insn "bytepick_w_<bytepick_imm>_extend" [(set (match_operand:DI 0 "register_operand" "=r") (sign_extend:DI - (ior:SI (lshiftrt (match_operand:SI 1 "register_operand" "r") - (const_int <bytepick_w_lshiftrt_amount>)) - (ashift (match_operand:SI 2 "register_operand" "r") - (const_int bytepick_w_ashift_amount)))))] + (subreg:SI + (ior:DI (subreg:DI (lshiftrt + (match_operand:SI 1 "register_operand" "r") + (const_int <bytepick_w_lshiftrt_amount>)) 0) + (subreg:DI (ashift + (match_operand:SI 2 "register_operand" "r") + (const_int bytepick_w_ashift_amount)) 0)) 0)))] "TARGET_64BIT" "bytepick.w\t%0,%1,%2,<bytepick_imm>" [(set_attr "mode" "SI")]) diff --git a/gcc/config/loongarch/loongarch.opt b/gcc/config/loongarch/loongarch.opt index b285a74..f10fcdd 100644 --- a/gcc/config/loongarch/loongarch.opt +++ b/gcc/config/loongarch/loongarch.opt @@ -41,7 +41,7 @@ Name(isa_base) Type(int) Basic ISAs of LoongArch: EnumValue -Enum(isa_base) String(la64) Value(ISA_BASE_LA64V100) +Enum(isa_base) String(la64) Value(ISA_BASE_LA64) ;; ISA extensions / adjustments Enum @@ -58,7 +58,7 @@ EnumValue Enum(isa_ext_fpu) String(64) Value(ISA_EXT_FPU64) mfpu= -Target RejectNegative Joined ToLower Enum(isa_ext_fpu) Var(la_opt_fpu) Init(M_OPT_UNSET) +Target RejectNegative Joined ToLower Enum(isa_ext_fpu) Var(la_opt_fpu) Init(M_OPT_UNSET) Save -mfpu=FPU Generate code for the given FPU. mfpu=0 @@ -90,7 +90,7 @@ EnumValue Enum(isa_ext_simd) String(lasx) Value(ISA_EXT_SIMD_LASX) msimd= -Target RejectNegative Joined ToLower Enum(isa_ext_simd) Var(la_opt_simd) Init(M_OPT_UNSET) +Target RejectNegative Joined ToLower Enum(isa_ext_simd) Var(la_opt_simd) Init(M_OPT_UNSET) Save -msimd=SIMD Generate code for the given SIMD extension. mlsx @@ -122,11 +122,11 @@ EnumValue Enum(cpu_type) String(la664) Value(CPU_LA664) march= -Target RejectNegative Joined Enum(cpu_type) Var(la_opt_cpu_arch) Init(M_OPT_UNSET) +Target RejectNegative Joined Enum(cpu_type) Var(la_opt_cpu_arch) Init(M_OPT_UNSET) Save -march=PROCESSOR Generate code for the given PROCESSOR ISA. mtune= -Target RejectNegative Joined Enum(cpu_type) Var(la_opt_cpu_tune) Init(M_OPT_UNSET) +Target RejectNegative Joined Enum(cpu_type) Var(la_opt_cpu_tune) Init(M_OPT_UNSET) Save -mtune=PROCESSOR Generate optimized code for PROCESSOR. @@ -157,31 +157,31 @@ Variable int la_opt_abi_ext = M_OPT_UNSET mbranch-cost= -Target RejectNegative Joined UInteger Var(loongarch_branch_cost) +Target RejectNegative Joined UInteger Var(la_branch_cost) Save -mbranch-cost=COST Set the cost of branches to roughly COST instructions. mcheck-zero-division -Target Mask(CHECK_ZERO_DIV) +Target Mask(CHECK_ZERO_DIV) Save Trap on integer divide by zero. mcond-move-int -Target Var(TARGET_COND_MOVE_INT) Init(1) +Target Mask(COND_MOVE_INT) Save Conditional moves for integral are enabled. mcond-move-float -Target Var(TARGET_COND_MOVE_FLOAT) Init(1) +Target Mask(COND_MOVE_FLOAT) Save Conditional moves for float are enabled. mmemcpy -Target Mask(MEMCPY) +Target Mask(MEMCPY) Save Prevent optimizing block moves, which is also the default behavior of -Os. mstrict-align -Target Var(TARGET_STRICT_ALIGN) Init(0) +Target Mask(STRICT_ALIGN) Save Do not generate unaligned memory accesses. mmax-inline-memcpy-size= -Target Joined RejectNegative UInteger Var(loongarch_max_inline_memcpy_size) Init(1024) +Target Joined RejectNegative UInteger Var(la_max_inline_memcpy_size) Init(1024) Save -mmax-inline-memcpy-size=SIZE Set the max size of memcpy to inline, default is 1024. Enum @@ -202,15 +202,15 @@ Target RejectNegative Joined Enum(explicit_relocs) Var(la_opt_explicit_relocs) I Use %reloc() assembly operators. mexplicit-relocs -Target Var(la_opt_explicit_relocs_backward) Init(M_OPT_UNSET) +Target Alias(mexplicit-relocs=, always, none) Use %reloc() assembly operators (for backward compatibility). mrecip -Target RejectNegative Var(loongarch_recip) +Target RejectNegative Var(la_recip) Save Generate approximate reciprocal divide and square root for better throughput. mrecip= -Target RejectNegative Joined Var(loongarch_recip_name) +Target RejectNegative Joined Var(la_recip_name) Save Control generation of reciprocal estimates. ; The code model option names for -mcmodel. @@ -237,29 +237,29 @@ EnumValue Enum(cmodel) String(extreme) Value(CMODEL_EXTREME) mcmodel= -Target RejectNegative Joined Enum(cmodel) Var(la_opt_cmodel) Init(M_OPT_UNSET) +Target RejectNegative Joined Enum(cmodel) Var(la_opt_cmodel) Init(M_OPT_UNSET) Save Specify the code model. mdirect-extern-access -Target Var(TARGET_DIRECT_EXTERN_ACCESS) Init(0) +Target Mask(DIRECT_EXTERN_ACCESS) Save Avoid using the GOT to access external symbols. mrelax -Target Var(loongarch_mrelax) Init(HAVE_AS_MRELAX_OPTION && HAVE_AS_COND_BRANCH_RELAXATION) +Target Mask(LINKER_RELAXATION) Take advantage of linker relaxations to reduce the number of instructions required to materialize symbol addresses. mpass-mrelax-to-as -Target Var(loongarch_pass_mrelax_to_as) Init(HAVE_AS_MRELAX_OPTION) +Driver Var(la_pass_mrelax_to_as) Init(HAVE_AS_MRELAX_OPTION) Pass -mrelax or -mno-relax option to the assembler. -param=loongarch-vect-unroll-limit= -Target Joined UInteger Var(loongarch_vect_unroll_limit) Init(6) IntegerRange(1, 64) Param +Target Joined UInteger Var(la_vect_unroll_limit) Init(6) IntegerRange(1, 64) Param Used to limit unroll factor which indicates how much the autovectorizer may unroll a loop. The default value is 6. -param=loongarch-vect-issue-info= -Target Undocumented Joined UInteger Var(loongarch_vect_issue_info) Init(4) IntegerRange(1, 64) Param +Target Undocumented Joined UInteger Var(la_vect_issue_info) Init(4) IntegerRange(1, 64) Param Indicate how many non memory access vector instructions can be issued per cycle, it's used in unroll factor determination for autovectorizer. The default value is 4. @@ -267,26 +267,26 @@ default value is 4. ; Features added during ISA evolution. This concept is different from ISA ; extension, read Section 1.5 of LoongArch v1.10 Volume 1 for the ; explanation. These features may be implemented and enumerated with -; CPUCFG independantly, so we use bit flags to specify them. -Variable -HOST_WIDE_INT isa_evolution = 0 +; CPUCFG independently, so we use bit flags to specify them. +TargetVariable +HOST_WIDE_INT la_isa_evolution = 0 mfrecipe -Target Mask(ISA_FRECIPE) Var(isa_evolution) +Target Mask(ISA_FRECIPE) Var(la_isa_evolution) Support frecipe.{s/d} and frsqrte.{s/d} instructions. mdiv32 -Target Mask(ISA_DIV32) Var(isa_evolution) +Target Mask(ISA_DIV32) Var(la_isa_evolution) Support div.w[u] and mod.w[u] instructions with inputs not sign-extended. mlam-bh -Target Mask(ISA_LAM_BH) Var(isa_evolution) +Target Mask(ISA_LAM_BH) Var(la_isa_evolution) Support am{swap/add}[_db].{b/h} instructions. mlamcas -Target Mask(ISA_LAMCAS) Var(isa_evolution) +Target Mask(ISA_LAMCAS) Var(la_isa_evolution) Support amcas[_db].{b/h/w/d} instructions. mld-seq-sa -Target Mask(ISA_LD_SEQ_SA) Var(isa_evolution) +Target Mask(ISA_LD_SEQ_SA) Var(la_isa_evolution) Do not need load-load barriers (dbar 0x700). diff --git a/gcc/config/loongarch/lsx.md b/gcc/config/loongarch/lsx.md index 91ce774..7002eda 100644 --- a/gcc/config/loongarch/lsx.md +++ b/gcc/config/loongarch/lsx.md @@ -1479,7 +1479,7 @@ [(set (match_operand:FLSX 0 "register_operand" "=f") (unspec:FLSX [(match_operand:FLSX 1 "register_operand" "f")] UNSPEC_LSX_VFRECIPE))] - "ISA_HAS_LSX && TARGET_FRECIPE" + "ISA_HAS_LSX && ISA_HAS_FRECIPE" "vfrecipe.<flsxfmt>\t%w0,%w1" [(set_attr "type" "simd_fdiv") (set_attr "mode" "<MODE>")]) @@ -1512,7 +1512,7 @@ [(set (match_operand:FLSX 0 "register_operand" "=f") (unspec:FLSX [(match_operand:FLSX 1 "register_operand" "f")] UNSPEC_LSX_VFRSQRTE))] - "ISA_HAS_LSX && TARGET_FRECIPE" + "ISA_HAS_LSX && ISA_HAS_FRECIPE" "vfrsqrte.<flsxfmt>\t%w0,%w1" [(set_attr "type" "simd_fdiv") (set_attr "mode" "<MODE>")]) diff --git a/gcc/config/loongarch/sync.md b/gcc/config/loongarch/sync.md index 71954f9..8f35a5b 100644 --- a/gcc/config/loongarch/sync.md +++ b/gcc/config/loongarch/sync.md @@ -124,9 +124,9 @@ return "ld.<size>\t%0,%1\\n\\t" "dbar\t0x14"; case MEMMODEL_RELAXED: - return TARGET_LD_SEQ_SA ? "ld.<size>\t%0,%1" - : "ld.<size>\t%0,%1\\n\\t" - "dbar\t0x700"; + return ISA_HAS_LD_SEQ_SA ? "ld.<size>\t%0,%1" + : "ld.<size>\t%0,%1\\n\\t" + "dbar\t0x700"; default: /* The valid memory order variants are __ATOMIC_RELAXED, __ATOMIC_SEQ_CST, @@ -193,7 +193,7 @@ (match_operand:SHORT 1 "reg_or_0_operand" "rJ")) (match_operand:SI 2 "const_int_operand")] ;; model UNSPEC_SYNC_OLD_OP))] - "TARGET_LAM_BH" + "ISA_HAS_LAM_BH" "amadd%A2.<amo>\t$zero,%z1,%0" [(set (attr "length") (const_int 4))]) @@ -230,7 +230,7 @@ UNSPEC_SYNC_EXCHANGE)) (set (match_dup 1) (match_operand:SHORT 2 "register_operand" "r"))] - "TARGET_LAM_BH" + "ISA_HAS_LAM_BH" "amswap%A3.<amo>\t%0,%z2,%1" [(set (attr "length") (const_int 4))]) @@ -266,7 +266,7 @@ (match_operand:QHWD 3 "reg_or_0_operand" "rJ") (match_operand:SI 4 "const_int_operand")] ;; mod_s UNSPEC_COMPARE_AND_SWAP))] - "TARGET_LAMCAS" + "ISA_HAS_LAMCAS" "ori\t%0,%z2,0\n\tamcas%A4.<amo>\t%0,%z3,%1" [(set (attr "length") (const_int 8))]) @@ -296,7 +296,7 @@ operands[6] = mod_s; - if (TARGET_LAMCAS) + if (ISA_HAS_LAMCAS) emit_insn (gen_atomic_cas_value_strong<mode>_amcas (operands[1], operands[2], operands[3], operands[4], operands[6])); @@ -422,7 +422,7 @@ operands[6] = mod_s; - if (TARGET_LAMCAS) + if (ISA_HAS_LAMCAS) emit_insn (gen_atomic_cas_value_strong<mode>_amcas (operands[1], operands[2], operands[3], operands[4], operands[6])); @@ -642,7 +642,7 @@ (match_operand:SHORT 2 "register_operand"))] "" { - if (TARGET_LAM_BH) + if (ISA_HAS_LAM_BH) emit_insn (gen_atomic_exchange<mode>_short (operands[0], operands[1], operands[2], operands[3])); else { @@ -663,7 +663,7 @@ (match_operand:SHORT 2 "reg_or_0_operand" "rJ")) (match_operand:SI 3 "const_int_operand")] ;; model UNSPEC_SYNC_OLD_OP))] - "TARGET_LAM_BH" + "ISA_HAS_LAM_BH" "amadd%A3.<amo>\t%0,%z2,%1" [(set (attr "length") (const_int 4))]) @@ -678,7 +678,7 @@ UNSPEC_SYNC_OLD_OP))] "" { - if (TARGET_LAM_BH) + if (ISA_HAS_LAM_BH) emit_insn (gen_atomic_fetch_add<mode>_short (operands[0], operands[1], operands[2], operands[3])); else diff --git a/gcc/config/mips/mips.cc b/gcc/config/mips/mips.cc index 60b336e..e752019 100644 --- a/gcc/config/mips/mips.cc +++ b/gcc/config/mips/mips.cc @@ -7330,7 +7330,8 @@ mips_start_unique_function (const char *name) function contains MIPS16 code. */ static void -mips_start_function_definition (const char *name, bool mips16_p, tree decl) +mips_start_function_definition (const char *name, bool mips16_p, + tree decl ATTRIBUTE_UNUSED) { if (mips16_p) fprintf (asm_out_file, "\t.set\tmips16\n"); diff --git a/gcc/config/mips/mips.md b/gcc/config/mips/mips.md index 17dfcbd..b0fb585 100644 --- a/gcc/config/mips/mips.md +++ b/gcc/config/mips/mips.md @@ -3440,16 +3440,16 @@ (set_attr "compression" "micromips,*,*") (set_attr "mode" "<MODE>")]) -(define_insn "*ior<mode>3_mips16_asmacro" - [(set (match_operand:GPR 0 "register_operand" "=d,d") - (ior:GPR (match_operand:GPR 1 "register_operand" "%0,0") - (match_operand:GPR 2 "uns_arith_operand" "d,K")))] +(define_insn "*iorsi3_mips16_asmacro" + [(set (match_operand:SI 0 "register_operand" "=d,d") + (ior:SI (match_operand:SI 1 "register_operand" "%0,0") + (match_operand:SI 2 "uns_arith_operand" "d,K")))] "ISA_HAS_MIPS16E2" "@ or\t%0,%2 ori\t%0,%x2" [(set_attr "alu_type" "or") - (set_attr "mode" "<MODE>") + (set_attr "mode" "SI") (set_attr "extended_mips16" "*,yes")]) (define_insn "*ior<mode>3_mips16" diff --git a/gcc/config/riscv/autovec.md b/gcc/config/riscv/autovec.md index 775eaa8..706cd97 100644 --- a/gcc/config/riscv/autovec.md +++ b/gcc/config/riscv/autovec.md @@ -2345,39 +2345,39 @@ ;; op[0] = (narrow) ((wide) op[1] + (wide) op[2] + 1)) >> 1; ;; ------------------------------------------------------------------------- -(define_expand "<u>avg<v_double_trunc>3_floor" +(define_expand "avg<v_double_trunc>3_floor" [(set (match_operand:<V_DOUBLE_TRUNC> 0 "register_operand") (truncate:<V_DOUBLE_TRUNC> - (<ext_to_rshift>:VWEXTI + (ashiftrt:VWEXTI (plus:VWEXTI - (any_extend:VWEXTI + (sign_extend:VWEXTI (match_operand:<V_DOUBLE_TRUNC> 1 "register_operand")) - (any_extend:VWEXTI + (sign_extend:VWEXTI (match_operand:<V_DOUBLE_TRUNC> 2 "register_operand"))))))] "TARGET_VECTOR" { /* First emit a widening addition. */ rtx tmp1 = gen_reg_rtx (<MODE>mode); rtx ops1[] = {tmp1, operands[1], operands[2]}; - insn_code icode = code_for_pred_dual_widen (PLUS, <CODE>, <MODE>mode); + insn_code icode = code_for_pred_dual_widen (PLUS, SIGN_EXTEND, <MODE>mode); riscv_vector::emit_vlmax_insn (icode, riscv_vector::BINARY_OP, ops1); /* Then a narrowing shift. */ rtx ops2[] = {operands[0], tmp1, const1_rtx}; - icode = code_for_pred_narrow_scalar (<EXT_TO_RSHIFT>, <MODE>mode); + icode = code_for_pred_narrow_scalar (ASHIFTRT, <MODE>mode); riscv_vector::emit_vlmax_insn (icode, riscv_vector::BINARY_OP, ops2); DONE; }) -(define_expand "<u>avg<v_double_trunc>3_ceil" +(define_expand "avg<v_double_trunc>3_ceil" [(set (match_operand:<V_DOUBLE_TRUNC> 0 "register_operand") (truncate:<V_DOUBLE_TRUNC> - (<ext_to_rshift>:VWEXTI + (ashiftrt:VWEXTI (plus:VWEXTI (plus:VWEXTI - (any_extend:VWEXTI + (sign_extend:VWEXTI (match_operand:<V_DOUBLE_TRUNC> 1 "register_operand")) - (any_extend:VWEXTI + (sign_extend:VWEXTI (match_operand:<V_DOUBLE_TRUNC> 2 "register_operand"))) (const_int 1)))))] "TARGET_VECTOR" @@ -2385,7 +2385,7 @@ /* First emit a widening addition. */ rtx tmp1 = gen_reg_rtx (<MODE>mode); rtx ops1[] = {tmp1, operands[1], operands[2]}; - insn_code icode = code_for_pred_dual_widen (PLUS, <CODE>, <MODE>mode); + insn_code icode = code_for_pred_dual_widen (PLUS, SIGN_EXTEND, <MODE>mode); riscv_vector::emit_vlmax_insn (icode, riscv_vector::BINARY_OP, ops1); /* Then add 1. */ @@ -2396,11 +2396,37 @@ /* Finally, a narrowing shift. */ rtx ops3[] = {operands[0], tmp2, const1_rtx}; - icode = code_for_pred_narrow_scalar (<EXT_TO_RSHIFT>, <MODE>mode); + icode = code_for_pred_narrow_scalar (ASHIFTRT, <MODE>mode); riscv_vector::emit_vlmax_insn (icode, riscv_vector::BINARY_OP, ops3); DONE; }) +;; csrwi vxrm, 2 +;; vaaddu.vv vd, vs2, vs1 +(define_expand "uavg<mode>3_floor" + [(match_operand:V_VLSI 0 "register_operand") + (match_operand:V_VLSI 1 "register_operand") + (match_operand:V_VLSI 2 "register_operand")] + "TARGET_VECTOR" +{ + insn_code icode = code_for_pred (UNSPEC_VAADDU, <MODE>mode); + riscv_vector::emit_vlmax_insn (icode, riscv_vector::BINARY_OP_VXRM_RDN, operands); + DONE; +}) + +;; csrwi vxrm, 0 +;; vaaddu.vv vd, vs2, vs1 +(define_expand "uavg<mode>3_ceil" + [(match_operand:V_VLSI 0 "register_operand") + (match_operand:V_VLSI 1 "register_operand") + (match_operand:V_VLSI 2 "register_operand")] + "TARGET_VECTOR" +{ + insn_code icode = code_for_pred (UNSPEC_VAADDU, <MODE>mode); + riscv_vector::emit_vlmax_insn (icode, riscv_vector::BINARY_OP_VXRM_RNU, operands); + DONE; +}) + ;; ------------------------------------------------------------------------- ;; ---- [FP] Rounding. ;; ------------------------------------------------------------------------- diff --git a/gcc/config/riscv/bitmanip.md b/gcc/config/riscv/bitmanip.md index fdab001..ccda25c 100644 --- a/gcc/config/riscv/bitmanip.md +++ b/gcc/config/riscv/bitmanip.md @@ -443,8 +443,8 @@ ;; orc.b (or-combine) is added as an unspec for the benefit of the support ;; for optimized string functions (such as strcmp). (define_insn "orcb<mode>2" - [(set (match_operand:X 0 "register_operand" "=r") - (unspec:X [(match_operand:X 1 "register_operand" "r")] UNSPEC_ORC_B))] + [(set (match_operand:GPR 0 "register_operand" "=r") + (unspec:GPR [(match_operand:GPR 1 "register_operand" "r")] UNSPEC_ORC_B))] "TARGET_ZBB" "orc.b\t%0,%1" [(set_attr "type" "bitmanip")]) @@ -852,9 +852,9 @@ ;; ZBKC or ZBC extension (define_insn "riscv_clmul_<mode>" - [(set (match_operand:X 0 "register_operand" "=r") - (unspec:X [(match_operand:X 1 "register_operand" "r") - (match_operand:X 2 "register_operand" "r")] + [(set (match_operand:GPR 0 "register_operand" "=r") + (unspec:GPR [(match_operand:GPR 1 "register_operand" "r") + (match_operand:GPR 2 "register_operand" "r")] UNSPEC_CLMUL))] "TARGET_ZBKC || TARGET_ZBC" "clmul\t%0,%1,%2" diff --git a/gcc/config/riscv/crypto.md b/gcc/config/riscv/crypto.md index bf613fc..dd2bc94 100644 --- a/gcc/config/riscv/crypto.md +++ b/gcc/config/riscv/crypto.md @@ -72,8 +72,8 @@ ;; ZBKB extension (define_insn "riscv_brev8_<mode>" - [(set (match_operand:X 0 "register_operand" "=r") - (unspec:X [(match_operand:X 1 "register_operand" "r")] + [(set (match_operand:GPR 0 "register_operand" "=r") + (unspec:GPR [(match_operand:GPR 1 "register_operand" "r")] UNSPEC_BREV8))] "TARGET_ZBKB" "brev8\t%0,%1" diff --git a/gcc/config/riscv/riscv-builtins.cc b/gcc/config/riscv/riscv-builtins.cc index e851693..1932ff0 100644 --- a/gcc/config/riscv/riscv-builtins.cc +++ b/gcc/config/riscv/riscv-builtins.cc @@ -105,6 +105,7 @@ AVAIL (zero32, TARGET_ZICBOZ && !TARGET_64BIT) AVAIL (zero64, TARGET_ZICBOZ && TARGET_64BIT) AVAIL (prefetchi32, TARGET_ZICBOP && !TARGET_64BIT) AVAIL (prefetchi64, TARGET_ZICBOP && TARGET_64BIT) +AVAIL (crypto_zbkb, TARGET_ZBKB) AVAIL (crypto_zbkb32, TARGET_ZBKB && !TARGET_64BIT) AVAIL (crypto_zbkb64, TARGET_ZBKB && TARGET_64BIT) AVAIL (crypto_zbkx32, TARGET_ZBKX && !TARGET_64BIT) @@ -119,10 +120,15 @@ AVAIL (crypto_zknh32, TARGET_ZKNH && !TARGET_64BIT) AVAIL (crypto_zknh64, TARGET_ZKNH && TARGET_64BIT) AVAIL (crypto_zksh, TARGET_ZKSH) AVAIL (crypto_zksed, TARGET_ZKSED) +AVAIL (clmul_zbkc_or_zbc, (TARGET_ZBKC || TARGET_ZBC)) AVAIL (clmul_zbkc32_or_zbc32, (TARGET_ZBKC || TARGET_ZBC) && !TARGET_64BIT) AVAIL (clmul_zbkc64_or_zbc64, (TARGET_ZBKC || TARGET_ZBC) && TARGET_64BIT) AVAIL (clmulr_zbc32, TARGET_ZBC && !TARGET_64BIT) AVAIL (clmulr_zbc64, TARGET_ZBC && TARGET_64BIT) +AVAIL (zbb, TARGET_ZBB) +AVAIL (zbb64, TARGET_ZBB && TARGET_64BIT) +AVAIL (zbb64_or_zbkb64, (TARGET_ZBKB || TARGET_ZBB) && TARGET_64BIT) +AVAIL (zbb_or_zbkb, (TARGET_ZBKB || TARGET_ZBB)) AVAIL (hint_pause, (!0)) // CORE-V AVAIL @@ -146,6 +152,22 @@ AVAIL (cvelw, TARGET_XCVELW && !TARGET_64BIT) { CODE_FOR_riscv_ ## INSN, "__builtin_riscv_" NAME, \ BUILTIN_TYPE, FUNCTION_TYPE, riscv_builtin_avail_ ## AVAIL } +/* Construct a riscv_builtin_description from the given arguments like RISCV_BUILTIN. + + INSN is the name of the associated instruction pattern, without the + leading CODE_FOR_. + + NAME is the name of the function itself, without the leading + "__builtin_riscv_". + + BUILTIN_TYPE and FUNCTION_TYPE are riscv_builtin_description fields. + + AVAIL is the name of the availability predicate, without the leading + riscv_builtin_avail_. */ +#define RISCV_BUILTIN_NO_PREFIX(INSN, NAME, BUILTIN_TYPE, FUNCTION_TYPE, AVAIL) \ + { CODE_FOR_ ## INSN, "__builtin_riscv_" NAME, \ + BUILTIN_TYPE, FUNCTION_TYPE, riscv_builtin_avail_ ## AVAIL } + /* Define __builtin_riscv_<INSN>, which is a RISCV_BUILTIN_DIRECT function mapped to instruction CODE_FOR_riscv_<INSN>, FUNCTION_TYPE and AVAIL are as for RISCV_BUILTIN. */ diff --git a/gcc/config/riscv/riscv-cmo.def b/gcc/config/riscv/riscv-cmo.def index ff713b7..78cf1d8 100644 --- a/gcc/config/riscv/riscv-cmo.def +++ b/gcc/config/riscv/riscv-cmo.def @@ -17,11 +17,11 @@ RISCV_BUILTIN (prefetchi_si, "zicbop_cbo_prefetchi", RISCV_BUILTIN_DIRECT, RISCV RISCV_BUILTIN (prefetchi_di, "zicbop_cbo_prefetchi", RISCV_BUILTIN_DIRECT, RISCV_UDI_FTYPE_UDI, prefetchi64), // zbkc or zbc -RISCV_BUILTIN (clmul_si, "clmul", RISCV_BUILTIN_DIRECT, RISCV_USI_FTYPE_USI_USI, clmul_zbkc32_or_zbc32), -RISCV_BUILTIN (clmul_di, "clmul", RISCV_BUILTIN_DIRECT, RISCV_UDI_FTYPE_UDI_UDI, clmul_zbkc64_or_zbc64), -RISCV_BUILTIN (clmulh_si, "clmulh", RISCV_BUILTIN_DIRECT, RISCV_USI_FTYPE_USI_USI, clmul_zbkc32_or_zbc32), -RISCV_BUILTIN (clmulh_di, "clmulh", RISCV_BUILTIN_DIRECT, RISCV_UDI_FTYPE_UDI_UDI, clmul_zbkc64_or_zbc64), +RISCV_BUILTIN (clmul_si, "clmul_32", RISCV_BUILTIN_DIRECT, RISCV_USI_FTYPE_USI_USI, clmul_zbkc_or_zbc), +RISCV_BUILTIN (clmul_di, "clmul_64", RISCV_BUILTIN_DIRECT, RISCV_UDI_FTYPE_UDI_UDI, clmul_zbkc64_or_zbc64), +RISCV_BUILTIN (clmulh_si, "clmulh_32", RISCV_BUILTIN_DIRECT, RISCV_USI_FTYPE_USI_USI, clmul_zbkc32_or_zbc32), +RISCV_BUILTIN (clmulh_di, "clmulh_64", RISCV_BUILTIN_DIRECT, RISCV_UDI_FTYPE_UDI_UDI, clmul_zbkc64_or_zbc64), // zbc -RISCV_BUILTIN (clmulr_si, "clmulr", RISCV_BUILTIN_DIRECT, RISCV_USI_FTYPE_USI_USI, clmulr_zbc32), -RISCV_BUILTIN (clmulr_di, "clmulr", RISCV_BUILTIN_DIRECT, RISCV_UDI_FTYPE_UDI_UDI, clmulr_zbc64), +RISCV_BUILTIN (clmulr_si, "clmulr_32", RISCV_BUILTIN_DIRECT, RISCV_USI_FTYPE_USI_USI, clmulr_zbc32), +RISCV_BUILTIN (clmulr_di, "clmulr_64", RISCV_BUILTIN_DIRECT, RISCV_UDI_FTYPE_UDI_UDI, clmulr_zbc64), diff --git a/gcc/config/riscv/riscv-ftypes.def b/gcc/config/riscv/riscv-ftypes.def index c724f23..5f051df 100644 --- a/gcc/config/riscv/riscv-ftypes.def +++ b/gcc/config/riscv/riscv-ftypes.def @@ -40,9 +40,11 @@ DEF_RISCV_FTYPE (1, (SI, HI)) DEF_RISCV_FTYPE (2, (USI, UQI, UQI)) DEF_RISCV_FTYPE (2, (USI, UHI, UHI)) DEF_RISCV_FTYPE (2, (USI, USI, USI)) +DEF_RISCV_FTYPE (2, (USI, USI, UQI)) DEF_RISCV_FTYPE (2, (UDI, UQI, UQI)) DEF_RISCV_FTYPE (2, (UDI, UHI, UHI)) DEF_RISCV_FTYPE (2, (UDI, USI, USI)) +DEF_RISCV_FTYPE (2, (UDI, UDI, UQI)) DEF_RISCV_FTYPE (2, (UDI, UDI, USI)) DEF_RISCV_FTYPE (2, (UDI, UDI, UDI)) DEF_RISCV_FTYPE (2, (SI, USI, USI)) diff --git a/gcc/config/riscv/riscv-protos.h b/gcc/config/riscv/riscv-protos.h index 00a5b64..21f6dad 100644 --- a/gcc/config/riscv/riscv-protos.h +++ b/gcc/config/riscv/riscv-protos.h @@ -250,6 +250,15 @@ struct scalable_vector_cost : common_vector_cost E.g. fold_left reduction cost, lanes load/store cost, ..., etc. */ }; +/* Additional costs for register copies. Cost is for one register. */ +struct regmove_vector_cost +{ + const int GR2VR; + const int FR2VR; + const int VR2GR; + const int VR2FR; +}; + /* Cost for vector insn classes. */ struct cpu_vector_cost { @@ -276,6 +285,9 @@ struct cpu_vector_cost /* Cost of an VLA modes operations. */ const scalable_vector_cost *vla; + + /* Cost of vector register move operations. */ + const regmove_vector_cost *regmove; }; /* Routines implemented in riscv-selftests.cc. */ @@ -366,6 +378,12 @@ enum insn_flags : unsigned int /* Means INSN has FRM operand and the value is FRM_RNE. */ FRM_RNE_P = 1 << 19, + + /* Means INSN has VXRM operand and the value is VXRM_RNU. */ + VXRM_RNU_P = 1 << 20, + + /* Means INSN has VXRM operand and the value is VXRM_RDN. */ + VXRM_RDN_P = 1 << 21, }; enum insn_type : unsigned int @@ -426,6 +444,8 @@ enum insn_type : unsigned int BINARY_OP_TAMU = __MASK_OP_TAMU | BINARY_OP_P, BINARY_OP_TUMA = __MASK_OP_TUMA | BINARY_OP_P, BINARY_OP_FRM_DYN = BINARY_OP | FRM_DYN_P, + BINARY_OP_VXRM_RNU = BINARY_OP | VXRM_RNU_P, + BINARY_OP_VXRM_RDN = BINARY_OP | VXRM_RDN_P, /* Ternary operator. Always have real merge operand. */ TERNARY_OP = HAS_DEST_P | HAS_MASK_P | USE_ALL_TRUES_MASK_P | HAS_MERGE_P @@ -718,6 +738,9 @@ extern void th_mempair_prepare_save_restore_operands (rtx[4], bool, int, HOST_WIDE_INT, int, HOST_WIDE_INT); extern void th_mempair_save_restore_regs (rtx[4], bool, machine_mode); +extern unsigned int th_int_get_mask (unsigned int); +extern unsigned int th_int_get_save_adjustment (void); +extern rtx th_int_adjust_cfi_prologue (unsigned int); #ifdef RTX_CODE extern const char* th_mempair_output_move (rtx[4], bool, machine_mode, RTX_CODE); @@ -753,5 +776,6 @@ struct riscv_tune_info { const struct riscv_tune_info * riscv_parse_tune (const char *, bool); +const cpu_vector_cost *get_vector_costs (); #endif /* ! GCC_RISCV_PROTOS_H */ diff --git a/gcc/config/riscv/riscv-scalar-crypto.def b/gcc/config/riscv/riscv-scalar-crypto.def index 959d8f5..d66b0fe 100644 --- a/gcc/config/riscv/riscv-scalar-crypto.def +++ b/gcc/config/riscv/riscv-scalar-crypto.def @@ -29,8 +29,8 @@ RISCV_BUILTIN (packw, "packw", RISCV_BUILTIN_DIRECT, RISCV_UDI_FTYPE_UHI_UHI, cr RISCV_BUILTIN (zip, "zip", RISCV_BUILTIN_DIRECT, RISCV_USI_FTYPE_USI, crypto_zbkb32), RISCV_BUILTIN (unzip, "unzip", RISCV_BUILTIN_DIRECT, RISCV_USI_FTYPE_USI, crypto_zbkb32), -RISCV_BUILTIN (brev8_si, "brev8", RISCV_BUILTIN_DIRECT, RISCV_USI_FTYPE_USI, crypto_zbkb32), -RISCV_BUILTIN (brev8_di, "brev8", RISCV_BUILTIN_DIRECT, RISCV_UDI_FTYPE_UDI, crypto_zbkb64), +RISCV_BUILTIN (brev8_si, "brev8_32", RISCV_BUILTIN_DIRECT, RISCV_USI_FTYPE_USI, crypto_zbkb), +RISCV_BUILTIN (brev8_di, "brev8_64", RISCV_BUILTIN_DIRECT, RISCV_UDI_FTYPE_UDI, crypto_zbkb64), // ZBKX RISCV_BUILTIN (xperm4_si, "xperm4", RISCV_BUILTIN_DIRECT, RISCV_USI_FTYPE_USI_USI, crypto_zbkx32), @@ -78,3 +78,21 @@ RISCV_BUILTIN (sm3p1_si, "sm3p1", RISCV_BUILTIN_DIRECT, RISCV_USI_FTYPE_USI, cry // ZKSED RISCV_BUILTIN (sm4ed_si, "sm4ed", RISCV_BUILTIN_DIRECT, RISCV_USI_FTYPE_USI_USI_USI, crypto_zksed), RISCV_BUILTIN (sm4ks_si, "sm4ks", RISCV_BUILTIN_DIRECT, RISCV_USI_FTYPE_USI_USI_USI, crypto_zksed), + + +// ZBB + +RISCV_BUILTIN_NO_PREFIX (clzsi2,"clz_32",RISCV_BUILTIN_DIRECT, RISCV_USI_FTYPE_USI,zbb), +RISCV_BUILTIN_NO_PREFIX (clzdi2,"clz_64",RISCV_BUILTIN_DIRECT, RISCV_UDI_FTYPE_UDI,zbb64), +RISCV_BUILTIN_NO_PREFIX (ctzsi2,"ctz_32",RISCV_BUILTIN_DIRECT, RISCV_USI_FTYPE_USI,zbb), +RISCV_BUILTIN_NO_PREFIX (ctzdi2,"ctz_64",RISCV_BUILTIN_DIRECT, RISCV_UDI_FTYPE_UDI,zbb64), +RISCV_BUILTIN_NO_PREFIX (popcountsi2,"popcount_32",RISCV_BUILTIN_DIRECT, RISCV_USI_FTYPE_USI,zbb), +RISCV_BUILTIN_NO_PREFIX (popcountdi2,"popcount_64",RISCV_BUILTIN_DIRECT, RISCV_UDI_FTYPE_UDI,zbb64), +RISCV_BUILTIN_NO_PREFIX (orcbsi2,"orc_b_32", RISCV_BUILTIN_DIRECT, RISCV_USI_FTYPE_USI,zbb), +RISCV_BUILTIN_NO_PREFIX (orcbdi2,"orc_b_64",RISCV_BUILTIN_DIRECT, RISCV_UDI_FTYPE_UDI,zbb64), + +// ZBKB +RISCV_BUILTIN_NO_PREFIX (rotrsi3,"ror_32",RISCV_BUILTIN_DIRECT, RISCV_USI_FTYPE_USI_UQI,zbb_or_zbkb), +RISCV_BUILTIN_NO_PREFIX (rotlsi3,"rol_32",RISCV_BUILTIN_DIRECT, RISCV_USI_FTYPE_USI_UQI,zbb_or_zbkb), +RISCV_BUILTIN_NO_PREFIX (rotrdi3,"ror_64",RISCV_BUILTIN_DIRECT, RISCV_UDI_FTYPE_UDI_UQI,zbb64_or_zbkb64), +RISCV_BUILTIN_NO_PREFIX (rotldi3,"rol_64",RISCV_BUILTIN_DIRECT, RISCV_UDI_FTYPE_UDI_UQI,zbb64_or_zbkb64), diff --git a/gcc/config/riscv/riscv-v.cc b/gcc/config/riscv/riscv-v.cc index 2491522..7ae579b 100644 --- a/gcc/config/riscv/riscv-v.cc +++ b/gcc/config/riscv/riscv-v.cc @@ -207,6 +207,13 @@ public: add_input_operand (frm_rtx, Pmode); } + void + add_rounding_mode_operand (enum fixed_point_rounding_mode rounding_mode) + { + rtx frm_rtx = gen_int_mode (rounding_mode, Pmode); + add_input_operand (frm_rtx, Pmode); + } + /* Return the vtype mode based on insn_flags. vtype mode mean the mode vsetvl insn set. */ machine_mode @@ -334,6 +341,10 @@ public: add_rounding_mode_operand (FRM_RMM); else if (m_insn_flags & FRM_RNE_P) add_rounding_mode_operand (FRM_RNE); + else if (m_insn_flags & VXRM_RNU_P) + add_rounding_mode_operand (VXRM_RNU); + else if (m_insn_flags & VXRM_RDN_P) + add_rounding_mode_operand (VXRM_RDN); gcc_assert (insn_data[(int) icode].n_operands == m_opno); expand (icode, any_mem_p); diff --git a/gcc/config/riscv/riscv-vector-builtins.def b/gcc/config/riscv/riscv-vector-builtins.def index 055ee8b..784b54c 100644 --- a/gcc/config/riscv/riscv-vector-builtins.def +++ b/gcc/config/riscv/riscv-vector-builtins.def @@ -483,7 +483,7 @@ DEF_RVV_TYPE (vfloat16m4_t, 17, __rvv_float16m4_t, float16, RVVM4HF, _f16m4, /* Define tuple types for SEW = 16, LMUL = M4. */ DEF_RVV_TUPLE_TYPE (vfloat16m4x2_t, 19, __rvv_float16m4x2_t, vfloat16m4_t, float16, 2, _f16m4x2) /* LMUL = 8. */ -DEF_RVV_TYPE (vfloat16m8_t, 16, __rvv_float16m8_t, float16, RVVM8HF, _f16m8, +DEF_RVV_TYPE (vfloat16m8_t, 17, __rvv_float16m8_t, float16, RVVM8HF, _f16m8, _f16, _e16m8) /* Disable all when !TARGET_VECTOR_ELEN_FP_32. */ diff --git a/gcc/config/riscv/riscv-vector-costs.cc b/gcc/config/riscv/riscv-vector-costs.cc index f4a1a78..7c9840d 100644 --- a/gcc/config/riscv/riscv-vector-costs.cc +++ b/gcc/config/riscv/riscv-vector-costs.cc @@ -872,19 +872,6 @@ costs::costs (vec_info *vinfo, bool costing_for_scalar) void costs::analyze_loop_vinfo (loop_vec_info loop_vinfo) { - /* Record the number of times that the vector loop would execute, - if known. */ - class loop *loop = LOOP_VINFO_LOOP (loop_vinfo); - auto scalar_niters = max_stmt_executions_int (loop); - if (scalar_niters >= 0) - { - unsigned int vf = vect_vf_for_cost (loop_vinfo); - if (LOOP_VINFO_LENS (loop_vinfo).is_empty ()) - m_num_vector_iterations = scalar_niters / vf; - else - m_num_vector_iterations = CEIL (scalar_niters, vf); - } - /* Detect whether we're vectorizing for VLA and should apply the unrolling heuristic described above m_unrolled_vls_niters. */ record_potential_vls_unrolling (loop_vinfo); @@ -994,7 +981,8 @@ costs::better_main_loop_than_p (const vector_costs *uncast_other) const vect_vf_for_cost (other_loop_vinfo)); /* Apply the unrolling heuristic described above m_unrolled_vls_niters. */ - if (bool (m_unrolled_vls_stmts) != bool (other->m_unrolled_vls_stmts)) + if (bool (m_unrolled_vls_stmts) != bool (other->m_unrolled_vls_stmts) + && m_cost_type != other->m_cost_type) { bool this_prefer_unrolled = this->prefer_unrolled_loop (); bool other_prefer_unrolled = other->prefer_unrolled_loop (); @@ -1041,10 +1029,42 @@ costs::better_main_loop_than_p (const vector_costs *uncast_other) const } } } + /* If NITERS is unknown, we should not use VLS modes to vectorize + the loop since we don't support partial vectors for VLS modes, + that is, we will have full vectors (VLSmodes) on loop body + and partial vectors (VLAmodes) on loop epilogue which is very + inefficient. Instead, we should apply partial vectors (VLAmodes) + on loop body without an epilogue on unknown NITERS loop. */ + else if (!LOOP_VINFO_NITERS_KNOWN_P (this_loop_vinfo) + && m_cost_type == VLS_VECTOR_COST) + return false; return vector_costs::better_main_loop_than_p (other); } +/* Adjust vectorization cost after calling riscv_builtin_vectorization_cost. + For some statement, we would like to further fine-grain tweak the cost on + top of riscv_builtin_vectorization_cost handling which doesn't have any + information on statement operation codes etc. */ + +static unsigned +adjust_stmt_cost (enum vect_cost_for_stmt kind, tree vectype, int stmt_cost) +{ + const cpu_vector_cost *costs = get_vector_costs (); + switch (kind) + { + case scalar_to_vec: + return stmt_cost += (FLOAT_TYPE_P (vectype) ? costs->regmove->FR2VR + : costs->regmove->GR2VR); + case vec_to_scalar: + return stmt_cost += (FLOAT_TYPE_P (vectype) ? costs->regmove->VR2FR + : costs->regmove->VR2GR); + default: + break; + } + return stmt_cost; +} + unsigned costs::add_stmt_cost (int count, vect_cost_for_stmt kind, stmt_vec_info stmt_info, slp_tree, tree vectype, @@ -1072,14 +1092,74 @@ costs::add_stmt_cost (int count, vect_cost_for_stmt kind, as one iteration of the VLA loop. */ if (where == vect_body && m_unrolled_vls_niters) m_unrolled_vls_stmts += count * m_unrolled_vls_niters; + + if (vectype) + stmt_cost = adjust_stmt_cost (kind, vectype, stmt_cost); } return record_stmt_cost (stmt_info, where, count * stmt_cost); } +/* For some target specific vectorization cost which can't be handled per stmt, + we check the requisite conditions and adjust the vectorization cost + accordingly if satisfied. One typical example is to model model and adjust + loop_len cost for known_lt (NITERS, VF). */ + +void +costs::adjust_vect_cost_per_loop (loop_vec_info loop_vinfo) +{ + if (LOOP_VINFO_FULLY_WITH_LENGTH_P (loop_vinfo) + && !LOOP_VINFO_USING_DECREMENTING_IV_P (loop_vinfo)) + { + /* In middle-end loop vectorizer, we don't count the loop_len cost in + vect_estimate_min_profitable_iters when NITERS < VF, that is, we only + count cost of len that we need to iterate loop more than once with VF. + It's correct for most of the cases: + + E.g. VF = [4, 4] + for (int i = 0; i < 3; i ++) + a[i] += b[i]; + + We don't need to cost MIN_EXPR or SELECT_VL for the case above. + + However, for some inefficient vectorized cases, it does use MIN_EXPR + to generate len. + + E.g. VF = [256, 256] + + Loop body: + # loop_len_110 = PHI <18(2), _119(11)> + ... + _117 = MIN_EXPR <ivtmp_114, 18>; + _118 = 18 - _117; + _119 = MIN_EXPR <_118, POLY_INT_CST [256, 256]>; + ... + + Epilogue: + ... + _112 = .VEC_EXTRACT (vect_patt_27.14_109, _111); + + We cost 1 unconditionally for this situation like other targets which + apply mask as the loop control. */ + rgroup_controls *rgc; + unsigned int num_vectors_m1; + unsigned int body_stmts = 0; + FOR_EACH_VEC_ELT (LOOP_VINFO_LENS (loop_vinfo), num_vectors_m1, rgc) + if (rgc->type) + body_stmts += num_vectors_m1 + 1; + + add_stmt_cost (body_stmts, scalar_stmt, NULL, NULL, NULL_TREE, 0, + vect_body); + } +} + void costs::finish_cost (const vector_costs *scalar_costs) { + if (loop_vec_info loop_vinfo = dyn_cast<loop_vec_info> (m_vinfo)) + { + adjust_vect_cost_per_loop (loop_vinfo); + } vector_costs::finish_cost (scalar_costs); } diff --git a/gcc/config/riscv/riscv-vector-costs.h b/gcc/config/riscv/riscv-vector-costs.h index 9bf041b..4e2bbfd 100644 --- a/gcc/config/riscv/riscv-vector-costs.h +++ b/gcc/config/riscv/riscv-vector-costs.h @@ -85,11 +85,6 @@ private: unsigned HOST_WIDE_INT m_unrolled_vls_niters = 0; unsigned HOST_WIDE_INT m_unrolled_vls_stmts = 0; - /* If we're vectorizing a loop that executes a constant number of times, - this variable gives the number of times that the vector loop would - iterate, otherwise it is zero. */ - uint64_t m_num_vector_iterations = 0; - void analyze_loop_vinfo (loop_vec_info); void record_potential_vls_unrolling (loop_vec_info); bool prefer_unrolled_loop () const; @@ -101,6 +96,8 @@ private: V_REGS spills according to the analysis. */ bool m_has_unexpected_spills_p = false; void record_potential_unexpected_spills (loop_vec_info); + + void adjust_vect_cost_per_loop (loop_vec_info); }; } // namespace riscv_vector diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc index 32183d6..41626fa 100644 --- a/gcc/config/riscv/riscv.cc +++ b/gcc/config/riscv/riscv.cc @@ -95,15 +95,22 @@ along with GCC; see the file COPYING3. If not see #define UNSPEC_ADDRESS_TYPE(X) \ ((enum riscv_symbol_type) (XINT (X, 1) - UNSPEC_ADDRESS_FIRST)) -/* True if bit BIT is set in VALUE. */ -#define BITSET_P(VALUE, BIT) (((VALUE) & (1ULL << (BIT))) != 0) - /* Extract the backup dynamic frm rtl. */ #define DYNAMIC_FRM_RTL(c) ((c)->machine->mode_sw_info.dynamic_frm) /* True the mode switching has static frm, or false. */ #define STATIC_FRM_P(c) ((c)->machine->mode_sw_info.static_frm_p) +/* True if we can use the instructions in the XTheadInt extension + to handle interrupts, or false. */ +#define TH_INT_INTERRUPT(c) \ + (TARGET_XTHEADINT \ + /* The XTheadInt extension only supports rv32. */ \ + && !TARGET_64BIT \ + && (c)->machine->interrupt_handler_p \ + /* The XTheadInt instructions can only be executed in M-mode. */ \ + && (c)->machine->interrupt_mode == MACHINE_MODE) + /* Information about a function's frame layout. */ struct GTY(()) riscv_frame_info { /* The size of the frame in bytes. */ @@ -352,39 +359,48 @@ const enum reg_class riscv_regno_to_class[FIRST_PSEUDO_REGISTER] = { VD_REGS, VD_REGS, VD_REGS, VD_REGS, }; -/* Generic costs for VLS vector operations. */ -static const common_vector_cost generic_vls_vector_cost = { +/* RVV costs for VLS vector operations. */ +static const common_vector_cost rvv_vls_vector_cost = { 1, /* int_stmt_cost */ 1, /* fp_stmt_cost */ 1, /* gather_load_cost */ 1, /* scatter_store_cost */ - 2, /* vec_to_scalar_cost */ + 1, /* vec_to_scalar_cost */ 1, /* scalar_to_vec_cost */ - 2, /* permute_cost */ + 1, /* permute_cost */ 1, /* align_load_cost */ 1, /* align_store_cost */ - 1, /* unalign_load_cost */ - 1, /* unalign_store_cost */ + 2, /* unalign_load_cost */ + 2, /* unalign_store_cost */ }; -/* Generic costs for VLA vector operations. */ -static const scalable_vector_cost generic_vla_vector_cost = { +/* RVV costs for VLA vector operations. */ +static const scalable_vector_cost rvv_vla_vector_cost = { { 1, /* int_stmt_cost */ 1, /* fp_stmt_cost */ 1, /* gather_load_cost */ 1, /* scatter_store_cost */ - 2, /* vec_to_scalar_cost */ + 1, /* vec_to_scalar_cost */ 1, /* scalar_to_vec_cost */ - 2, /* permute_cost */ + 1, /* permute_cost */ 1, /* align_load_cost */ 1, /* align_store_cost */ - 1, /* unalign_load_cost */ - 1, /* unalign_store_cost */ + 2, /* unalign_load_cost */ + 2, /* unalign_store_cost */ }, }; -/* Generic costs for vector insn classes. */ +/* RVV register move cost. */ +static const regmove_vector_cost rvv_regmove_vector_cost = { + 2, /* GR2VR */ + 2, /* FR2VR */ + 2, /* VR2GR */ + 2, /* VR2FR */ +}; + +/* Generic costs for vector insn classes. It is supposed to be the vector cost + models used by default if no other cost model was specified. */ static const struct cpu_vector_cost generic_vector_cost = { 1, /* scalar_int_stmt_cost */ 1, /* scalar_fp_stmt_cost */ @@ -392,8 +408,9 @@ static const struct cpu_vector_cost generic_vector_cost = { 1, /* scalar_store_cost */ 3, /* cond_taken_branch_cost */ 1, /* cond_not_taken_branch_cost */ - &generic_vls_vector_cost, /* vls */ - &generic_vla_vector_cost, /* vla */ + &rvv_vls_vector_cost, /* vls */ + &rvv_vla_vector_cost, /* vla */ + &rvv_regmove_vector_cost, /* regmove */ }; /* Costs to use when optimizing for rocket. */ @@ -1353,7 +1370,10 @@ riscv_v_ext_vls_mode_p (machine_mode mode) return false; } -/* Return true if it is either RVV vector mode or RVV tuple mode. */ +/* Return true if it is either of below modes. + 1. RVV vector mode. + 2. RVV tuple mode. + 3. RVV vls mode. */ static bool riscv_v_ext_mode_p (machine_mode mode) @@ -3555,7 +3575,7 @@ riscv_noce_conversion_profitable_p (rtx_insn *seq, this redundant zero extend operation counts towards the cost of the replacement sequence. Compensate for that by incrementing the cost of the original sequence as well as the maximum sequence cost - accordingly. */ + accordingly. Likewise for sign extension. */ rtx last_dest = NULL_RTX; for (rtx_insn *insn = seq; insn; insn = NEXT_INSN (insn)) { @@ -3567,8 +3587,9 @@ riscv_noce_conversion_profitable_p (rtx_insn *seq, && GET_CODE (x) == SET) { rtx src = SET_SRC (x); + enum rtx_code code = GET_CODE (src); if (last_dest != NULL_RTX - && GET_CODE (src) == ZERO_EXTEND + && (code == SIGN_EXTEND || code == ZERO_EXTEND) && REG_P (XEXP (src, 0)) && REGNO (XEXP (src, 0)) == REGNO (last_dest)) { @@ -4844,59 +4865,6 @@ riscv_pass_fpr_pair (machine_mode mode, unsigned regno1, GEN_INT (offset2)))); } -/* Return true if a vector type is included in the type TYPE. */ - -static bool -riscv_arg_has_vector (const_tree type) -{ - if (riscv_v_ext_mode_p (TYPE_MODE (type))) - return true; - - if (!COMPLETE_TYPE_P (type)) - return false; - - switch (TREE_CODE (type)) - { - case RECORD_TYPE: - /* If it is a record, it is further determined whether its fields have - vector type. */ - for (tree f = TYPE_FIELDS (type); f; f = DECL_CHAIN (f)) - if (TREE_CODE (f) == FIELD_DECL) - { - tree field_type = TREE_TYPE (f); - if (!TYPE_P (field_type)) - break; - - if (riscv_arg_has_vector (field_type)) - return true; - } - break; - case ARRAY_TYPE: - return riscv_arg_has_vector (TREE_TYPE (type)); - default: - break; - } - - return false; -} - -/* Pass the type to check whether it's a vector type or contains vector type. - Only check the value type and no checking for vector pointer type. */ - -static void -riscv_pass_in_vector_p (const_tree type) -{ - static int warned = 0; - - if (type && riscv_vector::lookup_vector_type_attribute (type) && !warned) - { - warning (OPT_Wpsabi, - "ABI for the vector type is currently in experimental stage and " - "may changes in the upcoming version of GCC."); - warned = 1; - } -} - /* Initialize a variable CUM of type CUMULATIVE_ARGS for a call to a function whose data type is FNTYPE. For a library call, FNTYPE is 0. */ @@ -4914,15 +4882,6 @@ riscv_init_cumulative_args (CUMULATIVE_ARGS *cum, cum->variant_cc = (riscv_cc) fntype_abi (fntype).id (); else cum->variant_cc = RISCV_CC_BASE; - - if (fndecl) - { - const tree_function_decl &fn - = FUNCTION_DECL_CHECK (fndecl)->function_decl; - - if (fn.built_in_class == NOT_BUILT_IN) - cum->rvv_psabi_warning = 1; - } } /* Return true if TYPE is a vector type that can be passed in vector registers. @@ -5039,12 +4998,6 @@ riscv_get_arg_info (struct riscv_arg_info *info, const CUMULATIVE_ARGS *cum, info->gpr_offset = cum->num_gprs; info->fpr_offset = cum->num_fprs; - if (cum->rvv_psabi_warning) - { - /* Only check existing of vector type. */ - riscv_pass_in_vector_p (type); - } - /* When disable vector_abi or scalable vector argument is anonymous, this argument is passed by reference. */ if (riscv_v_ext_mode_p (mode) && (!riscv_vector_abi || !named)) @@ -5222,17 +5175,7 @@ riscv_function_value (const_tree type, const_tree func, machine_mode mode) memset (&args, 0, sizeof args); - const_tree arg_type = type; - if (func && DECL_RESULT (func)) - { - const tree_function_decl &fn = FUNCTION_DECL_CHECK (func)->function_decl; - if (fn.built_in_class == NOT_BUILT_IN) - args.rvv_psabi_warning = 1; - - arg_type = TREE_TYPE (DECL_RESULT (func)); - } - - return riscv_get_arg_info (&info, &args, mode, arg_type, true, true); + return riscv_get_arg_info (&info, &args, mode, type, true, true); } /* Implement TARGET_PASS_BY_REFERENCE. */ @@ -7100,6 +7043,7 @@ riscv_expand_prologue (void) unsigned fmask = frame->fmask; int spimm, multi_push_additional, stack_adj; rtx insn, dwarf = NULL_RTX; + unsigned th_int_mask = 0; if (flag_stack_usage_info) current_function_static_stack_size = constant_lower_bound (remaining_size); @@ -7168,6 +7112,28 @@ riscv_expand_prologue (void) REG_NOTES (insn) = dwarf; } + th_int_mask = th_int_get_mask (frame->mask); + if (th_int_mask && TH_INT_INTERRUPT (cfun)) + { + frame->mask &= ~th_int_mask; + + /* RISCV_PROLOGUE_TEMP may be used to handle some CSR for + interrupts, such as fcsr. */ + if ((TARGET_HARD_FLOAT && frame->fmask) + || (TARGET_ZFINX && frame->mask)) + frame->mask |= (1 << RISCV_PROLOGUE_TEMP_REGNUM); + + unsigned save_adjustment = th_int_get_save_adjustment (); + frame->gp_sp_offset -= save_adjustment; + remaining_size -= save_adjustment; + + insn = emit_insn (gen_th_int_push ()); + + rtx dwarf = th_int_adjust_cfi_prologue (th_int_mask); + RTX_FRAME_RELATED_P (insn) = 1; + REG_NOTES (insn) = dwarf; + } + /* Save the GP, FP registers. */ if ((frame->mask | frame->fmask) != 0) { @@ -7396,6 +7362,7 @@ riscv_expand_epilogue (int style) = use_multi_pop ? frame->multi_push_adj_base + frame->multi_push_adj_addi : 0; rtx ra = gen_rtx_REG (Pmode, RETURN_ADDR_REGNUM); + unsigned th_int_mask = 0; rtx insn; /* We need to add memory barrier to prevent read from deallocated stack. */ @@ -7558,12 +7525,32 @@ riscv_expand_epilogue (int style) else if (use_restore_libcall) frame->mask = 0; /* Temporarily fib that we need not restore GPRs. */ + th_int_mask = th_int_get_mask (frame->mask); + if (th_int_mask && TH_INT_INTERRUPT (cfun)) + { + frame->mask &= ~th_int_mask; + + /* RISCV_PROLOGUE_TEMP may be used to handle some CSR for + interrupts, such as fcsr. */ + if ((TARGET_HARD_FLOAT && frame->fmask) + || (TARGET_ZFINX && frame->mask)) + frame->mask |= (1 << RISCV_PROLOGUE_TEMP_REGNUM); + } + /* Restore the registers. */ riscv_for_each_saved_v_reg (step2, riscv_restore_reg, false); riscv_for_each_saved_reg (frame->total_size - step2 - libcall_size - multipop_size, riscv_restore_reg, true, style == EXCEPTION_RETURN); + if (th_int_mask && TH_INT_INTERRUPT (cfun)) + { + frame->mask = mask; /* Undo the above fib. */ + unsigned save_adjustment = th_int_get_save_adjustment (); + gcc_assert (step2.to_constant () >= save_adjustment); + step2 -= save_adjustment; + } + if (use_restore_libcall) frame->mask = mask; /* Undo the above fib. */ @@ -7626,7 +7613,9 @@ riscv_expand_epilogue (int style) gcc_assert (mode != UNKNOWN_MODE); - if (mode == MACHINE_MODE) + if (th_int_mask && TH_INT_INTERRUPT (cfun)) + emit_jump_insn (gen_th_int_pop ()); + else if (mode == MACHINE_MODE) emit_jump_insn (gen_riscv_mret ()); else if (mode == SUPERVISOR_MODE) emit_jump_insn (gen_riscv_sret ()); @@ -8798,6 +8787,11 @@ riscv_override_options_internal (struct gcc_options *opts) sorry ("Current RISC-V GCC cannot support VLEN greater than 4096bit for " "'V' Extension"); + /* FIXME: We don't support RVV in big-endian for now, we may enable RVV with + big-endian after finishing full coverage testing. */ + if (TARGET_VECTOR && TARGET_BIG_ENDIAN) + sorry ("Current RISC-V GCC cannot support RVV in big-endian mode"); + /* Convert -march to a chunks count. */ riscv_vector_chunks = riscv_convert_vector_bits (opts); } @@ -10372,11 +10366,10 @@ riscv_frame_pointer_required (void) return riscv_save_frame_pointer && !crtl->is_leaf; } -/* Return the appropriate common costs for vectors of type VECTYPE. */ +/* Return the appropriate common costs according to VECTYPE from COSTS. */ static const common_vector_cost * -get_common_costs (tree vectype) +get_common_costs (const cpu_vector_cost *costs, tree vectype) { - const cpu_vector_cost *costs = tune_param->vec_costs; gcc_assert (costs); if (vectype && riscv_v_ext_vls_mode_p (TYPE_MODE (vectype))) @@ -10384,78 +10377,84 @@ get_common_costs (tree vectype) return costs->vla; } +/* Return the CPU vector costs according to -mtune if tune info has non-NULL + vector cost. Otherwide, return the default generic vector costs. */ +const cpu_vector_cost * +get_vector_costs () +{ + const cpu_vector_cost *costs = tune_param->vec_costs; + if (!costs) + return &generic_vector_cost; + return costs; +} + /* Implement targetm.vectorize.builtin_vectorization_cost. */ static int riscv_builtin_vectorization_cost (enum vect_cost_for_stmt type_of_cost, tree vectype, int misalign ATTRIBUTE_UNUSED) { - unsigned elements; - const cpu_vector_cost *costs = tune_param->vec_costs; + const cpu_vector_cost *costs = get_vector_costs (); bool fp = false; if (vectype != NULL) fp = FLOAT_TYPE_P (vectype); - if (costs != NULL) + const common_vector_cost *common_costs = get_common_costs (costs, vectype); + gcc_assert (common_costs != NULL); + switch (type_of_cost) { - const common_vector_cost *common_costs = get_common_costs (vectype); - gcc_assert (common_costs != NULL); - switch (type_of_cost) - { - case scalar_stmt: - return fp ? costs->scalar_fp_stmt_cost : costs->scalar_int_stmt_cost; + case scalar_stmt: + return fp ? costs->scalar_fp_stmt_cost : costs->scalar_int_stmt_cost; - case scalar_load: - return costs->scalar_load_cost; + case scalar_load: + return costs->scalar_load_cost; - case scalar_store: - return costs->scalar_store_cost; + case scalar_store: + return costs->scalar_store_cost; - case vector_stmt: - return fp ? common_costs->fp_stmt_cost : common_costs->int_stmt_cost; + case vector_stmt: + return fp ? common_costs->fp_stmt_cost : common_costs->int_stmt_cost; - case vector_load: - return common_costs->align_load_cost; + case vector_load: + return common_costs->align_load_cost; - case vector_store: - return common_costs->align_store_cost; + case vector_store: + return common_costs->align_store_cost; - case vec_to_scalar: - return common_costs->vec_to_scalar_cost; + case vec_to_scalar: + return common_costs->vec_to_scalar_cost; - case scalar_to_vec: - return common_costs->scalar_to_vec_cost; + case scalar_to_vec: + return common_costs->scalar_to_vec_cost; - case unaligned_load: - return common_costs->unalign_load_cost; - case vector_gather_load: - return common_costs->gather_load_cost; + case unaligned_load: + return common_costs->unalign_load_cost; + case vector_gather_load: + return common_costs->gather_load_cost; - case unaligned_store: - return common_costs->unalign_store_cost; - case vector_scatter_store: - return common_costs->scatter_store_cost; + case unaligned_store: + return common_costs->unalign_store_cost; + case vector_scatter_store: + return common_costs->scatter_store_cost; - case cond_branch_taken: - return costs->cond_taken_branch_cost; + case cond_branch_taken: + return costs->cond_taken_branch_cost; - case cond_branch_not_taken: - return costs->cond_not_taken_branch_cost; + case cond_branch_not_taken: + return costs->cond_not_taken_branch_cost; - case vec_perm: - return common_costs->permute_cost; + case vec_perm: + return common_costs->permute_cost; - case vec_promote_demote: - return fp ? common_costs->fp_stmt_cost : common_costs->int_stmt_cost; + case vec_promote_demote: + return fp ? common_costs->fp_stmt_cost : common_costs->int_stmt_cost; - case vec_construct: - elements = estimated_poly_value (TYPE_VECTOR_SUBPARTS (vectype)); - return elements / 2 + 1; + case vec_construct: + return estimated_poly_value (TYPE_VECTOR_SUBPARTS (vectype)); - default: - gcc_unreachable (); - } + default: + gcc_unreachable (); } return default_builtin_vectorization_cost (type_of_cost, vectype, misalign); diff --git a/gcc/config/riscv/riscv.h b/gcc/config/riscv/riscv.h index b13ccc5..1b2cb8d 100644 --- a/gcc/config/riscv/riscv.h +++ b/gcc/config/riscv/riscv.h @@ -634,6 +634,9 @@ enum reg_class (!SMALL_OPERAND (VALUE) \ && SMALL_OPERAND (VALUE & ~(HOST_WIDE_INT_1U << floor_log2 (VALUE)))) +/* True if bit BIT is set in VALUE. */ +#define BITSET_P(VALUE, BIT) (((VALUE) & (1ULL << (BIT))) != 0) + /* Stack layout; function entry, exit and calling. */ #define STACK_GROWS_DOWNWARD 1 @@ -733,8 +736,6 @@ typedef struct { /* Number of floating-point registers used so far, likewise. */ unsigned int num_fprs; - int rvv_psabi_warning; - /* Number of mask registers used so far, up to MAX_ARGS_IN_MASK_REGISTERS. */ unsigned int num_mrs; diff --git a/gcc/config/riscv/riscv.md b/gcc/config/riscv/riscv.md index 8421243..95753c7 100644 --- a/gcc/config/riscv/riscv.md +++ b/gcc/config/riscv/riscv.md @@ -130,6 +130,10 @@ ;; XTheadFmv unspec UNSPEC_XTHEADFMV UNSPEC_XTHEADFMV_HW + + ;; XTheadInt unspec + UNSPECV_XTHEADINT_PUSH + UNSPECV_XTHEADINT_POP ]) (define_constants diff --git a/gcc/config/riscv/riscv_bitmanip.h b/gcc/config/riscv/riscv_bitmanip.h new file mode 100644 index 0000000..c0cc86b --- /dev/null +++ b/gcc/config/riscv/riscv_bitmanip.h @@ -0,0 +1,297 @@ +/* RISC-V Bitmanip Extension intrinsics include file. + Copyright (C) 2024 Free Software Foundation, Inc. + + This file is part of GCC. + + GCC 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. + + GCC 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/>. */ + +#ifndef __RISCV_BITMANIP_H +#define __RISCV_BITMANIP_H + +#include <stdint.h> + +#ifdef __cplusplus +extern "C" { +#endif + +#if defined (__riscv_zbb) + +extern __inline unsigned +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +__riscv_clz_32 (uint32_t x) +{ + return __builtin_riscv_clz_32 (x); +} + +extern __inline unsigned +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +__riscv_ctz_32 (uint32_t x) +{ + return __builtin_riscv_ctz_32 (x); +} + +extern __inline unsigned +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +__riscv_cpop_32 (uint32_t x) +{ + return __builtin_riscv_popcount_32 (x); +} + +extern __inline uint32_t +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +__riscv_orc_b_32 (uint32_t x) +{ + return __builtin_riscv_orc_b_32 (x); +} + +#if __riscv_xlen == 64 + +extern __inline unsigned +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +__riscv_clz_64 (uint64_t x) +{ + return __builtin_riscv_clz_64 (x); +} + +extern __inline unsigned +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +__riscv_ctz_64 (uint64_t x) +{ + return __builtin_riscv_ctz_64 (x); +} + +extern __inline unsigned +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +__riscv_cpop_64 (uint64_t x) +{ + return __builtin_riscv_popcount_64 (x); +} + +extern __inline uint64_t +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +__riscv_orc_b_64 (uint64_t x) +{ + return __builtin_riscv_orc_b_64 (x); +} + +#endif + +#endif // __riscv_zbb + +#if defined (__riscv_zbb) || defined (__riscv_zbkb) + +extern __inline uint32_t +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +__riscv_ror_32 (uint32_t x, uint32_t shamt) +{ + return __builtin_riscv_ror_32 (x,shamt); +} + +extern __inline uint32_t +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +__riscv_rol_32 (uint32_t x, uint32_t shamt) +{ + return __builtin_riscv_rol_32 (x,shamt); +} + +extern __inline uint32_t +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +__riscv_rev8_32 (uint32_t x) +{ + return __builtin_bswap32 (x); +} + +#if __riscv_xlen == 64 + +extern __inline uint64_t +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +__riscv_ror_64 (uint64_t x, uint32_t shamt) +{ + return __builtin_riscv_ror_64 (x,shamt); +} + +extern __inline uint64_t +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +__riscv_rol_64 (uint64_t x, uint32_t shamt) +{ + return __builtin_riscv_rol_64 (x,shamt); +} + +extern __inline uint64_t +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +__riscv_rev8_64 (uint64_t x) +{ + return __builtin_bswap64 (x); +} + +#endif + +#endif // __riscv_zbb || __riscv_zbkb + +#if defined (__riscv_zbkb) + +extern __inline uint32_t +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +__riscv_brev8_32 (uint32_t x) +{ + return __builtin_riscv_brev8_32 (x); +} + +#if __riscv_xlen == 32 + +extern __inline uint32_t +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +__riscv_zip_32 (uint32_t x) +{ + return __builtin_riscv_zip (x); +} + +extern __inline uint32_t +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +__riscv_unzip_32 (uint32_t x) +{ + return __builtin_riscv_unzip (x); +} + +#endif + +#if __riscv_xlen == 64 + +extern __inline uint64_t +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +__riscv_brev8_64 (uint64_t x) +{ + return __builtin_riscv_brev8_64 (x); +} + +#endif + +#endif // __riscv_zbkb + +#if defined (__riscv_zbc) || defined (__riscv_zbkc) + +extern __inline uint32_t +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +__riscv_clmul_32 (uint32_t rs1, uint32_t rs2) +{ + return __builtin_riscv_clmul_32 (rs1,rs2); +} + +#if __riscv_xlen == 32 + +extern __inline uint32_t +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +__riscv_clmulh_32 (uint32_t rs1, uint32_t rs2) +{ + return __builtin_riscv_clmulh_32 (rs1,rs2); +} + +#endif + +#if __riscv_xlen == 64 + +extern __inline uint64_t +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +__riscv_clmul_64 (uint64_t rs1, uint64_t rs2) +{ + return __builtin_riscv_clmul_64 (rs1,rs2); +} + +extern __inline uint64_t +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +__riscv_clmulh_64 (uint64_t rs1, uint64_t rs2) +{ + return __builtin_riscv_clmulh_64 (rs1,rs2); +} + +#endif + +#endif // __riscv_zbc || __riscv_zbkc + +#if defined (__riscv_zbc) + +#if __riscv_xlen == 32 + +extern __inline uint32_t +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +__riscv_clmulr_32 (uint32_t rs1, uint32_t rs2) +{ + return __builtin_riscv_clmulr_32 (rs1,rs2); +} + +#endif + +#if __riscv_xlen == 64 + +extern __inline uint64_t +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +__riscv_clmulr_64 (uint64_t rs1, uint64_t rs2) +{ + return __builtin_riscv_clmulr_64 (rs1,rs2); +} + +#endif + +#endif // __riscv_zbc + +#if defined (__riscv_zbkx) + +#if __riscv_xlen == 32 + +extern __inline uint32_t +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +__riscv_xperm4_32 (uint32_t rs1, uint32_t rs2) +{ + return __builtin_riscv_xperm4 (rs1,rs2); +} + +extern __inline uint32_t +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +__riscv_xperm8_32 (uint32_t rs1, uint32_t rs2) +{ + return __builtin_riscv_xperm8 (rs1,rs2); +} + +#endif + +#if __riscv_xlen == 64 + +extern __inline uint64_t +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +__riscv_xperm4_64 (uint64_t rs1, uint64_t rs2) +{ + return __builtin_riscv_xperm4 (rs1,rs2); +} + +extern __inline uint64_t +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +__riscv_xperm8_64 (uint64_t rs1, uint64_t rs2) +{ + return __builtin_riscv_xperm8 (rs1,rs2); +} + +#endif + +#endif // __riscv_zbkx + +#if defined (__cplusplus) +} +#endif // __cplusplus +#endif // __RISCV_BITMANIP_H
\ No newline at end of file diff --git a/gcc/config/riscv/riscv_crypto.h b/gcc/config/riscv/riscv_crypto.h new file mode 100644 index 0000000..1bfe3d7 --- /dev/null +++ b/gcc/config/riscv/riscv_crypto.h @@ -0,0 +1,309 @@ +/* RISC-V 'Scalar Crypto' Extension intrinsics include file. + Copyright (C) 2024 Free Software Foundation, Inc. + + This file is part of GCC. + + GCC 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. + + GCC 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/>. */ + +#ifndef __RISCV_SCALAR_CRYPTO_H +#define __RISCV_SCALAR_CRYPTO_H + +#include <stdint.h> + +#ifdef __cplusplus +extern "C" { +#endif + +#if defined (__riscv_zknd) + +#if __riscv_xlen == 32 + +#ifdef __OPTIMIZE__ + +extern __inline uint32_t +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +__riscv_aes32dsi (uint32_t rs1, uint32_t rs2, const int bs) +{ + return __builtin_riscv_aes32dsi (rs1,rs2,bs); +} + +extern __inline uint32_t +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +__riscv_aes32dsmi (uint32_t rs1, uint32_t rs2, const int bs) +{ + return __builtin_riscv_aes32dsmi (rs1,rs2,bs); +} + +#else +#define __riscv_aes32dsi(x, y, bs) __builtin_riscv_aes32dsi (x, y, bs) +#define __riscv_aes32dsmi(x, y, bs) __builtin_riscv_aes32dsmi (x, y, bs) +#endif + +#endif + +#if __riscv_xlen == 64 + +extern __inline uint64_t +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +__riscv_aes64ds (uint64_t rs1, uint64_t rs2) +{ + return __builtin_riscv_aes64ds (rs1,rs2); +} + +extern __inline uint64_t +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +__riscv_aes64dsm (uint64_t rs1, uint64_t rs2) +{ + return __builtin_riscv_aes64dsm (rs1,rs2); +} + +extern __inline uint64_t +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +__riscv_aes64im (uint64_t rs1) +{ + return __builtin_riscv_aes64im (rs1); +} +#endif +#endif // __riscv_zknd + +#if (defined (__riscv_zknd) || defined (__riscv_zkne)) && (__riscv_xlen == 64) + +#ifdef __OPTIMIZE__ + +extern __inline uint64_t +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +__riscv_aes64ks1i (uint64_t rs1, const int rnum) +{ + return __builtin_riscv_aes64ks1i (rs1,rnum); +} + +#else +#define __riscv_aes64ks1i(x, rnum) __builtin_riscv_aes64ks1i (x, rnum) +#endif + +extern __inline uint64_t +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +__riscv_aes64ks2 (uint64_t rs1, uint64_t rs2) +{ + return __builtin_riscv_aes64ks2 (rs1,rs2); +} + +#endif // __riscv_zknd || __riscv_zkne + +#if defined (__riscv_zkne) + +#if __riscv_xlen == 32 + +#ifdef __OPTIMIZE__ + +extern __inline uint32_t +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +__riscv_aes32esi (uint32_t rs1, uint32_t rs2, const int bs) +{ + return __builtin_riscv_aes32esi (rs1,rs2,bs); +} + +extern __inline uint32_t +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +__riscv_aes32esmi (uint32_t rs1, uint32_t rs2, const int bs) +{ + return __builtin_riscv_aes32esmi (rs1,rs2,bs); +} + +#else +#define __riscv_aes32esi(x, y, bs) __builtin_riscv_aes32esi (x, y, bs) +#define __riscv_aes32esmi(x, y, bs) __builtin_riscv_aes32esmi (x, y, bs) +#endif + +#endif + +#if __riscv_xlen == 64 + +extern __inline uint64_t +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +__riscv_aes64es (uint64_t rs1,uint64_t rs2) +{ + return __builtin_riscv_aes64es (rs1,rs2); +} + +extern __inline uint64_t +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +__riscv_aes64esm (uint64_t rs1,uint64_t rs2) +{ + return __builtin_riscv_aes64esm (rs1,rs2); +} +#endif +#endif // __riscv_zkne + +#if defined (__riscv_zknh) + +extern __inline uint32_t +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +__riscv_sha256sig0 (uint32_t rs1) +{ + return __builtin_riscv_sha256sig0 (rs1); +} + +extern __inline uint32_t +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +__riscv_sha256sig1 (uint32_t rs1) +{ + return __builtin_riscv_sha256sig1 (rs1); +} + +extern __inline uint32_t +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +__riscv_sha256sum0 (uint32_t rs1) +{ + return __builtin_riscv_sha256sum0 (rs1); +} + +extern __inline uint32_t +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +__riscv_sha256sum1 (uint32_t rs1) +{ + return __builtin_riscv_sha256sum1 (rs1); +} + +#if __riscv_xlen == 32 + +extern __inline uint32_t +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +__riscv_sha512sig0h (uint32_t rs1, uint32_t rs2) +{ + return __builtin_riscv_sha512sig0h (rs1,rs2); +} + +extern __inline uint32_t +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +__riscv_sha512sig0l (uint32_t rs1, uint32_t rs2) +{ + return __builtin_riscv_sha512sig0l (rs1,rs2); +} + +extern __inline uint32_t +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +__riscv_sha512sig1h (uint32_t rs1, uint32_t rs2) +{ + return __builtin_riscv_sha512sig1h (rs1,rs2); +} + +extern __inline uint32_t +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +__riscv_sha512sig1l (uint32_t rs1, uint32_t rs2) +{ + return __builtin_riscv_sha512sig1l (rs1,rs2); +} + +extern __inline uint32_t +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +__riscv_sha512sum0r (uint32_t rs1, uint32_t rs2) +{ + return __builtin_riscv_sha512sum0r (rs1,rs2); +} + +extern __inline uint32_t +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +__riscv_sha512sum1r (uint32_t rs1, uint32_t rs2) +{ + return __builtin_riscv_sha512sum1r (rs1,rs2); +} + +#endif + +#if __riscv_xlen == 64 + +extern __inline uint64_t +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +__riscv_sha512sig0 (uint64_t rs1) +{ + return __builtin_riscv_sha512sig0 (rs1); +} + +extern __inline uint64_t +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +__riscv_sha512sig1 (uint64_t rs1) +{ + return __builtin_riscv_sha512sig1 (rs1); +} + +extern __inline uint64_t +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +__riscv_sha512sum0 (uint64_t rs1) +{ + return __builtin_riscv_sha512sum0 (rs1); +} + +extern __inline uint64_t +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +__riscv_sha512sum1 (uint64_t rs1) +{ + return __builtin_riscv_sha512sum1 (rs1); +} +#endif +#endif // __riscv_zknh + +#if defined (__riscv_zksh) + +extern __inline uint32_t +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +__riscv_sm3p0 (uint32_t rs1) +{ + return __builtin_riscv_sm3p0 (rs1); +} + +extern __inline uint32_t +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +__riscv_sm3p1 (uint32_t rs1) +{ + return __builtin_riscv_sm3p1 (rs1); +} + +#endif // __riscv_zksh + +#if defined (__riscv_zksed) + +#ifdef __OPTIMIZE__ + +extern __inline uint32_t +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +__riscv_sm4ed (uint32_t rs1, uint32_t rs2, const int bs) +{ + return __builtin_riscv_sm4ed (rs1,rs2,bs); +} + +extern __inline uint32_t +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +__riscv_sm4ks (uint32_t rs1, uint32_t rs2, const int bs) +{ + return __builtin_riscv_sm4ks (rs1,rs2,bs); +} + +#else +#define __riscv_sm4ed(x, y, bs) __builtin_riscv_sm4ed(x, y, bs); +#define __riscv_sm4ks(x, y, bs) __builtin_riscv_sm4ks(x, y, bs); +#endif + +#endif // __riscv_zksed + +#if defined (__cplusplus) +} +#endif // __cplusplus +#endif // __RISCV_SCALAR_CRYPTO_H diff --git a/gcc/config/riscv/thead.cc b/gcc/config/riscv/thead.cc index a75351d..0b7e4d8 100644 --- a/gcc/config/riscv/thead.cc +++ b/gcc/config/riscv/thead.cc @@ -912,3 +912,80 @@ th_print_operand_address (FILE *file, machine_mode mode, rtx x) gcc_unreachable (); } + +/* Number array of registers X1, X5-X7, X10-X17, X28-X31, to be + operated on by instruction th.ipush/th.ipop in XTheadInt. */ + +int th_int_regs[] ={ + RETURN_ADDR_REGNUM, + T0_REGNUM, T1_REGNUM, T2_REGNUM, + A0_REGNUM, A1_REGNUM, A2_REGNUM, A3_REGNUM, + A4_REGNUM, A5_REGNUM, A6_REGNUM, A7_REGNUM, + T3_REGNUM, T4_REGNUM, T5_REGNUM, T6_REGNUM, +}; + +/* If MASK contains registers X1, X5-X7, X10-X17, X28-X31, then + return the mask composed of these registers, otherwise return + zero. */ + +unsigned int +th_int_get_mask (unsigned int mask) +{ + unsigned int xtheadint_mask = 0; + + if (!TARGET_XTHEADINT || TARGET_64BIT) + return 0; + + for (unsigned int i = 0; i < ARRAY_SIZE (th_int_regs); i++) + { + if (!BITSET_P (mask, th_int_regs[i])) + return 0; + + xtheadint_mask |= (1 << th_int_regs[i]); + } + + return xtheadint_mask; /* Usually 0xf003fce2. */ +} + +/* Returns the occupied frame needed to save registers X1, X5-X7, + X10-X17, X28-X31. */ + +unsigned int +th_int_get_save_adjustment (void) +{ + gcc_assert (TARGET_XTHEADINT && !TARGET_64BIT); + return ARRAY_SIZE (th_int_regs) * UNITS_PER_WORD; +} + +rtx +th_int_adjust_cfi_prologue (unsigned int mask) +{ + gcc_assert (TARGET_XTHEADINT && !TARGET_64BIT); + + rtx dwarf = NULL_RTX; + rtx adjust_sp_rtx, reg, mem, insn; + int saved_size = ARRAY_SIZE (th_int_regs) * UNITS_PER_WORD; + int offset = saved_size; + + for (int regno = GP_REG_FIRST; regno <= GP_REG_LAST; regno++) + if (BITSET_P (mask, regno - GP_REG_FIRST)) + { + offset -= UNITS_PER_WORD; + reg = gen_rtx_REG (SImode, regno); + mem = gen_frame_mem (SImode, plus_constant (Pmode, + stack_pointer_rtx, + offset)); + + insn = gen_rtx_SET (mem, reg); + dwarf = alloc_reg_note (REG_CFA_OFFSET, insn, dwarf); + } + + /* Debug info for adjust sp. */ + adjust_sp_rtx = + gen_rtx_SET (stack_pointer_rtx, + gen_rtx_PLUS (GET_MODE (stack_pointer_rtx), + stack_pointer_rtx, GEN_INT (-saved_size))); + dwarf = alloc_reg_note (REG_CFA_ADJUST_CFA, adjust_sp_rtx, dwarf); + + return dwarf; +} diff --git a/gcc/config/riscv/thead.md b/gcc/config/riscv/thead.md index 903d3f7..5c7d4be 100644 --- a/gcc/config/riscv/thead.md +++ b/gcc/config/riscv/thead.md @@ -210,6 +210,73 @@ (set_attr "type" "fmove") (set_attr "mode" "DF")]) +;; XTheadInt + +(define_constants + [(T0_REGNUM 5) + (T1_REGNUM 6) + (T2_REGNUM 7) + (A0_REGNUM 10) + (A1_REGNUM 11) + (A2_REGNUM 12) + (A3_REGNUM 13) + (A4_REGNUM 14) + (A5_REGNUM 15) + (A6_REGNUM 16) + (A7_REGNUM 17) + (T3_REGNUM 28) + (T4_REGNUM 29) + (T5_REGNUM 30) + (T6_REGNUM 31) +]) + +(define_insn "th_int_push" + [(unspec_volatile [(const_int 0)] UNSPECV_XTHEADINT_PUSH) + (use (reg:SI RETURN_ADDR_REGNUM)) + (use (reg:SI T0_REGNUM)) + (use (reg:SI T1_REGNUM)) + (use (reg:SI T2_REGNUM)) + (use (reg:SI A0_REGNUM)) + (use (reg:SI A1_REGNUM)) + (use (reg:SI A2_REGNUM)) + (use (reg:SI A3_REGNUM)) + (use (reg:SI A4_REGNUM)) + (use (reg:SI A5_REGNUM)) + (use (reg:SI A6_REGNUM)) + (use (reg:SI A7_REGNUM)) + (use (reg:SI T3_REGNUM)) + (use (reg:SI T4_REGNUM)) + (use (reg:SI T5_REGNUM)) + (use (reg:SI T6_REGNUM))] + "TARGET_XTHEADINT && !TARGET_64BIT" + "th.ipush" + [(set_attr "type" "store") + (set_attr "mode" "SI")]) + +(define_insn "th_int_pop" + [(unspec_volatile [(const_int 0)] UNSPECV_XTHEADINT_POP) + (clobber (reg:SI RETURN_ADDR_REGNUM)) + (clobber (reg:SI T0_REGNUM)) + (clobber (reg:SI T1_REGNUM)) + (clobber (reg:SI T2_REGNUM)) + (clobber (reg:SI A0_REGNUM)) + (clobber (reg:SI A1_REGNUM)) + (clobber (reg:SI A2_REGNUM)) + (clobber (reg:SI A3_REGNUM)) + (clobber (reg:SI A4_REGNUM)) + (clobber (reg:SI A5_REGNUM)) + (clobber (reg:SI A6_REGNUM)) + (clobber (reg:SI A7_REGNUM)) + (clobber (reg:SI T3_REGNUM)) + (clobber (reg:SI T4_REGNUM)) + (clobber (reg:SI T5_REGNUM)) + (clobber (reg:SI T6_REGNUM)) + (return)] + "TARGET_XTHEADINT && !TARGET_64BIT" + "th.ipop" + [(set_attr "type" "ret") + (set_attr "mode" "SI")]) + ;; XTheadMac (define_insn "*th_mula<mode>" @@ -866,14 +933,17 @@ && pow2p_hwi (INTVAL (operands[2])) && IN_RANGE (exact_log2 (INTVAL (operands[2])), 1, 3)" "#" - "&& 1" + "&& reload_completed" [(set (match_dup 0) (mem:TH_M_NOEXTF (plus:X (match_dup 3) (ashift:X (match_dup 1) (match_dup 2)))))] { operands[2] = GEN_INT (exact_log2 (INTVAL (operands [2]))); } -) + [(set_attr "move_type" "fpload") + (set_attr "mode" "<UNITMODE>") + (set_attr "type" "fmove") + (set (attr "length") (const_int 16))]) (define_insn_and_split "*th_fmemidx_I_c" [(set (mem:TH_M_ANYF (plus:X @@ -910,7 +980,7 @@ && CONST_INT_P (operands[3]) && (INTVAL (operands[3]) >> exact_log2 (INTVAL (operands[2]))) == 0xffffffff" "#" - "&& 1" + "&& reload_completed" [(set (match_dup 0) (mem:TH_M_NOEXTF (plus:DI (match_dup 4) @@ -918,7 +988,10 @@ { operands[1] = gen_lowpart (SImode, operands[1]); operands[2] = GEN_INT (exact_log2 (INTVAL (operands [2]))); } -) + [(set_attr "move_type" "fpload") + (set_attr "mode" "<UNITMODE>") + (set_attr "type" "fmove") + (set (attr "length") (const_int 16))]) (define_insn_and_split "*th_fmemidx_US_c" [(set (mem:TH_M_ANYF (plus:DI @@ -953,12 +1026,16 @@ "TARGET_64BIT && TARGET_XTHEADMEMIDX && TARGET_XTHEADFMEMIDX && (!HARD_REGISTER_NUM_P (REGNO (operands[0])) || HARDFP_REG_P (REGNO (operands[0])))" "#" - "&& 1" + "&& reload_completed" [(set (match_dup 0) (mem:TH_M_NOEXTF (plus:DI (match_dup 2) (zero_extend:DI (match_dup 1)))))] -) + "" + [(set_attr "move_type" "fpload") + (set_attr "mode" "<UNITMODE>") + (set_attr "type" "fmove") + (set (attr "length") (const_int 16))]) (define_insn_and_split "*th_fmemidx_UZ_c" [(set (mem:TH_M_ANYF (plus:DI diff --git a/gcc/config/riscv/vector-iterators.md b/gcc/config/riscv/vector-iterators.md index b4a276d..c2ea7e8 100644 --- a/gcc/config/riscv/vector-iterators.md +++ b/gcc/config/riscv/vector-iterators.md @@ -3581,11 +3581,6 @@ (define_code_attr nmsub_nmadd [(plus "nmsub") (minus "nmadd")]) (define_code_attr nmsac_nmacc [(plus "nmsac") (minus "nmacc")]) -(define_code_attr ext_to_rshift [(sign_extend "ashiftrt") - (zero_extend "lshiftrt")]) -(define_code_attr EXT_TO_RSHIFT [(sign_extend "ASHIFTRT") - (zero_extend "LSHIFTRT")]) - (define_code_iterator and_ior [and ior]) (define_code_iterator any_float_binop [plus mult minus div]) diff --git a/gcc/config/riscv/vector.md b/gcc/config/riscv/vector.md index 24b7b43..ee4ee05 100644 --- a/gcc/config/riscv/vector.md +++ b/gcc/config/riscv/vector.md @@ -715,7 +715,7 @@ (const_int 1) (eq_attr "type" "vimuladd,vfmuladd") - (const_int 5)] + (const_int 2)] (const_int INVALID_ATTRIBUTE))) ;; The index of operand[] represents the machine mode of the instruction. @@ -4239,8 +4239,8 @@ (set_attr "mode" "<MODE>")]) (define_insn "@pred_<sat_op><mode>" - [(set (match_operand:VI 0 "register_operand" "=vd, vd, vr, vr") - (if_then_else:VI + [(set (match_operand:V_VLSI 0 "register_operand" "=vd, vd, vr, vr") + (if_then_else:V_VLSI (unspec:<VM> [(match_operand:<VM> 1 "vector_mask_operand" " vm, vm,Wc1,Wc1") (match_operand 5 "vector_length_operand" " rK, rK, rK, rK") @@ -4251,10 +4251,10 @@ (reg:SI VL_REGNUM) (reg:SI VTYPE_REGNUM) (reg:SI VXRM_REGNUM)] UNSPEC_VPREDICATE) - (unspec:VI - [(match_operand:VI 3 "register_operand" " vr, vr, vr, vr") - (match_operand:VI 4 "register_operand" " vr, vr, vr, vr")] VSAT_OP) - (match_operand:VI 2 "vector_merge_operand" " vu, 0, vu, 0")))] + (unspec:V_VLSI + [(match_operand:V_VLSI 3 "register_operand" " vr, vr, vr, vr") + (match_operand:V_VLSI 4 "register_operand" " vr, vr, vr, vr")] VSAT_OP) + (match_operand:V_VLSI 2 "vector_merge_operand" " vu, 0, vu, 0")))] "TARGET_VECTOR" "v<sat_op>.vv\t%0,%3,%4%p1" [(set_attr "type" "<sat_insn_type>") @@ -5308,7 +5308,7 @@ vmv.v.v\t%0,%2\;vmadd.vv\t%0,%3,%4%p1" [(set_attr "type" "vimuladd") (set_attr "mode" "<MODE>") - (set_attr "merge_op_idx" "4") + (set_attr "merge_op_idx" "2") (set_attr "vl_op_idx" "5") (set (attr "ta") (symbol_ref "riscv_vector::get_ta(operands[6])")) (set (attr "ma") (symbol_ref "riscv_vector::get_ma(operands[7])")) @@ -5339,7 +5339,7 @@ vmv.v.v\t%0,%4\;vmacc.vv\t%0,%2,%3%p1" [(set_attr "type" "vimuladd") (set_attr "mode" "<MODE>") - (set_attr "merge_op_idx" "2") + (set_attr "merge_op_idx" "4") (set_attr "vl_op_idx" "5") (set (attr "ta") (symbol_ref "riscv_vector::get_ta(operands[6])")) (set (attr "ma") (symbol_ref "riscv_vector::get_ma(operands[7])")) @@ -5392,7 +5392,7 @@ vmv.v.v\t%0,%3\;vmadd.vx\t%0,%2,%4%p1" [(set_attr "type" "vimuladd") (set_attr "mode" "<MODE>") - (set_attr "merge_op_idx" "4") + (set_attr "merge_op_idx" "3") (set_attr "vl_op_idx" "5") (set (attr "ta") (symbol_ref "riscv_vector::get_ta(operands[6])")) (set (attr "ma") (symbol_ref "riscv_vector::get_ma(operands[7])")) @@ -5424,7 +5424,7 @@ vmv.v.v\t%0,%4\;vmacc.vx\t%0,%2,%3%p1" [(set_attr "type" "vimuladd") (set_attr "mode" "<MODE>") - (set_attr "merge_op_idx" "2") + (set_attr "merge_op_idx" "4") (set_attr "vl_op_idx" "5") (set (attr "ta") (symbol_ref "riscv_vector::get_ta(operands[6])")) (set (attr "ma") (symbol_ref "riscv_vector::get_ma(operands[7])")) @@ -5492,7 +5492,7 @@ vmv.v.v\t%0,%2\;vmadd.vx\t%0,%2,%4%p1" [(set_attr "type" "vimuladd") (set_attr "mode" "<MODE>") - (set_attr "merge_op_idx" "4") + (set_attr "merge_op_idx" "3") (set_attr "vl_op_idx" "5") (set (attr "ta") (symbol_ref "riscv_vector::get_ta(operands[6])")) (set (attr "ma") (symbol_ref "riscv_vector::get_ma(operands[7])")) @@ -5525,7 +5525,7 @@ vmv.v.v\t%0,%4\;vmacc.vx\t%0,%2,%3%p1" [(set_attr "type" "vimuladd") (set_attr "mode" "<MODE>") - (set_attr "merge_op_idx" "2") + (set_attr "merge_op_idx" "4") (set_attr "vl_op_idx" "5") (set (attr "ta") (symbol_ref "riscv_vector::get_ta(operands[6])")) (set (attr "ma") (symbol_ref "riscv_vector::get_ma(operands[7])")) @@ -5606,7 +5606,7 @@ vmv.v.v\t%0,%2\;vnmsub.vv\t%0,%3,%4%p1" [(set_attr "type" "vimuladd") (set_attr "mode" "<MODE>") - (set_attr "merge_op_idx" "4") + (set_attr "merge_op_idx" "2") (set_attr "vl_op_idx" "5") (set (attr "ta") (symbol_ref "riscv_vector::get_ta(operands[6])")) (set (attr "ma") (symbol_ref "riscv_vector::get_ma(operands[7])")) @@ -5637,7 +5637,7 @@ vmv.v.v\t%0,%4\;vnmsac.vv\t%0,%2,%3%p1" [(set_attr "type" "vimuladd") (set_attr "mode" "<MODE>") - (set_attr "merge_op_idx" "2") + (set_attr "merge_op_idx" "4") (set_attr "vl_op_idx" "5") (set (attr "ta") (symbol_ref "riscv_vector::get_ta(operands[6])")) (set (attr "ma") (symbol_ref "riscv_vector::get_ma(operands[7])")) @@ -5690,7 +5690,7 @@ vmv.v.v\t%0,%3\;vnmsub.vx\t%0,%2,%4%p1" [(set_attr "type" "vimuladd") (set_attr "mode" "<MODE>") - (set_attr "merge_op_idx" "4") + (set_attr "merge_op_idx" "3") (set_attr "vl_op_idx" "5") (set (attr "ta") (symbol_ref "riscv_vector::get_ta(operands[6])")) (set (attr "ma") (symbol_ref "riscv_vector::get_ma(operands[7])")) @@ -5722,7 +5722,7 @@ vmv.v.v\t%0,%4\;vnmsac.vx\t%0,%2,%3%p1" [(set_attr "type" "vimuladd") (set_attr "mode" "<MODE>") - (set_attr "merge_op_idx" "2") + (set_attr "merge_op_idx" "4") (set_attr "vl_op_idx" "5") (set (attr "ta") (symbol_ref "riscv_vector::get_ta(operands[6])")) (set (attr "ma") (symbol_ref "riscv_vector::get_ma(operands[7])")) @@ -5790,7 +5790,7 @@ vmv.v.v\t%0,%3\;vnmsub.vx\t%0,%2,%4%p1" [(set_attr "type" "vimuladd") (set_attr "mode" "<MODE>") - (set_attr "merge_op_idx" "4") + (set_attr "merge_op_idx" "3") (set_attr "vl_op_idx" "5") (set (attr "ta") (symbol_ref "riscv_vector::get_ta(operands[6])")) (set (attr "ma") (symbol_ref "riscv_vector::get_ma(operands[7])")) @@ -5823,7 +5823,7 @@ vmv.v.v\t%0,%4\;vnmsac.vx\t%0,%2,%3%p1" [(set_attr "type" "vimuladd") (set_attr "mode" "<MODE>") - (set_attr "merge_op_idx" "2") + (set_attr "merge_op_idx" "4") (set_attr "vl_op_idx" "5") (set (attr "ta") (symbol_ref "riscv_vector::get_ta(operands[6])")) (set (attr "ma") (symbol_ref "riscv_vector::get_ma(operands[7])")) @@ -6516,7 +6516,7 @@ vmv.v.v\t%0,%2\;vf<madd_msub>.vv\t%0,%3,%4%p1" [(set_attr "type" "vfmuladd") (set_attr "mode" "<MODE>") - (set_attr "merge_op_idx" "4") + (set_attr "merge_op_idx" "2") (set_attr "vl_op_idx" "5") (set (attr "ta") (symbol_ref "riscv_vector::get_ta(operands[6])")) (set (attr "ma") (symbol_ref "riscv_vector::get_ma(operands[7])")) @@ -6551,7 +6551,7 @@ vmv.v.v\t%0,%4\;vf<macc_msac>.vv\t%0,%2,%3%p1" [(set_attr "type" "vfmuladd") (set_attr "mode" "<MODE>") - (set_attr "merge_op_idx" "2") + (set_attr "merge_op_idx" "4") (set_attr "vl_op_idx" "5") (set (attr "ta") (symbol_ref "riscv_vector::get_ta(operands[6])")) (set (attr "ma") (symbol_ref "riscv_vector::get_ma(operands[7])")) @@ -6610,7 +6610,7 @@ vmv.v.v\t%0,%3\;vf<madd_msub>.vf\t%0,%2,%4%p1" [(set_attr "type" "vfmuladd") (set_attr "mode" "<MODE>") - (set_attr "merge_op_idx" "4") + (set_attr "merge_op_idx" "3") (set_attr "vl_op_idx" "5") (set (attr "ta") (symbol_ref "riscv_vector::get_ta(operands[6])")) (set (attr "ma") (symbol_ref "riscv_vector::get_ma(operands[7])")) @@ -6646,7 +6646,7 @@ vmv.v.v\t%0,%4\;vf<macc_msac>.vf\t%0,%2,%3%p1" [(set_attr "type" "vfmuladd") (set_attr "mode" "<MODE>") - (set_attr "merge_op_idx" "2") + (set_attr "merge_op_idx" "4") (set_attr "vl_op_idx" "5") (set (attr "ta") (symbol_ref "riscv_vector::get_ta(operands[6])")) (set (attr "ma") (symbol_ref "riscv_vector::get_ma(operands[7])")) @@ -6740,7 +6740,7 @@ vmv.v.v\t%0,%2\;vf<nmsub_nmadd>.vv\t%0,%3,%4%p1" [(set_attr "type" "vfmuladd") (set_attr "mode" "<MODE>") - (set_attr "merge_op_idx" "4") + (set_attr "merge_op_idx" "2") (set_attr "vl_op_idx" "5") (set (attr "ta") (symbol_ref "riscv_vector::get_ta(operands[6])")) (set (attr "ma") (symbol_ref "riscv_vector::get_ma(operands[7])")) @@ -6776,7 +6776,7 @@ vmv.v.v\t%0,%4\;vf<nmsac_nmacc>.vv\t%0,%2,%3%p1" [(set_attr "type" "vfmuladd") (set_attr "mode" "<MODE>") - (set_attr "merge_op_idx" "2") + (set_attr "merge_op_idx" "4") (set_attr "vl_op_idx" "5") (set (attr "ta") (symbol_ref "riscv_vector::get_ta(operands[6])")) (set (attr "ma") (symbol_ref "riscv_vector::get_ma(operands[7])")) @@ -6837,7 +6837,7 @@ vmv.v.v\t%0,%3\;vf<nmsub_nmadd>.vf\t%0,%2,%4%p1" [(set_attr "type" "vfmuladd") (set_attr "mode" "<MODE>") - (set_attr "merge_op_idx" "4") + (set_attr "merge_op_idx" "3") (set_attr "vl_op_idx" "5") (set (attr "ta") (symbol_ref "riscv_vector::get_ta(operands[6])")) (set (attr "ma") (symbol_ref "riscv_vector::get_ma(operands[7])")) @@ -6874,7 +6874,7 @@ vmv.v.v\t%0,%4\;vf<nmsac_nmacc>.vf\t%0,%2,%3%p1" [(set_attr "type" "vfmuladd") (set_attr "mode" "<MODE>") - (set_attr "merge_op_idx" "2") + (set_attr "merge_op_idx" "4") (set_attr "vl_op_idx" "5") (set (attr "ta") (symbol_ref "riscv_vector::get_ta(operands[6])")) (set (attr "ma") (symbol_ref "riscv_vector::get_ma(operands[7])")) diff --git a/gcc/config/rs6000/host-darwin.cc b/gcc/config/rs6000/host-darwin.cc index 691dcb3..e000177 100644 --- a/gcc/config/rs6000/host-darwin.cc +++ b/gcc/config/rs6000/host-darwin.cc @@ -119,7 +119,7 @@ segv_handler (int sig ATTRIBUTE_UNUSED, } } - if (global_dc->abort_on_error) + if (global_dc->m_abort_on_error) fancy_abort (__FILE__, __LINE__, __FUNCTION__); exit (FATAL_EXIT_CODE); diff --git a/gcc/config/rs6000/rs6000.cc b/gcc/config/rs6000/rs6000.cc index 94fbf46..5d975da 100644 --- a/gcc/config/rs6000/rs6000.cc +++ b/gcc/config/rs6000/rs6000.cc @@ -21357,6 +21357,7 @@ rs6000_elf_declare_function_name (FILE *file, const char *name, tree decl) ASM_DECLARE_RESULT (file, DECL_RESULT (decl)); rs6000_output_function_entry (file, name); fputs (":\n", file); + assemble_function_label_final (); return; } diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md index c880cec..bc8bc6a 100644 --- a/gcc/config/rs6000/rs6000.md +++ b/gcc/config/rs6000/rs6000.md @@ -15020,9 +15020,27 @@ (define_expand "copysign<mode>3" [(use (match_operand:IEEE128 0 "altivec_register_operand")) (use (match_operand:IEEE128 1 "altivec_register_operand")) - (use (match_operand:IEEE128 2 "altivec_register_operand"))] + (use (match_operand:IEEE128 2 "any_operand"))] "FLOAT128_IEEE_P (<MODE>mode)" { + /* Middle-end canonicalizes -fabs (x) to copysign (x, -1), + but PowerPC prefers -fabs (x). */ + if (CONST_DOUBLE_AS_FLOAT_P (operands[2])) + { + if (real_isneg (CONST_DOUBLE_REAL_VALUE (operands[2]))) + { + rtx abs_res = gen_reg_rtx (<MODE>mode); + emit_insn (gen_abs<mode>2 (abs_res, operands[1])); + emit_insn (gen_neg<mode>2 (operands[0], abs_res)); + } + else + emit_insn (gen_abs<mode>2 (operands[0], operands[1])); + DONE; + } + + if (!altivec_register_operand (operands[2], <MODE>mode)) + operands[2] = copy_to_mode_reg (<MODE>mode, operands[2]); + if (TARGET_FLOAT128_HW) emit_insn (gen_copysign<mode>3_hard (operands[0], operands[1], operands[2])); diff --git a/gcc/config/rs6000/vsx.md b/gcc/config/rs6000/vsx.md index 4c1725a..6111cc9 100644 --- a/gcc/config/rs6000/vsx.md +++ b/gcc/config/rs6000/vsx.md @@ -411,6 +411,12 @@ (V2DF "d") (V4SF "w")]) +;; Iterator and attribute for vector count leading/trailing +;; zero least-significant bits byte +(define_int_iterator VCZLSBB [UNSPEC_VCLZLSBB + UNSPEC_VCTZLSBB]) +(define_int_attr vczlsbb_char [(UNSPEC_VCLZLSBB "l") + (UNSPEC_VCTZLSBB "t")]) ;; VSX moves @@ -5855,35 +5861,24 @@ "vcmpnezw %0,%1,%2" [(set_attr "type" "vecsimple")]) -;; Vector Count Leading Zero Least-Significant Bits Byte -(define_insn "vclzlsbb_<mode>" - [(set (match_operand:SI 0 "register_operand" "=r") - (unspec:SI - [(match_operand:VSX_EXTRACT_I 1 "altivec_register_operand" "v")] - UNSPEC_VCLZLSBB))] - "TARGET_P9_VECTOR" - "vclzlsbb %0,%1" - [(set_attr "type" "vecsimple")]) - -;; Vector Count Trailing Zero Least-Significant Bits Byte -(define_insn "*vctzlsbb_zext_<mode>" +;; Vector Count Leading/Trailing Zero Least-Significant Bits Byte +(define_insn "*vc<vczlsbb_char>zlsbb_zext_<mode>" [(set (match_operand:DI 0 "register_operand" "=r") - (zero_extend:DI - (unspec:SI - [(match_operand:VSX_EXTRACT_I 1 "altivec_register_operand" "v")] - UNSPEC_VCTZLSBB)))] + (zero_extend:DI + (unspec:SI + [(match_operand:VSX_EXTRACT_I 1 "altivec_register_operand" "v")] + VCZLSBB)))] "TARGET_P9_VECTOR" - "vctzlsbb %0,%1" + "vc<vczlsbb_char>zlsbb %0,%1" [(set_attr "type" "vecsimple")]) -;; Vector Count Trailing Zero Least-Significant Bits Byte -(define_insn "vctzlsbb_<mode>" +(define_insn "vc<vczlsbb_char>zlsbb_<mode>" [(set (match_operand:SI 0 "register_operand" "=r") - (unspec:SI - [(match_operand:VSX_EXTRACT_I 1 "altivec_register_operand" "v")] - UNSPEC_VCTZLSBB))] + (unspec:SI + [(match_operand:VSX_EXTRACT_I 1 "altivec_register_operand" "v")] + VCZLSBB))] "TARGET_P9_VECTOR" - "vctzlsbb %0,%1" + "vc<vczlsbb_char>zlsbb %0,%1" [(set_attr "type" "vecsimple")]) ;; Vector Extract Unsigned Byte Left-Indexed diff --git a/gcc/config/s390/s390.cc b/gcc/config/s390/s390.cc index 748ad9c..f182c26 100644 --- a/gcc/config/s390/s390.cc +++ b/gcc/config/s390/s390.cc @@ -17867,33 +17867,45 @@ expand_perm_as_a_vlbr_vstbr_candidate (const struct expand_vec_perm_d &d) if (memcmp (d.perm, perm[0], MAX_VECT_LEN) == 0) { - rtx target = gen_rtx_SUBREG (V8HImode, d.target, 0); - rtx op0 = gen_rtx_SUBREG (V8HImode, d.op0, 0); - emit_insn (gen_bswapv8hi (target, op0)); + if (!d.testing_p) + { + rtx target = gen_rtx_SUBREG (V8HImode, d.target, 0); + rtx op0 = gen_rtx_SUBREG (V8HImode, d.op0, 0); + emit_insn (gen_bswapv8hi (target, op0)); + } return true; } if (memcmp (d.perm, perm[1], MAX_VECT_LEN) == 0) { - rtx target = gen_rtx_SUBREG (V4SImode, d.target, 0); - rtx op0 = gen_rtx_SUBREG (V4SImode, d.op0, 0); - emit_insn (gen_bswapv4si (target, op0)); + if (!d.testing_p) + { + rtx target = gen_rtx_SUBREG (V4SImode, d.target, 0); + rtx op0 = gen_rtx_SUBREG (V4SImode, d.op0, 0); + emit_insn (gen_bswapv4si (target, op0)); + } return true; } if (memcmp (d.perm, perm[2], MAX_VECT_LEN) == 0) { - rtx target = gen_rtx_SUBREG (V2DImode, d.target, 0); - rtx op0 = gen_rtx_SUBREG (V2DImode, d.op0, 0); - emit_insn (gen_bswapv2di (target, op0)); + if (!d.testing_p) + { + rtx target = gen_rtx_SUBREG (V2DImode, d.target, 0); + rtx op0 = gen_rtx_SUBREG (V2DImode, d.op0, 0); + emit_insn (gen_bswapv2di (target, op0)); + } return true; } if (memcmp (d.perm, perm[3], MAX_VECT_LEN) == 0) { - rtx target = gen_rtx_SUBREG (V1TImode, d.target, 0); - rtx op0 = gen_rtx_SUBREG (V1TImode, d.op0, 0); - emit_insn (gen_bswapv1ti (target, op0)); + if (!d.testing_p) + { + rtx target = gen_rtx_SUBREG (V1TImode, d.target, 0); + rtx op0 = gen_rtx_SUBREG (V1TImode, d.op0, 0); + emit_insn (gen_bswapv1ti (target, op0)); + } return true; } diff --git a/gcc/config/sparc/sparc.cc b/gcc/config/sparc/sparc.cc index ebf1a55..30fa447 100644 --- a/gcc/config/sparc/sparc.cc +++ b/gcc/config/sparc/sparc.cc @@ -1052,6 +1052,7 @@ atomic_insn_for_leon3_p (rtx_insn *insn) { switch (INSN_CODE (insn)) { + case CODE_FOR_membar_storeload: case CODE_FOR_swapsi: case CODE_FOR_ldstub: case CODE_FOR_atomic_compare_and_swap_leon3_1: @@ -1118,6 +1119,7 @@ next_active_non_empty_insn (rtx_insn *insn) while (insn && (GET_CODE (PATTERN (insn)) == UNSPEC_VOLATILE || GET_CODE (PATTERN (insn)) == ASM_INPUT + || get_attr_length (insn) == 0 || (USEFUL_INSN_P (insn) && (asm_noperands (PATTERN (insn)) >= 0) && !strcmp (decode_asm_operands (PATTERN (insn), diff --git a/gcc/config/sparc/sync.md b/gcc/config/sparc/sync.md index 8808ed5..fa24990 100644 --- a/gcc/config/sparc/sync.md +++ b/gcc/config/sparc/sync.md @@ -64,21 +64,20 @@ "stbar" [(set_attr "type" "multi")]) -;; For LEON3, STB has the effect of membar #StoreLoad. -(define_insn "*membar_storeload_leon3" - [(set (match_operand:BLK 0 "" "") - (unspec:BLK [(match_dup 0) (const_int 2)] UNSPEC_MEMBAR))] - "TARGET_LEON3" - "stb\t%%g0, [%%sp-1]" - [(set_attr "type" "store")]) - ;; For V8, LDSTUB has the effect of membar #StoreLoad. -(define_insn "*membar_storeload" +(define_insn "membar_storeload" [(set (match_operand:BLK 0 "" "") (unspec:BLK [(match_dup 0) (const_int 2)] UNSPEC_MEMBAR))] - "TARGET_V8 && !TARGET_LEON3" - "ldstub\t[%%sp-1], %%g0" - [(set_attr "type" "multi")]) + "TARGET_V8" +{ + if (sparc_fix_gr712rc) + return ".align\t16\n\tldstub\t[%%sp-1], %%g0"; + else + return "ldstub\t[%%sp-1], %%g0"; +} + [(set_attr "type" "multi") + (set (attr "length") (if_then_else (eq_attr "fix_gr712rc" "true") + (const_int 4) (const_int 1)))]) ;; Put the two together, in combination with the fact that V8 implements PSO ;; as its weakest memory model, means a full barrier. Match all remaining @@ -88,9 +87,15 @@ (unspec:BLK [(match_dup 0) (match_operand:SI 1 "const_int_operand")] UNSPEC_MEMBAR))] "TARGET_V8" - "stbar\n\tldstub\t[%%sp-1], %%g0" +{ + if (sparc_fix_gr712rc) + return "stbar\n.align\t16\n\tldstub\t[%%sp-1], %%g0"; + else + return "stbar\n\tldstub\t[%%sp-1], %%g0"; +} [(set_attr "type" "multi") - (set_attr "length" "2")]) + (set (attr "length") (if_then_else (eq_attr "fix_gr712rc" "true") + (const_int 5) (const_int 2)))]) ;; For V9, we have the full membar instruction. (define_insn "*membar" diff --git a/gcc/configure b/gcc/configure index 996046f..4acb254 100755 --- a/gcc/configure +++ b/gcc/configure @@ -28455,6 +28455,7 @@ $as_echo "#define HAVE_AS_AVR_MGCCISR_OPTION 1" >>confdefs.h fi + avr_ld_ver="`$gcc_cv_ld -v | sed -e 's:^.* ::'`" # Check how default linker description file implements .rodata for # avrxmega3 (PR21472). avr-gcc assumes .rodata is *not* loaded to # RAM so avr-gcc skips __do_copy_data for .rodata objects. @@ -28499,7 +28500,6 @@ $as_echo "#define HAVE_LD_AVR_AVRXMEGA3_RODATA_IN_FLASH 1" >>confdefs.h $as_echo "no: avrxmega3 .rodata located in RAM" >&6; } echo "$as_me: nm output was" >&5 cat conftest.nm >&5 - avr_ld_ver="`$gcc_cv_ld -v | sed -e 's:^.* ::'`" { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: support for avrxmega3 .rodata in flash needs Binutils 2.29 or higher (have $avr_ld_ver)" >&5 $as_echo "$as_me: WARNING: support for avrxmega3 .rodata in flash needs Binutils 2.29 or higher (have $avr_ld_ver)" >&2;} fi @@ -28512,6 +28512,74 @@ $as_echo "test failed" >&6; } $as_echo "$as_me: WARNING: see \`config.log' for details" >&2;} fi rm -f conftest.s conftest.o conftest.elf conftest.nm + + # Check for emulation avrxmega2_flmap. + { $as_echo "$as_me:${as_lineno-$LINENO}: checking binutils for avrxmega2_flmap support (PR31124)" >&5 +$as_echo_n "checking binutils for avrxmega2_flmap support (PR31124)... " >&6; } + cat > conftest.s <<EOF + .section .text,"ax",@progbits + ldi r16, __flmap_value_with_lock +EOF + { ac_try='$gcc_cv_as -mmcu=avrxmega2 conftest.s -o conftest.o' + { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5 + (eval $ac_try) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; } + { ac_try='$gcc_cv_ld -mavrxmega2_flmap conftest.o -o conftest.elf' + { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5 + (eval $ac_try) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; } + if test -s conftest.elf + then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + +$as_echo "#define HAVE_LD_AVR_AVRXMEGA2_FLMAP 1" >>confdefs.h + + else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: support for avrxmega2_flmap requires Binutils 2.42 or higher (have $avr_ld_ver)" >&5 +$as_echo "$as_me: WARNING: support for avrxmega2_flmap requires Binutils 2.42 or higher (have $avr_ld_ver)" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: see \`config.log' for details" >&5 +$as_echo "$as_me: WARNING: see \`config.log' for details" >&2;} + fi + rm -f conftest.o conftest.elf + + # Check for emulation avrxmega4_flmap. + { $as_echo "$as_me:${as_lineno-$LINENO}: checking binutils for avrxmega4_flmap support (PR31124)" >&5 +$as_echo_n "checking binutils for avrxmega4_flmap support (PR31124)... " >&6; } + { ac_try='$gcc_cv_as -mmcu=avrxmega4 conftest.s -o conftest.o' + { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5 + (eval $ac_try) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; } + { ac_try='$gcc_cv_ld -mavrxmega4_flmap conftest.o -o conftest.elf' + { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5 + (eval $ac_try) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; } + if test -s conftest.elf + then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + +$as_echo "#define HAVE_LD_AVR_AVRXMEGA4_FLMAP 1" >>confdefs.h + + else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: support for avrxmega4_flmap requires Binutils 2.42 or higher (have $avr_ld_ver)" >&5 +$as_echo "$as_me: WARNING: support for avrxmega4_flmap requires Binutils 2.42 or higher (have $avr_ld_ver)" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: see \`config.log' for details" >&5 +$as_echo "$as_me: WARNING: see \`config.log' for details" >&2;} + fi + rm -f conftest.s conftest.o conftest.elf ;; cris-*-*) diff --git a/gcc/configure.ac b/gcc/configure.ac index 596e5f2..d2ed144 100644 --- a/gcc/configure.ac +++ b/gcc/configure.ac @@ -4549,6 +4549,7 @@ AS_HELP_STRING([--disable-fix-cortex-a53-843419], [AC_DEFINE(HAVE_AS_AVR_MGCCISR_OPTION, 1, [Define if your avr assembler supports -mgcc-isr option.])]) + avr_ld_ver="`$gcc_cv_ld -v | sed -e 's:^.* ::'`" # Check how default linker description file implements .rodata for # avrxmega3 (PR21472). avr-gcc assumes .rodata is *not* loaded to # RAM so avr-gcc skips __do_copy_data for .rodata objects. @@ -4574,7 +4575,6 @@ EOF AC_MSG_RESULT(no: avrxmega3 .rodata located in RAM) echo "$as_me: nm output was" >&AS_MESSAGE_LOG_FD cat conftest.nm >&AS_MESSAGE_LOG_FD - avr_ld_ver="`$gcc_cv_ld -v | sed -e 's:^.* ::'`" AC_MSG_WARN([[support for avrxmega3 .rodata in flash needs Binutils 2.29 or higher (have $avr_ld_ver)]]) fi else @@ -4584,6 +4584,42 @@ EOF AC_MSG_WARN([[see `config.log' for details]]) fi rm -f conftest.s conftest.o conftest.elf conftest.nm + + # Check for emulation avrxmega2_flmap. + AC_MSG_CHECKING(binutils for avrxmega2_flmap support (PR31124)) + cat > conftest.s <<EOF + .section .text,"ax",@progbits + ldi r16, __flmap_value_with_lock +EOF + AC_TRY_COMMAND([$gcc_cv_as -mmcu=avrxmega2 conftest.s -o conftest.o]) + AC_TRY_COMMAND([$gcc_cv_ld -mavrxmega2_flmap conftest.o -o conftest.elf]) + if test -s conftest.elf + then + AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_LD_AVR_AVRXMEGA2_FLMAP, 1, + [Define if your linker supports emulation avrxmega2_flmap.]) + else + AC_MSG_RESULT(no) + AC_MSG_WARN([[support for avrxmega2_flmap requires Binutils 2.42 or higher (have $avr_ld_ver)]]) + AC_MSG_WARN([[see `config.log' for details]]) + fi + rm -f conftest.o conftest.elf + + # Check for emulation avrxmega4_flmap. + AC_MSG_CHECKING(binutils for avrxmega4_flmap support (PR31124)) + AC_TRY_COMMAND([$gcc_cv_as -mmcu=avrxmega4 conftest.s -o conftest.o]) + AC_TRY_COMMAND([$gcc_cv_ld -mavrxmega4_flmap conftest.o -o conftest.elf]) + if test -s conftest.elf + then + AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_LD_AVR_AVRXMEGA4_FLMAP, 1, + [Define if your linker supports emulation avrxmega4_flmap.]) + else + AC_MSG_RESULT(no) + AC_MSG_WARN([[support for avrxmega4_flmap requires Binutils 2.42 or higher (have $avr_ld_ver)]]) + AC_MSG_WARN([[see `config.log' for details]]) + fi + rm -f conftest.s conftest.o conftest.elf ;; cris-*-*) diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 945ac62..49e93ec 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,258 @@ +2024-01-15 Marek Polacek <polacek@redhat.com> + + PR c++/110065 + * parser.cc (cp_parser_template_type_arg): Add auto checking. + +2024-01-15 Patrick Palka <ppalka@redhat.com> + + * parser.cc (cp_parser_check_access_in_redeclaration): Don't + check access for a partial or explicit specialization. + * pt.cc (maybe_new_partial_specialization): Don't set TREE_PRIVATE + or TREE_PROTECTED on the newly created partial specialization. + +2024-01-15 Patrick Palka <ppalka@redhat.com> + + PR c++/104634 + * pt.cc (maybe_new_partial_specialization): Propagate TREE_PUBLIC + to the newly created partial specialization. + +2024-01-15 Patrick Palka <ppalka@redhat.com> + + PR c++/109899 + * init.cc (build_vec_delete_1): Assume expr_noexcept_p returns + false in a template context. + +2024-01-13 Jakub Jelinek <jakub@redhat.com> + + * mangle.cc (write_nested_name): Mangle explicit object + member functions with H as per + https://github.com/itanium-cxx-abi/cxx-abi/issues/148 non-proposal. + +2024-01-12 Jason Merrill <jason@redhat.com> + + PR c++/113038 + * name-lookup.cc (lookup_elaborated_type): Look for bindings + in the global namespace in the ABI namespace. + +2024-01-12 Jason Merrill <jason@redhat.com> + + * call.cc (reversed_match): New. + (enum class pmatch): New enum. + (cand_parms_match): Add match_kind parm. + (object_parms_correspond): Add fn parms. + (joust): Adjust. + * class.cc (xobj_iobj_parameters_correspond): Rename to... + (iobj_parm_corresponds_to): ...this. Take the other + type instead of a second function. + (object_parms_correspond): Adjust. + * cp-tree.h (iobj_parm_corresponds_to): Declare. + +2024-01-11 Jason Merrill <jason@redhat.com> + + PR c++/113191 + * class.cc (xobj_iobj_parameters_correspond): Add context parm. + (object_parms_correspond): Factor out of... + (add_method): ...here. + * method.cc (defaulted_late_check): Use it. + * call.cc (class_of_implicit_object): New. + (object_parms_correspond): Overload taking two candidates. + (cand_parms_match): Use it. + (joust): Check reversed before comparing constraints. + * cp-tree.h (object_parms_correspond): Declare. + +2024-01-10 Tamar Christina <tamar.christina@arm.com> + + * parser.cc (cp_parser_pragma): Initialize to false. + +2024-01-09 Jason Merrill <jason@redhat.com> + + * semantics.cc (is_object_parameter): New. + * cp-tree.h (is_object_parameter): Declare. + * call.cc (maybe_warn_class_memaccess): Use it. + * search.cc (field_access_p): Use it. + (class_of_object_parm): New. + (field_accessor_p): Adjust for explicit object parms. + +2024-01-09 Jason Merrill <jason@redhat.com> + + * call.cc (build_over_call): Refactor handle_arg lambda. + * class.cc (xobj_iobj_parameters_correspond): Fix FIXME. + * method.cc (defaulted_late_check): Adjust comments. + +2024-01-09 waffl3x <waffl3x@protonmail.com> + + PR c++/102609 + PR c++/102609 + C++23 P0847R7 (deducing this) - CWG2586. + * decl.cc (copy_fn_p): Accept xobj copy assignment functions. + (move_signature_fn_p): Accept xobj move assignment functions. + * method.cc (do_build_copy_assign): Handle defaulted xobj member + functions. + (defaulted_late_check): Comment. + (defaultable_fn_check): Comment. + +2024-01-09 waffl3x <waffl3x@protonmail.com> + + PR c++/102609 + PR c++/102609 + C++23 P0847R7 (deducing this) - xobj lambdas. + * lambda.cc (build_capture_proxy): Don't fold direct object types. + * parser.cc (cp_parser_lambda_declarator_opt): Handle xobj lambdas, + diagnostics. Comments also updated. + * pt.cc (tsubst_function_decl): Handle xobj lambdas. Check object + type of xobj lambda call operator, diagnose incorrect types. + (tsubst_lambda_expr): Update comment. + * semantics.cc (finish_decltype_type): Also consider by-value object + parameter qualifications. + +2024-01-09 waffl3x <waffl3x@protonmail.com> + + PR c++/102609 + PR c++/102609 + C++23 P0847R7 (deducing this) - diagnostics. + * class.cc (resolve_address_of_overloaded_function): Diagnostics. + * cp-tree.h (TFF_XOBJ_FUNC): Define. + * decl.cc (grokfndecl): Diagnostics. + (grokdeclarator): Diagnostics. + * error.cc (dump_aggr_type): Pass TFF_XOBJ_FUNC. + (dump_lambda_function): Formatting for xobj lambda. + (dump_function_decl): Pass TFF_XOBJ_FUNC. + (dump_parameters): Formatting for xobj member functions. + (function_category): Formatting for xobj member functions. + * parser.cc (cp_parser_decl_specifier_seq): Diagnostics. + (cp_parser_parameter_declaration): Diagnostics. + * search.cc (look_for_overrides_here): Make xobj member functions + override. + (look_for_overrides_r): Reject an overriding xobj member function + and diagnose it. + * semantics.cc (finish_this_expr): Diagnostics. + * typeck.cc (cp_build_addr_expr_1): Diagnostics. + +2024-01-09 waffl3x <waffl3x@protonmail.com> + + PR c++/102609 + PR c++/102609 + C++23 P0847R7 (deducing this) - initial functionality. + * class.cc (xobj_iobj_parameters_correspond): New function, checks + for corresponding object parameters between xobj and iobj member + functions. + (add_method): Handle object parameters of xobj member functions, use + xobj_iobj_parameters_correspond. + * call.cc (build_over_call): Refactor, handle xobj member functions. + (cand_parms_match): Handle object parameters of xobj and iobj member + functions, use xobj_iobj_parameters_correspond. + * cp-tree.h (enum cp_decl_spec): Add ds_this, add comments. + * decl.cc (grokfndecl): Add xobj_func_p parameter. For xobj member + functions, Set xobj_flag, don't set static_function flag. + (grokdeclarator): Handle xobj member functions, tell grokfndecl. + (grok_op_properties): Don't error for xobj operators. + * parser.cc (cp_parser_decl_specifier_seq): Handle this specifier. + (cp_parser_parameter_declaration): Set default argument to + "this_identifier" for xobj parameters. + (set_and_check_decl_spec_loc): Add "this", add comments. + * tree.cc (build_min_non_dep_op_overload): Handle xobj operators. + * typeck.cc (cp_build_addr_expr_1): Handle address-of xobj member + functions. + +2024-01-09 waffl3x <waffl3x@protonmail.com> + Jason Merrill <jason@redhat.com> + + PR c++/102609 + * cp-tree.h (struct lang_decl_fn): New data member. + (DECL_NONSTATIC_MEMBER_FUNCTION_P): Poison. + (DECL_IOBJ_MEMBER_FUNCTION_P): Define. + (DECL_FUNCTION_XOBJ_FLAG): Define. + (DECL_XOBJ_MEMBER_FUNCTION_P): Define. + (DECL_OBJECT_MEMBER_FUNCTION_P): Define. + (DECL_FUNCTION_MEMBER_P): Don't use + DECL_NONSTATIC_MEMBER_FUNCTION_P. + (DECL_CONST_MEMFUNC_P): Likewise. + (DECL_VOLATILE_MEMFUNC_P): Likewise. + (DECL_NONSTATIC_MEMBER_P): Likewise. + * module.cc (trees_out::lang_decl_bools): Handle xobj_flag. + (trees_in::lang_decl_bools): Handle xobj_flag. + * call.cc (build_this_conversion) + (add_function_candidate) + (add_template_candidate_real) + (add_candidates) + (maybe_warn_class_memaccess) + (cand_parms_match) + (joust) + (do_warn_dangling_reference) + * class.cc (finalize_literal_type_property) + (finish_struct) + (resolve_address_of_overloaded_function) + * constexpr.cc (is_valid_constexpr_fn) + (cxx_bind_parameters_in_call) + * contracts.cc (build_contract_condition_function) + * cp-objcp-common.cc (cp_decl_dwarf_attribute) + * cxx-pretty-print.cc (cxx_pretty_printer::postfix_expression) + (cxx_pretty_printer::declaration_specifiers) + (cxx_pretty_printer::direct_declarator) + * decl.cc (cp_finish_decl) + (grok_special_member_properties) + (start_preparsed_function) + (record_key_method_defined) + * decl2.cc (cp_handle_deprecated_or_unavailable) + * init.cc (find_uninit_fields_r) + (build_offset_ref) + * lambda.cc (lambda_expr_this_capture) + (maybe_generic_this_capture) + (nonlambda_method_basetype) + * mangle.cc (write_nested_name) + * method.cc (early_check_defaulted_comparison) + (skip_artificial_parms_for) + (num_artificial_parms_for) + * pt.cc (is_specialization_of_friend) + (determine_specialization) + (copy_default_args_to_explicit_spec) + (check_explicit_specialization) + (tsubst_contract_attribute) + (check_non_deducible_conversions) + (more_specialized_fn) + (maybe_instantiate_noexcept) + (register_parameter_specializations) + (value_dependent_expression_p) + * search.cc (shared_member_p) + (lookup_member) + (field_access_p) + * semantics.cc (finish_omp_declare_simd_methods) + * tree.cc (lvalue_kind) + * typeck.cc (invalid_nonstatic_memfn_p): Don't use + DECL_NONSTATIC_MEMBER_FUNCTION_P. + +2024-01-09 Julian Brown <julian@codesourcery.com> + + * constexpr.cc (potential_consant_expression_1): Handle + OMP_ARRAY_SECTION. + * cp-tree.h (grok_omp_array_section, build_omp_array_section): Add + prototypes. + * decl2.cc (grok_omp_array_section): New function. + * error.cc (dump_expr): Handle OMP_ARRAY_SECTION. + * parser.cc (cp_parser_new): Initialize parser->omp_array_section_p. + (cp_parser_statement_expr): Disallow array sections. + (cp_parser_postfix_open_square_expression): Support OMP_ARRAY_SECTION + parsing. + (cp_parser_parenthesized_expression_list, cp_parser_lambda_expression, + cp_parser_braced_list): Disallow array sections. + (cp_parser_omp_var_list_no_open): Remove ALLOW_DEREF parameter, add + MAP_LVALUE in its place. Support generalised lvalue parsing for + OpenMP map, to and from clauses. Use OMP_ARRAY_SECTION + code instead of TREE_LIST to represent OpenMP array sections. + (cp_parser_omp_var_list): Remove ALLOW_DEREF parameter, add MAP_LVALUE. + Pass to cp_parser_omp_var_list_no_open. + (cp_parser_oacc_data_clause): Update call to cp_parser_omp_var_list. + (cp_parser_omp_clause_map): Add sk_omp scope around + cp_parser_omp_var_list_no_open call. + * parser.h (cp_parser): Add omp_array_section_p field. + * pt.cc (tsubst, tsubst_copy, tsubst_omp_clause_decl, + tsubst_copy_and_build): Add OMP_ARRAY_SECTION support. + * semantics.cc (handle_omp_array_sections_1, handle_omp_array_sections, + cp_oacc_check_attachments, finish_omp_clauses): Use OMP_ARRAY_SECTION + instead of TREE_LIST where appropriate. Handle more types of map + expression. + * typeck.cc (build_omp_array_section): New function. + 2024-01-07 Nathaniel Shead <nathanieloshead@gmail.com> * module.cc (trees_out::write_var_def): Only write initializers diff --git a/gcc/cp/call.cc b/gcc/cp/call.cc index 1c67572..1f5ff41 100644 --- a/gcc/cp/call.cc +++ b/gcc/cp/call.cc @@ -2323,7 +2323,7 @@ build_this_conversion (tree fn, tree ctype, tree& parmtype, tree& argtype, tree& arg, int flags, tsubst_flags_t complain) { - gcc_assert (DECL_NONSTATIC_MEMBER_FUNCTION_P (fn) + gcc_assert (DECL_IOBJ_MEMBER_FUNCTION_P (fn) && !DECL_CONSTRUCTOR_P (fn)); /* The type of the implicit object parameter ('this') for @@ -2536,7 +2536,7 @@ add_function_candidate (struct z_candidate **candidates, { tree parmtype = TREE_VALUE (parmnode); if (i == 0 - && DECL_NONSTATIC_MEMBER_FUNCTION_P (fn) + && DECL_IOBJ_MEMBER_FUNCTION_P (fn) && !DECL_CONSTRUCTOR_P (fn)) t = build_this_conversion (fn, ctype, parmtype, argtype, arg, flags, complain); @@ -3493,7 +3493,7 @@ add_template_candidate_real (struct z_candidate **candidates, tree tmpl, /* We don't do deduction on the in-charge parameter, the VTT parameter or 'this'. */ - if (DECL_NONSTATIC_MEMBER_FUNCTION_P (tmpl)) + if (DECL_IOBJ_MEMBER_FUNCTION_P (tmpl)) { if (first_arg_without_in_chrg != NULL_TREE) first_arg_without_in_chrg = NULL_TREE; @@ -3603,7 +3603,7 @@ add_template_candidate_real (struct z_candidate **candidates, tree tmpl, convs = alloc_conversions (nargs); if (shortcut_bad_convs - && DECL_NONSTATIC_MEMBER_FUNCTION_P (tmpl) + && DECL_IOBJ_MEMBER_FUNCTION_P (tmpl) && !DECL_CONSTRUCTOR_P (tmpl)) { /* Check the 'this' conversion before proceeding with deduction. @@ -6631,7 +6631,7 @@ add_candidates (tree fns, tree first_arg, const vec<tree, va_gc> *args, tree fn_first_arg = NULL_TREE; const vec<tree, va_gc> *fn_args = args; - if (DECL_NONSTATIC_MEMBER_FUNCTION_P (fn)) + if (DECL_OBJECT_MEMBER_FUNCTION_P (fn)) { /* Figure out where the object arg comes from. If this function is a non-static member and we didn't get an @@ -9870,14 +9870,9 @@ build_over_call (struct z_candidate *cand, int flags, tsubst_flags_t complain) const vec<tree, va_gc> *args = cand->args; tree first_arg = cand->first_arg; conversion **convs = cand->convs; - conversion *conv; tree parm = TYPE_ARG_TYPES (TREE_TYPE (fn)); int parmlen; tree val; - int i = 0; - int j = 0; - unsigned int arg_index = 0; - int is_method = 0; int nargs; tree *argarray; bool already_used = false; @@ -10074,45 +10069,46 @@ build_over_call (struct z_candidate *cand, int flags, tsubst_flags_t complain) if (immediate_invocation_p (STRIP_TEMPLATE (fn))) in_consteval_if_p = true; + int argarray_size = 0; + unsigned int arg_index = 0; + int conv_index = 0; + int param_index = 0; + + auto consume_object_arg = [&arg_index, &first_arg, args]() + { + if (!first_arg) + return (*args)[arg_index++]; + tree object_arg = first_arg; + first_arg = NULL_TREE; + return object_arg; + }; + /* The implicit parameters to a constructor are not considered by overload resolution, and must be of the proper type. */ if (DECL_CONSTRUCTOR_P (fn)) { - tree object_arg; - if (first_arg != NULL_TREE) - { - object_arg = first_arg; - first_arg = NULL_TREE; - } - else - { - object_arg = (*args)[arg_index]; - ++arg_index; - } - argarray[j++] = build_this (object_arg); + tree object_arg = consume_object_arg (); + argarray[argarray_size++] = build_this (object_arg); parm = TREE_CHAIN (parm); /* We should never try to call the abstract constructor. */ gcc_assert (!DECL_HAS_IN_CHARGE_PARM_P (fn)); if (DECL_HAS_VTT_PARM_P (fn)) { - argarray[j++] = (*args)[arg_index]; + argarray[argarray_size++] = (*args)[arg_index]; ++arg_index; parm = TREE_CHAIN (parm); } } /* Bypass access control for 'this' parameter. */ - else if (TREE_CODE (TREE_TYPE (fn)) == METHOD_TYPE) + else if (DECL_IOBJ_MEMBER_FUNCTION_P (fn)) { - tree arg = build_this (first_arg != NULL_TREE - ? first_arg - : (*args)[arg_index]); + tree arg = build_this (consume_object_arg ()); tree argtype = TREE_TYPE (arg); if (arg == error_mark_node) return error_mark_node; - - if (convs[i]->bad_p) + if (convs[conv_index++]->bad_p) { if (complain & tf_error) { @@ -10187,25 +10183,53 @@ build_over_call (struct z_candidate *cand, int flags, tsubst_flags_t complain) tree converted_arg = build_base_path (PLUS_EXPR, arg, base_binfo, 1, complain); - argarray[j++] = converted_arg; + argarray[argarray_size++] = converted_arg; parm = TREE_CHAIN (parm); - if (first_arg != NULL_TREE) - first_arg = NULL_TREE; + } + + auto handle_arg = [fn, flags](tree type, + tree arg, + int const param_index, + conversion *conv, + tsubst_flags_t const arg_complain) + { + /* Set user_conv_p on the argument conversions, so rvalue/base handling + knows not to allow any more UDCs. This needs to happen after we + process cand->warnings. */ + if (flags & LOOKUP_NO_CONVERSION) + conv->user_conv_p = true; + + if (arg_complain & tf_warning) + maybe_warn_pessimizing_move (arg, type, /*return_p=*/false); + + tree val = convert_like_with_context (conv, arg, fn, + param_index, arg_complain); + val = convert_for_arg_passing (type, val, arg_complain); + return val; + }; + + if (DECL_XOBJ_MEMBER_FUNCTION_P (fn)) + { + gcc_assert (cand->num_convs > 0); + tree object_arg = consume_object_arg (); + val = handle_arg (TREE_VALUE (parm), + object_arg, + param_index++, + convs[conv_index++], + complain); + + if (val == error_mark_node) + return error_mark_node; else - ++arg_index; - ++i; - is_method = 1; + argarray[argarray_size++] = val; + parm = TREE_CHAIN (parm); } gcc_assert (first_arg == NULL_TREE); for (; arg_index < vec_safe_length (args) && parm; - parm = TREE_CHAIN (parm), ++arg_index, ++i) + parm = TREE_CHAIN (parm), ++arg_index, ++param_index, ++conv_index) { - tree type = TREE_VALUE (parm); - tree arg = (*args)[arg_index]; - bool conversion_warning = true; - - conv = convs[i]; + tree current_arg = (*args)[arg_index]; /* If the argument is NULL and used to (implicitly) instantiate a template function (and bind one of the template arguments to @@ -10227,47 +10251,39 @@ build_over_call (struct z_candidate *cand, int flags, tsubst_flags_t complain) func(NULL); } */ - if (null_node_p (arg) - && DECL_TEMPLATE_INFO (fn) - && cand->template_decl - && !cand->explicit_targs) - conversion_warning = false; - - /* Set user_conv_p on the argument conversions, so rvalue/base handling - knows not to allow any more UDCs. This needs to happen after we - process cand->warnings. */ - if (flags & LOOKUP_NO_CONVERSION) - conv->user_conv_p = true; - - tsubst_flags_t arg_complain = complain; - if (!conversion_warning) - arg_complain &= ~tf_warning; + bool const conversion_warning = !(null_node_p (current_arg) + && DECL_TEMPLATE_INFO (fn) + && cand->template_decl + && !cand->explicit_targs); - if (arg_complain & tf_warning) - maybe_warn_pessimizing_move (arg, type, /*return_p*/false); + tsubst_flags_t const arg_complain + = conversion_warning ? complain : complain & ~tf_warning; - val = convert_like_with_context (conv, arg, fn, i - is_method, - arg_complain); - val = convert_for_arg_passing (type, val, arg_complain); + val = handle_arg (TREE_VALUE (parm), + current_arg, + param_index, + convs[conv_index], + arg_complain); if (val == error_mark_node) - return error_mark_node; + return error_mark_node; else - argarray[j++] = val; + argarray[argarray_size++] = val; } /* Default arguments */ - for (; parm && parm != void_list_node; parm = TREE_CHAIN (parm), i++) + for (; parm && parm != void_list_node; + parm = TREE_CHAIN (parm), param_index++) { if (TREE_VALUE (parm) == error_mark_node) return error_mark_node; val = convert_default_arg (TREE_VALUE (parm), TREE_PURPOSE (parm), - fn, i - is_method, + fn, param_index, complain); if (val == error_mark_node) - return error_mark_node; - argarray[j++] = val; + return error_mark_node; + argarray[argarray_size++] = val; } /* Ellipsis */ @@ -10304,11 +10320,11 @@ build_over_call (struct z_candidate *cand, int flags, tsubst_flags_t complain) a = convert_arg_to_ellipsis (a, complain); if (a == error_mark_node) return error_mark_node; - argarray[j++] = a; + argarray[argarray_size++] = a; } - gcc_assert (j <= nargs); - nargs = j; + gcc_assert (argarray_size <= nargs); + nargs = argarray_size; icip.reset (); /* Avoid performing argument transformation if warnings are disabled. @@ -10324,7 +10340,7 @@ build_over_call (struct z_candidate *cand, int flags, tsubst_flags_t complain) { tree *fargs = (!nargs ? argarray : (tree *) alloca (nargs * sizeof (tree))); - for (j = 0; j < nargs; j++) + for (int j = 0; j < nargs; j++) { /* For -Wformat undo the implicit passing by hidden reference done by convert_arg_to_ellipsis. */ @@ -10798,8 +10814,8 @@ maybe_warn_class_memaccess (location_t loc, tree fndecl, type. If so, and if the class has no non-trivial bases or members, be more permissive. */ if (current_function_decl - && DECL_NONSTATIC_MEMBER_FUNCTION_P (current_function_decl) - && is_this_parameter (tree_strip_nop_conversions (dest))) + && DECL_OBJECT_MEMBER_FUNCTION_P (current_function_decl) + && is_object_parameter (tree_strip_nop_conversions (dest))) { tree ctx = DECL_CONTEXT (current_function_decl); bool special = same_type_ignoring_top_level_qualifiers_p (ctx, desttype); @@ -12669,42 +12685,136 @@ joust_maybe_elide_copy (z_candidate *cand) return false; } +/* Return the class that CAND's implicit object parameter refers to. */ + +static tree +class_of_implicit_object (z_candidate *cand) +{ + if (!DECL_IOBJ_MEMBER_FUNCTION_P (cand->fn)) + return NULL_TREE; + + /* "For conversion functions that are implicit object member functions, + the function is considered to be a member of the class of the implied + object argument for the purpose of defining the type of the implicit + object parameter." */ + if (DECL_CONV_FN_P (cand->fn)) + return TYPE_MAIN_VARIANT (TREE_TYPE (cand->first_arg)); + + /* "For non-conversion functions that are implicit object member + functions nominated by a using-declaration in a derived class, the + function is considered to be a member of the derived class for the + purpose of defining the type of the implicit object parameter." + + That derived class is reflected in the conversion_path binfo. */ + return BINFO_TYPE (cand->conversion_path); +} + +/* True if candidates C1 and C2 have corresponding object parameters per + [basic.scope.scope]. */ + +static bool +object_parms_correspond (z_candidate *c1, tree fn1, z_candidate *c2, tree fn2) +{ + tree context = class_of_implicit_object (c1); + tree ctx2 = class_of_implicit_object (c2); + if (!ctx2) + /* Leave context as is. */; + else if (!context) + context = ctx2; + else if (context != ctx2) + /* This can't happen for normal function calls, since it means finding + functions in multiple bases which would fail with an ambiguous lookup, + but it can occur with reversed operators. */ + return false; + + return object_parms_correspond (fn1, fn2, context); +} + +/* Return whether the first parameter of C1 matches the second parameter + of C2. */ + +static bool +reversed_match (z_candidate *c1, z_candidate *c2) +{ + tree fn1 = c1->fn; + tree parms2 = TYPE_ARG_TYPES (TREE_TYPE (c2->fn)); + tree parm2 = TREE_VALUE (TREE_CHAIN (parms2)); + if (DECL_IOBJ_MEMBER_FUNCTION_P (fn1)) + { + tree ctx = class_of_implicit_object (c1); + return iobj_parm_corresponds_to (fn1, parm2, ctx); + } + else + { + tree parms1 = TYPE_ARG_TYPES (TREE_TYPE (fn1)); + tree parm1 = TREE_VALUE (parms1); + return same_type_p (parm1, parm2); + } +} + /* True if the defining declarations of the two candidates have equivalent - parameters. */ + parameters. MATCH_KIND controls whether we're trying to compare the + original declarations (for a warning) or the actual candidates. */ + +enum class pmatch { original, current }; static bool -cand_parms_match (z_candidate *c1, z_candidate *c2) +cand_parms_match (z_candidate *c1, z_candidate *c2, pmatch match_kind) { tree fn1 = c1->fn; tree fn2 = c2->fn; - if (fn1 == fn2) + bool reversed = (match_kind == pmatch::current + && c1->reversed () != c2->reversed ()); + if (fn1 == fn2 && !reversed) return true; if (identifier_p (fn1) || identifier_p (fn2)) return false; - /* We don't look at c1->template_decl because that's only set for primary - templates, not e.g. non-template member functions of class templates. */ - tree t1 = most_general_template (fn1); - tree t2 = most_general_template (fn2); - if (t1 || t2) + if (match_kind == pmatch::original) { - if (!t1 || !t2) - return false; - if (t1 == t2) - return true; - fn1 = DECL_TEMPLATE_RESULT (t1); - fn2 = DECL_TEMPLATE_RESULT (t2); + /* We don't look at c1->template_decl because that's only set for + primary templates, not e.g. non-template member functions of + class templates. */ + tree t1 = most_general_template (fn1); + tree t2 = most_general_template (fn2); + if (t1 || t2) + { + if (!t1 || !t2) + return false; + if (t1 == t2) + return true; + fn1 = DECL_TEMPLATE_RESULT (t1); + fn2 = DECL_TEMPLATE_RESULT (t2); + } } + + else if (reversed) + return (reversed_match (c1, c2) + && reversed_match (c2, c1)); + tree parms1 = TYPE_ARG_TYPES (TREE_TYPE (fn1)); tree parms2 = TYPE_ARG_TYPES (TREE_TYPE (fn2)); - if (DECL_FUNCTION_MEMBER_P (fn1) - && DECL_FUNCTION_MEMBER_P (fn2) - && (DECL_NONSTATIC_MEMBER_FUNCTION_P (fn1) - != DECL_NONSTATIC_MEMBER_FUNCTION_P (fn2))) + + if (!(DECL_FUNCTION_MEMBER_P (fn1) + && DECL_FUNCTION_MEMBER_P (fn2))) + /* Early escape. */; + + /* CWG2789 is not adequate, it should specify corresponding object + parameters, not same typed object parameters. */ + else if (!object_parms_correspond (c1, fn1, c2, fn2)) + return false; + else { - /* Ignore 'this' when comparing the parameters of a static member - function with those of a non-static one. */ - parms1 = skip_artificial_parms_for (fn1, parms1); - parms2 = skip_artificial_parms_for (fn2, parms2); + /* We just compared the object parameters, if they don't correspond + we already returned false. */ + auto skip_parms = [] (tree fn, tree parms) + { + if (DECL_XOBJ_MEMBER_FUNCTION_P (fn)) + return TREE_CHAIN (parms); + else + return skip_artificial_parms_for (fn, parms); + }; + parms1 = skip_parms (fn1, parms1); + parms2 = skip_parms (fn2, parms2); } return compparms (parms1, parms2); } @@ -12865,7 +12975,7 @@ joust (struct z_candidate *cand1, struct z_candidate *cand2, bool warn, this approach to resolving the ambiguity, so pedwarn. */ if ((complain & tf_warning_or_error) && (cand1->reversed () != cand2->reversed ()) - && cand_parms_match (cand1, cand2)) + && cand_parms_match (cand1, cand2, pmatch::original)) { struct z_candidate *w, *l; if (cand2->reversed ()) @@ -12884,7 +12994,7 @@ joust (struct z_candidate *cand1, struct z_candidate *cand2, bool warn, print_z_candidate (input_location, N_("candidate 2:"), l); if (w->fn == l->fn - && DECL_NONSTATIC_MEMBER_FUNCTION_P (w->fn) + && DECL_IOBJ_MEMBER_FUNCTION_P (w->fn) && (type_memfn_quals (TREE_TYPE (w->fn)) & TYPE_QUAL_CONST) == 0) { @@ -13066,7 +13176,7 @@ joust (struct z_candidate *cand1, struct z_candidate *cand2, bool warn, if (flag_concepts && DECL_P (cand1->fn) && DECL_P (cand2->fn) && !cand1->template_decl && !cand2->template_decl - && cand_parms_match (cand1, cand2)) + && cand_parms_match (cand1, cand2, pmatch::current)) { winner = more_constrained (cand1->fn, cand2->fn); if (winner) @@ -14033,7 +14143,7 @@ do_warn_dangling_reference (tree expr, bool arg_p) because R refers to one of the int elements of V, not to a temporary object. Member operator* may return a reference but probably not to one of its arguments. */ - || (DECL_NONSTATIC_MEMBER_FUNCTION_P (fndecl) + || (DECL_OBJECT_MEMBER_FUNCTION_P (fndecl) && DECL_OVERLOADED_OPERATOR_P (fndecl) && DECL_OVERLOADED_OPERATOR_IS (fndecl, INDIRECT_REF))) return NULL_TREE; @@ -14059,7 +14169,7 @@ do_warn_dangling_reference (tree expr, bool arg_p) tree arg = CALL_EXPR_ARG (expr, i); /* Check that this argument initializes a reference, except for the argument initializing the object of a member function. */ - if (!DECL_NONSTATIC_MEMBER_FUNCTION_P (fndecl) + if (!DECL_IOBJ_MEMBER_FUNCTION_P (fndecl) && !TYPE_REF_P (TREE_TYPE (arg))) continue; STRIP_NOPS (arg); @@ -14079,7 +14189,7 @@ do_warn_dangling_reference (tree expr, bool arg_p) const S& s = S().self(); where 's' dangles. If we've gotten here, the object this function is invoked on is not a temporary. */ - if (DECL_NONSTATIC_MEMBER_FUNCTION_P (fndecl)) + if (DECL_OBJECT_MEMBER_FUNCTION_P (fndecl)) break; } return NULL_TREE; diff --git a/gcc/cp/class.cc b/gcc/cp/class.cc index a45c0d6..556943c 100644 --- a/gcc/cp/class.cc +++ b/gcc/cp/class.cc @@ -1019,6 +1019,241 @@ modify_vtable_entry (tree t, } +/* Check if the object parameter of an iobj member function corresponds to + another parameter type. CONTEXT is the class that the implicit object + parameter is considered to refer to. */ + +bool +iobj_parm_corresponds_to (tree iobj_fn, tree xobj_param, tree context) +{ + tree iobj_fn_type = TREE_TYPE (iobj_fn); + + /* If the iobj member function was introduced with a using declaration, the + type of its object parameter is considered to be that of the class it was + introduced into. + + [over.match.funcs.general.4] + For non-conversion functions that are implicit object member + functions nominated by a using-declaration in a derived class, the + function is considered to be a member of the derived class for the purpose + of defining the type of the implicit object parameter. + + Unfortunately, because of this rule, we can't just compare the xobj member + function's DECL_CONTEXT to its object parameter. + + struct S; + + struct B { + int f(this S&) { return 5; } + }; + + struct S : B { + using B::f; + int f() { return 10; } + }; + + The using declaration does not change the object parameter of B::f as it + is an xobj member function. However, its object parameter still + corresponds to S::f as it was declared with an object parameter of type + S const&. The DECL_CONTEXT of B::f is B, so if we compare the type of the + object parameter to that, it will not match. If we naively assume a + different type from the DECL_CONTEXT for an xobj parameter means that the + object parameters do not correspond, then the object parameters in the + above example will be considered non-corresponding. + + As a result of this, B::f would incorrectly not be discarded, causing an + ambiguity when f is called on an object of type S. + + This also impacts member functions with constraints as in the following + example. + + template<typename = void> + struct S; + + template<typename = void> + struct B { + int f(this S<>&) requires true { return 5; } + }; + + template<typename> + struct S : B<> { + using B<>::f; + int f() { return 10; } + }; + + Once again, if we compare the DECL_CONTEXT of B<>::f to it's xobj + parameter, it would not match. If the object parameters do not + correspond, constraints are not taken into account, so in this example we + would (probably) get an ambiguous lookup instead of correctly picking + B<>::f. + + Because of this caveat, we must actually compare the type of the iobj + parameter to the type of the xobj parameter, shortcuts will have these + edge cases. + + Aside from the more complex reasons above, this logic also implicitly + handles xobj parameters of pointer type, we don't have to explicitly + check for that case. */ + + if (!same_type_ignoring_top_level_qualifiers_p + (context, non_reference (xobj_param))) + return false; + + /* We don't get to bail yet even if we have a by-value xobj parameter, + a by-value xobj parameter can correspond to an iobj parameter provided the + iobj member function is not declared with a reference qualifier. + + From this point on, we know we are dealing with an xobj parameter that has + an object parameter of the same type as the class it was declared in. + We still don't know if we have a reference or by-value parameter yet + though. */ + + cp_ref_qualifier const iobj_ref_qual = type_memfn_rqual (iobj_fn_type); + /* We only care about cv qualifiers when determining correspondence. */ + static constexpr cp_cv_quals cv_bits = TYPE_QUAL_VOLATILE + | TYPE_QUAL_CONST; + cp_cv_quals const iobj_cv_quals = type_memfn_quals (iobj_fn_type) & cv_bits; + /* We need to ignore the ref qualifier of the xobj parameter if the iobj + member function lacks a ref qualifier. + + [basic.scope.scope.3] + Two non-static member functions have corresponding object parameters if: + -- exactly one is an implicit object member function with no ref-qualifier + and the types of their object parameters ([dcl.fct]), after removing + top-level references, are the same, or + -- their object parameters have the same type. + + The cv qualifiers of a by-value parameter are supposed to be discarded, so + we ignore them. + + [dcl.fct.5] + After producing the list of parameter types, any top-level cv-qualifiers + modifying a parameter type are deleted when forming the function type. + + However, they still need to be taken into account when our xobj parameter + is a reference that is being ignored (according to [basic.scope.scope.3] + quoted above), but when we are actually dealing with a by-value xobj + parameter we can proceed following this table. + | iobj | xobj | equal | + | none | none | X | + | none | c | X | + | none | v | X | + | none | cv | X | + | c | none | O | + | c | c | O | + | c | v | O | + | c | cv | O | + | v | none | O | + | v | c | O | + | v | v | O | + | v | cv | O | + | cv | none | O | + | cv | c | O | + | cv | v | O | + | cv | cv | O | + + Additionally, if the iobj member function is ref qualified, we aren't + ignoring the ref qualifier of the iobj parameter, so we can't be dealing + with correspondence in that case either. + + So to recap, if we have a by-value xobj parameter, we know for sure that + we aren't dealing with corresponding object parameters if the iobj member + function has any cv-ref qualifiers. The only case where we might still be + dealing with corresponding object parameters is when the iobj member + function lacks any cv-ref qualification. */ + if (!TYPE_REF_P (xobj_param)) + { + if (iobj_ref_qual || iobj_cv_quals) + return false; + } + else + { + /* We are dealing with an xobj parameter that is a reference now, but due + to [basic.scope.scope.3] we need to ignore its ref qual. */ + cp_ref_qualifier const xobj_ref_qual = [&](){ + if (!TYPE_REF_P (xobj_param) || !iobj_ref_qual) + return REF_QUAL_NONE; + return TYPE_REF_IS_RVALUE (xobj_param) ? REF_QUAL_RVALUE + : REF_QUAL_LVALUE; + }(); /* IILE. */ + + /* Even if we are ignoring the reference qualifier, the xobj parameter + was still a reference so we still take the cv qualifiers into + account. */ + cp_cv_quals const xobj_cv_quals + = cp_type_quals (TREE_TYPE (xobj_param)) & cv_bits; + + /* Finally, if the qualifications don't match exactly, the object + parameters don't correspond. */ + if (iobj_ref_qual != xobj_ref_qual + || iobj_cv_quals != xobj_cv_quals) + return false; + } + /* If we got past everything else, the object parameters of fn1 and fn2 + definitely correspond. */ + return true; +} + +/* True if FN and METHOD have corresponding object parms per + [basic.scope.scope], or if one of them is a static member function (which + are considered to have an object parm that corresponds to any other). + CONTEXT is the class that an implicit object member function is considered + to be a member of for the purpose of this comparison, per + [over.match.funcs]. */ + +bool +object_parms_correspond (tree fn, tree method, tree context) +{ + tree fn_type = TREE_TYPE (fn); + tree method_type = TREE_TYPE (method); + + /* Compare the quals on the 'this' parm. Don't compare + the whole types, as used functions are treated as + coming from the using class in overload resolution. */ + if (DECL_IOBJ_MEMBER_FUNCTION_P (fn) + && DECL_IOBJ_MEMBER_FUNCTION_P (method)) + { + /* Either both or neither need to be ref-qualified for + differing quals to allow overloading. */ + if ((FUNCTION_REF_QUALIFIED (fn_type) + == FUNCTION_REF_QUALIFIED (method_type)) + && (type_memfn_quals (fn_type) != type_memfn_quals (method_type) + || type_memfn_rqual (fn_type) != type_memfn_rqual (method_type))) + return false; + return true; + } + /* Treat a static member function as corresponding to any object parm. */ + else if (DECL_STATIC_FUNCTION_P (fn) || DECL_STATIC_FUNCTION_P (method)) + return true; + /* Handle special correspondence rules for xobj vs xobj and xobj vs iobj + member function declarations. + We don't worry about static member functions here. */ + else if (DECL_XOBJ_MEMBER_FUNCTION_P (fn) + && DECL_XOBJ_MEMBER_FUNCTION_P (method)) + { + auto get_object_param = [] (tree fn) + { + return TREE_VALUE (TYPE_ARG_TYPES (TREE_TYPE (fn))); + }; + /* We skip the object parameter below, check it here instead of + making changes to that code. */ + tree fn_param = get_object_param (fn); + tree method_param = get_object_param (method); + if (!same_type_p (fn_param, method_param)) + return false; + } + else + { + tree xobj_fn = DECL_XOBJ_MEMBER_FUNCTION_P (fn) ? fn : method; + tree iobj_fn = xobj_fn != fn ? fn : method; + tree xobj_param = TREE_VALUE (TYPE_ARG_TYPES (TREE_TYPE (xobj_fn))); + + return iobj_parm_corresponds_to (iobj_fn, xobj_param, context); + } + + return true; +} + /* Add method METHOD to class TYPE. If VIA_USING indicates whether METHOD is being injected via a using_decl. Returns true if the method could be added to the method vec. */ @@ -1073,22 +1308,12 @@ add_method (tree type, tree method, bool via_using) functions in the derived class override and/or hide member functions with the same name and parameter types in a base class (rather than conflicting). */ + if (!object_parms_correspond (fn, method, type)) + continue; + tree fn_type = TREE_TYPE (fn); tree method_type = TREE_TYPE (method); - /* Compare the quals on the 'this' parm. Don't compare - the whole types, as used functions are treated as - coming from the using class in overload resolution. */ - if (! DECL_STATIC_FUNCTION_P (fn) - && ! DECL_STATIC_FUNCTION_P (method) - /* Either both or neither need to be ref-qualified for - differing quals to allow overloading. */ - && (FUNCTION_REF_QUALIFIED (fn_type) - == FUNCTION_REF_QUALIFIED (method_type)) - && (type_memfn_quals (fn_type) != type_memfn_quals (method_type) - || type_memfn_rqual (fn_type) != type_memfn_rqual (method_type))) - continue; - tree real_fn = fn; tree real_method = method; @@ -5968,7 +6193,7 @@ finalize_literal_type_property (tree t) for (fn = TYPE_FIELDS (t); fn; fn = DECL_CHAIN (fn)) if (TREE_CODE (fn) == FUNCTION_DECL && DECL_DECLARED_CONSTEXPR_P (fn) - && DECL_NONSTATIC_MEMBER_FUNCTION_P (fn) + && DECL_IOBJ_MEMBER_FUNCTION_P (fn) && !DECL_CONSTRUCTOR_P (fn)) { DECL_DECLARED_CONSTEXPR_P (fn) = false; @@ -7932,7 +8157,7 @@ finish_struct (tree t, tree attributes) if (flag_openmp) for (tree decl = TYPE_FIELDS (t); decl; decl = DECL_CHAIN (decl)) if (TREE_CODE (decl) == FUNCTION_DECL - && DECL_NONSTATIC_MEMBER_FUNCTION_P (decl)) + && DECL_OBJECT_MEMBER_FUNCTION_P (decl)) if (tree attr = lookup_attribute ("omp declare variant base", DECL_ATTRIBUTES (decl))) omp_declare_variant_finalize (decl, attr); @@ -8727,21 +8952,52 @@ resolve_address_of_overloaded_function (tree target_type, /* Good, exactly one match. Now, convert it to the correct type. */ fn = TREE_PURPOSE (matches); - if (DECL_NONSTATIC_MEMBER_FUNCTION_P (fn) - && !(complain & tf_ptrmem_ok) && !flag_ms_extensions) - { - static int explained; - - if (!(complain & tf_error)) + if (DECL_OBJECT_MEMBER_FUNCTION_P (fn) + && !(complain & tf_ptrmem_ok)) + { + /* Previously we allowed this behavior for iobj member functions when the + -fms-extensions flag is passed as MSVC allows this as a language + extension. MSVC also allows this for xobj member functions, but the + documentation for -fms-extensions states it's purpose is to support + the use of microsoft headers. Until otherwise demonstrated, we should + assume xobj member functions are not used in this manner in microsoft + headers and forbid the incorrect syntax instead of supporting it for + non-legacy uses. This should hopefully encourage conformance going + forward. + This comment is referred to in typeck.cc:cp_build_addr_expr_1. */ + if (DECL_IOBJ_MEMBER_FUNCTION_P (fn) && flag_ms_extensions) + /* Early escape. */; + else if (!(complain & tf_error)) return error_mark_node; - - auto_diagnostic_group d; - if (permerror (input_location, "assuming pointer to member %qD", fn) - && !explained) + else if (DECL_XOBJ_MEMBER_FUNCTION_P (fn)) { - inform (input_location, "(a pointer to member can only be " - "formed with %<&%E%>)", fn); - explained = 1; + auto_diagnostic_group d; + /* Should match the error in typeck.cc:cp_build_addr_expr_1. + We seem to lack the details here to match that diagnostic exactly, + perhaps this could be fixed in the future? See PR113075 bug 2. */ + error_at (input_location, + "ISO C++ forbids taking the address of an unqualified" + " or parenthesized non-static member function to form" + " a pointer to explicit object member function."); + /* This is incorrect, see PR113075 bug 3. */ + inform (input_location, + "a pointer to explicit object member function can only be " + "formed with %<&%E%>", fn); + } + else + { + static int explained; + gcc_assert (DECL_IOBJ_MEMBER_FUNCTION_P (fn) && !flag_ms_extensions); + /* Is there a reason this error message doesn't match the one in + typeck.cc:cp_build_addr_expr_1? */ + auto_diagnostic_group d; + if (permerror (input_location, "assuming pointer to member %qD", fn) + && !explained) + { + inform (input_location, "(a pointer to member can only be " + "formed with %<&%E%>)", fn); + explained = 1; + } } } diff --git a/gcc/cp/constexpr.cc b/gcc/cp/constexpr.cc index 37500b7..6350fe154 100644 --- a/gcc/cp/constexpr.cc +++ b/gcc/cp/constexpr.cc @@ -291,7 +291,7 @@ is_valid_constexpr_fn (tree fun, bool complain) /* C++14 DR 1684 removed this restriction. */ if (cxx_dialect < cxx14 - && DECL_NONSTATIC_MEMBER_FUNCTION_P (fun) + && DECL_IOBJ_MEMBER_FUNCTION_P (fun) && !CLASSTYPE_LITERAL_P (DECL_CONTEXT (fun))) { ret = false; @@ -1886,7 +1886,7 @@ cxx_bind_parameters_in_call (const constexpr_ctx *ctx, tree t, tree fun, non_constant_p, overflow_p); /* Check we aren't dereferencing a null pointer when calling a non-static member function, which is undefined behaviour. */ - if (i == 0 && DECL_NONSTATIC_MEMBER_FUNCTION_P (fun) + if (i == 0 && DECL_OBJECT_MEMBER_FUNCTION_P (fun) && integer_zerop (arg) /* But ignore calls from within compiler-generated code, to handle cases like lambda function pointer conversion operator thunks diff --git a/gcc/cp/contracts.cc b/gcc/cp/contracts.cc index 6c23f9d..634e3cf 100644 --- a/gcc/cp/contracts.cc +++ b/gcc/cp/contracts.cc @@ -1398,7 +1398,7 @@ build_contract_condition_function (tree fndecl, bool pre) { if (TREE_TYPE (fndecl) == error_mark_node) return error_mark_node; - if (DECL_NONSTATIC_MEMBER_FUNCTION_P (fndecl) + if (DECL_IOBJ_MEMBER_FUNCTION_P (fndecl) && !TYPE_METHOD_BASETYPE (TREE_TYPE (fndecl))) return error_mark_node; @@ -1421,7 +1421,7 @@ build_contract_condition_function (tree fndecl, bool pre) arg_type && arg_type != void_list_node; arg_type = TREE_CHAIN (arg_type)) { - if (DECL_NONSTATIC_MEMBER_FUNCTION_P (fndecl) + if (DECL_IOBJ_MEMBER_FUNCTION_P (fndecl) && TYPE_ARG_TYPES (TREE_TYPE (fn)) == arg_type) { class_type = TREE_TYPE (TREE_VALUE (arg_type)); @@ -1451,7 +1451,7 @@ build_contract_condition_function (tree fndecl, bool pre) } TREE_TYPE (fn) = build_function_type (value_type, arg_types); - if (DECL_NONSTATIC_MEMBER_FUNCTION_P (fndecl)) + if (DECL_IOBJ_MEMBER_FUNCTION_P (fndecl)) TREE_TYPE (fn) = build_method_type (class_type, TREE_TYPE (fn)); DECL_NAME (fn) = copy_node (DECL_NAME (fn)); diff --git a/gcc/cp/cp-objcp-common.cc b/gcc/cp/cp-objcp-common.cc index 2bec8e6..f06edf0 100644 --- a/gcc/cp/cp-objcp-common.cc +++ b/gcc/cp/cp-objcp-common.cc @@ -349,7 +349,7 @@ cp_decl_dwarf_attribute (const_tree decl, int attr) case DW_AT_reference: if (TREE_CODE (decl) == FUNCTION_DECL - && DECL_NONSTATIC_MEMBER_FUNCTION_P (decl) + && DECL_IOBJ_MEMBER_FUNCTION_P (decl) && FUNCTION_REF_QUALIFIED (TREE_TYPE (decl)) && !FUNCTION_RVALUE_QUALIFIED (TREE_TYPE (decl))) return 1; @@ -357,7 +357,7 @@ cp_decl_dwarf_attribute (const_tree decl, int attr) case DW_AT_rvalue_reference: if (TREE_CODE (decl) == FUNCTION_DECL - && DECL_NONSTATIC_MEMBER_FUNCTION_P (decl) + && DECL_IOBJ_MEMBER_FUNCTION_P (decl) && FUNCTION_REF_QUALIFIED (TREE_TYPE (decl)) && FUNCTION_RVALUE_QUALIFIED (TREE_TYPE (decl))) return 1; diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 86084b5..d9b14d7 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -2962,8 +2962,9 @@ struct GTY(()) lang_decl_fn { unsigned coroutine_p : 1; unsigned implicit_constexpr : 1; unsigned escalated_p : 1; + unsigned xobj_func : 1; - unsigned spare : 8; + unsigned spare : 7; /* 32-bits padding on 64-bit host. */ @@ -3361,33 +3362,55 @@ struct GTY(()) lang_decl { #define DECL_STATIC_FUNCTION_P(NODE) \ (LANG_DECL_FN_CHECK (NODE)->static_function) -/* Nonzero for FUNCTION_DECL means that this decl is a non-static +/* Nonzero for FUNCTION_DECL means that this decl is a non-static member + function. C++23 explicit object member functions are also considered + non-static, but most former uses of this macro meant implicit object member + function. Instead of this macro, use DECL_IOBJ_MEMBER_FUNCTION_P or + DECL_OBJECT_MEMBER_FUNCTION_P. */ +#define DECL_NONSTATIC_MEMBER_FUNCTION_P(NODE) did_you_mean_object_or_iobj + +/* Nonzero for FUNCTION_DECL means that this decl is an implicit object member function. */ -#define DECL_NONSTATIC_MEMBER_FUNCTION_P(NODE) \ +#define DECL_IOBJ_MEMBER_FUNCTION_P(NODE) \ (TREE_CODE (TREE_TYPE (NODE)) == METHOD_TYPE) +/* Simple member access, only valid for FUNCTION_DECL nodes. */ +#define DECL_FUNCTION_XOBJ_FLAG(NODE) \ + (LANG_DECL_FN_CHECK (NODE)->xobj_func) + +/* Nonzero if NODE is an xobj member function, + safely evaluates to false for all non FUNCTION_DECL nodes. */ +#define DECL_XOBJ_MEMBER_FUNCTION_P(NODE) \ + (TREE_CODE (STRIP_TEMPLATE (NODE)) == FUNCTION_DECL \ + && DECL_FUNCTION_XOBJ_FLAG (NODE) == 1) + +/* Nonzero if NODE is a member function with an object argument, + in other words, a non-static member function. */ +#define DECL_OBJECT_MEMBER_FUNCTION_P(NODE) \ + (DECL_IOBJ_MEMBER_FUNCTION_P (NODE) || DECL_XOBJ_MEMBER_FUNCTION_P (NODE)) + /* Nonzero for FUNCTION_DECL means that this decl is a member function (static or non-static). */ #define DECL_FUNCTION_MEMBER_P(NODE) \ - (DECL_NONSTATIC_MEMBER_FUNCTION_P (NODE) || DECL_STATIC_FUNCTION_P (NODE)) + (DECL_OBJECT_MEMBER_FUNCTION_P (NODE) || DECL_STATIC_FUNCTION_P (NODE)) \ /* Nonzero for FUNCTION_DECL means that this member function has `this' as const X *const. */ #define DECL_CONST_MEMFUNC_P(NODE) \ - (DECL_NONSTATIC_MEMBER_FUNCTION_P (NODE) \ + (DECL_IOBJ_MEMBER_FUNCTION_P (NODE) \ && CP_TYPE_CONST_P (TREE_TYPE (TREE_VALUE \ (TYPE_ARG_TYPES (TREE_TYPE (NODE)))))) /* Nonzero for FUNCTION_DECL means that this member function has `this' as volatile X *const. */ #define DECL_VOLATILE_MEMFUNC_P(NODE) \ - (DECL_NONSTATIC_MEMBER_FUNCTION_P (NODE) \ + (DECL_IOBJ_MEMBER_FUNCTION_P (NODE) \ && CP_TYPE_VOLATILE_P (TREE_TYPE (TREE_VALUE \ (TYPE_ARG_TYPES (TREE_TYPE (NODE)))))) /* Nonzero for a DECL means that this member is a non-static member. */ #define DECL_NONSTATIC_MEMBER_P(NODE) \ - (DECL_NONSTATIC_MEMBER_FUNCTION_P (NODE) \ + (DECL_OBJECT_MEMBER_FUNCTION_P (NODE) \ || TREE_CODE (NODE) == FIELD_DECL) /* Nonzero for a FIELD_DECL means that this member object type @@ -6158,7 +6181,9 @@ enum auto_deduction_context identical to their defaults. TFF_NO_TEMPLATE_BINDINGS: do not print information about the template arguments for a function template specialization. - TFF_POINTER: we are printing a pointer type. */ + TFF_POINTER: we are printing a pointer type. + TFF_XOBJ_FUNC: we are printing an explicit object member function's + parameters. */ #define TFF_PLAIN_IDENTIFIER (0) #define TFF_SCOPE (1) @@ -6176,6 +6201,7 @@ enum auto_deduction_context #define TFF_NO_OMIT_DEFAULT_TEMPLATE_ARGUMENTS (1 << 12) #define TFF_NO_TEMPLATE_BINDINGS (1 << 13) #define TFF_POINTER (1 << 14) +#define TFF_XOBJ_FUNC (1 << 15) /* These constants can be used as bit flags to control strip_typedefs. @@ -6318,11 +6344,13 @@ enum cp_storage_class { /* An individual decl-specifier. This is used to index the array of locations for the declspecs in struct cp_decl_specifier_seq - below. */ + below. + A subset of these enums also corresponds to elements of + cp_parser_set_decl_spec_type:decl_spec_names in parser.cc. */ enum cp_decl_spec { ds_first, - ds_signed = ds_first, + ds_signed = ds_first, /* Index of first element of decl_spec_names. */ ds_unsigned, ds_short, ds_long, @@ -6339,6 +6367,7 @@ enum cp_decl_spec { ds_complex, ds_constinit, ds_consteval, + ds_this, /* Index of last element of decl_spec_names. */ ds_thread, ds_type_spec, ds_redefined_builtin_type_spec, @@ -6824,6 +6853,8 @@ extern bool is_empty_base_ref (tree); extern tree build_vtbl_ref (tree, tree); extern tree build_vfn_ref (tree, tree); extern tree get_vtable_decl (tree, int); +extern bool object_parms_correspond (tree, tree, tree); +extern bool iobj_parm_corresponds_to (tree, tree, tree); extern bool add_method (tree, tree, bool); extern tree declared_access (tree); extern bool maybe_push_used_methods (tree); @@ -7755,6 +7786,7 @@ extern void finish_handler_parms (tree, tree); extern void finish_handler (tree); extern void finish_cleanup (tree, tree); extern bool is_this_parameter (tree); +extern bool is_object_parameter (tree); enum { BCS_NORMAL = 0, diff --git a/gcc/cp/cxx-pretty-print.cc b/gcc/cp/cxx-pretty-print.cc index c7c4ae5..c6d8cc8 100644 --- a/gcc/cp/cxx-pretty-print.cc +++ b/gcc/cp/cxx-pretty-print.cc @@ -553,7 +553,7 @@ cxx_pretty_printer::postfix_expression (tree t) instantiation time. */ if (TREE_CODE (fun) != FUNCTION_DECL) ; - else if (DECL_NONSTATIC_MEMBER_FUNCTION_P (fun)) + else if (DECL_OBJECT_MEMBER_FUNCTION_P (fun)) { tree object = (code == AGGR_INIT_EXPR ? (AGGR_INIT_VIA_CTOR_P (t) @@ -1342,7 +1342,7 @@ cxx_pretty_printer::declaration_specifiers (tree t) do not have a type-specifier in their return types. */ if (DECL_CONSTRUCTOR_P (t) || DECL_CONV_FN_P (t)) function_specifier (t); - else if (DECL_NONSTATIC_MEMBER_FUNCTION_P (t)) + else if (DECL_IOBJ_MEMBER_FUNCTION_P (t)) declaration_specifiers (TREE_TYPE (TREE_TYPE (t))); else c_pretty_printer::declaration_specifiers (t); @@ -1700,7 +1700,7 @@ cxx_pretty_printer::direct_declarator (tree t) expression (t); pp_cxx_parameter_declaration_clause (this, t); - if (DECL_NONSTATIC_MEMBER_FUNCTION_P (t)) + if (DECL_IOBJ_MEMBER_FUNCTION_P (t)) { padding = pp_before; pp_cxx_cv_qualifier_seq (this, pp_cxx_implicit_parameter_type (t)); diff --git a/gcc/cp/decl.cc b/gcc/cp/decl.cc index 80d0327..b10a72a 100644 --- a/gcc/cp/decl.cc +++ b/gcc/cp/decl.cc @@ -8655,7 +8655,7 @@ cp_finish_decl (tree decl, tree init, bool init_const_expr_p, && TREE_CODE (decl) == FUNCTION_DECL /* #pragma omp declare variant on methods handled in finish_struct instead. */ - && (!DECL_NONSTATIC_MEMBER_FUNCTION_P (decl) + && (!DECL_OBJECT_MEMBER_FUNCTION_P (decl) || COMPLETE_TYPE_P (DECL_CONTEXT (decl)))) if (tree attr = lookup_attribute ("omp declare variant base", DECL_ATTRIBUTES (decl))) @@ -10516,6 +10516,7 @@ grokfndecl (tree ctype, int publicp, int inlinep, bool deletedp, + bool xobj_func_p, special_function_kind sfk, bool funcdef_flag, bool late_return_type_p, @@ -10525,7 +10526,6 @@ grokfndecl (tree ctype, location_t location) { tree decl; - int staticp = ctype && TREE_CODE (type) == FUNCTION_TYPE; tree t; if (location == UNKNOWN_LOCATION) @@ -10723,12 +10723,9 @@ grokfndecl (tree ctype, (IDENTIFIER_POINTER (declarator)))))) SET_DECL_LANGUAGE (decl, lang_c); - /* Should probably propagate const out from type to decl I bet (mrs). */ - if (staticp) - { - DECL_STATIC_FUNCTION_P (decl) = 1; - DECL_CONTEXT (decl) = ctype; - } + DECL_STATIC_FUNCTION_P (decl) + = !xobj_func_p && ctype && TREE_CODE (type) == FUNCTION_TYPE; + DECL_FUNCTION_XOBJ_FLAG (decl) = xobj_func_p; if (deletedp) DECL_DELETED_FN (decl) = 1; @@ -10808,24 +10805,30 @@ grokfndecl (tree ctype, TREE_TYPE (decl) = apply_memfn_quals (TREE_TYPE (decl), TYPE_UNQUALIFIED, REF_QUAL_NONE); - + auto_diagnostic_group d; if (quals) - { - error (ctype + error (!ctype + ? G_("non-member function %qD cannot have cv-qualifier") + : !xobj_func_p ? G_("static member function %qD cannot have cv-qualifier") - : G_("non-member function %qD cannot have cv-qualifier"), - decl); - quals = TYPE_UNQUALIFIED; - } - + : G_("explicit object member function " + "%qD cannot have cv-qualifier"), + decl); if (rqual) - { - error (ctype + error (!ctype + ? G_("non-member function %qD cannot have ref-qualifier") + : !xobj_func_p ? G_("static member function %qD cannot have ref-qualifier") - : G_("non-member function %qD cannot have ref-qualifier"), + : G_("explicit object member function " + "%qD cannot have ref-qualifier"), decl); - rqual = REF_QUAL_NONE; - } + + if (xobj_func_p && (quals || rqual)) + inform (DECL_SOURCE_LOCATION (DECL_ARGUMENTS (decl)), + "explicit object parameter declared here"); + quals = TYPE_UNQUALIFIED; + rqual = REF_QUAL_NONE; + } if (deduction_guide_p (decl)) @@ -13198,6 +13201,8 @@ grokdeclarator (const cp_declarator *declarator, if (attrlist) diagnose_misapplied_contracts (*attrlist); + /* Skip over build_memfn_type when a FUNCTION_DECL is an xobj memfn. */ + bool is_xobj_member_function = false; /* Determine the type of the entity declared by recurring on the declarator. */ for (; declarator; declarator = declarator->declarator) @@ -13313,6 +13318,90 @@ grokdeclarator (const cp_declarator *declarator, if (raises == error_mark_node) raises = NULL_TREE; + auto find_xobj_parm = [](tree parm_list) + { + /* There is no need to iterate over the list, + only the first parm can be a valid xobj parm. */ + if (!parm_list || TREE_PURPOSE (parm_list) != this_identifier) + return NULL_TREE; + /* If we make it here, we are looking at an xobj parm. + + Non-null 'purpose' usually means the parm has a default + argument, we don't want to violate this assumption. */ + TREE_PURPOSE (parm_list) = NULL_TREE; + return TREE_VALUE (parm_list); + }; + + tree xobj_parm + = find_xobj_parm (declarator->u.function.parameters); + is_xobj_member_function = xobj_parm; + + if (xobj_parm && cxx_dialect < cxx23) + pedwarn (DECL_SOURCE_LOCATION (xobj_parm), OPT_Wc__23_extensions, + "explicit object member function only available " + "with %<-std=c++23%> or %<-std=gnu++23%>"); + + if (xobj_parm && decl_context == TYPENAME) + { + /* We inform in every case, just differently depending on what + case it is. */ + auto_diagnostic_group d; + bool ptr_type = true; + /* If declarator->kind is cdk_function and we are at the end of + the declarator chain, we are looking at a function type. */ + if (!declarator->declarator) + { + error_at (DECL_SOURCE_LOCATION (xobj_parm), + "a function type cannot " + "have an explicit object parameter"); + ptr_type = false; + } + else if (declarator->declarator->kind == cdk_pointer) + error_at (DECL_SOURCE_LOCATION (xobj_parm), + "a pointer to function type cannot " + "have an explicit object parameter"); + else if (declarator->declarator->kind == cdk_ptrmem) + error_at (DECL_SOURCE_LOCATION (xobj_parm), + "a pointer to member function type " + "cannot have an explicit object parameter"); + else + gcc_unreachable (); + + /* The locations being used here are probably not correct. */ + if (ptr_type) + inform (DECL_SOURCE_LOCATION (xobj_parm), + "the type of a pointer to explicit object member " + "function is a regular pointer to function type"); + else + inform (DECL_SOURCE_LOCATION (xobj_parm), + "the type of an explicit object " + "member function is a regular function type"); + /* Ideally we should synthesize the correct syntax + for the user, perhaps this could be added later. */ + } + /* Since a valid xobj parm has its purpose cleared in find_xobj_parm + the first parm node will never erroneously be detected here. */ + { + auto_diagnostic_group d; + bool bad_xobj_parm_encountered = false; + for (tree parm = declarator->u.function.parameters; + parm && parm != void_list_node; + parm = TREE_CHAIN (parm)) + { + if (TREE_PURPOSE (parm) != this_identifier) + continue; + bad_xobj_parm_encountered = true; + gcc_rich_location bad_xobj_parm + (DECL_SOURCE_LOCATION (TREE_VALUE (parm))); + error_at (&bad_xobj_parm, + "Only the first parameter of a member function " + "can be declared as an explicit object parameter"); + } + if (bad_xobj_parm_encountered && xobj_parm) + inform (DECL_SOURCE_LOCATION (xobj_parm), + "Valid explicit object parameter declared here"); + } + if (reqs) error_at (location_of (reqs), "requires-clause on return type"); reqs = declarator->u.function.requires_clause; @@ -13600,6 +13689,38 @@ grokdeclarator (const cp_declarator *declarator, explicitp = 2; } + if (xobj_parm) + { + if (!ctype + && decl_context == NORMAL + && (in_namespace + || !declarator->declarator->u.id.qualifying_scope)) + error_at (DECL_SOURCE_LOCATION (xobj_parm), + "a non-member function cannot have " + "an explicit object parameter"); + else + { + if (virtualp) + { + auto_diagnostic_group d; + error_at (declspecs->locations[ds_virtual], + "an explicit object member function cannot " + "be %<virtual%>"); + inform (DECL_SOURCE_LOCATION (xobj_parm), + "explicit object parameter declared here"); + virtualp = false; + } + if (staticp >= 2) + { + auto_diagnostic_group d; + error_at (declspecs->locations[ds_storage_class], + "an explicit object member function cannot " + "be %<static%>"); + inform (DECL_SOURCE_LOCATION (xobj_parm), + "explicit object parameter declared here"); + } + } + } tree pushed_scope = NULL_TREE; if (funcdecl_p && decl_context != FIELD @@ -14386,6 +14507,8 @@ grokdeclarator (const cp_declarator *declarator, } if (ctype && TREE_CODE (type) == FUNCTION_TYPE && staticp < 2 + /* Don't convert xobj member functions to METHOD_TYPE. */ + && !is_xobj_member_function && !(unqualified_id && identifier_p (unqualified_id) && IDENTIFIER_NEWDEL_OP_P (unqualified_id))) @@ -14607,7 +14730,8 @@ grokdeclarator (const cp_declarator *declarator, friendp ? -1 : 0, friendp, publicp, inlinep | (2 * constexpr_p) | (4 * concept_p) | (8 * consteval_p), - initialized == SD_DELETED, sfk, + initialized == SD_DELETED, + is_xobj_member_function, sfk, funcdef_flag, late_return_type_p, template_count, in_namespace, attrlist, id_loc); @@ -14942,8 +15066,8 @@ grokdeclarator (const cp_declarator *declarator, inlinep | (2 * constexpr_p) | (4 * concept_p) | (8 * consteval_p), initialized == SD_DELETED, - sfk, - funcdef_flag, + is_xobj_member_function, sfk, + funcdef_flag, late_return_type_p, template_count, in_namespace, attrlist, id_loc); @@ -15539,7 +15663,19 @@ copy_fn_p (const_tree d) && DECL_NAME (d) != assign_op_identifier) return 0; - args = FUNCTION_FIRST_USER_PARMTYPE (d); + if (DECL_XOBJ_MEMBER_FUNCTION_P (d)) + { + tree object_param = TREE_VALUE (TYPE_ARG_TYPES (TREE_TYPE (d))); + if (!TYPE_REF_P (object_param) + || TYPE_REF_IS_RVALUE (object_param) + /* Reject unrelated object parameters. */ + || TYPE_MAIN_VARIANT (TREE_TYPE (object_param)) != DECL_CONTEXT (d) + || CP_TYPE_CONST_P (TREE_TYPE (object_param))) + return 0; + args = TREE_CHAIN (TYPE_ARG_TYPES (TREE_TYPE (d))); + } + else + args = FUNCTION_FIRST_USER_PARMTYPE (d); if (!args) return 0; @@ -15614,7 +15750,19 @@ move_signature_fn_p (const_tree d) && DECL_NAME (d) != assign_op_identifier) return 0; - args = FUNCTION_FIRST_USER_PARMTYPE (d); + if (DECL_XOBJ_MEMBER_FUNCTION_P (d)) + { + tree object_param = TREE_VALUE (TYPE_ARG_TYPES (TREE_TYPE (d))); + if (!TYPE_REF_P (object_param) + || TYPE_REF_IS_RVALUE (object_param) + /* Reject unrelated object parameters. */ + || TYPE_MAIN_VARIANT (TREE_TYPE (object_param)) != DECL_CONTEXT (d) + || CP_TYPE_CONST_P (TREE_TYPE (object_param))) + return 0; + args = TREE_CHAIN (TYPE_ARG_TYPES (TREE_TYPE (d))); + } + else + args = FUNCTION_FIRST_USER_PARMTYPE (d); if (!args) return 0; @@ -15645,7 +15793,7 @@ grok_special_member_properties (tree decl) tree class_type; if (TREE_CODE (decl) == USING_DECL - || !DECL_NONSTATIC_MEMBER_FUNCTION_P (decl)) + || !DECL_OBJECT_MEMBER_FUNCTION_P (decl)) return; class_type = DECL_CONTEXT (decl); @@ -15744,7 +15892,7 @@ bool grok_op_properties (tree decl, bool complain) { tree argtypes = TYPE_ARG_TYPES (TREE_TYPE (decl)); - bool methodp = TREE_CODE (TREE_TYPE (decl)) == METHOD_TYPE; + bool const methodp = DECL_IOBJ_MEMBER_FUNCTION_P (decl); tree name = DECL_NAME (decl); location_t loc = DECL_SOURCE_LOCATION (decl); @@ -15837,7 +15985,7 @@ grok_op_properties (tree decl, bool complain) /* An operator function must either be a non-static member function or have at least one parameter of a class, a reference to a class, an enumeration, or a reference to an enumeration. 13.4.0.6 */ - if (! methodp || DECL_STATIC_FUNCTION_P (decl)) + if (!DECL_OBJECT_MEMBER_FUNCTION_P (decl)) { if (operator_code == TYPE_EXPR || operator_code == COMPONENT_REF @@ -15926,7 +16074,7 @@ grok_op_properties (tree decl, bool complain) } ++arity; } - + /* FIXME: We need tests for these errors with xobj member functions. */ /* Verify correct number of arguments. */ switch (op_flags) { @@ -17835,7 +17983,7 @@ start_preparsed_function (tree decl1, tree attrs, int flags) /* Start the statement-tree, start the tree now. */ DECL_SAVED_TREE (decl1) = push_stmt_list (); - if (DECL_NONSTATIC_MEMBER_FUNCTION_P (decl1)) + if (DECL_IOBJ_MEMBER_FUNCTION_P (decl1)) { /* We know that this was set up by `grokclassfn'. We do not wait until `store_parm_decls', since evil parse errors may @@ -18304,7 +18452,7 @@ outer_curly_brace_block (tree fndecl) static void record_key_method_defined (tree fndecl) { - if (DECL_NONSTATIC_MEMBER_FUNCTION_P (fndecl) + if (DECL_OBJECT_MEMBER_FUNCTION_P (fndecl) && DECL_VIRTUAL_P (fndecl) && !processing_template_decl) { diff --git a/gcc/cp/decl2.cc b/gcc/cp/decl2.cc index 5ceed56..fdc52a0 100644 --- a/gcc/cp/decl2.cc +++ b/gcc/cp/decl2.cc @@ -5676,7 +5676,7 @@ cp_handle_deprecated_or_unavailable (tree decl, tsubst_flags_t complain) if (cxx_dialect >= cxx11 && DECL_P (decl) && DECL_ARTIFICIAL (decl) - && DECL_NONSTATIC_MEMBER_FUNCTION_P (decl) + && DECL_IOBJ_MEMBER_FUNCTION_P (decl) && copy_fn_p (decl)) { /* Don't warn if the flag was disabled around the class definition diff --git a/gcc/cp/error.cc b/gcc/cp/error.cc index a384f62..52e24fb 100644 --- a/gcc/cp/error.cc +++ b/gcc/cp/error.cc @@ -840,10 +840,14 @@ dump_aggr_type (cxx_pretty_printer *pp, tree t, int flags) { /* A lambda's "type" is essentially its signature. */ pp_string (pp, M_("<lambda")); - if (lambda_function (t)) - dump_parameters (pp, - FUNCTION_FIRST_USER_PARMTYPE (lambda_function (t)), - flags); + tree const fn = lambda_function (t); + if (fn) + { + int const parm_flags + = DECL_XOBJ_MEMBER_FUNCTION_P (fn) ? TFF_XOBJ_FUNC | flags + : flags; + dump_parameters (pp, FUNCTION_FIRST_USER_PARMTYPE (fn), parm_flags); + } pp_greater (pp); } else if (!decl || IDENTIFIER_ANON_P (DECL_NAME (decl))) @@ -1712,7 +1716,9 @@ dump_lambda_function (cxx_pretty_printer *pp, { /* A lambda's signature is essentially its "type". */ dump_type (pp, DECL_CONTEXT (fn), flags); - if (TREE_CODE (TREE_TYPE (fn)) == FUNCTION_TYPE) + if (DECL_XOBJ_MEMBER_FUNCTION_P (fn)) + /* Early escape. */; + else if (TREE_CODE (TREE_TYPE (fn)) == FUNCTION_TYPE) { pp->padding = pp_before; pp_c_ws_string (pp, "static"); @@ -1833,7 +1839,9 @@ dump_function_decl (cxx_pretty_printer *pp, tree t, int flags) if (!(flags & TFF_NO_FUNCTION_ARGUMENTS)) { - dump_parameters (pp, parmtypes, flags); + int const parm_flags + = DECL_XOBJ_MEMBER_FUNCTION_P (t) ? TFF_XOBJ_FUNC | flags : flags; + dump_parameters (pp, parmtypes, parm_flags); if (TREE_CODE (fntype) == METHOD_TYPE) { @@ -1912,6 +1920,8 @@ dump_parameters (cxx_pretty_printer *pp, tree parmtypes, int flags) for (first = 1; parmtypes != void_list_node; parmtypes = TREE_CHAIN (parmtypes)) { + if (first && flags & TFF_XOBJ_FUNC) + pp_string (pp, "this "); if (!first) pp_separate_with_comma (pp); first = 0; @@ -3696,6 +3706,8 @@ function_category (tree fn) return _("In destructor %qD"); else if (LAMBDA_FUNCTION_P (fn)) return _("In lambda function"); + else if (DECL_XOBJ_MEMBER_FUNCTION_P (fn)) + return _("In explicit object member function %qD"); else return _("In member function %qD"); } diff --git a/gcc/cp/init.cc b/gcc/cp/init.cc index 0958471..adbdfc2 100644 --- a/gcc/cp/init.cc +++ b/gcc/cp/init.cc @@ -866,7 +866,7 @@ find_uninit_fields_r (tree *tp, int *walk_subtrees, void *data) else if (code == CALL_EXPR) { tree fn = get_callee_fndecl (init); - if (fn && DECL_NONSTATIC_MEMBER_FUNCTION_P (fn)) + if (fn && DECL_IOBJ_MEMBER_FUNCTION_P (fn)) { tree op = CALL_EXPR_ARG (init, 0); if (TREE_CODE (op) == ADDR_EXPR) @@ -2477,7 +2477,7 @@ build_offset_ref (tree type, tree member, bool address_p, -- in a mem-initializer for a constructor for that class or for a class derived from that class (_class.base.init_). */ - if (DECL_NONSTATIC_MEMBER_FUNCTION_P (member)) + if (DECL_OBJECT_MEMBER_FUNCTION_P (member)) { /* Build a representation of the qualified name suitable for use as the operand to "&" -- even though the "&" is @@ -4155,7 +4155,8 @@ build_vec_delete_1 (location_t loc, tree base, tree maxindex, tree type, /* If one destructor throws, keep trying to clean up the rest, unless we're already in a build_vec_init cleanup. */ - if (flag_exceptions && !in_cleanup && !expr_noexcept_p (tmp, tf_none)) + if (flag_exceptions && !in_cleanup && !processing_template_decl + && !expr_noexcept_p (tmp, tf_none)) { loop = build2 (TRY_CATCH_EXPR, void_type_node, loop, unshare_expr (loop)); diff --git a/gcc/cp/lambda.cc b/gcc/cp/lambda.cc index f995522..1d37e5a 100644 --- a/gcc/cp/lambda.cc +++ b/gcc/cp/lambda.cc @@ -404,8 +404,10 @@ build_capture_proxy (tree member, tree init) fn = lambda_function (closure); lam = CLASSTYPE_LAMBDA_EXPR (closure); + object = DECL_ARGUMENTS (fn); /* The proxy variable forwards to the capture field. */ - object = build_fold_indirect_ref (DECL_ARGUMENTS (fn)); + if (INDIRECT_TYPE_P (TREE_TYPE (object))) + object = build_fold_indirect_ref (object); object = finish_non_static_data_member (member, object, NULL_TREE); if (REFERENCE_REF_P (object)) object = TREE_OPERAND (object, 0); @@ -834,8 +836,9 @@ lambda_expr_this_capture (tree lambda, int add_capture_p) if (!LAMBDA_FUNCTION_P (containing_function)) { - /* We found a non-lambda function. */ - if (DECL_NONSTATIC_MEMBER_FUNCTION_P (containing_function)) + /* We found a non-lambda function. + There is no this pointer in xobj member functions. */ + if (DECL_IOBJ_MEMBER_FUNCTION_P (containing_function)) /* First parameter is 'this'. */ init = DECL_ARGUMENTS (containing_function); break; @@ -969,7 +972,7 @@ maybe_generic_this_capture (tree object, tree fns) for (lkp_iterator iter (fns); iter; ++iter) if (((!id_expr && TREE_CODE (*iter) != USING_DECL) || TREE_CODE (*iter) == TEMPLATE_DECL) - && DECL_NONSTATIC_MEMBER_FUNCTION_P (*iter)) + && DECL_IOBJ_MEMBER_FUNCTION_P (*iter)) { /* Found a non-static member. Capture this. */ lambda_expr_this_capture (lam, /*maybe*/-1); @@ -1012,7 +1015,7 @@ nonlambda_method_basetype (void) tree fn = TYPE_CONTEXT (type); if (!fn || TREE_CODE (fn) != FUNCTION_DECL - || !DECL_NONSTATIC_MEMBER_FUNCTION_P (fn)) + || !DECL_IOBJ_MEMBER_FUNCTION_P (fn)) /* No enclosing non-lambda method. */ return NULL_TREE; if (!LAMBDA_FUNCTION_P (fn)) diff --git a/gcc/cp/mangle.cc b/gcc/cp/mangle.cc index 0546860..a04bc58 100644 --- a/gcc/cp/mangle.cc +++ b/gcc/cp/mangle.cc @@ -1231,9 +1231,9 @@ write_nested_name (const tree decl) write_char ('N'); - /* Write CV-qualifiers, if this is a member function. */ + /* Write CV-qualifiers, if this is an iobj member function. */ if (TREE_CODE (decl) == FUNCTION_DECL - && DECL_NONSTATIC_MEMBER_FUNCTION_P (decl)) + && DECL_IOBJ_MEMBER_FUNCTION_P (decl)) { if (DECL_VOLATILE_MEMFUNC_P (decl)) write_char ('V'); @@ -1247,6 +1247,9 @@ write_nested_name (const tree decl) write_char ('R'); } } + else if (DECL_DECLARES_FUNCTION_P (decl) + && DECL_XOBJ_MEMBER_FUNCTION_P (decl)) + write_char ('H'); /* Is this a template instance? */ if (tree info = maybe_template_info (decl)) diff --git a/gcc/cp/method.cc b/gcc/cp/method.cc index fcf6cfa..d49e5a5 100644 --- a/gcc/cp/method.cc +++ b/gcc/cp/method.cc @@ -795,13 +795,19 @@ do_build_copy_assign (tree fndecl) compound_stmt = begin_compound_stmt (0); parm = convert_from_reference (parm); + /* If we are building a defaulted xobj copy/move assignment operator then + current_class_ref will not have been set up. + Kind of an icky hack, but what can ya do? */ + tree const class_ref = DECL_XOBJ_MEMBER_FUNCTION_P (fndecl) + ? cp_build_fold_indirect_ref (DECL_ARGUMENTS (fndecl)) : current_class_ref; + if (trivial && is_empty_class (current_class_type)) /* Don't copy the padding byte; it might not have been allocated if *this is a base subobject. */; else if (trivial) { - tree t = build2 (MODIFY_EXPR, void_type_node, current_class_ref, parm); + tree t = build2 (MODIFY_EXPR, void_type_node, class_ref, parm); finish_expr_stmt (t); } else @@ -826,7 +832,7 @@ do_build_copy_assign (tree fndecl) /* Call the base class assignment operator. */ releasing_vec parmvec (make_tree_vector_single (converted_parm)); finish_expr_stmt - (build_special_member_call (current_class_ref, + (build_special_member_call (class_ref, assign_op_identifier, &parmvec, base_binfo, @@ -839,7 +845,7 @@ do_build_copy_assign (tree fndecl) fields; fields = DECL_CHAIN (fields)) { - tree comp = current_class_ref; + tree comp = class_ref; tree init = parm; tree field = fields; tree expr_type; @@ -898,7 +904,7 @@ do_build_copy_assign (tree fndecl) finish_expr_stmt (init); } } - finish_return_stmt (current_class_ref); + finish_return_stmt (class_ref); finish_compound_stmt (compound_stmt); } @@ -1187,7 +1193,7 @@ early_check_defaulted_comparison (tree fn) ok = false; } - bool mem = DECL_NONSTATIC_MEMBER_FUNCTION_P (fn); + bool mem = DECL_IOBJ_MEMBER_FUNCTION_P (fn); if (mem && type_memfn_quals (TREE_TYPE (fn)) != TYPE_QUAL_CONST) { error_at (loc, "defaulted %qD must be %<const%>", fn); @@ -1230,7 +1236,7 @@ early_check_defaulted_comparison (tree fn) if (saw_bad || (saw_byval && saw_byref)) { - if (DECL_NONSTATIC_MEMBER_FUNCTION_P (fn)) + if (DECL_IOBJ_MEMBER_FUNCTION_P (fn)) error_at (loc, "defaulted member %qD must have parameter type " "%<const %T&%>", fn, ctx); else if (saw_bad) @@ -3380,10 +3386,32 @@ defaulted_late_check (tree fn) NULL, NULL); tree eh_spec = TYPE_RAISES_EXCEPTIONS (TREE_TYPE (implicit_fn)); + /* Includes special handling for a default xobj operator. */ + auto compare_fn_params = [](tree fn, tree implicit_fn){ + tree fn_parms = TYPE_ARG_TYPES (TREE_TYPE (fn)); + tree implicit_fn_parms = TYPE_ARG_TYPES (TREE_TYPE (implicit_fn)); + + if (DECL_XOBJ_MEMBER_FUNCTION_P (fn)) + { + tree fn_obj_ref_type = TREE_VALUE (fn_parms); + /* We can't default xobj operators with an xobj parameter that is not + an lvalue reference, even if it would correspond. */ + if (!TYPE_REF_P (fn_obj_ref_type) + || TYPE_REF_IS_RVALUE (fn_obj_ref_type) + || !object_parms_correspond (fn, implicit_fn, + DECL_CONTEXT (implicit_fn))) + return false; + /* We just compared the object parameters, skip over them before + passing to compparms. */ + fn_parms = TREE_CHAIN (fn_parms); + implicit_fn_parms = TREE_CHAIN (implicit_fn_parms); + } + return compparms (fn_parms, implicit_fn_parms); + }; + if (!same_type_p (TREE_TYPE (TREE_TYPE (fn)), TREE_TYPE (TREE_TYPE (implicit_fn))) - || !compparms (TYPE_ARG_TYPES (TREE_TYPE (fn)), - TYPE_ARG_TYPES (TREE_TYPE (implicit_fn)))) + || !compare_fn_params (fn, implicit_fn)) { error ("defaulted declaration %q+D does not match the " "expected signature", fn); @@ -3473,6 +3501,10 @@ defaultable_fn_check (tree fn) return false; } + /* FIXME: We need to check for xobj member functions here to give better + diagnostics for weird cases where unrelated xobj parameters are given. + We just want to do better than 'cannot be defaulted'. */ + if (kind == sfk_none) { error ("%qD cannot be defaulted", fn); @@ -3606,7 +3638,7 @@ lazily_declare_fn (special_function_kind sfk, tree type) tree skip_artificial_parms_for (const_tree fn, tree list) { - if (DECL_NONSTATIC_MEMBER_FUNCTION_P (fn)) + if (DECL_IOBJ_MEMBER_FUNCTION_P (fn)) list = TREE_CHAIN (list); else return list; @@ -3626,7 +3658,7 @@ num_artificial_parms_for (const_tree fn) { int count = 0; - if (DECL_NONSTATIC_MEMBER_FUNCTION_P (fn)) + if (DECL_IOBJ_MEMBER_FUNCTION_P (fn)) count++; else return 0; diff --git a/gcc/cp/module.cc b/gcc/cp/module.cc index 9bb6d26..aa75e28 100644 --- a/gcc/cp/module.cc +++ b/gcc/cp/module.cc @@ -5683,8 +5683,9 @@ trees_out::lang_decl_bools (tree t) WB (lang->u.fn.has_dependent_explicit_spec_p); WB (lang->u.fn.immediate_fn_p); WB (lang->u.fn.maybe_deleted); - WB (lang->u.fn.escalated_p); /* We do not stream lang->u.fn.implicit_constexpr. */ + WB (lang->u.fn.escalated_p); + WB (lang->u.fn.xobj_func); goto lds_min; case lds_decomp: /* lang_decl_decomp. */ @@ -5753,8 +5754,9 @@ trees_in::lang_decl_bools (tree t) RB (lang->u.fn.has_dependent_explicit_spec_p); RB (lang->u.fn.immediate_fn_p); RB (lang->u.fn.maybe_deleted); - RB (lang->u.fn.escalated_p); /* We do not stream lang->u.fn.implicit_constexpr. */ + RB (lang->u.fn.escalated_p); + RB (lang->u.fn.xobj_func); goto lds_min; case lds_decomp: /* lang_decl_decomp. */ diff --git a/gcc/cp/name-lookup.cc b/gcc/cp/name-lookup.cc index 26c6bc7..d827d33 100644 --- a/gcc/cp/name-lookup.cc +++ b/gcc/cp/name-lookup.cc @@ -8089,9 +8089,19 @@ lookup_elaborated_type (tree name, TAG_how how) { /* We're in the global module, perhaps there's a tag there? */ - // FIXME: This isn't quite right, if we find something - // here, from the language PoV we're not supposed to - // know it? + + /* FIXME: In general we should probably merge global module + classes in check_module_override rather than here, but for + GCC14 let's just fix lazy declarations of __class_type_info in + build_dynamic_cast_1. */ + if (current_namespace == abi_node) + { + tree g = (BINDING_VECTOR_CLUSTER (*slot, 0) + .slots[BINDING_SLOT_GLOBAL]); + for (ovl_iterator iter (g); iter; ++iter) + if (qualify_lookup (*iter, LOOK_want::TYPE)) + return *iter; + } } } } diff --git a/gcc/cp/parser.cc b/gcc/cp/parser.cc index 706ed21..c7ad3ec 100644 --- a/gcc/cp/parser.cc +++ b/gcc/cp/parser.cc @@ -11874,8 +11874,12 @@ cp_parser_lambda_declarator_opt (cp_parser* parser, tree lambda_expr) else if (cxx_dialect < cxx23) omitted_parms_loc = cp_lexer_peek_token (parser->lexer)->location; - /* In the decl-specifier-seq of the lambda-declarator, each - decl-specifier shall either be mutable or constexpr. */ + /* [expr.prim.lambda.general] + lambda-specifier: + consteval, constexpr, mutable, static + [4] A lambda-specifier-seq shall contain at most one of each + lambda-specifier and shall not contain both constexpr and consteval. + The lambda-specifier-seq shall not contain both mutable and static. */ int declares_class_or_enum; if (cp_lexer_next_token_is_decl_specifier_keyword (parser->lexer)) cp_parser_decl_specifier_seq (parser, @@ -11890,13 +11894,83 @@ cp_parser_lambda_declarator_opt (cp_parser* parser, tree lambda_expr) "%<-std=gnu++2b%>"); omitted_parms_loc = UNKNOWN_LOCATION; } - - if (lambda_specs.storage_class == sc_mutable) + /* Peek at the params, see if we have an xobj parameter. */ + if (param_list && TREE_PURPOSE (param_list) == this_identifier) + { + quals = TYPE_UNQUALIFIED; + /* We still need grokdeclarator to see that this is an xobj function + and finish the rest of the work, don't mutate it. */ + tree const xobj_param = TREE_VALUE (param_list); + tree const param_type = TREE_TYPE (xobj_param); + /* [expr.prim.lambda.closure-5] + Given a lambda with a lambda-capture, the type of the explicit object + parameter, if any, of the lambda's function call operator (possibly + instantiated from a function call operator template) shall be either: + -- the closure type, + -- a class type derived from the closure type, or + -- a reference to a possibly cv-qualified such type. */ + bool const unrelated_with_captures + = (LAMBDA_EXPR_DEFAULT_CAPTURE_MODE (lambda_expr) != CPLD_NONE + || LAMBDA_EXPR_CAPTURE_LIST (lambda_expr)) + /* Since a lambda's type is anonymous, we can assume an xobj + parameter is unrelated to the closure if it is non-dependent. + If it is dependent we handle it at instantiation time. */ + && !WILDCARD_TYPE_P (non_reference (param_type)); + if (unrelated_with_captures) + { + error_at (DECL_SOURCE_LOCATION (xobj_param), + "a lambda with captures may not have an explicit object " + "parameter of an unrelated type"); + LAMBDA_EXPR_CAPTURE_LIST (lambda_expr) = NULL_TREE; + } + + /* [expr.prim.lambda.general-4] + If the lambda-declarator contains an explicit object parameter + ([dcl.fct]), then no lambda-specifier in the lambda-specifier-seq + shall be mutable or static. */ + if (lambda_specs.storage_class == sc_mutable) + { + auto_diagnostic_group d; + error_at (lambda_specs.locations[ds_storage_class], + "%<mutable%> lambda specifier " + "with explicit object parameter"); + /* Tell the user how to do what they probably meant, maybe fixits + would be appropriate later? */ + if (unrelated_with_captures) + /* The following hints don't make sense when we already have an + unrelated type with captures, don't emit them. */; + else if (!TYPE_REF_P (param_type)) + inform (DECL_SOURCE_LOCATION (xobj_param), + "the passed in closure object will not be mutated because " + "it is taken by value"); + else if (TYPE_READONLY (TREE_TYPE (param_type))) + inform (DECL_SOURCE_LOCATION (xobj_param), + "declare the explicit object parameter as non-const " + "reference instead"); + else + inform (DECL_SOURCE_LOCATION (xobj_param), + "explicit object parameter is already a mutable " + "reference"); + } + else if (lambda_specs.storage_class == sc_static) + { + auto_diagnostic_group d; + error_at (lambda_specs.locations[ds_storage_class], + "%<static%> lambda specifier " + "with explicit object parameter"); + inform (DECL_SOURCE_LOCATION (xobj_param), + "explicit object parameter declared here"); + } + } + else if (lambda_specs.storage_class == sc_mutable) { quals = TYPE_UNQUALIFIED; } else if (lambda_specs.storage_class == sc_static) { + /* [expr.prim.lambda.general-4] + If the lambda-specifier-seq contains static, there shall be no + lambda-capture. */ if (LAMBDA_EXPR_DEFAULT_CAPTURE_MODE (lambda_expr) != CPLD_NONE || LAMBDA_EXPR_CAPTURE_LIST (lambda_expr)) error_at (lambda_specs.locations[ds_storage_class], @@ -12021,7 +12095,7 @@ cp_parser_lambda_declarator_opt (cp_parser* parser, tree lambda_expr) { DECL_INITIALIZED_IN_CLASS_P (fco) = 1; DECL_ARTIFICIAL (fco) = 1; - if (!LAMBDA_EXPR_STATIC_P (lambda_expr)) + if (DECL_IOBJ_MEMBER_FUNCTION_P (fco)) /* Give the object parameter a different name. */ DECL_NAME (DECL_ARGUMENTS (fco)) = closure_identifier; DECL_SET_LAMBDA_FUNCTION (fco, true); @@ -16188,6 +16262,8 @@ cp_parser_decl_specifier_seq (cp_parser* parser, /* Assume no class or enumeration type is declared. */ *declares_class_or_enum = 0; + /* Keep a token that additionally will be used for diagnostics. */ + cp_token *first_specifier = NULL; /* Keep reading specifiers until there are no more to read. */ while (true) { @@ -16260,6 +16336,36 @@ cp_parser_decl_specifier_seq (cp_parser* parser, decl_specs->locations[ds_attribute] = token->location; continue; } + /* We know by this point that the token is not part of an attribute. */ + if (!first_specifier) + first_specifier = token; + /* Special case for "this" specifier, indicating a parm is an xobj parm. + The "this" specifier must be the first specifier in the declaration, + after any attributes. */ + if (token->keyword == RID_THIS) + { + cp_lexer_consume_token (parser->lexer); + if (token != first_specifier) + { + /* Don't emit diagnostics if we have already seen "this", + leave it for set_and_check_decl_spec_loc. */ + if (decl_specs->locations[ds_this] == 0) + { + auto_diagnostic_group d; + gcc_rich_location richloc (token->location); + /* Works, need to add tests for it though. */ + richloc.add_fixit_remove (); + richloc.add_fixit_insert_before (first_specifier->location, + "this "); + error_at (&richloc, + "%<this%> must be the first specifier " + "in a parameter declaration"); + } + } + set_and_check_decl_spec_loc (decl_specs, ds_this, token); + continue; + } + /* Assume we will find a decl-specifier keyword. */ found_decl_spec = true; /* If the next token is an appropriate keyword, we can simply @@ -24957,12 +25063,20 @@ cp_parser_type_id (cp_parser *parser, cp_parser_flags flags, static tree cp_parser_template_type_arg (cp_parser *parser) { - tree r; const char *saved_message = parser->type_definition_forbidden_message; parser->type_definition_forbidden_message = G_("types may not be defined in template arguments"); - r = cp_parser_type_id_1 (parser, CP_PARSER_FLAGS_NONE, true, false, NULL); + tree r = cp_parser_type_id_1 (parser, CP_PARSER_FLAGS_NONE, + /*is_template_arg=*/true, + /*is_trailing_return=*/false, nullptr); parser->type_definition_forbidden_message = saved_message; + /* cp_parser_type_id_1 checks for auto, but only for + ->auto_is_implicit_function_template_parm_p. */ + if (cxx_dialect >= cxx14 && !flag_concepts_ts && type_uses_auto (r)) + { + error ("invalid use of %<auto%> in template argument"); + r = error_mark_node; + } return r; } @@ -25647,12 +25761,14 @@ cp_parser_parameter_declaration (cp_parser *parser, /* The restriction on defining new types applies only to the type of the parameter, not to the default argument. */ parser->type_definition_forbidden_message = saved_message; - + cp_token *eq_token = NULL; /* If the next token is `=', then process a default argument. */ if (cp_lexer_next_token_is (parser->lexer, CPP_EQ)) { tree type = decl_specifiers.type; token = cp_lexer_peek_token (parser->lexer); + /* Used for diagnostics with an xobj parameter. */ + eq_token = token; if (declarator) declarator->init_loc = token->location; /* If we are defining a class, then the tokens that make up the @@ -25721,6 +25837,25 @@ cp_parser_parameter_declaration (cp_parser *parser, if (default_argument) STRIP_ANY_LOCATION_WRAPPER (default_argument); + if (decl_spec_seq_has_spec_p (&decl_specifiers, ds_this)) + { + if (default_argument) + { + /* If there is a default_argument, eq_token should always be set. */ + gcc_assert (eq_token); + location_t param_with_init_loc + = make_location (eq_token->location, + decl_spec_token_start->location, + input_location); + error_at (param_with_init_loc, + "an explicit object parameter " + "may not have a default argument"); + } + /* Xobj parameters can not have default arguments, thus + we can reuse the default argument field to flag the param as such. */ + default_argument = this_identifier; + } + /* Generate a location for the parameter, ranging from the start of the initial token to the end of the final token (using input_location for the latter, set up by cp_lexer_set_source_position_from_token when @@ -34091,6 +34226,8 @@ set_and_check_decl_spec_loc (cp_decl_specifier_seq *decl_specs, } else { + /* These correspond to cp-tree.h:cp_decl_spec, + changes here should also be reflected there. */ static const char *const decl_spec_names[] = { "signed", "unsigned", @@ -34108,7 +34245,8 @@ set_and_check_decl_spec_loc (cp_decl_specifier_seq *decl_specs, "constexpr", "__complex", "constinit", - "consteval" + "consteval", + "this" }; gcc_rich_location richloc (location); richloc.add_fixit_remove (); @@ -35176,7 +35314,8 @@ static void cp_parser_check_access_in_redeclaration (tree decl, location_t location) { if (!decl - || (!CLASS_TYPE_P (TREE_TYPE (decl)) + || (!(CLASS_TYPE_P (TREE_TYPE (decl)) + && !CLASSTYPE_TEMPLATE_SPECIALIZATION (TREE_TYPE (decl))) && TREE_CODE (TREE_TYPE (decl)) != ENUMERAL_TYPE)) return; @@ -50841,7 +50980,7 @@ cp_parser_pragma (cp_parser *parser, enum pragma_context context, bool *if_p) case PRAGMA_UNROLL: case PRAGMA_NOVECTOR: { - bool ivdep; + bool ivdep = false; tree unroll = NULL_TREE; bool novector = false; const char *pragma_str; diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc index 7237bd3..b611723 100644 --- a/gcc/cp/pt.cc +++ b/gcc/cp/pt.cc @@ -978,8 +978,7 @@ maybe_new_partial_specialization (tree& type) tree d = create_implicit_typedef (DECL_NAME (tmpl), t); DECL_CONTEXT (d) = TYPE_CONTEXT (t); DECL_SOURCE_LOCATION (d) = input_location; - TREE_PRIVATE (d) = (current_access_specifier == access_private_node); - TREE_PROTECTED (d) = (current_access_specifier == access_protected_node); + TREE_PUBLIC (d) = TREE_PUBLIC (DECL_TEMPLATE_RESULT (tmpl)); set_instantiating_module (d); DECL_MODULE_EXPORT_P (d) = DECL_MODULE_EXPORT_P (tmpl); @@ -1446,9 +1445,9 @@ is_specialization_of_friend (tree decl, tree friend_decl) `this' parameter. */ friend_args_type = TYPE_ARG_TYPES (friend_type); decl_args_type = TYPE_ARG_TYPES (decl_type); - if (DECL_NONSTATIC_MEMBER_FUNCTION_P (friend_decl)) + if (DECL_IOBJ_MEMBER_FUNCTION_P (friend_decl)) friend_args_type = TREE_CHAIN (friend_args_type); - if (DECL_NONSTATIC_MEMBER_FUNCTION_P (decl)) + if (DECL_IOBJ_MEMBER_FUNCTION_P (decl)) decl_args_type = TREE_CHAIN (decl_args_type); return compparms (decl_args_type, friend_args_type); @@ -2236,7 +2235,7 @@ determine_specialization (tree template_id, that the const qualification is the same. Since get_bindings does not try to merge the "this" parameter, we must do the comparison explicitly. */ - if (DECL_NONSTATIC_MEMBER_FUNCTION_P (fn)) + if (DECL_IOBJ_MEMBER_FUNCTION_P (fn)) { if (!same_type_p (TREE_VALUE (fn_arg_types), TREE_VALUE (decl_arg_types))) @@ -2359,14 +2358,14 @@ determine_specialization (tree template_id, /* Adjust the type of DECL in case FN is a static member. */ decl_arg_types = TYPE_ARG_TYPES (TREE_TYPE (decl)); if (DECL_STATIC_FUNCTION_P (fn) - && DECL_NONSTATIC_MEMBER_FUNCTION_P (decl)) + && DECL_IOBJ_MEMBER_FUNCTION_P (decl)) decl_arg_types = TREE_CHAIN (decl_arg_types); if (!compparms (TYPE_ARG_TYPES (TREE_TYPE (fn)), decl_arg_types)) continue; - if (DECL_NONSTATIC_MEMBER_FUNCTION_P (fn) + if (DECL_IOBJ_MEMBER_FUNCTION_P (fn) && (type_memfn_rqual (TREE_TYPE (decl)) != type_memfn_rqual (TREE_TYPE (fn)))) continue; @@ -2552,7 +2551,7 @@ copy_default_args_to_explicit_spec (tree decl) old_type = TREE_TYPE (decl); spec_types = TYPE_ARG_TYPES (old_type); - if (DECL_NONSTATIC_MEMBER_FUNCTION_P (decl)) + if (DECL_IOBJ_MEMBER_FUNCTION_P (decl)) { /* Remove the this pointer, but remember the object's type for CV quals. */ @@ -3137,7 +3136,7 @@ check_explicit_specialization (tree declarator, make DECL a static member function as well. */ if (DECL_FUNCTION_TEMPLATE_P (tmpl) && DECL_STATIC_FUNCTION_P (tmpl) - && DECL_NONSTATIC_MEMBER_FUNCTION_P (decl)) + && DECL_IOBJ_MEMBER_FUNCTION_P (decl)) revert_static_member_fn (decl); /* If this is a specialization of a member template of a @@ -11814,7 +11813,7 @@ tsubst_contract_attribute (tree decl, tree t, tree args, /* For member functions, make this available for semantic analysis. */ tree save_ccp = current_class_ptr; tree save_ccr = current_class_ref; - if (DECL_NONSTATIC_MEMBER_FUNCTION_P (decl)) + if (DECL_IOBJ_MEMBER_FUNCTION_P (decl)) { tree arg_types = TYPE_ARG_TYPES (TREE_TYPE (decl)); tree this_type = TREE_TYPE (TREE_VALUE (arg_types)); @@ -14490,9 +14489,9 @@ tsubst_function_decl (tree t, tree args, tsubst_flags_t complain, tree ctx = closure ? closure : DECL_CONTEXT (t); bool member = ctx && TYPE_P (ctx); - /* If this is a static lambda, remove the 'this' pointer added in + /* If this is a static or xobj lambda, remove the 'this' pointer added in tsubst_lambda_expr now that we know the closure type. */ - if (lambda_fntype && DECL_STATIC_FUNCTION_P (t)) + if (lambda_fntype && !DECL_IOBJ_MEMBER_FUNCTION_P (t)) lambda_fntype = static_fn_type (lambda_fntype); if (member && !closure) @@ -14567,12 +14566,12 @@ tsubst_function_decl (tree t, tree args, tsubst_flags_t complain, DECL_NAME (r) = make_conv_op_name (TREE_TYPE (type)); tree parms = DECL_ARGUMENTS (t); - if (closure && !DECL_STATIC_FUNCTION_P (t)) + if (closure && DECL_IOBJ_MEMBER_FUNCTION_P (t)) parms = DECL_CHAIN (parms); parms = tsubst (parms, args, complain, t); for (tree parm = parms; parm; parm = DECL_CHAIN (parm)) DECL_CONTEXT (parm) = r; - if (closure && !DECL_STATIC_FUNCTION_P (t)) + if (closure && DECL_IOBJ_MEMBER_FUNCTION_P (t)) { tree tparm = build_this_parm (r, closure, type_memfn_quals (type)); DECL_NAME (tparm) = closure_identifier; @@ -14608,6 +14607,66 @@ tsubst_function_decl (tree t, tree args, tsubst_flags_t complain, && !grok_op_properties (r, /*complain=*/false)) return error_mark_node; + /* If we are looking at an xobj lambda, we might need to check the type of + its xobj parameter. */ + if (LAMBDA_FUNCTION_P (r) && DECL_XOBJ_MEMBER_FUNCTION_P (r)) + { + tree closure_obj = DECL_CONTEXT (r); + tree lambda_expr = CLASSTYPE_LAMBDA_EXPR (closure_obj); + tree obj_param = TREE_TYPE (DECL_ARGUMENTS (r)); + + if (!(LAMBDA_EXPR_DEFAULT_CAPTURE_MODE (lambda_expr) != CPLD_NONE + || LAMBDA_EXPR_CAPTURE_LIST (lambda_expr))) + /* If a lambda has an empty capture clause, an xobj parameter of + unrelated type is not an error. */; + else if (dependent_type_p (obj_param)) + /* If we are coming from tsubst_lambda_expr we might not have + substituted into our xobj parameter yet. We can't error out until + we know what the type really is so do nothing... + ...but if we are instantiating the call op for real and we don't + have a real type then something has gone incredibly wrong. */ + gcc_assert (lambda_fntype); + else + { + /* We have a lambda with captures, and know the type of the xobj + parameter, time to check it. */ + tree obj_param_type = TYPE_MAIN_VARIANT (non_reference (obj_param)); + if (!same_or_base_type_p (closure_obj, obj_param_type)) + { + /* This error does not emit when the lambda's call operator + template is instantiated by taking its address, such as in + the following case: + + auto f = [x = 0](this auto&&){}; + int (*fp)(int&) = &decltype(f)::operator(); + + It only emits when explicitly calling the call operator with + an explicit template parameter: + + template<typename T> + struct S : T { + using T::operator(); + operator int() const {return {};} + }; + + auto s = S{[x = 0](this auto&&) {}}; + s.operator()<int>(); + + This is due to resolve_address_of_overloaded_function being + deficient at reporting candidates when overload resolution + fails. + + This diagnostic will be active in the first case if/when + resolve_address_of_overloaded_function is fixed to properly + emit candidates upon failure to resolve to an overload. */ + if (complain & tf_error) + error ("a lambda with captures may not have an explicit " + "object parameter of an unrelated type"); + return error_mark_node; + } + } + } + /* Associate the constraints directly with the instantiation. We don't substitute through the constraints; that's only done when they are checked. */ @@ -19595,7 +19654,11 @@ tsubst_lambda_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl) which would be skipped if cp_unevaluated_operand. */ cp_evaluated ev; - /* Fix the type of 'this'. */ + /* Fix the type of 'this'. + For static and xobj member functions we use this to transport the + lambda's closure type. It appears that in the regular case the + object parameter is still pulled off, and then re-added again anyway. + So perhaps we could do something better here? */ fntype = build_memfn_type (fntype, type, type_memfn_quals (fntype), type_memfn_rqual (fntype)); @@ -22130,7 +22193,7 @@ check_non_deducible_conversions (tree parms, const tree *args, unsigned nargs, { /* Non-constructor methods need to leave a conversion for 'this', which isn't included in nargs here. */ - unsigned offset = (DECL_NONSTATIC_MEMBER_FUNCTION_P (fn) + unsigned offset = (DECL_IOBJ_MEMBER_FUNCTION_P (fn) && !DECL_CONSTRUCTOR_P (fn)); for (unsigned ia = 0; @@ -25357,16 +25420,16 @@ more_specialized_fn (tree pat1, tree pat2, int len) I think think the old G++ behavior of just skipping the object parameter when comparing to a static member function was better, so let's stick with that for now. This is CWG2834. --jason 2023-12 */ - if (DECL_NONSTATIC_MEMBER_FUNCTION_P (decl1)) /* FIXME or explicit */ + if (DECL_OBJECT_MEMBER_FUNCTION_P (decl1)) { len--; /* LEN is the number of significant arguments for DECL1 */ args1 = TREE_CHAIN (args1); } - else if (DECL_NONSTATIC_MEMBER_FUNCTION_P (decl2)) /* FIXME or explicit */ + else if (DECL_OBJECT_MEMBER_FUNCTION_P (decl2)) args2 = TREE_CHAIN (args2); } - else if (DECL_NONSTATIC_MEMBER_FUNCTION_P (decl1) /* FIXME implicit only */ - && DECL_NONSTATIC_MEMBER_FUNCTION_P (decl2)) + else if (DECL_IOBJ_MEMBER_FUNCTION_P (decl1) + && DECL_IOBJ_MEMBER_FUNCTION_P (decl2)) { /* Note DR2445 also (IMO wrongly) removed the "only one" above, which would break e.g. cpp1y/lambda-generic-variadic5.C. */ @@ -25374,12 +25437,12 @@ more_specialized_fn (tree pat1, tree pat2, int len) args1 = TREE_CHAIN (args1); args2 = TREE_CHAIN (args2); } - else if (DECL_NONSTATIC_MEMBER_FUNCTION_P (decl1) /* FIXME implicit only */ - || DECL_NONSTATIC_MEMBER_FUNCTION_P (decl2)) + else if (DECL_IOBJ_MEMBER_FUNCTION_P (decl1) + || DECL_IOBJ_MEMBER_FUNCTION_P (decl2)) { /* The other is a non-member or explicit object member function; rewrite the implicit object parameter to a reference. */ - tree ns = DECL_NONSTATIC_MEMBER_FUNCTION_P (decl2) ? decl2 : decl1; + tree ns = DECL_IOBJ_MEMBER_FUNCTION_P (decl2) ? decl2 : decl1; tree &nsargs = ns == decl2 ? args2 : args1; tree obtype = TREE_TYPE (TREE_VALUE (nsargs)); @@ -26712,7 +26775,7 @@ maybe_instantiate_noexcept (tree fn, tsubst_flags_t complain) push_deferring_access_checks (dk_no_deferred); input_location = DECL_SOURCE_LOCATION (fn); - if (DECL_NONSTATIC_MEMBER_FUNCTION_P (fn) + if (DECL_IOBJ_MEMBER_FUNCTION_P (fn) && !DECL_LOCAL_DECL_P (fn)) { /* If needed, set current_class_ptr for the benefit of @@ -26775,7 +26838,7 @@ register_parameter_specializations (tree pattern, tree inst) { tree tmpl_parm = DECL_ARGUMENTS (pattern); tree spec_parm = DECL_ARGUMENTS (inst); - if (DECL_NONSTATIC_MEMBER_FUNCTION_P (inst)) + if (DECL_IOBJ_MEMBER_FUNCTION_P (inst)) { register_local_specialization (spec_parm, tmpl_parm); spec_parm = skip_artificial_parms_for (inst, spec_parm); @@ -28118,7 +28181,7 @@ value_dependent_expression_p (tree expression) cause the call to be considered value-dependent. We also look through it in potential_constant_expression. */ if (i == 0 && fn && DECL_DECLARED_CONSTEXPR_P (fn) - && DECL_NONSTATIC_MEMBER_FUNCTION_P (fn) + && DECL_IOBJ_MEMBER_FUNCTION_P (fn) && TREE_CODE (op) == ADDR_EXPR) op = TREE_OPERAND (op, 0); if (value_dependent_expression_p (op)) diff --git a/gcc/cp/search.cc b/gcc/cp/search.cc index 9432200..2b4ed5d 100644 --- a/gcc/cp/search.cc +++ b/gcc/cp/search.cc @@ -1008,7 +1008,7 @@ shared_member_p (tree t) /* Conservatively assume a dependent using-declaration might resolve to a non-static member. */ return false; - if (DECL_NONSTATIC_MEMBER_FUNCTION_P (decl)) + if (DECL_OBJECT_MEMBER_FUNCTION_P (decl)) return false; } return true; @@ -1264,7 +1264,7 @@ lookup_member (tree xbasetype, tree name, int protect, bool want_type, decl = strip_using_decl (decl); /* A dependent USING_DECL will be checked after tsubsting. */ if (TREE_CODE (decl) != USING_DECL - && !DECL_NONSTATIC_MEMBER_FUNCTION_P (decl) + && !DECL_IOBJ_MEMBER_FUNCTION_P (decl) && !perform_or_defer_access_check (basetype_path, decl, decl, complain, afi)) return error_mark_node; @@ -1737,7 +1737,7 @@ field_access_p (tree component_ref, tree field_decl, tree field_type) return false; tree ptr = STRIP_NOPS (TREE_OPERAND (indirect_ref, 0)); - if (!is_this_parameter (ptr)) + if (!is_object_parameter (ptr)) return false; /* Must access the correct field. */ @@ -1817,6 +1817,17 @@ reference_accessor_p (tree init_expr, tree field_decl, tree field_type, return true; } +/* Return the class of the `this' or explicit object parameter of FN. */ + +static tree +class_of_object_parm (const_tree fn) +{ + tree fntype = TREE_TYPE (fn); + if (DECL_XOBJ_MEMBER_FUNCTION_P (fn)) + return non_reference (TREE_VALUE (TYPE_ARG_TYPES (fntype))); + return class_of_this_parm (fntype); +} + /* Return true if FN is an accessor method for FIELD_DECL. i.e. a method of the form { return FIELD; }, with no conversions. @@ -1834,15 +1845,14 @@ field_accessor_p (tree fn, tree field_decl, bool const_p) if (TREE_CODE (field_decl) != FIELD_DECL) return false; - tree fntype = TREE_TYPE (fn); - if (TREE_CODE (fntype) != METHOD_TYPE) + if (!DECL_OBJECT_MEMBER_FUNCTION_P (fn)) return false; /* If the field is accessed via a const "this" argument, verify that the "this" parameter is const. */ if (const_p) { - tree this_class = class_of_this_parm (fntype); + tree this_class = class_of_object_parm (fn); if (!TYPE_READONLY (this_class)) return false; } @@ -2223,10 +2233,13 @@ look_for_overrides_here (tree type, tree fndecl) /* Not a virtual. */; else if (DECL_CONTEXT (fn) != type) /* Introduced with a using declaration. */; - else if (DECL_STATIC_FUNCTION_P (fndecl)) + else if (DECL_STATIC_FUNCTION_P (fndecl) + || DECL_XOBJ_MEMBER_FUNCTION_P (fndecl)) { tree btypes = TYPE_ARG_TYPES (TREE_TYPE (fn)); tree dtypes = TYPE_ARG_TYPES (TREE_TYPE (fndecl)); + dtypes = DECL_XOBJ_MEMBER_FUNCTION_P (fndecl) ? TREE_CHAIN (dtypes) + : dtypes; if (compparms (TREE_CHAIN (btypes), dtypes)) return fn; } @@ -2254,6 +2267,15 @@ look_for_overrides_r (tree type, tree fndecl) error ("%q+#D cannot be declared", fndecl); error (" since %q+#D declared in base class", fn); } + else if (DECL_XOBJ_MEMBER_FUNCTION_P (fndecl)) + { + auto_diagnostic_group d; + error_at (DECL_SOURCE_LOCATION (fndecl), + "explicit object member function " + "overrides virtual function"); + inform (DECL_SOURCE_LOCATION (fn), + "virtual function declared here"); + } else { /* It's definitely virtual, even if not explicitly set. */ diff --git a/gcc/cp/semantics.cc b/gcc/cp/semantics.cc index 2162c57..3299e27 100644 --- a/gcc/cp/semantics.cc +++ b/gcc/cp/semantics.cc @@ -3169,7 +3169,30 @@ finish_this_expr (void) return rvalue (result); tree fn = current_nonlambda_function (); - if (fn && DECL_STATIC_FUNCTION_P (fn)) + if (fn && DECL_XOBJ_MEMBER_FUNCTION_P (fn)) + { + auto_diagnostic_group d; + error ("%<this%> is unavailable for explicit object member " + "functions"); + tree xobj_parm = DECL_ARGUMENTS (fn); + gcc_assert (xobj_parm); + tree parm_name = DECL_NAME (xobj_parm); + + static tree remembered_fn = NULL_TREE; + /* Only output this diagnostic once per function. */ + if (remembered_fn == fn) + /* Early escape. */; + else if (parm_name) + inform (DECL_SOURCE_LOCATION (xobj_parm), + "use explicit object parameter %qs instead", + IDENTIFIER_POINTER (parm_name)); + else + inform (DECL_SOURCE_LOCATION (xobj_parm), + "name the explicit object parameter"); + + remembered_fn = fn; + } + else if (fn && DECL_STATIC_FUNCTION_P (fn)) error ("%<this%> is unavailable for static member functions"); else if (fn && processing_contract_condition && DECL_CONSTRUCTOR_P (fn)) error ("invalid use of %<this%> before it is valid"); @@ -6727,7 +6750,7 @@ finish_omp_declare_simd_methods (tree t) for (tree x = TYPE_FIELDS (t); x; x = DECL_CHAIN (x)) { if (TREE_CODE (x) == USING_DECL - || !DECL_NONSTATIC_MEMBER_FUNCTION_P (x)) + || !DECL_IOBJ_MEMBER_FUNCTION_P (x)) continue; tree ods = lookup_attribute ("omp declare simd", DECL_ATTRIBUTES (x)); if (!ods || !TREE_VALUE (ods)) @@ -11910,9 +11933,13 @@ finish_decltype_type (tree expr, bool id_expression_or_member_access_p, if (WILDCARD_TYPE_P (non_reference (obtype))) /* We don't know what the eventual obtype quals will be. */ goto dependent; - int quals = cp_type_quals (type); - if (INDIRECT_TYPE_P (obtype)) - quals |= cp_type_quals (TREE_TYPE (obtype)); + auto direct_type = [](tree t){ + if (INDIRECT_TYPE_P (t)) + return TREE_TYPE (t); + return t; + }; + int const quals = cp_type_quals (type) + | cp_type_quals (direct_type (obtype)); type = cp_build_qualified_type (type, quals); type = build_reference_type (type); } @@ -12805,6 +12832,20 @@ is_this_parameter (tree t) return true; } +/* As above, or a C++23 explicit object parameter. */ + +bool +is_object_parameter (tree t) +{ + if (is_this_parameter (t)) + return true; + if (TREE_CODE (t) != PARM_DECL) + return false; + tree ctx = DECL_CONTEXT (t); + return (ctx && DECL_XOBJ_MEMBER_FUNCTION_P (ctx) + && t == DECL_ARGUMENTS (ctx)); +} + /* Insert the deduced return type for an auto function. */ void diff --git a/gcc/cp/tree.cc b/gcc/cp/tree.cc index 5dc495e..77f57e0 100644 --- a/gcc/cp/tree.cc +++ b/gcc/cp/tree.cc @@ -298,7 +298,7 @@ lvalue_kind (const_tree ref) case FUNCTION_DECL: /* All functions (except non-static-member functions) are lvalues. */ - return (DECL_NONSTATIC_MEMBER_FUNCTION_P (ref) + return (DECL_IOBJ_MEMBER_FUNCTION_P (ref) ? clk_none : clk_ordinary); case BASELINK: @@ -3677,7 +3677,7 @@ build_min_non_dep_op_overload (enum tree_code op, nargs = call_expr_nargs (non_dep); expected_nargs = cp_tree_code_length (op); - if (TREE_CODE (TREE_TYPE (overload)) == METHOD_TYPE + if (DECL_OBJECT_MEMBER_FUNCTION_P (overload) /* For ARRAY_REF, operator[] is either a non-static member or newly static member, never out of class and for the static member case if user uses single index the operator[] needs to have a single @@ -3695,7 +3695,7 @@ build_min_non_dep_op_overload (enum tree_code op, releasing_vec args; va_start (p, overload); - if (TREE_CODE (TREE_TYPE (overload)) == FUNCTION_TYPE) + if (!DECL_OBJECT_MEMBER_FUNCTION_P (overload)) { fn = overload; if (op == ARRAY_REF) @@ -3706,7 +3706,7 @@ build_min_non_dep_op_overload (enum tree_code op, vec_safe_push (args, arg); } } - else if (TREE_CODE (TREE_TYPE (overload)) == METHOD_TYPE) + else { tree object = va_arg (p, tree); tree binfo = TYPE_BINFO (TREE_TYPE (object)); @@ -3719,8 +3719,6 @@ build_min_non_dep_op_overload (enum tree_code op, vec_safe_push (args, arg); } } - else - gcc_unreachable (); va_end (p); call = build_min_non_dep_call_vec (non_dep, fn, args); @@ -3747,7 +3745,7 @@ build_min_non_dep_op_overload (tree non_dep, tree overload, tree object, unsigned int nargs = call_expr_nargs (non_dep); tree fn = overload; - if (TREE_CODE (TREE_TYPE (overload)) == METHOD_TYPE) + if (DECL_OBJECT_MEMBER_FUNCTION_P (overload)) { tree binfo = TYPE_BINFO (TREE_TYPE (object)); tree method = build_baselink (binfo, binfo, overload, NULL_TREE); diff --git a/gcc/cp/typeck.cc b/gcc/cp/typeck.cc index cfcaf12..a15eda3 100644 --- a/gcc/cp/typeck.cc +++ b/gcc/cp/typeck.cc @@ -2352,7 +2352,7 @@ invalid_nonstatic_memfn_p (location_t loc, tree expr, tsubst_flags_t complain) if (is_overloaded_fn (expr) && !really_overloaded_fn (expr)) expr = get_first_fn (expr); if (TREE_TYPE (expr) - && DECL_NONSTATIC_MEMBER_FUNCTION_P (expr)) + && DECL_IOBJ_MEMBER_FUNCTION_P (expr)) { if (complain & tf_error) { @@ -7129,26 +7129,47 @@ cp_build_addr_expr_1 (tree arg, bool strict_lvalue, tsubst_flags_t complain) tree fn = get_first_fn (TREE_OPERAND (arg, 1)); if (!mark_used (fn, complain) && !(complain & tf_error)) return error_mark_node; - - if (! flag_ms_extensions) + /* Until microsoft headers are known to incorrectly take the address of + unqualified xobj member functions we should not support this + extension. + See comment in class.cc:resolve_address_of_overloaded_function for + the extended reasoning. */ + if (!flag_ms_extensions || DECL_XOBJ_MEMBER_FUNCTION_P (fn)) { + auto_diagnostic_group d; tree name = DECL_NAME (fn); if (!(complain & tf_error)) return error_mark_node; else if (current_class_type && TREE_OPERAND (arg, 0) == current_class_ref) /* An expression like &memfn. */ - permerror (loc, - "ISO C++ forbids taking the address of an unqualified" - " or parenthesized non-static member function to form" - " a pointer to member function. Say %<&%T::%D%>", - base, name); + if (!DECL_XOBJ_MEMBER_FUNCTION_P (fn)) + permerror (loc, + "ISO C++ forbids taking the address of an unqualified" + " or parenthesized non-static member function to form" + " a pointer to member function. Say %<&%T::%D%>", + base, name); + else + error_at (loc, + "ISO C++ forbids taking the address of an unqualified" + " or parenthesized non-static member function to form" + " a pointer to explicit object member function"); else - permerror (loc, - "ISO C++ forbids taking the address of a bound member" - " function to form a pointer to member function." - " Say %<&%T::%D%>", - base, name); + if (!DECL_XOBJ_MEMBER_FUNCTION_P (fn)) + permerror (loc, + "ISO C++ forbids taking the address of a bound member" + " function to form a pointer to member function." + " Say %<&%T::%D%>", + base, name); + else + error_at (loc, + "ISO C++ forbids taking the address of a bound member" + " function to form a pointer to explicit object member" + " function"); + if (DECL_XOBJ_MEMBER_FUNCTION_P (fn)) + inform (loc, + "a pointer to explicit object member function can only be " + "formed with %<&%T::%D%>", base, name); } arg = build_offset_ref (base, fn, /*address_p=*/true, complain); } @@ -7265,6 +7286,15 @@ cp_build_addr_expr_1 (tree arg, bool strict_lvalue, tsubst_flags_t complain) && !mark_used (t, complain) && !(complain & tf_error)) return error_mark_node; + /* Pull out the function_decl for a single xobj member function, and + let the rest of this function handle it. This is similar to how + static member functions are handled in the BASELINK case above. */ + if (DECL_XOBJ_MEMBER_FUNCTION_P (t)) + { + arg = t; + break; + } + type = build_ptrmem_type (context_for_name_lookup (t), TREE_TYPE (t)); t = make_ptrmem_cst (type, t); diff --git a/gcc/diagnostic.cc b/gcc/diagnostic.cc index cc2b184..f5411b1 100644 --- a/gcc/diagnostic.cc +++ b/gcc/diagnostic.cc @@ -1603,7 +1603,7 @@ diagnostic_context::report_diagnostic (diagnostic_info *diagnostic) pp_format (this->printer, &diagnostic->message, m_urlifier); m_output_format->on_begin_diagnostic (*diagnostic); - pp_output_formatted_text (this->printer); + pp_output_formatted_text (this->printer, m_urlifier); if (m_show_cwe) print_any_cwe (*diagnostic); if (m_show_rules) diff --git a/gcc/doc/avr-mmcu.texi b/gcc/doc/avr-mmcu.texi index ddd429e..1a2c688 100644 --- a/gcc/doc/avr-mmcu.texi +++ b/gcc/doc/avr-mmcu.texi @@ -12,71 +12,71 @@ @table @code -@item avr2 +@item @anchor{avr2}avr2 ``Classic'' devices with up to 8@tie{}KiB of program memory. @*@var{mcu}@tie{}= @code{attiny22}, @code{attiny26}, @code{at90s2313}, @code{at90s2323}, @code{at90s2333}, @code{at90s2343}, @code{at90s4414}, @code{at90s4433}, @code{at90s4434}, @code{at90c8534}, @code{at90s8515}, @code{at90s8535}. -@item avr25 +@item @anchor{avr25}avr25 ``Classic'' devices with up to 8@tie{}KiB of program memory and with the @code{MOVW} instruction. @*@var{mcu}@tie{}= @code{attiny13}, @code{attiny13a}, @code{attiny24}, @code{attiny24a}, @code{attiny25}, @code{attiny261}, @code{attiny261a}, @code{attiny2313}, @code{attiny2313a}, @code{attiny43u}, @code{attiny44}, @code{attiny44a}, @code{attiny45}, @code{attiny48}, @code{attiny441}, @code{attiny461}, @code{attiny461a}, @code{attiny4313}, @code{attiny84}, @code{attiny84a}, @code{attiny85}, @code{attiny87}, @code{attiny88}, @code{attiny828}, @code{attiny841}, @code{attiny861}, @code{attiny861a}, @code{ata5272}, @code{ata6616c}, @code{at86rf401}. -@item avr3 +@item @anchor{avr3}avr3 ``Classic'' devices with 16@tie{}KiB up to 64@tie{}KiB of program memory. @*@var{mcu}@tie{}= @code{at76c711}, @code{at43usb355}. -@item avr31 +@item @anchor{avr31}avr31 ``Classic'' devices with 128@tie{}KiB of program memory. @*@var{mcu}@tie{}= @code{atmega103}, @code{at43usb320}. -@item avr35 +@item @anchor{avr35}avr35 ``Classic'' devices with 16@tie{}KiB up to 64@tie{}KiB of program memory and with the @code{MOVW} instruction. @*@var{mcu}@tie{}= @code{attiny167}, @code{attiny1634}, @code{atmega8u2}, @code{atmega16u2}, @code{atmega32u2}, @code{ata5505}, @code{ata6617c}, @code{ata664251}, @code{at90usb82}, @code{at90usb162}. -@item avr4 +@item @anchor{avr4}avr4 ``Enhanced'' devices with up to 8@tie{}KiB of program memory. @*@var{mcu}@tie{}= @code{atmega48}, @code{atmega48a}, @code{atmega48p}, @code{atmega48pa}, @code{atmega48pb}, @code{atmega8}, @code{atmega8a}, @code{atmega8hva}, @code{atmega88}, @code{atmega88a}, @code{atmega88p}, @code{atmega88pa}, @code{atmega88pb}, @code{atmega8515}, @code{atmega8535}, @code{ata6285}, @code{ata6286}, @code{ata6289}, @code{ata6612c}, @code{at90pwm1}, @code{at90pwm2}, @code{at90pwm2b}, @code{at90pwm3}, @code{at90pwm3b}, @code{at90pwm81}. -@item avr5 +@item @anchor{avr5}avr5 ``Enhanced'' devices with 16@tie{}KiB up to 64@tie{}KiB of program memory. @*@var{mcu}@tie{}= @code{atmega16}, @code{atmega16a}, @code{atmega16hva}, @code{atmega16hva2}, @code{atmega16hvb}, @code{atmega16hvbrevb}, @code{atmega16m1}, @code{atmega16u4}, @code{atmega161}, @code{atmega162}, @code{atmega163}, @code{atmega164a}, @code{atmega164p}, @code{atmega164pa}, @code{atmega165}, @code{atmega165a}, @code{atmega165p}, @code{atmega165pa}, @code{atmega168}, @code{atmega168a}, @code{atmega168p}, @code{atmega168pa}, @code{atmega168pb}, @code{atmega169}, @code{atmega169a}, @code{atmega169p}, @code{atmega169pa}, @code{atmega32}, @code{atmega32a}, @code{atmega32c1}, @code{atmega32hvb}, @code{atmega32hvbrevb}, @code{atmega32m1}, @code{atmega32u4}, @code{atmega32u6}, @code{atmega323}, @code{atmega324a}, @code{atmega324p}, @code{atmega324pa}, @code{atmega324pb}, @code{atmega325}, @code{atmega325a}, @code{atmega325p}, @code{atmega325pa}, @code{atmega328}, @code{atmega328p}, @code{atmega328pb}, @code{atmega329}, @code{atmega329a}, @code{atmega329p}, @code{atmega329pa}, @code{atmega3250}, @code{atmega3250a}, @code{atmega3250p}, @code{atmega3250pa}, @code{atmega3290}, @code{atmega3290a}, @code{atmega3290p}, @code{atmega3290pa}, @code{atmega406}, @code{atmega64}, @code{atmega64a}, @code{atmega64c1}, @code{atmega64hve}, @code{atmega64hve2}, @code{atmega64m1}, @code{atmega64rfr2}, @code{atmega640}, @code{atmega644}, @code{atmega644a}, @code{atmega644p}, @code{atmega644pa}, @code{atmega644rfr2}, @code{atmega645}, @code{atmega645a}, @code{atmega645p}, @code{atmega649}, @code{atmega649a}, @code{atmega649p}, @code{atmega6450}, @code{atmega6450a}, @code{atmega6450p}, @code{atmega6490}, @code{atmega6490a}, @code{atmega6490p}, @code{ata5795}, @code{ata5790}, @code{ata5790n}, @code{ata5791}, @code{ata6613c}, @code{ata6614q}, @code{ata5782}, @code{ata5831}, @code{ata8210}, @code{ata8510}, @code{ata5702m322}, @code{at90pwm161}, @code{at90pwm216}, @code{at90pwm316}, @code{at90can32}, @code{at90can64}, @code{at90scr100}, @code{at90usb646}, @code{at90usb647}, @code{at94k}, @code{m3000}. -@item avr51 +@item @anchor{avr51}avr51 ``Enhanced'' devices with 128@tie{}KiB of program memory. @*@var{mcu}@tie{}= @code{atmega128}, @code{atmega128a}, @code{atmega128rfa1}, @code{atmega128rfr2}, @code{atmega1280}, @code{atmega1281}, @code{atmega1284}, @code{atmega1284p}, @code{atmega1284rfr2}, @code{at90can128}, @code{at90usb1286}, @code{at90usb1287}. -@item avr6 +@item @anchor{avr6}avr6 ``Enhanced'' devices with 3-byte PC, i.e.@: with more than 128@tie{}KiB of program memory. @*@var{mcu}@tie{}= @code{atmega256rfr2}, @code{atmega2560}, @code{atmega2561}, @code{atmega2564rfr2}. -@item avrxmega2 +@item @anchor{avrxmega2}avrxmega2 ``XMEGA'' devices with more than 8@tie{}KiB and up to 64@tie{}KiB of program memory. @*@var{mcu}@tie{}= @code{atxmega8e5}, @code{atxmega16a4}, @code{atxmega16a4u}, @code{atxmega16c4}, @code{atxmega16d4}, @code{atxmega16e5}, @code{atxmega32a4}, @code{atxmega32a4u}, @code{atxmega32c3}, @code{atxmega32c4}, @code{atxmega32d3}, @code{atxmega32d4}, @code{atxmega32e5}, @code{avr64da28}, @code{avr64da32}, @code{avr64da48}, @code{avr64da64}, @code{avr64db28}, @code{avr64db32}, @code{avr64db48}, @code{avr64db64}, @code{avr64dd14}, @code{avr64dd20}, @code{avr64dd28}, @code{avr64dd32}, @code{avr64ea28}, @code{avr64ea32}, @code{avr64ea48}. -@item avrxmega3 +@item @anchor{avrxmega3}avrxmega3 ``XMEGA'' devices with up to 64@tie{}KiB of combined program memory and RAM, and with program memory visible in the RAM address space. -@*@var{mcu}@tie{}= @code{attiny202}, @code{attiny204}, @code{attiny212}, @code{attiny214}, @code{attiny402}, @code{attiny404}, @code{attiny406}, @code{attiny412}, @code{attiny414}, @code{attiny416}, @code{attiny417}, @code{attiny424}, @code{attiny426}, @code{attiny427}, @code{attiny804}, @code{attiny806}, @code{attiny807}, @code{attiny814}, @code{attiny816}, @code{attiny817}, @code{attiny824}, @code{attiny826}, @code{attiny827}, @code{attiny1604}, @code{attiny1606}, @code{attiny1607}, @code{attiny1614}, @code{attiny1616}, @code{attiny1617}, @code{attiny1624}, @code{attiny1626}, @code{attiny1627}, @code{attiny3214}, @code{attiny3216}, @code{attiny3217}, @code{attiny3224}, @code{attiny3226}, @code{attiny3227}, @code{atmega808}, @code{atmega809}, @code{atmega1608}, @code{atmega1609}, @code{atmega3208}, @code{atmega3209}, @code{atmega4808}, @code{atmega4809}, @code{avr16dd14}, @code{avr16dd20}, @code{avr16dd28}, @code{avr16dd32}, @code{avr32da28}, @code{avr32da32}, @code{avr32da48}, @code{avr32db28}, @code{avr32db32}, @code{avr32db48}, @code{avr32dd14}, @code{avr32dd20}, @code{avr32dd28}, @code{avr32dd32}. +@*@var{mcu}@tie{}= @code{attiny202}, @code{attiny204}, @code{attiny212}, @code{attiny214}, @code{attiny402}, @code{attiny404}, @code{attiny406}, @code{attiny412}, @code{attiny414}, @code{attiny416}, @code{attiny417}, @code{attiny424}, @code{attiny426}, @code{attiny427}, @code{attiny804}, @code{attiny806}, @code{attiny807}, @code{attiny814}, @code{attiny816}, @code{attiny817}, @code{attiny824}, @code{attiny826}, @code{attiny827}, @code{attiny1604}, @code{attiny1606}, @code{attiny1607}, @code{attiny1614}, @code{attiny1616}, @code{attiny1617}, @code{attiny1624}, @code{attiny1626}, @code{attiny1627}, @code{attiny3214}, @code{attiny3216}, @code{attiny3217}, @code{attiny3224}, @code{attiny3226}, @code{attiny3227}, @code{atmega808}, @code{atmega809}, @code{atmega1608}, @code{atmega1609}, @code{atmega3208}, @code{atmega3209}, @code{atmega4808}, @code{atmega4809}, @code{avr16dd14}, @code{avr16dd20}, @code{avr16dd28}, @code{avr16dd32}, @code{avr16ea28}, @code{avr16ea32}, @code{avr16ea48}, @code{avr16eb14}, @code{avr16eb20}, @code{avr16eb28}, @code{avr16eb32}, @code{avr32da28}, @code{avr32da32}, @code{avr32da48}, @code{avr32db28}, @code{avr32db32}, @code{avr32db48}, @code{avr32dd14}, @code{avr32dd20}, @code{avr32dd28}, @code{avr32dd32}, @code{avr32ea28}, @code{avr32ea32}, @code{avr32ea48}. -@item avrxmega4 +@item @anchor{avrxmega4}avrxmega4 ``XMEGA'' devices with more than 64@tie{}KiB and up to 128@tie{}KiB of program memory. @*@var{mcu}@tie{}= @code{atxmega64a3}, @code{atxmega64a3u}, @code{atxmega64a4u}, @code{atxmega64b1}, @code{atxmega64b3}, @code{atxmega64c3}, @code{atxmega64d3}, @code{atxmega64d4}, @code{avr128da28}, @code{avr128da32}, @code{avr128da48}, @code{avr128da64}, @code{avr128db28}, @code{avr128db32}, @code{avr128db48}, @code{avr128db64}. -@item avrxmega5 +@item @anchor{avrxmega5}avrxmega5 ``XMEGA'' devices with more than 64@tie{}KiB and up to 128@tie{}KiB of program memory and more than 64@tie{}KiB of RAM. @*@var{mcu}@tie{}= @code{atxmega64a1}, @code{atxmega64a1u}. -@item avrxmega6 +@item @anchor{avrxmega6}avrxmega6 ``XMEGA'' devices with more than 128@tie{}KiB of program memory. @*@var{mcu}@tie{}= @code{atxmega128a3}, @code{atxmega128a3u}, @code{atxmega128b1}, @code{atxmega128b3}, @code{atxmega128c3}, @code{atxmega128d3}, @code{atxmega128d4}, @code{atxmega192a3}, @code{atxmega192a3u}, @code{atxmega192c3}, @code{atxmega192d3}, @code{atxmega256a3}, @code{atxmega256a3b}, @code{atxmega256a3bu}, @code{atxmega256a3u}, @code{atxmega256c3}, @code{atxmega256d3}, @code{atxmega384c3}, @code{atxmega384d3}. -@item avrxmega7 +@item @anchor{avrxmega7}avrxmega7 ``XMEGA'' devices with more than 128@tie{}KiB of program memory and more than 64@tie{}KiB of RAM. @*@var{mcu}@tie{}= @code{atxmega128a1}, @code{atxmega128a1u}, @code{atxmega128a4u}. -@item avrtiny -``TINY'' Tiny core devices with 512@tie{}B up to 4@tie{}KiB of program memory. +@item @anchor{avrtiny}avrtiny +``Reduced Tiny'' Tiny core devices with only 16 general purpose registers and 512@tie{}B up to 4@tie{}KiB of program memory. @*@var{mcu}@tie{}= @code{attiny4}, @code{attiny5}, @code{attiny9}, @code{attiny10}, @code{attiny102}, @code{attiny104}, @code{attiny20}, @code{attiny40}. -@item avr1 +@item @anchor{avr1}avr1 This ISA is implemented by the minimal AVR core and supported for assembler only. @*@var{mcu}@tie{}= @code{attiny11}, @code{attiny12}, @code{attiny15}, @code{attiny28}, @code{at90s1200}. diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi index 84eef41..b9129d1 100644 --- a/gcc/doc/extend.texi +++ b/gcc/doc/extend.texi @@ -1594,7 +1594,7 @@ from @w{@uref{https://www.nongnu.org/avr-libc/user-manual/,AVR-LibC}} together with attribute @code{progmem}. @noindent -@b{Limitations and caveats} +@b{Limitations and Caveats} @itemize @item @@ -1608,6 +1608,8 @@ supports reading across the 64@tie{}KiB flash segment boundaries is If you use one of the @code{__flash@var{N}} address spaces you must arrange your linker script to locate the @code{.progmem@var{N}.data} sections according to your needs. +For an example, see the +@w{@uref{https://gcc.gnu.org/wiki/avr-gcc#Address_Spaces,avr-gcc wiki}} @item Any data or pointers to the non-generic address spaces must @@ -8288,21 +8290,20 @@ at all. @item io @itemx io (@var{addr}) Variables with the @code{io} attribute are used to address -memory-mapped peripherals in the io address range. +memory-mapped peripherals in the I/O address range. +No memory is allocated. If an address is specified, the variable is assigned that address, and the value is interpreted as an address in the data address space. Example: @smallexample -volatile int porta __attribute__((io (0x22))); +volatile int porta __attribute__((io (__AVR_SFR_OFFSET__ + 0x2))); @end smallexample -The address specified in the address in the data address range. - -Otherwise, the variable it is not assigned an address, but the -compiler will still use in/out instructions where applicable, -assuming some other module assigns an address in the io address range. +Otherwise, the variable is not assigned an address, but the +compiler will still use @code{in} and @code{out} instructions where applicable, +assuming some other module assigns an address in the I/O address range. Example: @smallexample @@ -8318,15 +8319,29 @@ allowing the use of @code{cbi}, @code{sbi}, @code{sbic} and @code{sbis} instructions. @cindex @code{address} variable attribute, AVR -@item address -@itemx address (@var{addr}) -Variables with the @code{address} attribute are used to address -memory-mapped peripherals that may lie outside the io address range. +@item address (@var{addr}) +Variables with the @code{address} attribute can be used to address +memory-mapped peripherals that may lie outside the I/O address range. +Just like with the @code{io} and @code{io_low} attributes, no memory is +allocated. @smallexample volatile int porta __attribute__((address (0x600))); @end smallexample +This attribute can also be used to define symbols in C/C++ +code which otherwise would require assembly, a linker description file +or command line options like @code{-Wl,--defsym,a_symbol=@var{value}}. +For example, +@smallexample +int a_symbol __attribute__((weak, address (1234))); +@end smallexample +will be compiled to +@smallexample +.weak a_symbol +a_symbol = 1234 +@end smallexample + @cindex @code{absdata} variable attribute, AVR @item absdata Variables in static storage and with the @code{absdata} attribute can diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi index a494420..01170c0 100644 --- a/gcc/doc/invoke.texi +++ b/gcc/doc/invoke.texi @@ -883,12 +883,12 @@ Objective-C and Objective-C++ Dialects}. @emph{AVR Options} @gccoptlist{-mmcu=@var{mcu} -mabsdata -maccumulate-args -mbranch-cost=@var{cost} --mcall-prologues -mgas-isr-prologues -mint8 --mdouble=@var{bits} -mlong-double=@var{bits} +-mcall-prologues -mgas-isr-prologues -mint8 -mflmap +-mdouble=@var{bits} -mlong-double=@var{bits} -mn_flash=@var{size} -mno-interrupts -mmain-is-OS_task -mrelax -mrmw -mstrict-X -mtiny-stack --mfract-convert-truncate --mshort-calls -nodevicelib -nodevicespecs +-mrodata-in-ram -mfract-convert-truncate +-mshort-calls -mskip-bug -nodevicelib -nodevicespecs -Waddr-space-convert -Wmisspelled-isr} @emph{Blackfin Options} @@ -1463,7 +1463,7 @@ See RS/6000 and PowerPC Options. -mamx-tile -mamx-int8 -mamx-bf16 -muintr -mhreset -mavxvnni -mavx512fp16 -mavxifma -mavxvnniint8 -mavxneconvert -mcmpccxadd -mamx-fp16 -mprefetchi -mraoint -mamx-complex -mavxvnniint16 -msm3 -msha512 -msm4 -mapxf --musermsr -mavx10.1 -mavx10.1-256 -mavx10.1-512 +-musermsr -mavx10.1 -mavx10.1-256 -mavx10.1-512 -mevex512 -mcldemote -mms-bitfields -mno-align-stringops -minline-all-stringops -minline-stringops-dynamically -mstringop-strategy=@var{alg} -mkl -mwidekl @@ -17734,6 +17734,9 @@ function. The value @code{full} is an alias for specifying both @code{branch} and @code{return}. The value @code{none} turns off instrumentation. +To override @option{-fcf-protection}, @option{-fcf-protection=none} +needs to be added and then with @option{-fcf-protection=xxx}. + The value @code{check} is used for the final link with link-time optimization (LTO). An error is issued if LTO object files are compiled with different @option{-fcf-protection} values. The @@ -23695,11 +23698,6 @@ Do not save registers in @code{main}. The effect is the same like attaching attribute @ref{AVR Function Attributes,,@code{OS_task}} to @code{main}. It is activated per default if optimization is on. -@opindex mn-flash -@item -mn-flash=@var{num} -Assume that the flash memory has a size of -@var{num} times 64@tie{}KiB. - @opindex mno-interrupts @item -mno-interrupts Generated code is not compatible with hardware interrupts. @@ -23721,34 +23719,19 @@ differ from instructions in the assembler code. Relaxing must be turned on if linker stubs are needed, see the section on @code{EIND} and linker stubs below. -@opindex mrmw -@item -mrmw -Assume that the device supports the Read-Modify-Write -instructions @code{XCH}, @code{LAC}, @code{LAS} and @code{LAT}. - -@opindex mshort-calls -@item -mshort-calls - -Assume that @code{RJMP} and @code{RCALL} can target the whole -program memory. - -This option is used internally for multilib selection. It is -not an optimization option, and you don't need to set it by hand. +@opindex mrodata-in-ram +@item -mrodata-in-ram +@itemx -mno-rodata-in-ram +Locate the @code{.rodata} sections for read-only data in RAM resp.@: +in program memory. +For most devices, there is no choice and this option acts rather +like an assertion. -@opindex msp8 -@item -msp8 -Treat the stack pointer register as an 8-bit register, -i.e.@: assume the high byte of the stack pointer is zero. -In general, you don't need to set this option by hand. - -This option is used internally by the compiler to select and -build multilibs for architectures @code{avr2} and @code{avr25}. -These architectures mix devices with and without @code{SPH}. -For any setting other than @option{-mmcu=avr2} or @option{-mmcu=avr25} -the compiler driver adds or removes this option from the compiler -proper's command line, because the compiler then knows if the device -or architecture has an 8-bit stack pointer and thus no @code{SPH} -register or not. +Since v14 and for the AVR64* and AVR128* devices, @code{.rodata} +is located in flash memory per default, provided the required GNU Binutils +support (@w{@uref{https://sourceware.org/PR31124,PR31124}}) is available. +In that case, @option{-mrodata-in-ram} can be used to return to the old +layout with @code{.rodata} in RAM. @opindex mstrict-X @item -mstrict-X @@ -23808,6 +23791,7 @@ Warn if the ISR is misspelled, i.e.@: without __vector prefix. Enabled by default. @end table +@anchor{eind} @subsubsection @code{EIND} and Devices with More Than 128 Ki Bytes of Flash @cindex @code{EIND} Pointers in the implementation are 16@tie{}bits wide. @@ -23944,6 +23928,7 @@ and the application be linked with @option{-Wl,--defsym,func_4=0x4}. Alternatively, @code{func_4} can be defined in the linker script. @end itemize +@anchor{ramp} @subsubsection Handling of the @code{RAMPD}, @code{RAMPX}, @code{RAMPY} and @code{RAMPZ} Special Function Registers @cindex @code{RAMPD} @cindex @code{RAMPX} @@ -23986,6 +23971,7 @@ you must reset it to zero after the access. @end itemize +@anchor{avr-macros} @subsubsection AVR Built-in Macros GCC defines several built-in macros so that the user code can test @@ -24140,6 +24126,23 @@ description file, and is currently available for there is no need to use address spaces like @code{__flash} or features like attribute @code{progmem} and @code{pgm_read_*}. +@item __AVR_HAVE_FLMAP__ +This macro is defined provided the following conditions are met: +@itemize @bullet +@item The device has the @code{NVMCTRL_CTRLB.FLMAP} bitfield. +This applies to the AVR64* and AVR128* devices. +@item It's not known at assembler-time which emulation will be used. +@end itemize +This implies the compiler was configured with GNU Binutils that implement +@w{@uref{https://sourceware.org/PR31124,PR31124}}. + +@item __AVR_RODATA_IN_RAM__ +This macro is undefined when the code is compiled for a core architecture. + +When the code is compiled for a device, the macro is defined to@tie{}1 +when the @code{.rodata} sections for read-only data is located in RAM; +and defined to@tie{}0, otherwise. + @item __WITH_AVRLIBC__ The compiler is configured to be used together with AVR-Libc. See the @option{--with-avrlibc} configure option. @@ -24176,6 +24179,56 @@ Reflects the @code{--with-libf7=@{libgcc|math|math-symbols@}} @end table +@subsubsection AVR Internal Options +The following options are used internally by the compiler and to communicate +between device specs files and the compiler proper. You don't need to set these +options by hand, in particular they are not optimization options. +Using these options in the wrong way may lead to sub-optimal or wrong code. +They are documented for completeness, and in order to get a better +understanding of +@w{@uref{https://gcc.gnu.org/wiki/avr-gcc#spec-files,device specs}} +files. + +@table @gcctabopt + +@opindex mn-flash +@item -mn-flash=@var{num} +Assume that the flash memory has a size of @var{num} times 64@tie{}KiB. +This determines which @code{__flash@var{N}} address spaces are available. + +@opindex mflmap +@item -mflmap +The device has the @code{FLMAP} bit field located in special function +register @code{NVMCTRL_CTRLB}. + +@opindex mrmw +@item -mrmw +Assume that the device supports the Read-Modify-Write +instructions @code{XCH}, @code{LAC}, @code{LAS} and @code{LAT}. + +@opindex mshort-calls +@item -mshort-calls + +Assume that @code{RJMP} and @code{RCALL} can target the whole +program memory. This option is used for multilib generation and selection +for the devices from architecture @code{avrxmega3}. + +@opindex mskip-bug +@item -mskip-bug + +Generate code without skips (@code{CPSE}, @code{SBRS}, +@code{SBRC}, @code{SBIS}, @code{SBIC}) over 32-bit instructions. + +@opindex msp8 +@item -msp8 +Treat the stack pointer register as an 8-bit register, +i.e.@: assume the high byte of the stack pointer is zero. +This option is used by the compiler to select and +build multilibs for architectures @code{avr2} and @code{avr25}. +These architectures mix devices with and without @code{SPH}. + +@end table + @node Blackfin Options @subsection Blackfin Options @cindex Blackfin Options @@ -35272,6 +35325,19 @@ r8-r15 registers so that the call and jmp instruction length is 6 bytes to allow them to be replaced with @samp{lfence; call *%r8-r15} or @samp{lfence; jmp *%r8-r15} at run-time. +@opindex mapx-inline-asm-use-gpr32 +@item -mapx-inline-asm-use-gpr32 +For inline asm support with APX, by default the EGPR feature was +disabled to prevent potential illegal instruction with EGPR occurs. +To invoke egpr usage in inline asm, use new compiler option +-mapx-inline-asm-use-gpr32 and user should ensure the instruction +supports EGPR. + +@opindex mevex512 +@item -mevex512 +@itemx -mno-evex512 +Enables/disables 512-bit vector. It will be default on if AVX512F is enabled. + @end table These @samp{-m} switches are supported in addition to the above diff --git a/gcc/doc/sourcebuild.texi b/gcc/doc/sourcebuild.texi index 3a394e7..8082100 100644 --- a/gcc/doc/sourcebuild.texi +++ b/gcc/doc/sourcebuild.texi @@ -2681,6 +2681,10 @@ Target requires a command line argument to enable a SIMD instruction set. @item xorsign Target supports the xorsign optab expansion. +@item ifn_copysign +Target supports the copysign optab expansion of float and double for +both scalar and vector modes. + @end table @subsubsection Environment attributes @@ -2873,6 +2877,18 @@ Target supports Graphite optimizations. @item fixed_point Target supports fixed-point extension to C. +@item bitint +Target supports _BitInt(N). + +@item bitint128 +Target supports _BitInt(128). + +@item bitint575 +Target supports _BitInt(575). + +@item bitint65535 +Target supports _BitInt(65535). + @item fopenacc Target supports OpenACC via @option{-fopenacc}. diff --git a/gcc/dwarf2out.cc b/gcc/dwarf2out.cc index 2f9010b..1c994bb 100644 --- a/gcc/dwarf2out.cc +++ b/gcc/dwarf2out.cc @@ -3940,7 +3940,7 @@ static void gen_descr_array_type_die (tree, struct array_descr_info *, dw_die_re #if 0 static void gen_entry_point_die (tree, dw_die_ref); #endif -static dw_die_ref gen_enumeration_type_die (tree, dw_die_ref); +static dw_die_ref gen_enumeration_type_die (tree, dw_die_ref, bool); static dw_die_ref gen_formal_parameter_die (tree, tree, bool, dw_die_ref); static dw_die_ref gen_formal_parameter_pack_die (tree, tree, dw_die_ref, tree*); static void gen_unspecified_parameters_die (tree, dw_die_ref); @@ -3960,7 +3960,7 @@ static void gen_struct_or_union_type_die (tree, dw_die_ref, enum debug_info_usage); static void gen_subroutine_type_die (tree, dw_die_ref); static void gen_typedef_die (tree, dw_die_ref); -static void gen_type_die (tree, dw_die_ref); +static void gen_type_die (tree, dw_die_ref, bool = false); static void gen_block_die (tree, dw_die_ref); static void decls_for_scope (tree, dw_die_ref, bool = true); static bool is_naming_typedef_decl (const_tree); @@ -3976,8 +3976,10 @@ static struct dwarf_file_data * lookup_filename (const char *); static void retry_incomplete_types (void); static void gen_type_die_for_member (tree, tree, dw_die_ref); static void gen_generic_params_dies (tree); -static void gen_tagged_type_die (tree, dw_die_ref, enum debug_info_usage); -static void gen_type_die_with_usage (tree, dw_die_ref, enum debug_info_usage); +static void gen_tagged_type_die (tree, dw_die_ref, enum debug_info_usage, + bool = false); +static void gen_type_die_with_usage (tree, dw_die_ref, enum debug_info_usage, + bool = false); static void splice_child_die (dw_die_ref, dw_die_ref); static int file_info_cmp (const void *, const void *); static dw_loc_list_ref new_loc_list (dw_loc_descr_ref, const char *, var_loc_view, @@ -13665,8 +13667,11 @@ modified_type_die (tree type, int cv_quals, bool reverse, const int cv_qual_mask = (TYPE_QUAL_CONST | TYPE_QUAL_VOLATILE | TYPE_QUAL_RESTRICT | TYPE_QUAL_ATOMIC | ENCODE_QUAL_ADDR_SPACE(~0U)); - const bool reverse_base_type - = need_endianity_attribute_p (reverse) && is_base_type (type); + /* DW_AT_endianity is specified only for base types in the standard. */ + const bool reverse_type + = need_endianity_attribute_p (reverse) + && (is_base_type (type) + || (TREE_CODE (type) == ENUMERAL_TYPE && !dwarf_strict)); if (code == ERROR_MARK) return NULL; @@ -13726,9 +13731,9 @@ modified_type_die (tree type, int cv_quals, bool reverse, /* DW_AT_endianity doesn't come from a qualifier on the type, so it is dealt with specially: the DIE with the attribute, if it exists, is - placed immediately after the regular DIE for the same base type. */ + placed immediately after the regular DIE for the same type. */ if (mod_type_die - && (!reverse_base_type + && (!reverse_type || ((mod_type_die = mod_type_die->die_sib) != NULL && get_AT_unsigned (mod_type_die, DW_AT_endianity)))) return mod_type_die; @@ -13745,7 +13750,7 @@ modified_type_die (tree type, int cv_quals, bool reverse, tree dtype = TREE_TYPE (name); /* Skip the typedef for base types with DW_AT_endianity, no big deal. */ - if (qualified_type == dtype && !reverse_base_type) + if (qualified_type == dtype && !reverse_type) { tree origin = decl_ultimate_origin (name); @@ -13952,7 +13957,7 @@ modified_type_die (tree type, int cv_quals, bool reverse, mod_type_die = base_type_die (type, reverse); /* The DIE with DW_AT_endianity is placed right after the naked DIE. */ - if (reverse_base_type) + if (reverse_type) { dw_die_ref after_die = modified_type_die (type, cv_quals, false, context_die); @@ -13965,6 +13970,17 @@ modified_type_die (tree type, int cv_quals, bool reverse, } else { + /* The DIE with DW_AT_endianity is placed right after the naked DIE. */ + if (reverse_type) + { + dw_die_ref after_die + = modified_type_die (type, cv_quals, false, context_die); + gen_type_die (type, context_die, true); + gcc_assert (after_die->die_sib + && get_AT_unsigned (after_die->die_sib, DW_AT_endianity)); + return after_die->die_sib; + } + gen_type_die (type, context_die); /* We have to get the type_main_variant here (and pass that to the @@ -14034,7 +14050,7 @@ modified_type_die (tree type, int cv_quals, bool reverse, } } - if (qualified_type && !reverse_base_type) + if (qualified_type && !reverse_type) equate_type_number_to_die (qualified_type, mod_type_die); if (item_type) @@ -22824,19 +22840,31 @@ record_type_tag (tree type) /* Generate a DIE to represent an enumeration type. Note that these DIEs include all of the information about the enumeration values also. Each enumerated type name/value is listed as a child of the enumerated type - DIE. */ + DIE. REVERSE is true if the type is to be interpreted in the reverse + storage order wrt the target order. */ static dw_die_ref -gen_enumeration_type_die (tree type, dw_die_ref context_die) +gen_enumeration_type_die (tree type, dw_die_ref context_die, bool reverse) { dw_die_ref type_die = lookup_type_die (type); dw_die_ref orig_type_die = type_die; - if (type_die == NULL) + if (type_die == NULL || reverse) { - type_die = new_die (DW_TAG_enumeration_type, - scope_die_for (type, context_die), type); - equate_type_number_to_die (type, type_die); + /* The DIE with DW_AT_endianity is placed right after the naked DIE. */ + if (reverse) + { + gcc_assert (type_die); + dw_die_ref after_die = type_die; + type_die = new_die_raw (DW_TAG_enumeration_type); + add_child_die_after (context_die, type_die, after_die); + } + else + { + type_die = new_die (DW_TAG_enumeration_type, + scope_die_for (type, context_die), type); + equate_type_number_to_die (type, type_die); + } add_name_attribute (type_die, type_tag (type)); if ((dwarf_version >= 4 || !dwarf_strict) && ENUM_IS_SCOPED (type)) @@ -22848,6 +22876,9 @@ gen_enumeration_type_die (tree type, dw_die_ref context_die) TYPE_UNSIGNED (type) ? DW_ATE_unsigned : DW_ATE_signed); + if (reverse) + add_AT_unsigned (type_die, DW_AT_endianity, + BYTES_BIG_ENDIAN ? DW_END_little : DW_END_big); } else if (! TYPE_SIZE (type) || ENUM_IS_OPAQUE (type)) return type_die; @@ -26155,7 +26186,8 @@ gen_typedef_die (tree decl, dw_die_ref context_die) static void gen_tagged_type_die (tree type, dw_die_ref context_die, - enum debug_info_usage usage) + enum debug_info_usage usage, + bool reverse) { if (type == NULL_TREE || !is_tagged_type (type)) @@ -26200,8 +26232,8 @@ gen_tagged_type_die (tree type, { /* This might have been written out by the call to declare_in_namespace. */ - if (!TREE_ASM_WRITTEN (type)) - gen_enumeration_type_die (type, context_die); + if (!TREE_ASM_WRITTEN (type) || reverse) + gen_enumeration_type_die (type, context_die, reverse); } else gen_struct_or_union_type_die (type, context_die, usage); @@ -26215,7 +26247,7 @@ gen_tagged_type_die (tree type, static void gen_type_die_with_usage (tree type, dw_die_ref context_die, - enum debug_info_usage usage) + enum debug_info_usage usage, bool reverse) { struct array_descr_info info; @@ -26279,7 +26311,7 @@ gen_type_die_with_usage (tree type, dw_die_ref context_die, if (debug_type != NULL_TREE && debug_type != type) { - gen_type_die_with_usage (debug_type, context_die, usage); + gen_type_die_with_usage (debug_type, context_die, usage, reverse); return; } } @@ -26326,7 +26358,7 @@ gen_type_die_with_usage (tree type, dw_die_ref context_die, } } - if (TREE_ASM_WRITTEN (type)) + if (TREE_ASM_WRITTEN (type) && !reverse) { /* Variable-length types may be incomplete even if TREE_ASM_WRITTEN. For such types, fall through to @@ -26398,7 +26430,7 @@ gen_type_die_with_usage (tree type, dw_die_ref context_die, case RECORD_TYPE: case UNION_TYPE: case QUAL_UNION_TYPE: - gen_tagged_type_die (type, context_die, usage); + gen_tagged_type_die (type, context_die, usage, reverse); return; case VOID_TYPE: @@ -26450,11 +26482,11 @@ gen_type_die_with_usage (tree type, dw_die_ref context_die, } static void -gen_type_die (tree type, dw_die_ref context_die) +gen_type_die (tree type, dw_die_ref context_die, bool reverse) { if (type != error_mark_node) { - gen_type_die_with_usage (type, context_die, DINFO_USAGE_DIR_USE); + gen_type_die_with_usage (type, context_die, DINFO_USAGE_DIR_USE, reverse); if (flag_checking) { dw_die_ref die = lookup_type_die (type); diff --git a/gcc/emit-rtl.h b/gcc/emit-rtl.h index f749ca9..34f44cb 100644 --- a/gcc/emit-rtl.h +++ b/gcc/emit-rtl.h @@ -141,6 +141,9 @@ struct GTY(()) rtl_data { If stack grows up, this is the address for the next slot. */ poly_int64 x_frame_offset; + /* The function's FUNCTION_BEG note. */ + rtx_insn *x_function_beg_insn; + /* Insn after which register parms and SAVE_EXPRs are born, if nonopt. */ rtx_insn *x_parm_birth_insn; @@ -323,6 +326,7 @@ struct GTY(()) rtl_data { #define return_label (crtl->x_return_label) #define naked_return_label (crtl->x_naked_return_label) #define stack_slot_list (crtl->x_stack_slot_list) +#define function_beg_insn (crtl->x_function_beg_insn) #define parm_birth_insn (crtl->x_parm_birth_insn) #define frame_offset (crtl->x_frame_offset) #define stack_check_probe_note (crtl->x_stack_check_probe_note) diff --git a/gcc/expr.cc b/gcc/expr.cc index dc816bc..34f5ff9 100644 --- a/gcc/expr.cc +++ b/gcc/expr.cc @@ -7841,10 +7841,12 @@ store_constructor (tree exp, rtx target, int cleared, poly_int64 size, break; } /* Use sign-extension for uniform boolean vectors with - integer modes. Effectively "vec_duplicate" for bitmasks. */ - if (!TREE_SIDE_EFFECTS (exp) + integer modes and single-bit mask entries. + Effectively "vec_duplicate" for bitmasks. */ + if (elt_size == 1 + && !TREE_SIDE_EFFECTS (exp) && VECTOR_BOOLEAN_TYPE_P (type) - && SCALAR_INT_MODE_P (mode) + && SCALAR_INT_MODE_P (TYPE_MODE (type)) && (elt = uniform_vector_p (exp)) && !VECTOR_TYPE_P (TREE_TYPE (elt))) { @@ -13619,6 +13621,8 @@ do_store_flag (sepops ops, rtx target, machine_mode mode) if ((code == NE || code == EQ) && (integer_zerop (arg1) || integer_pow2p (arg1)) + /* vector types are not handled here. */ + && TREE_CODE (TREE_TYPE (arg1)) != VECTOR_TYPE && (TYPE_PRECISION (ops->type) != 1 || TYPE_UNSIGNED (ops->type))) { tree narg0 = arg0; diff --git a/gcc/fold-const.cc b/gcc/fold-const.cc index 3a9d78b..385e4a6 100644 --- a/gcc/fold-const.cc +++ b/gcc/fold-const.cc @@ -12900,7 +12900,8 @@ fold_binary_loc (location_t loc, enum tree_code code, tree type, if (element_precision (TREE_TYPE (targ1)) > element_precision (newtype)) newtype = TREE_TYPE (targ1); - if (element_precision (newtype) < element_precision (TREE_TYPE (arg0))) + if (element_precision (newtype) < element_precision (TREE_TYPE (arg0)) + && (!VECTOR_TYPE_P (type) || is_truth_type_for (newtype, type))) return fold_build2_loc (loc, code, type, fold_convert_loc (loc, newtype, targ0), fold_convert_loc (loc, newtype, targ1)); diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog index 757e515..7f853a1 100644 --- a/gcc/fortran/ChangeLog +++ b/gcc/fortran/ChangeLog @@ -1,3 +1,27 @@ +2024-01-13 Harald Anlauf <anlauf@gmx.de> + + PR fortran/67277 + * trans-intrinsic.cc (gfc_conv_intrinsic_ishftc): Handle optional + dummy argument for SIZE passed to ISHFTC. Set default value to + BIT_SIZE(I) when missing. + +2024-01-13 Harald Anlauf <anlauf@gmx.de> + + PR fortran/113305 + * gfortran.h (gfc_loop_annot): New. + (gfc_iterator, gfc_forall_iterator): Use for annotation control. + * array.cc (gfc_copy_iterator): Adjust. + * gfortran.texi: Document annotations IVDEP, UNROLL n, VECTOR, + NOVECTOR as applied to DO CONCURRENT. + * parse.cc (parse_do_block): Parse annotations IVDEP, UNROLL n, + VECTOR, NOVECTOR as applied to DO CONCURRENT. Apply UNROLL only to + first loop control variable. + * trans-stmt.cc (iter_info): Use gfc_loop_annot. + (gfc_trans_simple_do): Adjust. + (gfc_trans_forall_loop): Annotate loops with IVDEP, UNROLL n, + VECTOR, NOVECTOR as needed for DO CONCURRENT. + (gfc_trans_forall_1): Handle loop annotations. + 2024-01-08 Harald Anlauf <anlauf@gmx.de> PR fortran/113245 diff --git a/gcc/fortran/array.cc b/gcc/fortran/array.cc index 19456ba..81fa99d 100644 --- a/gcc/fortran/array.cc +++ b/gcc/fortran/array.cc @@ -2308,10 +2308,7 @@ gfc_copy_iterator (gfc_iterator *src) dest->start = gfc_copy_expr (src->start); dest->end = gfc_copy_expr (src->end); dest->step = gfc_copy_expr (src->step); - dest->unroll = src->unroll; - dest->ivdep = src->ivdep; - dest->vector = src->vector; - dest->novector = src->novector; + dest->annot = src->annot; return dest; } diff --git a/gcc/fortran/gfortran.h b/gcc/fortran/gfortran.h index 82f388c..fd73e4c 100644 --- a/gcc/fortran/gfortran.h +++ b/gcc/fortran/gfortran.h @@ -2830,14 +2830,22 @@ gfc_case; #define gfc_get_case() XCNEW (gfc_case) +/* Annotations for loop constructs. */ typedef struct { - gfc_expr *var, *start, *end, *step; unsigned short unroll; bool ivdep; bool vector; bool novector; } +gfc_loop_annot; + + +typedef struct +{ + gfc_expr *var, *start, *end, *step; + gfc_loop_annot annot; +} gfc_iterator; #define gfc_get_iterator() XCNEW (gfc_iterator) @@ -2926,6 +2934,7 @@ gfc_dt; typedef struct gfc_forall_iterator { gfc_expr *var, *start, *end, *stride; + gfc_loop_annot annot; struct gfc_forall_iterator *next; } gfc_forall_iterator; diff --git a/gcc/fortran/gfortran.texi b/gcc/fortran/gfortran.texi index 5615fee..371666d 100644 --- a/gcc/fortran/gfortran.texi +++ b/gcc/fortran/gfortran.texi @@ -3262,6 +3262,9 @@ It must be placed immediately before a @code{DO} loop and applies only to the loop that follows. N is an integer constant specifying the unrolling factor. The values of 0 and 1 block any unrolling of the loop. +For @code{DO CONCURRENT} constructs the unrolling specification applies +only to the first loop control variable. + @node BUILTIN directive @subsection BUILTIN directive @@ -3300,6 +3303,9 @@ whether a particular loop is vectorizable due to potential dependencies between iterations. The purpose of the directive is to tell the compiler that vectorization is safe. +For @code{DO CONCURRENT} constructs this annotation is implicit to all +loop control variables. + This directive is intended for annotation of existing code. For new code it is recommended to consider OpenMP SIMD directives as potential alternative. @@ -3316,6 +3322,9 @@ This directive tells the compiler to vectorize the following loop. It must be placed immediately before a @code{DO} loop and applies only to the loop that follows. +For @code{DO CONCURRENT} constructs this annotation applies to all loops +specified in the concurrent header. + @node NOVECTOR directive @subsection NOVECTOR directive @@ -3328,6 +3337,9 @@ This directive tells the compiler to not vectorize the following loop. It must be placed immediately before a @code{DO} loop and applies only to the loop that follows. +For @code{DO CONCURRENT} constructs this annotation applies to all loops +specified in the concurrent header. + @node Non-Fortran Main Program @section Non-Fortran Main Program diff --git a/gcc/fortran/parse.cc b/gcc/fortran/parse.cc index d8b38cf..98a04e7 100644 --- a/gcc/fortran/parse.cc +++ b/gcc/fortran/parse.cc @@ -5307,27 +5307,51 @@ parse_do_block (void) do_op = new_st.op; s.ext.end_do_label = new_st.label1; - if (new_st.ext.iterator != NULL) + if (do_op == EXEC_DO_CONCURRENT) + { + gfc_forall_iterator *fa; + for (fa = new_st.ext.forall_iterator; fa; fa = fa->next) + { + /* Apply unroll only to innermost loop (first control + variable). */ + if (directive_unroll != -1) + { + fa->annot.unroll = directive_unroll; + directive_unroll = -1; + } + if (directive_ivdep) + fa->annot.ivdep = directive_ivdep; + if (directive_vector) + fa->annot.vector = directive_vector; + if (directive_novector) + fa->annot.novector = directive_novector; + } + directive_ivdep = false; + directive_vector = false; + directive_novector = false; + stree = NULL; + } + else if (new_st.ext.iterator != NULL) { stree = new_st.ext.iterator->var->symtree; if (directive_unroll != -1) { - new_st.ext.iterator->unroll = directive_unroll; + new_st.ext.iterator->annot.unroll = directive_unroll; directive_unroll = -1; } if (directive_ivdep) { - new_st.ext.iterator->ivdep = directive_ivdep; + new_st.ext.iterator->annot.ivdep = directive_ivdep; directive_ivdep = false; } if (directive_vector) { - new_st.ext.iterator->vector = directive_vector; + new_st.ext.iterator->annot.vector = directive_vector; directive_vector = false; } if (directive_novector) { - new_st.ext.iterator->novector = directive_novector; + new_st.ext.iterator->annot.novector = directive_novector; directive_novector = false; } } diff --git a/gcc/fortran/trans-intrinsic.cc b/gcc/fortran/trans-intrinsic.cc index 7413926..0468dfa 100644 --- a/gcc/fortran/trans-intrinsic.cc +++ b/gcc/fortran/trans-intrinsic.cc @@ -6863,9 +6863,23 @@ gfc_conv_intrinsic_ishftc (gfc_se * se, gfc_expr * expr) if (num_args == 3) { + gfc_expr *size = expr->value.function.actual->next->next->expr; + /* Use a library function for the 3 parameter version. */ tree int4type = gfc_get_int_type (4); + /* Treat optional SIZE argument when it is passed as an optional + dummy. If SIZE is absent, the default value is BIT_SIZE(I). */ + if (size->expr_type == EXPR_VARIABLE + && size->symtree->n.sym->attr.dummy + && size->symtree->n.sym->attr.optional) + { + tree type_of_size = TREE_TYPE (args[2]); + args[2] = build3_loc (input_location, COND_EXPR, type_of_size, + gfc_conv_expr_present (size->symtree->n.sym), + args[2], fold_convert (type_of_size, nbits)); + } + /* We convert the first argument to at least 4 bytes, and convert back afterwards. This removes the need for library functions for all argument sizes, and function will be diff --git a/gcc/fortran/trans-stmt.cc b/gcc/fortran/trans-stmt.cc index a718dce..5247d3d 100644 --- a/gcc/fortran/trans-stmt.cc +++ b/gcc/fortran/trans-stmt.cc @@ -41,6 +41,7 @@ typedef struct iter_info tree start; tree end; tree step; + gfc_loop_annot annot; struct iter_info *next; } iter_info; @@ -2462,21 +2463,22 @@ gfc_trans_simple_do (gfc_code * code, stmtblock_t *pblock, tree dovar, fold_convert (type, to)); cond = gfc_evaluate_now_loc (loc, cond, &body); - if (code->ext.iterator->unroll && cond != error_mark_node) + if (code->ext.iterator->annot.unroll && cond != error_mark_node) cond = build3 (ANNOTATE_EXPR, TREE_TYPE (cond), cond, build_int_cst (integer_type_node, annot_expr_unroll_kind), - build_int_cst (integer_type_node, code->ext.iterator->unroll)); + build_int_cst (integer_type_node, + code->ext.iterator->annot.unroll)); - if (code->ext.iterator->ivdep && cond != error_mark_node) + if (code->ext.iterator->annot.ivdep && cond != error_mark_node) cond = build3 (ANNOTATE_EXPR, TREE_TYPE (cond), cond, build_int_cst (integer_type_node, annot_expr_ivdep_kind), integer_zero_node); - if (code->ext.iterator->vector && cond != error_mark_node) + if (code->ext.iterator->annot.vector && cond != error_mark_node) cond = build3 (ANNOTATE_EXPR, TREE_TYPE (cond), cond, build_int_cst (integer_type_node, annot_expr_vector_kind), integer_zero_node); - if (code->ext.iterator->novector && cond != error_mark_node) + if (code->ext.iterator->annot.novector && cond != error_mark_node) cond = build3 (ANNOTATE_EXPR, TREE_TYPE (cond), cond, build_int_cst (integer_type_node, annot_expr_no_vector_kind), integer_zero_node); @@ -2806,21 +2808,22 @@ gfc_trans_do (gfc_code * code, tree exit_cond) /* End with the loop condition. Loop until countm1t == 0. */ cond = fold_build2_loc (loc, EQ_EXPR, logical_type_node, countm1t, build_int_cst (utype, 0)); - if (code->ext.iterator->unroll && cond != error_mark_node) + if (code->ext.iterator->annot.unroll && cond != error_mark_node) cond = build3 (ANNOTATE_EXPR, TREE_TYPE (cond), cond, build_int_cst (integer_type_node, annot_expr_unroll_kind), - build_int_cst (integer_type_node, code->ext.iterator->unroll)); + build_int_cst (integer_type_node, + code->ext.iterator->annot.unroll)); - if (code->ext.iterator->ivdep && cond != error_mark_node) + if (code->ext.iterator->annot.ivdep && cond != error_mark_node) cond = build3 (ANNOTATE_EXPR, TREE_TYPE (cond), cond, build_int_cst (integer_type_node, annot_expr_ivdep_kind), integer_zero_node); - if (code->ext.iterator->vector && cond != error_mark_node) + if (code->ext.iterator->annot.vector && cond != error_mark_node) cond = build3 (ANNOTATE_EXPR, TREE_TYPE (cond), cond, build_int_cst (integer_type_node, annot_expr_vector_kind), integer_zero_node); - if (code->ext.iterator->novector && cond != error_mark_node) + if (code->ext.iterator->annot.novector && cond != error_mark_node) cond = build3 (ANNOTATE_EXPR, TREE_TYPE (cond), cond, build_int_cst (integer_type_node, annot_expr_no_vector_kind), integer_zero_node); @@ -4117,12 +4120,30 @@ gfc_trans_forall_loop (forall_info *forall_tmp, tree body, /* PR 83064 means that we cannot use annot_expr_parallel_kind until the autoparallelizer can handle this. */ - if (forall_tmp->do_concurrent) + if (forall_tmp->do_concurrent || iter->annot.ivdep) cond = build3 (ANNOTATE_EXPR, TREE_TYPE (cond), cond, build_int_cst (integer_type_node, annot_expr_ivdep_kind), integer_zero_node); + if (iter->annot.unroll && cond != error_mark_node) + cond = build3 (ANNOTATE_EXPR, TREE_TYPE (cond), cond, + build_int_cst (integer_type_node, + annot_expr_unroll_kind), + build_int_cst (integer_type_node, iter->annot.unroll)); + + if (iter->annot.vector && cond != error_mark_node) + cond = build3 (ANNOTATE_EXPR, TREE_TYPE (cond), cond, + build_int_cst (integer_type_node, + annot_expr_vector_kind), + integer_zero_node); + + if (iter->annot.novector && cond != error_mark_node) + cond = build3 (ANNOTATE_EXPR, TREE_TYPE (cond), cond, + build_int_cst (integer_type_node, + annot_expr_no_vector_kind), + integer_zero_node); + tmp = build1_v (GOTO_EXPR, exit_label); tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node, cond, tmp, build_empty_stmt (input_location)); @@ -5090,6 +5111,9 @@ gfc_trans_forall_1 (gfc_code * code, forall_info * nested_forall_info) gfc_add_block_to_block (&block, &se.pre); step[n] = se.expr; + /* Copy loop annotations. */ + this_forall->annot = fa->annot; + /* Set the NEXT field of this_forall to NULL. */ this_forall->next = NULL; /* Link this_forall to the info construct. */ diff --git a/gcc/function.cc b/gcc/function.cc index de356f7..5ffd438 100644 --- a/gcc/function.cc +++ b/gcc/function.cc @@ -5202,7 +5202,7 @@ expand_function_start (tree subr) gcc_assert (NOTE_P (get_last_insn ())); - parm_birth_insn = get_last_insn (); + function_beg_insn = parm_birth_insn = get_last_insn (); /* If the function receives a non-local goto, then store the bits we need to restore the frame pointer. */ diff --git a/gcc/gcc-urlifier.cc b/gcc/gcc-urlifier.cc index 6bd176f..be6459e 100644 --- a/gcc/gcc-urlifier.cc +++ b/gcc/gcc-urlifier.cc @@ -154,11 +154,46 @@ gcc_urlifier::get_url_suffix_for_option (const char *p, size_t sz) const and skipping the leading '-'. We have a (pointer,size) pair that doesn't necessarily have a - terminator, so create a 0-terminated clone of the string. */ - gcc_assert (sz > 0); - char *tmp = xstrndup (p + 1, sz - 1); // skip the leading '-' - size_t opt = find_opt (tmp, m_lang_mask); - free (tmp); + terminator. + Additionally, we could have one of the e.g. "-Wno-" variants of + the option, which find_opt doesn't handle. + + Hence we need to create input for find_opt in a temporary buffer. */ + char *option_buffer; + + const char *new_prefix; + if (const char *old_prefix = get_option_prefix_remapping (p, sz, &new_prefix)) + { + /* We have one of the variants; generate a buffer containing a copy + that maps from the old prefix to the new prefix + e.g. given "-Wno-suffix", generate "-Wsuffix". */ + gcc_assert (old_prefix[0] == '-'); + gcc_assert (new_prefix); + gcc_assert (new_prefix[0] == '-'); + + const size_t old_prefix_len = strlen (old_prefix); + gcc_assert (old_prefix_len <= sz); + const size_t suffix_len = sz - old_prefix_len; + const size_t new_prefix_len = strlen (new_prefix); + const size_t new_sz = new_prefix_len + suffix_len + 1; + + option_buffer = (char *)xmalloc (new_sz); + memcpy (option_buffer, new_prefix, new_prefix_len); + /* Copy suffix. */ + memcpy (option_buffer + new_prefix_len, p + old_prefix_len, suffix_len); + /* Terminate. */ + option_buffer[new_prefix_len + suffix_len] = '\0'; + } + else + { + /* Otherwise we can simply create a 0-terminated clone of the string. */ + gcc_assert (sz > 0); + gcc_assert (p[0] == '-'); + option_buffer = xstrndup (p, sz); + } + + size_t opt = find_opt (option_buffer + 1, m_lang_mask); + free (option_buffer); if (opt >= N_OPTS) /* Option not recognized. */ @@ -221,6 +256,10 @@ gcc_urlifier_cc_tests () /* Check an option. */ ASSERT_STREQ (u.get_url_suffix_for_quoted_text ("-fpack-struct").get (), "gcc/Code-Gen-Options.html#index-fpack-struct"); + + /* Check a "-fno-" variant of an option. */ + ASSERT_STREQ (u.get_url_suffix_for_quoted_text ("-fno-inline").get (), + "gcc/Optimize-Options.html#index-finline"); } } // namespace selftest diff --git a/gcc/gimple-if-to-switch.cc b/gcc/gimple-if-to-switch.cc index 8b3a499..96ce1c3 100644 --- a/gcc/gimple-if-to-switch.cc +++ b/gcc/gimple-if-to-switch.cc @@ -54,6 +54,7 @@ along with GCC; see the file COPYING3. If not see #include "alloc-pool.h" #include "tree-switch-conversion.h" #include "tree-ssa-reassoc.h" +#include "tree-ssa.h" using namespace tree_switch_conversion; @@ -494,6 +495,8 @@ pass_if_to_switch::execute (function *fun) auto_vec<if_chain *> all_candidates; hash_map<basic_block, condition_info *> conditions_in_bbs; + mark_ssa_maybe_undefs (); + basic_block bb; FOR_EACH_BB_FN (bb, fun) find_conditions (bb, &conditions_in_bbs); diff --git a/gcc/gimple-lower-bitint.cc b/gcc/gimple-lower-bitint.cc index 8993a61..672a9a3 100644 --- a/gcc/gimple-lower-bitint.cc +++ b/gcc/gimple-lower-bitint.cc @@ -231,7 +231,8 @@ mergeable_op (gimple *stmt) && TREE_CODE (rhs_type) == BITINT_TYPE && bitint_precision_kind (lhs_type) >= bitint_prec_large && bitint_precision_kind (rhs_type) >= bitint_prec_large - && tree_int_cst_equal (TYPE_SIZE (lhs_type), TYPE_SIZE (rhs_type))) + && (CEIL (TYPE_PRECISION (lhs_type), limb_prec) + == CEIL (TYPE_PRECISION (rhs_type), limb_prec))) { if (TYPE_PRECISION (rhs_type) >= TYPE_PRECISION (lhs_type)) return true; @@ -868,7 +869,7 @@ bitint_large_huge::handle_operand (tree op, tree idx) && m_data[m_data_cnt + 1] == NULL_TREE)) { unsigned int prec = TYPE_PRECISION (TREE_TYPE (op)); - unsigned int rem = prec % (2 * limb_prec); + unsigned int rem = prec % ((m_upwards_2limb ? 2 : 1) * limb_prec); int ext; unsigned min_prec = bitint_min_cst_precision (op, ext); if (m_first) @@ -995,8 +996,8 @@ bitint_large_huge::handle_operand (tree op, tree idx) if (m_data[m_data_cnt + 1] == integer_type_node) { unsigned int prec = TYPE_PRECISION (TREE_TYPE (op)); - unsigned rem = prec % (2 * limb_prec); - int ext = tree_int_cst_sgn (op) < 0 ? -1 : 0; + unsigned rem = prec % ((m_upwards_2limb ? 2 : 1) * limb_prec); + int ext = wi::neg_p (wi::to_wide (op)) ? -1 : 0; tree c = m_data[m_data_cnt]; unsigned min_prec = TYPE_PRECISION (TREE_TYPE (c)); g = gimple_build_cond (LT_EXPR, idx, @@ -1263,8 +1264,8 @@ bitint_large_huge::handle_cast (tree lhs_type, tree rhs1, tree idx) if m_upwards_2limb * limb_prec is equal to lhs precision that is not the case. */ || (!m_var_msb - && tree_int_cst_equal (TYPE_SIZE (rhs_type), - TYPE_SIZE (lhs_type)) + && (CEIL (TYPE_PRECISION (lhs_type), limb_prec) + == CEIL (TYPE_PRECISION (rhs_type), limb_prec)) && (!m_upwards_2limb || (m_upwards_2limb * limb_prec < TYPE_PRECISION (lhs_type))))) @@ -2226,7 +2227,9 @@ bitint_large_huge::handle_operand_addr (tree op, gimple *stmt, mp = CEIL (min_prec, limb_prec) * limb_prec; if (mp == 0) mp = 1; - if (mp >= (unsigned) TYPE_PRECISION (TREE_TYPE (op))) + if (mp >= (unsigned) TYPE_PRECISION (TREE_TYPE (op)) + && (TREE_CODE (TREE_TYPE (op)) == BITINT_TYPE + || TYPE_PRECISION (TREE_TYPE (op)) <= limb_prec)) type = TREE_TYPE (op); else type = build_bitint_type (mp, 1); @@ -2236,11 +2239,15 @@ bitint_large_huge::handle_operand_addr (tree op, gimple *stmt, if (TYPE_PRECISION (type) <= limb_prec) type = m_limb_type; else - /* This case is for targets which e.g. have 64-bit - limb but categorize up to 128-bits _BitInts as - small. We could use type of m_limb_type[2] and - similar instead to save space. */ - type = build_bitint_type (mid_min_prec, 1); + { + while (bitint_precision_kind (mp) == bitint_prec_small) + mp += limb_prec; + /* This case is for targets which e.g. have 64-bit + limb but categorize up to 128-bits _BitInts as + small. We could use type of m_limb_type[2] and + similar instead to save space. */ + type = build_bitint_type (mp, 1); + } } if (prec_stored) { @@ -5117,14 +5124,23 @@ bitint_large_huge::lower_call (tree obj, gimple *stmt) || TREE_CODE (TREE_TYPE (arg)) != BITINT_TYPE || bitint_precision_kind (TREE_TYPE (arg)) <= bitint_prec_middle) continue; - int p = var_to_partition (m_map, arg); - tree v = m_vars[p]; - gcc_assert (v != NULL_TREE); - if (!types_compatible_p (TREE_TYPE (arg), TREE_TYPE (v))) - v = build1 (VIEW_CONVERT_EXPR, TREE_TYPE (arg), v); - arg = make_ssa_name (TREE_TYPE (arg)); - gimple *g = gimple_build_assign (arg, v); - gsi_insert_before (&gsi, g, GSI_SAME_STMT); + if (SSA_NAME_IS_DEFAULT_DEF (arg) + && (!SSA_NAME_VAR (arg) || VAR_P (SSA_NAME_VAR (arg)))) + { + tree var = create_tmp_reg (TREE_TYPE (arg)); + arg = get_or_create_ssa_default_def (cfun, var); + } + else + { + int p = var_to_partition (m_map, arg); + tree v = m_vars[p]; + gcc_assert (v != NULL_TREE); + if (!types_compatible_p (TREE_TYPE (arg), TREE_TYPE (v))) + v = build1 (VIEW_CONVERT_EXPR, TREE_TYPE (arg), v); + arg = make_ssa_name (TREE_TYPE (arg)); + gimple *g = gimple_build_assign (arg, v); + gsi_insert_before (&gsi, g, GSI_SAME_STMT); + } gimple_call_set_arg (stmt, i, arg); if (m_preserved == NULL) m_preserved = BITMAP_ALLOC (NULL); @@ -5503,7 +5519,7 @@ bitint_dom_walker::before_dom_children (basic_block bb) tree lhs = gimple_get_lhs (stmt); if (lhs && TREE_CODE (lhs) == SSA_NAME - && TREE_CODE (TREE_TYPE (lhs)) != BITINT_TYPE + && TREE_CODE (TREE_TYPE (lhs)) == BITINT_TYPE && bitint_precision_kind (TREE_TYPE (lhs)) >= bitint_prec_large && !bitmap_bit_p (m_names, SSA_NAME_VERSION (lhs))) /* If lhs of stmt is large/huge _BitInt SSA_NAME not in m_names, diff --git a/gcc/ipa-fnsummary.cc b/gcc/ipa-fnsummary.cc index ba1a2d8..74c9b4e 100644 --- a/gcc/ipa-fnsummary.cc +++ b/gcc/ipa-fnsummary.cc @@ -5090,4 +5090,5 @@ void ipa_fnsummary_cc_finalize (void) { ipa_free_fn_summary (); + ipa_free_size_summary (); } diff --git a/gcc/ipa-icf.cc b/gcc/ipa-icf.cc index 3d62d7b..29ed1f1 100644 --- a/gcc/ipa-icf.cc +++ b/gcc/ipa-icf.cc @@ -3663,3 +3663,12 @@ make_pass_ipa_icf (gcc::context *ctxt) { return new ipa_icf::pass_ipa_icf (ctxt); } + +/* Reset all state within ipa-icf.cc so that we can rerun the compiler + within the same process. For use by toplev::finalize. */ + +void +ipa_icf_cc_finalize (void) +{ + ipa_icf::optimizer = NULL; +} diff --git a/gcc/ipa-profile.cc b/gcc/ipa-profile.cc index 8880e86..5e89f67 100644 --- a/gcc/ipa-profile.cc +++ b/gcc/ipa-profile.cc @@ -1065,3 +1065,13 @@ make_pass_ipa_profile (gcc::context *ctxt) { return new pass_ipa_profile (ctxt); } + +/* Reset all state within ipa-profile.cc so that we can rerun the compiler + within the same process. For use by toplev::finalize. */ + +void +ipa_profile_cc_finalize (void) +{ + delete call_sums; + call_sums = NULL; +} diff --git a/gcc/ipa-prop.cc b/gcc/ipa-prop.cc index 12a2cab..bec0ebd 100644 --- a/gcc/ipa-prop.cc +++ b/gcc/ipa-prop.cc @@ -5988,5 +5988,23 @@ ipa_return_value_range (Value_Range &range, tree decl) return true; } +/* Reset all state within ipa-prop.cc so that we can rerun the compiler + within the same process. For use by toplev::finalize. */ + +void +ipa_prop_cc_finalize (void) +{ + if (function_insertion_hook_holder) + symtab->remove_cgraph_insertion_hook (function_insertion_hook_holder); + function_insertion_hook_holder = NULL; + + if (ipa_edge_args_sum) + ggc_delete (ipa_edge_args_sum); + ipa_edge_args_sum = NULL; + + if (ipa_node_params_sum) + ggc_delete (ipa_node_params_sum); + ipa_node_params_sum = NULL; +} #include "gt-ipa-prop.h" diff --git a/gcc/ipa-prop.h b/gcc/ipa-prop.h index 3daf5ce..9c78dc9 100644 --- a/gcc/ipa-prop.h +++ b/gcc/ipa-prop.h @@ -1255,6 +1255,8 @@ tree ipcp_get_aggregate_const (struct function *func, tree parm, bool by_ref, bool unadjusted_ptr_and_unit_offset (tree op, tree *ret, poly_int64 *offset_ret); +void ipa_prop_cc_finalize (void); + /* From tree-sra.cc: */ tree build_ref_for_offset (location_t, tree, poly_int64, bool, tree, gimple_stmt_iterator *, bool); diff --git a/gcc/ipa-sra.cc b/gcc/ipa-sra.cc index 2fdc305..14c2a34 100644 --- a/gcc/ipa-sra.cc +++ b/gcc/ipa-sra.cc @@ -4707,5 +4707,17 @@ make_pass_ipa_sra (gcc::context *ctxt) return new pass_ipa_sra (ctxt); } +/* Reset all state within ipa-sra.cc so that we can rerun the compiler + within the same process. For use by toplev::finalize. */ + +void +ipa_sra_cc_finalize (void) +{ + if (func_sums) + ggc_delete (func_sums); + func_sums = NULL; + delete call_sums; + call_sums = NULL; +} #include "gt-ipa-sra.h" diff --git a/gcc/ipa-utils.h b/gcc/ipa-utils.h index 0282de4..d1da9c3 100644 --- a/gcc/ipa-utils.h +++ b/gcc/ipa-utils.h @@ -57,6 +57,13 @@ bool ipa_make_function_pure (cgraph_node *, bool, bool); /* In ipa-profile.cc */ bool ipa_propagate_frequency (struct cgraph_node *node); +void ipa_profile_cc_finalize (void); + +/* In ipa-icf.cc */ +void ipa_icf_cc_finalize (void); + +/* In ipa-sra.cc */ +void ipa_sra_cc_finalize (void); /* In ipa-devirt.cc */ diff --git a/gcc/jit/ChangeLog b/gcc/jit/ChangeLog index b53c7e1..d233b7d 100644 --- a/gcc/jit/ChangeLog +++ b/gcc/jit/ChangeLog @@ -1,3 +1,55 @@ +2024-01-12 Guillaume Gomez <guillaume1.gomez@gmail.com> + Antoni Boucher <bouanto@zoho.com> + + * docs/topics/compatibility.rst: Add documentation for LIBGCCJIT_ABI_26. + * docs/topics/functions.rst: Add documentation for new functions. + * docs/topics/expressions.rst: Add documentation for new functions. + +2024-01-12 Guillaume Gomez <guillaume1.gomez@gmail.com> + Antoni Boucher <bouanto@zoho.com> + + * dummy-frontend.cc (handle_alias_attribute): New function. + (handle_always_inline_attribute): New function. + (handle_cold_attribute): New function. + (handle_fnspec_attribute): New function. + (handle_format_arg_attribute): New function. + (handle_format_attribute): New function. + (handle_noinline_attribute): New function. + (handle_target_attribute): New function. + (handle_used_attribute): New function. + (handle_visibility_attribute): New function. + (handle_weak_attribute): New function. + (handle_alias_ifunc_attribute): New function. + * jit-playback.cc (fn_attribute_to_string): New function. + (variable_attribute_to_string): New function. + (global_new_decl): Add attributes support. + (set_variable_attribute): New function. + (new_global): Add attributes support. + (new_global_initialized): Add attributes support. + (new_local): Add attributes support. + * jit-playback.h (fn_attribute_to_string): New function. + (set_variable_attribute): New function. + * jit-recording.cc (recording::lvalue::add_attribute): New function. + (recording::function::function): New function. + (recording::function::write_to_dump): Add attributes support. + (recording::function::add_attribute): New function. + (recording::function::add_string_attribute): New function. + (recording::function::add_integer_array_attribute): New function. + (recording::global::replay_into): Add attributes support. + (recording::local::replay_into): Add attributes support. + * jit-recording.h: Add attributes support. + * libgccjit.cc (gcc_jit_function_add_attribute): New function. + (gcc_jit_function_add_string_attribute): New function. + (gcc_jit_function_add_integer_array_attribute): New function. + (gcc_jit_lvalue_add_attribute): New function. + * libgccjit.h (enum gcc_jit_fn_attribute): New enum. + (gcc_jit_function_add_attribute): New function. + (gcc_jit_function_add_string_attribute): New function. + (gcc_jit_function_add_integer_array_attribute): New function. + (enum gcc_jit_variable_attribute): New function. + (gcc_jit_lvalue_add_string_attribute): New function. + * libgccjit.map: Declare new functions. + 2023-12-06 David Malcolm <dmalcolm@redhat.com> * dummy-frontend.cc (jit_begin_diagnostic): Make diagnostic_info diff --git a/gcc/jit/docs/topics/compatibility.rst b/gcc/jit/docs/topics/compatibility.rst index 704de1b..cbf5b41 100644 --- a/gcc/jit/docs/topics/compatibility.rst +++ b/gcc/jit/docs/topics/compatibility.rst @@ -378,3 +378,15 @@ alignment of a variable: -------------------- ``LIBGCCJIT_ABI_25`` covers the addition of :func:`gcc_jit_type_get_restrict` + +.. _LIBGCCJIT_ABI_26: + +``LIBGCCJIT_ABI_26`` +-------------------- +``LIBGCCJIT_ABI_26`` covers the addition of functions to set attributes +on functions and variables: + + * :func:`gcc_jit_function_add_attribute` + * :func:`gcc_jit_function_add_string_attribute` + * :func:`gcc_jit_function_add_integer_array_attribute` + * :func:`gcc_jit_lvalue_add_string_attribute` diff --git a/gcc/jit/docs/topics/expressions.rst b/gcc/jit/docs/topics/expressions.rst index cee6a30..35ee05c 100644 --- a/gcc/jit/docs/topics/expressions.rst +++ b/gcc/jit/docs/topics/expressions.rst @@ -944,6 +944,23 @@ Global variables #ifdef LIBGCCJIT_HAVE_CTORS +Variables +********* + +.. function:: void\ + gcc_jit_lvalue_add_string_attribute (gcc_jit_lvalue *variable, + enum gcc_jit_variable_attribute attribute, + const char *value) + + Add an attribute ``attribute`` with value ``value`` to a variable ``variable``. + + This entrypoint was added in :ref:`LIBGCCJIT_ABI_26`; you can test for + its presence using + + .. code-block:: c + + #ifdef LIBGCCJIT_HAVE_ATTRIBUTES + Working with pointers, structs and unions ----------------------------------------- diff --git a/gcc/jit/docs/topics/functions.rst b/gcc/jit/docs/topics/functions.rst index 127bc0e..804605e 100644 --- a/gcc/jit/docs/topics/functions.rst +++ b/gcc/jit/docs/topics/functions.rst @@ -197,6 +197,69 @@ Functions .. type:: gcc_jit_case +.. function:: void\ + gcc_jit_function_add_attribute (gcc_jit_function *func, + enum gcc_jit_fn_attribute attribute) + + Add an attribute ``attribute`` to a function ``func``. + + This is equivalent to the following code: + + .. code-block:: c + + __attribute__((always_inline)) + + This entrypoint was added in :ref:`LIBGCCJIT_ABI_26`; you can test for + its presence using + + .. code-block:: c + + #ifdef LIBGCCJIT_HAVE_ATTRIBUTES + +.. function:: void\ + gcc_jit_function_add_string_attribute (gcc_jit_function *func, + enum gcc_jit_fn_attribute attribute, + const char *value) + + Add a string attribute ``attribute`` with value ``value`` to a function + ``func``. + + This is equivalent to the following code: + + .. code-block:: c + + __attribute__ ((alias ("xxx"))) + + This entrypoint was added in :ref:`LIBGCCJIT_ABI_26`; you can test for + its presence using + + .. code-block:: c + + #ifdef LIBGCCJIT_HAVE_ATTRIBUTES + +.. function:: void\ + gcc_jit_function_add_integer_array_attribute (gcc_jit_function *func, + enum gcc_jit_fn_attribute attribute, + const int *value, + size_t length) + + Add an attribute ``attribute`` with ``length`` integer values ``value`` to a + function ``func``. The integer values must be the same as you would write + them in a C code. + + This is equivalent to the following code: + + .. code-block:: c + + __attribute__ ((nonnull (1, 2))) + + This entrypoint was added in :ref:`LIBGCCJIT_ABI_26`; you can test for + its presence using + + .. code-block:: c + + #ifdef LIBGCCJIT_HAVE_ATTRIBUTES + Blocks ------ .. type:: gcc_jit_block diff --git a/gcc/jit/dummy-frontend.cc b/gcc/jit/dummy-frontend.cc index 211f1be..dbeeacd 100644 --- a/gcc/jit/dummy-frontend.cc +++ b/gcc/jit/dummy-frontend.cc @@ -29,30 +29,42 @@ along with GCC; see the file COPYING3. If not see #include "options.h" #include "stringpool.h" #include "attribs.h" +#include "cgraph.h" +#include "target.h" #include <mpfr.h> /* Attribute handling. */ -static tree handle_noreturn_attribute (tree *, tree, tree, int, bool *); -static tree handle_leaf_attribute (tree *, tree, tree, int, bool *); +static tree handle_alias_attribute (tree *, tree, tree, int, bool *); +static tree handle_always_inline_attribute (tree *, tree, tree, int, + bool *); +static tree handle_cold_attribute (tree *, tree, tree, int, bool *); static tree handle_const_attribute (tree *, tree, tree, int, bool *); +static tree handle_fnspec_attribute (tree *, tree, tree, int, bool *); +static tree handle_format_arg_attribute (tree *, tree, tree, int, bool *); +static tree handle_format_attribute (tree *, tree, tree, int, bool *); +static tree handle_leaf_attribute (tree *, tree, tree, int, bool *); static tree handle_malloc_attribute (tree *, tree, tree, int, bool *); -static tree handle_pure_attribute (tree *, tree, tree, int, bool *); -static tree handle_novops_attribute (tree *, tree, tree, int, bool *); +static tree handle_noinline_attribute (tree *, tree, tree, int, bool *); static tree handle_nonnull_attribute (tree *, tree, tree, int, bool *); +static tree handle_noreturn_attribute (tree *, tree, tree, int, bool *); static tree handle_nothrow_attribute (tree *, tree, tree, int, bool *); -static tree handle_sentinel_attribute (tree *, tree, tree, int, bool *); -static tree handle_type_generic_attribute (tree *, tree, tree, int, bool *); -static tree handle_transaction_pure_attribute (tree *, tree, tree, int, bool *); -static tree handle_returns_twice_attribute (tree *, tree, tree, int, bool *); +static tree handle_novops_attribute (tree *, tree, tree, int, bool *); static tree handle_patchable_function_entry_attribute (tree *, tree, tree, int, bool *); -static tree ignore_attribute (tree *, tree, tree, int, bool *); +static tree handle_pure_attribute (tree *, tree, tree, int, bool *); +static tree handle_returns_twice_attribute (tree *, tree, tree, int, bool *); +static tree handle_sentinel_attribute (tree *, tree, tree, int, bool *); +static tree handle_target_attribute (tree *, tree, tree, int, bool *); +static tree handle_transaction_pure_attribute (tree *, tree, tree, int, bool *); +static tree handle_type_generic_attribute (tree *, tree, tree, int, bool *); +static tree handle_used_attribute (tree *, tree, tree, int, bool *); +static tree handle_visibility_attribute (tree *, tree, tree, int, + bool *); +static tree handle_weak_attribute (tree *, tree, tree, int, bool *) ; -static tree handle_format_attribute (tree *, tree, tree, int, bool *); -static tree handle_fnspec_attribute (tree *, tree, tree, int, bool *); -static tree handle_format_arg_attribute (tree *, tree, tree, int, bool *); +static tree ignore_attribute (tree *, tree, tree, int, bool *); /* Helper to define attribute exclusions. */ #define ATTR_EXCL(name, function, type, variable) \ @@ -61,7 +73,6 @@ static tree handle_format_arg_attribute (tree *, tree, tree, int, bool *); /* Define attributes that are mutually exclusive with one another. */ static const struct attribute_spec::exclusions attr_noreturn_exclusions[] = { - ATTR_EXCL ("noreturn", true, true, true), ATTR_EXCL ("alloc_align", true, true, true), ATTR_EXCL ("alloc_size", true, true, true), ATTR_EXCL ("const", true, true, true), @@ -78,57 +89,117 @@ static const struct attribute_spec::exclusions attr_returns_twice_exclusions[] = ATTR_EXCL (NULL, false, false, false), }; +/* Exclusions that apply to attribute alloc_align, alloc_size, and malloc. */ +static const struct attribute_spec::exclusions attr_alloc_exclusions[] = +{ + ATTR_EXCL ("const", true, true, true), + ATTR_EXCL ("noreturn", true, true, true), + ATTR_EXCL ("pure", true, true, true), + ATTR_EXCL (NULL, false, false, false), +}; + static const struct attribute_spec::exclusions attr_const_pure_exclusions[] = { ATTR_EXCL ("const", true, true, true), + ATTR_EXCL ("alloc_align", true, true, true), + ATTR_EXCL ("alloc_size", true, true, true), + ATTR_EXCL ("malloc", true, true, true), ATTR_EXCL ("noreturn", true, true, true), ATTR_EXCL ("pure", true, true, true), ATTR_EXCL (NULL, false, false, false) }; +static const struct attribute_spec::exclusions attr_always_inline_exclusions[] = +{ + ATTR_EXCL ("noinline", true, true, true), + ATTR_EXCL ("target_clones", true, true, true), + ATTR_EXCL (NULL, false, false, false), +}; + +extern const struct attribute_spec::exclusions attr_cold_hot_exclusions[] = +{ + ATTR_EXCL ("cold", true, true, true), + ATTR_EXCL ("hot", true, true, true), + ATTR_EXCL (NULL, false, false, false) +}; + +static const struct attribute_spec::exclusions attr_noinline_exclusions[] = +{ + ATTR_EXCL ("always_inline", true, true, true), + ATTR_EXCL ("gnu_inline", true, true, true), + ATTR_EXCL (NULL, false, false, false), +}; + +static const struct attribute_spec::exclusions attr_target_exclusions[] = +{ + ATTR_EXCL ("target_clones", TARGET_HAS_FMV_TARGET_ATTRIBUTE, + TARGET_HAS_FMV_TARGET_ATTRIBUTE, TARGET_HAS_FMV_TARGET_ATTRIBUTE), + ATTR_EXCL (NULL, false, false, false), +}; + /* Table of machine-independent attributes supported in libgccjit. */ static const attribute_spec jit_gnu_attributes[] = { /* { name, min_len, max_len, decl_req, type_req, fn_type_req, affects_type_identity, handler, exclude } */ - { "noreturn", 0, 0, true, false, false, false, - handle_noreturn_attribute, - attr_noreturn_exclusions }, - { "leaf", 0, 0, true, false, false, false, - handle_leaf_attribute, NULL }, + { "alias", 1, 1, true, false, false, false, + handle_alias_attribute, NULL }, + { "always_inline", 0, 0, true, false, false, false, + handle_always_inline_attribute, + attr_always_inline_exclusions }, + { "cold", 0, 0, true, false, false, false, + handle_cold_attribute, + attr_cold_hot_exclusions }, /* The same comments as for noreturn attributes apply to const ones. */ - { "const", 0, 0, true, false, false, false, + { "const", 0, 0, true, false, false, false, handle_const_attribute, attr_const_pure_exclusions }, - { "malloc", 0, 0, true, false, false, false, - handle_malloc_attribute, NULL }, - { "pure", 0, 0, true, false, false, false, - handle_pure_attribute, - attr_const_pure_exclusions }, - { "no vops", 0, 0, true, false, false, false, + { "fn spec", 1, 1, false, true, true, false, + handle_fnspec_attribute, NULL }, + + { "leaf", 0, 0, true, false, false, false, + handle_leaf_attribute, NULL }, + { "malloc", 0, 0, true, false, false, false, + handle_malloc_attribute, attr_alloc_exclusions }, + { "noreturn", 0, 0, true, false, false, false, + handle_noreturn_attribute, + attr_noreturn_exclusions }, + { "no vops", 0, 0, true, false, false, false, handle_novops_attribute, NULL }, - { "nonnull", 0, -1, false, true, true, false, + { "noinline", 0, 0, true, false, false, false, + handle_noinline_attribute, + attr_noinline_exclusions }, + { "nonnull", 0, -1, false, true, true, false, handle_nonnull_attribute, NULL }, - { "nothrow", 0, 0, true, false, false, false, + { "nothrow", 0, 0, true, false, false, false, handle_nothrow_attribute, NULL }, { "patchable_function_entry", 1, 2, true, false, false, false, handle_patchable_function_entry_attribute, NULL }, - { "returns_twice", 0, 0, true, false, false, false, + { "pure", 0, 0, true, false, false, false, + handle_pure_attribute, + attr_const_pure_exclusions }, + { "returns_twice", 0, 0, true, false, false, false, handle_returns_twice_attribute, attr_returns_twice_exclusions }, - { "sentinel", 0, 1, false, true, true, false, + { "sentinel", 0, 1, false, true, true, false, handle_sentinel_attribute, NULL }, - { "type generic", 0, 0, false, true, true, false, + { "target", 1, -1, true, false, false, false, + handle_target_attribute, attr_target_exclusions }, + { "type generic", 0, 0, false, true, true, false, handle_type_generic_attribute, NULL }, - { "fn spec", 1, 1, false, true, true, false, - handle_fnspec_attribute, NULL }, { "transaction_pure", 0, 0, false, true, true, false, handle_transaction_pure_attribute, NULL }, + { "used", 0, 0, true, false, false, false, + handle_used_attribute, NULL }, + { "visibility", 1, 1, false, false, false, false, + handle_visibility_attribute, NULL }, + { "weak", 0, 0, true, false, false, false, + handle_weak_attribute, NULL }, /* For internal use only. The leading '*' both prevents its usage in source code and signals that it may be overridden by machine tables. */ { "*tm regparm", 0, 0, false, true, true, false, - ignore_attribute, NULL } + ignore_attribute, NULL }, }; static const scoped_attribute_specs jit_gnu_attribute_table = @@ -143,7 +214,7 @@ static const attribute_spec jit_format_attributes[] = { /* { name, min_len, max_len, decl_req, type_req, fn_type_req, affects_type_identity, handler, exclude } */ - { "format", 3, 3, false, true, true, false, + { "format", 3, 3, false, true, true, false, handle_format_attribute, NULL }, { "format_arg", 1, 1, false, true, true, false, handle_format_arg_attribute, NULL } @@ -212,14 +283,9 @@ handle_leaf_attribute (tree *node, tree name, struct attribute_spec.handler. */ static tree -handle_const_attribute (tree *node, tree ARG_UNUSED (name), - tree ARG_UNUSED (args), int ARG_UNUSED (flags), - bool * ARG_UNUSED (no_add_attrs)) +handle_const_attribute (tree *node, tree name, tree ARG_UNUSED (args), + int ARG_UNUSED (flags), bool *no_add_attrs) { - if (TREE_CODE (*node) != FUNCTION_DECL - || !fndecl_built_in_p (*node)) - inform (UNKNOWN_LOCATION, "%s:%s: %E: %E", __FILE__, __func__, *node, name); - tree type = TREE_TYPE (*node); /* See FIXME comment on noreturn in c_common_attribute_table. */ @@ -228,11 +294,16 @@ handle_const_attribute (tree *node, tree ARG_UNUSED (name), else if (TREE_CODE (type) == POINTER_TYPE && TREE_CODE (TREE_TYPE (type)) == FUNCTION_TYPE) TREE_TYPE (*node) - = build_pointer_type - (build_type_variant (TREE_TYPE (type), 1, - TREE_THIS_VOLATILE (TREE_TYPE (type)))); + = (build_qualified_type + (build_pointer_type + (build_type_variant (TREE_TYPE (type), 1, + TREE_THIS_VOLATILE (TREE_TYPE (type)))), + TYPE_QUALS (type))); else - gcc_unreachable (); + { + warning (OPT_Wattributes, "%qE attribute ignored", name); + *no_add_attrs = true; + } return NULL_TREE; } @@ -494,6 +565,357 @@ handle_fnspec_attribute (tree *node ATTRIBUTE_UNUSED, tree ARG_UNUSED (name), return NULL_TREE; } +/* Handle an "visibility" attribute; arguments as in + struct attribute_spec.handler. */ + +static tree +handle_visibility_attribute (tree *node, tree name, tree args, + int ARG_UNUSED (flags), + bool *ARG_UNUSED (no_add_attrs)) +{ + tree decl = *node; + tree id = TREE_VALUE (args); + enum symbol_visibility vis; + + if (TYPE_P (*node)) + { + if (TREE_CODE (*node) == ENUMERAL_TYPE) + /* OK. */; + else if (!RECORD_OR_UNION_TYPE_P (*node)) + { + warning (OPT_Wattributes, "%qE attribute ignored on non-class types", + name); + return NULL_TREE; + } + else if (TYPE_FIELDS (*node)) + { + error ("%qE attribute ignored because %qT is already defined", + name, *node); + return NULL_TREE; + } + } + else if (decl_function_context (decl) != 0 || !TREE_PUBLIC (decl)) + { + warning (OPT_Wattributes, "%qE attribute ignored", name); + return NULL_TREE; + } + + if (TREE_CODE (id) != STRING_CST) + { + error ("visibility argument not a string"); + return NULL_TREE; + } + + /* If this is a type, set the visibility on the type decl. */ + if (TYPE_P (decl)) + { + decl = TYPE_NAME (decl); + if (!decl) + return NULL_TREE; + if (TREE_CODE (decl) == IDENTIFIER_NODE) + { + warning (OPT_Wattributes, "%qE attribute ignored on types", + name); + return NULL_TREE; + } + } + + if (strcmp (TREE_STRING_POINTER (id), "default") == 0) + vis = VISIBILITY_DEFAULT; + else if (strcmp (TREE_STRING_POINTER (id), "internal") == 0) + vis = VISIBILITY_INTERNAL; + else if (strcmp (TREE_STRING_POINTER (id), "hidden") == 0) + vis = VISIBILITY_HIDDEN; + else if (strcmp (TREE_STRING_POINTER (id), "protected") == 0) + vis = VISIBILITY_PROTECTED; + else + { + error ("attribute %qE argument must be one of %qs, %qs, %qs, or %qs", + name, "default", "hidden", "protected", "internal"); + vis = VISIBILITY_DEFAULT; + } + + if (DECL_VISIBILITY_SPECIFIED (decl) + && vis != DECL_VISIBILITY (decl)) + { + tree attributes = (TYPE_P (*node) + ? TYPE_ATTRIBUTES (*node) + : DECL_ATTRIBUTES (decl)); + if (lookup_attribute ("visibility", attributes)) + error ("%qD redeclared with different visibility", decl); + else if (TARGET_DLLIMPORT_DECL_ATTRIBUTES + && lookup_attribute ("dllimport", attributes)) + error ("%qD was declared %qs which implies default visibility", + decl, "dllimport"); + else if (TARGET_DLLIMPORT_DECL_ATTRIBUTES + && lookup_attribute ("dllexport", attributes)) + error ("%qD was declared %qs which implies default visibility", + decl, "dllexport"); + } + + DECL_VISIBILITY (decl) = vis; + DECL_VISIBILITY_SPECIFIED (decl) = 1; + + /* Go ahead and attach the attribute to the node as well. This is needed + so we can determine whether we have VISIBILITY_DEFAULT because the + visibility was not specified, or because it was explicitly overridden + from the containing scope. */ + + return NULL_TREE; +} + +/* Handle a "always_inline" attribute; arguments as in + struct attribute_spec.handler. */ + +static tree +handle_always_inline_attribute (tree *node, tree name, + tree ARG_UNUSED (args), + int ARG_UNUSED (flags), + bool *no_add_attrs) +{ + if (TREE_CODE (*node) == FUNCTION_DECL) + { + /* Set the attribute and mark it for disregarding inline + limits. */ + DECL_DISREGARD_INLINE_LIMITS (*node) = 1; + } + else + { + warning (OPT_Wattributes, "%qE attribute ignored", name); + *no_add_attrs = true; + } + + return NULL_TREE; +} + +/* Handle a "cold" and attribute; arguments as in + struct attribute_spec.handler. */ + +static tree +handle_cold_attribute (tree *node, tree name, tree ARG_UNUSED (args), + int ARG_UNUSED (flags), bool *no_add_attrs) +{ + if (TREE_CODE (*node) == FUNCTION_DECL + || TREE_CODE (*node) == LABEL_DECL) + { + /* Attribute cold processing is done later with lookup_attribute. */ + } + else + { + warning (OPT_Wattributes, "%qE attribute ignored", name); + *no_add_attrs = true; + } + + return NULL_TREE; +} + +/* Handle a "noinline" attribute; arguments as in + struct attribute_spec.handler. */ + +static tree +handle_noinline_attribute (tree *node, tree name, + tree ARG_UNUSED (args), + int ARG_UNUSED (flags), bool *no_add_attrs) +{ + if (TREE_CODE (*node) == FUNCTION_DECL) + DECL_UNINLINABLE (*node) = 1; + else + { + warning (OPT_Wattributes, "%qE attribute ignored", name); + *no_add_attrs = true; + } + + return NULL_TREE; +} + +/* Handle a "weak" attribute; arguments as in + struct attribute_spec.handler. */ + +static tree +handle_weak_attribute (tree *node, tree name, + tree ARG_UNUSED (args), + int ARG_UNUSED (flags), + bool * ARG_UNUSED (no_add_attrs)) +{ + if (TREE_CODE (*node) == FUNCTION_DECL + && DECL_DECLARED_INLINE_P (*node)) + { + warning (OPT_Wattributes, "inline function %q+D declared weak", *node); + *no_add_attrs = true; + } + else if (lookup_attribute ("ifunc", DECL_ATTRIBUTES (*node))) + { + error ("indirect function %q+D cannot be declared weak", *node); + *no_add_attrs = true; + return NULL_TREE; + } + else if (VAR_OR_FUNCTION_DECL_P (*node)) + declare_weak (*node); + else + warning (OPT_Wattributes, "%qE attribute ignored", name); + + return NULL_TREE; +} + +/* Handle a "target" attribute. */ + +static tree +handle_target_attribute (tree *node, tree name, tree args, int flags, + bool *no_add_attrs) +{ + /* Ensure we have a function declaration. */ + if (TREE_CODE (*node) != FUNCTION_DECL) + { + warning (OPT_Wattributes, "%qE attribute ignored", name); + *no_add_attrs = true; + } + else if (! targetm.target_option.valid_attribute_p (*node, name, args, + flags)) + *no_add_attrs = true; + + /* Check that there's no empty string in values of the attribute. */ + for (tree t = args; t != NULL_TREE; t = TREE_CHAIN (t)) + { + tree value = TREE_VALUE (t); + if (TREE_CODE (value) == STRING_CST + && TREE_STRING_LENGTH (value) == 1 + && TREE_STRING_POINTER (value)[0] == '\0') + { + warning (OPT_Wattributes, "empty string in attribute %<target%>"); + *no_add_attrs = true; + } + } + + return NULL_TREE; +} + +/* Handle a "used" attribute; arguments as in + struct attribute_spec.handler. */ + +static tree +handle_used_attribute (tree *pnode, tree name, tree ARG_UNUSED (args), + int ARG_UNUSED (flags), bool *no_add_attrs) +{ + tree node = *pnode; + + if (TREE_CODE (node) == FUNCTION_DECL + || (VAR_P (node) && TREE_STATIC (node)) + || (TREE_CODE (node) == TYPE_DECL)) + { + TREE_USED (node) = 1; + DECL_PRESERVE_P (node) = 1; + if (VAR_P (node)) + DECL_READ_P (node) = 1; + } + else + { + warning (OPT_Wattributes, "%qE attribute ignored", name); + *no_add_attrs = true; + } + + return NULL_TREE; +} + +/* Handle an "alias" or "ifunc" attribute; arguments as in + struct attribute_spec.handler, except that IS_ALIAS tells us + whether this is an alias as opposed to ifunc attribute. */ + +static tree +handle_alias_ifunc_attribute (bool is_alias, tree *node, tree name, tree args, + bool *no_add_attrs) +{ + tree decl = *node; + + if (TREE_CODE (decl) != FUNCTION_DECL + && (!is_alias || !VAR_P (decl))) + { + warning (OPT_Wattributes, "%qE attribute ignored", name); + *no_add_attrs = true; + } + else if ((TREE_CODE (decl) == FUNCTION_DECL && DECL_INITIAL (decl)) + || (TREE_CODE (decl) != FUNCTION_DECL + && TREE_PUBLIC (decl) && !DECL_EXTERNAL (decl)) + /* A static variable declaration is always a tentative definition, + but the alias is a non-tentative definition which overrides. */ + || (TREE_CODE (decl) != FUNCTION_DECL + && ! TREE_PUBLIC (decl) && DECL_INITIAL (decl))) + { + error ("%q+D defined both normally and as %qE attribute", decl, name); + *no_add_attrs = true; + return NULL_TREE; + } + else if (!is_alias + && (lookup_attribute ("weak", DECL_ATTRIBUTES (decl)) + || lookup_attribute ("weakref", DECL_ATTRIBUTES (decl)))) + { + error ("weak %q+D cannot be defined %qE", decl, name); + *no_add_attrs = true; + return NULL_TREE; + } + + /* Note that the very first time we process a nested declaration, + decl_function_context will not be set. Indeed, *would* never + be set except for the DECL_INITIAL/DECL_EXTERNAL frobbery that + we do below. After such frobbery, pushdecl would set the context. + In any case, this is never what we want. */ + else if (decl_function_context (decl) == 0 && current_function_decl == NULL) + { + tree id; + + id = TREE_VALUE (args); + if (TREE_CODE (id) != STRING_CST) + { + error ("attribute %qE argument not a string", name); + *no_add_attrs = true; + return NULL_TREE; + } + id = get_identifier (TREE_STRING_POINTER (id)); + /* This counts as a use of the object pointed to. */ + TREE_USED (id) = 1; + + if (TREE_CODE (decl) == FUNCTION_DECL) + DECL_INITIAL (decl) = error_mark_node; + else + TREE_STATIC (decl) = 1; + + if (!is_alias) + { + /* ifuncs are also aliases, so set that attribute too. */ + DECL_ATTRIBUTES (decl) + = tree_cons (get_identifier ("alias"), args, + DECL_ATTRIBUTES (decl)); + DECL_ATTRIBUTES (decl) = tree_cons (get_identifier ("ifunc"), + NULL, DECL_ATTRIBUTES (decl)); + } + } + else + { + warning (OPT_Wattributes, "%qE attribute ignored", name); + *no_add_attrs = true; + } + + if (decl_in_symtab_p (*node)) + { + struct symtab_node *n = symtab_node::get (decl); + if (n && n->refuse_visibility_changes) + error ("%+qD declared %qs after being used", + decl, is_alias ? "alias" : "ifunc"); + } + + + return NULL_TREE; +} + +/* Handle an "alias" or "ifunc" attribute; arguments as in + struct attribute_spec.handler. */ + +static tree +handle_alias_attribute (tree *node, tree name, tree args, + int ARG_UNUSED (flags), bool *no_add_attrs) +{ + return handle_alias_ifunc_attribute (true, node, name, args, no_add_attrs); +} + /* (end of attribute-handling). */ /* Language-dependent contents of a type. */ diff --git a/gcc/jit/jit-playback.cc b/gcc/jit/jit-playback.cc index f87351e..84df6c1 100644 --- a/gcc/jit/jit-playback.cc +++ b/gcc/jit/jit-playback.cc @@ -20,6 +20,7 @@ along with GCC; see the file COPYING3. If not see #include "config.h" #define INCLUDE_MUTEX +#include "libgccjit.h" #include "system.h" #include "coretypes.h" #include "target.h" @@ -499,6 +500,54 @@ new_param (location *loc, return new param (this, inner); } +const char* fn_attribute_to_string (gcc_jit_fn_attribute attr) +{ + switch (attr) + { + case GCC_JIT_FN_ATTRIBUTE_ALIAS: + return "alias"; + case GCC_JIT_FN_ATTRIBUTE_ALWAYS_INLINE: + return "always_inline"; + case GCC_JIT_FN_ATTRIBUTE_INLINE: + return NULL; + case GCC_JIT_FN_ATTRIBUTE_NOINLINE: + return "noinline"; + case GCC_JIT_FN_ATTRIBUTE_TARGET: + return "target"; + case GCC_JIT_FN_ATTRIBUTE_USED: + return "used"; + case GCC_JIT_FN_ATTRIBUTE_VISIBILITY: + return "visibility"; + case GCC_JIT_FN_ATTRIBUTE_COLD: + return "cold"; + case GCC_JIT_FN_ATTRIBUTE_RETURNS_TWICE: + return "returns_twice"; + case GCC_JIT_FN_ATTRIBUTE_PURE: + return "pure"; + case GCC_JIT_FN_ATTRIBUTE_CONST: + return "const"; + case GCC_JIT_FN_ATTRIBUTE_WEAK: + return "weak"; + case GCC_JIT_FN_ATTRIBUTE_NONNULL: + return "nonnull"; + case GCC_JIT_FN_ATTRIBUTE_MAX: + return NULL; + } + return NULL; +} + +const char* variable_attribute_to_string (gcc_jit_variable_attribute attr) +{ + switch (attr) + { + case GCC_JIT_VARIABLE_ATTRIBUTE_VISIBILITY: + return "visibility"; + case GCC_JIT_VARIABLE_ATTRIBUTE_MAX: + return NULL; + } + return NULL; +} + /* Construct a playback::function instance. */ playback::function * @@ -509,7 +558,13 @@ new_function (location *loc, const char *name, const auto_vec<param *> *params, int is_variadic, - enum built_in_function builtin_id) + enum built_in_function builtin_id, + const std::vector<gcc_jit_fn_attribute> &attributes, + const std::vector<std::pair<gcc_jit_fn_attribute, + std::string>> &string_attributes, + const std::vector<std::pair<gcc_jit_fn_attribute, + std::vector<int>>> + &int_array_attributes) { int i; param *param; @@ -543,6 +598,8 @@ new_function (location *loc, DECL_RESULT (fndecl) = resdecl; DECL_CONTEXT (resdecl) = fndecl; + tree fn_attributes = NULL_TREE; + if (builtin_id) { gcc_assert (loc == NULL); @@ -588,12 +645,62 @@ new_function (location *loc, DECL_DECLARED_INLINE_P (fndecl) = 1; /* Add attribute "always_inline": */ - DECL_ATTRIBUTES (fndecl) = - tree_cons (get_identifier ("always_inline"), - NULL, - DECL_ATTRIBUTES (fndecl)); + fn_attributes = tree_cons (get_identifier ("always_inline"), + NULL, + fn_attributes); } + /* All attributes need to be declared in `dummy-frontend.cc` and more + specifically in `jit_attribute_table`. */ + for (auto attr: attributes) + { + if (attr == GCC_JIT_FN_ATTRIBUTE_INLINE) + DECL_DECLARED_INLINE_P (fndecl) = 1; + + const char* attribute = fn_attribute_to_string (attr); + if (attribute) + { + tree ident = get_identifier (attribute); + fn_attributes = tree_cons (ident, NULL_TREE, fn_attributes); + } + } + + for (auto attr: string_attributes) + { + gcc_jit_fn_attribute& name = std::get<0>(attr); + std::string& value = std::get<1>(attr); + tree attribute_value = build_tree_list (NULL_TREE, + ::build_string (value.length () + 1, value.c_str ())); + const char* attribute = fn_attribute_to_string (name); + tree ident = attribute ? get_identifier (attribute) : NULL; + + if (ident) + fn_attributes = tree_cons (ident, attribute_value, fn_attributes); + } + + for (auto attr: int_array_attributes) + { + gcc_jit_fn_attribute& name = std::get<0>(attr); + std::vector<int>& values = std::get<1>(attr); + + const char* attribute = fn_attribute_to_string (name); + tree ident = attribute ? get_identifier (attribute) : NULL; + + if (!ident) + continue; + + tree tree_list = NULL_TREE; + tree *p_tree_list = &tree_list; + for (auto value : values) + { + tree int_value = build_int_cst (integer_type_node, value); + *p_tree_list = build_tree_list (NULL, int_value); + p_tree_list = &TREE_CHAIN (*p_tree_list); + } + fn_attributes = tree_cons (ident, tree_list, fn_attributes); + } + + decl_attributes (&fndecl, fn_attributes, 0); function *func = new function (this, fndecl, kind); m_functions.safe_push (func); return func; @@ -607,7 +714,9 @@ global_new_decl (location *loc, enum gcc_jit_global_kind kind, type *type, const char *name, - enum global_var_flags flags) + enum global_var_flags flags, + const std::vector<std::pair<gcc_jit_variable_attribute, + std::string>> &attributes) { gcc_assert (type); gcc_assert (name); @@ -652,9 +761,32 @@ global_new_decl (location *loc, if (loc) set_tree_location (inner, loc); + set_variable_string_attribute (attributes, inner); + return inner; } +void +playback:: +set_variable_string_attribute ( + const std::vector<std::pair<gcc_jit_variable_attribute, + std::string>> &string_attributes, + tree decl) +{ + tree var_attributes = NULL_TREE; + for (auto attr: string_attributes) + { + gcc_jit_variable_attribute& name = std::get<0>(attr); + std::string& value = std::get<1>(attr); + tree attribute_value = build_tree_list (NULL_TREE, + ::build_string (value.length () + 1, value.c_str ())); + tree ident = get_identifier (variable_attribute_to_string (name)); + if (ident) + var_attributes = tree_cons (ident, attribute_value, var_attributes); + } + decl_attributes (&decl, var_attributes, 0); +} + /* In use by new_global and new_global_initialized. */ playback::lvalue * @@ -674,10 +806,12 @@ new_global (location *loc, enum gcc_jit_global_kind kind, type *type, const char *name, - enum global_var_flags flags) + enum global_var_flags flags, + const std::vector<std::pair<gcc_jit_variable_attribute, + std::string>> &attributes) { tree inner = - global_new_decl (loc, kind, type, name, flags); + global_new_decl (loc, kind, type, name, flags, attributes); return global_finalize_lvalue (inner); } @@ -818,13 +952,15 @@ playback::context:: new_global_initialized (location *loc, enum gcc_jit_global_kind kind, type *type, - size_t element_size, + size_t element_size, size_t initializer_num_elem, const void *initializer, const char *name, - enum global_var_flags flags) + enum global_var_flags flags, + const std::vector<std::pair<gcc_jit_variable_attribute, + std::string>> &attributes) { - tree inner = global_new_decl (loc, kind, type, name, flags); + tree inner = global_new_decl (loc, kind, type, name, flags, attributes); vec<constructor_elt, va_gc> *constructor_elements = NULL; @@ -1812,7 +1948,9 @@ playback::lvalue * playback::function:: new_local (location *loc, type *type, - const char *name) + const char *name, + const std::vector<std::pair<gcc_jit_variable_attribute, + std::string>> &attributes) { gcc_assert (type); gcc_assert (name); @@ -1825,6 +1963,8 @@ new_local (location *loc, DECL_CHAIN (inner) = BIND_EXPR_VARS (m_inner_bind_expr); BIND_EXPR_VARS (m_inner_bind_expr) = inner; + set_variable_string_attribute (attributes, inner); + if (loc) set_tree_location (inner, loc); return new lvalue (m_ctxt, inner); @@ -1947,6 +2087,9 @@ postprocess () current_function_decl = NULL; } + else + /* Add to cgraph to output aliases: */ + rest_of_decl_compilation (m_inner_fndecl, true, 0); } /* Don't leak vec's internal buffer (in non-GC heap) when we are @@ -3365,7 +3508,7 @@ void playback::context:: init_types () { - /* See lto_init() in lto-lang.cc or void visit (TypeBasic *t) in D's types.cc + /* See lto_init () in lto-lang.cc or void visit (TypeBasic *t) in D's types.cc for reference. If TYPE_NAME is not set, debug info will not contain types */ #define NAME_TYPE(t,n) \ if (t) \ diff --git a/gcc/jit/jit-playback.h b/gcc/jit/jit-playback.h index 9654507..05bafcd 100644 --- a/gcc/jit/jit-playback.h +++ b/gcc/jit/jit-playback.h @@ -21,7 +21,9 @@ along with GCC; see the file COPYING3. If not see #ifndef JIT_PLAYBACK_H #define JIT_PLAYBACK_H +#include <string> #include <utility> // for std::pair +#include <vector> #include "timevar.h" #include "varasm.h" @@ -35,12 +37,21 @@ namespace gcc { namespace jit { +const char* fn_attribute_to_string (gcc_jit_fn_attribute attr); +const char* variable_attribute_to_string (gcc_jit_variable_attribute attr); + /********************************************************************** Playback. **********************************************************************/ namespace playback { +void +set_variable_string_attribute ( + const std::vector<std::pair<gcc_jit_variable_attribute, + std::string>> &attributes, + tree decl); + /* playback::context is an abstract base class. The two concrete subclasses are: @@ -104,14 +115,22 @@ public: const char *name, const auto_vec<param *> *params, int is_variadic, - enum built_in_function builtin_id); + enum built_in_function builtin_id, + const std::vector<gcc_jit_fn_attribute> &attributes, + const std::vector<std::pair<gcc_jit_fn_attribute, + std::string>> &string_attributes, + const std::vector<std::pair<gcc_jit_fn_attribute, + std::vector<int>>> + &int_array_attributes); lvalue * new_global (location *loc, enum gcc_jit_global_kind kind, type *type, const char *name, - enum global_var_flags flags); + enum global_var_flags flags, + const std::vector<std::pair<gcc_jit_variable_attribute, + std::string>> &attributes); lvalue * new_global_initialized (location *loc, @@ -121,7 +140,11 @@ public: size_t initializer_num_elem, const void *initializer, const char *name, - enum global_var_flags flags); + enum global_var_flags flags, + const std::vector<std::pair< + gcc_jit_variable_attribute, + std::string>> + &attributes); rvalue * new_ctor (location *log, @@ -306,7 +329,9 @@ private: enum gcc_jit_global_kind kind, type *type, const char *name, - enum global_var_flags flags); + enum global_var_flags flags, + const std::vector<std::pair<gcc_jit_variable_attribute, + std::string>> &attributes); lvalue * global_finalize_lvalue (tree inner); @@ -500,7 +525,9 @@ public: lvalue * new_local (location *loc, type *type, - const char *name); + const char *name, + const std::vector<std::pair<gcc_jit_variable_attribute, + std::string>> &attributes); block* new_block (const char *name); diff --git a/gcc/jit/jit-recording.cc b/gcc/jit/jit-recording.cc index 686c058..6ffadbe 100644 --- a/gcc/jit/jit-recording.cc +++ b/gcc/jit/jit-recording.cc @@ -29,6 +29,7 @@ along with GCC; see the file COPYING3. If not see #include "jit-builtins.h" #include "jit-recording.h" #include "jit-playback.h" +#include <sstream> namespace gcc { namespace jit { @@ -2068,7 +2069,7 @@ recording::memento::get_debug_string () void recording::memento::write_to_dump (dump &d) { - d.write(" %s\n", get_debug_string ()); + d.write (" %s\n", get_debug_string ()); } /* The implementation of class gcc::jit::recording::string. */ @@ -4026,6 +4027,13 @@ void recording::lvalue::set_alignment (unsigned bytes) m_alignment = bytes; } +void recording::lvalue::add_string_attribute ( + gcc_jit_variable_attribute attribute, + const char* value) +{ + m_string_attributes.push_back (std::make_pair (attribute, std::string (value))); +} + /* The implementation of class gcc::jit::recording::param. */ /* Implementation of pure virtual hook recording::memento::replay_into @@ -4102,7 +4110,10 @@ recording::function::function (context *ctxt, m_builtin_id (builtin_id), m_locals (), m_blocks (), - m_fn_ptr_type (NULL) + m_fn_ptr_type (NULL), + m_attributes (), + m_string_attributes (), + m_int_array_attributes () { for (int i = 0; i< num_params; i++) { @@ -4161,7 +4172,10 @@ recording::function::replay_into (replayer *r) m_name->c_str (), ¶ms, m_is_variadic, - m_builtin_id)); + m_builtin_id, + m_attributes, + m_string_attributes, + m_int_array_attributes)); } /* Create a recording::local instance and add it to @@ -4210,6 +4224,40 @@ recording::function::new_block (const char *name) void recording::function::write_to_dump (dump &d) { + for (auto attr: m_attributes) + { + const char* attribute = fn_attribute_to_string (attr); + if (attribute) + d.write ("__attribute(%s)__\n", attribute); + } + for (auto attr: m_string_attributes) + { + gcc_jit_fn_attribute& name = std::get<0>(attr); + std::string& value = std::get<1>(attr); + const char* attribute = fn_attribute_to_string (name); + + if (attribute) + d.write ("__attribute(%s(\"%s\"))__\n", attribute, value.c_str()); + } + for (auto attr: m_int_array_attributes) + { + gcc_jit_fn_attribute& name = std::get<0>(attr); + std::vector<int>& values = std::get<1>(attr); + const char* attribute = fn_attribute_to_string (name); + if (attribute) + { + d.write ("__attribute(%s(", attribute); + for (size_t i = 0; i < values.size(); ++i) + { + if (i > 0) + d.write (", %d", values[i]); + else + d.write ("%d", values[i]); + } + d.write ("))__\n"); + } + } + switch (m_kind) { default: gcc_unreachable (); @@ -4404,6 +4452,31 @@ recording::function::get_address (recording::location *loc) return result; } +void +recording::function::add_attribute (gcc_jit_fn_attribute attribute) +{ + m_attributes.push_back (attribute); +} + +void +recording::function::add_string_attribute (gcc_jit_fn_attribute attribute, + const char* value) +{ + m_string_attributes.push_back ( + std::make_pair (attribute, std::string (value))); +} + +void +recording::function::add_integer_array_attribute ( + gcc_jit_fn_attribute attribute, + const int* value, + size_t length) +{ + m_int_array_attributes.push_back (std::make_pair ( + attribute, + std::vector<int> (value, value + length))); +} + /* Implementation of recording::memento::make_debug_string for functions. */ @@ -4425,6 +4498,39 @@ static const char * const names_of_function_kinds[] = { /* Implementation of recording::memento::write_reproducer for functions. */ +static const char * const fn_attribute_reproducer_strings[] = +{ + "GCC_JIT_FN_ATTRIBUTE_ALIAS", + "GCC_JIT_FN_ATTRIBUTE_ALWAYS_INLINE", + "GCC_JIT_FN_ATTRIBUTE_INLINE", + "GCC_JIT_FN_ATTRIBUTE_NOINLINE", + "GCC_JIT_FN_ATTRIBUTE_TARGET", + "GCC_JIT_FN_ATTRIBUTE_USED", + "GCC_JIT_FN_ATTRIBUTE_VISIBILITY", + "GCC_JIT_FN_ATTRIBUTE_COLD", + "GCC_JIT_FN_ATTRIBUTE_RETURNS_TWICE", + "GCC_JIT_FN_ATTRIBUTE_PURE", + "GCC_JIT_FN_ATTRIBUTE_CONST", + "GCC_JIT_FN_ATTRIBUTE_WEAK", + "GCC_JIT_FN_ATTRIBUTE_NONNULL", +}; + +std::string +get_vector_int_debug (std::vector<int> &values) +{ + std::stringstream s; + + s << "{"; + for(auto it = values.begin(); it != values.end(); ++it) + { + if (it != values.begin() ) + s << ", "; + s << *it; + } + s << "}"; + return s.str(); +} + void recording::function::write_reproducer (reproducer &r) { @@ -4467,6 +4573,25 @@ recording::function::write_reproducer (reproducer &r) m_params.length (), params_id, m_is_variadic); + for (auto attribute : m_attributes) + r.write(" gcc_jit_function_add_attribute (%s, %s);\n", + id, + fn_attribute_reproducer_strings[attribute]); + for (auto attribute : m_string_attributes) + r.write(" gcc_jit_function_add_string_attribute (%s, %s, \"%s\");\n", + id, + fn_attribute_reproducer_strings[std::get<0>(attribute)], + std::get<1>(attribute).c_str()); + for (auto attribute : m_int_array_attributes) { + r.write(" gcc_jit_function_add_integer_array_attribute (%s,\n" + " %s,\n" + " (int[])%s,\n" + " %lu);\n", + id, + fn_attribute_reproducer_strings[std::get<0>(attribute)], + get_vector_int_debug (std::get<1>(attribute)).c_str(), + std::get<1>(attribute).size ()); + } } @@ -4879,12 +5004,14 @@ recording::global::replay_into (replayer *r) / m_type->dereference ()->get_size (), m_initializer, playback_string (m_name), - m_flags) + m_flags, + m_string_attributes) : r->new_global (playback_location (r, m_loc), m_kind, m_type->playback_type (), playback_string (m_name), - m_flags); + m_flags, + m_string_attributes); if (m_tls_model != GCC_JIT_TLS_MODEL_NONE) global->set_tls_model (recording::tls_models[m_tls_model]); @@ -4943,6 +5070,15 @@ recording::global::write_to_dump (dump &d) break; } + for (auto attr: m_string_attributes) + { + gcc_jit_variable_attribute& name = std::get<0>(attr); + std::string& value = std::get<1>(attr); + const char* attribute = variable_attribute_to_string (name); + + if (attribute) + d.write ("__attribute(%s(\"%s\"))__\n", attribute, value.c_str()); + } d.write ("%s %s", m_type->get_debug_string (), get_debug_string ()); @@ -5013,6 +5149,10 @@ static const char * const tls_model_enum_strings[] = { "GCC_JIT_TLS_MODEL_LOCAL_EXEC", }; +static const char * const gcc_jit_variable_attribute_enum_strings[] = { + "GCC_JIT_VARIABLE_ATTRIBUTE_VISIBILITY", +}; + void recording::global::write_reproducer (reproducer &r) { @@ -5042,6 +5182,13 @@ recording::global::write_reproducer (reproducer &r) id, m_link_section->c_str ()); + for (auto attribute : m_string_attributes) + r.write(" gcc_jit_lvalue_add_string_attribute (%s, %s, \"%s\");\n", + id, + gcc_jit_variable_attribute_enum_strings[std::get<0>(attribute)], + std::get<1>(attribute).c_str()); + + if (m_initializer) switch (m_type->dereference ()->get_size ()) { @@ -6622,7 +6769,8 @@ recording::local::replay_into (replayer *r) playback::lvalue *obj = m_func->playback_function () ->new_local (playback_location (r, m_loc), m_type->playback_type (), - playback_string (m_name)); + playback_string (m_name), + m_string_attributes); if (m_reg_name != NULL) obj->set_register_name (m_reg_name->c_str ()); @@ -6644,9 +6792,9 @@ recording::local::write_to_dump (dump &d) { if (d.update_locations ()) m_loc = d.make_location (); - d.write(" %s %s;\n", - m_type->get_debug_string (), - get_debug_string ()); + d.write (" %s %s;\n", + m_type->get_debug_string (), + get_debug_string ()); } void diff --git a/gcc/jit/jit-recording.h b/gcc/jit/jit-recording.h index b951c71..cd2e0ad 100644 --- a/gcc/jit/jit-recording.h +++ b/gcc/jit/jit-recording.h @@ -23,6 +23,10 @@ along with GCC; see the file COPYING3. If not see #include "jit-common.h" #include "jit-logging.h" +#include "libgccjit.h" + +#include <string> +#include <vector> class timer; @@ -1216,7 +1220,8 @@ public: m_link_section (NULL), m_reg_name (NULL), m_tls_model (GCC_JIT_TLS_MODEL_NONE), - m_alignment (0) + m_alignment (0), + m_string_attributes () {} playback::lvalue * @@ -1236,8 +1241,12 @@ public: as_rvalue () { return this; } const char *access_as_rvalue (reproducer &r) override; + + void add_string_attribute (gcc_jit_variable_attribute attribute, const char* value); + virtual const char *access_as_lvalue (reproducer &r); virtual bool is_global () const { return false; } + virtual bool is_local () const { return false; } void set_tls_model (enum gcc_jit_tls_model model); void set_link_section (const char *name); void set_register_name (const char *reg_name); @@ -1249,6 +1258,8 @@ protected: string *m_reg_name; enum gcc_jit_tls_model m_tls_model; unsigned m_alignment; + std::vector<std::pair<gcc_jit_variable_attribute, + std::string>> m_string_attributes; }; class param : public lvalue @@ -1342,6 +1353,10 @@ public: rvalue *get_address (location *loc); + void add_attribute (gcc_jit_fn_attribute attribute); + void add_string_attribute (gcc_jit_fn_attribute attribute, const char* value); + void add_integer_array_attribute (gcc_jit_fn_attribute attribute, const int* value, size_t length); + private: string * make_debug_string () final override; void write_reproducer (reproducer &r) final override; @@ -1357,6 +1372,9 @@ private: auto_vec<local *> m_locals; auto_vec<block *> m_blocks; type *m_fn_ptr_type; + std::vector<gcc_jit_fn_attribute> m_attributes; + std::vector<std::pair<gcc_jit_fn_attribute, std::string>> m_string_attributes; + std::vector<std::pair<gcc_jit_fn_attribute, std::vector<int>>> m_int_array_attributes; }; class block : public memento @@ -2086,6 +2104,8 @@ public: void visit_children (rvalue_visitor *) final override {} + bool is_local () const final override { return true; } + void write_to_dump (dump &d) final override; private: diff --git a/gcc/jit/libgccjit.cc b/gcc/jit/libgccjit.cc index 8ecfe4a..9616f38 100644 --- a/gcc/jit/libgccjit.cc +++ b/gcc/jit/libgccjit.cc @@ -3965,6 +3965,73 @@ gcc_jit_type_get_aligned (gcc_jit_type *type, return (gcc_jit_type *)type->get_aligned (alignment_in_bytes); } +void +gcc_jit_function_add_attribute (gcc_jit_function *func, + gcc_jit_fn_attribute attribute) +{ + RETURN_IF_FAIL (func, NULL, NULL, "NULL func"); + RETURN_IF_FAIL ((attribute >= 0 && attribute < GCC_JIT_FN_ATTRIBUTE_MAX), + NULL, + NULL, + "attribute should be a `gcc_jit_fn_attribute` enum value"); + + func->add_attribute (attribute); +} + +void +gcc_jit_function_add_string_attribute (gcc_jit_function *func, + gcc_jit_fn_attribute attribute, + const char* value) +{ + RETURN_IF_FAIL (func, NULL, NULL, "NULL func"); + RETURN_IF_FAIL (value, NULL, NULL, "NULL value"); + RETURN_IF_FAIL ((attribute >= 0 && attribute < GCC_JIT_FN_ATTRIBUTE_MAX), + NULL, + NULL, + "attribute should be a `gcc_jit_fn_attribute` enum value"); + + func->add_string_attribute (attribute, value); +} + +/* This function adds an attribute with multiple integer values. For example + `nonnull(1, 2)`. The numbers in `values` are supposed to map how they + should be written in C code. So for `nonnull(1, 2)`, you should pass `1` + and `2` in `values` (and set `length` to `2`). */ +void +gcc_jit_function_add_integer_array_attribute (gcc_jit_function *func, + gcc_jit_fn_attribute attribute, + const int* values, + size_t length) +{ + RETURN_IF_FAIL (func, NULL, NULL, "NULL func"); + RETURN_IF_FAIL (values, NULL, NULL, "NULL values"); + RETURN_IF_FAIL ((attribute >= 0 && attribute < GCC_JIT_FN_ATTRIBUTE_MAX), + NULL, + NULL, + "attribute should be a `gcc_jit_fn_attribute` enum value"); + + func->add_integer_array_attribute (attribute, values, length); +} + +void +gcc_jit_lvalue_add_string_attribute (gcc_jit_lvalue *variable, + gcc_jit_variable_attribute attribute, + const char* value) +{ + RETURN_IF_FAIL (variable, NULL, NULL, "NULL variable"); + RETURN_IF_FAIL (value, NULL, NULL, "NULL value"); + RETURN_IF_FAIL (variable->is_global () || variable->is_local (), + NULL, + NULL, + "variable should be a variable"); + RETURN_IF_FAIL ((attribute >= 0 && attribute < GCC_JIT_VARIABLE_ATTRIBUTE_MAX), + NULL, + NULL, + "attribute should be a `gcc_jit_variable_attribute` enum value"); + + variable->add_string_attribute (attribute, value); +} + /* Public entrypoint. See description in libgccjit.h. After error-checking, the real work is done by the diff --git a/gcc/jit/libgccjit.h b/gcc/jit/libgccjit.h index cbcfabb..235cab0 100644 --- a/gcc/jit/libgccjit.h +++ b/gcc/jit/libgccjit.h @@ -1999,6 +1999,61 @@ gcc_jit_vector_type_get_element_type (gcc_jit_vector_type *vector_type); extern gcc_jit_type * gcc_jit_type_unqualified (gcc_jit_type *type); +#define LIBGCCJIT_HAVE_ATTRIBUTES + +/* Function attributes. */ +enum gcc_jit_fn_attribute +{ + GCC_JIT_FN_ATTRIBUTE_ALIAS, + GCC_JIT_FN_ATTRIBUTE_ALWAYS_INLINE, + GCC_JIT_FN_ATTRIBUTE_INLINE, + GCC_JIT_FN_ATTRIBUTE_NOINLINE, + GCC_JIT_FN_ATTRIBUTE_TARGET, + GCC_JIT_FN_ATTRIBUTE_USED, + GCC_JIT_FN_ATTRIBUTE_VISIBILITY, + GCC_JIT_FN_ATTRIBUTE_COLD, + GCC_JIT_FN_ATTRIBUTE_RETURNS_TWICE, + GCC_JIT_FN_ATTRIBUTE_PURE, + GCC_JIT_FN_ATTRIBUTE_CONST, + GCC_JIT_FN_ATTRIBUTE_WEAK, + GCC_JIT_FN_ATTRIBUTE_NONNULL, + + /* Maximum value of this enum, should always be last. */ + GCC_JIT_FN_ATTRIBUTE_MAX, +}; + +/* Add an attribute to a function. */ +extern void +gcc_jit_function_add_attribute (gcc_jit_function *func, + enum gcc_jit_fn_attribute attribute); + +extern void +gcc_jit_function_add_string_attribute (gcc_jit_function *func, + enum gcc_jit_fn_attribute attribute, + const char* value); + +extern void +gcc_jit_function_add_integer_array_attribute ( + gcc_jit_function *func, + enum gcc_jit_fn_attribute attribute, + const int* value, + size_t length); + +/* Variable attributes. */ +enum gcc_jit_variable_attribute +{ + GCC_JIT_VARIABLE_ATTRIBUTE_VISIBILITY, + + /* Maximum value of this enum, should always be last. */ + GCC_JIT_VARIABLE_ATTRIBUTE_MAX, +}; + +/* Add a string attribute to a variable. */ +extern void +gcc_jit_lvalue_add_string_attribute (gcc_jit_lvalue *variable, + enum gcc_jit_variable_attribute attribute, + const char* value); + #ifdef __cplusplus } #endif /* __cplusplus */ diff --git a/gcc/jit/libgccjit.map b/gcc/jit/libgccjit.map index b62f5de..dfb8a9d 100644 --- a/gcc/jit/libgccjit.map +++ b/gcc/jit/libgccjit.map @@ -276,3 +276,11 @@ LIBGCCJIT_ABI_25 { global: gcc_jit_type_get_restrict; } LIBGCCJIT_ABI_24; + +LIBGCCJIT_ABI_26 { + global: + gcc_jit_function_add_attribute; + gcc_jit_function_add_string_attribute; + gcc_jit_lvalue_add_string_attribute; + gcc_jit_function_add_integer_array_attribute; +} LIBGCCJIT_ABI_25; diff --git a/gcc/loop-unroll.cc b/gcc/loop-unroll.cc index 4176a21..bfdfe6c 100644 --- a/gcc/loop-unroll.cc +++ b/gcc/loop-unroll.cc @@ -1855,7 +1855,7 @@ insert_var_expansion_initialization (struct var_to_expand *ve, rtx var, zero_init; unsigned i; machine_mode mode = GET_MODE (ve->reg); - bool honor_signed_zero_p = HONOR_SIGNED_ZEROS (mode); + bool has_signed_zero_p = MODE_HAS_SIGNED_ZEROS (mode); if (ve->var_expansions.length () == 0) return; @@ -1869,7 +1869,7 @@ insert_var_expansion_initialization (struct var_to_expand *ve, case MINUS: FOR_EACH_VEC_ELT (ve->var_expansions, i, var) { - if (honor_signed_zero_p) + if (has_signed_zero_p) zero_init = simplify_gen_unary (NEG, mode, CONST0_RTX (mode), mode); else zero_init = CONST0_RTX (mode); diff --git a/gcc/lra-constraints.cc b/gcc/lra-constraints.cc index 3ffeb9c..3379b88 100644 --- a/gcc/lra-constraints.cc +++ b/gcc/lra-constraints.cc @@ -261,6 +261,13 @@ enough_allocatable_hard_regs_p (enum reg_class reg_class, return false; } +/* True if C is a non-empty register class that has too few registers + to be safely used as a reload target class. */ +#define SMALL_REGISTER_CLASS_P(C) \ + (ira_class_hard_regs_num [(C)] == 1 \ + || (ira_class_hard_regs_num [(C)] >= 1 \ + && targetm.class_likely_spilled_p (C))) + /* Return true if REG satisfies (or will satisfy) reg class constraint CL. Use elimination first if REG is a hard register. If REG is a reload pseudo created by this constraints pass, assume that it will @@ -318,7 +325,11 @@ in_class_p (rtx reg, enum reg_class cl, enum reg_class *new_class, common_class = ira_reg_class_subset[rclass][cl]; if (new_class != NULL) *new_class = common_class; - return enough_allocatable_hard_regs_p (common_class, reg_mode); + return (enough_allocatable_hard_regs_p (common_class, reg_mode) + /* Do not permit reload insn operand matching (new_class == NULL + case) if the new class is too small. */ + && (new_class != NULL || common_class == rclass + || !SMALL_REGISTER_CLASS_P (common_class))); } } @@ -923,13 +934,6 @@ operands_match_p (rtx x, rtx y, int y_hard_regno) && GET_MODE_SIZE (MODE).is_constant () \ && !targetm.cannot_force_const_mem (MODE, X)) -/* True if C is a non-empty register class that has too few registers - to be safely used as a reload target class. */ -#define SMALL_REGISTER_CLASS_P(C) \ - (ira_class_hard_regs_num [(C)] == 1 \ - || (ira_class_hard_regs_num [(C)] >= 1 \ - && targetm.class_likely_spilled_p (C))) - /* If REG is a reload pseudo, try to make its class satisfying CL. */ static void narrow_reload_pseudo_class (rtx reg, enum reg_class cl) @@ -2137,6 +2141,7 @@ process_alt_operands (int only_alternative) /* True if output stack pointer reload should be generated for the current alternative. */ bool curr_alt_out_sp_reload_p; + bool curr_alt_class_change_p; rtx op; /* The register when the operand is a subreg of register, otherwise the operand itself. */ @@ -2223,6 +2228,7 @@ process_alt_operands (int only_alternative) early_clobbered_regs_num = 0; curr_alt_out_sp_reload_p = false; curr_reuse_alt_p = true; + curr_alt_class_change_p = false; for (nop = 0; nop < n_operands; nop++) { @@ -2247,6 +2253,7 @@ process_alt_operands (int only_alternative) bool scratch_p; machine_mode mode; enum constraint_num cn; + bool class_change_p = false; opalt_num = nalt * n_operands + nop; if (curr_static_id->operand_alternative[opalt_num].anything_ok) @@ -2630,9 +2637,16 @@ process_alt_operands (int only_alternative) (this_alternative_exclude_start_hard_regs, hard_regno[nop])))) win = true; - else if (hard_regno[nop] < 0 - && in_class_p (op, this_alternative, NULL)) - win = true; + else if (hard_regno[nop] < 0) + { + if (in_class_p (op, this_alternative, NULL)) + win = true; + else if (in_class_p (op, this_alternative, NULL, true)) + { + class_change_p = true; + win = true; + } + } } break; } @@ -2647,6 +2661,15 @@ process_alt_operands (int only_alternative) if (win) { this_alternative_win = true; + if (class_change_p) + { + curr_alt_class_change_p = true; + if (lra_dump_file != NULL) + fprintf (lra_dump_file, + " %d Narrowing class: reject+=3\n", + nop); + reject += 3; + } if (operand_reg[nop] != NULL_RTX) { if (hard_regno[nop] >= 0) @@ -2675,7 +2698,7 @@ process_alt_operands (int only_alternative) reject++; } if (in_class_p (operand_reg[nop], - this_costly_alternative, NULL)) + this_costly_alternative, NULL, true)) { if (lra_dump_file != NULL) fprintf @@ -3351,7 +3374,7 @@ process_alt_operands (int only_alternative) best_reload_sum = reload_sum; goal_alt_number = nalt; } - if (losers == 0) + if (losers == 0 && !curr_alt_class_change_p) /* Everything is satisfied. Do not process alternatives anymore. */ break; @@ -4388,7 +4411,7 @@ curr_insn_transform (bool check_only_p) if (REG_P (reg) && (regno = REGNO (reg)) >= FIRST_PSEUDO_REGISTER) { - bool ok_p = in_class_p (reg, goal_alt[i], &new_class); + bool ok_p = in_class_p (reg, goal_alt[i], &new_class, true); if (new_class != NO_REGS && get_reg_class (regno) != new_class) { @@ -4468,23 +4491,18 @@ curr_insn_transform (bool check_only_p) { if (goal_alt[i] == NO_REGS && REG_P (op) - /* When we assign NO_REGS it means that we will not - assign a hard register to the scratch pseudo by - assigment pass and the scratch pseudo will be - spilled. Spilled scratch pseudos are transformed - back to scratches at the LRA end. */ - && ira_former_scratch_operand_p (curr_insn, i) - && ira_former_scratch_p (REGNO (op))) + && (regno = REGNO (op)) >= FIRST_PSEUDO_REGISTER + /* We assigned a hard register to the pseudo in the past but now + decided to spill it for the insn. If the pseudo is used only + in this insn, it is better to spill it here as we free hard + registers for other pseudos referenced in the insn. The most + common case of this is a scratch register which will be + transformed to scratch back at the end of LRA. */ + && lra_get_regno_hard_regno (regno) >= 0 + && bitmap_single_bit_set_p (&lra_reg_info[regno].insn_bitmap)) { - int regno = REGNO (op); lra_change_class (regno, NO_REGS, " Change to", true); - if (lra_get_regno_hard_regno (regno) >= 0) - /* We don't have to mark all insn affected by the - spilled pseudo as there is only one such insn, the - current one. */ - reg_renumber[regno] = -1; - lra_assert (bitmap_single_bit_set_p - (&lra_reg_info[REGNO (op)].insn_bitmap)); + reg_renumber[regno] = -1; } /* We can do an optional reload. If the pseudo got a hard reg, we might improve the code through inheritance. If diff --git a/gcc/m2/ChangeLog b/gcc/m2/ChangeLog index 938f530..c1904d8 100644 --- a/gcc/m2/ChangeLog +++ b/gcc/m2/ChangeLog @@ -1,3 +1,84 @@ +2024-01-11 Gaius Mulley <gaiusmod2@gmail.com> + + PR modula2/112946 + * gm2-compiler/M2GenGCC.mod (IsExpressionCompatible): Import. + (ExpressionTypeCompatible): Import. + (CodeStatement): Remove op1, op2, op3 parameters from CodeSetOr, + CodeSetAnd, CodeSetSymmetricDifference, CodeSetLogicalDifference. + (checkArrayElements): Rename op1 to des and op3 to expr. + Use despos and exprpos instead of CurrentQuadToken. + (checkRecordTypes): Rename op1 to des and op2 to expr. + Use virtpos instead of CurrentQuadToken. + (checkIncorrectMeta): Ditto. + (checkBecomes): Rename op1 to des and op3 to expr. + Use virtpos instead of CurrentQuadToken. + (NoWalkProcedure): New procedure stub. + (CheckBinaryExpressionTypes): New procedure function. + (CheckElementSetTypes): New procedure function. + (CodeBinarySet): Re-write. + (FoldBinarySet): Re-write. + (CodeSetOr): Remove parameters op1, op2 and op3. + (CodeSetAnd): Ditto. + (CodeSetLogicalDifference): Ditto. + (CodeSetSymmetricDifference): Ditto. + (CodeIfIn): Call CheckBinaryExpressionTypes and + CheckElementSetTypes. + * gm2-compiler/M2Quads.mod (BuildRotateFunction): Correct + parameters to MakeVirtualTok to reflect parameter block + passed to Rotate. + +2024-01-09 Gaius Mulley <gaiusmod2@gmail.com> + + PR modula2/112920 + * gm2-compiler/M2GCCDeclare.mod (Group): New declaration. + Import MakeSubrange, MakeConstVar, MakeConstLit and DivTrunc. + (FreeGroup): New declaration. + (GlobalGroup): New declaration. + (ToBeSolvedByQuads): Remove. + (NilTypedArrays): Remove. + (PartiallyDeclared): Remove. + (HeldByAlignment): Remove. + (FinishedAlignment): Remove. + (ToDoList): Remove. + (DebugSet): Re-format. + (DebugNumber): Re-format. + (DebugSetNumbers): Reference sets using GlobalGroup. + (AddSymToWatch): Re-format. + (WatchIncludeList): Reference sets using GlobalGroup. + (WatchRemoveList): Reference sets using GlobalGroup. + (NewGroup): New procedure. + (DisposeGroup): New procedure. + (InitGroup): New procedure. + (KillGroup): New procedure. + (DupGroup): New procedure. + (EqualGroup): New procedure. + (LookupSet): New procedure. + (CanDeclareTypePartially): Reference sets using GlobalGroup. + (CompletelyResolved): Reference sets using GlobalGroup. + (IsNilTypedArrays): Reference sets using GlobalGroup. + (IsFullyDeclared): Reference sets using GlobalGroup. + (IsPartiallyDeclared): Reference sets using GlobalGroup. + (IsPartiallyOrFullyDeclared): Reference sets using GlobalGroup. + (DeclareTypeConstFully): Reference sets using GlobalGroup. + (bodyl): Remove. + (Body): Use bodyt and to lookup the required set. + (ForeachTryDeclare): Remove parameter l. Lookup set instead. + (DeclareOutstandingTypes): Add new rules setarraynul and setfully. + Reference sets using GlobalGroup. + (ActivateWatch): New procedure. + (DeclareTypesConstantsProceduresInRange): Re-written to check + group change. + (DeclareTypesConstantsProcedures): Re-written to check + group change. + (DeclareBoolean): Reference sets using GlobalGroup. + (DeclarePackedBoolean): Ditto. + (DeclareDefaultConstants): Ditto. + (FreeGroup): Initialized. + (GlobalGroup): Ditto. + * gm2-compiler/Sets.def (EqualSet): New procedure function. + Remove export qualified list of identifiers. + * gm2-compiler/Sets.mod (EqualSet): New procedure function. + 2024-01-04 David Malcolm <dmalcolm@redhat.com> * lang.opt.urls: New file, autogenerated by diff --git a/gcc/m2/gm2-compiler/M2GenGCC.mod b/gcc/m2/gm2-compiler/M2GenGCC.mod index bfcff70..2261cb0 100644 --- a/gcc/m2/gm2-compiler/M2GenGCC.mod +++ b/gcc/m2/gm2-compiler/M2GenGCC.mod @@ -107,7 +107,8 @@ FROM M2Base IMPORT MixTypes, NegateType, ActivationPointer, IsMathType, Cardinal, Char, Integer, IsTrunc, Boolean, True, Im, Re, Cmplx, GetCmplxReturnType, GetBaseTypeMinMax, - CheckAssignmentCompatible, IsAssignmentCompatible ; + CheckAssignmentCompatible, + IsAssignmentCompatible, IsExpressionCompatible ; FROM M2Bitset IMPORT Bitset ; FROM NameKey IMPORT Name, MakeKey, KeyToCharStar, LengthKey, makekey, NulName ; @@ -258,7 +259,7 @@ FROM M2Quads IMPORT QuadOperator, GetQuad, IsReferenced, GetNextQuad, GetM2OperatorDesc, GetQuadOp, DisplayQuadList ; -FROM M2Check IMPORT ParameterTypeCompatible, AssignmentTypeCompatible ; +FROM M2Check IMPORT ParameterTypeCompatible, AssignmentTypeCompatible, ExpressionTypeCompatible ; FROM M2SSA IMPORT EnableSSA ; @@ -504,10 +505,10 @@ BEGIN NegateOp : CodeNegateChecked (q, op1, op3) | LogicalShiftOp : CodeSetShift (q, op1, op2, op3) | LogicalRotateOp : CodeSetRotate (q, op1, op2, op3) | - LogicalOrOp : CodeSetOr (q, op1, op2, op3) | - LogicalAndOp : CodeSetAnd (q, op1, op2, op3) | - LogicalXorOp : CodeSetSymmetricDifference (q, op1, op2, op3) | - LogicalDiffOp : CodeSetLogicalDifference (q, op1, op2, op3) | + LogicalOrOp : CodeSetOr (q) | + LogicalAndOp : CodeSetAnd (q) | + LogicalXorOp : CodeSetSymmetricDifference (q) | + LogicalDiffOp : CodeSetLogicalDifference (q) | IfLessOp : CodeIfLess (q, op1, op2, op3) | IfEquOp : CodeIfEqu (q, op1, op2, op3) | IfNotEquOp : CodeIfNotEqu (q, op1, op2, op3) | @@ -3098,30 +3099,32 @@ END PrepareCopyString ; (* - checkArrayElements - return TRUE if op1 or op3 are not arrays. + checkArrayElements - return TRUE if des or expr are not arrays. If they are arrays and have different number of elements return FALSE, otherwise TRUE. *) -PROCEDURE checkArrayElements (op1, op3: CARDINAL) : BOOLEAN ; +PROCEDURE checkArrayElements (des, expr: CARDINAL; virtpos, despos, exprpos: CARDINAL) : BOOLEAN ; VAR e1, e3 : Tree ; t1, t3 : CARDINAL ; location: location_t ; BEGIN - location := TokenToLocation(CurrentQuadToken) ; - t1 := GetType(op1) ; - t3 := GetType(op3) ; - IF (t1#NulSym) AND (t3#NulSym) AND - IsArray(SkipType(GetType(op3))) AND IsArray(SkipType(GetType(op1))) + t1 := GetType (des) ; + t3 := GetType (expr) ; + IF (t1 # NulSym) AND (t3 # NulSym) AND + IsArray (SkipType (GetType (expr))) AND IsArray (SkipType (GetType (des))) THEN (* both arrays continue checking *) - e1 := GetArrayNoOfElements(location, Mod2Gcc(SkipType(GetType(op1)))) ; - e3 := GetArrayNoOfElements(location, Mod2Gcc(SkipType(GetType(op3)))) ; - IF CompareTrees(e1, e3)#0 - THEN - MetaErrorT2(CurrentQuadToken, 'not allowed to assign array {%2Ead} to {%1ad} as they have a different number of elements', - op1, op3) ; + e1 := GetArrayNoOfElements (TokenToLocation (despos), + Mod2Gcc (SkipType (GetType (des)))) ; + e3 := GetArrayNoOfElements (TokenToLocation (exprpos), + Mod2Gcc (SkipType (GetType (expr)))) ; + IF CompareTrees (e1, e3) # 0 + THEN + MetaErrorT2 (virtpos, + 'not allowed to assign array {%2Ead} to {%1ad} as they have a different number of elements', + des, expr) ; RETURN( FALSE ) END END ; @@ -3151,32 +3154,36 @@ END CodeInitAddress ; (* - checkRecordTypes - returns TRUE if op1 is not a record or if the record - is the same type as op2. + checkRecordTypes - returns TRUE if des is not a record or if the record + is the same type as expr. *) -PROCEDURE checkRecordTypes (op1, op2: CARDINAL) : BOOLEAN ; +PROCEDURE checkRecordTypes (des, expr: CARDINAL; virtpos: CARDINAL) : BOOLEAN ; VAR t1, t2: CARDINAL ; BEGIN - IF (GetType(op1)=NulSym) OR (GetMode(op1)=LeftValue) + IF (GetType (des) = NulSym) OR (GetMode (des) = LeftValue) THEN RETURN( TRUE ) ELSE - t1 := SkipType(GetType(op1)) ; - IF IsRecord(t1) + t1 := SkipType (GetType (des)) ; + IF IsRecord (t1) THEN - IF GetType(op2)=NulSym + IF GetType (expr) = NulSym THEN - MetaErrorT2 (CurrentQuadToken, 'cannot assign an operand of type {%1Ets} to a record type {%2tsa}', op2, op1) ; + MetaErrorT2 (virtpos, + 'cannot assign an operand of type {%1Ets} to a record type {%2tsa}', + expr, des) ; RETURN( FALSE ) ELSE - t2 := SkipType(GetType(op2)) ; - IF t1=t2 + t2 := SkipType (GetType (expr)) ; + IF t1 = t2 THEN RETURN( TRUE ) ELSE - MetaErrorT2 (CurrentQuadToken, 'cannot assign an operand of type {%1ts} to a record type {%2tsa}', op2, op1) ; + MetaErrorT2 (virtpos, + 'cannot assign an operand of type {%1ts} to a record type {%2tsa}', + expr, des) ; RETURN( FALSE ) END END @@ -3187,26 +3194,29 @@ END checkRecordTypes ; (* - checkIncorrectMeta - + checkIncorrectMeta - checks to see if des and expr are assignment compatible is allows + generic system types to be assigned. *) -PROCEDURE checkIncorrectMeta (op1, op2: CARDINAL) : BOOLEAN ; +PROCEDURE checkIncorrectMeta (des, expr: CARDINAL; virtpos: CARDINAL) : BOOLEAN ; VAR t1, t2: CARDINAL ; BEGIN - t1 := SkipType(GetType(op1)) ; - t2 := SkipType(GetType(op2)) ; - IF (t1=NulSym) OR (GetMode(op1)=LeftValue) OR - (t2=NulSym) OR (GetMode(op2)=LeftValue) + t1 := SkipType (GetType (des)) ; + t2 := SkipType (GetType (expr)) ; + IF (t1 = NulSym) OR (GetMode(des) = LeftValue) OR + (t2 = NulSym) OR (GetMode(expr) = LeftValue) THEN RETURN( TRUE ) - ELSIF (t1#t2) AND (NOT IsGenericSystemType(t1)) AND (NOT IsGenericSystemType(t2)) + ELSIF (t1 # t2) AND (NOT IsGenericSystemType (t1)) AND (NOT IsGenericSystemType (t2)) THEN - IF IsArray(t1) OR IsSet(t1) OR IsRecord(t1) + IF IsArray (t1) OR IsSet (t1) OR IsRecord (t1) THEN - IF NOT IsAssignmentCompatible(t1, t2) + IF NOT IsAssignmentCompatible (t1, t2) THEN - MetaErrorT2 (CurrentQuadToken, 'illegal assignment error between {%1Etad} and {%2tad}', op1, op2) ; + MetaErrorT2 (virtpos, + 'illegal assignment error between {%1Etad} and {%2tad}', + des, expr) ; RETURN( FALSE ) END END @@ -3219,11 +3229,11 @@ END checkIncorrectMeta ; checkBecomes - returns TRUE if the checks pass. *) -PROCEDURE checkBecomes (des, expr: CARDINAL) : BOOLEAN ; +PROCEDURE checkBecomes (des, expr: CARDINAL; virtpos, despos, exprpos: CARDINAL) : BOOLEAN ; BEGIN - IF (NOT checkArrayElements (des, expr)) OR - (NOT checkRecordTypes (des, expr)) OR - (NOT checkIncorrectMeta (des, expr)) + IF (NOT checkArrayElements (des, expr, virtpos, despos, exprpos)) OR + (NOT checkRecordTypes (des, expr, virtpos)) OR + (NOT checkIncorrectMeta (des, expr, virtpos)) THEN RETURN FALSE END ; @@ -3256,71 +3266,73 @@ PROCEDURE CodeBecomes (quad: CARDINAL) ; VAR overflowChecking: BOOLEAN ; op : QuadOperator ; - op1, op2, op3 : CARDINAL ; + des, op2, expr : CARDINAL ; + virtpos, becomespos, - op1pos, + despos, op2pos, - op3pos : CARDINAL ; + exprpos : CARDINAL ; length, - op3t : Tree ; + exprt : Tree ; location : location_t ; BEGIN - GetQuadOtok (quad, becomespos, op, op1, op2, op3, overflowChecking, - op1pos, op2pos, op3pos) ; + GetQuadOtok (quad, becomespos, op, des, op2, expr, overflowChecking, + despos, op2pos, exprpos) ; Assert (op2pos = UnknownTokenNo) ; - DeclareConstant (CurrentQuadToken, op3) ; (* Check to see whether op3 is a constant and declare it. *) - DeclareConstructor (CurrentQuadToken, quad, op3) ; - location := TokenToLocation (CurrentQuadToken) ; + DeclareConstant (exprpos, expr) ; (* Check to see whether expr is a constant and declare it. *) + DeclareConstructor (exprpos, quad, expr) ; + virtpos := MakeVirtualTok (becomespos, despos, exprpos) ; + location := TokenToLocation (virtpos) ; IF StrictTypeChecking AND - (NOT AssignmentTypeCompatible (CurrentQuadToken, "", op1, op3)) + (NOT AssignmentTypeCompatible (virtpos, "", des, expr)) THEN - MetaErrorT2 (MakeVirtualTok (becomespos, op1pos, op3pos), + MetaErrorT2 (virtpos, 'assignment check caught mismatch between {%1Ead} and {%2ad}', - op1, op3) + des, expr) END ; - IF IsConst (op1) AND (NOT GccKnowsAbout (op1)) + IF IsConst (des) AND (NOT GccKnowsAbout (des)) THEN - ConstantKnownAndUsed (op1, CheckConstant (CurrentQuadToken, op1, op3)) - ELSIF IsConstString (op3) AND (SkipTypeAndSubrange (GetType (op1)) # Char) + ConstantKnownAndUsed (des, CheckConstant (virtpos, des, expr)) + ELSIF IsConstString (expr) AND (SkipTypeAndSubrange (GetType (des)) # Char) THEN - checkDeclare (op1) ; - IF NOT PrepareCopyString (becomespos, length, op3t, op3, SkipType (GetType (op1))) + checkDeclare (des) ; + IF NOT PrepareCopyString (becomespos, length, exprt, expr, SkipType (GetType (des))) THEN - MetaErrorT2 (MakeVirtualTok (becomespos, op1pos, op3pos), + MetaErrorT2 (virtpos, 'string constant {%1Ea} is too large to be assigned to the array {%2ad}', - op3, op1) + expr, des) END ; AddStatement (location, - MaybeDebugBuiltinMemcpy (location, CurrentQuadToken, - BuildAddr (location, Mod2Gcc (op1), FALSE), - BuildAddr (location, op3t, FALSE), + MaybeDebugBuiltinMemcpy (location, virtpos, + BuildAddr (location, Mod2Gcc (des), FALSE), + BuildAddr (location, exprt, FALSE), length)) ELSE - IF ((IsGenericSystemType(SkipType(GetType(op1))) # - IsGenericSystemType(SkipType(GetType(op3)))) OR - (IsUnbounded(SkipType(GetType(op1))) AND - IsUnbounded(SkipType(GetType(op3))) AND - (IsGenericSystemType(SkipType(GetType(GetType(op1)))) # - IsGenericSystemType(SkipType(GetType(GetType(op3))))))) AND - (NOT IsConstant(op3)) - THEN - checkDeclare (op1) ; + IF ((IsGenericSystemType(SkipType(GetType(des))) # + IsGenericSystemType(SkipType(GetType(expr)))) OR + (IsUnbounded(SkipType(GetType(des))) AND + IsUnbounded(SkipType(GetType(expr))) AND + (IsGenericSystemType(SkipType(GetType(GetType(des)))) # + IsGenericSystemType(SkipType(GetType(GetType(expr))))))) AND + (NOT IsConstant(expr)) + THEN + checkDeclare (des) ; AddStatement (location, - MaybeDebugBuiltinMemcpy (location, CurrentQuadToken, - BuildAddr(location, Mod2Gcc (op1), FALSE), - BuildAddr(location, Mod2Gcc (op3), FALSE), - BuildSize(location, Mod2Gcc (op1), FALSE))) + MaybeDebugBuiltinMemcpy (location, virtpos, + BuildAddr(location, Mod2Gcc (des), FALSE), + BuildAddr(location, Mod2Gcc (expr), FALSE), + BuildSize(location, Mod2Gcc (des), FALSE))) ELSE - IF checkBecomes (op1, op3) + IF checkBecomes (des, expr, virtpos, despos, exprpos) THEN - IF IsVariableSSA (op1) + IF IsVariableSSA (des) THEN - Replace (op1, FoldConstBecomes (CurrentQuadToken, op1, op3)) + Replace (des, FoldConstBecomes (virtpos, des, expr)) ELSE BuildAssignmentStatement (location, - Mod2Gcc (op1), - FoldConstBecomes (CurrentQuadToken, op1, op3)) + Mod2Gcc (des), + FoldConstBecomes (virtpos, des, expr)) END ELSE SubQuad (quad) (* we don't want multiple errors for the quad. *) @@ -3609,48 +3621,196 @@ END CodeBinary ; (* - CodeBinarySet - encode a binary set arithmetic operation. - Set operands may be longer than a word. + NoWalkProcedure - *) -PROCEDURE CodeBinarySet (binop: BuildBinProcedure; doOp: DoProcedure; - quad: CARDINAL; op1, op2, op3: CARDINAL) ; +PROCEDURE NoWalkProcedure (param: CARDINAL) ; +BEGIN +END NoWalkProcedure ; + + +(* + CheckBinaryExpressionTypes - returns TRUE if all expression checks pass. + If the expression check fails quad is removed, + the walk procedure (des) is called and NoChange is + set to FALSE. +*) + +PROCEDURE CheckBinaryExpressionTypes (quad: CARDINAL; p: WalkAction) : BOOLEAN ; VAR - location: location_t ; + lefttype, + righttype, + des, left, right: CARDINAL ; + overflowChecking: BOOLEAN ; + despos, leftpos, + rightpos, + operatorpos, + subexprpos : CARDINAL ; + op : QuadOperator ; BEGIN - (* firstly ensure that constant literals are declared *) - DeclareConstant(CurrentQuadToken, op3) ; - DeclareConstant(CurrentQuadToken, op2) ; - DeclareConstructor(CurrentQuadToken, quad, op3) ; - DeclareConstructor(CurrentQuadToken, quad, op2) ; - location := TokenToLocation(CurrentQuadToken) ; + GetQuadOtok (quad, operatorpos, op, + des, left, right, overflowChecking, + despos, leftpos, rightpos) ; + IF ((op # LogicalRotateOp) AND (op # LogicalShiftOp)) + THEN + subexprpos := MakeVirtualTok (operatorpos, leftpos, rightpos) ; + lefttype := GetType (left) ; + righttype := GetType (right) ; + IF StrictTypeChecking AND + (NOT ExpressionTypeCompatible (subexprpos, "", lefttype, righttype, + StrictTypeChecking, FALSE)) + THEN + MetaErrorT2 (subexprpos, + 'expression mismatch between {%1Etad} and {%2tad}', + left, right) ; + NoChange := FALSE ; + SubQuad (quad) ; + p (des) ; + RETURN FALSE + END ; + (* --fixme-- the ExpressionTypeCompatible above should be enough + and the code below can be removed once ExpressionTypeCompatible + is bug free. *) + IF NOT IsExpressionCompatible (lefttype, righttype) + THEN + MetaErrorT2 (subexprpos, + 'expression mismatch between {%1Etad} and {%2tad}', + left, right) ; + NoChange := FALSE ; + SubQuad (quad) ; + p (des) ; + RETURN FALSE + END + END ; + RETURN TRUE +END CheckBinaryExpressionTypes ; - IF IsConst(op1) + +(* + CheckElementSetTypes - returns TRUE if all expression checks pass. + If the expression check fails quad is removed, + the walk procedure (des) is called and NoChange is + set to FALSE. +*) + +PROCEDURE CheckElementSetTypes (quad: CARDINAL; p: WalkAction) : BOOLEAN ; +VAR + lefttype, + righttype, + ignore, left, right: CARDINAL ; + overflowChecking: BOOLEAN ; + ignorepos, + leftpos, + rightpos, + operatorpos, + subexprpos : CARDINAL ; + op : QuadOperator ; +BEGIN + GetQuadOtok (quad, operatorpos, op, + left, right, ignore, overflowChecking, + leftpos, rightpos, ignorepos) ; + subexprpos := MakeVirtualTok (operatorpos, leftpos, rightpos) ; + lefttype := GetType (left) ; + righttype := GetType (right) ; + (* --fixme-- the ExpressionTypeCompatible below does not always catch + type errors, it needs to be fixed and then some of the subsequent tests + can be removed (and/or this procedure function rewritten). *) + IF StrictTypeChecking AND + (NOT ExpressionTypeCompatible (subexprpos, "", lefttype, righttype, + StrictTypeChecking, TRUE)) THEN - IF IsValueSolved(op2) AND IsValueSolved(op3) - THEN - Assert(MixTypes(FindType(op3), FindType(op2), CurrentQuadToken)#NulSym) ; - PutConst(op1, FindType(op3)) ; - PushValue(op2) ; - PushValue(op3) ; - doOp(CurrentQuadToken) ; - PopValue(op1) ; - PutConstSet(op1) ; + MetaErrorT2 (subexprpos, + 'the types used in expression {%1Etad} {%kIN} {%2tad} are incompatible', + left, right) ; + NoChange := FALSE ; + SubQuad (quad) ; + RETURN FALSE + END ; + IF (righttype = NulSym) OR (NOT IsSet (SkipType (righttype))) + THEN + MetaErrorT1 (rightpos, + 'an {%kIN} expression is expecting {%1Etad} to be a {%kSET} type', + right) ; + NoChange := FALSE ; + SubQuad (quad) ; + RETURN FALSE + END ; + righttype := GetType (SkipType (righttype)) ; + (* Now fall though and compare the set element left against the type of set righttype. *) + IF NOT IsExpressionCompatible (lefttype, righttype) + THEN + MetaErrorT2 (subexprpos, + 'the types used in expression {%1Etad} {%kIN} {%2tad} are incompatible', + left, right) ; + NoChange := FALSE ; + SubQuad (quad) ; + RETURN FALSE + END ; + RETURN TRUE +END CheckElementSetTypes ; + + +(* + CodeBinarySet - encode a binary set arithmetic operation. + Set operands may be longer than a word. +*) + +PROCEDURE CodeBinarySet (binop: BuildBinProcedure; doOp: DoProcedure; + quad: CARDINAL) ; +VAR + location : location_t ; + overflowChecking: BOOLEAN ; + op : QuadOperator ; + virttoken, + virtexpr, + des, + left, + right, + despos, + leftpos, + rightpos, + operatorpos : CARDINAL ; +BEGIN + GetQuadOtok (quad, operatorpos, op, des, left, right, overflowChecking, + despos, leftpos, rightpos) ; + + (* Firstly ensure that constant literals are declared. *) + DeclareConstant (rightpos, right) ; + DeclareConstant (leftpos, left) ; + DeclareConstructor (rightpos, quad, right) ; + DeclareConstructor (leftpos, quad, left) ; + + virttoken := MakeVirtualTok (operatorpos, despos, rightpos) ; + location := TokenToLocation (virttoken) ; + IF CheckBinaryExpressionTypes (quad, NoWalkProcedure) + THEN + IF IsConst (des) + THEN + virtexpr := MakeVirtualTok (operatorpos, leftpos, rightpos) ; + IF IsValueSolved (left) AND IsValueSolved (right) + THEN + Assert (MixTypes (FindType (right), FindType (left), virtexpr) # NulSym) ; + PutConst (des, FindType (right)) ; + PushValue (left) ; + PushValue (right) ; + doOp (virttoken) ; + PopValue (des) ; + PutConstSet (des) + ELSE + MetaErrorT0 (virtexpr, '{%E}constant expression cannot be evaluated') + END ELSE - MetaErrorT0 (CurrentQuadToken, - '{%E}constant expression cannot be evaluated') + checkDeclare (des) ; + BuildBinaryForeachWordDo (location, + Mod2Gcc (SkipType (GetType (des))), + Mod2Gcc (des), Mod2Gcc (left), Mod2Gcc (right), binop, + GetMode (des) = LeftValue, + GetMode (left) = LeftValue, + GetMode (right) = LeftValue, + IsConst (des), + IsConst (left), + IsConst (right)) END - ELSE - checkDeclare (op1) ; - BuildBinaryForeachWordDo(location, - Mod2Gcc(SkipType(GetType(op1))), - Mod2Gcc(op1), Mod2Gcc(op2), Mod2Gcc(op3), binop, - GetMode(op1)=LeftValue, - GetMode(op2)=LeftValue, - GetMode(op3)=LeftValue, - IsConst(op1), - IsConst(op2), - IsConst(op3)) END END CodeBinarySet ; @@ -4695,27 +4855,30 @@ BEGIN TryDeclareConstant(tokenno, op3) ; location := TokenToLocation(tokenno) ; - IF IsConst(op2) AND IsConstSet(op2) AND - IsConst(op3) AND IsConstSet(op3) AND - IsConst(op1) + IF CheckBinaryExpressionTypes (quad, p) THEN - IF IsValueSolved(op2) AND IsValueSolved(op3) + IF IsConst(op2) AND IsConstSet(op2) AND + IsConst(op3) AND IsConstSet(op3) AND + IsConst(op1) THEN - Assert(MixTypes(FindType(op3), FindType(op2), tokenno)#NulSym) ; - PutConst(op1, MixTypes(FindType(op3), FindType(op2), tokenno)) ; - PushValue(op2) ; - PushValue(op3) ; - op(tokenno) ; - PopValue(op1) ; - PushValue(op1) ; - PutConstSet(op1) ; - AddModGcc(op1, - DeclareKnownConstant(location, - Mod2Gcc(GetType(op3)), - PopSetTree(tokenno))) ; - p(op1) ; - NoChange := FALSE ; - SubQuad(quad) + IF IsValueSolved(op2) AND IsValueSolved(op3) + THEN + Assert(MixTypes(FindType(op3), FindType(op2), tokenno)#NulSym) ; + PutConst(op1, MixTypes(FindType(op3), FindType(op2), tokenno)) ; + PushValue(op2) ; + PushValue(op3) ; + op(tokenno) ; + PopValue(op1) ; + PushValue(op1) ; + PutConstSet(op1) ; + AddModGcc(op1, + DeclareKnownConstant(location, + Mod2Gcc(GetType(op3)), + PopSetTree(tokenno))) ; + p(op1) ; + NoChange := FALSE ; + SubQuad(quad) + END END END END FoldBinarySet ; @@ -4736,9 +4899,9 @@ END FoldSetOr ; CodeSetOr - encode set arithmetic or. *) -PROCEDURE CodeSetOr (quad: CARDINAL; op1, op2, op3: CARDINAL) ; +PROCEDURE CodeSetOr (quad: CARDINAL) ; BEGIN - CodeBinarySet (BuildLogicalOr, SetOr, quad, op1, op2, op3) + CodeBinarySet (BuildLogicalOr, SetOr, quad) END CodeSetOr ; @@ -4757,9 +4920,9 @@ END FoldSetAnd ; CodeSetAnd - encode set arithmetic and. *) -PROCEDURE CodeSetAnd (quad: CARDINAL; op1, op2, op3: CARDINAL) ; +PROCEDURE CodeSetAnd (quad: CARDINAL) ; BEGIN - CodeBinarySet (BuildLogicalAnd, SetAnd, quad, op1, op2, op3) + CodeBinarySet (BuildLogicalAnd, SetAnd, quad) END CodeSetAnd ; @@ -4909,10 +5072,9 @@ END FoldSetLogicalDifference ; CodeSetLogicalDifference - encode set arithmetic logical difference. *) -PROCEDURE CodeSetLogicalDifference (quad: CARDINAL; op1, op2, op3: CARDINAL) ; +PROCEDURE CodeSetLogicalDifference (quad: CARDINAL) ; BEGIN - CodeBinarySet (BuildLogicalDifference, SetDifference, - quad, op1, op2, op3) + CodeBinarySet (BuildLogicalDifference, SetDifference, quad) END CodeSetLogicalDifference ; @@ -4931,10 +5093,9 @@ END FoldSymmetricDifference ; CodeSetSymmetricDifference - code set difference. *) -PROCEDURE CodeSetSymmetricDifference (quad: CARDINAL; op1, op2, op3: CARDINAL) ; +PROCEDURE CodeSetSymmetricDifference (quad: CARDINAL) ; BEGIN - CodeBinarySet (BuildSymmetricDifference, SetSymmetricDifference, - quad, op1, op2, op3) + CodeBinarySet (BuildSymmetricDifference, SetSymmetricDifference, quad) END CodeSetSymmetricDifference ; @@ -5052,11 +5213,16 @@ BEGIN THEN IF IsValueSolved (left) AND IsValueSolved (right) THEN - (* fine, we can take advantage of this and evaluate the condition *) - PushValue (right) ; - IF SetIn (tokenno, left) + IF CheckBinaryExpressionTypes (quad, NoWalkProcedure) THEN - PutQuad (quad, GotoOp, NulSym, NulSym, destQuad) + (* fine, we can take advantage of this and evaluate the condition *) + PushValue (right) ; + IF SetIn (tokenno, left) + THEN + PutQuad (quad, GotoOp, NulSym, NulSym, destQuad) + ELSE + SubQuad (quad) + END ELSE SubQuad (quad) END @@ -5080,11 +5246,16 @@ BEGIN THEN IF IsValueSolved (left) AND IsValueSolved (right) THEN - (* fine, we can take advantage of this and evaluate the condition *) - PushValue (right) ; - IF NOT SetIn (tokenno, left) + IF CheckBinaryExpressionTypes (quad, NoWalkProcedure) THEN - PutQuad (quad, GotoOp, NulSym, NulSym, destQuad) + (* fine, we can take advantage of this and evaluate the condition *) + PushValue (right) ; + IF NOT SetIn (tokenno, left) + THEN + PutQuad (quad, GotoOp, NulSym, NulSym, destQuad) + ELSE + SubQuad (quad) + END ELSE SubQuad (quad) END @@ -7200,7 +7371,8 @@ BEGIN IF IsConst(op1) AND IsConst(op2) THEN InternalError ('should not get to here (if we do we should consider calling FoldIfIn)') - ELSE + ELSIF CheckElementSetTypes (quad, NoWalkProcedure) + THEN IF IsConst(op1) THEN fieldno := GetFieldNo(CurrentQuadToken, op1, GetType(op2), offset) ; @@ -7266,7 +7438,8 @@ BEGIN IF IsConst(op1) AND IsConst(op2) THEN InternalError ('should not get to here (if we do we should consider calling FoldIfIn)') - ELSE + ELSIF CheckElementSetTypes (quad, NoWalkProcedure) + THEN IF IsConst(op1) THEN fieldno := GetFieldNo(CurrentQuadToken, op1, SkipType(GetType(op2)), offset) ; diff --git a/gcc/m2/gm2-compiler/M2Quads.mod b/gcc/m2/gm2-compiler/M2Quads.mod index 4833ac0..45e2769 100644 --- a/gcc/m2/gm2-compiler/M2Quads.mod +++ b/gcc/m2/gm2-compiler/M2Quads.mod @@ -9032,14 +9032,14 @@ BEGIN MarkAsRead (r) ; PopTtok (varSet, vartok) ; PopT (procSym) ; - combinedtok := MakeVirtualTok (functok, exptok, vartok) ; + combinedtok := MakeVirtualTok (functok, functok, exptok) ; IF (GetSType (varSet) # NulSym) AND IsSet (GetDType (varSet)) THEN derefExp := DereferenceLValue (exptok, Exp) ; BuildRange (InitShiftCheck (varSet, derefExp)) ; returnVar := MakeTemporary (combinedtok, RightValue) ; PutVar (returnVar, GetSType (varSet)) ; - GenQuad (LogicalShiftOp, returnVar, varSet, derefExp) ; + GenQuadO (combinedtok, LogicalShiftOp, returnVar, varSet, derefExp, TRUE) ; PushTFtok (returnVar, GetSType (varSet), combinedtok) ELSE MetaErrorT1 (vartok, diff --git a/gcc/match.pd b/gcc/match.pd index 7b4b15a..e42ecaf 100644 --- a/gcc/match.pd +++ b/gcc/match.pd @@ -560,7 +560,8 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) 1 / X -> X >= -1 && X <= 1 ? X : 0 for signed integer X. But not for 1 / 0 so that we can get proper warnings and errors, and not for 1-bit integers as they are edge cases better handled - elsewhere. */ + elsewhere. Delay the conversion of the signed division until late + because `1 / X` is simplier to handle than the resulting COND_EXPR. */ (simplify (trunc_div integer_onep@0 @1) (if (INTEGRAL_TYPE_P (type) @@ -569,10 +570,11 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) && (!flag_non_call_exceptions || tree_expr_nonzero_p (@1))) (if (TYPE_UNSIGNED (type)) (convert (eq:boolean_type_node @1 { build_one_cst (type); })) - (with { tree utype = unsigned_type_for (type); } - (cond (le (plus (convert:utype @1) { build_one_cst (utype); }) - { build_int_cst (utype, 2); }) - @1 { build_zero_cst (type); }))))) + (if (!canonicalize_math_p ()) + (with { tree utype = unsigned_type_for (type); } + (cond (le (plus (convert:utype @1) { build_one_cst (utype); }) + { build_int_cst (utype, 2); }) + @1 { build_zero_cst (type); })))))) /* Combine two successive divisions. Note that combining ceil_div and floor_div is trickier and combining round_div even more so. */ @@ -1160,18 +1162,30 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) (hypots @0 (copysigns @1 @2)) (hypots @0 @1)))) -/* copysign(x, CST) -> abs (x). */ +/* copysign(x, CST) -> abs (x). If the target does not + support the copysign optab then canonicalize + copysign(x, -CST) -> fneg (abs (x)). */ (for copysigns (COPYSIGN_ALL) (simplify (copysigns @0 REAL_CST@1) (if (!REAL_VALUE_NEGATIVE (TREE_REAL_CST (@1))) - (abs @0)))) + (abs @0) +#if GIMPLE + (if (!direct_internal_fn_supported_p (IFN_COPYSIGN, type, + OPTIMIZE_FOR_BOTH)) + (negate (abs @0))) +#endif + ))) -/* Transform fneg (fabs (X)) -> copysign (X, -1). */ +#if GIMPLE +/* Transform fneg (fabs (X)) -> copysign (X, -1) as the canonical + representation if the target supports the copysign optab. */ (simplify (negate (abs @0)) - (IFN_COPYSIGN @0 { build_minus_one_cst (type); })) - + (if (direct_internal_fn_supported_p (IFN_COPYSIGN, type, + OPTIMIZE_FOR_BOTH)) + (IFN_COPYSIGN @0 { build_minus_one_cst (type); }))) +#endif /* copysign(copysign(x, y), z) -> copysign(x, z). */ (for copysigns (COPYSIGN_ALL) (simplify @@ -5672,6 +5686,27 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) (if (VECTOR_TYPE_P (type)) (view_convert @c0) (convert @c0)))))))) + +/* This is for VEC_COND_EXPR + Optimize A < B ? A : B to MIN (A, B) + A > B ? A : B to MAX (A, B). */ +(for cmp (lt le ungt unge gt ge unlt unle) + minmax (min min min min max max max max) + MINMAX (MIN_EXPR MIN_EXPR MIN_EXPR MIN_EXPR MAX_EXPR MAX_EXPR MAX_EXPR MAX_EXPR) + (simplify + (vec_cond (cmp @0 @1) @0 @1) + (if (VECTOR_INTEGER_TYPE_P (type) + && target_supports_op_p (type, MINMAX, optab_vector)) + (minmax @0 @1)))) + +(for cmp (lt le ungt unge gt ge unlt unle) + minmax (max max max max min min min min) + MINMAX (MAX_EXPR MAX_EXPR MAX_EXPR MAX_EXPR MIN_EXPR MIN_EXPR MIN_EXPR MIN_EXPR) + (simplify + (vec_cond (cmp @0 @1) @1 @0) + (if (VECTOR_INTEGER_TYPE_P (type) + && target_supports_op_p (type, MINMAX, optab_vector)) + (minmax @0 @1)))) #endif (for cnd (cond vec_cond) @@ -6759,11 +6794,12 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) && exact_real_truncate (TYPE_MODE (double_type_node), &orig)) type1 = double_type_node; } - tree newtype - = (element_precision (TREE_TYPE (@00)) > element_precision (type1) - ? TREE_TYPE (@00) : type1); + tree newtype + = (element_precision (TREE_TYPE (@00)) > element_precision (type1) + ? TREE_TYPE (@00) : type1); } - (if (element_precision (TREE_TYPE (@0)) > element_precision (newtype)) + (if (element_precision (TREE_TYPE (@0)) > element_precision (newtype) + && (!VECTOR_TYPE_P (type) || is_truth_type_for (newtype, type))) (cmp (convert:newtype @00) (convert:newtype @10)))))))) diff --git a/gcc/objc/ChangeLog b/gcc/objc/ChangeLog index 2a50fa0..7e61c71 100644 --- a/gcc/objc/ChangeLog +++ b/gcc/objc/ChangeLog @@ -1,3 +1,9 @@ +2024-01-12 Iain Sandoe <iain@sandoe.co.uk> + + * objc-next-runtime-abi-02.cc + (build_v2_objc_method_fixup_call): Early exit for cases + where the sender or receiver are known to be in error. + 2023-11-27 Alex Coplan <alex.coplan@arm.com> Iain Sandoe <iain@sandoe.co.uk> diff --git a/gcc/objc/objc-next-runtime-abi-02.cc b/gcc/objc/objc-next-runtime-abi-02.cc index dfc1129..a622f4c 100644 --- a/gcc/objc/objc-next-runtime-abi-02.cc +++ b/gcc/objc/objc-next-runtime-abi-02.cc @@ -1657,6 +1657,8 @@ build_v2_objc_method_fixup_call (int super_flag, tree method_prototype, rcv_p = (super_flag ? objc_super_type : objc_object_type); lookup_object = build_c_cast (input_location, rcv_p, lookup_object); + if (sender == error_mark_node || lookup_object == error_mark_node) + return error_mark_node; /* Use SAVE_EXPR to avoid evaluating the receiver twice. */ lookup_object = save_expr (lookup_object); diff --git a/gcc/opts-common.cc b/gcc/opts-common.cc index 73126cb..4a2dff2 100644 --- a/gcc/opts-common.cc +++ b/gcc/opts-common.cc @@ -468,6 +468,28 @@ static const struct option_map option_map[] = { "--no-", NULL, "-f", false, true } }; +/* Given buffer P of size SZ, look for a prefix within OPTION_MAP; + if found, return the prefix and write the new prefix to *OUT_NEW_PREFIX. + Otherwise return nullptr. */ + +const char * +get_option_prefix_remapping (const char *p, size_t sz, + const char **out_new_prefix) +{ + for (unsigned i = 0; i < ARRAY_SIZE (option_map); i++) + { + const char * const old_prefix = option_map[i].opt0; + const size_t old_prefix_len = strlen (old_prefix); + if (old_prefix_len <= sz + && !memcmp (p, old_prefix, old_prefix_len)) + { + *out_new_prefix = option_map[i].new_prefix; + return old_prefix; + } + } + return nullptr; +} + /* Helper function for gcc.cc's driver::suggest_option, for populating the vec of suggestions for misspelled options. @@ -491,6 +491,9 @@ extern const struct zero_call_used_regs_opts_s extern vec<const char *> help_option_arguments; +extern const char *get_option_prefix_remapping (const char *p, size_t sz, + const char **out_new_prefix); + extern void add_misspelling_candidates (auto_vec<char *> *candidates, const struct cl_option *option, const char *base_option); diff --git a/gcc/output.h b/gcc/output.h index c8fe1d2..46b0033 100644 --- a/gcc/output.h +++ b/gcc/output.h @@ -182,6 +182,10 @@ extern const char *get_fnname_from_decl (tree); code or data is output after the label. */ extern void assemble_function_label_raw (FILE *, const char *); +/* Finish outputting function label. Needs to be called when outputting + function label without using assemble_function_label_raw (). */ +extern void assemble_function_label_final (void); + /* Output assembler code for the constant pool of a function and associated with defining the name of the function. DECL describes the function. NAME is the function's name. For the constant pool, we use the current diff --git a/gcc/pretty-print.cc b/gcc/pretty-print.cc index fd4c38e..de454ab 100644 --- a/gcc/pretty-print.cc +++ b/gcc/pretty-print.cc @@ -19,6 +19,7 @@ along with GCC; see the file COPYING3. If not see <http://www.gnu.org/licenses/>. */ #include "config.h" +#define INCLUDE_VECTOR #include "system.h" #include "coretypes.h" #include "intl.h" @@ -1031,7 +1032,16 @@ obstack_append_string (obstack *ostack, const char *str) obstack_grow (ostack, str, strlen (str)); } -/* Given quoted text starting at QUOTED_TEXT_START_IDX within PP's buffer, +/* Append STR to OSTACK, without a null-terminator. */ + +static void +obstack_append_string (obstack *ostack, const char *str, size_t len) +{ + obstack_grow (ostack, str, len); +} + +/* Given quoted text within the buffer OBSTACK + at the half-open interval [QUOTED_TEXT_START_IDX, QUOTED_TEXT_END_IDX), potentially use URLIFIER (if non-null) to see if there's a URL for the quoted text. @@ -1039,47 +1049,45 @@ obstack_append_string (obstack *ostack, const char *str) version of the text, using PP's settings. For example, given this is the buffer: - "this is a test `hello world" + "this is a test `hello worldTRAILING-CONTENT" .................^~~~~~~~~~~ with the quoted text starting at the 'h' of "hello world", the buffer becomes: - "this is a test `BEGIN_URL(URL)hello worldEND(URL)" + "this is a test `BEGIN_URL(URL)hello worldEND(URL)TRAILING-CONTENT" .................^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .................-----------replacement----------- -*/ -static void + Return the new offset into the buffer of the quoted text endpoint i.e. + the offset of "TRAILING-CONTENT" in the above. */ + +static size_t urlify_quoted_string (pretty_printer *pp, + obstack *obstack, const urlifier *urlifier, - size_t quoted_text_start_idx) + size_t quoted_text_start_idx, + size_t quoted_text_end_idx) { if (pp->url_format == URL_FORMAT_NONE) - return; + return quoted_text_end_idx; if (!urlifier) - return; + return quoted_text_end_idx; - output_buffer * const buffer = pp_buffer (pp); - - /* Get end of quoted string. */ - const size_t close_quote_idx - = obstack_object_size (&buffer->chunk_obstack); - gcc_assert (close_quote_idx >= quoted_text_start_idx); - if (close_quote_idx == quoted_text_start_idx) + const size_t quoted_len = quoted_text_end_idx - quoted_text_start_idx; + if (quoted_len == 0) /* Empty quoted string; do nothing. */ - return; - const size_t len = close_quote_idx - quoted_text_start_idx; - const char *start = (buffer->chunk_obstack.object_base - + quoted_text_start_idx); - char *url = urlifier->get_url_for_quoted_text (start, len); + return quoted_text_end_idx; + const char *start = (obstack->object_base + quoted_text_start_idx); + char *url = urlifier->get_url_for_quoted_text (start, quoted_len); if (!url) /* No URL for this quoted text; do nothing. */ - return; + return quoted_text_end_idx; - /* Stash a copy of the quoted text. */ - char *text = xstrndup (start, len); + /* Stash a copy of the remainder of the chunk. */ + char *text = xstrndup (start, + obstack_object_size (obstack) - quoted_text_start_idx); /* Replace quoted text... */ - buffer->chunk_obstack.next_free -= len; + obstack->next_free = obstack->object_base + quoted_text_start_idx; /* ...with URLified version of the text. */ /* Begin URL. */ @@ -1089,27 +1097,136 @@ urlify_quoted_string (pretty_printer *pp, case URL_FORMAT_NONE: gcc_unreachable (); case URL_FORMAT_ST: - obstack_append_string (&buffer->chunk_obstack, - "\33]8;;"); - obstack_append_string (&buffer->chunk_obstack, url); - obstack_append_string (&buffer->chunk_obstack, - "\33\\"); + obstack_append_string (obstack, "\33]8;;"); + obstack_append_string (obstack, url); + obstack_append_string (obstack, "\33\\"); break; case URL_FORMAT_BEL: - obstack_append_string (&buffer->chunk_obstack, - "\33]8;;"); - obstack_append_string (&buffer->chunk_obstack, url); - obstack_append_string (&buffer->chunk_obstack, - "\a"); + obstack_append_string (obstack, "\33]8;;"); + obstack_append_string (obstack, url); + obstack_append_string (obstack, "\a"); break; } - /* Add the text back. */ - obstack_append_string (&buffer->chunk_obstack, text); + /* Add back the quoted part of the text. */ + obstack_append_string (obstack, text, quoted_len); /* End URL. */ - obstack_append_string (&buffer->chunk_obstack, + obstack_append_string (obstack, get_end_url_string (pp)); + + size_t new_end_idx = obstack_object_size (obstack); + + /* Add back the remainder of the text after the quoted part. */ + obstack_append_string (obstack, text + quoted_len); free (text); free (url); + return new_end_idx; +} + +/* A class for tracking quoted text within a buffer for + use by a urlifier. */ + +class quoting_info +{ +public: + /* Called when quoted text is begun in phase 1 or 2. */ + void on_begin_quote (const output_buffer &buf, + unsigned chunk_idx) + { + /* Stash location of start of quoted string. */ + size_t byte_offset = obstack_object_size (&buf.chunk_obstack); + m_loc_last_open_quote = location (chunk_idx, byte_offset); + } + + /* Called when quoted text is ended in phase 1 or 2. */ + void on_end_quote (pretty_printer *pp, + output_buffer &buf, + unsigned chunk_idx, + const urlifier &urlifier) + { + /* If possible, do urlification now. */ + if (chunk_idx == m_loc_last_open_quote.m_chunk_idx) + { + urlify_quoted_string (pp, + &buf.chunk_obstack, + &urlifier, + m_loc_last_open_quote.m_byte_offset, + obstack_object_size (&buf.chunk_obstack)); + m_loc_last_open_quote = location (); + return; + } + /* Otherwise the quoted text straddles multiple chunks. + Stash the location of end of quoted string for use in phase 3. */ + size_t byte_offset = obstack_object_size (&buf.chunk_obstack); + m_phase_3_quotes.push_back (run (m_loc_last_open_quote, + location (chunk_idx, byte_offset))); + m_loc_last_open_quote = location (); + } + + bool has_phase_3_quotes_p () const + { + return m_phase_3_quotes.size () > 0; + } + void handle_phase_3 (pretty_printer *pp, + const urlifier &urlifier); + +private: + struct location + { + location () + : m_chunk_idx (UINT_MAX), + m_byte_offset (SIZE_MAX) + { + } + + location (unsigned chunk_idx, + size_t byte_offset) + : m_chunk_idx (chunk_idx), + m_byte_offset (byte_offset) + { + } + + unsigned m_chunk_idx; + size_t m_byte_offset; + }; + + struct run + { + run (location start, location end) + : m_start (start), m_end (end) + { + } + + location m_start; + location m_end; + }; + + location m_loc_last_open_quote; + std::vector<run> m_phase_3_quotes; +}; + +static void +on_begin_quote (const output_buffer &buf, + unsigned chunk_idx, + const urlifier *urlifier) +{ + if (!urlifier) + return; + if (!buf.cur_chunk_array->m_quotes) + buf.cur_chunk_array->m_quotes = new quoting_info (); + buf.cur_chunk_array->m_quotes->on_begin_quote (buf, chunk_idx); +} + +static void +on_end_quote (pretty_printer *pp, + output_buffer &buf, + unsigned chunk_idx, + const urlifier *urlifier) +{ + if (!urlifier) + return; + if (!buf.cur_chunk_array->m_quotes) + buf.cur_chunk_array->m_quotes = new quoting_info (); + buf.cur_chunk_array->m_quotes->on_end_quote (pp, buf, chunk_idx, *urlifier); } /* The following format specifiers are recognized as being client independent: @@ -1161,11 +1278,12 @@ urlify_quoted_string (pretty_printer *pp, "before %<quoted%> after" with a URLIFIER that has a URL for "quoted" might be emitted as: "before `BEGIN_URL(http://example.com)quotedEND_URL' after" - This only works for message fragments that are: + This is handled here for message fragments that are: - quoted entirely in phase 1 (e.g. "%<this is quoted%>"), or - quoted entirely in phase 2 (e.g. "%qs"), - but *not* in strings that use a mixture of both phases - (e.g. "%<this is a mixture: %s %>"). */ + Quoted fragments that use a mixture of both phases + (e.g. "%<this is a mixture: %s %>") + are stashed into the output_buffer's m_quotes for use in phase 3. */ void pp_format (pretty_printer *pp, @@ -1182,12 +1300,11 @@ pp_format (pretty_printer *pp, bool any_unnumbered = false, any_numbered = false; const char **formatters[PP_NL_ARGMAX]; - /* Keep track of location of last "%", if any. */ - size_t quoted_text_start_idx = 0; - /* Allocate a new chunk structure. */ new_chunk_array = XOBNEW (&buffer->chunk_obstack, struct chunk_info); + new_chunk_array->prev = buffer->cur_chunk_array; + new_chunk_array->m_quotes = nullptr; buffer->cur_chunk_array = new_chunk_array; args = new_chunk_array->args; @@ -1229,20 +1346,14 @@ pp_format (pretty_printer *pp, obstack_grow (&buffer->chunk_obstack, colorstr, strlen (colorstr)); p++; - /* Stash offset of start of quoted string. */ - quoted_text_start_idx - = obstack_object_size (&buffer->chunk_obstack); - + on_begin_quote (*buffer, chunk, urlifier); continue; } case '>': { - if (quoted_text_start_idx) - { - urlify_quoted_string (pp, urlifier, quoted_text_start_idx); - quoted_text_start_idx = 0; - } + on_end_quote (pp, *buffer, chunk, urlifier); + const char *colorstr = colorize_stop (pp_show_color (pp)); obstack_grow (&buffer->chunk_obstack, colorstr, strlen (colorstr)); } @@ -1282,14 +1393,7 @@ pp_format (pretty_printer *pp, default: /* Handled in phase 2. Terminate the plain chunk here. */ obstack_1grow (&buffer->chunk_obstack, '\0'); - gcc_assert (chunk < PP_NL_ARGMAX * 2); args[chunk++] = XOBFINISH (&buffer->chunk_obstack, const char *); - /* We can't yet handle urlifying quoted strings that use - a combination of phase 1 and phase 2 e.g. - "did you mean %<-%s%>". - Stop any phase 1 quoted text if there are going to be any - phase 2 quoted chunks. */ - quoted_text_start_idx = 0; break; } @@ -1392,7 +1496,6 @@ pp_format (pretty_printer *pp, bool plus = false; bool hash = false; bool quote = false; - quoted_text_start_idx = 0; /* We do not attempt to enforce any ordering on the modifier characters. */ @@ -1435,8 +1538,7 @@ pp_format (pretty_printer *pp, if (quote) { pp_begin_quote (pp, pp_show_color (pp)); - quoted_text_start_idx - = obstack_object_size (&buffer->chunk_obstack); + on_begin_quote (*buffer, chunk, urlifier); } switch (*p) @@ -1608,11 +1710,7 @@ pp_format (pretty_printer *pp, if (quote) { - if (quoted_text_start_idx) - { - urlify_quoted_string (pp, urlifier, quoted_text_start_idx); - quoted_text_start_idx = 0; - } + on_end_quote (pp, *buffer, chunk, urlifier); pp_end_quote (pp, pp_show_color (pp)); } @@ -1636,9 +1734,136 @@ pp_format (pretty_printer *pp, pp_clear_state (pp); } -/* Format of a message pointed to by TEXT. */ +struct auto_obstack +{ + auto_obstack () + { + obstack_init (&m_obstack); + } + + ~auto_obstack () + { + obstack_free (&m_obstack, NULL); + } + + void grow (const void *src, size_t length) + { + obstack_grow (&m_obstack, src, length); + } + + void *object_base () const + { + return m_obstack.object_base; + } + + size_t object_size () const + { + return obstack_object_size (&m_obstack); + } + + obstack m_obstack; +}; + +/* Subroutine of pp_output_formatted_text for the awkward case where + quoted text straddles multiple chunks. + + Flush PP's buffer's chunks to PP's output buffer, whilst inserting + URLs for any quoted text that should be URLified. + + For example, given: + | pp_format (pp, + | "unrecognized option %qs; did you mean %<-%s%>", + | "foo", "foption"); + we would have these chunks: + | chunk 0: "unrecognized option " + | chunk 1: "`foo'" (already checked for urlification) + | chunk 2: "; did you mean `-" + | ^* + | chunk 3: "foption" + | ******* + | chunk 4: "'" + | ^ + and this quoting_info would have recorded the open quote near the end + of chunk 2 and close quote at the start of chunk 4; this function would + check the combination of the end of chunk 2 and all of chunk 3 ("-foption") + for urlification. */ + void -pp_output_formatted_text (pretty_printer *pp) +quoting_info::handle_phase_3 (pretty_printer *pp, + const urlifier &urlifier) +{ + unsigned int chunk; + output_buffer * const buffer = pp_buffer (pp); + struct chunk_info *chunk_array = buffer->cur_chunk_array; + const char **args = chunk_array->args; + + /* We need to construct the string into an intermediate buffer + for this case, since using pp_string can introduce prefixes + and line-wrapping, and omit whitespace at the start of lines. */ + auto_obstack combined_buf; + + /* Iterate simultaneously through both + - the chunks and + - the runs of quoted characters + Accumulate text from the chunks into combined_buf, and handle + runs of quoted characters when handling the chunks they + correspond to. */ + size_t start_of_run_byte_offset = 0; + std::vector<quoting_info::run>::const_iterator iter_run + = buffer->cur_chunk_array->m_quotes->m_phase_3_quotes.begin (); + std::vector<quoting_info::run>::const_iterator end_runs + = buffer->cur_chunk_array->m_quotes->m_phase_3_quotes.end (); + for (chunk = 0; args[chunk]; chunk++) + { + size_t start_of_chunk_idx = combined_buf.object_size (); + + combined_buf.grow (args[chunk], strlen (args[chunk])); + + if (iter_run != end_runs + && chunk == iter_run->m_end.m_chunk_idx) + { + /* A run is ending; consider for it urlification. */ + const size_t end_of_run_byte_offset + = start_of_chunk_idx + iter_run->m_end.m_byte_offset; + const size_t end_offset + = urlify_quoted_string (pp, + &combined_buf.m_obstack, + &urlifier, + start_of_run_byte_offset, + end_of_run_byte_offset); + + /* If URLification occurred it will have grown the buffer. + We need to update start_of_chunk_idx so that offsets + relative to it are still correct, for the case where + we have a chunk that both ends a quoted run and starts + another quoted run. */ + gcc_assert (end_offset >= end_of_run_byte_offset); + start_of_chunk_idx += end_offset - end_of_run_byte_offset; + + iter_run++; + } + if (iter_run != end_runs + && chunk == iter_run->m_start.m_chunk_idx) + { + /* Note where the run starts w.r.t. the composed buffer. */ + start_of_run_byte_offset + = start_of_chunk_idx + iter_run->m_start.m_byte_offset; + } + } + + /* Now print to PP. */ + const char *start + = static_cast <const char *> (combined_buf.object_base ()); + pp_maybe_wrap_text (pp, start, start + combined_buf.object_size ()); +} + +/* Format of a message pointed to by TEXT. + If URLIFIER is non-null then use it on any quoted text that was not + handled in phases 1 or 2 to potentially add URLs. */ + +void +pp_output_formatted_text (pretty_printer *pp, + const urlifier *urlifier) { unsigned int chunk; output_buffer * const buffer = pp_buffer (pp); @@ -1649,11 +1874,20 @@ pp_output_formatted_text (pretty_printer *pp) /* This is a third phase, first 2 phases done in pp_format_args. Now we actually print it. */ - for (chunk = 0; args[chunk]; chunk++) - pp_string (pp, args[chunk]); + + /* If we have any deferred urlification, handle it now. */ + if (urlifier + && pp->url_format != URL_FORMAT_NONE + && buffer->cur_chunk_array->m_quotes + && buffer->cur_chunk_array->m_quotes->has_phase_3_quotes_p ()) + buffer->cur_chunk_array->m_quotes->handle_phase_3 (pp, *urlifier); + else + for (chunk = 0; args[chunk]; chunk++) + pp_string (pp, args[chunk]); /* Deallocate the chunk structure and everything after it (i.e. the associated series of formatted strings). */ + delete buffer->cur_chunk_array->m_quotes; buffer->cur_chunk_array = chunk_array->prev; obstack_free (&buffer->chunk_obstack, chunk_array); } @@ -2605,6 +2839,20 @@ test_pp_format () assert_pp_format (SELFTEST_LOCATION, "item 3 of 7", "item %i of %i", 3, 7); assert_pp_format (SELFTEST_LOCATION, "problem with `bar' at line 10", "problem with %qs at line %i", "bar", 10); + + /* Verified numbered args. */ + assert_pp_format (SELFTEST_LOCATION, + "foo: second bar: first", + "foo: %2$s bar: %1$s", + "first", "second"); + assert_pp_format (SELFTEST_LOCATION, + "foo: 1066 bar: 1776", + "foo: %2$i bar: %1$i", + 1776, 1066); + assert_pp_format (SELFTEST_LOCATION, + "foo: second bar: 1776", + "foo: %2$s bar: %1$i", + 1776, "second"); } /* A subclass of pretty_printer for use by test_prefixes_and_wrapping. */ @@ -2786,7 +3034,7 @@ pp_printf_with_urlifier (pretty_printer *pp, va_start (ap, msg); text_info text (msg, &ap, errno); pp_format (pp, &text, urlifier); - pp_output_formatted_text (pp); + pp_output_formatted_text (pp, urlifier); va_end (ap); } @@ -2862,9 +3110,71 @@ test_urlification () pp_printf_with_urlifier (&pp, &urlifier, "foo %<-f%s%> bar", "option"); - /* We don't support this, but make sure we don't crash. */ ASSERT_STREQ - ("foo `-foption' bar", + ("foo `\33]8;;http://example.com\33\\-foption\33]8;;\33\\' bar", + pp_formatted_text (&pp)); + } + + /* Likewise, where there is trailing phase 1 content within the + quoted region. */ + { + pretty_printer pp; + pp.url_format = URL_FORMAT_ST; + pp_printf_with_urlifier (&pp, &urlifier, + "foo %<-f%sion%> bar %<-f%sion%> baz", + "opt", "opt"); + ASSERT_STREQ + ("foo `\33]8;;http://example.com\33\\-foption\33]8;;\33\\' bar `\33]8;;http://example.com\33\\-foption\33]8;;\33\\' baz", + pp_formatted_text (&pp)); + } + + /* Likewise. */ + { + pretty_printer pp; + pp.url_format = URL_FORMAT_ST; + pp_printf_with_urlifier (&pp, &urlifier, + "foo %<%sption%> bar %<-f%sion%> baz", + "-fo", "opt"); + ASSERT_STREQ + ("foo `\33]8;;http://example.com\33\\-foption\33]8;;\33\\' bar `\33]8;;http://example.com\33\\-foption\33]8;;\33\\' baz", + pp_formatted_text (&pp)); + } + + /* Another mixed usage of %< and %s, where the quoted string is built + between a mixture of phase 1 and multiple phase 2. */ + { + pretty_printer pp; + pp.url_format = URL_FORMAT_ST; + pp_printf_with_urlifier (&pp, &urlifier, + "foo %<-f%s%s%> bar", + "opt", "ion"); + ASSERT_STREQ + ("foo `\33]8;;http://example.com\33\\-foption\33]8;;\33\\' bar", + pp_formatted_text (&pp)); + } + + /* Mixed usage of %< and %s with a prefix. */ + { + pretty_printer pp; + pp.url_format = URL_FORMAT_ST; + pp_set_prefix (&pp, xstrdup ("PREFIX")); + pp_printf_with_urlifier (&pp, &urlifier, + "foo %<-f%s%> bar", + "option"); + ASSERT_STREQ + ("PREFIXfoo `\33]8;;http://example.com\33\\-foption\33]8;;\33\\' bar", + pp_formatted_text (&pp)); + } + + /* Example of mixed %< and %s with numbered args. */ + { + pretty_printer pp; + pp.url_format = URL_FORMAT_ST; + pp_printf_with_urlifier (&pp, &urlifier, + "foo %<-f%2$st%1$sn%> bar", + "io", "op"); + ASSERT_STREQ + ("foo `\33]8;;http://example.com\33\\-foption\33]8;;\33\\' bar", pp_formatted_text (&pp)); } } diff --git a/gcc/pretty-print.h b/gcc/pretty-print.h index 4548c25..14a225e 100644 --- a/gcc/pretty-print.h +++ b/gcc/pretty-print.h @@ -69,6 +69,8 @@ enum diagnostic_prefixing_rule_t DIAGNOSTICS_SHOW_PREFIX_EVERY_LINE = 0x2 }; +class quoting_info; + /* The chunk_info data structure forms a stack of the results from the first phase of formatting (pp_format) which have not yet been output (pp_output_formatted_text). A stack is necessary because @@ -86,6 +88,10 @@ struct chunk_info text, and the third phase simply emits all the chunks in sequence with appropriate line-wrapping. */ const char *args[PP_NL_ARGMAX * 2]; + + /* If non-null, information on quoted text runs within the chunks + for use by a urlifier. */ + quoting_info *m_quotes; }; /* The output buffer datatype. This is best seen as an abstract datatype @@ -409,7 +415,8 @@ extern void pp_flush (pretty_printer *); extern void pp_really_flush (pretty_printer *); extern void pp_format (pretty_printer *, text_info *, const urlifier * = nullptr); -extern void pp_output_formatted_text (pretty_printer *); +extern void pp_output_formatted_text (pretty_printer *, + const urlifier * = nullptr); extern void pp_format_verbatim (pretty_printer *, text_info *); extern void pp_indent (pretty_printer *); diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index a8437be..ef27cf1 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,886 @@ +2024-01-16 David Malcolm <dmalcolm@redhat.com> + + PR analyzer/106229 + * c-c++-common/analyzer/taint-index-pr106229.c: New test. + +2024-01-16 David Malcolm <dmalcolm@redhat.com> + + PR analyzer/113333 + * c-c++-common/analyzer/calloc-1.c: Add tests. + * c-c++-common/analyzer/pr96639.c: Update expected results. + * gcc.dg/analyzer/data-model-9.c: Likewise. + +2024-01-15 Marek Polacek <polacek@redhat.com> + + PR c++/110065 + * g++.dg/concepts/auto8.C: New test. + * g++.dg/concepts/auto8a.C: New test. + +2024-01-15 Patrick Palka <ppalka@redhat.com> + + * g++.dg/template/partial-specialization14.C: New test. + +2024-01-15 Patrick Palka <ppalka@redhat.com> + + PR c++/104634 + * g++.dg/cpp2a/concepts-explicit-inst6.C: New test. + +2024-01-15 Patrick Palka <ppalka@redhat.com> + + PR c++/109899 + * g++.dg/cpp0x/initlist-array21.C: New test. + +2024-01-15 H.J. Lu <hjl.tools@gmail.com> + + PR testsuite/113369 + * g++.dg/abi/ref-temp1.C: Remove --save-temps. + * g++.target/i386/bfloat_cpp_typecheck.C: Likewise. + * gcc.dg/debug/dwarf2/pr111080.c: Likewise. + * gcc.dg/debug/dwarf2/pr47939-1.c: Likewise. + * gcc.dg/debug/dwarf2/pr47939-2.c: Likewise. + * gcc.dg/debug/dwarf2/pr47939-3.c: Likewise. + * gcc.dg/debug/dwarf2/pr47939-4.c: Likewise. + +2024-01-15 Jakub Jelinek <jakub@redhat.com> + + PR rtl-optimization/113048 + * gcc.target/i386/pr113048.c: New test. + +2024-01-15 Liao Shihua <shihua@iscas.ac.cn> + + * gcc.target/riscv/scalar_bitmanip_intrinsic-32.c: New test. + * gcc.target/riscv/scalar_bitmanip_intrinsic-64-emulated.c: New test. + * gcc.target/riscv/scalar_bitmanip_intrinsic-64.c: New test. + +2024-01-15 Liao Shihua <shihua@iscas.ac.cn> + + * gcc.target/riscv/scalar_crypto_intrinsic-32.c: New test. + * gcc.target/riscv/scalar_crypto_intrinsic-64.c: New test. + +2024-01-15 Liao Shihua <shihua@iscas.ac.cn> + + * gcc.target/riscv/zbb_32_bswap-2.c: Moved to... + * gcc.target/riscv/zbb_bswap16.c: ...here. + * gcc.target/riscv/zbkb32.c: Remove __builtin_riscv_(un)zip and + zip,__builtin_riscv_brev8. + * gcc.target/riscv/zbkb64.c: Remove __builtin_riscv_brev8. + * gcc.target/riscv/zbb_32_bswap-1.c: Removed. + * gcc.target/riscv/zbb_bswap-1.c: Removed. + * gcc.target/riscv/zbb_bswap-2.c: Removed. + * gcc.target/riscv/zbbw.c: Removed. + * gcc.target/riscv/zbc32.c: Removed. + * gcc.target/riscv/zbc64.c: Removed. + * gcc.target/riscv/zbkc32.c: Removed. + * gcc.target/riscv/zbkc64.c: Removed. + * gcc.target/riscv/zbkx32.c: Removed. + * gcc.target/riscv/zbkx64.c: Removed. + * gcc.target/riscv/zknd32-2.c: Removed. + * gcc.target/riscv/zknd64-2.c: Removed. + * gcc.target/riscv/zkne32-2.c: Removed. + * gcc.target/riscv/zkne64-2.c: Removed. + * gcc.target/riscv/zknh-sha256-32.c: Removed. + * gcc.target/riscv/zknh-sha256-64.c: Removed. + * gcc.target/riscv/zknh-sha512-32.c: Removed. + * gcc.target/riscv/zknh-sha512-64.c: Removed. + * gcc.target/riscv/zksed32-2.c: Removed. + * gcc.target/riscv/zksed64-2.c: Removed. + * gcc.target/riscv/zksh32.c: Removed. + * gcc.target/riscv/zksh64.c: Removed. + +2024-01-15 Juzhe-Zhong <juzhe.zhong@rivai.ai> + + PR target/113247 + * gcc.target/riscv/rvv/autovec/vls/reduc-19.c: Adapt test. + * gcc.target/riscv/rvv/autovec/vls/reduc-20.c: Ditto. + * gcc.target/riscv/rvv/autovec/vls/reduc-21.c: Ditto. + * gcc.dg/vect/costmodel/riscv/rvv/pr113247-1.c: New test. + * gcc.dg/vect/costmodel/riscv/rvv/pr113247-2.c: New test. + * gcc.dg/vect/costmodel/riscv/rvv/pr113247-3.c: New test. + * gcc.dg/vect/costmodel/riscv/rvv/pr113247-4.c: New test. + +2024-01-15 Juzhe-Zhong <juzhe.zhong@rivai.ai> + + PR target/113281 + * gcc.dg/vect/costmodel/riscv/rvv/pr113281-3.c: New test. + * gcc.dg/vect/costmodel/riscv/rvv/pr113281-4.c: New test. + * gcc.dg/vect/costmodel/riscv/rvv/pr113281-5.c: New test. + +2024-01-15 Juzhe-Zhong <juzhe.zhong@rivai.ai> + + * gcc.target/riscv/rvv/autovec/vls/reduc-1.c: Add dump check. + * gcc.target/riscv/rvv/autovec/vls/reduc-10.c: Ditto. + * gcc.target/riscv/rvv/autovec/vls/reduc-11.c: Ditto. + * gcc.target/riscv/rvv/autovec/vls/reduc-12.c: Ditto. + * gcc.target/riscv/rvv/autovec/vls/reduc-13.c: Ditto. + * gcc.target/riscv/rvv/autovec/vls/reduc-14.c: Ditto. + * gcc.target/riscv/rvv/autovec/vls/reduc-15.c: Ditto. + * gcc.target/riscv/rvv/autovec/vls/reduc-16.c: Ditto. + * gcc.target/riscv/rvv/autovec/vls/reduc-17.c: Ditto. + * gcc.target/riscv/rvv/autovec/vls/reduc-18.c: Ditto. + * gcc.target/riscv/rvv/autovec/vls/reduc-19.c: Ditto. + * gcc.target/riscv/rvv/autovec/vls/reduc-2.c: Ditto. + * gcc.target/riscv/rvv/autovec/vls/reduc-20.c: Ditto. + * gcc.target/riscv/rvv/autovec/vls/reduc-21.c: Ditto. + * gcc.target/riscv/rvv/autovec/vls/reduc-3.c: Ditto. + * gcc.target/riscv/rvv/autovec/vls/reduc-4.c: Ditto. + * gcc.target/riscv/rvv/autovec/vls/reduc-5.c: Ditto. + * gcc.target/riscv/rvv/autovec/vls/reduc-6.c: Ditto. + * gcc.target/riscv/rvv/autovec/vls/reduc-7.c: Ditto. + * gcc.target/riscv/rvv/autovec/vls/reduc-8.c: Ditto. + * gcc.target/riscv/rvv/autovec/vls/reduc-9.c: Ditto. + +2024-01-15 Jakub Jelinek <jakub@redhat.com> + + PR tree-optimization/113370 + * gcc.dg/torture/bitint-48.c: New test. + +2024-01-15 Juzhe-Zhong <juzhe.zhong@rivai.ai> + + PR target/113393 + * gcc.target/riscv/rvv/autovec/pr113393-1.c: New test. + * gcc.target/riscv/rvv/autovec/pr113393-2.c: New test. + * gcc.target/riscv/rvv/autovec/pr113393-3.c: New test. + +2024-01-15 YunQiang Su <syq@gcc.gnu.org> + + * gcc.target/mips/unaligned-2.c: Add -mno-abicalls option. + +2024-01-14 John David Anglin <danglin@gcc.gnu.org> + + * gcc.dg/builtin-object-size-1.c: Disable tests for strdup/strndup + on __hpux__. + * gcc.dg/builtin-object-size-2.c: Likewise. + * gcc.dg/builtin-object-size-3.c: Likewise. + * gcc.dg/builtin-object-size-4.c: Likewise. + +2024-01-14 John David Anglin <danglin@gcc.gnu.org> + + * gcc.dg/builtin-dynamic-object-size-0.c: Skip on hppa*-*-hpux*. + * gcc.dg/builtin-dynamic-object-size-1.c: Likewise. + * gcc.dg/builtin-dynamic-object-size-2.c: Likewise. + * gcc.dg/builtin-dynamic-object-size-3.c: Likewise. + * gcc.dg/builtin-dynamic-object-size-4.c: Likewise. + +2024-01-14 John David Anglin <danglin@gcc.gnu.org> + + * gcc.dg/Wattributes-6.c: Fix dg-warning on hppa*64*-*-*. + +2024-01-14 John David Anglin <danglin@gcc.gnu.org> + + PR analyzer/113150 + * c-c++-common/analyzer/fd-glibc-byte-stream-socket.c: Skip + on hppa*-*-hpux*. + * c-c++-common/analyzer/fd-manpage-getaddrinfo-client.c: Likewise. + * c-c++-common/analyzer/fd-mappage-getaddrinfo-server.c: Likewise. + * c-c++-common/analyzer/fd-symbolic-socket.c: Likewise. + * gcc.dg/analyzer/fd-glibc-byte-stream-connection-server.c: Likewise. + +2024-01-14 Georg-Johann Lay <avr@gjlay.de> + + PR target/112944 + * gcc.target/avr/torture/pr112944-flmap-0.c: New test. + * gcc.target/avr/torture/pr112944-flmap-1.c: New test. + +2024-01-13 Harald Anlauf <anlauf@gmx.de> + + PR fortran/67277 + * gfortran.dg/ishftc_optional_size_1.f90: New test. + +2024-01-13 John David Anglin <danglin@gcc.gnu.org> + + * gfortran.dg/fmt_f_default_field_width_3.f90: Add hppa*64*-*-hpux* + to real_16 dg-error targets. + * gfortran.dg/fmt_g_default_field_width_3.f90: Likewise. + +2024-01-13 Harald Anlauf <anlauf@gmx.de> + + PR fortran/113305 + * gfortran.dg/do_concurrent_7.f90: New test. + +2024-01-13 Jakub Jelinek <jakub@redhat.com> + + PR tree-optimization/113361 + * gcc.dg/torture/bitint-47.c: New test. + +2024-01-13 Jakub Jelinek <jakub@redhat.com> + + PR tree-optimization/113287 + * gcc.dg/vect/vect-early-break_100-pr113287.c: Use long long instead + of long. + +2024-01-13 Jakub Jelinek <jakub@redhat.com> + + * g++.dg/abi/mangle79.C: New test. + +2024-01-13 Andrew Pinski <quic_apinski@quicinc.com> + + PR tree-optimization/107823 + PR tree-optimization/110768 + PR tree-optimization/110941 + PR tree-optimization/110450 + PR tree-optimization/110841 + * gcc.dg/tree-ssa/ssa-thread-22.c: New test. + * gcc.dg/tree-ssa/vrp-loop-1.c: New test. + * gcc.dg/tree-ssa/vrp-loop-2.c: New test. + * gcc.dg/tree-ssa/vrp-unreachable-1.c: New test. + * gcc.dg/tree-ssa/vrp-unreachable-2.c: New test. + +2024-01-12 Jason Merrill <jason@redhat.com> + + PR c++/113038 + * g++.dg/modules/pr106304_b.C: Add dynamic_cast. + +2024-01-12 Ezra Sitorus <ezra.sitorus@arm.com> + + * gcc.target/arm/simd/vld1_base_xN_1.c: Updated. + * gcc.target/arm/simd/vld1_bf16_xN_1.c: Updated. + * gcc.target/arm/simd/vld1_fp16_xN_1.c: Updated. + * gcc.target/arm/simd/vld1_p64_xN_1.c: Updated. + +2024-01-12 Ezra Sitorus <ezra.sitorus@arm.com> + + * gcc.target/arm/simd/vld1_base_xN_1.c: Updated. + * gcc.target/arm/simd/vld1_bf16_xN_1.c: Updated. + * gcc.target/arm/simd/vld1_fp16_xN_1.c: Updated. + * gcc.target/arm/simd/vld1_p64_xN_1.c: Updated. + +2024-01-12 Ezra Sitorus <ezra.sitorus@arm.com> + + * gcc.target/arm/simd/vld1_base_xN_1.c: Add new tests. + * gcc.target/arm/simd/vld1_bf16_xN_1.c: Add new tests. + * gcc.target/arm/simd/vld1_fp16_xN_1.c: Add new tests. + * gcc.target/arm/simd/vld1_p64_xN_1.c: Add new tests. + +2024-01-12 Ezra Sitorus <ezra.sitorus@arm.com> + + * gcc.target/arm/simd/vst1q_base_xN_1.c: Updated + * gcc.target/arm/simd/vst1q_bf16_xN_1.c: Updated + * gcc.target/arm/simd/vst1q_fp16_xN_1.c: Updated + * gcc.target/arm/simd/vst1q_p64_xN_1.c: Updated + +2024-01-12 Ezra Sitorus <ezra.sitorus@arm.com> + + * gcc.target/arm/simd/vst1q_base_xN_1.c: Add new tests. + * gcc.target/arm/simd/vst1q_bf16_xN_1.c: Add new tests. + * gcc.target/arm/simd/vst1q_fp16_xN_1.c: Add new tests. + * gcc.target/arm/simd/vst1q_p64_xN_1.c: Add new tests. + +2024-01-12 Ezra Sitorus <ezra.sitorus@arm.com> + + * gcc.target/arm/simd/vst1q_base_xN_1.c: Add new tests. + * gcc.target/arm/simd/vst1q_bf16_xN_1.c: Add new tests. + * gcc.target/arm/simd/vst1q_fp16_xN_1.c: Add new tests. + * gcc.target/arm/simd/vst1q_p64_xN_1.c: Add new tests. + +2024-01-12 Ezra Sitorus <ezra.sitorus@arm.com> + + * gcc.target/arm/simd/vst1_base_xN_1.c: Updated. + * gcc.target/arm/simd/vst1_bf16_xN_1.c: Updated. + * gcc.target/arm/simd/vst1_fp16_xN_1.c: Updated. + * gcc.target/arm/simd/vst1_p64_xN_1.c: Updated. + +2024-01-12 Ezra Sitorus <ezra.sitorus@arm.com> + + * gcc.target/arm/simd/vst1_base_xN_1.c: Updated. + * gcc.target/arm/simd/vst1_bf16_xN_1.c: Updated. + * gcc.target/arm/simd/vst1_fp16_xN_1.c: Updated. + * gcc.target/arm/simd/vst1_p64_xN_1.c: Updated. + +2024-01-12 Ezra Sitorus <ezra.sitorus@arm.com> + + * gcc.target/arm/simd/vst1_base_xN_1.c: Add new tests. + * gcc.target/arm/simd/vst1_bf16_xN_1.c: Add new tests. + * gcc.target/arm/simd/vst1_fp16_xN_1.c: Add new tests. + * gcc.target/arm/simd/vst1_p64_xN_1.c: Add new tests. + +2024-01-12 Ezra Sitorus <ezra.sitorus@arm.com> + + * gcc.target/arm/simd/vld1q_base_xN_1.c: Updated. + * gcc.target/arm/simd/vld1q_bf16_xN_1.c: Updated. + * gcc.target/arm/simd/vld1q_fp16_xN_1.c: Updated. + * gcc.target/arm/simd/vld1q_p64_xN_1.c: Updated. + +2024-01-12 Ezra Sitorus <ezra.sitorus@arm.com> + + * gcc.target/arm/simd/vld1q_base_xN_1.c: Add new tests. + * gcc.target/arm/simd/vld1q_bf16_xN_1.c: Add new tests. + * gcc.target/arm/simd/vld1q_fp16_xN_1.c: Add new tests. + * gcc.target/arm/simd/vld1q_p64_xN_1.c: Add new tests. + +2024-01-12 Ezra Sitorus <ezra.sitorus@arm.com> + + * gcc.target/arm/simd/vld1q_base_xN_1.c: Add new test. + * gcc.target/arm/simd/vld1q_bf16_xN_1.c: Add new test. + * gcc.target/arm/simd/vld1q_fp16_xN_1.c: Add new test. + * gcc.target/arm/simd/vld1q_p64_xN_1.c: Add new test. + +2024-01-12 Jakub Jelinek <jakub@redhat.com> + + PR c/113315 + * gcc.dg/bitint-65.c: New test. + * gcc.dg/bitint-66.c: New test. + +2024-01-12 Tamar Christina <tamar.christina@arm.com> + + PR tree-optimization/113287 + * gcc.dg/vect/vect-early-break_100-pr113287.c: Support non-bitint. + * gcc.dg/vect/vect-early-break_99-pr113287.c: Likewise. + * lib/target-supports.exp (bitint, bitint128, bitint575, bitint65535): + Document them. + +2024-01-12 Tamar Christina <tamar.christina@arm.com> + + PR tree-optimization/113178 + * gcc.dg/vect/vect-early-break_101-pr113178.c: New test. + * gcc.dg/vect/vect-early-break_102-pr113178.c: New test. + +2024-01-12 Tamar Christina <tamar.christina@arm.com> + + PR tree-optimization/113237 + * gcc.dg/vect/vect-early-break_98-pr113237.c: New test. + +2024-01-12 Tamar Christina <tamar.christina@arm.com> + + PR tree-optimization/113137 + PR tree-optimization/113136 + PR tree-optimization/113172 + PR tree-optimization/113178 + * g++.dg/vect/vect-early-break_4-pr113137.cc: New test. + * g++.dg/vect/vect-early-break_5-pr113137.cc: New test. + * gcc.dg/vect/vect-early-break_95-pr113137.c: New test. + * gcc.dg/vect/vect-early-break_96-pr113136.c: New test. + * gcc.dg/vect/vect-early-break_97-pr113172.c: New test. + +2024-01-12 Tamar Christina <tamar.christina@arm.com> + + PR tree-optimization/113135 + * gcc.dg/vect/vect-early-break_103-pr113135.c: New test. + +2024-01-12 Jason Merrill <jason@redhat.com> + + * g++.dg/cpp2a/concepts-memfun4.C: Change expected + reversed handling. + +2024-01-12 Richard Sandiford <richard.sandiford@arm.com> + + PR target/113196 + * gcc.target/aarch64/pr113196.c: New test. + * gcc.target/aarch64/simd/vmovl_high_1.c: Remove double include. + Expect uxtl2 rather than zip2. + * gcc.target/aarch64/vect_mixed_sizes_8.c: Expect zip1 rather + than uxtl. + * gcc.target/aarch64/vect_mixed_sizes_9.c: Likewise. + * gcc.target/aarch64/vect_mixed_sizes_10.c: Likewise. + +2024-01-12 Richard Sandiford <richard.sandiford@arm.com> + + PR target/112989 + * gcc.target/aarch64/sve/acle/general-c/clamp_1.c: Remove bogus + error test. + +2024-01-12 Juzhe-Zhong <juzhe.zhong@rivai.ai> + + PR target/113281 + * gcc.target/riscv/rvv/autovec/pr113209.c: Adapt test. + * gcc.dg/vect/costmodel/riscv/rvv/pr113281-1.c: New test. + * gcc.dg/vect/costmodel/riscv/rvv/pr113281-2.c: New test. + +2024-01-12 Jakub Jelinek <jakub@redhat.com> + + PR tree-optimization/113334 + * gcc.dg/torture/bitint-46.c: New test. + +2024-01-12 Jakub Jelinek <jakub@redhat.com> + + PR tree-optimization/113330 + * gcc.dg/bitint-69.c: New test. + +2024-01-12 Jakub Jelinek <jakub@redhat.com> + + PR tree-optimization/113323 + * gcc.dg/bitint-68.c: New test. + +2024-01-12 Jakub Jelinek <jakub@redhat.com> + + PR tree-optimization/113316 + * gcc.dg/bitint-67.c: New test. + +2024-01-12 Guillaume Gomez <guillaume1.gomez@gmail.com> + Antoni Boucher <bouanto@zoho.com> + + * jit.dg/all-non-failing-tests.h: Add new attributes tests. + * jit.dg/jit.exp: Add `jit-verify-assembler-output-not` test command. + * jit.dg/test-restrict-attribute.c: New test. + * jit.dg/test-alias-attribute.c: New test. + * jit.dg/test-always_inline-attribute.c: New test. + * jit.dg/test-cold-attribute.c: New test. + * jit.dg/test-const-attribute.c: New test. + * jit.dg/test-noinline-attribute.c: New test. + * jit.dg/test-nonnull-attribute.c: New test. + * jit.dg/test-pure-attribute.c: New test. + * jit.dg/test-used-attribute.c: New test. + * jit.dg/test-variable-attribute.c: New test. + * jit.dg/test-weak-attribute.c: New test. + +2024-01-12 Jakub Jelinek <jakub@redhat.com> + + * gcc.dg/bitint-31.c: Fix up #if conditions checking whether + __*_MANT_DIG__ is equal to a particular precision. + +2024-01-12 Juzhe-Zhong <juzhe.zhong@rivai.ai> + + * gcc.target/riscv/rvv/autovec/fold-min-poly.c: Remove -fno-vect-cost-model + +2024-01-12 Li Wei <liwei@loongson.cn> + + * gcc.target/loongarch/sign-extend-2.c: Adjust. + +2024-01-12 Li Wei <liwei@loongson.cn> + + * gcc.target/loongarch/sign-extend.c: Moved to... + * gcc.target/loongarch/sign-extend-1.c: ...here. + * gcc.target/loongarch/sign-extend-2.c: New test. + +2024-01-11 Julian Brown <julian@codesourcery.com> + + * gcc.dg/gomp/bad-array-section-c-1.c: New test. + * gcc.dg/gomp/bad-array-section-c-2.c: New test. + * gcc.dg/gomp/bad-array-section-c-3.c: New test. + * gcc.dg/gomp/bad-array-section-c-4.c: New test. + * gcc.dg/gomp/bad-array-section-c-5.c: New test. + * gcc.dg/gomp/bad-array-section-c-6.c: New test. + * gcc.dg/gomp/bad-array-section-c-7.c: New test. + * gcc.dg/gomp/bad-array-section-c-8.c: New test. + +2024-01-11 Jason Merrill <jason@redhat.com> + + PR c++/113191 + * g++.dg/cpp2a/concepts-memfun4.C: New test. + +2024-01-11 Jin Ma <jinma@linux.alibaba.com> + + * gcc.target/riscv/xtheadfmemidx-medany.c: New test. + +2024-01-11 Andrew Pinski <quic_apinski@quicinc.com> + + PR middle-end/113322 + * gcc.c-torture/compile/pr113322-1.c: New test. + +2024-01-11 Andrew Pinski <quic_apinski@quicinc.com> + + PR tree-optimization/113301 + * gcc.dg/tree-ssa/divide-8.c: New test. + +2024-01-11 Jason Merrill <jason@redhat.com> + + * g++.dg/cpp23/explicit-obj-diagnostics7.C: Remove xfail. + +2024-01-11 Tamar Christina <tamar.christina@arm.com> + + PR testsuite/113319 + * gcc.dg/bic-bitmask-13.c: Remove -save-temps. + * gcc.dg/bic-bitmask-14.c: Likewise. + * gcc.dg/bic-bitmask-15.c: Likewise. + * gcc.dg/bic-bitmask-16.c: Likewise. + * gcc.dg/bic-bitmask-17.c: Likewise. + * gcc.dg/bic-bitmask-18.c: Likewise. + * gcc.dg/bic-bitmask-19.c: Likewise. + * gcc.dg/bic-bitmask-20.c: Likewise. + * gcc.dg/bic-bitmask-21.c: Likewise. + * gcc.dg/bic-bitmask-22.c: Likewise. + * gcc.dg/bic-bitmask-7.c: Likewise. + * gcc.dg/vect/vect-early-break-run_1.c: Likewise. + * gcc.dg/vect/vect-early-break-run_10.c: Likewise. + * gcc.dg/vect/vect-early-break-run_2.c: Likewise. + * gcc.dg/vect/vect-early-break-run_3.c: Likewise. + * gcc.dg/vect/vect-early-break-run_4.c: Likewise. + * gcc.dg/vect/vect-early-break-run_5.c: Likewise. + * gcc.dg/vect/vect-early-break-run_6.c: Likewise. + * gcc.dg/vect/vect-early-break-run_7.c: Likewise. + * gcc.dg/vect/vect-early-break-run_8.c: Likewise. + * gcc.dg/vect/vect-early-break-run_9.c: Likewise. + +2024-01-11 Richard Biener <rguenther@suse.de> + + PR tree-optimization/112505 + * gcc.dg/vect/pr112505.c: New testcase. + +2024-01-11 Richard Biener <rguenther@suse.de> + + PR tree-optimization/113126 + * gcc.dg/torture/pr113126.c: New testcase. + +2024-01-11 Richard Biener <rguenther@suse.de> + + PR tree-optimization/112636 + * gcc.dg/pr112636.c: New testcase. + +2024-01-11 Pan Li <pan2.li@intel.com> + + * gcc.dg/pr30957-1.c: Remove. + +2024-01-11 Alex Coplan <alex.coplan@arm.com> + + PR target/113077 + * gcc.target/aarch64/pr113077.c: New test. + +2024-01-11 Richard Biener <rguenther@suse.de> + + PR tree-optimization/111003 + * gcc.dg/tree-ssa/pr111003.c: New testcase. + +2024-01-11 Richard Biener <rguenther@suse.de> + + PR middle-end/112740 + * gcc.dg/pr112740.c: New testcase. + +2024-01-11 Juzhe-Zhong <juzhe.zhong@rivai.ai> + + * gcc.target/riscv/rvv/autovec/partial/slp-1.c: Remove xfail. + * gcc.target/riscv/rvv/autovec/partial/slp-16.c: Ditto. + * gcc.target/riscv/rvv/autovec/partial/slp-3.c: Ditto. + * gcc.target/riscv/rvv/autovec/partial/slp-5.c: Ditto. + +2024-01-11 Lulu Cheng <chenglulu@loongson.cn> + + * gcc.target/loongarch/sign-extend-bitwise.c: New test. + +2024-01-11 liuhongt <hongtao.liu@intel.com> + + * gcc.target/i386/pr104401.c: New test. + * gcc.dg/tree-ssa/pr95906.c: Adjust testcase. + +2024-01-11 Gaius Mulley <gaiusmod2@gmail.com> + + PR modula2/112946 + * gm2/pim/fail/badbecomes.mod: New test. + * gm2/pim/fail/badexpression.mod: New test. + * gm2/pim/fail/badexpression2.mod: New test. + * gm2/pim/fail/badifin.mod: New test. + * gm2/pim/pass/goodifin.mod: New test. + +2024-01-10 Juzhe-Zhong <juzhe.zhong@rivai.ai> + + * gcc.dg/vect/costmodel/riscv/rvv/vla_vs_vls-10.c: Fix test. + * gcc.dg/vect/costmodel/riscv/rvv/vla_vs_vls-11.c: Ditto. + * gcc.dg/vect/costmodel/riscv/rvv/vla_vs_vls-12.c: Ditto. + +2024-01-10 Antoni Boucher <bouanto@zoho.com> + + PR jit/111396 + * jit.dg/all-non-failing-tests.h: Add note about test-ggc-bugfix. + * jit.dg/test-ggc-bugfix.c: New test. + +2024-01-10 Jin Ma <jinma@linux.alibaba.com> + + * gcc.target/riscv/xtheadint-push-pop.c: New test. + +2024-01-10 Tamar Christina <tamar.christina@arm.com> + + PR tree-optimization/112468 + * gcc.dg/fold-copysign-1.c: Modify tests based on if target supports + IFN_COPYSIGN. + * gcc.dg/pr55152-2.c: Likewise. + * gcc.dg/tree-ssa/abs-4.c: Likewise. + * gcc.dg/tree-ssa/backprop-6.c: Likewise. + * gcc.dg/tree-ssa/copy-sign-2.c: Likewise. + * gcc.dg/tree-ssa/mult-abs-2.c: Likewise. + * lib/target-supports.exp (check_effective_target_ifn_copysign): New. + +2024-01-10 Andrew Pinski <quic_apinski@quicinc.com> + + PR tree-optimization/112581 + * gcc.c-torture/execute/pr112581-1.c: New test. + +2024-01-10 Maciej W. Rozycki <macro@embecosm.com> + + * gcc.target/riscv/pr105314.c: Fix comment termination. + +2024-01-10 Maciej W. Rozycki <macro@embecosm.com> + + * gcc.target/riscv/cset-sext-sfb.c: New test. + * gcc.target/riscv/cset-sext-thead.c: New test. + * gcc.target/riscv/cset-sext-ventana.c: New test. + * gcc.target/riscv/cset-sext-zicond.c: New test. + * gcc.target/riscv/cset-sext.c: New test. + +2024-01-10 Jakub Jelinek <jakub@redhat.com> + + PR tree-optimization/112734 + * gcc.dg/bitint-64.c: New test. + +2024-01-10 Tamar Christina <tamar.christina@arm.com> + + PR tree-optimization/113287 + * gcc.dg/vect/vect-early-break_100-pr113287.c: New test. + * gcc.dg/vect/vect-early-break_99-pr113287.c: New test. + +2024-01-10 Richard Biener <rguenther@suse.de> + + PR tree-optimization/113078 + * gcc.dg/vect/vect-reduc-cond-sub.c: New testcase. + * gcc.target/i386/vect-pr113078.c: Likewise. + +2024-01-10 Julian Brown <julian@codesourcery.com> + + * g++.dg/gomp/bad-array-section-10.C: Adjust diagnostics for C++23 and + up. + +2024-01-10 Julian Brown <julian@codesourcery.com> + + * g++.dg/gomp/array-section-1.C: Fix scan output for 32-bit target. + * g++.dg/gomp/array-section-2.C: Likewise. + * g++.dg/gomp/bad-array-section-4.C: Adjust error output for 32-bit + target. + +2024-01-10 Tamar Christina <tamar.christina@arm.com> + + PR tree-optimization/113144 + PR tree-optimization/113145 + * gcc.dg/vect/vect-early-break_94-pr113144.c: New test. + +2024-01-10 Jakub Jelinek <jakub@redhat.com> + + PR tree-optimization/113297 + * gcc.dg/bitint-63.c: Fix PR number. + +2024-01-10 chenxiaolong <chenxiaolong@loongson.cn> + + * gcc.dg/vect/slp-21.c: Add loongarch. + +2024-01-10 chenxiaolong <chenxiaolong@loongson.cn> + + * lib/target-supports.exp: Removed an issue with "target keyword" + checking errors on LoongArch architecture. + +2024-01-10 Jakub Jelinek <jakub@redhat.com> + + PR tree-optimization/113120 + * gcc.dg/bitint-63.c: New test. + +2024-01-10 Juzhe-Zhong <juzhe.zhong@rivai.ai> + + * gcc.target/riscv/rvv/autovec/vls/avg-1.c: Adapt test. + * gcc.target/riscv/rvv/autovec/vls/avg-2.c: Ditto. + * gcc.target/riscv/rvv/autovec/vls/avg-3.c: Ditto. + * gcc.target/riscv/rvv/autovec/vls/avg-4.c: Ditto. + * gcc.target/riscv/rvv/autovec/vls/avg-5.c: Ditto. + * gcc.target/riscv/rvv/autovec/vls/avg-6.c: Ditto. + * gcc.target/riscv/rvv/autovec/widen/vec-avg-rv32gcv.c: Ditto. + * gcc.target/riscv/rvv/autovec/widen/vec-avg-rv64gcv.c: Ditto. + +2024-01-10 Kewen Lin <linkw@linux.ibm.com> + + PR testsuite/112751 + * gcc.target/powerpc/pcrel-sibcall-1.c: Replace noinline as noipa. + +2024-01-10 Juzhe-Zhong <juzhe.zhong@rivai.ai> + + * gcc.dg/vect/costmodel/riscv/rvv/dynamic-lmul2-7.c: Add assembler-not check. + +2024-01-09 Jason Merrill <jason@redhat.com> + + * g++.dg/torture/accessor-fixits-9-xobj.C: New test. + +2024-01-09 waffl3x <waffl3x@protonmail.com> + + PR c++/102609 + PR c++/102609 + C++23 P0847R7 (deducing this) - CWG2586. + * g++.dg/cpp23/explicit-obj-basic6.C: New test. + * g++.dg/cpp23/explicit-obj-default1.C: New test. + * g++.dg/cpp23/explicit-obj-default2.C: New test. + +2024-01-09 waffl3x <waffl3x@protonmail.com> + + PR c++/102609 + PR c++/102609 + C++23 P0847R7 (deducing this) - xobj lambdas. + * g++.dg/cpp23/explicit-obj-diagnostics8.C: New test. + * g++.dg/cpp23/explicit-obj-lambda1.C: New test. + * g++.dg/cpp23/explicit-obj-lambda10.C: New test. + * g++.dg/cpp23/explicit-obj-lambda11.C: New test. + * g++.dg/cpp23/explicit-obj-lambda12.C: New test. + * g++.dg/cpp23/explicit-obj-lambda13.C: New test. + * g++.dg/cpp23/explicit-obj-lambda2.C: New test. + * g++.dg/cpp23/explicit-obj-lambda3.C: New test. + * g++.dg/cpp23/explicit-obj-lambda4.C: New test. + * g++.dg/cpp23/explicit-obj-lambda5.C: New test. + * g++.dg/cpp23/explicit-obj-lambda6.C: New test. + * g++.dg/cpp23/explicit-obj-lambda7.C: New test. + * g++.dg/cpp23/explicit-obj-lambda8.C: New test. + * g++.dg/cpp23/explicit-obj-lambda9.C: New test. + +2024-01-09 waffl3x <waffl3x@protonmail.com> + + PR c++/102609 + PR c++/102609 + C++23 P0847R7 (deducing this) - diagnostics. + * g++.dg/cpp23/feat-cxx2b.C: Test existance and value of + __cpp_explicit_this_parameter feature test macro. + * g++.dg/cpp26/feat-cxx26.C: Likewise. + * g++.dg/cpp23/explicit-obj-cxx-dialect-A.C: New test. + * g++.dg/cpp23/explicit-obj-cxx-dialect-B.C: New test. + * g++.dg/cpp23/explicit-obj-cxx-dialect-C.C: New test. + * g++.dg/cpp23/explicit-obj-cxx-dialect-D.C: New test. + * g++.dg/cpp23/explicit-obj-cxx-dialect-E.C: New test. + * g++.dg/cpp23/explicit-obj-diagnostics1.C: New test. + * g++.dg/cpp23/explicit-obj-diagnostics2.C: New test. + * g++.dg/cpp23/explicit-obj-diagnostics3.C: New test. + * g++.dg/cpp23/explicit-obj-diagnostics4.C: New test. + * g++.dg/cpp23/explicit-obj-diagnostics5.C: New test. + * g++.dg/cpp23/explicit-obj-diagnostics6.C: New test. + * g++.dg/cpp23/explicit-obj-diagnostics7.C: New test. + +2024-01-09 waffl3x <waffl3x@protonmail.com> + + PR c++/102609 + PR c++/102609 + C++23 P0847R7 (deducing this) - initial functionality. + * g++.dg/cpp23/explicit-obj-basic1.C: New test. + * g++.dg/cpp23/explicit-obj-basic2.C: New test. + * g++.dg/cpp23/explicit-obj-basic3.C: New test. + * g++.dg/cpp23/explicit-obj-basic4.C: New test. + * g++.dg/cpp23/explicit-obj-basic5.C: New test. + * g++.dg/cpp23/explicit-obj-by-value1.C: New test. + * g++.dg/cpp23/explicit-obj-by-value2.C: New test. + * g++.dg/cpp23/explicit-obj-by-value3.C: New test. + * g++.dg/cpp23/explicit-obj-by-value4.C: New test. + * g++.dg/cpp23/explicit-obj-constraints.C: New test. + * g++.dg/cpp23/explicit-obj-constraints2.C: New test. + * g++.dg/cpp23/explicit-obj-ops-mem-arrow.C: New test. + * g++.dg/cpp23/explicit-obj-ops-mem-assignment.C: New test. + * g++.dg/cpp23/explicit-obj-ops-mem-call.C: New test. + * g++.dg/cpp23/explicit-obj-ops-mem-subscript.C: New test. + * g++.dg/cpp23/explicit-obj-ops-non-mem-dep.C: New test. + * g++.dg/cpp23/explicit-obj-ops-non-mem-non-dep.C: New test. + * g++.dg/cpp23/explicit-obj-ops-non-mem.h: New test. + * g++.dg/cpp23/explicit-obj-ops-requires-mem.C: New test. + * g++.dg/cpp23/explicit-obj-ops-requires-non-mem.C: New test. + * g++.dg/cpp23/explicit-obj-redecl.C: New test. + * g++.dg/cpp23/explicit-obj-redecl2.C: New test. + * g++.dg/cpp23/explicit-obj-redecl3.C: New test. + * g++.dg/cpp23/explicit-obj-redecl4.C: New test. + +2024-01-09 Jakub Jelinek <jakub@redhat.com> + + PR c/113262 + * gcc.dg/pr113262.c: New test. + +2024-01-09 Tamar Christina <tamar.christina@arm.com> + + PR tree-optimization/113199 + * gcc.target/gcn/pr113199.c: New test. + +2024-01-09 Tamar Christina <tamar.christina@arm.com> + + * gcc.target/arm/vect-early-break-cbranch.c: Accept thumb output. + +2024-01-09 Tamar Christina <tamar.christina@arm.com> + + PR c/113267 + * gcc.dg/pr113267.c: New test. + +2024-01-09 Tamar Christina <tamar.christina@arm.com> + + PR middle-end/113163 + * gcc.target/gcn/pr113163.c: New test. + +2024-01-09 Julian Brown <julian@codesourcery.com> + + * c-c++-common/gomp/map-6.c: Update expected output. + * c-c++-common/gomp/target-enter-data-1.c: Update scan test. + * g++.dg/gomp/array-section-1.C: New test. + * g++.dg/gomp/array-section-2.C: New test. + * g++.dg/gomp/bad-array-section-1.C: New test. + * g++.dg/gomp/bad-array-section-2.C: New test. + * g++.dg/gomp/bad-array-section-3.C: New test. + * g++.dg/gomp/bad-array-section-4.C: New test. + * g++.dg/gomp/bad-array-section-5.C: New test. + * g++.dg/gomp/bad-array-section-6.C: New test. + * g++.dg/gomp/bad-array-section-7.C: New test. + * g++.dg/gomp/bad-array-section-8.C: New test. + * g++.dg/gomp/bad-array-section-9.C: New test. + * g++.dg/gomp/bad-array-section-10.C: New test. + * g++.dg/gomp/bad-array-section-11.C: New test. + * g++.dg/gomp/has_device_addr-non-lvalue-1.C: New test. + * g++.dg/gomp/pr67522.C: Update expected output. + * g++.dg/gomp/ind-base-3.C: New test. + * g++.dg/gomp/map-assignment-1.C: New test. + * g++.dg/gomp/map-inc-1.C: New test. + * g++.dg/gomp/map-lvalue-ref-1.C: New test. + * g++.dg/gomp/map-ptrmem-1.C: New test. + * g++.dg/gomp/map-ptrmem-2.C: New test. + * g++.dg/gomp/map-static-cast-lvalue-1.C: New test. + * g++.dg/gomp/map-ternary-1.C: New test. + * g++.dg/gomp/member-array-2.C: New test. + +2024-01-09 Eric Botcazou <ebotcazou@adacore.com> + + * gnat.dg/bip_prim_func2.adb: New test. + * gnat.dg/bip_prim_func2_pkg.ads, gnat.dg/bip_prim_func2_pkg.adb: + New helper package. + +2024-01-09 Jakub Jelinek <jakub@redhat.com> + + PR tree-optimization/113210 + * gcc.c-torture/compile/pr113210.c: New test. + +2024-01-09 Eric Botcazou <ebotcazou@adacore.com> + + * gnat.dg/specs/anon4.ads: New test. + +2024-01-09 Eric Botcazou <ebotcazou@adacore.com> + + * g++.dg/opt/delay-slot-2.C: New test. + +2024-01-09 Roger Sayle <roger@nextmovesoftware.com> + Hongtao Liu <hongtao.liu@intel.com> + + * gcc.target/i386/auto-init-8.c: Update test case. + * gcc.target/i386/avx512f-broadcast-pr87767-1.c: Likewise. + * gcc.target/i386/avx512f-broadcast-pr87767-5.c: Likewise. + * gcc.target/i386/avx512fp16-13.c: Likewise. + * gcc.target/i386/avx512vl-broadcast-pr87767-1.c: Likewise. + * gcc.target/i386/avx512vl-broadcast-pr87767-5.c: Likewise. + * gcc.target/i386/pr100865-1.c: Likewise. + * gcc.target/i386/pr100865-10a.c: Likewise. + * gcc.target/i386/pr100865-10b.c: Likewise. + * gcc.target/i386/pr100865-2.c: Likewise. + * gcc.target/i386/pr100865-3.c: Likewise. + * gcc.target/i386/pr100865-4a.c: Likewise. + * gcc.target/i386/pr100865-4b.c: Likewise. + * gcc.target/i386/pr100865-5a.c: Likewise. + * gcc.target/i386/pr100865-5b.c: Likewise. + * gcc.target/i386/pr100865-9a.c: Likewise. + * gcc.target/i386/pr100865-9b.c: Likewise. + * gcc.target/i386/pr102021.c: Likewise. + * gcc.target/i386/pr90773-17.c: Likewise. + +2024-01-09 Haochen Jiang <haochen.jiang@intel.com> + + * gcc.target/i386/avx512fp16-xorsign-1.c: Fix testcase. + * gcc.target/i386/part-vect-absneghf.c: Ditto. + +2024-01-09 Jiahao Xu <xujiahao@loongson.cn> + + * gcc.target/loongarch/vector/lasx/lasx-vec-init-2.c: New test. + +2024-01-09 Feng Wang <wangfeng@eswincomputing.com> + + * gcc.target/riscv/rvv/base/zvbb-intrinsic.c: New test. + * gcc.target/riscv/rvv/base/zvbb_vandn_vx_constraint.c: New test. + * gcc.target/riscv/rvv/base/zvbc-intrinsic.c: New test. + * gcc.target/riscv/rvv/base/zvbc_vx_constraint-1.c: New test. + * gcc.target/riscv/rvv/base/zvbc_vx_constraint-2.c: New test. + * gcc.target/riscv/rvv/base/zvkg-intrinsic.c: New test. + * gcc.target/riscv/rvv/base/zvkned-intrinsic.c: New test. + * gcc.target/riscv/rvv/base/zvknha-intrinsic.c: New test. + * gcc.target/riscv/rvv/base/zvknhb-intrinsic.c: New test. + * gcc.target/riscv/rvv/base/zvksed-intrinsic.c: New test. + * gcc.target/riscv/rvv/base/zvksh-intrinsic.c: New test. + * gcc.target/riscv/zvkb.c: New test. + 2024-01-08 John David Anglin <danglin@gcc.gnu.org> * gcc.dg/tree-ssa/ssa-sink-18.c: xfail dg-final "Sunk statements: 5" diff --git a/gcc/testsuite/c-c++-common/analyzer/calloc-1.c b/gcc/testsuite/c-c++-common/analyzer/calloc-1.c index 6bd658e..cb93fa8 100644 --- a/gcc/testsuite/c-c++-common/analyzer/calloc-1.c +++ b/gcc/testsuite/c-c++-common/analyzer/calloc-1.c @@ -22,3 +22,37 @@ char *test_1 (size_t sz) return p; } + +char ** +test_pr113333_1 (void) +{ + char **p = (char **)calloc (1, sizeof(char *)); + if (p) + { + __analyzer_eval (*p == 0); /* { dg-warning "TRUE" } */ + __analyzer_eval (p[0] == 0); /* { dg-warning "TRUE" } */ + } + return p; +} + +char ** +test_pr113333_2 (void) +{ + char **p = (char **)calloc (2, sizeof(char *)); + if (p) + { + __analyzer_eval (*p == 0); /* { dg-warning "TRUE" } */ + __analyzer_eval (p[0] == 0); /* { dg-warning "TRUE" } */ + __analyzer_eval (p[1] == 0); /* { dg-warning "TRUE" } */ + } + return p; +} + +char ** +test_pr113333_3 (void) +{ + char **vec = (char **)calloc (1, sizeof(char *)); + if (vec) + for (char **p=vec ; *p ; p++); /* { dg-bogus "heap-based buffer over-read" } */ + return vec; +} diff --git a/gcc/testsuite/c-c++-common/analyzer/fd-glibc-byte-stream-socket.c b/gcc/testsuite/c-c++-common/analyzer/fd-glibc-byte-stream-socket.c index d9666f9..fab8426 100644 --- a/gcc/testsuite/c-c++-common/analyzer/fd-glibc-byte-stream-socket.c +++ b/gcc/testsuite/c-c++-common/analyzer/fd-glibc-byte-stream-socket.c @@ -1,6 +1,6 @@ /* Example from glibc manual (16.9.6). */ /* { dg-require-effective-target sockets } */ -/* { dg-skip-if "" { powerpc*-*-aix* } } */ +/* { dg-skip-if "" { hppa*-*-hpux* powerpc*-*-aix* } } */ #include <stdio.h> #include <string.h> diff --git a/gcc/testsuite/c-c++-common/analyzer/fd-manpage-getaddrinfo-client.c b/gcc/testsuite/c-c++-common/analyzer/fd-manpage-getaddrinfo-client.c index 16da933..21dfe97 100644 --- a/gcc/testsuite/c-c++-common/analyzer/fd-manpage-getaddrinfo-client.c +++ b/gcc/testsuite/c-c++-common/analyzer/fd-manpage-getaddrinfo-client.c @@ -28,7 +28,7 @@ the source, must acknowledge the copyright and authors of this work. /* { dg-require-effective-target sockets } */ /* { dg-additional-options "-Wno-analyzer-too-complex" } */ -/* { dg-skip-if "" { powerpc*-*-aix* } } */ +/* { dg-skip-if "" { hppa*-*-hpux* powerpc*-*-aix* } } */ #include <sys/types.h> #include <sys/socket.h> diff --git a/gcc/testsuite/c-c++-common/analyzer/fd-mappage-getaddrinfo-server.c b/gcc/testsuite/c-c++-common/analyzer/fd-mappage-getaddrinfo-server.c index c02ee6f..2e9cec4 100644 --- a/gcc/testsuite/c-c++-common/analyzer/fd-mappage-getaddrinfo-server.c +++ b/gcc/testsuite/c-c++-common/analyzer/fd-mappage-getaddrinfo-server.c @@ -27,7 +27,7 @@ the source, must acknowledge the copyright and authors of this work. */ /* { dg-require-effective-target sockets } */ -/* { dg-skip-if "" { powerpc*-*-aix* } } */ +/* { dg-skip-if "" { hppa*-*-hpux* powerpc*-*-aix* } } */ #include <sys/types.h> #include <stdio.h> diff --git a/gcc/testsuite/c-c++-common/analyzer/fd-symbolic-socket.c b/gcc/testsuite/c-c++-common/analyzer/fd-symbolic-socket.c index d7dc46a..32264fd 100644 --- a/gcc/testsuite/c-c++-common/analyzer/fd-symbolic-socket.c +++ b/gcc/testsuite/c-c++-common/analyzer/fd-symbolic-socket.c @@ -1,5 +1,5 @@ /* { dg-require-effective-target sockets } */ -/* { dg-skip-if "" { powerpc*-*-aix* } } */ +/* { dg-skip-if "" { hppa*-*-hpux* powerpc*-*-aix* } } */ #include <string.h> #include <sys/socket.h> diff --git a/gcc/testsuite/c-c++-common/analyzer/pr96639.c b/gcc/testsuite/c-c++-common/analyzer/pr96639.c index b95217d..2610ce8 100644 --- a/gcc/testsuite/c-c++-common/analyzer/pr96639.c +++ b/gcc/testsuite/c-c++-common/analyzer/pr96639.c @@ -6,5 +6,5 @@ x7 (void) int **md = (int **) calloc (1, sizeof (void *)); return md[0][0]; /* { dg-warning "possibly-NULL" "unchecked deref" } */ - /* { dg-warning "leak of 'md'" "leak" { target *-*-* } .-1 } */ + /* { dg-warning "Wanalyzer-null-dereference" "deref of NULL" { target *-*-* } .-1 } */ } diff --git a/gcc/testsuite/c-c++-common/analyzer/taint-index-pr106229.c b/gcc/testsuite/c-c++-common/analyzer/taint-index-pr106229.c new file mode 100644 index 0000000..76dca63 --- /dev/null +++ b/gcc/testsuite/c-c++-common/analyzer/taint-index-pr106229.c @@ -0,0 +1,109 @@ +#include <stdint.h> + +/* Attacker-controlled 8 bit values where the array isn't + necessarily big enough. We should warn about these. */ + +struct st_s8_field_255_elements +{ + int8_t idx; + char buf[255]; +}; + +char __attribute__((tainted_args)) +test_s8_field_255_elements (struct st_s8_field_255_elements s) +{ + return s.buf[s.idx]; /* { dg-warning "tainted-array-index" } */ +} + +struct st_u8_field_255_elements +{ + uint8_t idx; + char buf[255]; +}; + +char __attribute__((tainted_args)) +test_u8_field_255_elements (struct st_u8_field_255_elements s) +{ + return s.buf[s.idx]; /* { dg-warning "tainted-array-index" } */ +} + +/* Attacker-controlled 8 bit values where the array is + big enough, but where the value might be signed. */ + +struct st_s8_field_256_elements +{ + int8_t idx; + char buf[256]; +}; + +char __attribute__((tainted_args)) +test_s8_field_256_elements (struct st_s8_field_256_elements s) +{ + return s.buf[s.idx]; /* { dg-warning "tainted-array-index" } */ +} + +struct st_u8_field_256_elements +{ + uint8_t idx; + char buf[256]; +}; + +char __attribute__((tainted_args)) +test_u8_field_256_elements (struct st_u8_field_256_elements s) +{ + return s.buf[s.idx]; /* { dg-bogus "tainted-array-index" } */ +} + +/* Attacker-controlled 16 bit values where the array isn't + necessarily big enough. We should warn about these. */ + +struct st_s16_field_256_elements +{ + int16_t idx; + char buf[256]; +}; + +char __attribute__((tainted_args)) +test_s16_field_256_elements (struct st_s16_field_256_elements s) +{ + return s.buf[s.idx]; /* { dg-warning "tainted-array-index" } */ +} + +struct st_u16_field_256_elements +{ + uint16_t idx; + char buf[256]; +}; + +char __attribute__((tainted_args)) +test_u16_field_256_elements (struct st_u16_field_256_elements s) +{ + return s.buf[s.idx]; /* { dg-warning "tainted-array-index" } */ +} + +/* Attacker-controlled 16 bit values where the array is + big enough, but where the value might be signed. */ + +struct st_s16_field_65536_elements +{ + int16_t idx; + char buf[65536]; +}; + +char __attribute__((tainted_args)) +test_s16_field_65536_elements (struct st_s16_field_65536_elements s) +{ + return s.buf[s.idx]; /* { dg-warning "tainted-array-index" } */ +} + +struct st_u16_field_65536_elements +{ + uint16_t idx; + char buf[65536]; +}; + +char __attribute__((tainted_args)) +test_u16_field_65536_elements (struct st_u16_field_65536_elements s) +{ + return s.buf[s.idx]; /* { dg-bogus "tainted-array-index" } */ +} diff --git a/gcc/testsuite/g++.dg/abi/mangle79.C b/gcc/testsuite/g++.dg/abi/mangle79.C new file mode 100644 index 0000000..99ae822 --- /dev/null +++ b/gcc/testsuite/g++.dg/abi/mangle79.C @@ -0,0 +1,61 @@ +// { dg-do compile { target c++11 } } +// { dg-options "" } + +struct S { + static void foo (S); + void foo (this S); // { dg-warning "explicit object member function only available with" "" { target c++20_down } } + template <int N, typename T> + static void bar (S, T); + template <int N, typename T> + void bar (this S, T); // { dg-warning "explicit object member function only available with" "" { target c++20_down } } + static void baz (const S &); + void baz (this const S &); // { dg-warning "explicit object member function only available with" "" { target c++20_down } } +}; + +void +S::foo (S) +{ +} + +void +S::foo (this S) // { dg-warning "explicit object member function only available with" "" { target c++20_down } } +{ +} + +template <int N, typename T> +void +S::bar (S, T) +{ +} + +template <int N, typename T> +void +S::bar (this S, T) // { dg-warning "explicit object member function only available with" "" { target c++20_down } } +{ +} + +void +S::baz (const S &) +{ +} + +void +S::baz (this const S &) // { dg-warning "explicit object member function only available with" "" { target c++20_down } } +{ +} + +void +qux (S *p) +{ + S::foo (*p); + p->foo (); + S::bar <5> (*p, 0); + p->bar <5> (0); +} + +// { dg-final { scan-assembler "_ZN1S3fooES_" } } +// { dg-final { scan-assembler "_ZNH1S3fooES_" } } +// { dg-final { scan-assembler "_ZN1S3barILi5EiEEvS_T0_" } } +// { dg-final { scan-assembler "_ZNH1S3barILi5EiEEvS_T0_" } } +// { dg-final { scan-assembler "_ZN1S3bazERKS_" } } +// { dg-final { scan-assembler "_ZNH1S3bazERKS_" } } diff --git a/gcc/testsuite/g++.dg/abi/ref-temp1.C b/gcc/testsuite/g++.dg/abi/ref-temp1.C index c9963ca..70c9a7a 100644 --- a/gcc/testsuite/g++.dg/abi/ref-temp1.C +++ b/gcc/testsuite/g++.dg/abi/ref-temp1.C @@ -1,7 +1,6 @@ // From ABI document // { dg-do compile { target c++14 } } // { dg-skip-if "No .weak" { { hppa*-*-hpux* } && { ! lp64 } } } -// { dg-additional-options --save-temps } struct A { const int (&x)[3]; }; struct B { const A (&x)[2]; }; diff --git a/gcc/testsuite/g++.dg/concepts/auto8.C b/gcc/testsuite/g++.dg/concepts/auto8.C new file mode 100644 index 0000000..f9d98b2 --- /dev/null +++ b/gcc/testsuite/g++.dg/concepts/auto8.C @@ -0,0 +1,17 @@ +// PR c++/110065 +// { dg-do compile { target c++17 } } + +template <typename> +inline constexpr bool t = false; + +int +f () +{ + return t<auto(&)(const int*) -> auto&>; // { dg-error "template argument" } +} + +void +g () +{ + t<auto(&)(const int*) -> auto&>; // { dg-error "template argument" } +} diff --git a/gcc/testsuite/g++.dg/concepts/auto8a.C b/gcc/testsuite/g++.dg/concepts/auto8a.C new file mode 100644 index 0000000..fc60dc8 --- /dev/null +++ b/gcc/testsuite/g++.dg/concepts/auto8a.C @@ -0,0 +1,18 @@ +// PR c++/110065 +// { dg-do compile { target c++17 } } +// { dg-additional-options -fconcepts-ts } + +template <typename> +inline constexpr bool t = false; + +int +f () +{ + return t<auto(&)(const int*) -> auto&>; // { dg-error "template argument" } +} + +void +g () +{ + t<auto(&)(const int*) -> auto&>; // { dg-error "template argument" } +} diff --git a/gcc/testsuite/g++.dg/cpp0x/initlist-array21.C b/gcc/testsuite/g++.dg/cpp0x/initlist-array21.C new file mode 100644 index 0000000..357d88e --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/initlist-array21.C @@ -0,0 +1,12 @@ +// PR c++/109899 +// { dg-do compile { target c++11 } } + +struct A { A(); ~A(); }; + +template<class T> +using array = T[42]; + +template<class T> +void f() { + array<A>{}; +} diff --git a/gcc/testsuite/g++.dg/cpp23/explicit-obj-basic1.C b/gcc/testsuite/g++.dg/cpp23/explicit-obj-basic1.C new file mode 100644 index 0000000..134182c --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp23/explicit-obj-basic1.C @@ -0,0 +1,114 @@ +// P0847R7 +// { dg-do compile { target c++23 } } + +// basic use cases and calling + +// non-trailing return +// definitions +struct S0 { + void f0(this S0) {} + void f1(this S0&) {} + void f2(this S0&&) {} + void f3(this S0 const&) {} + void f4(this S0 const&&) {} + template<typename Self> + void d0(this Self&&) {} + void d1(this auto&&) {} +}; +// declarations +struct S1 { + void f0(this S1); + void f1(this S1&); + void f2(this S1&&); + void f3(this S1 const&); + void f4(this S1 const&&); + template<typename Self> + void d0(this Self&&); + void d1(this auto&&); +}; +// out of line definitions +void S1::f0(this S1) {} +void S1::f1(this S1&) {} +void S1::f2(this S1&&) {} +void S1::f3(this S1 const&) {} +void S1::f4(this S1 const&&) {} +template<typename Self> +void S1::d0(this Self&&) {} +void S1::d1(this auto&&) {} + +// trailing return +// definitions +struct S2 { + auto f0(this S2) -> void {} + auto f1(this S2&) -> void {} + auto f2(this S2&&) -> void {} + auto f3(this S2 const&) -> void {} + auto f4(this S2 const&&) -> void {} + template<typename Self> + auto d0(this Self&&) -> void {} + + auto d1(this auto&&) -> void {} +}; +// declarations +struct S3 { + auto f0(this S3) -> void; + auto f1(this S3&) -> void; + auto f2(this S3&&) -> void; + auto f3(this S3 const&) -> void; + auto f4(this S3 const&&) -> void; + template<typename Self> + auto d0(this Self&&) -> void; + auto d1(this auto&&) -> void; +}; +// out of line definitions +auto S3::f0(this S3) -> void {} +auto S3::f1(this S3&) -> void {} +auto S3::f2(this S3&&) -> void {} +auto S3::f3(this S3 const&) -> void {} +auto S3::f4(this S3 const&&) -> void {} +template<typename Self> +auto S3::d0(this Self&&) -> void {} +auto S3::d1(this auto&&) -> void {} + +template<typename T> +void call_with_qualification() +{ + T obj{}; + // by value should take any qualification (f0) + T{}.f0(); + obj.f0(); + static_cast<T&&>(obj).f0(); + static_cast<T const&>(obj).f0(); + static_cast<T const&&>(obj).f0(); + // specific qualification (f1 - f4) + T{}.f2(); + T{}.f3(); + T{}.f4(); + obj.f1(); + obj.f3(); + static_cast<T&&>(obj).f2(); + static_cast<T&&>(obj).f3(); + static_cast<T&&>(obj).f4(); + static_cast<T const&>(obj).f3(); + static_cast<T const&&>(obj).f4(); + // deduced should (obviously) take any qualification (d0, d1) + T{}.d0(); + obj.d0(); + static_cast<T&&>(obj).d0(); + static_cast<T const&>(obj).d0(); + static_cast<T const&&>(obj).d0(); + T{}.d1(); + obj.d1(); + static_cast<T&&>(obj).d1(); + static_cast<T const&>(obj).d1(); + static_cast<T const&&>(obj).d1(); +} + +void perform_calls() +{ + call_with_qualification<S0>(); + call_with_qualification<S1>(); + call_with_qualification<S2>(); + call_with_qualification<S3>(); +} + diff --git a/gcc/testsuite/g++.dg/cpp23/explicit-obj-basic2.C b/gcc/testsuite/g++.dg/cpp23/explicit-obj-basic2.C new file mode 100644 index 0000000..6b2cad1 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp23/explicit-obj-basic2.C @@ -0,0 +1,28 @@ +// P0847R7 +// { dg-do run { target c++23 } } + +// explicit object member function pointer type deduction, +// conversion to function pointer, +// and calling through pointer to function + +struct S { + int _n; + int f(this S& self) { return self._n; } +}; + +using f_type = int(*)(S&); + +static_assert (__is_same (f_type, decltype (&S::f))); + +int main() +{ + auto fp0 = &S::f; + f_type fp1 = &S::f; + static_assert (__is_same (decltype (fp0), decltype (fp1))); + S s{42}; + if (fp0 (s) != 42) + __builtin_abort (); + if (fp1 (s) != 42) + __builtin_abort (); +} + diff --git a/gcc/testsuite/g++.dg/cpp23/explicit-obj-basic3.C b/gcc/testsuite/g++.dg/cpp23/explicit-obj-basic3.C new file mode 100644 index 0000000..e466cc9 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp23/explicit-obj-basic3.C @@ -0,0 +1,496 @@ +// P0847R7 +// { dg-do compile { target c++23 } } + +// bogus diagnosis of valid declarations as redeclarations +// tests for by-value are elsewhere (todo: add filename) + +// each group has 8 overloads that each take +// lvalue ref to S +// rvalue ref to S +// lvalue c ref to S +// rvalue c ref to S +// lvalue v ref to S +// rvalue v ref to S +// lvalue cv ref to S +// rvalue cv ref to S +// where S is the struct the function is declared in + +// only xobj (the most basic case) + +struct S { + void f(this S &); + void f(this S &&); + void f(this S const&); + void f(this S const&&); + void f(this S volatile&); + void f(this S volatile&&); + void f(this S const volatile&); + void f(this S const volatile&&); +}; + +// I* has the 1 xobj 7 iobj cases +// X* has the 7 xobj 1 iobj cases +// *0 has the unique function first, the rest after +// *1 has the unique function last, the rest after +// *2 has the functions in the order stated above +// xobj first, 1 xobj, 7 iobj + +// (yes there are some redundant cases) + +// unique first, 1 xobj 7 iobj + +struct I0 { + void f0(this I0&); + void f0() &&; + void f0() const&; + void f0() const&&; + void f0() volatile&; + void f0() volatile&&; + void f0() const volatile&; + void f0() const volatile&&; + + void f1(this I0&&); + void f1() &; + void f1() const&; + void f1() const&&; + void f1() volatile&; + void f1() volatile&&; + void f1() const volatile&; + void f1() const volatile&&; + + void fc0(this I0 const&); + void fc0() &; + void fc0() &&; + void fc0() const&&; + void fc0() volatile&; + void fc0() volatile&&; + void fc0() const volatile&; + void fc0() const volatile&&; + + void fc1(this I0 const&&); + void fc1() &; + void fc1() &&; + void fc1() const&; + void fc1() volatile&; + void fc1() volatile&&; + void fc1() const volatile&; + void fc1() const volatile&&; + + void fv0(this I0 volatile&); + void fv0() &; + void fv0() &&; + void fv0() const&; + void fv0() const&&; + void fv0() volatile&&; + void fv0() const volatile&; + void fv0() const volatile&&; + + void fv1(this I0 volatile&&); + void fv1() &; + void fv1() &&; + void fv1() const&; + void fv1() const&&; + void fv1() volatile&; + void fv1() const volatile&; + void fv1() const volatile&&; + + void fcv0(this I0 const volatile&); + void fcv0() &; + void fcv0() &&; + void fcv0() const&; + void fcv0() const&&; + void fcv0() volatile&; + void fcv0() volatile&&; + void fcv0() const volatile&&; + + void fcv1(this I0 const volatile&&); + void fcv1() &; + void fcv1() &&; + void fcv1() const&; + void fcv1() const&&; + void fcv1() volatile&; + void fcv1() volatile&&; + void fcv1() const volatile&; +}; + +// unique last, 1 xobj 7 iobj + +struct I1 { + void f0() &&; + void f0() const&; + void f0() const&&; + void f0() volatile&; + void f0() volatile&&; + void f0() const volatile&; + void f0() const volatile&&; + void f0(this I1&); + + void f1() &; + void f1() const&; + void f1() const&&; + void f1() volatile&; + void f1() volatile&&; + void f1() const volatile&; + void f1() const volatile&&; + void f1(this I1&&); + + void fc0() &; + void fc0() &&; + void fc0() const&&; + void fc0() volatile&; + void fc0() volatile&&; + void fc0() const volatile&; + void fc0() const volatile&&; + void fc0(this I1 const&); + + void fc1() &; + void fc1() &&; + void fc1() const&; + void fc1() volatile&; + void fc1() volatile&&; + void fc1() const volatile&; + void fc1() const volatile&&; + void fc1(this I1 const&&); + + void fv0() &; + void fv0() &&; + void fv0() const&; + void fv0() const&&; + void fv0() volatile&&; + void fv0() const volatile&; + void fv0() const volatile&&; + void fv0(this I1 volatile&); + + void fv1() &; + void fv1() &&; + void fv1() const&; + void fv1() const&&; + void fv1() volatile&; + void fv1() const volatile&; + void fv1() const volatile&&; + void fv1(this I1 volatile&&); + + void fcv0() &; + void fcv0() &&; + void fcv0() const&; + void fcv0() const&&; + void fcv0() volatile&; + void fcv0() volatile&&; + void fcv0() const volatile&&; + void fcv0(this I1 const volatile&); + + void fcv1() &; + void fcv1() &&; + void fcv1() const&; + void fcv1() const&&; + void fcv1() volatile&; + void fcv1() volatile&&; + void fcv1() const volatile&; + void fcv1(this I1 const volatile&&); +}; + +// ordered, 1 xobj 7 iobj + +struct I2 { + void f0(this I2&); + void f0() &&; + void f0() const&; + void f0() const&&; + void f0() volatile&; + void f0() volatile&&; + void f0() const volatile&; + void f0() const volatile&&; + + void f1() &; + void f1(this I2&&); + void f1() const&; + void f1() const&&; + void f1() volatile&; + void f1() volatile&&; + void f1() const volatile&; + void f1() const volatile&&; + + void fc0() &; + void fc0() &&; + void fc0(this I2 const&); + void fc0() const&&; + void fc0() volatile&; + void fc0() volatile&&; + void fc0() const volatile&; + void fc0() const volatile&&; + + void fc1() &; + void fc1() &&; + void fc1() const&; + void fc1(this I2 const&&); + void fc1() volatile&; + void fc1() volatile&&; + void fc1() const volatile&; + void fc1() const volatile&&; + + void fv0() &; + void fv0() &&; + void fv0() const&; + void fv0() const&&; + void fv0(this I2 volatile&); + void fv0() volatile&&; + void fv0() const volatile&; + void fv0() const volatile&&; + + void fv1() &; + void fv1() &&; + void fv1() const&; + void fv1() const&&; + void fv1() volatile&; + void fv1(this I2 volatile&&); + void fv1() const volatile&; + void fv1() const volatile&&; + + void fcv0() &; + void fcv0() &&; + void fcv0() const&; + void fcv0() const&&; + void fcv0() volatile&; + void fcv0() volatile&&; + void fcv0(this I2 const volatile&); + void fcv0() const volatile&&; + + void fcv1() &; + void fcv1() &&; + void fcv1() const&; + void fcv1() const&&; + void fcv1() volatile&; + void fcv1() volatile&&; + void fcv1() const volatile&; + void fcv1(this I2 const volatile&&); +}; + + +// iobj first, 7 xobj, 1 iobj + +struct X0 { + void f0() &; + void f0(this X0 &&); + void f0(this X0 const&); + void f0(this X0 const&&); + void f0(this X0 volatile&); + void f0(this X0 volatile&&); + void f0(this X0 const volatile&); + void f0(this X0 const volatile&&); + + void f1() &&; + void f1(this X0 &); + void f1(this X0 const&); + void f1(this X0 const&&); + void f1(this X0 volatile&); + void f1(this X0 volatile&&); + void f1(this X0 const volatile&); + void f1(this X0 const volatile&&); + + void fc0() const&; + void fc0(this X0 &); + void fc0(this X0 &&); + void fc0(this X0 const&&); + void fc0(this X0 volatile&); + void fc0(this X0 volatile&&); + void fc0(this X0 const volatile&); + void fc0(this X0 const volatile&&); + + void fc1() const&&; + void fc1(this X0 &); + void fc1(this X0 &&); + void fc1(this X0 const&); + void fc1(this X0 volatile&); + void fc1(this X0 volatile&&); + void fc1(this X0 const volatile&); + void fc1(this X0 const volatile&&); + + void fv0() volatile&; + void fv0(this X0 &); + void fv0(this X0 &&); + void fv0(this X0 const&); + void fv0(this X0 const&&); + void fv0(this X0 volatile&&); + void fv0(this X0 const volatile&); + void fv0(this X0 const volatile&&); + + void fv1() volatile&&; + void fv1(this X0 &); + void fv1(this X0 &&); + void fv1(this X0 const&); + void fv1(this X0 const&&); + void fv1(this X0 volatile&); + void fv1(this X0 const volatile&); + void fv1(this X0 const volatile&&); + + void fcv0() const volatile&; + void fcv0(this X0 &); + void fcv0(this X0 &&); + void fcv0(this X0 const&); + void fcv0(this X0 const&&); + void fcv0(this X0 volatile&); + void fcv0(this X0 volatile&&); + void fcv0(this X0 const volatile&&); + + void fcv1() const volatile&&; + void fcv1(this X0 &); + void fcv1(this X0 &&); + void fcv1(this X0 const&); + void fcv1(this X0 const&&); + void fcv1(this X0 volatile&); + void fcv1(this X0 volatile&&); + void fcv1(this X0 const volatile&); +}; + +// iobj last, 7 xobj 1 iobj + +struct X1 { + void f0(this X1 &&); + void f0(this X1 const&); + void f0(this X1 const&&); + void f0(this X1 volatile&); + void f0(this X1 volatile&&); + void f0(this X1 const volatile&); + void f0(this X1 const volatile&&); + void f0() &; + + void f1(this X1 &); + void f1(this X1 const&); + void f1(this X1 const&&); + void f1(this X1 volatile&); + void f1(this X1 volatile&&); + void f1(this X1 const volatile&); + void f1(this X1 const volatile&&); + void f1() &&; + + void fc0(this X1 &); + void fc0(this X1 &&); + void fc0(this X1 const&&); + void fc0(this X1 volatile&); + void fc0(this X1 volatile&&); + void fc0(this X1 const volatile&); + void fc0(this X1 const volatile&&); + void fc0() const&; + + void fc1(this X1 &); + void fc1(this X1 &&); + void fc1(this X1 const&); + void fc1(this X1 volatile&); + void fc1(this X1 volatile&&); + void fc1(this X1 const volatile&); + void fc1(this X1 const volatile&&); + void fc1() const&&; + + void fv0(this X1 &); + void fv0(this X1 &&); + void fv0(this X1 const&); + void fv0(this X1 const&&); + void fv0(this X1 volatile&&); + void fv0(this X1 const volatile&); + void fv0(this X1 const volatile&&); + void fv0() volatile&; + + void fv1(this X1 &); + void fv1(this X1 &&); + void fv1(this X1 const&); + void fv1(this X1 const&&); + void fv1(this X1 volatile&); + void fv1(this X1 const volatile&); + void fv1(this X1 const volatile&&); + void fv1() volatile&&; + + void fcv0(this X1 &); + void fcv0(this X1 &&); + void fcv0(this X1 const&); + void fcv0(this X1 const&&); + void fcv0(this X1 volatile&); + void fcv0(this X1 volatile&&); + void fcv0(this X1 const volatile&&); + void fcv0() const volatile&; + + void fcv1(this X1 &); + void fcv1(this X1 &&); + void fcv1(this X1 const&); + void fcv1(this X1 const&&); + void fcv1(this X1 volatile&); + void fcv1(this X1 volatile&&); + void fcv1(this X1 const volatile&); + void fcv1() const volatile&&; +}; + +// ordered, 7 xobj 1 iobj + +struct X2 { + void f0() &; + void f0(this X2 &&); + void f0(this X2 const&); + void f0(this X2 const&&); + void f0(this X2 volatile&); + void f0(this X2 volatile&&); + void f0(this X2 const volatile&); + void f0(this X2 const volatile&&); + + void f1(this X2 &); + void f1() &&; + void f1(this X2 const&); + void f1(this X2 const&&); + void f1(this X2 volatile&); + void f1(this X2 volatile&&); + void f1(this X2 const volatile&); + void f1(this X2 const volatile&&); + + void fc0(this X2 &); + void fc0(this X2 &&); + void fc0() const&; + void fc0(this X2 const&&); + void fc0(this X2 volatile&); + void fc0(this X2 volatile&&); + void fc0(this X2 const volatile&); + void fc0(this X2 const volatile&&); + + void fc1(this X2 &); + void fc1(this X2 &&); + void fc1(this X2 const&); + void fc1() const&&; + void fc1(this X2 volatile&); + void fc1(this X2 volatile&&); + void fc1(this X2 const volatile&); + void fc1(this X2 const volatile&&); + + void fv0(this X2 &); + void fv0(this X2 &&); + void fv0(this X2 const&); + void fv0(this X2 const&&); + void fv0() volatile&; + void fv0(this X2 volatile&&); + void fv0(this X2 const volatile&); + void fv0(this X2 const volatile&&); + + void fv1(this X2 &); + void fv1(this X2 &&); + void fv1(this X2 const&); + void fv1(this X2 const&&); + void fv1(this X2 volatile&); + void fv1() volatile&&; + void fv1(this X2 const volatile&); + void fv1(this X2 const volatile&&); + + void fcv0(this X2 &); + void fcv0(this X2 &&); + void fcv0(this X2 const&); + void fcv0(this X2 const&&); + void fcv0(this X2 volatile&); + void fcv0(this X2 volatile&&); + void fcv0() const volatile&; + void fcv0(this X2 const volatile&&); + + void fcv1(this X2 &); + void fcv1(this X2 &&); + void fcv1(this X2 const&); + void fcv1(this X2 const&&); + void fcv1(this X2 volatile&); + void fcv1(this X2 volatile&&); + void fcv1(this X2 const volatile&); + void fcv1() const volatile&&; +}; + diff --git a/gcc/testsuite/g++.dg/cpp23/explicit-obj-basic4.C b/gcc/testsuite/g++.dg/cpp23/explicit-obj-basic4.C new file mode 100644 index 0000000..691ef68 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp23/explicit-obj-basic4.C @@ -0,0 +1,113 @@ +// P0847R7 +// { dg-do compile { target c++23 } } + +// valid overloading of iobj member functions without ref qualifiers +// with xobj member functions (and vice-versa) + +// this is the most you can mix these, it may look short but it does test +// all allowed cases (other than by-value and unrelated types) + +// [over.match.funcs.general.4] +// For implicit object member functions, the type of the implicit +// object parameter is +// -- “lvalue reference to cv X” for functions declared +// without a ref-qualifier or with the & ref-qualifier +// -- “rvalue reference to cv X” for functions declared with +// the && ref-qualifier + +// [basic.scope.scope.3] +// Two non-static member functions have corresponding object +// parameters if: +// -- exactly one is an implicit object member function with no +// ref-qualifier and the types of their object parameters +// ([dcl.fct]), after removing top-level references, are the +// same, or + +// in simpler terms, only the cv qualification of the explicit/implicit object +// parameter matter for determining whether these are redeclarations or overloads +// (when a ref qualifier is not present on the iobj member function) + +// xobj first, iobj last + +struct S0 { + void f(this S0 &); + void f(this S0 &&); + void f() const; + void f() volatile; + void f() const volatile; + + void fc(this S0 const&); + void fc(this S0 const&&); + void fc(); + void fc() volatile; + void fc() const volatile; + + void fv(this S0 volatile&); + void fv(this S0 volatile&&); + void fv(); + void fv() const; + void fv() const volatile; + + void fcv(this S0 const volatile&); + void fcv(this S0 const volatile&&); + void fcv(); + void fcv() const; + void fcv() volatile; +}; + +// iobj first, xobj last + +struct S1 { + void f() const; + void f() volatile; + void f() const volatile; + void f(this S1 &); + void f(this S1 &&); + + void fc(); + void fc() volatile; + void fc() const volatile; + void fc(this S1 const&); + void fc(this S1 const&&); + + void fv(); + void fv() const; + void fv() const volatile; + void fv(this S1 volatile&); + void fv(this S1 volatile&&); + + void fcv(); + void fcv() const; + void fcv() volatile; + void fcv(this S1 const volatile&); + void fcv(this S1 const volatile&&); +}; + +// in order + +struct S2 { + void f(this S2 &); + void f(this S2 &&); + void f() const; + void f() volatile; + void f() const volatile; + + void fc(); + void fc(this S2 const&); + void fc(this S2 const&&); + void fc() volatile; + void fc() const volatile; + + void fv(); + void fv() const; + void fv(this S2 volatile&); + void fv(this S2 volatile&&); + void fv() const volatile; + + void fcv(); + void fcv() const; + void fcv() volatile; + void fcv(this S2 const volatile&); + void fcv(this S2 const volatile&&); +}; + diff --git a/gcc/testsuite/g++.dg/cpp23/explicit-obj-basic5.C b/gcc/testsuite/g++.dg/cpp23/explicit-obj-basic5.C new file mode 100644 index 0000000..9cf23d9 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp23/explicit-obj-basic5.C @@ -0,0 +1,33 @@ +// P0847R7 +// { dg-do run { target c++23 } } + +// conversion operators with xobj parameter + +inline constexpr int magic = 42; + +struct S0 { + operator int(this S0 const&) { + return magic; + } +}; + +struct S1 { + int _v; + int f(this int self) { + return self; + } + operator int(this S1 const& self) { + return self._v; + } +}; + +int main() +{ + if (S0{} != magic) + __builtin_abort (); + + S1 s{42}; + if (static_cast<int>(s) != magic) + __builtin_abort (); +} + diff --git a/gcc/testsuite/g++.dg/cpp23/explicit-obj-basic6.C b/gcc/testsuite/g++.dg/cpp23/explicit-obj-basic6.C new file mode 100644 index 0000000..6b8881e --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp23/explicit-obj-basic6.C @@ -0,0 +1,51 @@ +// P0847R7 +// { dg-do compile { target c++23 } } + +// user defined copy/move assignment operators + +inline constexpr int add_when_copy = 5; +inline constexpr int add_when_move = 10; +inline constexpr int poison = -1; + +struct S { + int _v; + S& operator=(this S& self, S const& rhs) { + self._v = rhs._v + add_when_copy; + return self; + }; + S& operator=(this S& self, S&& rhs) { + self._v = rhs._v + add_when_move; + rhs._v = poison; + return self; + } +}; + +inline constexpr int init_val = 5; + +int main() +{ + S s0{0}; + S s1{init_val}; + + // Sanity check. + if (s0._v != 0 + || s1._v != init_val) + __builtin_abort (); + + s0 = s1; + if (s0._v != init_val + add_when_copy) + __builtin_abort (); + if (s1._v != init_val) + __builtin_abort (); + + s0 = S{init_val}; + if (s0._v != init_val + add_when_move) + __builtin_abort (); + + S s2{init_val}; + s0 = static_cast<S&&>(s2); + if (s0._v != init_val + add_when_move) + __builtin_abort (); + if (s2._v != poison) + __builtin_abort (); +} diff --git a/gcc/testsuite/g++.dg/cpp23/explicit-obj-by-value1.C b/gcc/testsuite/g++.dg/cpp23/explicit-obj-by-value1.C new file mode 100644 index 0000000..5ea5bcb --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp23/explicit-obj-by-value1.C @@ -0,0 +1,48 @@ +// P0847R7 +// { dg-do run { target c++23 } } + +// conversion of the implicit object argument to an xobj parameter +// when calling by value xobj member functions + +// The initial implementation of xobj member functions incorrectly did not +// convert the implicit object argument when binding to the xobj +// parameter. In spite of this, it did correctly check to see if such a +// conversion would be valid, thus no diagnostic would be emitted when a +// conversion was valid, but instead of applying the conversion, the +// argument would silently be reinterpreted as the type of the parameter. + +// This is why we use uintptr_t for the value in S and compare the result +// of f to &s, we want to test for simple reinterpretation of the +// argument. To accurately test for this we make sure to use an object +// that has a different address than the value of our magic number. It's +// an impossibly improbable edge case but it's trivial to work around. We +// still compare against both the address of s and the magic number so we +// can additionally test for bugged conversions, while also +// differentiating that case from reinterpretation of the argument. + +using uintptr_t = __UINTPTR_TYPE__; +inline constexpr uintptr_t magic = 42; + +struct S { + uintptr_t _v; + uintptr_t f(this S self) { + return self._v; + } +}; + +int main() +{ + S s0{magic}; + S s1{magic}; + // prevent (absurdly improbable) bogus failures + S& s = magic != (uintptr_t)(&s0) ? s0 : s1; + + uintptr_t const ret = s.f(); + // check for reinterpretation of the object argument + if (ret == (uintptr_t)(&s)) + __builtin_abort (); + // check for a bugged conversion + if (ret != magic) + __builtin_abort (); +} + diff --git a/gcc/testsuite/g++.dg/cpp23/explicit-obj-by-value2.C b/gcc/testsuite/g++.dg/cpp23/explicit-obj-by-value2.C new file mode 100644 index 0000000..b8e8e73df --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp23/explicit-obj-by-value2.C @@ -0,0 +1,58 @@ +// P0847R7 +// { dg-do run { target c++23 } } + +// conversion of the implicit object argument to an xobj parameter +// using a user defined conversion or converting constructor +// when calling by value xobj member functions + +// see explicit-obj-by-value1.C for details on this test + +using uintptr_t = __UINTPTR_TYPE__; +inline constexpr uintptr_t magic = 42; + +struct S; + +struct FromS { + uintptr_t _v; + FromS(S); +}; + +struct S { + operator uintptr_t() const { + return magic; + } + uintptr_t f(this uintptr_t n) { + return n; + } + uintptr_t g(this FromS from_s) { + return from_s._v; + } +}; + +FromS::FromS(S) : _v(magic) {} + + +int main() +{ + S s0{}; + S s1{}; + // prevent (absurdly improbable) bogus failures + S& s = magic != (uintptr_t)(&s0) ? s0 : s1; + + uintptr_t const ret0 = s.f(); + // check for reinterpretation of the object argument + if (ret0 == (uintptr_t)(&s)) + __builtin_abort (); + // check for a bugged conversion + if (ret0 != magic) + __builtin_abort (); + + uintptr_t const ret1 = s.g(); + // check for reinterpretation of the object argument + if (ret1 == (uintptr_t)(&s)) + __builtin_abort (); + // check for a bugged conversion + if (ret1 != magic) + __builtin_abort (); +} + diff --git a/gcc/testsuite/g++.dg/cpp23/explicit-obj-by-value3.C b/gcc/testsuite/g++.dg/cpp23/explicit-obj-by-value3.C new file mode 100644 index 0000000..e6aff01 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp23/explicit-obj-by-value3.C @@ -0,0 +1,41 @@ +// P0847R7 +// { dg-do run { target c++23 } } + +// correct constructor selection when initializing a by value xobj parameter + +// see explicit-obj-by-value1.C for details on this test + +using uintptr_t = __UINTPTR_TYPE__; +inline constexpr uintptr_t magic = 42; +inline constexpr uintptr_t copy_magic = 5; +inline constexpr uintptr_t move_magic = 10; + +struct S { + uintptr_t _v; + explicit S(uintptr_t v) : _v(v) {} + S(S const& other) : _v(other._v + copy_magic) {} + S(S&& other) : _v(other._v + move_magic) {} + uintptr_t f(this S self) { + return self._v; + } +}; + +int main() +{ + S s0{magic}; + S s1{magic}; + // prevent (absurdly improbable (^2)) bogus results + // it's virtually impossible for both to have a bogus result, + // but we can guarantee correct results from both easily, so why not? + S& s_copy_from = magic + copy_magic != (uintptr_t)(&s0) ? s0 : s1; + S& s_move_from = magic + move_magic != (uintptr_t)(&s0) ? s0 : s1; + uintptr_t const copy_ret = static_cast<S const&>(s_copy_from).f(); + uintptr_t const move_ret = static_cast<S&&>(s_move_from).f(); + // we test specifically for reinterpretation in other + // by value tests, it's unnecessary to do it again here + if (copy_ret != magic + copy_magic) + __builtin_abort (); + if (move_ret != magic + move_magic) + __builtin_abort (); +} + diff --git a/gcc/testsuite/g++.dg/cpp23/explicit-obj-by-value4.C b/gcc/testsuite/g++.dg/cpp23/explicit-obj-by-value4.C new file mode 100644 index 0000000..9b4e005 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp23/explicit-obj-by-value4.C @@ -0,0 +1,20 @@ +// P0847R7 +// { dg-do compile { target c++23 } } + +// diagnosis of ill-formed calls to by-value xobj member functions +// due to an absence of valid conversion functions + +struct NotFromS {}; + +struct S { + void f(this int) {} + void g(this NotFromS) {} +}; + +void test() +{ + S s{}; + s.f(); // { dg-error {cannot convert 'S' to 'int'} } + s.g(); // { dg-error {cannot convert 'S' to 'NotFromS'} } +} + diff --git a/gcc/testsuite/g++.dg/cpp23/explicit-obj-constraints.C b/gcc/testsuite/g++.dg/cpp23/explicit-obj-constraints.C new file mode 100644 index 0000000..eb8a855 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp23/explicit-obj-constraints.C @@ -0,0 +1,418 @@ +// P0847R7 +// { dg-do run { target c++23 } } + +// overload resolution of static/xobj and iobj/xobj member functions +// with constraints + +template<typename T> +concept Constrain = true; + +inline constexpr int iobj_fn = 5; +inline constexpr int xobj_fn = 10; +inline constexpr int static_fn = 20; + +// first 2 letters are the order of the definitions +// the constraint applies to the first definition, +// for *_r cases the constraint applies to the second + +struct S { + // xobj/static + int f_xs_v(this S, Constrain auto) { return xobj_fn; }; + static int f_xs_v(auto) { return static_fn; }; + + int f_xs_ref(this S&, Constrain auto) { return xobj_fn; }; + static int f_xs_ref(auto) { return static_fn; }; + + int f_xs_cref(this S const&, Constrain auto) { return xobj_fn; }; + static int f_xs_cref(auto) { return static_fn; }; + + int f_xs_rref(this S&&, Constrain auto) { return xobj_fn; }; + static int f_xs_rref(auto) { return static_fn; }; + + int f_xs_crref(this S const&&, Constrain auto) { return xobj_fn; }; + static int f_xs_crref(auto) { return static_fn; }; + + // _r + int f_xs_v_r(this S, auto) { return xobj_fn; }; + static int f_xs_v_r(Constrain auto) { return static_fn; }; + + int f_xs_ref_r(this S&, auto) { return xobj_fn; }; + static int f_xs_ref_r(Constrain auto) { return static_fn; }; + + int f_xs_cref_r(this S const&, auto) { return xobj_fn; }; + static int f_xs_cref_r(Constrain auto) { return static_fn; }; + + int f_xs_rref_r(this S&&, auto) { return xobj_fn; }; + static int f_xs_rref_r(Constrain auto) { return static_fn; }; + + int f_xs_crref_r(this S const&&, auto) { return xobj_fn; }; + static int f_xs_crref_r(Constrain auto) { return static_fn; }; + + // static/xobj + static int f_sx_v(Constrain auto) { return static_fn; }; + int f_sx_v(this S, auto) { return xobj_fn; }; + + static int f_sx_ref(Constrain auto) { return static_fn; }; + int f_sx_ref(this S&, auto) { return xobj_fn; }; + + static int f_sx_cref(Constrain auto) { return static_fn; }; + int f_sx_cref(this S const&, auto) { return xobj_fn; }; + + static int f_sx_rref(Constrain auto) { return static_fn; }; + int f_sx_rref(this S&&, auto) { return xobj_fn; }; + + static int f_sx_crref(Constrain auto) { return static_fn; }; + int f_sx_crref(this S const&&, auto) { return xobj_fn; }; + + // _r + static int f_sx_v_r(auto) { return static_fn; }; + int f_sx_v_r(this S, Constrain auto) { return xobj_fn; }; + + static int f_sx_ref_r(auto) { return static_fn; }; + int f_sx_ref_r(this S&, Constrain auto) { return xobj_fn; }; + + static int f_sx_cref_r(auto) { return static_fn; }; + int f_sx_cref_r(this S const&, Constrain auto) { return xobj_fn; }; + + static int f_sx_rref_r(auto) { return static_fn; }; + int f_sx_rref_r(this S&&, Constrain auto) { return xobj_fn; }; + + static int f_sx_crref_r(auto) { return static_fn; }; + int f_sx_crref_r(this S const&&, Constrain auto) { return xobj_fn; }; + + // xobj/iobj with matching object parameters + + // We are only testing constraints here, so we need parameter lists + // to match, which means we need corresponding object parameters. + // Remember, the rules for object parameter correspondence are weird. + // ([basic.scope.scope-3.1]) + + // *_refqual the iobj member function has a reference qualifier + // *_r the constraint applies to the second definition + + // ix + int f_ix_m0(Constrain auto) { return iobj_fn; }; + int f_ix_m0(this S&, auto) { return xobj_fn; }; + // See note + int f_ix_m1(Constrain auto) { return iobj_fn; }; + int f_ix_m1(this S&&, auto) { return xobj_fn; }; + + int f_ix_c0(Constrain auto) const { return iobj_fn; }; + int f_ix_c0(this S const&, auto) { return xobj_fn; }; + // See note + int f_ix_c1(Constrain auto) const { return iobj_fn; }; + int f_ix_c1(this S const&&, auto) { return xobj_fn; }; + + // xi + int f_xi_m0(this S&, Constrain auto) { return xobj_fn; }; + int f_xi_m0(auto) { return iobj_fn; }; + // See note + int f_xi_m1(this S&&, Constrain auto) { return xobj_fn; }; + int f_xi_m1(auto) { return iobj_fn; }; + + int f_xi_c0(this S const&, Constrain auto) { return xobj_fn; }; + int f_xi_c0(auto) const { return iobj_fn; }; + // See note + int f_xi_c1(this S const&&, Constrain auto) { return xobj_fn; }; + int f_xi_c1(auto) const { return iobj_fn; }; + + // with ref qualifier + + // ix + int f_ix_m0_refqual(Constrain auto) & { return iobj_fn; }; + int f_ix_m0_refqual(this S&, auto) { return xobj_fn; }; + + int f_ix_m1_refqual(Constrain auto) && { return iobj_fn; }; + int f_ix_m1_refqual(this S&&, auto) { return xobj_fn; }; + + int f_ix_c0_refqual(Constrain auto) const& { return iobj_fn; }; + int f_ix_c0_refqual(this S const&, auto) { return xobj_fn; }; + + int f_ix_c1_refqual(Constrain auto) const&& { return iobj_fn; }; + int f_ix_c1_refqual(this S const&&, auto) { return xobj_fn; }; + + // xi + int f_xi_m0_refqual(this S&, Constrain auto) { return xobj_fn; }; + int f_xi_m0_refqual(auto) & { return iobj_fn; }; + + int f_xi_m1_refqual(this S&&, Constrain auto) { return xobj_fn; }; + int f_xi_m1_refqual(auto) && { return iobj_fn; }; + + int f_xi_c0_refqual(this S const&, Constrain auto) { return xobj_fn; }; + int f_xi_c0_refqual(auto) const& { return iobj_fn; }; + + int f_xi_c1_refqual(this S const&&, Constrain auto) { return xobj_fn; }; + int f_xi_c1_refqual(auto) const&& { return iobj_fn; }; + + // _r without ref qualifier + + // ix + int f_ix_m0_r(auto) { return iobj_fn; }; + int f_ix_m0_r(this S&, Constrain auto) { return xobj_fn; }; + // See note + int f_ix_m1_r(auto) { return iobj_fn; }; + int f_ix_m1_r(this S&&, Constrain auto) { return xobj_fn; }; + + int f_ix_c0_r(auto) const { return iobj_fn; }; + int f_ix_c0_r(this S const&, Constrain auto) { return xobj_fn; }; + // See note + int f_ix_c1_r(auto) const { return iobj_fn; }; + int f_ix_c1_r(this S const&&, Constrain auto) { return xobj_fn; }; + + // xi + int f_xi_m0_r(this S&, auto) { return xobj_fn; }; + int f_xi_m0_r(Constrain auto) { return iobj_fn; }; + // See note + int f_xi_m1_r(this S&&, auto) { return xobj_fn; }; + int f_xi_m1_r(Constrain auto) { return iobj_fn; }; + + int f_xi_c0_r(this S const&, auto) { return xobj_fn; }; + int f_xi_c0_r(Constrain auto) const { return iobj_fn; }; + // See note + int f_xi_c1_r(this S const&&, auto) { return xobj_fn; }; + int f_xi_c1_r(Constrain auto) const { return iobj_fn; }; + + // _r with ref qualifier + // ix + int f_ix_m0_refqual_r(auto) & { return iobj_fn; }; + int f_ix_m0_refqual_r(this S&, Constrain auto) { return xobj_fn; }; + + int f_ix_m1_refqual_r(auto) && { return iobj_fn; }; + int f_ix_m1_refqual_r(this S&&, Constrain auto) { return xobj_fn; }; + + int f_ix_c0_refqual_r(auto) const& { return iobj_fn; }; + int f_ix_c0_refqual_r(this S const&, Constrain auto) { return xobj_fn; }; + + int f_ix_c1_refqual_r(auto) const&& { return iobj_fn; }; + int f_ix_c1_refqual_r(this S const&&, Constrain auto) { return xobj_fn; }; + + // xi + int f_xi_m0_refqual_r(this S&, auto) { return xobj_fn; }; + int f_xi_m0_refqual_r(Constrain auto) & { return iobj_fn; }; + + int f_xi_m1_refqual_r(this S&&, auto) { return xobj_fn; }; + int f_xi_m1_refqual_r(Constrain auto) && { return iobj_fn; }; + + int f_xi_c0_refqual_r(this S const&, auto) { return xobj_fn; }; + int f_xi_c0_refqual_r(Constrain auto) const& { return iobj_fn; }; + + int f_xi_c1_refqual_r(this S const&&, auto) { return xobj_fn; }; + int f_xi_c1_refqual_r(Constrain auto) const&& { return iobj_fn; }; +}; + + +int main() +{ + // The commented out cases are ambiguous, which is most likely the correct + // behavior. It is something that I want to propose to change, and I want + // to leave them in as they are a little weird. + // + // Furthermore, as the comment at the top of this file indicates, I am not + // clear on the correct behavior of the static/xobj cases in general. + + S s{}; + if (s.f_xs_v (0) != xobj_fn) + __builtin_abort (); + if (s.f_xs_ref (0) != xobj_fn) + __builtin_abort (); + if (s.f_xs_cref (0) != xobj_fn) + __builtin_abort (); + if (static_cast<S&&>(s).f_xs_rref (0) != xobj_fn) + __builtin_abort (); + if (static_cast<S&&>(s).f_xs_crref (0) != xobj_fn) + __builtin_abort (); + // if (s.f_xs_dv (0) != xobj_fn) + // __builtin_abort (); + // if (s.f_xs_dcref (0) != xobj_fn) + // __builtin_abort (); + // if (s.f_xs_dfwdref (0) != xobj_fn) + // __builtin_abort (); + + if (s.f_xs_v_r (0) != static_fn) + __builtin_abort (); + if (s.f_xs_ref_r (0) != static_fn) + __builtin_abort (); + if (s.f_xs_cref_r (0) != static_fn) + __builtin_abort (); + if (static_cast<S&&>(s).f_xs_rref_r (0) != static_fn) + __builtin_abort (); + if (static_cast<S&&>(s).f_xs_crref_r (0) != static_fn) + __builtin_abort (); + // if (s.f_xs_dv_r (0) != static_fn) + // __builtin_abort (); + // if (s.f_xs_dcref_r (0) != static_fn) + // __builtin_abort (); + // if (s.f_xs_dfwdref_r (0) != static_fn) + // __builtin_abort (); + + if (s.f_sx_v (0) != static_fn) + __builtin_abort (); + if (s.f_sx_ref (0) != static_fn) + __builtin_abort (); + if (s.f_sx_cref (0) != static_fn) + __builtin_abort (); + if (static_cast<S&&>(s).f_sx_rref (0) != static_fn) + __builtin_abort (); + if (static_cast<S&&>(s).f_sx_crref (0) != static_fn) + __builtin_abort (); + // if (s.f_sx_dv (0) != static_fn) + // __builtin_abort (); + // if (s.f_sx_dcref (0) != static_fn) + // __builtin_abort (); + // if (s.f_sx_dfwdref (0) != static_fn) + // __builtin_abort (); + + if (s.f_sx_v_r (0) != xobj_fn) + __builtin_abort (); + if (s.f_sx_ref_r (0) != xobj_fn) + __builtin_abort (); + if (s.f_sx_cref_r (0) != xobj_fn) + __builtin_abort (); + if (static_cast<S&&>(s).f_sx_rref_r (0) != xobj_fn) + __builtin_abort (); + if (static_cast<S&&>(s).f_sx_crref_r (0) != xobj_fn) + __builtin_abort (); + // if (s.f_sx_dv_r (0) != xobj_fn) + // __builtin_abort (); + // if (s.f_sx_dcref_r (0) != xobj_fn) + // __builtin_abort (); + // if (s.f_sx_dfwdref_r (0) != xobj_fn) + // __builtin_abort (); + + // iobj/xobj + + // The commented out cases are tested below as their correct behavior is + // unintuitive, see the note below for details. + + if (s.f_ix_m0 (0) != iobj_fn) + __builtin_abort (); + // s.f_ix_m1 + if (s.f_ix_c0 (0) != iobj_fn) + __builtin_abort (); + // s.f_ix_c1 + if (s.f_xi_m0 (0) != xobj_fn) + __builtin_abort (); + // s.f_xi_m1 + if (s.f_xi_c0 (0) != xobj_fn) + __builtin_abort (); + // s.f_xi_c1 + if (s.f_ix_m0_refqual (0) != iobj_fn) + __builtin_abort (); + if (static_cast<S&&>(s).f_ix_m1_refqual (0) != iobj_fn) + __builtin_abort (); + if (s.f_ix_c0_refqual (0) != iobj_fn) + __builtin_abort (); + if (static_cast<S&&>(s).f_ix_c1_refqual (0) != iobj_fn) + __builtin_abort (); + if (s.f_xi_m0_refqual (0) != xobj_fn) + __builtin_abort (); + if (static_cast<S&&>(s).f_xi_m1_refqual (0) != xobj_fn) + __builtin_abort (); + if (s.f_xi_c0_refqual (0) != xobj_fn) + __builtin_abort (); + if (static_cast<S&&>(s).f_xi_c1_refqual (0) != xobj_fn) + __builtin_abort (); + if (s.f_ix_m0_r (0) != xobj_fn) + __builtin_abort (); + // s.f_ix_m1_r + if (s.f_ix_c0_r (0) != xobj_fn) + __builtin_abort (); + // s.f_ix_c1_r + if (s.f_xi_m0_r (0) != iobj_fn) + __builtin_abort (); + // s.f_xi_m1_r + if (s.f_xi_c0_r (0) != iobj_fn) + __builtin_abort (); + // s.f_xi_c1_r + if (s.f_ix_m0_refqual_r (0) != xobj_fn) + __builtin_abort (); + if (static_cast<S&&>(s).f_ix_m1_refqual_r (0) != xobj_fn) + __builtin_abort (); + if (s.f_ix_c0_refqual_r (0) != xobj_fn) + __builtin_abort (); + if (static_cast<S&&>(s).f_ix_c1_refqual_r (0) != xobj_fn) + __builtin_abort (); + if (s.f_xi_m0_refqual_r (0) != iobj_fn) + __builtin_abort (); + if (static_cast<S&&>(s).f_xi_m1_refqual_r (0) != iobj_fn) + __builtin_abort (); + if (s.f_xi_c0_refqual_r (0) != iobj_fn) + __builtin_abort (); + if (static_cast<S&&>(s).f_xi_c1_refqual_r (0) != iobj_fn) + __builtin_abort (); + + +/* Note: + These cases are weird, the object argument correspond, but are not the same + type ([basic.scope.scope-3.1]), so we get this funny edge case where the + constraint stops them from being considered redeclarations, but isn't taken + into account for the lvalue case. You can't bind an lvalue to an rvalue + reference so the iobj member function is always taken regardless of which + overload is constrained. + + [over.match.funcs.general-4] + For implicit object member functions, the type of the implicit object + parameter is + (4.1) “lvalue reference to cv X” for functions declared without a + ref-qualifier or with the & ref-qualifier + + You would think that calling these functions with an rvalue would be the + same then, always taking the xobj member function. However, for backwards + compatibility reasons, an unqualified member function can be called on an + object that is an rvalue. + + [over.match.funcs.general-5] + For implicit object member functions declared without a ref-qualifier, even + if the implicit object parameter is not const-qualified, an rvalue can be + bound to the parameter as long as in all other respects the argument can be + converted to the type of the implicit object parameter. + + And finally, since the object parameters correspond ([basic.scope.scope-3.1]) + the constraints are taken into account. + + So in conclusion, calling these functions with an lvalue always resolves to + the iobj member function, and calling them with rvalues take the constraints + into account. + + As wacky as this is, this is the correct behavior. */ + + // Always takes the iobj member function, can't bind an lvalue to an rvalue + // reference. + if (s.f_ix_m1 (0) != iobj_fn) + __builtin_abort (); + if (s.f_ix_c1 (0) != iobj_fn) + __builtin_abort (); + if (s.f_xi_m1 (0) != iobj_fn) + __builtin_abort (); + if (s.f_xi_c1 (0) != iobj_fn) + __builtin_abort (); + + if (s.f_ix_m1_r (0) != iobj_fn) + __builtin_abort (); + if (s.f_ix_c1_r (0) != iobj_fn) + __builtin_abort (); + if (s.f_xi_m1_r (0) != iobj_fn) + __builtin_abort (); + if (s.f_xi_c1_r (0) != iobj_fn) + __builtin_abort (); + + // Constraints are taken into account here, see note for more information. + if (static_cast<S&&>(s).f_ix_m1 (0) != iobj_fn) + __builtin_abort (); + if (static_cast<S&&>(s).f_ix_c1 (0) != iobj_fn) + __builtin_abort (); + if (static_cast<S&&>(s).f_xi_m1 (0) != xobj_fn) + __builtin_abort (); + if (static_cast<S&&>(s).f_xi_c1 (0) != xobj_fn) + __builtin_abort (); + + if (static_cast<S&&>(s).f_ix_m1_r (0) != xobj_fn) + __builtin_abort (); + if (static_cast<S&&>(s).f_ix_c1_r (0) != xobj_fn) + __builtin_abort (); + if (static_cast<S&&>(s).f_xi_m1_r (0) != iobj_fn) + __builtin_abort (); + if (static_cast<S&&>(s).f_xi_c1_r (0) != iobj_fn) + __builtin_abort (); +} + diff --git a/gcc/testsuite/g++.dg/cpp23/explicit-obj-constraints2.C b/gcc/testsuite/g++.dg/cpp23/explicit-obj-constraints2.C new file mode 100644 index 0000000..d3909ec --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp23/explicit-obj-constraints2.C @@ -0,0 +1,462 @@ +// P0847R7 +// { dg-do run { target c++23 } } + +// overload resolution of static/xobj and iobj/xobj non-template member functions +// with constraints in a class template + +template<typename T> +concept Constrain = true; + +inline constexpr int iobj_fn = 5; +inline constexpr int xobj_fn = 10; +inline constexpr int static_fn = 20; + +// first 2 letters are the order of the definitions +// the constraint applies to the first definition, +// for *_r cases the constraint applies to the second + +template<typename T> +struct S { + // xobj/static + int f_xs_v(this S) requires Constrain<T> { return xobj_fn; }; + static int f_xs_v() { return static_fn; }; + + int f_xs_ref(this S&) requires Constrain<T> { return xobj_fn; }; + static int f_xs_ref() { return static_fn; }; + + int f_xs_cref(this S const&) requires Constrain<T> { return xobj_fn; }; + static int f_xs_cref() { return static_fn; }; + + int f_xs_rref(this S&&) requires Constrain<T> { return xobj_fn; }; + static int f_xs_rref() { return static_fn; }; + + int f_xs_crref(this S const&&) requires Constrain<T> { return xobj_fn; }; + static int f_xs_crref() { return static_fn; }; + + int f_xs_dv(this auto) requires Constrain<T> { return xobj_fn; }; + static int f_xs_dv() { return static_fn; }; + + int f_xs_dcref(this auto const&) requires Constrain<T> { return xobj_fn; }; + static int f_xs_dcref() { return static_fn; }; + + int f_xs_dfwdref(this auto&&) requires Constrain<T> { return xobj_fn; }; + static int f_xs_dfwdref() { return static_fn; }; + + // _r + int f_xs_v_r(this S) { return xobj_fn; }; + static int f_xs_v_r() requires Constrain<T> { return static_fn; }; + + int f_xs_ref_r(this S&) { return xobj_fn; }; + static int f_xs_ref_r() requires Constrain<T> { return static_fn; }; + + int f_xs_cref_r(this S const&) { return xobj_fn; }; + static int f_xs_cref_r() requires Constrain<T> { return static_fn; }; + + int f_xs_rref_r(this S&&) { return xobj_fn; }; + static int f_xs_rref_r() requires Constrain<T> { return static_fn; }; + + int f_xs_crref_r(this S const&&) { return xobj_fn; }; + static int f_xs_crref_r() requires Constrain<T> { return static_fn; }; + + int f_xs_dv_r(this auto) { return xobj_fn; }; + static int f_xs_dv_r() requires Constrain<T> { return static_fn; }; + + int f_xs_dcref_r(this auto const&) { return xobj_fn; }; + static int f_xs_dcref_r() requires Constrain<T> { return static_fn; }; + + int f_xs_dfwdref_r(this auto&&) { return xobj_fn; }; + static int f_xs_dfwdref_r() requires Constrain<T> { return static_fn; }; + + // static/xobj + static int f_sx_v() requires Constrain<T> { return static_fn; }; + int f_sx_v(this S) { return xobj_fn; }; + + static int f_sx_ref() requires Constrain<T> { return static_fn; }; + int f_sx_ref(this S&) { return xobj_fn; }; + + static int f_sx_cref() requires Constrain<T> { return static_fn; }; + int f_sx_cref(this S const&) { return xobj_fn; }; + + static int f_sx_rref() requires Constrain<T> { return static_fn; }; + int f_sx_rref(this S&&) { return xobj_fn; }; + + static int f_sx_crref() requires Constrain<T> { return static_fn; }; + int f_sx_crref(this S const&&) { return xobj_fn; }; + + static int f_sx_dv() requires Constrain<T> { return static_fn; }; + int f_sx_dv(this auto) { return xobj_fn; }; + + static int f_sx_dcref() requires Constrain<T> { return static_fn; }; + int f_sx_dcref(this auto const&) { return xobj_fn; }; + + static int f_sx_dfwdref() requires Constrain<T> { return static_fn; }; + int f_sx_dfwdref(this auto&&) { return xobj_fn; }; + + // _r + static int f_sx_v_r() { return static_fn; }; + int f_sx_v_r(this S) requires Constrain<T> { return xobj_fn; }; + + static int f_sx_ref_r() { return static_fn; }; + int f_sx_ref_r(this S&) requires Constrain<T> { return xobj_fn; }; + + static int f_sx_cref_r() { return static_fn; }; + int f_sx_cref_r(this S const&) requires Constrain<T> { return xobj_fn; }; + + static int f_sx_rref_r() { return static_fn; }; + int f_sx_rref_r(this S&&) requires Constrain<T> { return xobj_fn; }; + + static int f_sx_crref_r() { return static_fn; }; + int f_sx_crref_r(this S const&&) requires Constrain<T> { return xobj_fn; }; + + static int f_sx_dv_r() { return static_fn; }; + int f_sx_dv_r(this auto) requires Constrain<T> { return xobj_fn; }; + + static int f_sx_dcref_r() { return static_fn; }; + int f_sx_dcref_r(this auto const&) requires Constrain<T> { return xobj_fn; }; + + static int f_sx_dfwdref_r() { return static_fn; }; + int f_sx_dfwdref_r(this auto&&) requires Constrain<T> { return xobj_fn; }; + + // xobj/iobj with matching object parameters + + // We are only testing constraints here, so we need parameter lists + // to match, which means we need corresponding object parameters. + // Remember, the rules for object parameter correspondence are weird. + // ([basic.scope.scope-3.1]) + // + // NOTE: CWG2789 does not specify this properly, I am implementing it + // assuming the above correspondence rules + + // *_refqual the iobj member function has a reference qualifier + // *_r the constraint applies to the second definition + + // ix + int f_ix_m0() requires Constrain<T> { return iobj_fn; }; + int f_ix_m0(this S&) { return xobj_fn; }; + // See note + int f_ix_m1() requires Constrain<T> { return iobj_fn; }; + int f_ix_m1(this S&&) { return xobj_fn; }; + + int f_ix_c0() const requires Constrain<T> { return iobj_fn; }; + int f_ix_c0(this S const&) { return xobj_fn; }; + // See note + int f_ix_c1() const requires Constrain<T> { return iobj_fn; }; + int f_ix_c1(this S const&&) { return xobj_fn; }; + + // xi + int f_xi_m0(this S&) requires Constrain<T> { return xobj_fn; }; + int f_xi_m0() { return iobj_fn; }; + // See note + int f_xi_m1(this S&&) requires Constrain<T> { return xobj_fn; }; + int f_xi_m1() { return iobj_fn; }; + + int f_xi_c0(this S const&) requires Constrain<T> { return xobj_fn; }; + int f_xi_c0() const { return iobj_fn; }; + // See note + int f_xi_c1(this S const&&) requires Constrain<T> { return xobj_fn; }; + int f_xi_c1() const { return iobj_fn; }; + + // with ref qualifier + + // ix + int f_ix_m0_refqual() & requires Constrain<T> { return iobj_fn; }; + int f_ix_m0_refqual(this S&) { return xobj_fn; }; + + int f_ix_m1_refqual() && requires Constrain<T> { return iobj_fn; }; + int f_ix_m1_refqual(this S&&) { return xobj_fn; }; + + int f_ix_c0_refqual() const& requires Constrain<T> { return iobj_fn; }; + int f_ix_c0_refqual(this S const&) { return xobj_fn; }; + + int f_ix_c1_refqual() const&& requires Constrain<T> { return iobj_fn; }; + int f_ix_c1_refqual(this S const&&) { return xobj_fn; }; + + // xi + int f_xi_m0_refqual(this S&) requires Constrain<T> { return xobj_fn; }; + int f_xi_m0_refqual() & { return iobj_fn; }; + + int f_xi_m1_refqual(this S&&) requires Constrain<T> { return xobj_fn; }; + int f_xi_m1_refqual() && { return iobj_fn; }; + + int f_xi_c0_refqual(this S const&) requires Constrain<T> { return xobj_fn; }; + int f_xi_c0_refqual() const& { return iobj_fn; }; + + int f_xi_c1_refqual(this S const&&) requires Constrain<T> { return xobj_fn; }; + int f_xi_c1_refqual() const&& { return iobj_fn; }; + + // _r without ref qualifier + + // ix + int f_ix_m0_r() { return iobj_fn; }; + int f_ix_m0_r(this S&) requires Constrain<T> { return xobj_fn; }; + // See note + int f_ix_m1_r() { return iobj_fn; }; + int f_ix_m1_r(this S&&) requires Constrain<T> { return xobj_fn; }; + + int f_ix_c0_r() const { return iobj_fn; }; + int f_ix_c0_r(this S const&) requires Constrain<T> { return xobj_fn; }; + // See note + int f_ix_c1_r() const { return iobj_fn; }; + int f_ix_c1_r(this S const&&) requires Constrain<T> { return xobj_fn; }; + + // xi + int f_xi_m0_r(this S&) { return xobj_fn; }; + int f_xi_m0_r() requires Constrain<T> { return iobj_fn; }; + // See note + int f_xi_m1_r(this S&&) { return xobj_fn; }; + int f_xi_m1_r() requires Constrain<T> { return iobj_fn; }; + + int f_xi_c0_r(this S const&) { return xobj_fn; }; + int f_xi_c0_r() const requires Constrain<T> { return iobj_fn; }; + // See note + int f_xi_c1_r(this S const&&) { return xobj_fn; }; + int f_xi_c1_r() const requires Constrain<T> { return iobj_fn; }; + + // _r with ref qualifier + // ix + int f_ix_m0_refqual_r() & { return iobj_fn; }; + int f_ix_m0_refqual_r(this S&) requires Constrain<T> { return xobj_fn; }; + + int f_ix_m1_refqual_r() && { return iobj_fn; }; + int f_ix_m1_refqual_r(this S&&) requires Constrain<T> { return xobj_fn; }; + + int f_ix_c0_refqual_r() const& { return iobj_fn; }; + int f_ix_c0_refqual_r(this S const&) requires Constrain<T> { return xobj_fn; }; + + int f_ix_c1_refqual_r() const&& { return iobj_fn; }; + int f_ix_c1_refqual_r(this S const&&) requires Constrain<T> { return xobj_fn; }; + + // xi + int f_xi_m0_refqual_r(this S&) { return xobj_fn; }; + int f_xi_m0_refqual_r() & requires Constrain<T> { return iobj_fn; }; + + int f_xi_m1_refqual_r(this S&&) { return xobj_fn; }; + int f_xi_m1_refqual_r() && requires Constrain<T> { return iobj_fn; }; + + int f_xi_c0_refqual_r(this S const&) { return xobj_fn; }; + int f_xi_c0_refqual_r() const& requires Constrain<T> { return iobj_fn; }; + + int f_xi_c1_refqual_r(this S const&&) { return xobj_fn; }; + int f_xi_c1_refqual_r() const&& requires Constrain<T> { return iobj_fn; }; +}; + +int main() +{ + // The commented out cases are ambiguous, which is most likely the correct + // behavior. It is something that I want to propose to change, and I want + // to leave them in as they are a little weird. + // + // Furthermore, as the comment at the top of this file indicates, I am not + // clear on the correct behavior of the static/xobj cases in general. + using S = S<int>; + S s{}; + if (s.f_xs_v () != xobj_fn) + __builtin_abort (); + if (s.f_xs_ref () != xobj_fn) + __builtin_abort (); + if (s.f_xs_cref () != xobj_fn) + __builtin_abort (); + if (static_cast<S&&>(s).f_xs_rref () != xobj_fn) + __builtin_abort (); + if (static_cast<S&&>(s).f_xs_crref () != xobj_fn) + __builtin_abort (); + // if (s.f_xs_dv () != xobj_fn) + // __builtin_abort (); + // if (s.f_xs_dcref () != xobj_fn) + // __builtin_abort (); + // if (s.f_xs_dfwdref () != xobj_fn) + // __builtin_abort (); + + if (s.f_xs_v_r () != static_fn) + __builtin_abort (); + if (s.f_xs_ref_r () != static_fn) + __builtin_abort (); + if (s.f_xs_cref_r () != static_fn) + __builtin_abort (); + if (static_cast<S&&>(s).f_xs_rref_r () != static_fn) + __builtin_abort (); + if (static_cast<S&&>(s).f_xs_crref_r () != static_fn) + __builtin_abort (); + // if (s.f_xs_dv_r () != static_fn) + // __builtin_abort (); + // if (s.f_xs_dcref_r () != static_fn) + // __builtin_abort (); + // if (s.f_xs_dfwdref_r () != static_fn) + // __builtin_abort (); + + if (s.f_sx_v () != static_fn) + __builtin_abort (); + if (s.f_sx_ref () != static_fn) + __builtin_abort (); + if (s.f_sx_cref () != static_fn) + __builtin_abort (); + if (static_cast<S&&>(s).f_sx_rref () != static_fn) + __builtin_abort (); + if (static_cast<S&&>(s).f_sx_crref () != static_fn) + __builtin_abort (); + // if (s.f_sx_dv () != static_fn) + // __builtin_abort (); + // if (s.f_sx_dcref () != static_fn) + // __builtin_abort (); + // if (s.f_sx_dfwdref () != static_fn) + // __builtin_abort (); + + if (s.f_sx_v_r () != xobj_fn) + __builtin_abort (); + if (s.f_sx_ref_r () != xobj_fn) + __builtin_abort (); + if (s.f_sx_cref_r () != xobj_fn) + __builtin_abort (); + if (static_cast<S&&>(s).f_sx_rref_r () != xobj_fn) + __builtin_abort (); + if (static_cast<S&&>(s).f_sx_crref_r () != xobj_fn) + __builtin_abort (); + // if (s.f_sx_dv_r () != xobj_fn) + // __builtin_abort (); + // if (s.f_sx_dcref_r () != xobj_fn) + // __builtin_abort (); + // if (s.f_sx_dfwdref_r () != xobj_fn) + // __builtin_abort (); + + // iobj/xobj + + // The commented out cases are tested below as their correct behavior is + // unintuitive, see the note below for details. + + if (s.f_ix_m0 () != iobj_fn) + __builtin_abort (); + // s.f_ix_m1 + if (s.f_ix_c0 () != iobj_fn) + __builtin_abort (); + // s.f_ix_c1 + if (s.f_xi_m0 () != xobj_fn) + __builtin_abort (); + // s.f_xi_m1 + if (s.f_xi_c0 () != xobj_fn) + __builtin_abort (); + // s.f_xi_c1 + if (s.f_ix_m0_refqual () != iobj_fn) + __builtin_abort (); + if (static_cast<S&&>(s).f_ix_m1_refqual () != iobj_fn) + __builtin_abort (); + if (s.f_ix_c0_refqual () != iobj_fn) + __builtin_abort (); + if (static_cast<S&&>(s).f_ix_c1_refqual () != iobj_fn) + __builtin_abort (); + if (s.f_xi_m0_refqual () != xobj_fn) + __builtin_abort (); + if (static_cast<S&&>(s).f_xi_m1_refqual () != xobj_fn) + __builtin_abort (); + if (s.f_xi_c0_refqual () != xobj_fn) + __builtin_abort (); + if (static_cast<S&&>(s).f_xi_c1_refqual () != xobj_fn) + __builtin_abort (); + if (s.f_ix_m0_r () != xobj_fn) + __builtin_abort (); + // s.f_ix_m1_r + if (s.f_ix_c0_r () != xobj_fn) + __builtin_abort (); + // s.f_ix_c1_r + if (s.f_xi_m0_r () != iobj_fn) + __builtin_abort (); + // s.f_xi_m1_r + if (s.f_xi_c0_r () != iobj_fn) + __builtin_abort (); + // s.f_xi_c1_r + if (s.f_ix_m0_refqual_r () != xobj_fn) + __builtin_abort (); + if (static_cast<S&&>(s).f_ix_m1_refqual_r () != xobj_fn) + __builtin_abort (); + if (s.f_ix_c0_refqual_r () != xobj_fn) + __builtin_abort (); + if (static_cast<S&&>(s).f_ix_c1_refqual_r () != xobj_fn) + __builtin_abort (); + if (s.f_xi_m0_refqual_r () != iobj_fn) + __builtin_abort (); + if (static_cast<S&&>(s).f_xi_m1_refqual_r () != iobj_fn) + __builtin_abort (); + if (s.f_xi_c0_refqual_r () != iobj_fn) + __builtin_abort (); + if (static_cast<S&&>(s).f_xi_c1_refqual_r () != iobj_fn) + __builtin_abort (); + + +/* Foreword: CWG2789 does not specifiy this correctly, it needs to be changed + to consider correspondence instead of "same type" or else the following + does not make sense. My implementation assumes correspondence should be + considered. + + Note: + These cases are weird, the object argument correspond, but are not the same + type ([basic.scope.scope-3.1]), so we get this funny edge case where the + constraint stops them from being considered redeclarations, but isn't taken + into account for the lvalue case. You can't bind an lvalue to an rvalue + reference so the iobj member function is always taken regardless of which + overload is constrained. + + [over.match.funcs.general-4] + For implicit object member functions, the type of the implicit object + parameter is + (4.1) “lvalue reference to cv X” for functions declared without a + ref-qualifier or with the & ref-qualifier + + You would think that calling these functions with an rvalue would be the + same then, always taking the xobj member function. However, for backwards + compatibility reasons, an unqualified member function can be called on an + object that is an rvalue. + + [over.match.funcs.general-5] + For implicit object member functions declared without a ref-qualifier, even + if the implicit object parameter is not const-qualified, an rvalue can be + bound to the parameter as long as in all other respects the argument can be + converted to the type of the implicit object parameter. + + And finally, since the object parameters correspond ([basic.scope.scope-3.1]) + the constraints are taken into account. + + So in conclusion, calling these functions with an lvalue always resolves to + the iobj member function, and calling them with rvalues take the constraints + into account. + + As wacky as this is, this is the correct behavior. */ + + // Always takes the iobj member function, can't bind an lvalue to an rvalue + // reference. + if (s.f_ix_m1 () != iobj_fn) + __builtin_abort (); + if (s.f_ix_c1 () != iobj_fn) + __builtin_abort (); + if (s.f_xi_m1 () != iobj_fn) + __builtin_abort (); + if (s.f_xi_c1 () != iobj_fn) + __builtin_abort (); + + if (s.f_ix_m1_r () != iobj_fn) + __builtin_abort (); + if (s.f_ix_c1_r () != iobj_fn) + __builtin_abort (); + if (s.f_xi_m1_r () != iobj_fn) + __builtin_abort (); + if (s.f_xi_c1_r () != iobj_fn) + __builtin_abort (); + + // Constraints are taken into account here, see note for more information. + if (static_cast<S&&>(s).f_ix_m1 () != iobj_fn) + __builtin_abort (); + if (static_cast<S&&>(s).f_ix_c1 () != iobj_fn) + __builtin_abort (); + if (static_cast<S&&>(s).f_xi_m1 () != xobj_fn) + __builtin_abort (); + if (static_cast<S&&>(s).f_xi_c1 () != xobj_fn) + __builtin_abort (); + + if (static_cast<S&&>(s).f_ix_m1_r () != xobj_fn) + __builtin_abort (); + if (static_cast<S&&>(s).f_ix_c1_r () != xobj_fn) + __builtin_abort (); + if (static_cast<S&&>(s).f_xi_m1_r () != iobj_fn) + __builtin_abort (); + if (static_cast<S&&>(s).f_xi_c1_r () != iobj_fn) + __builtin_abort (); +} + diff --git a/gcc/testsuite/g++.dg/cpp23/explicit-obj-cxx-dialect-A.C b/gcc/testsuite/g++.dg/cpp23/explicit-obj-cxx-dialect-A.C new file mode 100644 index 0000000..5043e91 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp23/explicit-obj-cxx-dialect-A.C @@ -0,0 +1,7 @@ +// P0847R7 +// { dg-do compile { target c++23 } } + +struct S { + void f(this S); // { dg-bogus {explicit object member function only available with '-std=c\+\+23' or '-std=gnu\+\+23'} } +}; + diff --git a/gcc/testsuite/g++.dg/cpp23/explicit-obj-cxx-dialect-B.C b/gcc/testsuite/g++.dg/cpp23/explicit-obj-cxx-dialect-B.C new file mode 100644 index 0000000..fb2a6a0 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp23/explicit-obj-cxx-dialect-B.C @@ -0,0 +1,7 @@ +// P0847R7 +// { dg-do compile { target c++20_down } } + +struct S { + void f(this S); // { dg-error {explicit object member function only available with '-std=c\+\+23' or '-std=gnu\+\+23'} } +}; + diff --git a/gcc/testsuite/g++.dg/cpp23/explicit-obj-cxx-dialect-C.C b/gcc/testsuite/g++.dg/cpp23/explicit-obj-cxx-dialect-C.C new file mode 100644 index 0000000..182e294 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp23/explicit-obj-cxx-dialect-C.C @@ -0,0 +1,9 @@ +// P0847R7 +// { dg-do compile { target c++20_down } } +// don't pass in -pedantic-errors +// { dg-options "" } + +struct S { + void f(this S); // { dg-warning {explicit object member function only available with '-std=c\+\+23' or '-std=gnu\+\+23'} } +}; + diff --git a/gcc/testsuite/g++.dg/cpp23/explicit-obj-cxx-dialect-D.C b/gcc/testsuite/g++.dg/cpp23/explicit-obj-cxx-dialect-D.C new file mode 100644 index 0000000..49b7ea0 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp23/explicit-obj-cxx-dialect-D.C @@ -0,0 +1,8 @@ +// P0847R7 +// { dg-do compile { target c++20_down } } +// { dg-options "-Wno-c++23-extensions" } + +struct S { + void f(this S); // { dg-bogus {explicit object member function only available with '-std=c\+\+23' or '-std=gnu\+\+23'} } +}; + diff --git a/gcc/testsuite/g++.dg/cpp23/explicit-obj-cxx-dialect-E.C b/gcc/testsuite/g++.dg/cpp23/explicit-obj-cxx-dialect-E.C new file mode 100644 index 0000000..411b70c --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp23/explicit-obj-cxx-dialect-E.C @@ -0,0 +1,8 @@ +// P0847R7 +// { dg-do compile { target c++20_down } } +// { dg-options "-Wno-c++23-extensions -pedantic-errors" } + +struct S { + void f(this S); // { dg-bogus {explicit object member function only available with '-std=c\+\+23' or '-std=gnu\+\+23'} } +}; + diff --git a/gcc/testsuite/g++.dg/cpp23/explicit-obj-default1.C b/gcc/testsuite/g++.dg/cpp23/explicit-obj-default1.C new file mode 100644 index 0000000..fac3c28 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp23/explicit-obj-default1.C @@ -0,0 +1,57 @@ +// P0847R7 +// { dg-do run { target c++23 } } + +// defaulted comparison operators + +#include <compare> + +struct S { + int _v; + bool operator==(this S const&, S const&) = default; + auto operator<=>(this S const&, S const&) = default; +}; + +int main() +{ + S const a_10{10}; + S const b_10{10}; + S const c_20{20}; + S const d_5{5}; + + if (a_10 != b_10) + __builtin_abort (); + if (c_20 == a_10) + __builtin_abort (); + if (!(a_10 == b_10)) + __builtin_abort (); + if (!(c_20 != a_10)) + __builtin_abort (); + + if (a_10 < b_10) + __builtin_abort (); + if (a_10 > b_10) + __builtin_abort (); + if (!(a_10 <= b_10)) + __builtin_abort (); + if (!(a_10 >= b_10)) + __builtin_abort (); + + if (!(a_10 < c_20)) + __builtin_abort (); + if (a_10 > c_20) + __builtin_abort (); + if (!(a_10 <= c_20)) + __builtin_abort (); + if (a_10 >= c_20) + __builtin_abort (); + + if (a_10 < d_5) + __builtin_abort (); + if (!(a_10 > d_5)) + __builtin_abort (); + if (a_10 <= d_5) + __builtin_abort (); + if (!(a_10 >= d_5)) + __builtin_abort (); +} + diff --git a/gcc/testsuite/g++.dg/cpp23/explicit-obj-default2.C b/gcc/testsuite/g++.dg/cpp23/explicit-obj-default2.C new file mode 100644 index 0000000..786f0c2 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp23/explicit-obj-default2.C @@ -0,0 +1,65 @@ +// P0847R7 +// { dg-do run { target c++23 } } + +// defaulted copy/move assignment operators + +inline constexpr int add_when_copy = 5; +inline constexpr int add_when_move = 10; +inline constexpr int poison = -1; + +struct A { + int _v; + A(int v) : _v(v) {} + A& operator=(A const& rhs) { + if (&rhs == this) + return *this; + _v = rhs._v + add_when_copy; + return *this; + } + A& operator=(A&& rhs) { + if (&rhs == this) + return *this; + _v = rhs._v + add_when_move; + rhs._v = poison; + return *this; + } +}; + +struct S { + A _a; + S& operator=(this S&, S const&) = default; + S& operator=(this S&, S&&) = default; + + int v() const { return _a._v; } +}; + +inline constexpr int init_val = 5; + +int main() +{ + S s0{0}; + S s1{init_val}; + + // Sanity check. + if (s0.v () != 0 + || s1.v () != init_val) + __builtin_abort (); + + s0 = s1; + if (s0.v () != init_val + add_when_copy) + __builtin_abort (); + if (s1.v () != init_val) + __builtin_abort (); + + s0 = S{init_val}; + if (s0.v () != init_val + add_when_move) + __builtin_abort (); + + S s2{init_val}; + s0 = static_cast<S&&>(s2); + if (s0.v () != init_val + add_when_move) + __builtin_abort (); + if (s2.v () != poison) + __builtin_abort (); +} + diff --git a/gcc/testsuite/g++.dg/cpp23/explicit-obj-diagnostics1.C b/gcc/testsuite/g++.dg/cpp23/explicit-obj-diagnostics1.C new file mode 100644 index 0000000..dfac118 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp23/explicit-obj-diagnostics1.C @@ -0,0 +1,139 @@ +// P0847R7 +// { dg-do compile { target c++23 } } + +// rejection and diagnosis of xobj member functions that have member function qualifiers. + +struct S { + void f_value_0(this S) const; // { dg-error "explicit object member function '(?!static)\[^\n\r\]+' cannot have cv-qualifier" } + void f_value_1(this S) volatile; // { dg-error "explicit object member function '(?!static)\[^\n\r\]+' cannot have cv-qualifier" } + void f_value_2(this S) const volatile; // { dg-error "explicit object member function '(?!static)\[^\n\r\]+' cannot have cv-qualifier" } + void f_value_3(this S) &; // { dg-error "explicit object member function '(?!static)\[^\n\r\]+' cannot have ref-qualifier" } + void f_value_4(this S) &&; // { dg-error "explicit object member function '(?!static)\[^\n\r\]+' cannot have ref-qualifier" } + void f_value_5(this S) const &; // { dg-error "explicit object member function '(?!static)\[^\n\r\]+' cannot have (ref|cv)-qualifier" } + void f_value_6(this S) const &&; // { dg-error "explicit object member function '(?!static)\[^\n\r\]+' cannot have (ref|cv)-qualifier" } + void f_value_7(this S) volatile &; // { dg-error "explicit object member function '(?!static)\[^\n\r\]+' cannot have (ref|cv)-qualifier" } + void f_value_8(this S) volatile &&; // { dg-error "explicit object member function '(?!static)\[^\n\r\]+' cannot have (ref|cv)-qualifier" } + void f_value_9(this S) const volatile &; // { dg-error "explicit object member function '(?!static)\[^\n\r\]+' cannot have (ref|cv)-qualifier" } + void f_value_A(this S) const volatile &&; // { dg-error "explicit object member function '(?!static)\[^\n\r\]+' cannot have (ref|cv)-qualifier" } + + void f_ref_0(this S&) const; // { dg-error "explicit object member function '(?!static)\[^\n\r\]+' cannot have cv-qualifier" } + void f_ref_1(this S&) volatile; // { dg-error "explicit object member function '(?!static)\[^\n\r\]+' cannot have cv-qualifier" } + void f_ref_2(this S&) const volatile; // { dg-error "explicit object member function '(?!static)\[^\n\r\]+' cannot have cv-qualifier" } + void f_ref_3(this S&) &; // { dg-error "explicit object member function '(?!static)\[^\n\r\]+' cannot have ref-qualifier" } + void f_ref_4(this S&) &&; // { dg-error "explicit object member function '(?!static)\[^\n\r\]+' cannot have ref-qualifier" } + void f_ref_5(this S&) const &; // { dg-error "explicit object member function '(?!static)\[^\n\r\]+' cannot have (ref|cv)-qualifier" } + void f_ref_6(this S&) const &&; // { dg-error "explicit object member function '(?!static)\[^\n\r\]+' cannot have (ref|cv)-qualifier" } + void f_ref_7(this S&) volatile &; // { dg-error "explicit object member function '(?!static)\[^\n\r\]+' cannot have (ref|cv)-qualifier" } + void f_ref_8(this S&) volatile &&; // { dg-error "explicit object member function '(?!static)\[^\n\r\]+' cannot have (ref|cv)-qualifier" } + void f_ref_9(this S&) const volatile &; // { dg-error "explicit object member function '(?!static)\[^\n\r\]+' cannot have (ref|cv)-qualifier" } + void f_ref_A(this S&) const volatile &&; // { dg-error "explicit object member function '(?!static)\[^\n\r\]+' cannot have (ref|cv)-qualifier" } + + void f_refref_0(this S&&) const; // { dg-error "explicit object member function '(?!static)\[^\n\r\]+' cannot have cv-qualifier" } + void f_refref_1(this S&&) volatile; // { dg-error "explicit object member function '(?!static)\[^\n\r\]+' cannot have cv-qualifier" } + void f_refref_2(this S&&) const volatile; // { dg-error "explicit object member function '(?!static)\[^\n\r\]+' cannot have cv-qualifier" } + void f_refref_3(this S&&) &; // { dg-error "explicit object member function '(?!static)\[^\n\r\]+' cannot have ref-qualifier" } + void f_refref_4(this S&&) &&; // { dg-error "explicit object member function '(?!static)\[^\n\r\]+' cannot have ref-qualifier" } + void f_refref_5(this S&&) const &; // { dg-error "explicit object member function '(?!static)\[^\n\r\]+' cannot have (ref|cv)-qualifier" } + void f_refref_6(this S&&) const &&; // { dg-error "explicit object member function '(?!static)\[^\n\r\]+' cannot have (ref|cv)-qualifier" } + void f_refref_7(this S&&) volatile &; // { dg-error "explicit object member function '(?!static)\[^\n\r\]+' cannot have (ref|cv)-qualifier" } + void f_refref_8(this S&&) volatile &&; // { dg-error "explicit object member function '(?!static)\[^\n\r\]+' cannot have (ref|cv)-qualifier" } + void f_refref_9(this S&&) const volatile &; // { dg-error "explicit object member function '(?!static)\[^\n\r\]+' cannot have (ref|cv)-qualifier" } + void f_refref_A(this S&&) const volatile &&; // { dg-error "explicit object member function '(?!static)\[^\n\r\]+' cannot have (ref|cv)-qualifier" } + + void f_cref_0(this S const&) const; // { dg-error "explicit object member function '(?!static)\[^\n\r\]+' cannot have cv-qualifier" } + void f_cref_1(this S const&) volatile; // { dg-error "explicit object member function '(?!static)\[^\n\r\]+' cannot have cv-qualifier" } + void f_cref_2(this S const&) const volatile; // { dg-error "explicit object member function '(?!static)\[^\n\r\]+' cannot have cv-qualifier" } + void f_cref_3(this S const&) &; // { dg-error "explicit object member function '(?!static)\[^\n\r\]+' cannot have ref-qualifier" } + void f_cref_4(this S const&) &&; // { dg-error "explicit object member function '(?!static)\[^\n\r\]+' cannot have ref-qualifier" } + void f_cref_5(this S const&) const &; // { dg-error "explicit object member function '(?!static)\[^\n\r\]+' cannot have (ref|cv)-qualifier" } + void f_cref_6(this S const&) const &&; // { dg-error "explicit object member function '(?!static)\[^\n\r\]+' cannot have (ref|cv)-qualifier" } + void f_cref_7(this S const&) volatile &; // { dg-error "explicit object member function '(?!static)\[^\n\r\]+' cannot have (ref|cv)-qualifier" } + void f_cref_8(this S const&) volatile &&; // { dg-error "explicit object member function '(?!static)\[^\n\r\]+' cannot have (ref|cv)-qualifier" } + void f_cref_9(this S const&) const volatile &; // { dg-error "explicit object member function '(?!static)\[^\n\r\]+' cannot have (ref|cv)-qualifier" } + void f_cref_A(this S const&) const volatile &&; // { dg-error "explicit object member function '(?!static)\[^\n\r\]+' cannot have (ref|cv)-qualifier" } + + void f_crefref_0(this S const&&) const; // { dg-error "explicit object member function '(?!static)\[^\n\r\]+' cannot have cv-qualifier" } + void f_crefref_1(this S const&&) volatile; // { dg-error "explicit object member function '(?!static)\[^\n\r\]+' cannot have cv-qualifier" } + void f_crefref_2(this S const&&) const volatile; // { dg-error "explicit object member function '(?!static)\[^\n\r\]+' cannot have cv-qualifier" } + void f_crefref_3(this S const&&) &; // { dg-error "explicit object member function '(?!static)\[^\n\r\]+' cannot have ref-qualifier" } + void f_crefref_4(this S const&&) &&; // { dg-error "explicit object member function '(?!static)\[^\n\r\]+' cannot have ref-qualifier" } + void f_crefref_5(this S const&&) const &; // { dg-error "explicit object member function '(?!static)\[^\n\r\]+' cannot have (ref|cv)-qualifier" } + void f_crefref_6(this S const&&) const &&; // { dg-error "explicit object member function '(?!static)\[^\n\r\]+' cannot have (ref|cv)-qualifier" } + void f_crefref_7(this S const&&) volatile &; // { dg-error "explicit object member function '(?!static)\[^\n\r\]+' cannot have (ref|cv)-qualifier" } + void f_crefref_8(this S const&&) volatile &&; // { dg-error "explicit object member function '(?!static)\[^\n\r\]+' cannot have (ref|cv)-qualifier" } + void f_crefref_9(this S const&&) const volatile &; // { dg-error "explicit object member function '(?!static)\[^\n\r\]+' cannot have (ref|cv)-qualifier" } + void f_crefref_A(this S const&&) const volatile &&; // { dg-error "explicit object member function '(?!static)\[^\n\r\]+' cannot have (ref|cv)-qualifier" } + + void f_vref_0(this S volatile&) const; // { dg-error "explicit object member function '(?!static)\[^\n\r\]+' cannot have cv-qualifier" } + void f_vref_1(this S volatile&) volatile; // { dg-error "explicit object member function '(?!static)\[^\n\r\]+' cannot have cv-qualifier" } + void f_vref_2(this S volatile&) const volatile; // { dg-error "explicit object member function '(?!static)\[^\n\r\]+' cannot have cv-qualifier" } + void f_vref_3(this S volatile&) &; // { dg-error "explicit object member function '(?!static)\[^\n\r\]+' cannot have ref-qualifier" } + void f_vref_4(this S volatile&) &&; // { dg-error "explicit object member function '(?!static)\[^\n\r\]+' cannot have ref-qualifier" } + void f_vref_5(this S volatile&) const &; // { dg-error "explicit object member function '(?!static)\[^\n\r\]+' cannot have (ref|cv)-qualifier" } + void f_vref_6(this S volatile&) const &&; // { dg-error "explicit object member function '(?!static)\[^\n\r\]+' cannot have (ref|cv)-qualifier" } + void f_vref_7(this S volatile&) volatile &; // { dg-error "explicit object member function '(?!static)\[^\n\r\]+' cannot have (ref|cv)-qualifier" } + void f_vref_8(this S volatile&) volatile &&; // { dg-error "explicit object member function '(?!static)\[^\n\r\]+' cannot have (ref|cv)-qualifier" } + void f_vref_9(this S volatile&) const volatile &; // { dg-error "explicit object member function '(?!static)\[^\n\r\]+' cannot have (ref|cv)-qualifier" } + void f_vref_A(this S volatile&) const volatile &&; // { dg-error "explicit object member function '(?!static)\[^\n\r\]+' cannot have (ref|cv)-qualifier" } + + void f_vrefref_0(this S volatile&&) const; // { dg-error "explicit object member function '(?!static)\[^\n\r\]+' cannot have cv-qualifier" } + void f_vrefref_1(this S volatile&&) volatile; // { dg-error "explicit object member function '(?!static)\[^\n\r\]+' cannot have cv-qualifier" } + void f_vrefref_2(this S volatile&&) const volatile; // { dg-error "explicit object member function '(?!static)\[^\n\r\]+' cannot have cv-qualifier" } + void f_vrefref_3(this S volatile&&) &; // { dg-error "explicit object member function '(?!static)\[^\n\r\]+' cannot have ref-qualifier" } + void f_vrefref_4(this S volatile&&) &&; // { dg-error "explicit object member function '(?!static)\[^\n\r\]+' cannot have ref-qualifier" } + void f_vrefref_5(this S volatile&&) const &; // { dg-error "explicit object member function '(?!static)\[^\n\r\]+' cannot have (ref|cv)-qualifier" } + void f_vrefref_6(this S volatile&&) const &&; // { dg-error "explicit object member function '(?!static)\[^\n\r\]+' cannot have (ref|cv)-qualifier" } + void f_vrefref_7(this S volatile&&) volatile &; // { dg-error "explicit object member function '(?!static)\[^\n\r\]+' cannot have (ref|cv)-qualifier" } + void f_vrefref_8(this S volatile&&) volatile &&; // { dg-error "explicit object member function '(?!static)\[^\n\r\]+' cannot have (ref|cv)-qualifier" } + void f_vrefref_9(this S volatile&&) const volatile &; // { dg-error "explicit object member function '(?!static)\[^\n\r\]+' cannot have (ref|cv)-qualifier" } + void f_vrefref_A(this S volatile&&) const volatile &&; // { dg-error "explicit object member function '(?!static)\[^\n\r\]+' cannot have (ref|cv)-qualifier" } + + void f_cvref_0(this S const volatile&) const; // { dg-error "explicit object member function '(?!static)\[^\n\r\]+' cannot have cv-qualifier" } + void f_cvref_1(this S const volatile&) volatile; // { dg-error "explicit object member function '(?!static)\[^\n\r\]+' cannot have cv-qualifier" } + void f_cvref_2(this S const volatile&) const volatile; // { dg-error "explicit object member function '(?!static)\[^\n\r\]+' cannot have cv-qualifier" } + void f_cvref_3(this S const volatile&) &; // { dg-error "explicit object member function '(?!static)\[^\n\r\]+' cannot have ref-qualifier" } + void f_cvref_4(this S const volatile&) &&; // { dg-error "explicit object member function '(?!static)\[^\n\r\]+' cannot have ref-qualifier" } + void f_cvref_5(this S const volatile&) const &; // { dg-error "explicit object member function '(?!static)\[^\n\r\]+' cannot have (ref|cv)-qualifier" } + void f_cvref_6(this S const volatile&) const &&; // { dg-error "explicit object member function '(?!static)\[^\n\r\]+' cannot have (ref|cv)-qualifier" } + void f_cvref_7(this S const volatile&) volatile &; // { dg-error "explicit object member function '(?!static)\[^\n\r\]+' cannot have (ref|cv)-qualifier" } + void f_cvref_8(this S const volatile&) volatile &&; // { dg-error "explicit object member function '(?!static)\[^\n\r\]+' cannot have (ref|cv)-qualifier" } + void f_cvref_9(this S const volatile&) const volatile &; // { dg-error "explicit object member function '(?!static)\[^\n\r\]+' cannot have (ref|cv)-qualifier" } + void f_cvref_A(this S const volatile&) const volatile &&; // { dg-error "explicit object member function '(?!static)\[^\n\r\]+' cannot have (ref|cv)-qualifier" } + + void f_cvrefref_0(this S const volatile&&) const; // { dg-error "explicit object member function '(?!static)\[^\n\r\]+' cannot have cv-qualifier" } + void f_cvrefref_1(this S const volatile&&) volatile; // { dg-error "explicit object member function '(?!static)\[^\n\r\]+' cannot have cv-qualifier" } + void f_cvrefref_2(this S const volatile&&) const volatile; // { dg-error "explicit object member function '(?!static)\[^\n\r\]+' cannot have cv-qualifier" } + void f_cvrefref_3(this S const volatile&&) &; // { dg-error "explicit object member function '(?!static)\[^\n\r\]+' cannot have ref-qualifier" } + void f_cvrefref_4(this S const volatile&&) &&; // { dg-error "explicit object member function '(?!static)\[^\n\r\]+' cannot have ref-qualifier" } + void f_cvrefref_5(this S const volatile&&) const &; // { dg-error "explicit object member function '(?!static)\[^\n\r\]+' cannot have (ref|cv)-qualifier" } + void f_cvrefref_6(this S const volatile&&) const &&; // { dg-error "explicit object member function '(?!static)\[^\n\r\]+' cannot have (ref|cv)-qualifier" } + void f_cvrefref_7(this S const volatile&&) volatile &; // { dg-error "explicit object member function '(?!static)\[^\n\r\]+' cannot have (ref|cv)-qualifier" } + void f_cvrefref_8(this S const volatile&&) volatile &&; // { dg-error "explicit object member function '(?!static)\[^\n\r\]+' cannot have (ref|cv)-qualifier" } + void f_cvrefref_9(this S const volatile&&) const volatile &; // { dg-error "explicit object member function '(?!static)\[^\n\r\]+' cannot have (ref|cv)-qualifier" } + void f_cvrefref_A(this S const volatile&&) const volatile &&; // { dg-error "explicit object member function '(?!static)\[^\n\r\]+' cannot have (ref|cv)-qualifier" } + + template<typename Self> void d_templ_0(this Self&&) const; // { dg-error "explicit object member function '(?!static)\[^\n\r\]+' cannot have cv-qualifier" } + template<typename Self> void d_templ_1(this Self&&) volatile; // { dg-error "explicit object member function '(?!static)\[^\n\r\]+' cannot have cv-qualifier" } + template<typename Self> void d_templ_2(this Self&&) const volatile; // { dg-error "explicit object member function '(?!static)\[^\n\r\]+' cannot have cv-qualifier" } + template<typename Self> void d_templ_3(this Self&&) &; // { dg-error "explicit object member function '(?!static)\[^\n\r\]+' cannot have ref-qualifier" } + template<typename Self> void d_templ_4(this Self&&) &&; // { dg-error "explicit object member function '(?!static)\[^\n\r\]+' cannot have ref-qualifier" } + template<typename Self> void d_templ_5(this Self&&) const &; // { dg-error "explicit object member function '(?!static)\[^\n\r\]+' cannot have (ref|cv)-qualifier" } + template<typename Self> void d_templ_6(this Self&&) const &&; // { dg-error "explicit object member function '(?!static)\[^\n\r\]+' cannot have (ref|cv)-qualifier" } + template<typename Self> void d_templ_7(this Self&&) volatile &; // { dg-error "explicit object member function '(?!static)\[^\n\r\]+' cannot have (ref|cv)-qualifier" } + template<typename Self> void d_templ_8(this Self&&) volatile &&; // { dg-error "explicit object member function '(?!static)\[^\n\r\]+' cannot have (ref|cv)-qualifier" } + template<typename Self> void d_templ_9(this Self&&) const volatile &; // { dg-error "explicit object member function '(?!static)\[^\n\r\]+' cannot have (ref|cv)-qualifier" } + template<typename Self> void d_templ_A(this Self&&) const volatile &&; // { dg-error "explicit object member function '(?!static)\[^\n\r\]+' cannot have (ref|cv)-qualifier" } + + void d_auto_0(this auto&&) const; // { dg-error "explicit object member function '(?!static)\[^\n\r\]+' cannot have cv-qualifier" } + void d_auto_1(this auto&&) volatile; // { dg-error "explicit object member function '(?!static)\[^\n\r\]+' cannot have cv-qualifier" } + void d_auto_2(this auto&&) const volatile; // { dg-error "explicit object member function '(?!static)\[^\n\r\]+' cannot have cv-qualifier" } + void d_auto_3(this auto&&) &; // { dg-error "explicit object member function '(?!static)\[^\n\r\]+' cannot have ref-qualifier" } + void d_auto_4(this auto&&) &&; // { dg-error "explicit object member function '(?!static)\[^\n\r\]+' cannot have ref-qualifier" } + void d_auto_5(this auto&&) const &; // { dg-error "explicit object member function '(?!static)\[^\n\r\]+' cannot have (ref|cv)-qualifier" } + void d_auto_6(this auto&&) const &&; // { dg-error "explicit object member function '(?!static)\[^\n\r\]+' cannot have (ref|cv)-qualifier" } + void d_auto_7(this auto&&) volatile &; // { dg-error "explicit object member function '(?!static)\[^\n\r\]+' cannot have (ref|cv)-qualifier" } + void d_auto_8(this auto&&) volatile &&; // { dg-error "explicit object member function '(?!static)\[^\n\r\]+' cannot have (ref|cv)-qualifier" } + void d_auto_9(this auto&&) const volatile &; // { dg-error "explicit object member function '(?!static)\[^\n\r\]+' cannot have (ref|cv)-qualifier" } + void d_auto_A(this auto&&) const volatile &&; // { dg-error "explicit object member function '(?!static)\[^\n\r\]+' cannot have (ref|cv)-qualifier" } +}; + diff --git a/gcc/testsuite/g++.dg/cpp23/explicit-obj-diagnostics2.C b/gcc/testsuite/g++.dg/cpp23/explicit-obj-diagnostics2.C new file mode 100644 index 0000000..771200b --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp23/explicit-obj-diagnostics2.C @@ -0,0 +1,26 @@ +// P0847R7 +// { dg-do compile { target c++23 } } + +// rejection and diagnosis of incorrect uses of 'this' in declarations and definitions + +using func_type = void(this int); // { dg-line func_type_line } +// { dg-error "a function type cannot have an explicit object parameter" "" { target *-*-* } func_type_line } +// { dg-note "the type of an explicit object member function is a regular function type" "" { target *-*-* } func_type_line } + +using func_ptr_type = void(*)(this int); // { dg-line func_ptr_type_line } +// { dg-error "a pointer to function type cannot have an explicit object parameter" "" { target *-*-* } func_ptr_type_line } +// { dg-note "the type of a pointer to explicit object member function is a regular pointer to function type" "" { target *-*-* } func_ptr_type_line } + +struct S { + static void f(this S) {} // { dg-line static_member_func_line } +}; +// { dg-error "an explicit object member function cannot be 'static'" "" { target *-*-* } static_member_func_line } +// { dg-note "explicit object parameter declared here" "" { target *-*-* } static_member_func_line } + +using mem_func_type = void (S::*)(this S&); // { dg-line mem_func_type_line } +// { dg-error "a pointer to member function type cannot have an explicit object parameter" "" { target *-*-* } mem_func_type_line } +// { dg-note "the type of a pointer to explicit object member function is a regular pointer to function type" "" { target *-*-* } mem_func_type_line } + +void f(this int); // { dg-error "a non-member function cannot have an explicit object parameter" } +void f(this int) {} // { dg-error "a non-member function cannot have an explicit object parameter" } + diff --git a/gcc/testsuite/g++.dg/cpp23/explicit-obj-diagnostics3.C b/gcc/testsuite/g++.dg/cpp23/explicit-obj-diagnostics3.C new file mode 100644 index 0000000..ec091d6 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp23/explicit-obj-diagnostics3.C @@ -0,0 +1,20 @@ +// P0847R7 +// { dg-do compile { target c++23 } } + +// rejection and diagnosis of an xobj parameter declared with a default argument + +struct S { + void f0(this S = {}) {} // { dg-error "an explicit object parameter may not have a default argument" } + void f1(this S = {}); // { dg-error "an explicit object parameter may not have a default argument" } + void f2(this S); + void f10(this S s = {}) {} // { dg-error "an explicit object parameter may not have a default argument" } + void f11(this S s = {}); // { dg-error "an explicit object parameter may not have a default argument" } + void f12(this S s); +}; + +void S::f1(this S) {} +void S::f2(this S = {}) {} // { dg-error "an explicit object parameter may not have a default argument" } + +void S::f11(this S s) {} +void S::f12(this S s = {}) {} // { dg-error "an explicit object parameter may not have a default argument" } + diff --git a/gcc/testsuite/g++.dg/cpp23/explicit-obj-diagnostics4.C b/gcc/testsuite/g++.dg/cpp23/explicit-obj-diagnostics4.C new file mode 100644 index 0000000..1744b3f --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp23/explicit-obj-diagnostics4.C @@ -0,0 +1,16 @@ +// P0847R7 +// { dg-do compile { target c++23 } } + +// location diagnostic text when an error is emitted from an xobj member function +// this does not test for specific ill-formed code, just the additional diagnostic message + +// { dg-message "In explicit object member function" "" { target *-*-* } 0 } + +struct S { + void f(this S s) { + // The specific diagnosis issued here does not matter + // we just need to force an error to be emitted + +s; // { dg-error "" } + } +}; + diff --git a/gcc/testsuite/g++.dg/cpp23/explicit-obj-diagnostics5.C b/gcc/testsuite/g++.dg/cpp23/explicit-obj-diagnostics5.C new file mode 100644 index 0000000..7ec43f6 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp23/explicit-obj-diagnostics5.C @@ -0,0 +1,23 @@ +// P0847R7 +// { dg-do compile { target c++23 } } + +// rejection and diagnosis of invalid uses of 'this' in body of xobj member functions + +// { dg-message "In explicit object member function" "" { target *-*-* } 0 } + +struct S0 { + int _n; + void f(this S0& s) { // { dg-note {use explicit object parameter 's' instead} } + this->_n = 10; // { dg-error "'this' is unavailable for explicit object member functions" } + // suppress unused variable warning + static_cast<void>(s); + } +}; + +struct S1 { + int _n; + void f(this S1&) { // { dg-note "name the explicit object parameter" } + this->_n = 10; // { dg-error "'this' is unavailable for explicit object member functions" } + } +}; + diff --git a/gcc/testsuite/g++.dg/cpp23/explicit-obj-diagnostics6.C b/gcc/testsuite/g++.dg/cpp23/explicit-obj-diagnostics6.C new file mode 100644 index 0000000..77ace49 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp23/explicit-obj-diagnostics6.C @@ -0,0 +1,206 @@ +// P0847R7 +// { dg-do compile { target c++23 } } + +// rejection and diagnosis when taking address of an unqualified xobj member function + +// { dg-message "In explicit object member function" "" { target *-*-* } 0 } + +struct S { + void f(this S&) {} + + void g(this S&) {} + void g(this S&, int) {} + + void test0() { + void (*fp)(S&) = &f; // { dg-line line_sf } + // { dg-error {ISO C\+\+ forbids taking the address of an unqualified or parenthesized non-static member function to form a pointer to explicit object member function} "" { target *-*-* } line_sf } + // { dg-note {a pointer to explicit object member function can only be formed with '&S::f'} "" { target *-*-* } line_sf } + void (*gp)(S&) = &g; // { dg-line line_sg } + // { dg-error {ISO C\+\+ forbids taking the address of an unqualified or parenthesized non-static member function to form a pointer to explicit object member function} "" { target *-*-* } line_sg } + // { dg-note {a pointer to explicit object member function can only be formed with '&S::g'} "" { target *-*-* } line_sg } + } + + void test1(this S& self) { + void (*fp)(S&) = &self.f; // { dg-line s_test1_f } + // { dg-error {ISO C\+\+ forbids taking the address of a bound member function to form a pointer to explicit object member function} "" { target *-*-* } s_test1_f } + // { dg-note {a pointer to explicit object member function can only be formed with '&S::f'} "" { target *-*-* } s_test1_f } + void (*gp)(S&) = &self.g; // { dg-line s_test1_g } + // { dg-error {ISO C\+\+ forbids taking the address of a bound member function to form a pointer to explicit object member function} "PR113075" { xfail *-*-* } s_test1_g } + // { dg-bogus {ISO C\+\+ forbids taking the address of an unqualified or parenthesized non-static member function to form a pointer to explicit object member function} "PR113075" { xfail *-*-* } s_test1_g } + // { dg-note {a pointer to explicit object member function can only be formed with '&S::g'} "" { target *-*-* } s_test1_g } + } +}; + +void test0() +{ + S s{}; + + void (*fp)(S&) = &s.f; // { dg-line s_free_test0_f } + // { dg-error {ISO C\+\+ forbids taking the address of a bound member function to form a pointer to explicit object member function} "" { target *-*-* } s_free_test0_f } + // { dg-note {a pointer to explicit object member function can only be formed with '&S::f'} "" { target *-*-* } s_free_test0_f } + void (*gp)(S&) = &s.g; // { dg-line s_free_test0_g } + // { dg-error {ISO C\+\+ forbids taking the address of a bound member function to form a pointer to explicit object member function} "PR113075" { xfail *-*-* } s_free_test0_g } + // { dg-bogus {ISO C\+\+ forbids taking the address of an unqualified or parenthesized non-static member function to form a pointer to explicit object member function} "PR113075" { xfail *-*-* } s_free_test0_g } + // { dg-note {a pointer to explicit object member function can only be formed with '&S::g'} "" { target *-*-* } s_free_test0_g } +} + +struct D; + +struct B { + void fb(this B&) {} + + void gb(this B&) {} + void gb(this B&, int) {} + + void fd(this D&) {} + + void gd(this D&) {} + void gd(this D&, int) {} +}; + +struct D : B { + void fb2(this B&) {} + + void gb2(this B&) {} + void gb2(this B&, int) {} + + void fd2(this D&) {} + + void gd2(this D&) {} + void gd2(this D&, int) {} + + void test0() { + void (*fbp)(B&) = &fb; // { dg-line d_test0_fb } + // { dg-error {ISO C\+\+ forbids taking the address of an unqualified or parenthesized non-static member function to form a pointer to explicit object member function} "" { target *-*-* } d_test0_fb } + // { dg-note {a pointer to explicit object member function can only be formed with '&D::fb'} "" { target *-*-* } d_test0_fb } + void (*gbp)(B&) = &gb; // { dg-line d_test0_gb } + // { dg-error {ISO C\+\+ forbids taking the address of an unqualified or parenthesized non-static member function to form a pointer to explicit object member function} "" { target *-*-* } d_test0_gb } + // { dg-note {a pointer to explicit object member function can only be formed with '&D::gb'} "PR113075" { xfail *-*-* } d_test0_gb } + // { dg-bogus {a pointer to explicit object member function can only be formed with '&B::gb'} "PR113075" { xfail *-*-* } d_test0_gb } + + void (*fdp)(D&) = &fd; // { dg-line d_test0_fd } + // { dg-error {ISO C\+\+ forbids taking the address of an unqualified or parenthesized non-static member function to form a pointer to explicit object member function} "" { target *-*-* } d_test0_fd } + // { dg-note {a pointer to explicit object member function can only be formed with '&D::fd'} "" { target *-*-* } d_test0_fd } + void (*gdp)(D&) = &gd; // { dg-line d_test0_gd } + // { dg-error {ISO C\+\+ forbids taking the address of an unqualified or parenthesized non-static member function to form a pointer to explicit object member function} "" { target *-*-* } d_test0_gd } + // { dg-note {a pointer to explicit object member function can only be formed with '&D::gd'} "PR113075" { xfail *-*-* } d_test0_gd } + // { dg-bogus {a pointer to explicit object member function can only be formed with '&B::gd'} "PR113075" { xfail *-*-* } d_test0_gd } + } + + void test1(this B& self) { + void (*fbp)(B&) = &self.fb; // { dg-line d_test1_fb } + // { dg-error {ISO C\+\+ forbids taking the address of a bound member function to form a pointer to explicit object member function} "" { target *-*-* } d_test1_fb } + // { dg-note {a pointer to explicit object member function can only be formed with '&B::fb'} "" { target *-*-* } d_test1_fb } + void (*gbp)(B&) = &self.gb; // { dg-line d_test1_gb } + // { dg-error {ISO C\+\+ forbids taking the address of a bound member function to form a pointer to explicit object member function} "PR113075" { xfail *-*-* } d_test1_gb } + // { dg-bogus {ISO C\+\+ forbids taking the address of an unqualified or parenthesized non-static member function to form a pointer to explicit object member function} "PR113075" { xfail *-*-* } d_test1_gb } + // { dg-note {a pointer to explicit object member function can only be formed with '&B::gb'} "" { target *-*-* } d_test1_gb } + + void (*fdp)(D&) = &self.fd; // { dg-line d_test1_fd } + // { dg-error {ISO C\+\+ forbids taking the address of a bound member function to form a pointer to explicit object member function} "" { target *-*-* } d_test1_fd } + // { dg-note {a pointer to explicit object member function can only be formed with '&B::fd'} "" { target *-*-* } d_test1_fd } + void (*gdp)(D&) = &self.gd; // { dg-line d_test1_gd } + // { dg-error {ISO C\+\+ forbids taking the address of a bound member function to form a pointer to explicit object member function} "PR113075" { xfail *-*-* } d_test1_gd } + // { dg-bogus {ISO C\+\+ forbids taking the address of an unqualified or parenthesized non-static member function to form a pointer to explicit object member function} "PR113075" { xfail *-*-* } d_test1_gd } + // { dg-note {a pointer to explicit object member function can only be formed with '&B::gd'} "" { target *-*-* } d_test1_gd } + } + + void test2(this D& self) { + void (*fbp)(B&) = &self.fb; // { dg-line d_test2_fb } + // { dg-error {ISO C\+\+ forbids taking the address of a bound member function to form a pointer to explicit object member function} "" { target *-*-* } d_test2_fb } + // { dg-note {a pointer to explicit object member function can only be formed with '&D::fb'} "" { target *-*-* } d_test2_fb } + void (*gbp)(B&) = &self.gb; // { dg-line d_test2_gb } + // { dg-error {ISO C\+\+ forbids taking the address of a bound member function to form a pointer to explicit object member function} "PR113075" { xfail *-*-* } d_test2_gb } + // { dg-bogus {ISO C\+\+ forbids taking the address of an unqualified or parenthesized non-static member function to form a pointer to explicit object member function} "PR113075" { xfail *-*-* } d_test2_gb } + // { dg-note {a pointer to explicit object member function can only be formed with '&D::gb'} "PR113075" { xfail *-*-* } d_test2_gb } + // { dg-bogus {a pointer to explicit object member function can only be formed with '&B::gb'} "PR113075" { xfail *-*-* } d_test2_gb } + + void (*fdp)(D&) = &self.fd; // { dg-line d_test2_fd } + // { dg-error {ISO C\+\+ forbids taking the address of a bound member function to form a pointer to explicit object member function} "" { target *-*-* } d_test2_fd } + // { dg-note {a pointer to explicit object member function can only be formed with '&D::fd'} "" { target *-*-* } d_test2_fd } + void (*gdp)(D&) = &self.gd; // { dg-line d_test2_gd } + // { dg-error {ISO C\+\+ forbids taking the address of a bound member function to form a pointer to explicit object member function} "PR113075" { xfail *-*-* } d_test2_gd } + // { dg-bogus {ISO C\+\+ forbids taking the address of an unqualified or parenthesized non-static member function to form a pointer to explicit object member function} "PR113075" { xfail *-*-* } d_test2_gd } + // { dg-note {a pointer to explicit object member function can only be formed with '&D::gd'} "PR113075" { xfail *-*-* } d_test2_gd } + // { dg-bogus {a pointer to explicit object member function can only be formed with '&B::gd'} "PR113075" { xfail *-*-* } d_test2_gd } + } + + void test3() { + void (*fbp)(B&) = &fb2; // { dg-line d_test3_fb2 } + // { dg-error {ISO C\+\+ forbids taking the address of an unqualified or parenthesized non-static member function to form a pointer to explicit object member function} "" { target *-*-* } d_test3_fb2 } + // { dg-note {a pointer to explicit object member function can only be formed with '&D::fb2'} "" { target *-*-* } d_test3_fb2 } + void (*gbp)(B&) = &gb2; // { dg-line d_test3_gb2 } + // { dg-error {ISO C\+\+ forbids taking the address of an unqualified or parenthesized non-static member function to form a pointer to explicit object member function} "" { target *-*-* } d_test3_gb2 } + // { dg-note {a pointer to explicit object member function can only be formed with '&D::gb2'} "" { target *-*-* } d_test3_gb2 } + + void (*fdp)(D&) = &fd2; // { dg-line d_test3_fd2 } + // { dg-error {ISO C\+\+ forbids taking the address of an unqualified or parenthesized non-static member function to form a pointer to explicit object member function} "" { target *-*-* } d_test3_fd2 } + // { dg-note {a pointer to explicit object member function can only be formed with '&D::fd2'} "" { target *-*-* } d_test3_fd2 } + void (*gdp)(D&) = &gd2; // { dg-line d_test3_gd2 } + // { dg-error {ISO C\+\+ forbids taking the address of an unqualified or parenthesized non-static member function to form a pointer to explicit object member function} "" { target *-*-* } d_test3_gd2 } + // { dg-note {a pointer to explicit object member function can only be formed with '&D::gd2'} "" { target *-*-* } d_test3_gd2 } + } + + void test4(this D& self) { + void (*fbp)(B&) = &self.fb2; // { dg-line d_test4_fb2 } + // { dg-error {ISO C\+\+ forbids taking the address of a bound member function to form a pointer to explicit object member function} "" { target *-*-* } d_test4_fb2 } + // { dg-note {a pointer to explicit object member function can only be formed with '&D::fb2'} "" { target *-*-* } d_test4_fb2 } + void (*gbp)(B&) = &self.gb2; // { dg-line d_test4_gb2 } + // { dg-error {ISO C\+\+ forbids taking the address of a bound member function to form a pointer to explicit object member function} "PR113075" { xfail *-*-* } d_test4_gb2 } + // { dg-bogus {ISO C\+\+ forbids taking the address of an unqualified or parenthesized non-static member function to form a pointer to explicit object member function} "PR113075" { xfail *-*-* } d_test4_gb2 } + // { dg-note {a pointer to explicit object member function can only be formed with '&D::gb2'} "" { target *-*-* } d_test4_gb2 } + + void (*fdp)(D&) = &self.fd2; // { dg-line d_test4_fd2 } + // { dg-error {ISO C\+\+ forbids taking the address of a bound member function to form a pointer to explicit object member function} "" { target *-*-* } d_test4_fd2 } + // { dg-note {a pointer to explicit object member function can only be formed with '&D::fd2'} "" { target *-*-* } d_test4_fd2 } + void (*gdp)(D&) = &self.gd2; // { dg-line d_test4_gd2 } + // { dg-error {ISO C\+\+ forbids taking the address of a bound member function to form a pointer to explicit object member function} "PR113075" { xfail *-*-* } d_test4_gd2 } + // { dg-bogus {ISO C\+\+ forbids taking the address of an unqualified or parenthesized non-static member function to form a pointer to explicit object member function} "PR113075" { xfail *-*-* } d_test4_gd2 } + // { dg-note {a pointer to explicit object member function can only be formed with '&D::gd2'} "" { target *-*-* } d_test4_gd2 } + } +}; + +void test1() +{ + D d{}; + + void (*fbp)(B&) = &d.fb; // { dg-line d_free_test1_fb } + // { dg-error {ISO C\+\+ forbids taking the address of a bound member function to form a pointer to explicit object member function} "" { target *-*-* } d_free_test1_fb } + // { dg-note {a pointer to explicit object member function can only be formed with '&D::fb'} "" { target *-*-* } d_free_test1_fb } + void (*gbp)(B&) = &d.gb; // { dg-line d_free_test1_gb } + // { dg-error {ISO C\+\+ forbids taking the address of a bound member function to form a pointer to explicit object member function} "PR113075" { xfail *-*-* } d_free_test1_gb } + // { dg-bogus {ISO C\+\+ forbids taking the address of an unqualified or parenthesized non-static member function to form a pointer to explicit object member function} "PR113075" { xfail *-*-* } d_free_test1_gb } + // { dg-note {a pointer to explicit object member function can only be formed with '&D::gb'} "PR113075" { xfail *-*-* } d_free_test1_gb } + // { dg-bogus {a pointer to explicit object member function can only be formed with '&B::gb'} "PR113075" { xfail *-*-* } d_free_test1_gb } + + void (*fdp)(D&) = &d.fd; // { dg-line d_free_test1_fd } + // { dg-error {ISO C\+\+ forbids taking the address of a bound member function to form a pointer to explicit object member function} "" { target *-*-* } d_free_test1_fd } + // { dg-note {a pointer to explicit object member function can only be formed with '&D::fd'} "" { target *-*-* } d_free_test1_fd } + void (*gdp)(D&) = &d.gd; // { dg-line d_free_test1_gd } + // { dg-error {ISO C\+\+ forbids taking the address of a bound member function to form a pointer to explicit object member function} "PR113075" { xfail *-*-* } d_free_test1_gd } + // { dg-bogus {ISO C\+\+ forbids taking the address of an unqualified or parenthesized non-static member function to form a pointer to explicit object member function} "PR113075" { xfail *-*-* } d_free_test1_gd } + // { dg-note {a pointer to explicit object member function can only be formed with '&D::gd'} "PR113075" { xfail *-*-* } d_free_test1_gd } + // { dg-bogus {a pointer to explicit object member function can only be formed with '&B::gd'} "PR113075" { xfail *-*-* } d_free_test1_gd } +} + +void test2() +{ + D d{}; + + void (*fbp)(B&) = &d.fb2; // { dg-line d_free_test2_fb2 } + // { dg-error {ISO C\+\+ forbids taking the address of a bound member function to form a pointer to explicit object member function} "" { target *-*-* } d_free_test2_fb2 } + // { dg-note {a pointer to explicit object member function can only be formed with '&D::fb2'} "" { target *-*-* } d_free_test2_fb2 } + void (*gbp)(B&) = &d.gb2; // { dg-line d_free_test2_gb2 } + // { dg-error {ISO C\+\+ forbids taking the address of a bound member function to form a pointer to explicit object member function} "PR113075" { xfail *-*-* } d_free_test2_gb2 } + // { dg-bogus {ISO C\+\+ forbids taking the address of an unqualified or parenthesized non-static member function to form a pointer to explicit object member function} "PR113075" { xfail *-*-* } d_free_test2_gb2 } + // { dg-note {a pointer to explicit object member function can only be formed with '&D::gb2'} "" { target *-*-* } d_free_test2_gb2 } + + void (*fdp)(D&) = &d.fd2; // { dg-line d_free_test2_fd2 } + // { dg-error {ISO C\+\+ forbids taking the address of a bound member function to form a pointer to explicit object member function} "" { target *-*-* } d_free_test2_fd2 } + // { dg-note {a pointer to explicit object member function can only be formed with '&D::fd2'} "" { target *-*-* } d_free_test2_fd2 } + void (*gdp)(D&) = &d.gd2; // { dg-line d_free_test2_gd2 } + // { dg-error {ISO C\+\+ forbids taking the address of a bound member function to form a pointer to explicit object member function} "PR113075" { xfail *-*-* } d_free_test2_gd2 } + // { dg-bogus {ISO C\+\+ forbids taking the address of an unqualified or parenthesized non-static member function to form a pointer to explicit object member function} "PR113075" { xfail *-*-* } d_free_test2_gd2 } + // { dg-note {a pointer to explicit object member function can only be formed with '&D::gd2'} "" { target *-*-* } d_free_test2_gd2 } +} + diff --git a/gcc/testsuite/g++.dg/cpp23/explicit-obj-diagnostics7.C b/gcc/testsuite/g++.dg/cpp23/explicit-obj-diagnostics7.C new file mode 100644 index 0000000..d30ba5c --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp23/explicit-obj-diagnostics7.C @@ -0,0 +1,95 @@ +// P0847R7 +// { dg-do compile { target c++23 } } + +// diagnose xobj member functions that override +// or are declared as virtual, override, or final + +struct B { + virtual void f0() {} // { dg-note {virtual function declared here} } + virtual void f1() {} // { dg-note {virtual function declared here} } + virtual void f2() {} // { dg-note {virtual function declared here} } + virtual void f3() {} // { dg-note {virtual function declared here} } + virtual void f4() {} // { dg-note {virtual function declared here} } + virtual void f5() {} // { dg-note {virtual function declared here} } + virtual void f6() {} // { dg-note {virtual function declared here} } + virtual void f7() {} // { dg-note {virtual function declared here} } + virtual ~B() {} +}; + +struct S : B { + virtual void f0(this S&) {} // { dg-line line_f0 } + virtual void f1(this S&) override {} // { dg-line line_f1 } + virtual void f2(this S&) final {} // { dg-line line_f2 } + virtual void f3(this S&) override final {} // { dg-line line_f3 } + void f4(this S&) {} // { dg-line line_f4 } + void f5(this S&) override {} // { dg-line line_f5 } + void f6(this S&) final {} // { dg-line line_f6 } + void f7(this S&) override final {} // { dg-line line_f7 } +}; + +// { dg-error {an explicit object member function cannot be 'virtual'} "" { target *-*-* } line_f0 } +// { dg-error {an explicit object member function cannot be 'virtual'} "" { target *-*-* } line_f1 } +// { dg-error {an explicit object member function cannot be 'virtual'} "" { target *-*-* } line_f2 } +// { dg-error {an explicit object member function cannot be 'virtual'} "" { target *-*-* } line_f3 } + +// { dg-error {explicit object member function overrides virtual function} "" { target *-*-* } line_f0 } +// { dg-error {explicit object member function overrides virtual function} "" { target *-*-* } line_f1 } +// { dg-error {explicit object member function overrides virtual function} "" { target *-*-* } line_f2 } +// { dg-error {explicit object member function overrides virtual function} "" { target *-*-* } line_f3 } +// { dg-error {explicit object member function overrides virtual function} "" { target *-*-* } line_f4 } +// { dg-error {explicit object member function overrides virtual function} "" { target *-*-* } line_f5 } +// { dg-error {explicit object member function overrides virtual function} "" { target *-*-* } line_f6 } +// { dg-error {explicit object member function overrides virtual function} "" { target *-*-* } line_f7 } + +// these should be suppressed, the wording conflicts with the error +// the issue is not that they don't override, it's that they do override, and that isn't allowed +// { dg-bogus "marked 'override', but does not override" "" { target *-*-* } line_f1 } +// { dg-bogus "marked 'final', but is not virtual" "" { xfail *-*-* } line_f2 } +// { dg-bogus "marked '(override|final)'" "" { xfail *-*-* } line_f3 } + +// { dg-bogus "marked 'override', but does not override" "" { target *-*-* } line_f5 } +// { dg-bogus "marked 'final', but is not virtual" "" { xfail *-*-* } line_f6 } +// { dg-bogus "marked '(override|final)'" "" { xfail *-*-* } line_f7 } + +// { dg-note "explicit object parameter declared here" "" { target *-*-* } line_f0 } +// { dg-note "explicit object parameter declared here" "" { target *-*-* } line_f1 } +// { dg-note "explicit object parameter declared here" "" { target *-*-* } line_f2 } +// { dg-note "explicit object parameter declared here" "" { target *-*-* } line_f3 } +// { dg-note "explicit object parameter declared here" "" { xfail *-*-* } line_f4 } +// { dg-note "explicit object parameter declared here" "" { xfail *-*-* } line_f5 } +// { dg-note "explicit object parameter declared here" "" { xfail *-*-* } line_f6 } +// { dg-note "explicit object parameter declared here" "" { xfail *-*-* } line_f7 } + +struct S1 { + virtual void f0(this S&) {} // { dg-line line_S1_f0 } + virtual void f1(this S&) override {} // { dg-line line_S1_f1 } + virtual void f2(this S&) final {} // { dg-line line_S1_f2 } + virtual void f3(this S&) override final {} // { dg-line line_S1_f3 } + void f4(this S&) {} + void f5(this S&) override {} // { dg-line line_S1_f5 } + void f6(this S&) final {} // { dg-line line_S1_f6 } + void f7(this S&) override final {} // { dg-line line_S1_f7 } +}; + +// { dg-error "an explicit object member function cannot be 'virtual'" "" { target *-*-* } line_S1_f0 } +// { dg-error "an explicit object member function cannot be 'virtual'" "" { target *-*-* } line_S1_f1 } +// { dg-error "an explicit object member function cannot be 'virtual'" "" { target *-*-* } line_S1_f2 } +// { dg-error "an explicit object member function cannot be 'virtual'" "" { target *-*-* } line_S1_f3 } + +// { dg-note "explicit object parameter declared here" "" { target *-*-* } line_S1_f0 } +// { dg-note "explicit object parameter declared here" "" { target *-*-* } line_S1_f1 } +// { dg-note "explicit object parameter declared here" "" { target *-*-* } line_S1_f2 } +// { dg-note "explicit object parameter declared here" "" { target *-*-* } line_S1_f3 } + +// I think I want these suppressed, but theres a decent argument that they should stay +// theres arguably no reason the error about virtual should suppress these +// { dg-bogus "marked 'override', but does not override" "" { xfail *-*-* } line_S1_f1 } +// { dg-bogus "marked 'final', but is not virtual" "" { xfail *-*-* } line_S1_f2 } +// { dg-bogus "marked '(override|final)'" "" { xfail *-*-* } line_S1_f3 } + +// I don't want to suppress these, there is nothing that could possibly be overridden +// even if the xobj param was removed +// { dg-error "marked 'override', but does not override" "" { target *-*-* } line_S1_f5 } +// { dg-error "marked 'final', but is not virtual" "" { target *-*-* } line_S1_f6 } +// { dg-error "marked '(override|final)'" "" { target *-*-* } line_S1_f7 } + diff --git a/gcc/testsuite/g++.dg/cpp23/explicit-obj-diagnostics8.C b/gcc/testsuite/g++.dg/cpp23/explicit-obj-diagnostics8.C new file mode 100644 index 0000000..7b75dc9 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp23/explicit-obj-diagnostics8.C @@ -0,0 +1,68 @@ +// P0847R7 +// { dg-do compile { target c++23 } } + +// xobj lambda with invalid decl specs + +void test() +{ + auto f0 = [](this auto) mutable {}; // { dg-line line_f0 } + auto f1 = [](this auto&) mutable {}; // { dg-line line_f1 } + auto f2 = [](this auto const&) mutable {}; // { dg-line line_f2 } + auto f3 = [](this auto&&) mutable {}; // { dg-line line_f3 } + + auto g0 = [](this auto) static {}; // { dg-line line_g0 } + auto g1 = [](this auto&) static {}; // { dg-line line_g1 } + auto g2 = [](this auto const&) static {}; // { dg-line line_g2 } + auto g3 = [](this auto&&) static {}; // { dg-line line_g3 } + + auto fc0 = [n = 0](this auto) mutable {}; // { dg-line line_fc0 } + auto fc1 = [n = 0](this auto&) mutable {}; // { dg-line line_fc1 } + auto fc2 = [n = 0](this auto const&) mutable {}; // { dg-line line_fc2 } + auto fc3 = [n = 0](this auto&&) mutable {}; // { dg-line line_fc3 } + + auto gc0 = [n = 0](this auto) static {}; // { dg-line line_gc0 } + auto gc1 = [n = 0](this auto&) static {}; // { dg-line line_gc1 } + auto gc2 = [n = 0](this auto const&) static {}; // { dg-line line_gc2 } + auto gc3 = [n = 0](this auto&&) static {}; // { dg-line line_gc3 } +} + +// { dg-error {'mutable' lambda specifier with explicit object parameter} {} { target *-*-* } line_f0 } +// { dg-error {'mutable' lambda specifier with explicit object parameter} {} { target *-*-* } line_f1 } +// { dg-error {'mutable' lambda specifier with explicit object parameter} {} { target *-*-* } line_f2 } +// { dg-error {'mutable' lambda specifier with explicit object parameter} {} { target *-*-* } line_f3 } + +// { dg-note {the passed in closure object will not be mutated because it is taken by value} {} { target *-*-* } line_f0 } +// { dg-note {explicit object parameter is already a mutable reference} {} { target *-*-* } line_f1 } +// { dg-note {declare the explicit object parameter as non-const reference instead} {} { target *-*-* } line_f2 } +// { dg-note {explicit object parameter is already a mutable reference} {} { target *-*-* } line_f3 } + +// { dg-error {'static' lambda specifier with explicit object parameter} {} { target *-*-* } line_g0 } +// { dg-error {'static' lambda specifier with explicit object parameter} {} { target *-*-* } line_g1 } +// { dg-error {'static' lambda specifier with explicit object parameter} {} { target *-*-* } line_g2 } +// { dg-error {'static' lambda specifier with explicit object parameter} {} { target *-*-* } line_g3 } + +// { dg-note {explicit object parameter declared here} {} { target *-*-* } line_g0 } +// { dg-note {explicit object parameter declared here} {} { target *-*-* } line_g1 } +// { dg-note {explicit object parameter declared here} {} { target *-*-* } line_g2 } +// { dg-note {explicit object parameter declared here} {} { target *-*-* } line_g3 } + +// { dg-error {'mutable' lambda specifier with explicit object parameter} {} { target *-*-* } line_fc0 } +// { dg-error {'mutable' lambda specifier with explicit object parameter} {} { target *-*-* } line_fc1 } +// { dg-error {'mutable' lambda specifier with explicit object parameter} {} { target *-*-* } line_fc2 } +// { dg-error {'mutable' lambda specifier with explicit object parameter} {} { target *-*-* } line_fc3 } + +// { dg-note {the passed in closure object will not be mutated because it is taken by value} {} { target *-*-* } line_fc0 } +// { dg-note {explicit object parameter is already a mutable reference} {} { target *-*-* } line_fc1 } +// { dg-note {declare the explicit object parameter as non-const reference instead} {} { target *-*-* } line_fc2 } +// { dg-note {explicit object parameter is already a mutable reference} {} { target *-*-* } line_fc3 } + +// { dg-error {'static' lambda specifier with explicit object parameter} {} { target *-*-* } line_gc0 } +// { dg-error {'static' lambda specifier with explicit object parameter} {} { target *-*-* } line_gc1 } +// { dg-error {'static' lambda specifier with explicit object parameter} {} { target *-*-* } line_gc2 } +// { dg-error {'static' lambda specifier with explicit object parameter} {} { target *-*-* } line_gc3 } + +// { dg-note {explicit object parameter declared here} {} { target *-*-* } line_gc0 } +// { dg-note {explicit object parameter declared here} {} { target *-*-* } line_gc1 } +// { dg-note {explicit object parameter declared here} {} { target *-*-* } line_gc2 } +// { dg-note {explicit object parameter declared here} {} { target *-*-* } line_gc3 } + diff --git a/gcc/testsuite/g++.dg/cpp23/explicit-obj-lambda1.C b/gcc/testsuite/g++.dg/cpp23/explicit-obj-lambda1.C new file mode 100644 index 0000000..86e0471 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp23/explicit-obj-lambda1.C @@ -0,0 +1,25 @@ +// P0847R7 +// { dg-do compile { target c++23 } } + +// lambda declaration with xobj parameter + +struct S{}; + +void test() +{ + (void)[](this auto&& self){}; + (void)[](this auto& self){}; + (void)[](this auto const& self){}; + (void)[](this auto self){}; + + (void)[](this S&& self){}; + (void)[](this S& self){}; + (void)[](this S const& self){}; + (void)[](this S self){}; + + (void)[x = 0](this auto&& self){}; + (void)[x = 0](this auto& self){}; + (void)[x = 0](this auto const& self){}; + (void)[x = 0](this auto self){}; +} + diff --git a/gcc/testsuite/g++.dg/cpp23/explicit-obj-lambda10.C b/gcc/testsuite/g++.dg/cpp23/explicit-obj-lambda10.C new file mode 100644 index 0000000..715a245 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp23/explicit-obj-lambda10.C @@ -0,0 +1,39 @@ +// P0847R7 +// { dg-do compile { target c++23 } } + +// instantiating captureless lambda call operator with unrelated explicit object parameter + +void test0() +{ + auto f0 = [](this auto self) { return self; }; + auto fp0_value = static_cast<int(*)(int) >(&decltype(f0)::operator()); + auto fp0_lref = static_cast<int(*)(int&) >(&decltype(f0)::operator()); + auto fp0_rref = static_cast<int(*)(int&&) >(&decltype(f0)::operator()); + auto fp0_constlref = static_cast<int(*)(int const&) >(&decltype(f0)::operator()); + auto fp0_constrref = static_cast<int(*)(int const&&)>(&decltype(f0)::operator()); + + auto f1 = [](this auto&& self) { return self; }; + auto fp1_value = static_cast<int(*)(int) >(&decltype(f1)::operator()); // { dg-error {invalid 'static_cast' from type} } + auto fp1_lref = static_cast<int(*)(int&) >(&decltype(f1)::operator()); + auto fp1_rref = static_cast<int(*)(int&&) >(&decltype(f1)::operator()); + auto fp1_constlref = static_cast<int(*)(int const&) >(&decltype(f1)::operator()); + auto fp1_constrref = static_cast<int(*)(int const&&)>(&decltype(f1)::operator()); +} + +void test1() +{ + auto f0 = [](this auto self) { return self; }; + int (*fp0_value)(int) = &decltype(f0)::operator(); + int (*fp0_lref)(int&) = &decltype(f0)::operator(); + int (*fp0_rref)(int&&) = &decltype(f0)::operator(); + int (*fp0_constlref)(int const&) = &decltype(f0)::operator(); + int (*fp0_constrref)(int const&&) = &decltype(f0)::operator(); + + auto f1 = [](this auto&& self) { return self; }; + int (*fp1_value)(int) = &decltype(f1)::operator(); // { dg-error {no matches converting function} } + int (*fp1_lref)(int&) = &decltype(f1)::operator(); + int (*fp1_rref)(int&&) = &decltype(f1)::operator(); + int (*fp1_constlref)(int const&) = &decltype(f1)::operator(); + int (*fp1_constrref)(int const&&) = &decltype(f1)::operator(); +} + diff --git a/gcc/testsuite/g++.dg/cpp23/explicit-obj-lambda11.C b/gcc/testsuite/g++.dg/cpp23/explicit-obj-lambda11.C new file mode 100644 index 0000000..7f2bdb8 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp23/explicit-obj-lambda11.C @@ -0,0 +1,46 @@ +// P0847R7 +// { dg-do compile { target c++23 } } + +// unrelated xobj parameter type in captureless lambdas and lambdas with captures + +struct S0{}; + +void test0() +{ + auto f0 = [](this S0){ return 5; }; // { dg-bogus "a lambda with captures may not have an explicit object parameter of an unrelated type" } + auto f1 = [x = 42](this S0){ return 5; }; // { dg-error "a lambda with captures may not have an explicit object parameter of an unrelated type" } +} + +// instantiation by calling with explicit template arguments + +template<typename T> +struct S1 : T { + using T::operator(); + operator int() const {return {};} +}; + +void test1() +{ + auto s0 = S1{[](this auto&& self) { return self; }}; // { dg-bogus {a lambda with captures may not have an explicit object parameter of an unrelated type} } + s0.operator()<int>(); // { dg-bogus {no matching function for call to} } + + auto s1 = S1{[x = 0](this auto&& self) { return self; }}; // { dg-line t1_s1 } + s1.operator()<int>(); // { dg-error {no matching function for call to} } +} +// { dg-note {candidate:} {} { target *-*-* } t1_s1 } +// { dg-note {template argument deduction/substitution failed} {} { target *-*-* } t1_s1 } +// { dg-error {a lambda with captures may not have an explicit object parameter of an unrelated type} {} { target *-*-* } t1_s1 } + +// instantiation from overload resolution when taking address of call operator + +void test2() +{ + auto f = [x = 42](this auto&&){ return x; }; // { dg-line t2_f } + + int (*fp0)(decltype(f)&) = &decltype(f)::operator(); + int (*fp1)(int&) = &decltype(f)::operator(); // { dg-error {no matches converting function} } +} + +// { dg-error "a lambda with captures may not have an explicit object parameter of an unrelated type" {depends on PR112874} { xfail *-*-* } t2_f } +// { dg-note "candidate is" "" { target *-*-* } t2_f } + diff --git a/gcc/testsuite/g++.dg/cpp23/explicit-obj-lambda12.C b/gcc/testsuite/g++.dg/cpp23/explicit-obj-lambda12.C new file mode 100644 index 0000000..8b6c2ba --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp23/explicit-obj-lambda12.C @@ -0,0 +1,103 @@ +// P0847R7 +// { dg-do compile { target c++23 } } + +// SFINAE when the call operator for a lambda with captures is instantiated +// with an unrelated type. +// diagnose ambiguous overloads when the call operator for a captureless lambda is instantiated +// with an unrelated type. + +// overload resolution when taking address of function + +/* [expr.prim.lambda.general-5] + + Given a lambda with a lambda-capture, the type of the explicit object + parameter, if any, of the lambda's function call operator (possibly + instantiated from a function call operator template) shall be either: + + --(5.1) the closure type, + --(5.2) a class type derived from the closure type, or + --(5.3) a reference to a possibly cv-qualified such type. */ + +// The above wording is similar to [dcl.fct-15] which is handled by SFINAE, +// thus we also handle the following cases the same way. + +// We need the 2 overloads to be ambiguous to observe substitution failure +// for the lambda's call operator when instantiated with an unrelated type. +// We accomplish this by introducing both overloads through using declarations. + +struct B0 { + void operator()(this auto) {} +}; +template<typename T> +struct S0 : T, B0 { + using B0::operator(); + using T::operator(); +}; + +void test0() +{ + auto s0 = S0{[](this auto){}}; + void (*p0)(int) = &decltype(s0)::operator(); // { dg-error {converting overloaded function '[^\n\r]+' to type '[^\n\r]+' is ambiguous} } + + auto s1 = S0{[x = 42](this auto){}}; + void (*p1)(int) = &decltype(s1)::operator(); // { dg-bogus {converting overloaded function '[^\n\r]+' to type '[^\n\r]+' is ambiguous} {Substitution failure for a captureful lambda with an unrelated xobj parameter type failed!} } +} + +struct B1 { + void operator()(this auto&&) {} +}; +template<typename T> +struct S1 : T, B1 { + using B1::operator(); + using T::operator(); +}; + +void test1() +{ + auto s0 = S1{[](this auto&&){}}; + void (*p0)(int&) = &decltype(s0)::operator(); // { dg-error {converting overloaded function '[^\n\r]+' to type '[^\n\r]+' is ambiguous} } + + auto s1 = S1{[x = 42](this auto&&){}}; + void (*p1)(int&) = &decltype(s1)::operator(); // { dg-bogus {converting overloaded function '[^\n\r]+' to type '[^\n\r]+' is ambiguous} {Substitution failure for a captureful lambda with an unrelated xobj parameter type failed!} } +} + + +struct B2 { + // not a template, should be taken over the lambda's call operator + void operator()(this int&) {} +}; +template<typename T> +struct S2 : T, B2 { + using T::operator(); + using B2::operator(); +}; + +void test2() +{ + auto s0 = S2{[](this auto&&){}}; + void (*p0)(int&) = &decltype(s0)::operator(); // { dg-bogus {converting overloaded function '[^\n\r]+' to type '[^\n\r]+' is ambiguous} } + + auto s1 = S2{[x = 42](this auto&&){}}; + void (*p1)(int&) = &decltype(s1)::operator(); // { dg-bogus {converting overloaded function '[^\n\r]+' to type '[^\n\r]+' is ambiguous} } +} + +struct B3 { + // must be a template so it is not taken over the lambda's call operator + template<typename U = void> + void operator()(this int&) {} +}; +template<typename T> +struct S3 : T, B3 { + using B3::operator(); + using T::operator(); +}; + +void test3() +{ + auto s0 = S3{[](this auto&&){}}; + void (*p0)(int&) = &decltype(s0)::operator(); // { dg-error {converting overloaded function '[^\n\r]+' to type '[^\n\r]+' is ambiguous} } + + auto s1 = S3{[x = 42](this auto&&){}}; + void (*p1)(int&) = &decltype(s1)::operator(); // { dg-bogus {converting overloaded function '[^\n\r]+' to type '[^\n\r]+' is ambiguous} {Substitution failure for a captureful lambda with an unrelated xobj parameter type failed!} } +} + diff --git a/gcc/testsuite/g++.dg/cpp23/explicit-obj-lambda13.C b/gcc/testsuite/g++.dg/cpp23/explicit-obj-lambda13.C new file mode 100644 index 0000000..c48de47 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp23/explicit-obj-lambda13.C @@ -0,0 +1,103 @@ +// P0847R7 +// { dg-do compile { target c++23 } } + +// SFINAE when the call operator for a lambda with captures is instantiated +// with an unrelated type. +// diagnose ambiguous overloads when the call operator for a captureless lambda is instantiated +// with an unrelated type. + +// overload resolution from call expression + +/* [expr.prim.lambda.general-5] + + Given a lambda with a lambda-capture, the type of the explicit object + parameter, if any, of the lambda's function call operator (possibly + instantiated from a function call operator template) shall be either: + + --(5.1) the closure type, + --(5.2) a class type derived from the closure type, or + --(5.3) a reference to a possibly cv-qualified such type. */ + +// The above wording is similar to [dcl.fct-15] which is handled by SFINAE, +// thus we also handle the following cases the same way. + +// We need the 2 overloads to be ambiguous to observe substitution failure +// for the lambda's call operator when instantiated with an unrelated type. +// We accomplish this by introducing both overloads through using declarations. + +struct B0 { + void operator()(this auto) {} +}; + +template<typename T> +struct S0 : T, B0 { + using T::operator(); + using B0::operator(); + operator int() const {return {};} +}; + +void test0() +{ + auto s0 = S0{[](this auto){}}; + s0.operator()<int>(); // { dg-error {call of overloaded 'operator\(\)\(\)' is ambiguous} } + + auto s1 = S0{[x = 42](this auto){}}; + s1.operator()<int>(); // { dg-bogus {call of overloaded 'operator\(\)\(\)' is ambiguous} } +} + + +struct B1 { + void operator()(this auto&&) {} +}; +template<typename T> +struct S1 : T, B1 { + using T::operator(); + using B1::operator(); + operator int() const {return {};} +}; + +void test1() +{ + auto s0 = S1{[](this auto&&){}}; + s0.operator()<int>(); // { dg-error {call of overloaded 'operator\(\)\(\)' is ambiguous} } + + auto s1 = S1{[x = 42](this auto&&){}}; + s1.operator()<int>(); // { dg-bogus {call of overloaded 'operator\(\)\(\)' is ambiguous} } +} + + +struct B2 { + // needs to be a template, we are explicitly passing a template argument, + // without the parameter here this would not be a candidate + template<typename U = void> + void operator()(this int) {} +}; + +template<typename T> +struct S2 : T, B2 { + using T::operator(); + using B2::operator(); + operator int() const {return {};} +}; + +// I don't know why the calls to s0::operator() are not ambiguous, it might have to do with one taking less conversions, I'm not sure. +// Someone who knows better should remove those cases if they are sure they are actually correct. + +void test2() +{ + auto s0 = S2{[](this auto){}}; + s0.operator()<int>(); // { dg-error {call of overloaded 'operator\(\)\(\)' is ambiguous} {Not sure if this is a bug, one might be a better conversion} { xfail *-*-* } } + + auto s1 = S2{[x = 42](this auto){}}; + s1.operator()<int>(); // { dg-bogus {call of overloaded 'operator\(\)\(\)' is ambiguous} } +} + +void test3() +{ + auto s0 = S2{[](this auto&&){}}; + s0.operator()<int>(); // { dg-error {call of overloaded 'operator\(\)\(\)' is ambiguous} {Not sure if this is a bug, one might be a better conversion} { xfail *-*-* } } + + auto s1 = S2{[x = 42](this auto&&){}}; + s1.operator()<int>(); // { dg-bogus {call of overloaded 'operator\(\)\(\)' is ambiguous} } +} + diff --git a/gcc/testsuite/g++.dg/cpp23/explicit-obj-lambda2.C b/gcc/testsuite/g++.dg/cpp23/explicit-obj-lambda2.C new file mode 100644 index 0000000..827197a --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp23/explicit-obj-lambda2.C @@ -0,0 +1,23 @@ +// P0847R7 +// { dg-do run { target c++23 } } + +// recursive lambdas + +inline constexpr int correct_result = 5 + 4 + 3 + 2 + 1; + +int main() +{ + auto cl0 = [](this auto&& self, int n) -> int { return n ? self(n - 1) + n : 0; }; + auto cl1 = [](this auto const& self, int n) -> int { return n ? self(n - 1) + n : 0; }; + auto cl2 = [](this auto self, int n) -> int { return n ? self(n - 1) + n : 0; }; + auto cl3 = [](this auto&& self, int n) { if (!n) return 0; else return self(n - 1) + n; }; + auto cl4 = [](this auto const& self, int n){ if (!n) return 0; else return self(n - 1) + n; }; + auto cl5 = [](this auto self, int n) { if (!n) return 0; else return self(n - 1) + n; }; + if (cl0(5) != correct_result) __builtin_abort (); + if (cl1(5) != correct_result) __builtin_abort (); + if (cl2(5) != correct_result) __builtin_abort (); + if (cl3(5) != correct_result) __builtin_abort (); + if (cl4(5) != correct_result) __builtin_abort (); + if (cl5(5) != correct_result) __builtin_abort (); +} + diff --git a/gcc/testsuite/g++.dg/cpp23/explicit-obj-lambda3.C b/gcc/testsuite/g++.dg/cpp23/explicit-obj-lambda3.C new file mode 100644 index 0000000..9d222b0 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp23/explicit-obj-lambda3.C @@ -0,0 +1,64 @@ +// P0847R7 +// { dg-do run { target c++23 } } + +// an adaptation of one of the examples in P0847R7 + +struct Leaf { }; +struct Node; + +struct Tree { + enum class stored {leaf, node}; + stored _discriminator; + union { + Leaf _leaf; + Node* _node; + }; + Tree(Leaf) : _discriminator(stored::leaf), _leaf() {} + Tree(Node& node) : _discriminator(stored::node), _node(&node) {} +}; + +struct Node { + Tree left; + Tree right; +}; + +template<typename Visitor> +auto visit_tree(Visitor&& visitor, Tree const& tree) +{ + switch (tree._discriminator) + { + case Tree::stored::leaf: + return visitor (tree._leaf); + case Tree::stored::node: + return visitor (tree._node); + default: + __builtin_abort (); + } +} + +template<typename... Ts> +struct overload : Ts... { using Ts::operator()...; }; + +int main() +{ + static constexpr int true_num_leaves = 8; + Node branch0{.left = Leaf{}, .right = Leaf{}}; + Node branch1{.left = Leaf{}, .right = branch0}; + Node branch2{.left = Leaf{}, .right = Leaf{}}; + Node branch3{.left = branch1, .right = branch2}; + Node branch4{.left = branch3, .right = Leaf{}}; + Node branch5{.left = Leaf{}, .right = Leaf{}}; + Node branch6{.left = branch4, .right = branch5}; + + Tree root (branch6); + + int num_leaves = visit_tree (overload{ + [](Leaf const&) { return 1; }, + [](this auto const& self, Node* n) -> int { + return visit_tree (self, n->left) + visit_tree (self, n->right); + }}, + root); + if (num_leaves != true_num_leaves) + __builtin_abort (); +} + diff --git a/gcc/testsuite/g++.dg/cpp23/explicit-obj-lambda4.C b/gcc/testsuite/g++.dg/cpp23/explicit-obj-lambda4.C new file mode 100644 index 0000000..6ce42eb --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp23/explicit-obj-lambda4.C @@ -0,0 +1,23 @@ +// P0847R7 +// { dg-do run { target c++23 } } + +// calls to call operator of a lambda with captures with an implicit object argument +// that derives from the lambda closure object + +template<typename T> +struct S : T { + using T::operator(); +}; + +template<typename T> +S(T) -> S<T>; + +int main() +{ + static constexpr int magic = 42; + int n = magic; + S s{[n](this auto&&){return n;}}; + if (s () != magic) + __builtin_abort (); +} + diff --git a/gcc/testsuite/g++.dg/cpp23/explicit-obj-lambda5.C b/gcc/testsuite/g++.dg/cpp23/explicit-obj-lambda5.C new file mode 100644 index 0000000..88d45d9 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp23/explicit-obj-lambda5.C @@ -0,0 +1,21 @@ +// P0847R7 +// { dg-do run { target c++23 } } + +// calls to (captureless) lambda with explicit object parameter of unrelated type +// with an appropriate converting constructor + +inline constexpr int magic = 42; + +struct S { + int _v; + template<typename T> + S(T) : _v(magic) {} +}; + +int main() +{ + auto f = [](this S self){ return self._v; }; + if (f () != magic) + __builtin_abort (); +} + diff --git a/gcc/testsuite/g++.dg/cpp23/explicit-obj-lambda6.C b/gcc/testsuite/g++.dg/cpp23/explicit-obj-lambda6.C new file mode 100644 index 0000000..aa56306 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp23/explicit-obj-lambda6.C @@ -0,0 +1,873 @@ +// P0847R7 +// { dg-do compile { target c++23 } } + +// decltype((x)) and decltype(x) in explicit object lambda + +template<typename T> inline constexpr bool is_const_v = false; +template<typename T> inline constexpr bool is_const_v<T const> = true; + +template<typename T> inline constexpr bool is_lvalue_ref = false; +template<typename T> inline constexpr bool is_lvalue_ref<T&> = true; + +void non_dep() +{ + int n = 0; + int const c = 0; + // value + auto f0_value = [=]<typename Self>(this Self){ + static_assert(is_lvalue_ref<decltype((n))>, + "decltype((n)) is not an lvalue ref"); + static_assert(is_const_v<Self> == is_const_v<__remove_reference (decltype((n)))>, // { dg-bogus {static assertion failed: qualification of decltype\(\(n\)\) does not match qualification of Self} } + "qualification of decltype((n)) does not match qualification of Self"); + static_assert(__is_same (__remove_cvref (decltype((n))), int), + "decltype((n)) is not an int"); + static_assert(__is_same (decltype(n), int)); + + static_assert(is_lvalue_ref<decltype((c))>, + "decltype((c)) is not an lvalue ref"); + static_assert(is_const_v<__remove_reference (decltype((c)))>, + "qualification of decltype((c)) is not const"); + static_assert(__is_same (__remove_cvref (decltype((c))), int), + "decltype((c)) is not an int"); + static_assert(__is_same (decltype(c), int const)); + }; + f0_value(); + f0_value.operator()<decltype(f0_value) const>(); + + auto f1_value = [&]<typename Self>(this Self){ + static_assert(__is_same (decltype((n)), int&)); + static_assert(__is_same (decltype(n), int)); + + static_assert(__is_same (decltype((c)), int const&)); + static_assert(__is_same (decltype(c), int const)); + }; + f1_value(); + f1_value.operator()<decltype(f1_value) const>(); + + auto f2_value = [n, c]<typename Self>(this Self){ + static_assert(is_lvalue_ref<decltype((n))>, + "decltype((n)) is not an lvalue ref"); + static_assert(is_const_v<Self> == is_const_v<__remove_reference (decltype((n)))>, // { dg-bogus {static assertion failed: qualification of decltype\(\(n\)\) does not match qualification of Self} } + "qualification of decltype((n)) does not match qualification of Self"); + static_assert(__is_same (__remove_cvref (decltype((n))), int), + "decltype((n)) is not an int"); + static_assert(__is_same (decltype(n), int)); + + static_assert(is_lvalue_ref<decltype((c))>, + "decltype((c)) is not an lvalue ref"); + static_assert(is_const_v<__remove_reference (decltype((c)))>, + "qualification of decltype((c)) is not const"); + static_assert(__is_same (__remove_cvref (decltype((c))), int), + "decltype((c)) is not an int"); + static_assert(__is_same (decltype(c), int const)); + }; + f2_value(); + f2_value.operator()<decltype(f2_value) const>(); + + auto f3_value = [&n, &c]<typename Self>(this Self){ + static_assert(__is_same (decltype((n)), int&)); + static_assert(__is_same (decltype(n), int)); + + static_assert(__is_same (decltype((c)), int const&)); + static_assert(__is_same (decltype(c), int const)); + }; + f3_value(); + f3_value.operator()<decltype(f3_value) const>(); + + auto f4_value = []<typename Self>(this Self){ + static_assert(__is_same (decltype(n), int)); + static_assert(__is_same (decltype((n)), int&)); + + static_assert(__is_same (decltype(c), int const)); + static_assert(__is_same (decltype((c)), int const&)); + }; + f4_value(); + f4_value.operator()<decltype(f4_value) const>(); + + // ref + auto f0_ref = [=]<typename Self>(this Self&){ + static_assert(is_lvalue_ref<decltype((n))>, + "decltype((n)) is not an lvalue ref"); + static_assert(is_const_v<Self> == is_const_v<__remove_reference (decltype((n)))>, // { dg-bogus {static assertion failed: qualification of decltype\(\(n\)\) does not match qualification of Self} } + "qualification of decltype((n)) does not match qualification of Self"); + static_assert(__is_same (__remove_cvref (decltype((n))), int), + "decltype((n)) is not an int"); + static_assert(__is_same (decltype(n), int)); + + static_assert(is_lvalue_ref<decltype((c))>, + "decltype((c)) is not an lvalue ref"); + static_assert(is_const_v<__remove_reference (decltype((c)))>, + "qualification of decltype((c)) is not const"); + static_assert(__is_same (__remove_cvref (decltype((c))), int), + "decltype((c)) is not an int"); + static_assert(__is_same (decltype(c), int const)); + }; + f0_ref(); + f0_ref.operator()<decltype(f0_ref) const>(); + static_cast<decltype(f0_ref) const&>(f0_ref)(); + + auto f1_ref = [&]<typename Self>(this Self&){ + static_assert(__is_same (decltype((n)), int&)); + static_assert(__is_same (decltype(n), int)); + + static_assert(__is_same (decltype((c)), int const&)); + static_assert(__is_same (decltype(c), int const)); + }; + f1_ref(); + f1_ref.operator()<decltype(f1_ref) const>(); + static_cast<decltype(f1_ref) const&>(f1_ref)(); + + auto f2_ref = [n, c]<typename Self>(this Self&){ + static_assert(is_lvalue_ref<decltype((n))>, + "decltype((n)) is not an lvalue ref"); + static_assert(is_const_v<Self> == is_const_v<__remove_reference (decltype((n)))>, // { dg-bogus {static assertion failed: qualification of decltype\(\(n\)\) does not match qualification of Self} } + "qualification of decltype((n)) does not match qualification of Self"); + static_assert(__is_same (__remove_cvref (decltype((n))), int), + "decltype((n)) is not an int"); + static_assert(__is_same (decltype(n), int)); + + static_assert(is_lvalue_ref<decltype((c))>, + "decltype((c)) is not an lvalue ref"); + static_assert(is_const_v<__remove_reference (decltype((c)))>, + "qualification of decltype((c)) is not const"); + static_assert(__is_same (__remove_cvref (decltype((c))), int), + "decltype((c)) is not an int"); + static_assert(__is_same (decltype(c), int const)); + }; + f2_ref(); + f2_ref.operator()<decltype(f2_ref) const>(); + static_cast<decltype(f2_ref) const&>(f2_ref)(); + + auto f3_ref = [&n, &c]<typename Self>(this Self&){ + static_assert(__is_same(decltype((n)), int&)); + static_assert(__is_same (decltype(n), int)); + + static_assert(__is_same (decltype((c)), int const&)); + static_assert(__is_same (decltype(c), int const)); + }; + f3_ref(); + f3_ref.operator()<decltype(f3_ref) const>(); + static_cast<decltype(f3_ref) const&>(f3_ref)(); + + auto f4_ref = []<typename Self>(this Self&){ + static_assert(__is_same (decltype(n), int)); + static_assert(__is_same (decltype((n)), int&)); + + static_assert(__is_same (decltype(c), int const)); + static_assert(__is_same (decltype((c)), int const&)); + }; + f4_ref(); + f4_ref.operator()<decltype(f4_ref) const>(); + static_cast<decltype(f4_ref) const&>(f4_ref)(); + + // const value + auto f0_const_value = [=]<typename Self>(this Self const){ + static_assert(is_lvalue_ref<decltype((n))>, + "decltype((n)) is not an lvalue ref"); + static_assert(is_const_v<__remove_reference (decltype((n)))>, // { dg-bogus {static assertion failed: qualification of decltype\(\(n\)\) does not match qualification of Self} } + "qualification of decltype((n)) does not match qualification of Self"); + static_assert(__is_same (__remove_cvref (decltype((n))), int), + "decltype((n)) is not an int"); + static_assert(__is_same (decltype(n), int)); + + static_assert(is_lvalue_ref<decltype((c))>, + "decltype((c)) is not an lvalue ref"); + static_assert(is_const_v<__remove_reference (decltype((c)))>, + "qualification of decltype((c)) is not const"); + static_assert(__is_same (__remove_cvref (decltype((c))), int), + "decltype((c)) is not an int"); + static_assert(__is_same (decltype(c), int const)); + }; + f0_const_value(); + + auto f1_const_value = [&]<typename Self>(this Self const){ + static_assert(__is_same (decltype((n)), int&)); + static_assert(__is_same (decltype(n), int)); + + static_assert(__is_same (decltype((c)), int const&)); + static_assert(__is_same (decltype(c), int const)); + }; + f1_const_value(); + + auto f2_const_value = [n, c]<typename Self>(this Self const){ + static_assert(is_lvalue_ref<decltype((n))>, + "decltype((n)) is not an lvalue ref"); + static_assert(is_const_v<__remove_reference (decltype((n)))>, // { dg-bogus {static assertion failed: qualification of decltype\(\(n\)\) does not match qualification of Self} } + "qualification of decltype((n)) does not match qualification of Self"); + static_assert(__is_same (__remove_cvref (decltype((n))), int), + "decltype((n)) is not an int"); + static_assert(__is_same (decltype(n), int)); + + static_assert(is_lvalue_ref<decltype((c))>, + "decltype((c)) is not an lvalue ref"); + static_assert(is_const_v<__remove_reference (decltype((c)))>, + "qualification of decltype((c)) is not const"); + static_assert(__is_same (__remove_cvref (decltype((c))), int), + "decltype((c)) is not an int"); + static_assert(__is_same (decltype(c), int const)); + }; + f2_const_value(); + + auto f3_const_value = [&n, &c]<typename Self>(this Self const){ + static_assert(__is_same (decltype((n)), int&)); + static_assert(__is_same (decltype(n), int)); + + static_assert(__is_same (decltype((c)), int const&)); + static_assert(__is_same (decltype(c), int const)); + }; + f3_const_value(); + + auto f4_const_value = []<typename Self>(this Self const){ + static_assert(__is_same (decltype(n), int)); + static_assert(__is_same (decltype((n)), int&)); + + static_assert(__is_same (decltype(c), int const)); + static_assert(__is_same (decltype((c)), int const&)); + }; + f4_const_value(); + + // const ref + auto f0_const_ref = [=]<typename Self>(this Self const&){ + static_assert(is_lvalue_ref<decltype((n))>, + "decltype((n)) is not an lvalue ref"); + static_assert(is_const_v<__remove_reference (decltype((n)))>, // { dg-bogus {static assertion failed: qualification of decltype\(\(n\)\) does not match qualification of Self} } + "qualification of decltype((n)) does not match qualification of Self"); + static_assert(__is_same (__remove_cvref (decltype((n))), int), + "decltype((n)) is not an int"); + static_assert(__is_same (decltype(n), int)); + + static_assert(is_lvalue_ref<decltype((c))>, + "decltype((c)) is not an lvalue ref"); + static_assert(is_const_v<__remove_reference (decltype((c)))>, + "qualification of decltype((c)) is not const"); + static_assert(__is_same (__remove_cvref (decltype((c))), int), + "decltype((c)) is not an int"); + static_assert(__is_same (decltype(c), int const)); + }; + f0_const_ref(); + + auto f1_const_ref = [&]<typename Self>(this Self const&){ + static_assert(__is_same (decltype((n)), int&)); + static_assert(__is_same (decltype(n), int)); + + static_assert(__is_same (decltype((c)), int const&)); + static_assert(__is_same (decltype(c), int const)); + }; + f1_const_ref(); + + auto f2_const_ref = [n, c]<typename Self>(this Self const&){ + static_assert(is_lvalue_ref<decltype((n))>, + "decltype((n)) is not an lvalue ref"); + static_assert(is_const_v<__remove_reference (decltype((n)))>, // { dg-bogus {static assertion failed: qualification of decltype\(\(n\)\) does not match qualification of Self} } + "qualification of decltype((n)) does not match qualification of Self"); + static_assert(__is_same (__remove_cvref (decltype((n))), int), + "decltype((n)) is not an int"); + static_assert(__is_same (decltype(n), int)); + + static_assert(is_lvalue_ref<decltype((c))>, + "decltype((c)) is not an lvalue ref"); + static_assert(is_const_v<__remove_reference (decltype((c)))>, + "qualification of decltype((c)) is not const"); + static_assert(__is_same (__remove_cvref (decltype((c))), int), + "decltype((c)) is not an int"); + static_assert(__is_same (decltype(c), int const)); + }; + f2_const_ref(); + + auto f3_const_ref = [&n, &c]<typename Self>(this Self const&){ + static_assert(__is_same (decltype((n)), int&)); + static_assert(__is_same (decltype(n), int)); + + static_assert(__is_same (decltype((c)), int const&)); + static_assert(__is_same (decltype(c), int const)); + }; + f3_const_ref(); + + auto f4_const_ref = []<typename Self>(this Self const&){ + static_assert(__is_same (decltype(n), int)); + static_assert(__is_same (decltype((n)), int&)); + + static_assert(__is_same (decltype(c), int const)); + static_assert(__is_same (decltype((c)), int const&)); + }; + f4_const_ref(); +} + +template<typename = void> +void dep0() +{ + int n = 0; + int const c = 0; + // value + auto f0_value = [=]<typename Self>(this Self){ + static_assert(is_lvalue_ref<decltype((n))>, + "decltype((n)) is not an lvalue ref"); + static_assert(is_const_v<Self> == is_const_v<__remove_reference (decltype((n)))>, // { dg-bogus {static assertion failed: qualification of decltype\(\(n\)\) does not match qualification of Self} } + "qualification of decltype((n)) does not match qualification of Self"); + static_assert(__is_same (__remove_cvref (decltype((n))), int), + "decltype((n)) is not an int"); + static_assert(__is_same (decltype(n), int)); + + static_assert(is_lvalue_ref<decltype((c))>, + "decltype((c)) is not an lvalue ref"); + static_assert(is_const_v<__remove_reference (decltype((c)))>, + "qualification of decltype((c)) is not const"); + static_assert(__is_same (__remove_cvref (decltype((c))), int), + "decltype((c)) is not an int"); + static_assert(__is_same (decltype(c), int const)); + }; + f0_value(); + f0_value.template operator()<decltype(f0_value) const>(); + + auto f1_value = [&]<typename Self>(this Self){ + static_assert(__is_same (decltype((n)), int&)); + static_assert(__is_same (decltype(n), int)); + + static_assert(__is_same (decltype((c)), int const&)); + static_assert(__is_same (decltype(c), int const)); + }; + f1_value(); + f1_value.template operator()<decltype(f1_value) const>(); + + auto f2_value = [n, c]<typename Self>(this Self){ + static_assert(is_lvalue_ref<decltype((n))>, + "decltype((n)) is not an lvalue ref"); + static_assert(is_const_v<Self> == is_const_v<__remove_reference (decltype((n)))>, // { dg-bogus {static assertion failed: qualification of decltype\(\(n\)\) does not match qualification of Self} } + "qualification of decltype((n)) does not match qualification of Self"); + static_assert(__is_same (__remove_cvref (decltype((n))), int), + "decltype((n)) is not an int"); + static_assert(__is_same (decltype(n), int)); + + static_assert(is_lvalue_ref<decltype((c))>, + "decltype((c)) is not an lvalue ref"); + static_assert(is_const_v<__remove_reference (decltype((c)))>, + "qualification of decltype((c)) is not const"); + static_assert(__is_same (__remove_cvref (decltype((c))), int), + "decltype((c)) is not an int"); + static_assert(__is_same (decltype(c), int const)); + }; + f2_value(); + f2_value.template operator()<decltype(f2_value) const>(); + + auto f3_value = [&n, &c]<typename Self>(this Self){ + static_assert(__is_same (decltype((n)), int&)); + static_assert(__is_same (decltype(n), int)); + + static_assert(__is_same (decltype((c)), int const&)); + static_assert(__is_same (decltype(c), int const)); + }; + f3_value(); + f3_value.template operator()<decltype(f3_value) const>(); + + auto f4_value = []<typename Self>(this Self){ + static_assert(__is_same (decltype(n), int)); + static_assert(__is_same (decltype((n)), int&)); + + static_assert(__is_same (decltype(c), int const)); + static_assert(__is_same (decltype((c)), int const&)); + }; + f4_value(); + f4_value.template operator()<decltype(f4_value) const>(); + + // ref + auto f0_ref = [=]<typename Self>(this Self&){ + static_assert(is_lvalue_ref<decltype((n))>, + "decltype((n)) is not an lvalue ref"); + static_assert(is_const_v<Self> == is_const_v<__remove_reference (decltype((n)))>, // { dg-bogus {static assertion failed: qualification of decltype\(\(n\)\) does not match qualification of Self} } + "qualification of decltype((n)) does not match qualification of Self"); + static_assert(__is_same (__remove_cvref (decltype((n))), int), + "decltype((n)) is not an int"); + static_assert(__is_same (decltype(n), int)); + + static_assert(is_lvalue_ref<decltype((c))>, + "decltype((c)) is not an lvalue ref"); + static_assert(is_const_v<__remove_reference (decltype((c)))>, + "qualification of decltype((c)) is not const"); + static_assert(__is_same (__remove_cvref (decltype((c))), int), + "decltype((c)) is not an int"); + static_assert(__is_same (decltype(c), int const)); + }; + f0_ref(); + f0_ref.template operator()<decltype(f0_ref) const>(); + static_cast<decltype(f0_ref) const&>(f0_ref)(); + + auto f1_ref = [&]<typename Self>(this Self&){ + static_assert(__is_same (decltype((n)), int&)); + static_assert(__is_same (decltype(n), int)); + + static_assert(__is_same (decltype((c)), int const&)); + static_assert(__is_same (decltype(c), int const)); + }; + f1_ref(); + f1_ref.template operator()<decltype(f1_ref) const>(); + static_cast<decltype(f1_ref) const&>(f1_ref)(); + + auto f2_ref = [n, c]<typename Self>(this Self&){ + static_assert(is_lvalue_ref<decltype((n))>, + "decltype((n)) is not an lvalue ref"); + static_assert(is_const_v<Self> == is_const_v<__remove_reference (decltype((n)))>, // { dg-bogus {static assertion failed: qualification of decltype\(\(n\)\) does not match qualification of Self} } + "qualification of decltype((n)) does not match qualification of Self"); + static_assert(__is_same (__remove_cvref (decltype((n))), int), + "decltype((n)) is not an int"); + static_assert(__is_same (decltype(n), int)); + + static_assert(is_lvalue_ref<decltype((c))>, + "decltype((c)) is not an lvalue ref"); + static_assert(is_const_v<__remove_reference (decltype((c)))>, + "qualification of decltype((c)) is not const"); + static_assert(__is_same (__remove_cvref (decltype((c))), int), + "decltype((c)) is not an int"); + static_assert(__is_same (decltype(c), int const)); + }; + f2_ref(); + f2_ref.template operator()<decltype(f2_ref) const>(); + static_cast<decltype(f2_ref) const&>(f2_ref)(); + + auto f3_ref = [&n, &c]<typename Self>(this Self&){ + static_assert(__is_same(decltype((n)), int&)); + static_assert(__is_same (decltype(n), int)); + + static_assert(__is_same (decltype((c)), int const&)); + static_assert(__is_same (decltype(c), int const)); + }; + f3_ref(); + f3_ref.template operator()<decltype(f3_ref) const>(); + static_cast<decltype(f3_ref) const&>(f3_ref)(); + + auto f4_ref = []<typename Self>(this Self&){ + static_assert(__is_same (decltype(n), int)); + static_assert(__is_same (decltype((n)), int&)); + + static_assert(__is_same (decltype(c), int const)); + static_assert(__is_same (decltype((c)), int const&)); + }; + f4_ref(); + f4_ref.template operator()<decltype(f4_ref) const>(); + static_cast<decltype(f4_ref) const&>(f4_ref)(); + + // const value + auto f0_const_value = [=]<typename Self>(this Self const){ + static_assert(is_lvalue_ref<decltype((n))>, + "decltype((n)) is not an lvalue ref"); + static_assert(is_const_v<__remove_reference (decltype((n)))>, // { dg-bogus {static assertion failed: qualification of decltype\(\(n\)\) does not match qualification of Self} } + "qualification of decltype((n)) does not match qualification of Self"); + static_assert(__is_same (__remove_cvref (decltype((n))), int), + "decltype((n)) is not an int"); + static_assert(__is_same (decltype(n), int)); + + static_assert(is_lvalue_ref<decltype((c))>, + "decltype((c)) is not an lvalue ref"); + static_assert(is_const_v<__remove_reference (decltype((c)))>, + "qualification of decltype((c)) is not const"); + static_assert(__is_same (__remove_cvref (decltype((c))), int), + "decltype((c)) is not an int"); + static_assert(__is_same (decltype(c), int const)); + }; + f0_const_value(); + + auto f1_const_value = [&]<typename Self>(this Self const){ + static_assert(__is_same (decltype((n)), int&)); + static_assert(__is_same (decltype(n), int)); + + static_assert(__is_same (decltype((c)), int const&)); + static_assert(__is_same (decltype(c), int const)); + }; + f1_const_value(); + + auto f2_const_value = [n, c]<typename Self>(this Self const){ + static_assert(is_lvalue_ref<decltype((n))>, + "decltype((n)) is not an lvalue ref"); + static_assert(is_const_v<__remove_reference (decltype((n)))>, // { dg-bogus {static assertion failed: qualification of decltype\(\(n\)\) does not match qualification of Self} } + "qualification of decltype((n)) does not match qualification of Self"); + static_assert(__is_same (__remove_cvref (decltype((n))), int), + "decltype((n)) is not an int"); + static_assert(__is_same (decltype(n), int)); + + static_assert(is_lvalue_ref<decltype((c))>, + "decltype((c)) is not an lvalue ref"); + static_assert(is_const_v<__remove_reference (decltype((c)))>, + "qualification of decltype((c)) is not const"); + static_assert(__is_same (__remove_cvref (decltype((c))), int), + "decltype((c)) is not an int"); + static_assert(__is_same (decltype(c), int const)); + }; + f2_const_value(); + + auto f3_const_value = [&n, &c]<typename Self>(this Self const){ + static_assert(__is_same (decltype((n)), int&)); + static_assert(__is_same (decltype(n), int)); + + static_assert(__is_same (decltype((c)), int const&)); + static_assert(__is_same (decltype(c), int const)); + }; + f3_const_value(); + + auto f4_const_value = []<typename Self>(this Self const){ + static_assert(__is_same (decltype(n), int)); + static_assert(__is_same (decltype((n)), int&)); + + static_assert(__is_same (decltype(c), int const)); + static_assert(__is_same (decltype((c)), int const&)); + }; + f4_const_value(); + + // const ref + auto f0_const_ref = [=]<typename Self>(this Self const&){ + static_assert(is_lvalue_ref<decltype((n))>, + "decltype((n)) is not an lvalue ref"); + static_assert(is_const_v<__remove_reference (decltype((n)))>, // { dg-bogus {static assertion failed: qualification of decltype\(\(n\)\) does not match qualification of Self} } + "qualification of decltype((n)) does not match qualification of Self"); + static_assert(__is_same (__remove_cvref (decltype((n))), int), + "decltype((n)) is not an int"); + static_assert(__is_same (decltype(n), int)); + + static_assert(is_lvalue_ref<decltype((c))>, + "decltype((c)) is not an lvalue ref"); + static_assert(is_const_v<__remove_reference (decltype((c)))>, + "qualification of decltype((c)) is not const"); + static_assert(__is_same (__remove_cvref (decltype((c))), int), + "decltype((c)) is not an int"); + static_assert(__is_same (decltype(c), int const)); + }; + f0_const_ref(); + + auto f1_const_ref = [&]<typename Self>(this Self const&){ + static_assert(__is_same (decltype((n)), int&)); + static_assert(__is_same (decltype(n), int)); + + static_assert(__is_same (decltype((c)), int const&)); + static_assert(__is_same (decltype(c), int const)); + }; + f1_const_ref(); + + auto f2_const_ref = [n, c]<typename Self>(this Self const&){ + static_assert(is_lvalue_ref<decltype((n))>, + "decltype((n)) is not an lvalue ref"); + static_assert(is_const_v<__remove_reference (decltype((n)))>, // { dg-bogus {static assertion failed: qualification of decltype\(\(n\)\) does not match qualification of Self} } + "qualification of decltype((n)) does not match qualification of Self"); + static_assert(__is_same (__remove_cvref (decltype((n))), int), + "decltype((n)) is not an int"); + static_assert(__is_same (decltype(n), int)); + + static_assert(is_lvalue_ref<decltype((c))>, + "decltype((c)) is not an lvalue ref"); + static_assert(is_const_v<__remove_reference (decltype((c)))>, + "qualification of decltype((c)) is not const"); + static_assert(__is_same (__remove_cvref (decltype((c))), int), + "decltype((c)) is not an int"); + static_assert(__is_same (decltype(c), int const)); + }; + f2_const_ref(); + + auto f3_const_ref = [&n, &c]<typename Self>(this Self const&){ + static_assert(__is_same (decltype((n)), int&)); + static_assert(__is_same (decltype(n), int)); + + static_assert(__is_same (decltype((c)), int const&)); + static_assert(__is_same (decltype(c), int const)); + }; + f3_const_ref(); + + auto f4_const_ref = []<typename Self>(this Self const&){ + static_assert(__is_same (decltype(n), int)); + static_assert(__is_same (decltype((n)), int&)); + + static_assert(__is_same (decltype(c), int const)); + static_assert(__is_same (decltype((c)), int const&)); + }; + f4_const_ref(); +} + +// dep1 uses the template parameter + +template<typename T = int> +void dep1() +{ + T n = 0; + T const c = 0; + // value + auto f0_value = [=]<typename Self>(this Self){ + static_assert(is_lvalue_ref<decltype((n))>, + "decltype((n)) is not an lvalue ref"); + static_assert(is_const_v<Self> == is_const_v<__remove_reference (decltype((n)))>, // { dg-bogus {static assertion failed: qualification of decltype\(\(n\)\) does not match qualification of Self} } + "qualification of decltype((n)) does not match qualification of Self"); + static_assert(__is_same (__remove_cvref (decltype((n))), int), + "decltype((n)) is not an int"); + static_assert(__is_same (decltype(n), int)); + + static_assert(is_lvalue_ref<decltype((c))>, + "decltype((c)) is not an lvalue ref"); + static_assert(is_const_v<__remove_reference (decltype((c)))>, + "qualification of decltype((c)) is not const"); + static_assert(__is_same (__remove_cvref (decltype((c))), int), + "decltype((c)) is not an int"); + static_assert(__is_same (decltype(c), int const)); + }; + f0_value(); + f0_value.template operator()<decltype(f0_value) const>(); + + auto f1_value = [&]<typename Self>(this Self){ + static_assert(__is_same (decltype((n)), int&)); + static_assert(__is_same (decltype(n), int)); + + static_assert(__is_same (decltype((c)), int const&)); + static_assert(__is_same (decltype(c), int const)); + }; + f1_value(); + f1_value.template operator()<decltype(f1_value) const>(); + + auto f2_value = [n, c]<typename Self>(this Self){ + static_assert(is_lvalue_ref<decltype((n))>, + "decltype((n)) is not an lvalue ref"); + static_assert(is_const_v<Self> == is_const_v<__remove_reference (decltype((n)))>, // { dg-bogus {static assertion failed: qualification of decltype\(\(n\)\) does not match qualification of Self} } + "qualification of decltype((n)) does not match qualification of Self"); + static_assert(__is_same (__remove_cvref (decltype((n))), int), + "decltype((n)) is not an int"); + static_assert(__is_same (decltype(n), int)); + + static_assert(is_lvalue_ref<decltype((c))>, + "decltype((c)) is not an lvalue ref"); + static_assert(is_const_v<__remove_reference (decltype((c)))>, + "qualification of decltype((c)) is not const"); + static_assert(__is_same (__remove_cvref (decltype((c))), int), + "decltype((c)) is not an int"); + static_assert(__is_same (decltype(c), int const)); + }; + f2_value(); + f2_value.template operator()<decltype(f2_value) const>(); + + auto f3_value = [&n, &c]<typename Self>(this Self){ + static_assert(__is_same (decltype((n)), int&)); + static_assert(__is_same (decltype(n), int)); + + static_assert(__is_same (decltype((c)), int const&)); + static_assert(__is_same (decltype(c), int const)); + }; + f3_value(); + f3_value.template operator()<decltype(f3_value) const>(); + + auto f4_value = []<typename Self>(this Self){ + static_assert(__is_same (decltype(n), int)); + static_assert(__is_same (decltype((n)), int&)); + + static_assert(__is_same (decltype(c), int const)); + static_assert(__is_same (decltype((c)), int const&)); + }; + f4_value(); + f4_value.template operator()<decltype(f4_value) const>(); + + // ref + auto f0_ref = [=]<typename Self>(this Self&){ + static_assert(is_lvalue_ref<decltype((n))>, + "decltype((n)) is not an lvalue ref"); + static_assert(is_const_v<Self> == is_const_v<__remove_reference (decltype((n)))>, // { dg-bogus {static assertion failed: qualification of decltype\(\(n\)\) does not match qualification of Self} } + "qualification of decltype((n)) does not match qualification of Self"); + static_assert(__is_same (__remove_cvref (decltype((n))), int), + "decltype((n)) is not an int"); + static_assert(__is_same (decltype(n), int)); + + static_assert(is_lvalue_ref<decltype((c))>, + "decltype((c)) is not an lvalue ref"); + static_assert(is_const_v<__remove_reference (decltype((c)))>, + "qualification of decltype((c)) is not const"); + static_assert(__is_same (__remove_cvref (decltype((c))), int), + "decltype((c)) is not an int"); + static_assert(__is_same (decltype(c), int const)); + }; + f0_ref(); + f0_ref.template operator()<decltype(f0_ref) const>(); + static_cast<decltype(f0_ref) const&>(f0_ref)(); + + auto f1_ref = [&]<typename Self>(this Self&){ + static_assert(__is_same (decltype((n)), int&)); + static_assert(__is_same (decltype(n), int)); + + static_assert(__is_same (decltype((c)), int const&)); + static_assert(__is_same (decltype(c), int const)); + }; + f1_ref(); + f1_ref.template operator()<decltype(f1_ref) const>(); + static_cast<decltype(f1_ref) const&>(f1_ref)(); + + auto f2_ref = [n, c]<typename Self>(this Self&){ + static_assert(is_lvalue_ref<decltype((n))>, + "decltype((n)) is not an lvalue ref"); + static_assert(is_const_v<Self> == is_const_v<__remove_reference (decltype((n)))>, // { dg-bogus {static assertion failed: qualification of decltype\(\(n\)\) does not match qualification of Self} } + "qualification of decltype((n)) does not match qualification of Self"); + static_assert(__is_same (__remove_cvref (decltype((n))), int), + "decltype((n)) is not an int"); + static_assert(__is_same (decltype(n), int)); + + static_assert(is_lvalue_ref<decltype((c))>, + "decltype((c)) is not an lvalue ref"); + static_assert(is_const_v<__remove_reference (decltype((c)))>, + "qualification of decltype((c)) is not const"); + static_assert(__is_same (__remove_cvref (decltype((c))), int), + "decltype((c)) is not an int"); + static_assert(__is_same (decltype(c), int const)); + }; + f2_ref(); + f2_ref.template operator()<decltype(f2_ref) const>(); + static_cast<decltype(f2_ref) const&>(f2_ref)(); + + auto f3_ref = [&n, &c]<typename Self>(this Self&){ + static_assert(__is_same(decltype((n)), int&)); + static_assert(__is_same (decltype(n), int)); + + static_assert(__is_same (decltype((c)), int const&)); + static_assert(__is_same (decltype(c), int const)); + }; + f3_ref(); + f3_ref.template operator()<decltype(f3_ref) const>(); + static_cast<decltype(f3_ref) const&>(f3_ref)(); + + auto f4_ref = []<typename Self>(this Self&){ + static_assert(__is_same (decltype(n), int)); + static_assert(__is_same (decltype((n)), int&)); + + static_assert(__is_same (decltype(c), int const)); + static_assert(__is_same (decltype((c)), int const&)); + }; + f4_ref(); + f4_ref.template operator()<decltype(f4_ref) const>(); + static_cast<decltype(f4_ref) const&>(f4_ref)(); + + // const value + auto f0_const_value = [=]<typename Self>(this Self const){ + static_assert(is_lvalue_ref<decltype((n))>, + "decltype((n)) is not an lvalue ref"); + static_assert(is_const_v<__remove_reference (decltype((n)))>, // { dg-bogus {static assertion failed: qualification of decltype\(\(n\)\) does not match qualification of Self} } + "qualification of decltype((n)) does not match qualification of Self"); + static_assert(__is_same (__remove_cvref (decltype((n))), int), + "decltype((n)) is not an int"); + static_assert(__is_same (decltype(n), int)); + + static_assert(is_lvalue_ref<decltype((c))>, + "decltype((c)) is not an lvalue ref"); + static_assert(is_const_v<__remove_reference (decltype((c)))>, + "qualification of decltype((c)) is not const"); + static_assert(__is_same (__remove_cvref (decltype((c))), int), + "decltype((c)) is not an int"); + static_assert(__is_same (decltype(c), int const)); + }; + f0_const_value(); + + auto f1_const_value = [&]<typename Self>(this Self const){ + static_assert(__is_same (decltype((n)), int&)); + static_assert(__is_same (decltype(n), int)); + + static_assert(__is_same (decltype((c)), int const&)); + static_assert(__is_same (decltype(c), int const)); + }; + f1_const_value(); + + auto f2_const_value = [n, c]<typename Self>(this Self const){ + static_assert(is_lvalue_ref<decltype((n))>, + "decltype((n)) is not an lvalue ref"); + static_assert(is_const_v<__remove_reference (decltype((n)))>, // { dg-bogus {static assertion failed: qualification of decltype\(\(n\)\) does not match qualification of Self} } + "qualification of decltype((n)) does not match qualification of Self"); + static_assert(__is_same (__remove_cvref (decltype((n))), int), + "decltype((n)) is not an int"); + static_assert(__is_same (decltype(n), int)); + + static_assert(is_lvalue_ref<decltype((c))>, + "decltype((c)) is not an lvalue ref"); + static_assert(is_const_v<__remove_reference (decltype((c)))>, + "qualification of decltype((c)) is not const"); + static_assert(__is_same (__remove_cvref (decltype((c))), int), + "decltype((c)) is not an int"); + static_assert(__is_same (decltype(c), int const)); + }; + f2_const_value(); + + auto f3_const_value = [&n, &c]<typename Self>(this Self const){ + static_assert(__is_same (decltype((n)), int&)); + static_assert(__is_same (decltype(n), int)); + + static_assert(__is_same (decltype((c)), int const&)); + static_assert(__is_same (decltype(c), int const)); + }; + f3_const_value(); + + auto f4_const_value = []<typename Self>(this Self const){ + static_assert(__is_same (decltype(n), int)); + static_assert(__is_same (decltype((n)), int&)); + + static_assert(__is_same (decltype(c), int const)); + static_assert(__is_same (decltype((c)), int const&)); + }; + f4_const_value(); + + // const ref + auto f0_const_ref = [=]<typename Self>(this Self const&){ + static_assert(is_lvalue_ref<decltype((n))>, + "decltype((n)) is not an lvalue ref"); + static_assert(is_const_v<__remove_reference (decltype((n)))>, // { dg-bogus {static assertion failed: qualification of decltype\(\(n\)\) does not match qualification of Self} } + "qualification of decltype((n)) does not match qualification of Self"); + static_assert(__is_same (__remove_cvref (decltype((n))), int), + "decltype((n)) is not an int"); + static_assert(__is_same (decltype(n), int)); + + static_assert(is_lvalue_ref<decltype((c))>, + "decltype((c)) is not an lvalue ref"); + static_assert(is_const_v<__remove_reference (decltype((c)))>, + "qualification of decltype((c)) is not const"); + static_assert(__is_same (__remove_cvref (decltype((c))), int), + "decltype((c)) is not an int"); + static_assert(__is_same (decltype(c), int const)); + }; + f0_const_ref(); + + auto f1_const_ref = [&]<typename Self>(this Self const&){ + static_assert(__is_same (decltype((n)), int&)); + static_assert(__is_same (decltype(n), int)); + + static_assert(__is_same (decltype((c)), int const&)); + static_assert(__is_same (decltype(c), int const)); + }; + f1_const_ref(); + + auto f2_const_ref = [n, c]<typename Self>(this Self const&){ + static_assert(is_lvalue_ref<decltype((n))>, + "decltype((n)) is not an lvalue ref"); + static_assert(is_const_v<__remove_reference (decltype((n)))>, // { dg-bogus {static assertion failed: qualification of decltype\(\(n\)\) does not match qualification of Self} } + "qualification of decltype((n)) does not match qualification of Self"); + static_assert(__is_same (__remove_cvref (decltype((n))), int), + "decltype((n)) is not an int"); + static_assert(__is_same (decltype(n), int)); + + static_assert(is_lvalue_ref<decltype((c))>, + "decltype((c)) is not an lvalue ref"); + static_assert(is_const_v<__remove_reference (decltype((c)))>, + "qualification of decltype((c)) is not const"); + static_assert(__is_same (__remove_cvref (decltype((c))), int), + "decltype((c)) is not an int"); + static_assert(__is_same (decltype(c), int const)); + }; + f2_const_ref(); + + auto f3_const_ref = [&n, &c]<typename Self>(this Self const&){ + static_assert(__is_same (decltype((n)), int&)); + static_assert(__is_same (decltype(n), int)); + + static_assert(__is_same (decltype((c)), int const&)); + static_assert(__is_same (decltype(c), int const)); + }; + f3_const_ref(); + + auto f4_const_ref = []<typename Self>(this Self const&){ + static_assert(__is_same (decltype(n), int)); + static_assert(__is_same (decltype((n)), int&)); + + static_assert(__is_same (decltype(c), int const)); + static_assert(__is_same (decltype((c)), int const&)); + }; + f4_const_ref(); +} + +void instantiate_dep() +{ + dep0(); + dep1(); +} + diff --git a/gcc/testsuite/g++.dg/cpp23/explicit-obj-lambda7.C b/gcc/testsuite/g++.dg/cpp23/explicit-obj-lambda7.C new file mode 100644 index 0000000..1e10fb2 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp23/explicit-obj-lambda7.C @@ -0,0 +1,20 @@ +// P0847R7 +// { dg-do compile { target c++23 } } + +// diagnose mutation of lambda capture when called with a deduced as const explicit object parameter + +void test() +{ + auto f0 = [n = 5](this auto){ n = 10; }; // { dg-bogus {assignment of read-only variable} } + auto f1 = [n = 5](this auto const){ n = 10; }; // { dg-error {assignment of read-only variable} } + auto f2 = [n = 5](this auto&){ n = 10; }; // { dg-error {assignment of read-only variable} } + auto f3 = [n = 5](this auto const&){ n = 10; }; // { dg-error {assignment of read-only variable} } + auto f4 = [n = 5](this auto&&){ n = 10; }; // { dg-error {assignment of read-only variable} } + + static_cast<decltype(f0) const&>(f0)(); + f1(); + static_cast<decltype(f2) const&>(f2)(); + f3(); + static_cast<decltype(f4) const&>(f4)(); +} + diff --git a/gcc/testsuite/g++.dg/cpp23/explicit-obj-lambda8.C b/gcc/testsuite/g++.dg/cpp23/explicit-obj-lambda8.C new file mode 100644 index 0000000..a068941 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp23/explicit-obj-lambda8.C @@ -0,0 +1,87 @@ +// P0847R7 +// { dg-do run { target c++23 } } + +// lambda capture mutability with explicit object parameter + +void capture_by_value() +{ + static constexpr int magic = 42; + auto f0 = [n = 0](this auto self){ + n += magic; + return n; + }; + auto f1 = [n = 0](this auto& self){ + n += magic; + return n; + }; + auto f2 = [n = 0](this auto&& self){ + n += magic; + return n; + }; + + // passed by value, should still return a value equal to magic regardless + // of how many times it is called + if (f0 () != magic) + __builtin_abort (); + if (f0 () != magic) + __builtin_abort (); + // passed by reference, the returned value should increase by magic + // each time it is called + if (f1 () != magic) + __builtin_abort (); + if (f1 () != magic + magic) + __builtin_abort (); + if (f2 () != magic) + __builtin_abort (); + if (f2 () != magic + magic) + __builtin_abort (); +} + +void capture_by_ref() +{ + static constexpr int magic = 42; + int n0 = 0; + auto f0 = [&n0](this auto self){ + n0 += magic; + }; + int n1 = 0; + auto f1 = [&n1](this auto& self){ + n1 += magic; + }; + int n2 = 0; + auto f2 = [&n2](this auto&& self){ + n2 += magic; + }; + int n3 = 0; + auto f3 = [&n3](this auto const& self){ + n3 += magic; + }; + + // all calls should mutate their capture, the capture is by reference + if (f0 (); n0 != magic) + __builtin_abort (); + if (f0 (); n0 != magic + magic) + __builtin_abort (); + + if (f1 (); n1 != magic) + __builtin_abort (); + if (f1 (); n1 != magic + magic) + __builtin_abort (); + + if (f2 (); n2 != magic) + __builtin_abort (); + if (f2 (); n2 != magic + magic) + __builtin_abort (); + + if (f3 (); n3 != magic) + __builtin_abort (); + if (f3 (); n3 != magic + magic) + __builtin_abort (); +} + +int main() +{ + capture_by_value (); + capture_by_ref (); +} + diff --git a/gcc/testsuite/g++.dg/cpp23/explicit-obj-lambda9.C b/gcc/testsuite/g++.dg/cpp23/explicit-obj-lambda9.C new file mode 100644 index 0000000..a808019 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp23/explicit-obj-lambda9.C @@ -0,0 +1,46 @@ +// P0847R7 +// { dg-do run { target c++23 } } + +// calling captureless lambda call operator with unrelated explicit object parameter +// through function pointer + +int main() +{ + auto f0 = [](this auto self) { return self; }; + auto fp0_value = static_cast<int(*)(int) >(&decltype(f0)::operator()); + auto fp0_lref = static_cast<int(*)(int&) >(&decltype(f0)::operator()); + auto fp0_rref = static_cast<int(*)(int&&) >(&decltype(f0)::operator()); + auto fp0_constlref = static_cast<int(*)(int const&) >(&decltype(f0)::operator()); + auto fp0_constrref = static_cast<int(*)(int const&&)>(&decltype(f0)::operator()); + + auto f1 = [](this auto&& self) { return self; }; + auto fp1_lref = static_cast<int(*)(int&) >(&decltype(f1)::operator()); + auto fp1_rref = static_cast<int(*)(int&&) >(&decltype(f1)::operator()); + auto fp1_constlref = static_cast<int(*)(int const&) >(&decltype(f1)::operator()); + auto fp1_constrref = static_cast<int(*)(int const&&)>(&decltype(f1)::operator()); + + // both are needed for lvalue/rvalue overloads + #define MAGIC 42 + int magic = MAGIC; + + if (fp0_value (magic) != magic) + __builtin_abort (); + if (fp0_lref (magic) != magic) + __builtin_abort (); + if (fp0_rref (MAGIC) != magic) + __builtin_abort (); + if (fp0_constlref (magic) != magic) + __builtin_abort (); + if (fp0_constrref (MAGIC) != magic) + __builtin_abort (); + + if (fp1_lref (magic) != magic) + __builtin_abort (); + if (fp1_rref (MAGIC) != magic) + __builtin_abort (); + if (fp1_constlref (magic) != magic) + __builtin_abort (); + if (fp1_constrref (MAGIC) != magic) + __builtin_abort (); +} + diff --git a/gcc/testsuite/g++.dg/cpp23/explicit-obj-ops-mem-arrow.C b/gcc/testsuite/g++.dg/cpp23/explicit-obj-ops-mem-arrow.C new file mode 100644 index 0000000..eb86077 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp23/explicit-obj-ops-mem-arrow.C @@ -0,0 +1,28 @@ +// P0847R7 +// { dg-do compile { target c++23 } } + +// uses of member only operators (arrow) + +struct S { + int _v; + S* operator->(this S& self) { return &self; } +}; + +void non_dep() +{ + S s{}; + (void)s->_v; +} + +template<typename = void> +void dependent() +{ + S s{}; + (void)s->_v; +} + +void call() +{ + dependent(); +} + diff --git a/gcc/testsuite/g++.dg/cpp23/explicit-obj-ops-mem-assignment.C b/gcc/testsuite/g++.dg/cpp23/explicit-obj-ops-mem-assignment.C new file mode 100644 index 0000000..bb43a0a --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp23/explicit-obj-ops-mem-assignment.C @@ -0,0 +1,27 @@ +// P0847R7 +// { dg-do compile { target c++23 } } + +// uses of member only operators (assignment) + +struct S { + void operator=(this S&, int) {} +}; + +void non_dep() +{ + S s{}; + s = 0; +} + +template<typename = void> +void dependent() +{ + S s{}; + s = 0; +} + +void call() +{ + dependent(); +} + diff --git a/gcc/testsuite/g++.dg/cpp23/explicit-obj-ops-mem-call.C b/gcc/testsuite/g++.dg/cpp23/explicit-obj-ops-mem-call.C new file mode 100644 index 0000000..ecd6bdf --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp23/explicit-obj-ops-mem-call.C @@ -0,0 +1,40 @@ +// P0847R7 +// { dg-do compile { target c++23 } } + +// uses of member only operators (call op) + +// execution paths for subscript with 1 argument and 0 and 2+ arguments are different +// just to be safe, also test 0 and 2 argument cases here too + +struct S { + void operator()(this S&) {} + void operator()(this S&, int) {} + void operator()(this S&, int, int) {} + template<typename... Args> + void operator()(this S&, Args... args) {} +}; + +void non_dep() +{ + S s{}; + s(); + s(0); + s(0, 0); + s(0, 0, 0); +} + +template<typename = void> +void dependent() +{ + S s{}; + s(); + s(0); + s(0, 0); + s(0, 0, 0); +} + +void call() +{ + dependent(); +} + diff --git a/gcc/testsuite/g++.dg/cpp23/explicit-obj-ops-mem-subscript.C b/gcc/testsuite/g++.dg/cpp23/explicit-obj-ops-mem-subscript.C new file mode 100644 index 0000000..3eb0030 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp23/explicit-obj-ops-mem-subscript.C @@ -0,0 +1,40 @@ +// P0847R7 +// { dg-do compile { target c++23 } } + +// uses of member only operators (subscript) + +// execution paths for subscript with 1 argument and 0 and 2+ arguments are different +// therefore we should additionally test the 0 and 2 argument cases as well + +struct S { + void operator[](this S&) {} + void operator[](this S&, int) {} + void operator[](this S&, int, int) {} + template<typename... Args> + void operator[](this S&, Args... args) {} +}; + +void non_dep() +{ + S s{}; + s[]; + s[0]; + s[0, 0]; + s[0, 0, 0]; +} + +template<typename = void> +void dependent() +{ + S s{}; + s[]; + s[0]; + s[0, 0]; + s[0, 0, 0]; +} + +void call() +{ + dependent(); +} + diff --git a/gcc/testsuite/g++.dg/cpp23/explicit-obj-ops-non-mem-dep.C b/gcc/testsuite/g++.dg/cpp23/explicit-obj-ops-non-mem-dep.C new file mode 100644 index 0000000..f38615e --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp23/explicit-obj-ops-non-mem-dep.C @@ -0,0 +1,58 @@ +// P0847R7 +// { dg-do compile { target c++23 } } + +// operators that are not required to be members +// called in a dependent context (as non dependent exprs) +// see header +#include "explicit-obj-ops-non-mem.h" + +// noop, indicates which versions are ill-formed +// I could not find a way to test the invalid cases +// without requires expressions +#define TEST_INVALID(X) + +template<typename T = void> +void do_calls() +{ + Value value{}; + TEST_OPS(value) + TEST_OPS(static_cast<Value&&>(value)) + TEST_OPS(static_cast<Value const&>(value)) + TEST_OPS(static_cast<Value const&&>(value)) + + LRef l_ref{}; + TEST_OPS(l_ref) + TEST_INVALID(static_cast<LRef&&>(l_ref)) + TEST_INVALID(static_cast<LRef const&>(l_ref)) + TEST_INVALID(static_cast<LRef const&&>(l_ref)) + + RRef r_ref{}; + TEST_INVALID(r_ref) + TEST_OPS(static_cast<RRef&&>(r_ref)) + TEST_INVALID(static_cast<RRef const&>(r_ref)) + TEST_INVALID(static_cast<RRef const&&>(r_ref)) + + ConstLRef const_l_ref{}; + TEST_OPS(const_l_ref) + TEST_OPS(static_cast<ConstLRef&&>(const_l_ref)) + TEST_OPS(static_cast<ConstLRef const&>(const_l_ref)) + TEST_OPS(static_cast<ConstLRef const&&>(const_l_ref)) + + ConstRRef const_r_ref{}; + TEST_INVALID(const_r_ref) + TEST_OPS(static_cast<ConstRRef&&>(const_r_ref)) + TEST_INVALID(static_cast<ConstRRef const&>(const_r_ref)) + TEST_OPS(static_cast<ConstRRef const&&>(const_r_ref)) + + Deduced deduced{}; + TEST_OPS(deduced) + TEST_OPS(static_cast<Deduced&&>(deduced)) + TEST_OPS(static_cast<Deduced const&>(deduced)) + TEST_OPS(static_cast<Deduced const&&>(deduced)) + + VALIDATE_RETURN_TYPES(deduced, Deduced&) + VALIDATE_RETURN_TYPES(static_cast<Deduced&&>(deduced), Deduced&&) + VALIDATE_RETURN_TYPES(static_cast<Deduced const&>(deduced), Deduced const&) + VALIDATE_RETURN_TYPES(static_cast<Deduced const&&>(deduced), Deduced const&&) +} + diff --git a/gcc/testsuite/g++.dg/cpp23/explicit-obj-ops-non-mem-non-dep.C b/gcc/testsuite/g++.dg/cpp23/explicit-obj-ops-non-mem-non-dep.C new file mode 100644 index 0000000..634e878 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp23/explicit-obj-ops-non-mem-non-dep.C @@ -0,0 +1,57 @@ +// P0847R7 +// { dg-do compile { target c++23 } } + +// operators that are not required to be members +// called in a non-dependent context +// see header +#include "explicit-obj-ops-non-mem.h" + +// noop, indicates which versions are ill-formed +// I could not find a way to test the invalid cases +// without requires expressions +#define TEST_INVALID(X) + +void do_calls() +{ + Value value{}; + TEST_OPS(value) + TEST_OPS(static_cast<Value&&>(value)) + TEST_OPS(static_cast<Value const&>(value)) + TEST_OPS(static_cast<Value const&&>(value)) + + LRef l_ref{}; + TEST_OPS(l_ref) + TEST_INVALID(static_cast<LRef&&>(l_ref)) + TEST_INVALID(static_cast<LRef const&>(l_ref)) + TEST_INVALID(static_cast<LRef const&&>(l_ref)) + + RRef r_ref{}; + TEST_INVALID(r_ref) + TEST_OPS(static_cast<RRef&&>(r_ref)) + TEST_INVALID(static_cast<RRef const&>(r_ref)) + TEST_INVALID(static_cast<RRef const&&>(r_ref)) + + ConstLRef const_l_ref{}; + TEST_OPS(const_l_ref) + TEST_OPS(static_cast<ConstLRef&&>(const_l_ref)) + TEST_OPS(static_cast<ConstLRef const&>(const_l_ref)) + TEST_OPS(static_cast<ConstLRef const&&>(const_l_ref)) + + ConstRRef const_r_ref{}; + TEST_INVALID(const_r_ref) + TEST_OPS(static_cast<ConstRRef&&>(const_r_ref)) + TEST_INVALID(static_cast<ConstRRef const&>(const_r_ref)) + TEST_OPS(static_cast<ConstRRef const&&>(const_r_ref)) + + Deduced deduced{}; + TEST_OPS(deduced) + TEST_OPS(static_cast<Deduced&&>(deduced)) + TEST_OPS(static_cast<Deduced const&>(deduced)) + TEST_OPS(static_cast<Deduced const&&>(deduced)) + + VALIDATE_RETURN_TYPES(deduced, Deduced&) + VALIDATE_RETURN_TYPES(static_cast<Deduced&&>(deduced), Deduced&&) + VALIDATE_RETURN_TYPES(static_cast<Deduced const&>(deduced), Deduced const&) + VALIDATE_RETURN_TYPES(static_cast<Deduced const&&>(deduced), Deduced const&&) +} + diff --git a/gcc/testsuite/g++.dg/cpp23/explicit-obj-ops-non-mem.h b/gcc/testsuite/g++.dg/cpp23/explicit-obj-ops-non-mem.h new file mode 100644 index 0000000..b897a4b --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp23/explicit-obj-ops-non-mem.h @@ -0,0 +1,210 @@ +// tests for ops that must be member functions are seperate + +// the name of the class refers to the type of it's member functions xobj parameter + +#define MAKE_STRUCT_OPS(TYPE) \ + TYPE operator+=(this TYPE self, int) { return self; } \ + TYPE operator-=(this TYPE self, int) { return self; } \ + TYPE operator*=(this TYPE self, int) { return self; } \ + TYPE operator/=(this TYPE self, int) { return self; } \ + TYPE operator%=(this TYPE self, int) { return self; } \ + TYPE operator&=(this TYPE self, int) { return self; } \ + TYPE operator|=(this TYPE self, int) { return self; } \ + TYPE operator^=(this TYPE self, int) { return self; } \ + TYPE operator<<=(this TYPE self, int) { return self; } \ + TYPE operator>>=(this TYPE self, int) { return self; } \ + TYPE operator++(this TYPE self) { return self; } \ + TYPE operator--(this TYPE self) { return self; } \ + TYPE operator++(this TYPE self, int) { return self; } \ + TYPE operator--(this TYPE self, int) { return self; } \ + TYPE operator+(this TYPE self) { return self; } \ + TYPE operator-(this TYPE self) { return self; } \ + TYPE operator+(this TYPE self, int) { return self; } \ + TYPE operator-(this TYPE self, int) { return self; } \ + TYPE operator*(this TYPE self, int) { return self; } \ + TYPE operator/(this TYPE self, int) { return self; } \ + TYPE operator%(this TYPE self, int) { return self; } \ + TYPE operator&(this TYPE self, int) { return self; } \ + TYPE operator|(this TYPE self, int) { return self; } \ + TYPE operator^(this TYPE self, int) { return self; } \ + TYPE operator<<(this TYPE self, int) { return self; } \ + TYPE operator>>(this TYPE self, int) { return self; } \ + TYPE operator!(this TYPE self) { return self; } \ + TYPE operator&&(this TYPE self, int const&) { return self; } \ + TYPE operator||(this TYPE self, int const&) { return self; } \ + TYPE operator==(this TYPE self, int) { return self; } \ + TYPE operator!=(this TYPE self, int) { return self; } \ + TYPE operator<(this TYPE self, int) { return self; } \ + TYPE operator>(this TYPE self, int) { return self; } \ + TYPE operator<=(this TYPE self, int) { return self; } \ + TYPE operator>=(this TYPE self, int) { return self; } \ + TYPE operator<=>(this TYPE self, int) { return self; } \ + TYPE operator*(this TYPE self) { return self; } \ + TYPE operator->*(this TYPE self, int) { return self; } \ + TYPE operator&(this TYPE self) { return self; } \ + TYPE operator,(this TYPE self, int) { return self; } + +struct Value { + MAKE_STRUCT_OPS (Value) +}; + +struct LRef { + MAKE_STRUCT_OPS (LRef&) +}; + +struct RRef { + MAKE_STRUCT_OPS (RRef&&) +}; + +struct ConstLRef { + MAKE_STRUCT_OPS (ConstLRef const&) +}; + +struct ConstRRef { + MAKE_STRUCT_OPS (ConstRRef const&&) +}; + +#undef MAKE_STRUCT_OPS + +struct Deduced { + template<typename Self> Self&& operator+=(this Self&& self, int) { return static_cast<Self&&>(self); } + template<typename Self> Self&& operator-=(this Self&& self, int) { return static_cast<Self&&>(self); } + template<typename Self> Self&& operator*=(this Self&& self, int) { return static_cast<Self&&>(self); } + template<typename Self> Self&& operator/=(this Self&& self, int) { return static_cast<Self&&>(self); } + template<typename Self> Self&& operator%=(this Self&& self, int) { return static_cast<Self&&>(self); } + template<typename Self> Self&& operator&=(this Self&& self, int) { return static_cast<Self&&>(self); } + template<typename Self> Self&& operator|=(this Self&& self, int) { return static_cast<Self&&>(self); } + template<typename Self> Self&& operator^=(this Self&& self, int) { return static_cast<Self&&>(self); } + template<typename Self> Self&& operator<<=(this Self&& self, int) { return static_cast<Self&&>(self); } + template<typename Self> Self&& operator>>=(this Self&& self, int) { return static_cast<Self&&>(self); } + + template<typename Self> Self&& operator++(this Self&& self) { return static_cast<Self&&>(self); } + template<typename Self> Self&& operator--(this Self&& self) { return static_cast<Self&&>(self); } + template<typename Self> Self&& operator++(this Self&& self, int) { return static_cast<Self&&>(self); } + template<typename Self> Self&& operator--(this Self&& self, int) { return static_cast<Self&&>(self); } + + template<typename Self> Self&& operator+(this Self&& self) { return static_cast<Self&&>(self); } + template<typename Self> Self&& operator-(this Self&& self) { return static_cast<Self&&>(self); } + template<typename Self> Self&& operator+(this Self&& self, int) { return static_cast<Self&&>(self); } + template<typename Self> Self&& operator-(this Self&& self, int) { return static_cast<Self&&>(self); } + template<typename Self> Self&& operator*(this Self&& self, int) { return static_cast<Self&&>(self); } + template<typename Self> Self&& operator/(this Self&& self, int) { return static_cast<Self&&>(self); } + template<typename Self> Self&& operator%(this Self&& self, int) { return static_cast<Self&&>(self); } + template<typename Self> Self&& operator&(this Self&& self, int) { return static_cast<Self&&>(self); } + template<typename Self> Self&& operator|(this Self&& self, int) { return static_cast<Self&&>(self); } + template<typename Self> Self&& operator^(this Self&& self, int) { return static_cast<Self&&>(self); } + template<typename Self> Self&& operator<<(this Self&& self, int) { return static_cast<Self&&>(self); } + template<typename Self> Self&& operator>>(this Self&& self, int) { return static_cast<Self&&>(self); } + + template<typename Self> Self&& operator!(this Self&& self) { return static_cast<Self&&>(self); } + template<typename Self> Self&& operator&&(this Self&& self, int const&) { return static_cast<Self&&>(self); } + template<typename Self> Self&& operator||(this Self&& self, int const&) { return static_cast<Self&&>(self); } + + template<typename Self> Self&& operator==(this Self&& self, int) { return static_cast<Self&&>(self); } + template<typename Self> Self&& operator!=(this Self&& self, int) { return static_cast<Self&&>(self); } + template<typename Self> Self&& operator<(this Self&& self, int) { return static_cast<Self&&>(self); } + template<typename Self> Self&& operator>(this Self&& self, int) { return static_cast<Self&&>(self); } + template<typename Self> Self&& operator<=(this Self&& self, int) { return static_cast<Self&&>(self); } + template<typename Self> Self&& operator>=(this Self&& self, int) { return static_cast<Self&&>(self); } + template<typename Self> Self&& operator<=>(this Self&& self, int) { return static_cast<Self&&>(self); } + + template<typename Self> Self&& operator*(this Self&& self) { return static_cast<Self&&>(self); } + template<typename Self> Self&& operator->*(this Self&& self, int) { return static_cast<Self&&>(self); } + template<typename Self> Self&& operator&(this Self&& self) { return static_cast<Self&&>(self); } + template<typename Self> Self&& operator,(this Self&& self, int) { return static_cast<Self&&>(self); } +}; + +#define TEST_OPS(OPERAND) \ + (OPERAND) += 0; \ + (OPERAND) -= 0; \ + (OPERAND) *= 0; \ + (OPERAND) /= 0; \ + (OPERAND) %= 0; \ + (OPERAND) &= 0; \ + (OPERAND) |= 0; \ + (OPERAND) ^= 0; \ + (OPERAND) <<= 0; \ + (OPERAND) >>= 0; \ + \ + ++(OPERAND); \ + --(OPERAND); \ + (OPERAND)++; \ + (OPERAND)--; \ + \ + +(OPERAND); \ + -(OPERAND); \ + (OPERAND) + 0; \ + (OPERAND) - 0; \ + (OPERAND) * 0; \ + (OPERAND) / 0; \ + (OPERAND) % 0; \ + (OPERAND) & 0; \ + (OPERAND) | 0; \ + (OPERAND) ^ 0; \ + (OPERAND) << 0; \ + (OPERAND) >> 0; \ + \ + !(OPERAND); \ + (OPERAND) && 0; \ + (OPERAND) || 0; \ + \ + (OPERAND) == 0; \ + (OPERAND) != 0; \ + (OPERAND) < 0; \ + (OPERAND) > 0; \ + (OPERAND) <= 0; \ + (OPERAND) >= 0; \ + (OPERAND) <=> 0; \ + \ + *(OPERAND); \ + (OPERAND) ->* 0; \ + &(OPERAND); \ + (OPERAND), 0; + +#define VALIDATE_RETURN_TYPES(OPERAND, CORRECT_TYPE) \ + static_assert(__is_same(CORRECT_TYPE, decltype((OPERAND) += 0))); \ + static_assert(__is_same(CORRECT_TYPE, decltype((OPERAND) -= 0))); \ + static_assert(__is_same(CORRECT_TYPE, decltype((OPERAND) *= 0))); \ + static_assert(__is_same(CORRECT_TYPE, decltype((OPERAND) /= 0))); \ + static_assert(__is_same(CORRECT_TYPE, decltype((OPERAND) %= 0))); \ + static_assert(__is_same(CORRECT_TYPE, decltype((OPERAND) &= 0))); \ + static_assert(__is_same(CORRECT_TYPE, decltype((OPERAND) |= 0))); \ + static_assert(__is_same(CORRECT_TYPE, decltype((OPERAND) ^= 0))); \ + static_assert(__is_same(CORRECT_TYPE, decltype((OPERAND) <<= 0))); \ + static_assert(__is_same(CORRECT_TYPE, decltype((OPERAND) >>= 0))); \ + \ + static_assert(__is_same(CORRECT_TYPE, decltype(++(OPERAND)))); \ + static_assert(__is_same(CORRECT_TYPE, decltype(--(OPERAND)))); \ + static_assert(__is_same(CORRECT_TYPE, decltype((OPERAND)++))); \ + static_assert(__is_same(CORRECT_TYPE, decltype((OPERAND)--))); \ + \ + static_assert(__is_same(CORRECT_TYPE, decltype(+(OPERAND)))); \ + static_assert(__is_same(CORRECT_TYPE, decltype(-(OPERAND)))); \ + static_assert(__is_same(CORRECT_TYPE, decltype((OPERAND) + 0))); \ + static_assert(__is_same(CORRECT_TYPE, decltype((OPERAND) - 0))); \ + static_assert(__is_same(CORRECT_TYPE, decltype((OPERAND) * 0))); \ + static_assert(__is_same(CORRECT_TYPE, decltype((OPERAND) / 0))); \ + static_assert(__is_same(CORRECT_TYPE, decltype((OPERAND) % 0))); \ + static_assert(__is_same(CORRECT_TYPE, decltype((OPERAND) & 0))); \ + static_assert(__is_same(CORRECT_TYPE, decltype((OPERAND) | 0))); \ + static_assert(__is_same(CORRECT_TYPE, decltype((OPERAND) ^ 0))); \ + static_assert(__is_same(CORRECT_TYPE, decltype((OPERAND) << 0))); \ + static_assert(__is_same(CORRECT_TYPE, decltype((OPERAND) >> 0))); \ + \ + static_assert(__is_same(CORRECT_TYPE, decltype(!(OPERAND)))); \ + static_assert(__is_same(CORRECT_TYPE, decltype((OPERAND) && 0))); \ + static_assert(__is_same(CORRECT_TYPE, decltype((OPERAND) || 0))); \ + \ + static_assert(__is_same(CORRECT_TYPE, decltype((OPERAND) == 0))); \ + static_assert(__is_same(CORRECT_TYPE, decltype((OPERAND) != 0))); \ + static_assert(__is_same(CORRECT_TYPE, decltype((OPERAND) < 0))); \ + static_assert(__is_same(CORRECT_TYPE, decltype((OPERAND) > 0))); \ + static_assert(__is_same(CORRECT_TYPE, decltype((OPERAND) <= 0))); \ + static_assert(__is_same(CORRECT_TYPE, decltype((OPERAND) >= 0))); \ + static_assert(__is_same(CORRECT_TYPE, decltype((OPERAND) <=> 0))); \ + \ + static_assert(__is_same(CORRECT_TYPE, decltype(*(OPERAND)))); \ + static_assert(__is_same(CORRECT_TYPE, decltype((OPERAND) ->* 0))); \ + static_assert(__is_same(CORRECT_TYPE, decltype(&(OPERAND)))); \ + static_assert(__is_same(CORRECT_TYPE, decltype((OPERAND), 0))); + diff --git a/gcc/testsuite/g++.dg/cpp23/explicit-obj-ops-requires-mem.C b/gcc/testsuite/g++.dg/cpp23/explicit-obj-ops-requires-mem.C new file mode 100644 index 0000000..d08e938 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp23/explicit-obj-ops-requires-mem.C @@ -0,0 +1,171 @@ +// P0847R7 +// { dg-do compile { target c++23 } } + +// well-formed and ill-formed uses of member only operators in a requires expression + +// suppress the warning for Value's arrow operator +// { dg-options "-Wno-return-local-addr" } + +// It's very hard to test for incorrect successes without requires, and by extension a non dependent variable +// so for the time being, there are no non dependent tests invalid calls. + +struct Value { + int _v; + Value operator=(this Value self, int) { return self; } + Value operator()(this Value self) { return self; } + Value operator[](this Value self) { return self; } + Value* operator->(this Value self) { return &self; } +}; + +struct LRef { + int _v; + LRef& operator=(this LRef& self, int) { return self; } + LRef& operator()(this LRef& self) { return self; } + LRef& operator[](this LRef& self) { return self; } + LRef* operator->(this LRef& self) { return &self; } +}; + +struct RRef { + int _v; + RRef&& operator=(this RRef&& self, int) { return static_cast<RRef&&>(self); } + RRef&& operator()(this RRef&& self) { return static_cast<RRef&&>(self); } + RRef&& operator[](this RRef&& self) { return static_cast<RRef&&>(self); } + RRef* operator->(this RRef&& self) { return &self; } +}; + +struct ConstLRef { + int _v; + ConstLRef const& operator=(this ConstLRef const& self, int) { return self; } + ConstLRef const& operator()(this ConstLRef const& self) { return self; } + ConstLRef const& operator[](this ConstLRef const& self) { return self; } + ConstLRef const* operator->(this ConstLRef const& self) { return &self; } +}; + +struct ConstRRef { + int _v; + ConstRRef const&& operator=(this ConstRRef const&& self, int) { return static_cast<ConstRRef const&&>(self); } + ConstRRef const&& operator()(this ConstRRef const&& self) { return static_cast<ConstRRef const&&>(self); } + ConstRRef const&& operator[](this ConstRRef const&& self) { return static_cast<ConstRRef const&&>(self); } + ConstRRef const* operator->(this ConstRRef const&& self) { return &self; } +}; + +// needed to implement deduced operator-> +template<typename T> struct remove_ref { using type = T; }; +template<typename T> struct remove_ref<T&> { using type = T; }; +template<typename T> struct remove_ref<T&&> { using type = T; }; +template<typename T> using remove_ref_t = typename remove_ref<T>::type; + +struct Deduced { + int _v; + template<typename Self> + Self&& operator=(this Self&& self, int) { return static_cast<Self&&>(self); } + template<typename Self> + Self&& operator()(this Self&& self) { return static_cast<Self&&>(self); } + template<typename Self> + Self&& operator[](this Self&& self) { return static_cast<Self&&>(self); } + template<typename Self> + remove_ref_t<Self>* operator->(this Self&& self) { return &self; } +}; + +#define TEST_INVALID(OPERAND) \ + static_assert(!requires{ (OPERAND) = 0; }, "Unexpected success calling operator = with " #OPERAND); \ + static_assert(!requires{ (OPERAND)(); }, "Unexpected success calling operator () with " #OPERAND); \ + static_assert(!requires{ (OPERAND)[]; }, "Unexpected success calling operator [] with " #OPERAND); \ + static_assert(!requires{ (OPERAND)->_v; }, "Unexpected success calling operator -> with " #OPERAND); + +#define TEST_VALID(OPERAND) \ + static_assert(requires{ (OPERAND) = 0; }, "Unexpected failure calling operator = with " #OPERAND); \ + static_assert(requires{ (OPERAND)(); }, "Unexpected failure calling operator () with " #OPERAND); \ + static_assert(requires{ (OPERAND)[]; }, "Unexpected failure calling operator [] with " #OPERAND); \ + static_assert(requires{ (OPERAND)->_v; }, "Unexpected failure calling operator -> with " #OPERAND); + +template<typename T, typename U> +concept same_as = __is_same(T, U); + +#define TEST_VALID_WITH_RETURN_TYPES(OPERAND, CORRECT_TYPE) \ + static_assert(requires{ {(OPERAND) = 0} -> same_as<CORRECT_TYPE>; },"Unexpected failure with return type check calling operator = with " #OPERAND " -> expected return type: " #CORRECT_TYPE); \ + static_assert(requires{ {(OPERAND)()} -> same_as<CORRECT_TYPE>; }, "Unexpected failure with return type check calling operator () with " #OPERAND " -> expected return type: " #CORRECT_TYPE); \ + static_assert(requires{ {(OPERAND)[]} -> same_as<CORRECT_TYPE>; }, "Unexpected failure with return type check calling operator [] with " #OPERAND " -> expected return type: " #CORRECT_TYPE); + + +template<typename DepValue = Value> +void test_value() +{ + DepValue value{}; + TEST_VALID(value) + TEST_VALID(static_cast<DepValue&&>(value)) + TEST_VALID(static_cast<DepValue const&>(value)) + TEST_VALID(static_cast<DepValue const&&>(value)) +} + +template<typename DepLRef = LRef> +void test_l_ref() +{ + DepLRef l_ref{}; + TEST_VALID(l_ref) + TEST_INVALID(static_cast<DepLRef&&>(l_ref)) + TEST_INVALID(static_cast<DepLRef const&>(l_ref)) + TEST_INVALID(static_cast<DepLRef const&&>(l_ref)) +} + +template<typename DepRRef = RRef> +void test_r_ref() +{ + DepRRef r_ref{}; + TEST_INVALID(r_ref) + TEST_VALID(static_cast<DepRRef&&>(r_ref)) + TEST_INVALID(static_cast<DepRRef const&>(r_ref)) + TEST_INVALID(static_cast<DepRRef const&&>(r_ref)) +} + +template<typename DepConstLRef = ConstLRef> +void test_const_l_ref() +{ + DepConstLRef const_l_ref{}; + TEST_VALID(const_l_ref) + TEST_VALID(static_cast<DepConstLRef&&>(const_l_ref)) + TEST_VALID(static_cast<DepConstLRef const&>(const_l_ref)) + TEST_VALID(static_cast<DepConstLRef const&&>(const_l_ref)) +} + +template<typename DepConstRRef = ConstRRef> +void test_const_r_ref() +{ + DepConstRRef const_r_ref{}; + TEST_INVALID(const_r_ref) + TEST_VALID(static_cast<DepConstRRef&&>(const_r_ref)) + TEST_INVALID(static_cast<DepConstRRef const&>(const_r_ref)) + TEST_VALID(static_cast<DepConstRRef const&&>(const_r_ref)) +} + +template<typename DepDeduced = Deduced> +void test_deduced() +{ + DepDeduced deduced{}; + + TEST_VALID(deduced) + TEST_VALID(static_cast<DepDeduced&&>(deduced)) + TEST_VALID(static_cast<DepDeduced const&>(deduced)) + TEST_VALID(static_cast<DepDeduced const&&>(deduced)) + + TEST_VALID_WITH_RETURN_TYPES(deduced, DepDeduced&) + TEST_VALID_WITH_RETURN_TYPES(static_cast<DepDeduced&&>(deduced), DepDeduced&&) + TEST_VALID_WITH_RETURN_TYPES(static_cast<DepDeduced const&>(deduced), DepDeduced const&) + TEST_VALID_WITH_RETURN_TYPES(static_cast<DepDeduced const&&>(deduced), DepDeduced const&&) + // arrow operator needs to be seperate to check the type of _v + static_assert(requires{ {(deduced->_v)} -> same_as<int&>; }, "Unexpected failure with return type check calling operator -> with deduced->_v"); + static_assert(requires{ {(static_cast<DepDeduced&&>(deduced)->_v)} -> same_as<int&>; }, "Unexpected failure with return type check calling operator -> with static_cast<DepDeduced&&>(deduced)->_v"); + static_assert(requires{ {(static_cast<DepDeduced const&>(deduced)->_v)} -> same_as<int const&>; }, "Unexpected failure with return type check calling operator -> with static_cast<DepDeduced const&>(deduced)->_v"); + static_assert(requires{ {(static_cast<DepDeduced const&&>(deduced)->_v)} -> same_as<int const&>; }, "Unexpected failure with return type check calling operator -> with static_cast<DepDeduced const&&>(deduced)->_v"); +} + +void test() +{ + test_value(); + test_l_ref(); + test_r_ref(); + test_const_l_ref(); + test_const_r_ref(); + test_deduced(); +} + diff --git a/gcc/testsuite/g++.dg/cpp23/explicit-obj-ops-requires-non-mem.C b/gcc/testsuite/g++.dg/cpp23/explicit-obj-ops-requires-non-mem.C new file mode 100644 index 0000000..865b1f5 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp23/explicit-obj-ops-requires-non-mem.C @@ -0,0 +1,237 @@ +// P0847R7 +// { dg-do compile { target c++23 } } + +// well-formed and ill-formed uses of non-member capable operators in a requires expression + +#include "explicit-obj-ops-non-mem.h" + +// we only need the structs from the header +#undef TEST_OPS +#undef VALIDATE_RETURN_TYPES + +// It's very hard to test for incorrect successes without requires, and by extension a non dependent variable +// so for the time being, there are no non dependent tests invalid calls. + +template<typename T, typename U> +concept same_as = __is_same(T, U); + +#define TEST_INVALID(OPERAND, CORRECT_TYPE) \ + static_assert(!requires{ (OPERAND) += 0; }, "Unexpected success calling operator += with " #OPERAND); \ + static_assert(!requires{ (OPERAND) -= 0; }, "Unexpected success calling operator -= with " #OPERAND); \ + static_assert(!requires{ (OPERAND) *= 0; }, "Unexpected success calling operator *= with " #OPERAND); \ + static_assert(!requires{ (OPERAND) /= 0; }, "Unexpected success calling operator /= with " #OPERAND); \ + static_assert(!requires{ (OPERAND) %= 0; }, "Unexpected success calling operator %= with " #OPERAND); \ + static_assert(!requires{ (OPERAND) &= 0; }, "Unexpected success calling operator &= with " #OPERAND); \ + static_assert(!requires{ (OPERAND) |= 0; }, "Unexpected success calling operator |= with " #OPERAND); \ + static_assert(!requires{ (OPERAND) ^= 0; }, "Unexpected success calling operator ^= with " #OPERAND); \ + static_assert(!requires{ (OPERAND) <<= 0; }, "Unexpected success calling operator <<= with " #OPERAND); \ + static_assert(!requires{ (OPERAND) >>= 0; }, "Unexpected success calling operator >>= with " #OPERAND); \ + \ + static_assert(!requires{ ++(OPERAND); }, "Unexpected success calling operator pre++ with " #OPERAND); \ + static_assert(!requires{ --(OPERAND); }, "Unexpected success calling operator pre-- with " #OPERAND); \ + static_assert(!requires{ (OPERAND)++; }, "Unexpected success calling operator post++ with " #OPERAND); \ + static_assert(!requires{ (OPERAND)--; }, "Unexpected success calling operator post-- with " #OPERAND); \ + \ + static_assert(!requires{ +(OPERAND); }, "Unexpected success calling operator unary+ with " #OPERAND); \ + static_assert(!requires{ -(OPERAND); }, "Unexpected success calling operator unary- with " #OPERAND); \ + static_assert(!requires{ (OPERAND) + 0; }, "Unexpected success calling operator binary+ with " #OPERAND); \ + static_assert(!requires{ (OPERAND) - 0; }, "Unexpected success calling operator binary- with " #OPERAND); \ + static_assert(!requires{ (OPERAND) * 0; }, "Unexpected success calling operator binary* with " #OPERAND); \ + static_assert(!requires{ (OPERAND) / 0; }, "Unexpected success calling operator / with " #OPERAND); \ + static_assert(!requires{ (OPERAND) % 0; }, "Unexpected success calling operator % with " #OPERAND); \ + static_assert(!requires{ (OPERAND) & 0; }, "Unexpected success calling operator binary& with " #OPERAND); \ + static_assert(!requires{ (OPERAND) | 0; }, "Unexpected success calling operator | with " #OPERAND); \ + static_assert(!requires{ (OPERAND) ^ 0; }, "Unexpected success calling operator ^ with " #OPERAND); \ + static_assert(!requires{ (OPERAND) << 0; }, "Unexpected success calling operator << with " #OPERAND); \ + static_assert(!requires{ (OPERAND) >> 0; }, "Unexpected success calling operator >> with " #OPERAND); \ + \ + static_assert(!requires{ !(OPERAND); }, "Unexpected success calling operator ! with " #OPERAND); \ + static_assert(!requires{ (OPERAND) && 0; }, "Unexpected success calling operator && with " #OPERAND); \ + static_assert(!requires{ (OPERAND) || 0; }, "Unexpected success calling operator || with " #OPERAND); \ + \ + static_assert(!requires{ (OPERAND) == 0; }, "Unexpected success calling operator == with " #OPERAND); \ + static_assert(!requires{ (OPERAND) != 0; }, "Unexpected success calling operator != with " #OPERAND); \ + static_assert(!requires{ (OPERAND) < 0; }, "Unexpected success calling operator < with " #OPERAND); \ + static_assert(!requires{ (OPERAND) > 0; }, "Unexpected success calling operator > with " #OPERAND); \ + static_assert(!requires{ (OPERAND) <= 0; }, "Unexpected success calling operator <= with " #OPERAND); \ + static_assert(!requires{ (OPERAND) >= 0; }, "Unexpected success calling operator >= with " #OPERAND); \ + static_assert(!requires{ (OPERAND) <=> 0; }, "Unexpected success calling operator <=> with " #OPERAND); \ + \ + static_assert(!requires{ *(OPERAND); }, "Unexpected success calling operator unary* with " #OPERAND); \ + static_assert(!requires{ (OPERAND) ->* 0; }, "Unexpected success calling operator ->* with " #OPERAND); \ + /* We need to check the return type to confirm the built-in operator was not selected. */ \ + static_assert(!requires{ {&(OPERAND)} -> same_as<CORRECT_TYPE>; }, \ + "Unexpected success calling operator unary& with " #OPERAND); \ + static_assert(!requires{ {(OPERAND), 0} -> same_as<CORRECT_TYPE>; }, \ + "Unexpected success calling operator , with " #OPERAND); + +#define TEST_VALID(OPERAND, CORRECT_TYPE) \ + static_assert(requires{ (OPERAND) += 0; }, "Unexpected failure calling operator += with " #OPERAND); \ + static_assert(requires{ (OPERAND) -= 0; }, "Unexpected failure calling operator -= with " #OPERAND); \ + static_assert(requires{ (OPERAND) *= 0; }, "Unexpected failure calling operator *= with " #OPERAND); \ + static_assert(requires{ (OPERAND) /= 0; }, "Unexpected failure calling operator /= with " #OPERAND); \ + static_assert(requires{ (OPERAND) %= 0; }, "Unexpected failure calling operator %= with " #OPERAND); \ + static_assert(requires{ (OPERAND) &= 0; }, "Unexpected failure calling operator &= with " #OPERAND); \ + static_assert(requires{ (OPERAND) |= 0; }, "Unexpected failure calling operator |= with " #OPERAND); \ + static_assert(requires{ (OPERAND) ^= 0; }, "Unexpected failure calling operator ^= with " #OPERAND); \ + static_assert(requires{ (OPERAND) <<= 0; }, "Unexpected failure calling operator <<= with " #OPERAND); \ + static_assert(requires{ (OPERAND) >>= 0; }, "Unexpected failure calling operator >>= with " #OPERAND); \ + \ + static_assert(requires{ ++(OPERAND); }, "Unexpected failure calling operator pre++ with " #OPERAND); \ + static_assert(requires{ --(OPERAND); }, "Unexpected failure calling operator pre-- with " #OPERAND); \ + static_assert(requires{ (OPERAND)++; }, "Unexpected failure calling operator post++ with " #OPERAND); \ + static_assert(requires{ (OPERAND)--; }, "Unexpected failure calling operator post-- with " #OPERAND); \ + \ + static_assert(requires{ +(OPERAND); }, "Unexpected failure calling operator unary+ with " #OPERAND); \ + static_assert(requires{ -(OPERAND); }, "Unexpected failure calling operator unary- with " #OPERAND); \ + static_assert(requires{ (OPERAND) + 0; }, "Unexpected failure calling operator binary+ with " #OPERAND); \ + static_assert(requires{ (OPERAND) - 0; }, "Unexpected failure calling operator binary- with " #OPERAND); \ + static_assert(requires{ (OPERAND) * 0; }, "Unexpected failure calling operator binary* with " #OPERAND); \ + static_assert(requires{ (OPERAND) / 0; }, "Unexpected failure calling operator / with " #OPERAND); \ + static_assert(requires{ (OPERAND) % 0; }, "Unexpected failure calling operator % with " #OPERAND); \ + static_assert(requires{ (OPERAND) & 0; }, "Unexpected failure calling operator binary& with " #OPERAND); \ + static_assert(requires{ (OPERAND) | 0; }, "Unexpected failure calling operator | with " #OPERAND); \ + static_assert(requires{ (OPERAND) ^ 0; }, "Unexpected failure calling operator ^ with " #OPERAND); \ + static_assert(requires{ (OPERAND) << 0; }, "Unexpected failure calling operator << with " #OPERAND); \ + static_assert(requires{ (OPERAND) >> 0; }, "Unexpected failure calling operator >> with " #OPERAND); \ + \ + static_assert(requires{ !(OPERAND); }, "Unexpected failure calling operator ! with " #OPERAND); \ + static_assert(requires{ (OPERAND) && 0; }, "Unexpected failure calling operator && with " #OPERAND); \ + static_assert(requires{ (OPERAND) || 0; }, "Unexpected failure calling operator || with " #OPERAND); \ + \ + static_assert(requires{ (OPERAND) == 0; }, "Unexpected failure calling operator == with " #OPERAND); \ + static_assert(requires{ (OPERAND) != 0; }, "Unexpected failure calling operator != with " #OPERAND); \ + static_assert(requires{ (OPERAND) < 0; }, "Unexpected failure calling operator < with " #OPERAND); \ + static_assert(requires{ (OPERAND) > 0; }, "Unexpected failure calling operator > with " #OPERAND); \ + static_assert(requires{ (OPERAND) <= 0; }, "Unexpected failure calling operator <= with " #OPERAND); \ + static_assert(requires{ (OPERAND) >= 0; }, "Unexpected failure calling operator >= with " #OPERAND); \ + static_assert(requires{ (OPERAND) <=> 0; }, "Unexpected failure calling operator <=> with " #OPERAND); \ + \ + static_assert(requires{ *(OPERAND); }, "Unexpected failure calling operator unary* with " #OPERAND); \ + static_assert(requires{ (OPERAND) ->* 0; }, "Unexpected failure calling operator ->* with " #OPERAND); \ + /* We need to check the return type to confirm we selected our overload, not the built-in operator. */ \ + static_assert(requires{ {&(OPERAND)} -> same_as<CORRECT_TYPE>; }, \ + "Unexpected failure calling operator unary& with " #OPERAND); \ + static_assert(requires{ {(OPERAND), 0} -> same_as<CORRECT_TYPE>; }, \ + "Unexpected failure calling operator , with " #OPERAND); + +// Return types need to be tested for the deduced case + +#define TEST_VALID_WITH_RETURN_TYPES(OPERAND, CORRECT_TYPE) \ + static_assert(requires{ {(OPERAND) += 0} -> same_as<CORRECT_TYPE>; }); \ + static_assert(requires{ {(OPERAND) -= 0} -> same_as<CORRECT_TYPE>; }); \ + static_assert(requires{ {(OPERAND) *= 0} -> same_as<CORRECT_TYPE>; }); \ + static_assert(requires{ {(OPERAND) /= 0} -> same_as<CORRECT_TYPE>; }); \ + static_assert(requires{ {(OPERAND) %= 0} -> same_as<CORRECT_TYPE>; }); \ + static_assert(requires{ {(OPERAND) &= 0} -> same_as<CORRECT_TYPE>; }); \ + static_assert(requires{ {(OPERAND) |= 0} -> same_as<CORRECT_TYPE>; }); \ + static_assert(requires{ {(OPERAND) ^= 0} -> same_as<CORRECT_TYPE>; }); \ + static_assert(requires{ {(OPERAND) <<= 0} -> same_as<CORRECT_TYPE>; }); \ + static_assert(requires{ {(OPERAND) >>= 0} -> same_as<CORRECT_TYPE>; }); \ + \ + static_assert(requires{ {++(OPERAND)} -> same_as<CORRECT_TYPE>; }); \ + static_assert(requires{ {--(OPERAND)} -> same_as<CORRECT_TYPE>; }); \ + static_assert(requires{ {(OPERAND)++} -> same_as<CORRECT_TYPE>; }); \ + static_assert(requires{ {(OPERAND)--} -> same_as<CORRECT_TYPE>; }); \ + \ + static_assert(requires{ {+(OPERAND)} -> same_as<CORRECT_TYPE>; }); \ + static_assert(requires{ {-(OPERAND)} -> same_as<CORRECT_TYPE>; }); \ + static_assert(requires{ {(OPERAND) + 0} -> same_as<CORRECT_TYPE>; }); \ + static_assert(requires{ {(OPERAND) - 0} -> same_as<CORRECT_TYPE>; }); \ + static_assert(requires{ {(OPERAND) * 0} -> same_as<CORRECT_TYPE>; }); \ + static_assert(requires{ {(OPERAND) / 0} -> same_as<CORRECT_TYPE>; }); \ + static_assert(requires{ {(OPERAND) % 0} -> same_as<CORRECT_TYPE>; }); \ + static_assert(requires{ {(OPERAND) & 0} -> same_as<CORRECT_TYPE>; }); \ + static_assert(requires{ {(OPERAND) | 0} -> same_as<CORRECT_TYPE>; }); \ + static_assert(requires{ {(OPERAND) ^ 0} -> same_as<CORRECT_TYPE>; }); \ + static_assert(requires{ {(OPERAND) << 0} -> same_as<CORRECT_TYPE>; }); \ + static_assert(requires{ {(OPERAND) >> 0} -> same_as<CORRECT_TYPE>; }); \ + \ + static_assert(requires{ {!(OPERAND)} -> same_as<CORRECT_TYPE>; }); \ + static_assert(requires{ {(OPERAND) && 0} -> same_as<CORRECT_TYPE>; }); \ + static_assert(requires{ {(OPERAND) || 0} -> same_as<CORRECT_TYPE>; }); \ + \ + static_assert(requires{ {(OPERAND) == 0} -> same_as<CORRECT_TYPE>; }); \ + static_assert(requires{ {(OPERAND) != 0} -> same_as<CORRECT_TYPE>; }); \ + static_assert(requires{ {(OPERAND) < 0} -> same_as<CORRECT_TYPE>; }); \ + static_assert(requires{ {(OPERAND) > 0} -> same_as<CORRECT_TYPE>; }); \ + static_assert(requires{ {(OPERAND) <= 0} -> same_as<CORRECT_TYPE>; }); \ + static_assert(requires{ {(OPERAND) >= 0} -> same_as<CORRECT_TYPE>; }); \ + static_assert(requires{ {(OPERAND) <=> 0} -> same_as<CORRECT_TYPE>; }); \ + \ + static_assert(requires{ {*(OPERAND)} -> same_as<CORRECT_TYPE>; }); \ + static_assert(requires{ {(OPERAND) ->* 0} -> same_as<CORRECT_TYPE>; }); \ + static_assert(requires{ {&(OPERAND)} -> same_as<CORRECT_TYPE>; }); \ + static_assert(requires{ {(OPERAND), 0} -> same_as<CORRECT_TYPE>; }); + +template<typename DepValue = Value> +void test_value() +{ + DepValue value{}; + TEST_VALID(value, DepValue) + TEST_VALID(static_cast<DepValue&&>(value), DepValue) + TEST_VALID(static_cast<DepValue const&>(value), DepValue) + TEST_VALID(static_cast<DepValue const&&>(value), DepValue) +} + +template<typename DepLRef = LRef> +void test_l_ref() +{ + DepLRef l_ref{}; + TEST_VALID(l_ref, DepLRef&) + TEST_INVALID(static_cast<DepLRef&&>(l_ref), DepLRef&) + TEST_INVALID(static_cast<DepLRef const&>(l_ref), DepLRef&) + TEST_INVALID(static_cast<DepLRef const&&>(l_ref), DepLRef&) +} + +template<typename DepRRef = RRef> +void test_r_ref() +{ + DepRRef r_ref{}; + TEST_INVALID(r_ref, DepRRef&&) + TEST_VALID(static_cast<DepRRef&&>(r_ref), DepRRef&&) + TEST_INVALID(static_cast<DepRRef const&>(r_ref), DepRRef&&) + TEST_INVALID(static_cast<DepRRef const&&>(r_ref), DepRRef&&) +} + +template<typename DepConstLRef = ConstLRef> +void test_const_l_ref() +{ + DepConstLRef const_l_ref{}; + TEST_VALID(const_l_ref, DepConstLRef const&) + TEST_VALID(static_cast<DepConstLRef&&>(const_l_ref), DepConstLRef const&) + TEST_VALID(static_cast<DepConstLRef const&>(const_l_ref), DepConstLRef const&) + TEST_VALID(static_cast<DepConstLRef const&&>(const_l_ref), DepConstLRef const&) +} + +template<typename DepConstRRef = ConstRRef> +void test_const_r_ref() +{ + DepConstRRef const_r_ref{}; + TEST_INVALID(const_r_ref, DepConstRRef const&&) + TEST_VALID(static_cast<DepConstRRef&&>(const_r_ref), DepConstRRef const&&) + TEST_INVALID(static_cast<DepConstRRef const&>(const_r_ref), DepConstRRef const&&) + TEST_VALID(static_cast<DepConstRRef const&&>(const_r_ref), DepConstRRef const&&) +} + +template<typename DepDeduced = Deduced> +void test_deduced() +{ + DepDeduced deduced{}; + + TEST_VALID_WITH_RETURN_TYPES(deduced, DepDeduced&) + TEST_VALID_WITH_RETURN_TYPES(static_cast<DepDeduced&&>(deduced), DepDeduced&&) + TEST_VALID_WITH_RETURN_TYPES(static_cast<DepDeduced const&>(deduced), DepDeduced const&) + TEST_VALID_WITH_RETURN_TYPES(static_cast<DepDeduced const&&>(deduced), DepDeduced const&&) +} + +void test() +{ + test_value(); + test_l_ref(); + test_r_ref(); + test_const_l_ref(); + test_const_r_ref(); + test_deduced(); +} + diff --git a/gcc/testsuite/g++.dg/cpp23/explicit-obj-redecl.C b/gcc/testsuite/g++.dg/cpp23/explicit-obj-redecl.C new file mode 100644 index 0000000..7fcfcc3 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp23/explicit-obj-redecl.C @@ -0,0 +1,246 @@ +// P0847R7 +// { dg-do compile { target c++23 } } + +// redeclarations of xobj/iobj member functions where the iobj member function +// is not ref qualified + +// it does not make sense to check for the inverse in this test (7 iobj, 1 xobj) +// because you are not allowed to overload iobj member functions without ref qualifiers +// with iobj member functions that do (and vice versa) + +// iobj first + +struct S0 { + void f0(); // { dg-note "previous declaration" } + void f0(this S0 &&); // { dg-error "cannot be overloaded with" } + void f0(this S0 const&); // { dg-bogus "" } + void f0(this S0 const&&); // { dg-bogus "" } + void f0(this S0 volatile&); // { dg-bogus "" } + void f0(this S0 volatile&&); // { dg-bogus "" } + void f0(this S0 const volatile&); // { dg-bogus "" } + void f0(this S0 const volatile&&); // { dg-bogus "" } + + void f1(); // { dg-note "previous declaration" } + void f1(this S0 &); // { dg-error "cannot be overloaded with" } + void f1(this S0 const&); // { dg-bogus "" } + void f1(this S0 const&&); // { dg-bogus "" } + void f1(this S0 volatile&); // { dg-bogus "" } + void f1(this S0 volatile&&); // { dg-bogus "" } + void f1(this S0 const volatile&); // { dg-bogus "" } + void f1(this S0 const volatile&&); // { dg-bogus "" } + + void fc0() const; // { dg-note "previous declaration" } + void fc0(this S0 &); // { dg-bogus "" } + void fc0(this S0 &&); // { dg-bogus "" } + void fc0(this S0 const&&); // { dg-error "cannot be overloaded with" } + void fc0(this S0 volatile&); // { dg-bogus "" } + void fc0(this S0 volatile&&); // { dg-bogus "" } + void fc0(this S0 const volatile&); // { dg-bogus "" } + void fc0(this S0 const volatile&&); // { dg-bogus "" } + + void fc1() const; // { dg-note "previous declaration" } + void fc1(this S0 &); // { dg-bogus "" } + void fc1(this S0 &&); // { dg-bogus "" } + void fc1(this S0 const&); // { dg-error "cannot be overloaded with" } + void fc1(this S0 volatile&); // { dg-bogus "" } + void fc1(this S0 volatile&&); // { dg-bogus "" } + void fc1(this S0 const volatile&); // { dg-bogus "" } + void fc1(this S0 const volatile&&); // { dg-bogus "" } + + void fv0() volatile; // { dg-note "previous declaration" } + void fv0(this S0 &); // { dg-bogus "" } + void fv0(this S0 &&); // { dg-bogus "" } + void fv0(this S0 const&); // { dg-bogus "" } + void fv0(this S0 const&&); // { dg-bogus "" } + void fv0(this S0 volatile&&); // { dg-error "cannot be overloaded with" } + void fv0(this S0 const volatile&); // { dg-bogus "" } + void fv0(this S0 const volatile&&); // { dg-bogus "" } + + void fv1() volatile; // { dg-note "previous declaration" } + void fv1(this S0 &); // { dg-bogus "" } + void fv1(this S0 &&); // { dg-bogus "" } + void fv1(this S0 const&); // { dg-bogus "" } + void fv1(this S0 const&&); // { dg-bogus "" } + void fv1(this S0 volatile&); // { dg-error "cannot be overloaded with" } + void fv1(this S0 const volatile&); // { dg-bogus "" } + void fv1(this S0 const volatile&&); // { dg-bogus "" } + + void fcv0() const volatile; // { dg-note "previous declaration" } + void fcv0(this S0 &); // { dg-bogus "" } + void fcv0(this S0 &&); // { dg-bogus "" } + void fcv0(this S0 const&); // { dg-bogus "" } + void fcv0(this S0 const&&); // { dg-bogus "" } + void fcv0(this S0 volatile&); // { dg-bogus "" } + void fcv0(this S0 volatile&&); // { dg-bogus "" } + void fcv0(this S0 const volatile&&); // { dg-error "cannot be overloaded with" } + + void fcv1() const volatile; // { dg-note "previous declaration" } + void fcv1(this S0 &); // { dg-bogus "" } + void fcv1(this S0 &&); // { dg-bogus "" } + void fcv1(this S0 const&); // { dg-bogus "" } + void fcv1(this S0 const&&); // { dg-bogus "" } + void fcv1(this S0 volatile&); // { dg-bogus "" } + void fcv1(this S0 volatile&&); // { dg-bogus "" } + void fcv1(this S0 const volatile&); // { dg-error "cannot be overloaded with" } +}; + +// iobj last + +struct S1 { + void f0(this S1 &&); // { dg-note "previous declaration" } + void f0(this S1 const&); // { dg-bogus "" } + void f0(this S1 const&&); // { dg-bogus "" } + void f0(this S1 volatile&); // { dg-bogus "" } + void f0(this S1 volatile&&); // { dg-bogus "" } + void f0(this S1 const volatile&); // { dg-bogus "" } + void f0(this S1 const volatile&&); // { dg-bogus "" } + void f0(); // { dg-error "cannot be overloaded with" } + + void f1(this S1 &); // { dg-note "previous declaration" } + void f1(this S1 const&); // { dg-bogus "" } + void f1(this S1 const&&); // { dg-bogus "" } + void f1(this S1 volatile&); // { dg-bogus "" } + void f1(this S1 volatile&&); // { dg-bogus "" } + void f1(this S1 const volatile&); // { dg-bogus "" } + void f1(this S1 const volatile&&); // { dg-bogus "" } + void f1(); // { dg-error "cannot be overloaded with" } + + void fc0(this S1 &); // { dg-bogus "" } + void fc0(this S1 &&); // { dg-bogus "" } + void fc0(this S1 const&&); // { dg-note "previous declaration" } + void fc0(this S1 volatile&); // { dg-bogus "" } + void fc0(this S1 volatile&&); // { dg-bogus "" } + void fc0(this S1 const volatile&); // { dg-bogus "" } + void fc0(this S1 const volatile&&); // { dg-bogus "" } + void fc0() const; // { dg-error "cannot be overloaded with" } + + void fc1(this S1 &); // { dg-bogus "" } + void fc1(this S1 &&); // { dg-bogus "" } + void fc1(this S1 const&); // { dg-note "previous declaration" } + void fc1(this S1 volatile&); // { dg-bogus "" } + void fc1(this S1 volatile&&); // { dg-bogus "" } + void fc1(this S1 const volatile&); // { dg-bogus "" } + void fc1(this S1 const volatile&&); // { dg-bogus "" } + void fc1() const; // { dg-error "cannot be overloaded with" } + + void fv0(this S1 &); // { dg-bogus "" } + void fv0(this S1 &&); // { dg-bogus "" } + void fv0(this S1 const&); // { dg-bogus "" } + void fv0(this S1 const&&); // { dg-bogus "" } + void fv0(this S1 volatile&&); // { dg-note "previous declaration" } + void fv0(this S1 const volatile&); // { dg-bogus "" } + void fv0(this S1 const volatile&&); // { dg-bogus "" } + void fv0() volatile; // { dg-error "cannot be overloaded with" } + + void fv1(this S1 &); // { dg-bogus "" } + void fv1(this S1 &&); // { dg-bogus "" } + void fv1(this S1 const&); // { dg-bogus "" } + void fv1(this S1 const&&); // { dg-bogus "" } + void fv1(this S1 volatile&); // { dg-note "previous declaration" } + void fv1(this S1 const volatile&); // { dg-bogus "" } + void fv1(this S1 const volatile&&); // { dg-bogus "" } + void fv1() volatile; // { dg-error "cannot be overloaded with" } + + void fcv0(this S1 &); // { dg-bogus "" } + void fcv0(this S1 &&); // { dg-bogus "" } + void fcv0(this S1 const&); // { dg-bogus "" } + void fcv0(this S1 const&&); // { dg-bogus "" } + void fcv0(this S1 volatile&); // { dg-bogus "" } + void fcv0(this S1 volatile&&); // { dg-bogus "" } + void fcv0(this S1 const volatile&&); // { dg-note "previous declaration" } + void fcv0() const volatile; // { dg-error "cannot be overloaded with" } + + void fcv1(this S1 &); // { dg-bogus "" } + void fcv1(this S1 &&); // { dg-bogus "" } + void fcv1(this S1 const&); // { dg-bogus "" } + void fcv1(this S1 const&&); // { dg-bogus "" } + void fcv1(this S1 volatile&); // { dg-bogus "" } + void fcv1(this S1 volatile&&); // { dg-bogus "" } + void fcv1(this S1 const volatile&); // { dg-note "previous declaration" } + void fcv1() const volatile; // { dg-error "cannot be overloaded with" } +}; + +// in order (iobj replacing one of the following in each group) +// lvalue ref to S +// rvalue ref to S +// lvalue c ref to S +// rvalue c ref to S +// lvalue v ref to S +// rvalue v ref to S +// lvalue cv ref to S +// rvalue cv ref to S + +struct S2 { + void f0(); // { dg-note "previous declaration" } + void f0(this S2 &&); // { dg-error "cannot be overloaded with" } + void f0(this S2 const&); // { dg-bogus "" } + void f0(this S2 const&&); // { dg-bogus "" } + void f0(this S2 volatile&); // { dg-bogus "" } + void f0(this S2 volatile&&); // { dg-bogus "" } + void f0(this S2 const volatile&); // { dg-bogus "" } + void f0(this S2 const volatile&&); // { dg-bogus "" } + + void f1(this S2 &); // { dg-note "previous declaration" } + void f1(); // { dg-error "cannot be overloaded with" } + void f1(this S2 const&); // { dg-bogus "" } + void f1(this S2 const&&); // { dg-bogus "" } + void f1(this S2 volatile&); // { dg-bogus "" } + void f1(this S2 volatile&&); // { dg-bogus "" } + void f1(this S2 const volatile&); // { dg-bogus "" } + void f1(this S2 const volatile&&); // { dg-bogus "" } + + void fc0(this S2 &); // { dg-bogus "" } + void fc0(this S2 &&); // { dg-bogus "" } + void fc0() const; // { dg-note "previous declaration" } + void fc0(this S2 const&&); // { dg-error "cannot be overloaded with" } + void fc0(this S2 volatile&); // { dg-bogus "" } + void fc0(this S2 volatile&&); // { dg-bogus "" } + void fc0(this S2 const volatile&); // { dg-bogus "" } + void fc0(this S2 const volatile&&); // { dg-bogus "" } + + void fc1(this S2 &); // { dg-bogus "" } + void fc1(this S2 &&); // { dg-bogus "" } + void fc1(this S2 const&); // { dg-note "previous declaration" } + void fc1() const; // { dg-error "cannot be overloaded with" } + void fc1(this S2 volatile&); // { dg-bogus "" } + void fc1(this S2 volatile&&); // { dg-bogus "" } + void fc1(this S2 const volatile&); // { dg-bogus "" } + void fc1(this S2 const volatile&&); // { dg-bogus "" } + + void fv0(this S2 &); // { dg-bogus "" } + void fv0(this S2 &&); // { dg-bogus "" } + void fv0(this S2 const&); // { dg-bogus "" } + void fv0(this S2 const&&); // { dg-bogus "" } + void fv0() volatile; // { dg-note "previous declaration" } + void fv0(this S2 volatile&&); // { dg-error "cannot be overloaded with" } + void fv0(this S2 const volatile&); // { dg-bogus "" } + void fv0(this S2 const volatile&&); // { dg-bogus "" } + + void fv1(this S2 &); // { dg-bogus "" } + void fv1(this S2 &&); // { dg-bogus "" } + void fv1(this S2 const&); // { dg-bogus "" } + void fv1(this S2 const&&); // { dg-bogus "" } + void fv1(this S2 volatile&); // { dg-note "previous declaration" } + void fv1() volatile; // { dg-error "cannot be overloaded with" } + void fv1(this S2 const volatile&); // { dg-bogus "" } + void fv1(this S2 const volatile&&); // { dg-bogus "" } + + void fcv0(this S2 &); // { dg-bogus "" } + void fcv0(this S2 &&); // { dg-bogus "" } + void fcv0(this S2 const&); // { dg-bogus "" } + void fcv0(this S2 const&&); // { dg-bogus "" } + void fcv0(this S2 volatile&); // { dg-bogus "" } + void fcv0(this S2 volatile&&); // { dg-bogus "" } + void fcv0() const volatile; // { dg-note "previous declaration" } + void fcv0(this S2 const volatile&&); // { dg-error "cannot be overloaded with" } + + void fcv1(this S2 &); // { dg-bogus "" } + void fcv1(this S2 &&); // { dg-bogus "" } + void fcv1(this S2 const&); // { dg-bogus "" } + void fcv1(this S2 const&&); // { dg-bogus "" } + void fcv1(this S2 volatile&); // { dg-bogus "" } + void fcv1(this S2 volatile&&); // { dg-bogus "" } + void fcv1(this S2 const volatile&); // { dg-note "previous declaration" } + void fcv1() const volatile; // { dg-error "cannot be overloaded with" } +}; + diff --git a/gcc/testsuite/g++.dg/cpp23/explicit-obj-redecl2.C b/gcc/testsuite/g++.dg/cpp23/explicit-obj-redecl2.C new file mode 100644 index 0000000..adb6ae5 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp23/explicit-obj-redecl2.C @@ -0,0 +1,161 @@ +// P0847R7 +// { dg-do compile { target c++23 } } +// { dg-options "-pedantic-errors -Wno-volatile" } + +// rejecting redeclarations of by-value xobj member functions +// as iobj member functions that are not ref qualified (and vice-versa) +// also check that valid overloads are accepted without diagnostic + +// iobj | xobj | MSVC | clang | ISOC++ +// none | none | X | X | X +// none | c | X | O | X +// none | v | X | O | X +// none | cv | X | O | X +// c | none | O | O | O +// c | c | O | X | O +// c | v | O | O | O +// c | cv | O | O | O +// v | none | O | O | O +// v | c | O | O | O +// v | v | O | X | O +// v | cv | O | O | O +// cv | none | O | O | O +// cv | c | O | O | O +// cv | v | O | O | O +// cv | cv | O | X | O + +/* Top-level cv qualifiers are supposed to be discarded from + the parameters of a function declaration. + + [dcl.fct.5] + After producing the list of parameter types, any top-level + cv-qualifiers modifying a parameter type are deleted when forming + the function type. + + According to the standard, the type of an implicit object parameter + is always a reference. This isn't reflected in GCC but we still need + to take this rule into account here. + + [over.match.funcs.general.4] + For implicit object member functions, the type of the implicit + object parameter is + -- “lvalue reference to cv X” for functions declared + without a ref-qualifier or with the & ref-qualifier + -- “rvalue reference to cv X” for functions declared with + the && ref-qualifier + + When comparing an iobj and xobj member function to see if they are + redeclarations we treat them differently depending on if the iobj + member function has a ref qualifier or not. + If the iobj member function does not have a ref qualifier, we need to + strip the top-level references before comparing them. + + [basic.scope.scope.3] + Two non-static member functions have corresponding object + parameters if: + -- exactly one is an implicit object member function with no + ref-qualifier and the types of their object parameters + ([dcl.fct]), after removing top-level references, are the + same, or + -- their object parameters have the same type. */ + +struct S { + void f0(); // { dg-note "previous declaration" } + void f0(this S); // { dg-error "cannot be overloaded with" } + + void f1(); // { dg-note "previous declaration" } + void f1(this S const); // { dg-error "cannot be overloaded with" } + + void f2(); // { dg-note "previous declaration" } + void f2(this S volatile); // { dg-error "cannot be overloaded with" } + + void f3(); // { dg-note "previous declaration" } + void f3(this S const volatile); // { dg-error "cannot be overloaded with" } + + void fc0() const; // { dg-bogus "" } + void fc0(this S); // { dg-bogus "" } + + void fc1() const; // { dg-bogus "" } + void fc1(this S const); // { dg-bogus "" } + + void fc2() const; // { dg-bogus "" } + void fc2(this S volatile); // { dg-bogus "" } + + void fc3() const; // { dg-bogus "" } + void fc3(this S const volatile); // { dg-bogus "" } + + void fv0() volatile; // { dg-bogus "" } + void fv0(this S); // { dg-bogus "" } + + void fv1() volatile; // { dg-bogus "" } + void fv1(this S const); // { dg-bogus "" } + + void fv2() volatile; // { dg-bogus "" } + void fv2(this S volatile); // { dg-bogus "" } + + void fv3() volatile; // { dg-bogus "" } + void fv3(this S const volatile); // { dg-bogus "" } + + void fcv0() const volatile; // { dg-bogus "" } + void fcv0(this S); // { dg-bogus "" } + + void fcv1() const volatile; // { dg-bogus "" } + void fcv1(this S const); // { dg-bogus "" } + + void fcv2() const volatile; // { dg-bogus "" } + void fcv2(this S volatile); // { dg-bogus "" } + + void fcv3() const volatile; // { dg-bogus "" } + void fcv3(this S const volatile); // { dg-bogus "" } + + // same as the above f cases except reversed + + void g0(this S); // { dg-note "previous declaration" } + void g0(); // { dg-error "cannot be overloaded with" } + + void g1(this S const); // { dg-note "previous declaration" } + void g1(); // { dg-error "cannot be overloaded with" } + + void g2(this S volatile); // { dg-note "previous declaration" } + void g2(); // { dg-error "cannot be overloaded with" } + + void g3(this S const volatile); // { dg-note "previous declaration" } + void g3(); // { dg-error "cannot be overloaded with" } + + void gc0(this S); // { dg-bogus "" } + void gc0() const; // { dg-bogus "" } + + void gc1(this S const); // { dg-bogus "" } + void gc1() const; // { dg-bogus "" } + + void gc2(this S volatile); // { dg-bogus "" } + void gc2() const; // { dg-bogus "" } + + void gc3(this S const volatile); // { dg-bogus "" } + void gc3() const; // { dg-bogus "" } + + void gv0(this S); // { dg-bogus "" } + void gv0() volatile; // { dg-bogus "" } + + void gv1(this S const); // { dg-bogus "" } + void gv1() volatile; // { dg-bogus "" } + + void gv2(this S volatile); // { dg-bogus "" } + void gv2() volatile; // { dg-bogus "" } + + void gv3(this S const volatile); // { dg-bogus "" } + void gv3() volatile; // { dg-bogus "" } + + void gcv0(this S); // { dg-bogus "" } + void gcv0() const volatile; // { dg-bogus "" } + + void gcv1(this S const); // { dg-bogus "" } + void gcv1() const volatile; // { dg-bogus "" } + + void gcv2(this S volatile); // { dg-bogus "" } + void gcv2() const volatile; // { dg-bogus "" } + + void gcv3(this S const volatile); // { dg-bogus "" } + void gcv3() const volatile; // { dg-bogus "" } +}; + diff --git a/gcc/testsuite/g++.dg/cpp23/explicit-obj-redecl3.C b/gcc/testsuite/g++.dg/cpp23/explicit-obj-redecl3.C new file mode 100644 index 0000000..10cf82d --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp23/explicit-obj-redecl3.C @@ -0,0 +1,206 @@ +// P0847R7 +// { dg-do compile { target c++23 } } + +// redeclarations of xobj member functions as static member functions and vice versa + +struct S { +// no additional params + void f_xs_v(this S) {}; // { dg-note {previous declaration} } + static void f_xs_v() {}; // { dg-error {cannot be overloaded with} } + + void f_xs_ref(this S&) {}; // { dg-note {previous declaration} } + static void f_xs_ref() {}; // { dg-error {cannot be overloaded with} } + + void f_xs_cref(this S const&) {}; // { dg-note {previous declaration} } + static void f_xs_cref() {}; // { dg-error {cannot be overloaded with} } + + void f_xs_rref(this S&&) {}; // { dg-note {previous declaration} } + static void f_xs_rref() {}; // { dg-error {cannot be overloaded with} } + + void f_xs_crref(this S const&&) {}; // { dg-note {previous declaration} } + static void f_xs_crref() {}; // { dg-error {cannot be overloaded with} } + +// reversed + static void f_sx_v() {}; // { dg-note {previous declaration} } + void f_sx_v(this S) {}; // { dg-error {cannot be overloaded with} } + + static void f_sx_ref() {}; // { dg-note {previous declaration} } + void f_sx_ref(this S&) {}; // { dg-error {cannot be overloaded with} } + + static void f_sx_cref() {}; // { dg-note {previous declaration} } + void f_sx_cref(this S const&) {}; // { dg-error {cannot be overloaded with} } + + static void f_sx_rref() {}; // { dg-note {previous declaration} } + void f_sx_rref(this S&&) {}; // { dg-error {cannot be overloaded with} } + + static void f_sx_crref() {}; // { dg-note {previous declaration} } + void f_sx_crref(this S const&&) {}; // { dg-error {cannot be overloaded with} } + +// one additional param + void f_xs_v_int(this S, int) {}; // { dg-note {previous declaration} } + static void f_xs_v_int(int) {}; // { dg-error {cannot be overloaded with} } + + void f_xs_ref_int(this S&, int) {}; // { dg-note {previous declaration} } + static void f_xs_ref_int(int) {}; // { dg-error {cannot be overloaded with} } + + void f_xs_cref_int(this S const&, int) {}; // { dg-note {previous declaration} } + static void f_xs_cref_int(int) {}; // { dg-error {cannot be overloaded with} } + + void f_xs_rref_int(this S&&, int) {}; // { dg-note {previous declaration} } + static void f_xs_rref_int(int) {}; // { dg-error {cannot be overloaded with} } + + void f_xs_crref_int(this S const&&, int) {}; // { dg-note {previous declaration} } + static void f_xs_crref_int(int) {}; // { dg-error {cannot be overloaded with} } + +// reversed + static void f_sx_v_int(int) {}; // { dg-note {previous declaration} } + void f_sx_v_int(this S, int) {}; // { dg-error {cannot be overloaded with} } + + static void f_sx_ref_int(int) {}; // { dg-note {previous declaration} } + void f_sx_ref_int(this S&, int) {}; // { dg-error {cannot be overloaded with} } + + static void f_sx_cref_int(int) {}; // { dg-note {previous declaration} } + void f_sx_cref_int(this S const&, int) {}; // { dg-error {cannot be overloaded with} } + + static void f_sx_rref_int(int) {}; // { dg-note {previous declaration} } + void f_sx_rref_int(this S&&, int) {}; // { dg-error {cannot be overloaded with} } + + static void f_sx_crref_int(int) {}; // { dg-note {previous declaration} } + void f_sx_crref_int(this S const&&, int) {}; // { dg-error {cannot be overloaded with} } + +// two additional params + void f_xs_v_int2(this S, int, int) {}; // { dg-note {previous declaration} } + static void f_xs_v_int2(int, int) {}; // { dg-error {cannot be overloaded with} } + + void f_xs_ref_int2(this S&, int, int) {}; // { dg-note {previous declaration} } + static void f_xs_ref_int2(int, int) {}; // { dg-error {cannot be overloaded with} } + + void f_xs_cref_int2(this S const&, int, int) {}; // { dg-note {previous declaration} } + static void f_xs_cref_int2(int, int) {}; // { dg-error {cannot be overloaded with} } + + void f_xs_rref_int2(this S&&, int, int) {}; // { dg-note {previous declaration} } + static void f_xs_rref_int2(int, int) {}; // { dg-error {cannot be overloaded with} } + + void f_xs_crref_int2(this S const&&, int, int) {}; // { dg-note {previous declaration} } + static void f_xs_crref_int2(int, int) {}; // { dg-error {cannot be overloaded with} } + +// reversed + static void f_sx_v_int2(int, int) {}; // { dg-note {previous declaration} } + void f_sx_v_int2(this S, int, int) {}; // { dg-error {cannot be overloaded with} } + + static void f_sx_ref_int2(int, int) {}; // { dg-note {previous declaration} } + void f_sx_ref_int2(this S&, int, int) {}; // { dg-error {cannot be overloaded with} } + + static void f_sx_cref_int2(int, int) {}; // { dg-note {previous declaration} } + void f_sx_cref_int2(this S const&, int, int) {}; // { dg-error {cannot be overloaded with} } + + static void f_sx_rref_int2(int, int) {}; // { dg-note {previous declaration} } + void f_sx_rref_int2(this S&&, int, int) {}; // { dg-error {cannot be overloaded with} } + + static void f_sx_crref_int2(int, int) {}; // { dg-note {previous declaration} } + void f_sx_crref_int2(this S const&&, int, int) {}; // { dg-error {cannot be overloaded with} } +}; + +// unrelated explicit object parameter type + +struct A {}; + +struct S1 +{ +// no additional params + void f_xs_v(this A) {}; // { dg-note {previous declaration} } + static void f_xs_v() {}; // { dg-error {cannot be overloaded with} } + + void f_xs_ref(this A&) {}; // { dg-note {previous declaration} } + static void f_xs_ref() {}; // { dg-error {cannot be overloaded with} } + + void f_xs_cref(this A const&) {}; // { dg-note {previous declaration} } + static void f_xs_cref() {}; // { dg-error {cannot be overloaded with} } + + void f_xs_rref(this A&&) {}; // { dg-note {previous declaration} } + static void f_xs_rref() {}; // { dg-error {cannot be overloaded with} } + + void f_xs_crref(this A const&&) {}; // { dg-note {previous declaration} } + static void f_xs_crref() {}; // { dg-error {cannot be overloaded with} } + +// reversed + static void f_sx_v() {}; // { dg-note {previous declaration} } + void f_sx_v(this A) {}; // { dg-error {cannot be overloaded with} } + + static void f_sx_ref() {}; // { dg-note {previous declaration} } + void f_sx_ref(this A&) {}; // { dg-error {cannot be overloaded with} } + + static void f_sx_cref() {}; // { dg-note {previous declaration} } + void f_sx_cref(this A const&) {}; // { dg-error {cannot be overloaded with} } + + static void f_sx_rref() {}; // { dg-note {previous declaration} } + void f_sx_rref(this A&&) {}; // { dg-error {cannot be overloaded with} } + + static void f_sx_crref() {}; // { dg-note {previous declaration} } + void f_sx_crref(this A const&&) {}; // { dg-error {cannot be overloaded with} } + +// one additional param + void f_xs_v_int(this A, int) {}; // { dg-note {previous declaration} } + static void f_xs_v_int(int) {}; // { dg-error {cannot be overloaded with} } + + void f_xs_ref_int(this A&, int) {}; // { dg-note {previous declaration} } + static void f_xs_ref_int(int) {}; // { dg-error {cannot be overloaded with} } + + void f_xs_cref_int(this A const&, int) {}; // { dg-note {previous declaration} } + static void f_xs_cref_int(int) {}; // { dg-error {cannot be overloaded with} } + + void f_xs_rref_int(this A&&, int) {}; // { dg-note {previous declaration} } + static void f_xs_rref_int(int) {}; // { dg-error {cannot be overloaded with} } + + void f_xs_crref_int(this A const&&, int) {}; // { dg-note {previous declaration} } + static void f_xs_crref_int(int) {}; // { dg-error {cannot be overloaded with} } + +// reversed + static void f_sx_v_int(int) {}; // { dg-note {previous declaration} } + void f_sx_v_int(this A, int) {}; // { dg-error {cannot be overloaded with} } + + static void f_sx_ref_int(int) {}; // { dg-note {previous declaration} } + void f_sx_ref_int(this A&, int) {}; // { dg-error {cannot be overloaded with} } + + static void f_sx_cref_int(int) {}; // { dg-note {previous declaration} } + void f_sx_cref_int(this A const&, int) {}; // { dg-error {cannot be overloaded with} } + + static void f_sx_rref_int(int) {}; // { dg-note {previous declaration} } + void f_sx_rref_int(this A&&, int) {}; // { dg-error {cannot be overloaded with} } + + static void f_sx_crref_int(int) {}; // { dg-note {previous declaration} } + void f_sx_crref_int(this A const&&, int) {}; // { dg-error {cannot be overloaded with} } + +// two additional params + void f_xs_v_int2(this A, int, int) {}; // { dg-note {previous declaration} } + static void f_xs_v_int2(int, int) {}; // { dg-error {cannot be overloaded with} } + + void f_xs_ref_int2(this A&, int, int) {}; // { dg-note {previous declaration} } + static void f_xs_ref_int2(int, int) {}; // { dg-error {cannot be overloaded with} } + + void f_xs_cref_int2(this A const&, int, int) {}; // { dg-note {previous declaration} } + static void f_xs_cref_int2(int, int) {}; // { dg-error {cannot be overloaded with} } + + void f_xs_rref_int2(this A&&, int, int) {}; // { dg-note {previous declaration} } + static void f_xs_rref_int2(int, int) {}; // { dg-error {cannot be overloaded with} } + + void f_xs_crref_int2(this A const&&, int, int) {}; // { dg-note {previous declaration} } + static void f_xs_crref_int2(int, int) {}; // { dg-error {cannot be overloaded with} } + +// reversed + static void f_sx_v_int2(int, int) {}; // { dg-note {previous declaration} } + void f_sx_v_int2(this A, int, int) {}; // { dg-error {cannot be overloaded with} } + + static void f_sx_ref_int2(int, int) {}; // { dg-note {previous declaration} } + void f_sx_ref_int2(this A&, int, int) {}; // { dg-error {cannot be overloaded with} } + + static void f_sx_cref_int2(int, int) {}; // { dg-note {previous declaration} } + void f_sx_cref_int2(this A const&, int, int) {}; // { dg-error {cannot be overloaded with} } + + static void f_sx_rref_int2(int, int) {}; // { dg-note {previous declaration} } + void f_sx_rref_int2(this A&&, int, int) {}; // { dg-error {cannot be overloaded with} } + + static void f_sx_crref_int2(int, int) {}; // { dg-note {previous declaration} } + void f_sx_crref_int2(this A const&&, int, int) {}; // { dg-error {cannot be overloaded with} } +}; + diff --git a/gcc/testsuite/g++.dg/cpp23/explicit-obj-redecl4.C b/gcc/testsuite/g++.dg/cpp23/explicit-obj-redecl4.C new file mode 100644 index 0000000..2e1b12b --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp23/explicit-obj-redecl4.C @@ -0,0 +1,97 @@ +// P0847R7 +// { dg-do compile { target c++23 } } + +// redeclarations with equivalent constraints + +template<typename T> +concept Constrain = true; + + +struct S { +// xobj/static + void f_xs_v(this S, Constrain auto) {}; // { dg-note {previous declaration} } + static void f_xs_v(Constrain auto) {}; // { dg-error {cannot be overloaded with} } + + void f_xs_ref(this S&, Constrain auto) {}; // { dg-note {previous declaration} } + static void f_xs_ref(Constrain auto) {}; // { dg-error {cannot be overloaded with} } + + void f_xs_cref(this S const&, Constrain auto) {}; // { dg-note {previous declaration} } + static void f_xs_cref(Constrain auto) {}; // { dg-error {cannot be overloaded with} } + + void f_xs_rref(this S&&, Constrain auto) {}; // { dg-note {previous declaration} } + static void f_xs_rref(Constrain auto) {}; // { dg-error {cannot be overloaded with} } + + void f_xs_crref(this S const&&, Constrain auto) {}; // { dg-note {previous declaration} } + static void f_xs_crref(Constrain auto) {}; // { dg-error {cannot be overloaded with} } + +// static/xobj + static void f_sx_v(Constrain auto) {}; // { dg-note {previous declaration} } + void f_sx_v(this S, Constrain auto) {}; // { dg-error {cannot be overloaded with} } + + static void f_sx_ref(Constrain auto) {}; // { dg-note {previous declaration} } + void f_sx_ref(this S&, Constrain auto) {}; // { dg-error {cannot be overloaded with} } + + static void f_sx_cref(Constrain auto) {}; // { dg-note {previous declaration} } + void f_sx_cref(this S const&, Constrain auto) {}; // { dg-error {cannot be overloaded with} } + + static void f_sx_rref(Constrain auto) {}; // { dg-note {previous declaration} } + void f_sx_rref(this S&&, Constrain auto) {}; // { dg-error {cannot be overloaded with} } + + static void f_sx_crref(Constrain auto) {}; // { dg-note {previous declaration} } + void f_sx_crref(this S const&&, Constrain auto) {}; // { dg-error {cannot be overloaded with} } + + // iobj/xobj + void f_ix_lref(Constrain auto) {}; // { dg-note {previous declaration} } + void f_ix_lref(this S&, Constrain auto) {}; // { dg-error {cannot be overloaded with} } + + void f_ix_rref(Constrain auto) {}; // { dg-note {previous declaration} } + void f_ix_rref(this S&&, Constrain auto) {}; // { dg-error {cannot be overloaded with} } + + void f_ix_const_lref(Constrain auto) const {}; // { dg-note {previous declaration} } + void f_ix_const_lref(this S const&, Constrain auto) {}; // { dg-error {cannot be overloaded with} } + + void f_ix_const_rref(Constrain auto) const {}; // { dg-note {previous declaration} } + void f_ix_const_rref(this S const&&, Constrain auto) {}; // { dg-error {cannot be overloaded with} } + + // xobj/iobj + void f_xi_lref(this S&, Constrain auto) {}; // { dg-note {previous declaration} } + void f_xi_lref(Constrain auto) {}; // { dg-error {cannot be overloaded with} } + + void f_xi_rref(this S&&, Constrain auto) {}; // { dg-note {previous declaration} } + void f_xi_rref(Constrain auto) {}; // { dg-error {cannot be overloaded with} } + + void f_xi_const_lref(this S const&, Constrain auto) {}; // { dg-note {previous declaration} } + void f_xi_const_lref(Constrain auto) const {}; // { dg-error {cannot be overloaded with} } + + void f_xi_const_rref(this S const&&, Constrain auto) {}; // { dg-note {previous declaration} } + void f_xi_const_rref(Constrain auto) const {}; // { dg-error {cannot be overloaded with} } + + // with ref qualifier + + // iobj/xobj + void f_ix_lref_refqual(Constrain auto) & {}; // { dg-note {previous declaration} } + void f_ix_lref_refqual(this S&, Constrain auto) {}; // { dg-error {cannot be overloaded with} } + + void f_ix_rref_refqual(Constrain auto) && {}; // { dg-note {previous declaration} } + void f_ix_rref_refqual(this S&&, Constrain auto) {}; // { dg-error {cannot be overloaded with} } + + void f_ix_const_lref_refqual(Constrain auto) const& {}; // { dg-note {previous declaration} } + void f_ix_const_lref_refqual(this S const&, Constrain auto) {}; // { dg-error {cannot be overloaded with} } + + void f_ix_const_rref_refqual(Constrain auto) const&& {}; // { dg-note {previous declaration} } + void f_ix_const_rref_refqual(this S const&&, Constrain auto) {}; // { dg-error {cannot be overloaded with} } + + // xobj/iobj + void f_xi_lref_refqual(this S&, Constrain auto) {}; // { dg-note {previous declaration} } + void f_xi_lref_refqual(Constrain auto) & {}; // { dg-error {cannot be overloaded with} } + + void f_xi_rref_refqual(this S&&, Constrain auto) {}; // { dg-note {previous declaration} } + void f_xi_rref_refqual(Constrain auto) && {}; // { dg-error {cannot be overloaded with} } + + void f_xi_const_lref_refqual(this S const&, Constrain auto) {}; // { dg-note {previous declaration} } + void f_xi_const_lref_refqual(Constrain auto) const& {}; // { dg-error {cannot be overloaded with} } + + void f_xi_const_rref_refqual(this S const&&, Constrain auto) {}; // { dg-note {previous declaration} } + void f_xi_const_rref_refqual(Constrain auto) const&& {}; // { dg-error {cannot be overloaded with} } +}; + diff --git a/gcc/testsuite/g++.dg/cpp23/feat-cxx2b.C b/gcc/testsuite/g++.dg/cpp23/feat-cxx2b.C index 2b21bd1..d81aab7 100644 --- a/gcc/testsuite/g++.dg/cpp23/feat-cxx2b.C +++ b/gcc/testsuite/g++.dg/cpp23/feat-cxx2b.C @@ -578,6 +578,12 @@ # error "__cpp_implicit_move != 202207" #endif +#ifndef __cpp_explicit_this_parameter +# error "__cpp_explicit_this_parameter" +#elif __cpp_explicit_this_parameter != 202110 +# error "__cpp_explicit_this_parameter != 202110" +#endif + #ifndef __cpp_auto_cast # error "__cpp_auto_cast" #elif __cpp_auto_cast != 202110 diff --git a/gcc/testsuite/g++.dg/cpp26/feat-cxx26.C b/gcc/testsuite/g++.dg/cpp26/feat-cxx26.C index 4507ea0..d19fca4 100644 --- a/gcc/testsuite/g++.dg/cpp26/feat-cxx26.C +++ b/gcc/testsuite/g++.dg/cpp26/feat-cxx26.C @@ -578,6 +578,12 @@ # error "__cpp_implicit_move != 202207" #endif +#ifndef __cpp_explicit_this_parameter +# error "__cpp_explicit_this_parameter" +#elif __cpp_explicit_this_parameter != 202110 +# error "__cpp_explicit_this_parameter != 202110" +#endif + #ifndef __cpp_auto_cast # error "__cpp_auto_cast" #elif __cpp_auto_cast != 202110 diff --git a/gcc/testsuite/g++.dg/cpp2a/concepts-explicit-inst6.C b/gcc/testsuite/g++.dg/cpp2a/concepts-explicit-inst6.C new file mode 100644 index 0000000..a3ae1ca --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp2a/concepts-explicit-inst6.C @@ -0,0 +1,35 @@ +// PR c++/104634 +// { dg-do compile { target c++20 } } + +// { dg-final { scan-assembler "_ZN1AIiE2f1Ev" } } +// { dg-final { scan-assembler "_ZN1AIdE2f2Ev" } } +// { dg-final { scan-assembler "_ZN1AIPiE2f3Ev" } } +// { dg-final { scan-assembler "_ZN1AIPdE2f4Ev" } } + +template<class T> +struct A { }; + +template<class T> requires __is_same(T, int) +struct A<T> { + void f1() { } +}; + +template<class T> requires __is_same(T, double) +struct A<T> { + void f2() { } +}; + +template<class T> requires __is_same(T, int) +struct A<T*> { + void f3() { } +}; + +template<class T> requires __is_same(T, double) +struct A<T*> { + void f4() { } +}; + +template struct A<int>; +template struct A<double>; +template struct A<int*>; +template struct A<double*>; diff --git a/gcc/testsuite/g++.dg/cpp2a/concepts-memfun4.C b/gcc/testsuite/g++.dg/cpp2a/concepts-memfun4.C new file mode 100644 index 0000000..91e34f1 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp2a/concepts-memfun4.C @@ -0,0 +1,95 @@ +// PR c++/113191 +// { dg-do compile { target c++23 } } + +template<typename> struct S; + +template<typename T = void> +struct B { + constexpr int f() const requires true { return 5; } + constexpr operator int () const requires true { return 5; } + constexpr int g(this S<T>&&) requires true { return 5; } + constexpr int h() requires true { return 5; } +}; + +template<typename = void> +struct S : B<> { + using B::f; + using B::g; + using B::h; + constexpr int f() const { return 10; } + constexpr operator int () const { return 10; } + constexpr int g() { return 10; } + constexpr int h(this S&&) { return 10; } +}; + +// implicit object parms match, B::f is more constrained +static_assert(S<>{}.f() == 5); +static_assert(S<>{}.g() == 5); +static_assert(S<>{}.h() == 5); + +template <typename = void> +struct C { + constexpr int f() const { return 15; } + constexpr operator int () const { return 15; } +}; + +template <typename = void> +struct S2: B<>, C<> { }; + +// implicit object parms for conversion functions are all considered to be from +// the class of the object argument +static_assert(S2<>{} == 5); + +// ambiguous lookup, so we never actually compare the candidates +// if we did, implicit object parms don't match due to different classes +// so constraints aren't considered and it would still be ambiguous +static_assert(S2<>{}.f() == 5); // { dg-error "ambiguous" } + +template <typename = void> +struct S3 : B<> { + using B::f; + constexpr int f() volatile { return 10; } +}; + +// implicit object parms don't match due to different cv-quals +static_assert(S3<>{}.f() == 5); // { dg-error "ambiguous" } + +template <typename = void> +struct S4 : B<> { + using B::f; + constexpr int f() const & { return 10; } +}; + +// no ref-qual matches any ref-qual +static_assert(S4<>{}.f() == 5); + +template <typename = void> +struct C2 { + constexpr operator int () volatile { return 15; } +}; + +template <typename = void> +struct S5: B<>, C2<> { }; + +// implicit object parms don't match due to different cv-quals +static_assert(S5<>{} == 5); // { dg-error "ambiguous" } + +namespace N1 { + template <class = void> struct B; + + template <class = void> + struct A { + constexpr bool operator==(B<>&) { return false; } + }; + + template <class> + struct B { + constexpr bool operator==(A<>&) requires true { return true; } + }; + + A<> a; + B<> b; + // when comparing the A op== to the reversed B op==, we compare them in + // reverse order, so they match, and we choose the more constrained. + static_assert (a == b); +} diff --git a/gcc/testsuite/g++.dg/gomp/array-section-1.C b/gcc/testsuite/g++.dg/gomp/array-section-1.C index 023706b..562475a 100644 --- a/gcc/testsuite/g++.dg/gomp/array-section-1.C +++ b/gcc/testsuite/g++.dg/gomp/array-section-1.C @@ -8,10 +8,10 @@ void foo() { int arr1[40]; #pragma omp target map(arr1[x ? C : D]) -// { dg-final { scan-tree-dump {map\(tofrom:arr1\[SAVE_EXPR <x != 0 \? 3 : 5>\] \[len: [0-9]+\]\) map\(firstprivate:arr1 \[pointer assign, bias: \(long int\) &arr1\[SAVE_EXPR <x != 0 \? 3 : 5>\] - \(long int\) &arr1\]\)} "original" } } +// { dg-final { scan-tree-dump {map\(tofrom:arr1\[SAVE_EXPR <x != 0 \? 3 : 5>\] \[len: [0-9]+\]\) map\(firstprivate:arr1 \[pointer assign, bias: \((?:long )?int\) &arr1\[SAVE_EXPR <x != 0 \? 3 : 5>\] - \((?:long )?int\) &arr1\]\)} "original" } } { } #pragma omp target map(arr1[x ? C : D : D]) -// { dg-final { scan-tree-dump {map\(tofrom:arr1\[SAVE_EXPR <x != 0 \? 3 : 5>\] \[len: [0-9]+\]\) map\(firstprivate:arr1 \[pointer assign, bias: \(long int\) &arr1\[SAVE_EXPR <x != 0 \? 3 : 5>\] - \(long int\) &arr1\]\)} "original" } } +// { dg-final { scan-tree-dump {map\(tofrom:arr1\[SAVE_EXPR <x != 0 \? 3 : 5>\] \[len: [0-9]+\]\) map\(firstprivate:arr1 \[pointer assign, bias: \((?:long )?int\) &arr1\[SAVE_EXPR <x != 0 \? 3 : 5>\] - \((?:long )?int\) &arr1\]\)} "original" } } { } #pragma omp target map(arr1[1 : x ? C : D]) // { dg-final { scan-tree-dump {map\(tofrom:arr1\[1\] \[len: x != 0 \? [0-9]+ : [0-9]+\]\) map\(firstprivate:arr1 \[pointer assign, bias: [0-9]+\]\)} "original" } } @@ -22,10 +22,10 @@ int main() { int arr1[40]; #pragma omp target map(arr1[x ? 3 : 5]) -// { dg-final { scan-tree-dump {map\(tofrom:arr1\[SAVE_EXPR <x != 0 \? 3 : 5>\] \[len: [0-9]+\]\) map\(firstprivate:arr1 \[pointer assign, bias: \(long int\) &arr1\[SAVE_EXPR <x != 0 \? 3 : 5>\] - \(long int\) &arr1\]\)} "original" } } +// { dg-final { scan-tree-dump {map\(tofrom:arr1\[SAVE_EXPR <x != 0 \? 3 : 5>\] \[len: [0-9]+\]\) map\(firstprivate:arr1 \[pointer assign, bias: \((?:long )?int\) &arr1\[SAVE_EXPR <x != 0 \? 3 : 5>\] - \((?:long )?int\) &arr1\]\)} "original" } } { } #pragma omp target map(arr1[x ? 3 : 5 : 5]) -// { dg-final { scan-tree-dump {map\(tofrom:arr1\[SAVE_EXPR <x != 0 \? 3 : 5>\] \[len: [0-9]+\]\) map\(firstprivate:arr1 \[pointer assign, bias: \(long int\) &arr1\[SAVE_EXPR <x != 0 \? 3 : 5>\] - \(long int\) &arr1\]\)} "original" } } +// { dg-final { scan-tree-dump {map\(tofrom:arr1\[SAVE_EXPR <x != 0 \? 3 : 5>\] \[len: [0-9]+\]\) map\(firstprivate:arr1 \[pointer assign, bias: \((?:long )?int\) &arr1\[SAVE_EXPR <x != 0 \? 3 : 5>\] - \((?:long )?int\) &arr1\]\)} "original" } } { } #pragma omp target map(arr1[1 : x ? 3 : 5]) // { dg-final { scan-tree-dump {map\(tofrom:arr1\[1\] [len: x != 0 ? [0-9]+ : [0-9]+\]\) map\(firstprivate:arr1 \[pointer assign, bias: [0-9]+\]\)} "original" } } diff --git a/gcc/testsuite/g++.dg/gomp/array-section-2.C b/gcc/testsuite/g++.dg/gomp/array-section-2.C index 072108d..e2be979 100644 --- a/gcc/testsuite/g++.dg/gomp/array-section-2.C +++ b/gcc/testsuite/g++.dg/gomp/array-section-2.C @@ -16,10 +16,10 @@ int C::foo() /* There is a parsing ambiguity here without the space. We don't try to resolve that automatically (though maybe we could, in theory). */ #pragma omp target map(arr1[::x: ::y]) -// { dg-final { scan-tree-dump {map\(tofrom:arr1\[SAVE_EXPR <x>\] \[len: \(sizetype\) y \* [0-9]+\]\) map\(firstprivate:arr1 \[pointer assign, bias: \(long int\) &arr1\[SAVE_EXPR <x>\] - \(long int\) &arr1\]\)} "original" } } +// { dg-final { scan-tree-dump {map\(tofrom:arr1\[SAVE_EXPR <x>\] \[len: \(sizetype\) y \* [0-9]+\]\) map\(firstprivate:arr1 \[pointer assign, bias: \((?:long )?int\) &arr1\[SAVE_EXPR <x>\] - \((?:long )?int\) &arr1\]\)} "original" } } { } #pragma omp target map(arr1[::x:]) -// { dg-final { scan-tree-dump {map\(tofrom:arr1\[SAVE_EXPR <x>\] \[len: \(40 - \(sizetype\) SAVE_EXPR <x>\) \* [0-9]+\]\) map\(firstprivate:arr1 \[pointer assign, bias: \(long int\) &arr1\[SAVE_EXPR <x>\] - \(long int\) &arr1\]\)} "original" } } +// { dg-final { scan-tree-dump {map\(tofrom:arr1\[SAVE_EXPR <x>\] \[len: \(40 - \(sizetype\) SAVE_EXPR <x>\) \* [0-9]+\]\) map\(firstprivate:arr1 \[pointer assign, bias: \((?:long )?int\) &arr1\[SAVE_EXPR <x>\] - \((?:long )?int\) &arr1\]\)} "original" } } { } #pragma omp target map(arr1[: ::y]) // { dg-final { scan-tree-dump {map\(tofrom:arr1\[0\] \[len: \(sizetype\) y \* [0-9]+\]\) map\(firstprivate:arr1 \[pointer assign, bias: 0\]\)} "original" } } @@ -40,10 +40,10 @@ void Ct<T>::foo() { int arr1[40]; #pragma omp target map(arr1[::x: ::y]) -// { dg-final { scan-tree-dump {map\(tofrom:arr1\[SAVE_EXPR <x>\] \[len: \(sizetype\) y \* [0-9]+\]\) map\(firstprivate:arr1 \[pointer assign, bias: \(long int\) &arr1\[SAVE_EXPR <x>\] - \(long int\) &arr1\]\)} "original" } } +// { dg-final { scan-tree-dump {map\(tofrom:arr1\[SAVE_EXPR <x>\] \[len: \(sizetype\) y \* [0-9]+\]\) map\(firstprivate:arr1 \[pointer assign, bias: \((?:long )?int\) &arr1\[SAVE_EXPR <x>\] - \((?:long )?int\) &arr1\]\)} "original" } } { } #pragma omp target map(arr1[::x:]) -// { dg-final { scan-tree-dump {map\(tofrom:arr1\[SAVE_EXPR <x>\] \[len: \(40 - \(sizetype\) SAVE_EXPR <x>\) \* [0-9]+\]\) map\(firstprivate:arr1 \[pointer assign, bias: \(long int\) &arr1\[SAVE_EXPR <x>\] - \(long int\) &arr1\]\)} "original" } } +// { dg-final { scan-tree-dump {map\(tofrom:arr1\[SAVE_EXPR <x>\] \[len: \(40 - \(sizetype\) SAVE_EXPR <x>\) \* [0-9]+\]\) map\(firstprivate:arr1 \[pointer assign, bias: \((?:long )?int\) &arr1\[SAVE_EXPR <x>\] - \((?:long )?int\) &arr1\]\)} "original" } } { } #pragma omp target map(arr1[: ::y]) // { dg-final { scan-tree-dump {map\(tofrom:arr1\[0\] \[len: \(sizetype\) y \* [0-9]+\]\) map\(firstprivate:arr1 \[pointer assign, bias: 0\]\)} "original" } } diff --git a/gcc/testsuite/g++.dg/gomp/bad-array-section-10.C b/gcc/testsuite/g++.dg/gomp/bad-array-section-10.C index 393b0fe..286e72e 100644 --- a/gcc/testsuite/g++.dg/gomp/bad-array-section-10.C +++ b/gcc/testsuite/g++.dg/gomp/bad-array-section-10.C @@ -6,12 +6,15 @@ void foo() int arr1[40]; #pragma omp target map(arr1[4,C:]) // { dg-warning "top-level comma expression in array subscript is deprecated" "" { target c++20_only } .-1 } +// { dg-error "cannot use multidimensional subscript in OpenMP array section" "" { target c++23 } .-2 } { } #pragma omp target map(arr1[4,5:C,7]) // { dg-warning "top-level comma expression in array subscript is deprecated" "" { target c++20_only } .-1 } +// { dg-error "cannot use multidimensional subscript in OpenMP array section" "" { target c++23 } .-2 } { } #pragma omp target map(arr1[:8,C,10]) // { dg-warning "top-level comma expression in array subscript is deprecated" "" { target c++20_only } .-1 } +// { dg-error "cannot use multidimensional subscript in OpenMP array section" "" { target c++23 } .-2 } { } } @@ -20,12 +23,15 @@ int main() int arr1[40]; #pragma omp target map(arr1[4,5:]) // { dg-warning "top-level comma expression in array subscript is deprecated" "" { target c++20_only } .-1 } +// { dg-error "cannot use multidimensional subscript in OpenMP array section" "" { target c++23 } .-2 } { } #pragma omp target map(arr1[4,5:6,7]) // { dg-warning "top-level comma expression in array subscript is deprecated" "" { target c++20_only } .-1 } +// { dg-error "cannot use multidimensional subscript in OpenMP array section" "" { target c++23 } .-2 } { } #pragma omp target map(arr1[:8,9,10]) // { dg-warning "top-level comma expression in array subscript is deprecated" "" { target c++20_only } .-1 } +// { dg-error "cannot use multidimensional subscript in OpenMP array section" "" { target c++23 } .-2 } { } foo<6, 9> (); diff --git a/gcc/testsuite/g++.dg/gomp/bad-array-section-4.C b/gcc/testsuite/g++.dg/gomp/bad-array-section-4.C index 707c2c3..5d9f056 100644 --- a/gcc/testsuite/g++.dg/gomp/bad-array-section-4.C +++ b/gcc/testsuite/g++.dg/gomp/bad-array-section-4.C @@ -34,7 +34,7 @@ int main() // Reject array section in compound initialiser. #pragma omp target map( (struct S) { .ptr = (int *) arr[5:5] } ) // { dg-error {expected '\]' before ':' token} "" { target *-*-* } .-1 } -// { dg-warning {cast to pointer from integer of different size} "" { target *-*-* } .-2 } +// { dg-warning {cast to pointer from integer of different size} "" { target lp64 } .-2 } // { dg-error {expected primary-expression before 'struct'} "" { target *-*-* } .-3 } // { dg-error {expected '\)' before 'struct'} "" { target *-*-* } .-4 } { } diff --git a/gcc/testsuite/g++.dg/modules/pr106304_b.C b/gcc/testsuite/g++.dg/modules/pr106304_b.C index e833390..0d1da08 100644 --- a/gcc/testsuite/g++.dg/modules/pr106304_b.C +++ b/gcc/testsuite/g++.dg/modules/pr106304_b.C @@ -5,4 +5,5 @@ module pr106304; void f(A& a) { as_b(a); + dynamic_cast<B*>(&a); } diff --git a/gcc/testsuite/g++.dg/template/partial-specialization14.C b/gcc/testsuite/g++.dg/template/partial-specialization14.C new file mode 100644 index 0000000..3780574 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/partial-specialization14.C @@ -0,0 +1,15 @@ +// Verify we don't care about the access specifier when declaring +// a partial specialization of a member class template. + +struct A1 { + template<class T> struct B { }; +private: + template<class T> struct B<T*> { }; // { dg-bogus "different access" } +}; + +struct A2 { + template<class T> struct B { }; + template<class T> struct B<T*>; +private: + template<class T> struct B<T*> { }; // { dg-bogus "different access" } +}; diff --git a/gcc/testsuite/g++.dg/torture/accessor-fixits-9-xobj.C b/gcc/testsuite/g++.dg/torture/accessor-fixits-9-xobj.C new file mode 100644 index 0000000..89be978 --- /dev/null +++ b/gcc/testsuite/g++.dg/torture/accessor-fixits-9-xobj.C @@ -0,0 +1,119 @@ +// PR c++/84993 +// { dg-options "-fdiagnostics-show-caret -std=c++23" } + +/* Misspelling (by omitting a leading "m_") of a private member for which + there's a public accessor. + + We expect a fix-it hint suggesting the accessor. */ + +class t1 +{ +public: + int get_ratio (this const t1& x) { return x.m_ratio; } + +private: + int m_ratio; +}; + +int test (t1 *ptr_1) +{ + return ptr_1->ratio; // { dg-error "'class t1' has no member named 'ratio'; did you mean 'int t1::m_ratio'\\? \\(accessible via 'int t1::get_ratio\\(this const t1&\\)'\\)" } + /* { dg-begin-multiline-output "" } + return ptr_1->ratio; + ^~~~~ + get_ratio() + { dg-end-multiline-output "" } */ +} + + +/* Misspelling of a private member for which there's a public accessor. + + We expect a fix-it hint suggesting the accessor. */ + +class t2 +{ +public: + int get_color (this const t2& x) { return x.m_color; } + +private: + int m_color; +}; + +int test (t2 *ptr_2) +{ + return ptr_2->m_colour; // { dg-error "'class t2' has no member named 'm_colour'; did you mean 'int t2::m_color'\\? \\(accessible via 'int t2::get_color\\(this const t2&\\)'\\)" } + /* { dg-begin-multiline-output "" } + return ptr_2->m_colour; + ^~~~~~~~ + get_color() + { dg-end-multiline-output "" } */ +} + + +/* Misspelling of a private member via a subclass pointer, for which there's + a public accessor in the base class. + + We expect a fix-it hint suggesting the accessor. */ + +class t3 : public t2 {}; + +int test (t3 *ptr_3) +{ + return ptr_3->m_colour; // { dg-error "'class t3' has no member named 'm_colour'; did you mean 'int t2::m_color'\\? \\(accessible via 'int t2::get_color\\(this const t2&\\)'\\)" } + /* { dg-begin-multiline-output "" } + return ptr_3->m_colour; + ^~~~~~~~ + get_color() + { dg-end-multiline-output "" } */ +} + + +/* Misspelling of a protected member, for which there's isn't a public + accessor. + + We expect no fix-it hint; instead a message identifying where the + data member was declared. */ + +class t4 +{ +protected: + int m_color; // { dg-message "declared protected here" } +}; + +int test (t4 *ptr_4) +{ + return ptr_4->m_colour; // { dg-error "'class t4' has no member named 'm_colour'; did you mean 'int t4::m_color'\\? \\(not accessible from this context\\)" } + /* { dg-begin-multiline-output "" } + return ptr_4->m_colour; + ^~~~~~~~ + { dg-end-multiline-output "" } */ + /* { dg-begin-multiline-output "" } + int m_color; + ^~~~~~~ + { dg-end-multiline-output "" } */ +} + + +/* Misspelling of a private member, for which the accessor is also private. + + We expect no fix-it hint; instead a message identifying where the + data member was declared. */ + +class t5 +{ + int get_color (this const t5& x) { return x.m_color; } + int m_color; // { dg-message "declared private here" } +}; + +int test (t5 *ptr_5) +{ + return ptr_5->m_colour; // { dg-error "'class t5' has no member named 'm_colour'; did you mean 'int t5::m_color'\\? \\(not accessible from this context\\)" } + /* { dg-begin-multiline-output "" } + return ptr_5->m_colour; + ^~~~~~~~ + { dg-end-multiline-output "" } */ + /* { dg-begin-multiline-output "" } + int m_color; + ^~~~~~~ + { dg-end-multiline-output "" } */ +} diff --git a/gcc/testsuite/g++.dg/vect/vect-early-break_4-pr113137.cc b/gcc/testsuite/g++.dg/vect/vect-early-break_4-pr113137.cc new file mode 100644 index 0000000..f78db86 --- /dev/null +++ b/gcc/testsuite/g++.dg/vect/vect-early-break_4-pr113137.cc @@ -0,0 +1,15 @@ +/* { dg-do compile } */ +/* { dg-add-options vect_early_break } */ +/* { dg-require-effective-target vect_early_break } */ +/* { dg-require-effective-target vect_int } */ + +int b; +void a() __attribute__((__noreturn__)); +void c() { + char *buf; + int bufsz = 64; + while (b) { + !bufsz ? a(), 0 : *buf++ = bufsz--; + b -= 4; + } +} diff --git a/gcc/testsuite/g++.dg/vect/vect-early-break_5-pr113137.cc b/gcc/testsuite/g++.dg/vect/vect-early-break_5-pr113137.cc new file mode 100644 index 0000000..dcd19fa --- /dev/null +++ b/gcc/testsuite/g++.dg/vect/vect-early-break_5-pr113137.cc @@ -0,0 +1,13 @@ +/* { dg-do compile } */ +/* { dg-add-options vect_early_break } */ +/* { dg-require-effective-target vect_early_break } */ +/* { dg-require-effective-target vect_int } */ + +char UnpackReadTables_BitLength[20]; +int UnpackReadTables_ZeroCount; +void UnpackReadTables() { + for (unsigned I = 0; I < 20;) + while (UnpackReadTables_ZeroCount-- && + I < sizeof(UnpackReadTables_BitLength)) + UnpackReadTables_BitLength[I++] = 0; +} diff --git a/gcc/testsuite/g++.target/i386/bfloat_cpp_typecheck.C b/gcc/testsuite/g++.target/i386/bfloat_cpp_typecheck.C index 2567129..3a725f5 100644 --- a/gcc/testsuite/g++.target/i386/bfloat_cpp_typecheck.C +++ b/gcc/testsuite/g++.target/i386/bfloat_cpp_typecheck.C @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-msse2 -O3 --save-temps" } */ +/* { dg-options "-msse2 -O3" } */ void foo (void) { diff --git a/gcc/testsuite/gcc.c-torture/compile/pr113322-1.c b/gcc/testsuite/gcc.c-torture/compile/pr113322-1.c new file mode 100644 index 0000000..efed960 --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/compile/pr113322-1.c @@ -0,0 +1,14 @@ +/* { dg-additional-options "-march=sapphirerapids" { target x86_64*-*-* i?86-*-* } } */ +/* PR middle-end/113322 */ + +float a[16]; +void +foo () +{ +int i; +for (i = 0; i < 16/2; i++) + { + if (a[2*i+((0 +1)%2)] != (3 * (2*i+((0 +1)%2)) + 2)) + __builtin_abort (); + } +} diff --git a/gcc/testsuite/gcc.c-torture/execute/pr110115.c b/gcc/testsuite/gcc.c-torture/execute/pr110115.c new file mode 100644 index 0000000..02dec54 --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/execute/pr110115.c @@ -0,0 +1,45 @@ +/* PR middle-end/110115 */ + +int a; +signed char b; + +static int +foo (signed char *e, int f) +{ + int d; + for (d = 0; d < f; d++) + e[d] = 0; + return d; +} + +int +bar (signed char e, int f) +{ + signed char h[20]; + int i = foo (h, f); + return i; +} + +int +baz () +{ + switch (a) + { + case 'f': + return 0; + default: + return ~0; + } +} + +int +main () +{ + { + signed char *k[3]; + int d; + for (d = 0; bar (8, 15) - 15 + d < 1; d++) + k[baz () + 1] = &b; + *k[0] = -*k[0]; + } +} diff --git a/gcc/testsuite/gcc.c-torture/execute/pr111422.c b/gcc/testsuite/gcc.c-torture/execute/pr111422.c new file mode 100644 index 0000000..f5920dd --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/execute/pr111422.c @@ -0,0 +1,39 @@ +/* PR middle-end/111422 */ + +int a, b; +int *c = &b; +unsigned d; +signed char e; +int f = 1; + +int +foo (int k, signed char *l) +{ + if (k < 6) + return a; + l[0] = l[1] = l[k - 1] = 8; + return 0; +} + +int +bar (int k) +{ + signed char g[11]; + int h = foo (k, g); + return h; +} + +int +main () +{ + for (; b < 8; b = b + 1) + ; + int j; + int *n[8]; + for (j = 0; 18446744073709551608ULL + bar (*c) + *c + j < 2; j++) + n[j] = &f; + for (; e <= 4; e++) + d = *n[0] == f; + if (d != 1) + __builtin_abort (); +} diff --git a/gcc/testsuite/gcc.c-torture/execute/pr112581-1.c b/gcc/testsuite/gcc.c-torture/execute/pr112581-1.c new file mode 100644 index 0000000..14081c9 --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/execute/pr112581-1.c @@ -0,0 +1,37 @@ +/* { dg-require-effective-target int32plus } */ +/* PR tree-optimization/112581 */ +/* reassociation, used to combine 2 bb to together, + that made an unitialized variable unconditional used + which then at runtime would cause an infinite loop. */ +int a = -1, b = 2501896061, c, d, e, f = 3, g; +int main() { + unsigned h; + int i; + d = 0; + for (; d < 1; d++) { + int j = ~-((6UL ^ a) / b); + if (b) + L: + if (!f) + continue; + if (c) + i = 1; + if (j) { + i = 0; + while (e) + ; + } + g = -1 % b; + h = ~(b || h); + f = g || 0; + a = a || 0; + if (!a) + h = 0; + while (h > 4294967294) + if (i) + break; + if (c) + goto L; + } + return 0; +} diff --git a/gcc/testsuite/gcc.c-torture/execute/pr90348.c b/gcc/testsuite/gcc.c-torture/execute/pr90348.c new file mode 100644 index 0000000..341cedd --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/execute/pr90348.c @@ -0,0 +1,38 @@ +/* PR middle-end/90348 */ + +void __attribute__ ((noipa)) +set_one (unsigned char *ptr) +{ + *ptr = 1; +} + +void __attribute__ ((noipa)) +check_zero (unsigned char const *in, unsigned int len) +{ + for (unsigned int i = 0; i < len; ++i) + if (in[i] != 0) + __builtin_abort (); +} + +static void +set_one_on_stack (void) +{ + unsigned char buf[1]; + set_one (buf); +} + +int +main () +{ + for (int i = 0; i <= 4; ++i) + { + unsigned char in[4]; + for (int j = 0; j < i; ++j) + { + in[j] = 0; + set_one_on_stack (); + } + check_zero (in, i); + } + return 0; +} diff --git a/gcc/testsuite/gcc.dg/Wattributes-6.c b/gcc/testsuite/gcc.dg/Wattributes-6.c index 978f3f9..49a085d 100644 --- a/gcc/testsuite/gcc.dg/Wattributes-6.c +++ b/gcc/testsuite/gcc.dg/Wattributes-6.c @@ -408,7 +408,7 @@ finline_hot_noret_align (int); /* { dg-warning "ignoring attribute .warn_unused /* { dg-note "previous declaration here" "" { target *-*-* } .-1 } */ inline int ATTR ((aligned (4))) - finline_hot_noret_align (int); /* { dg-warning "ignoring attribute .aligned \\(4\\). because it conflicts with attribute .aligned \\(8\\)." "" { target { ! { hppa*64*-*-* } } } } */ + finline_hot_noret_align (int); /* { dg-warning "ignoring attribute .aligned \\(4\\). because it conflicts with attribute .aligned \\(8\\)." "" } */ inline int ATTR ((aligned (8))) finline_hot_noret_align (int); /* { dg-note "previous declaration here" } */ diff --git a/gcc/testsuite/gcc.dg/analyzer/data-model-9.c b/gcc/testsuite/gcc.dg/analyzer/data-model-9.c index 159bc61..2121f20 100644 --- a/gcc/testsuite/gcc.dg/analyzer/data-model-9.c +++ b/gcc/testsuite/gcc.dg/analyzer/data-model-9.c @@ -14,8 +14,7 @@ void test_1 (void) struct foo *f = calloc (1, sizeof (struct foo)); if (f == NULL) return; - __analyzer_eval (f->i == 0); /* { dg-warning "TRUE" "desired" { xfail *-*-* } } */ - /* { dg-bogus "UNKNOWN" "status quo" { xfail *-*-* } .-1 } */ + __analyzer_eval (f->i == 0); /* { dg-warning "TRUE" } */ free (f); } @@ -27,7 +26,6 @@ void test_2 (void) if (f == NULL) return; memset (f, 0, sizeof (struct foo)); - __analyzer_eval (f->i == 0); /* { dg-warning "TRUE" "desired" { xfail *-*-* } } */ - /* { dg-bogus "UNKNOWN" "status quo" { xfail *-*-* } .-1 } */ + __analyzer_eval (f->i == 0); /* { dg-warning "TRUE" } */ free (f); } diff --git a/gcc/testsuite/gcc.dg/analyzer/fd-glibc-byte-stream-connection-server.c b/gcc/testsuite/gcc.dg/analyzer/fd-glibc-byte-stream-connection-server.c index d8b697d..fcbcc74 100644 --- a/gcc/testsuite/gcc.dg/analyzer/fd-glibc-byte-stream-connection-server.c +++ b/gcc/testsuite/gcc.dg/analyzer/fd-glibc-byte-stream-connection-server.c @@ -1,7 +1,7 @@ /* Example from glibc manual (16.9.7). */ /* { dg-require-effective-target sockets } */ /* { dg-additional-options "-Wno-analyzer-too-complex" } */ -/* { dg-skip-if "" { powerpc*-*-aix* } } */ +/* { dg-skip-if "" { hppa*-*-hpux* powerpc*-*-aix* } } */ #include <stdio.h> #include <errno.h> diff --git a/gcc/testsuite/gcc.dg/bic-bitmask-13.c b/gcc/testsuite/gcc.dg/bic-bitmask-13.c index bac86c2..141b03d 100644 --- a/gcc/testsuite/gcc.dg/bic-bitmask-13.c +++ b/gcc/testsuite/gcc.dg/bic-bitmask-13.c @@ -1,5 +1,5 @@ /* { dg-do run } */ -/* { dg-options "-O0 -save-temps -fdump-tree-dce" } */ +/* { dg-options "-O0 -fdump-tree-dce" } */ #include <stdint.h> diff --git a/gcc/testsuite/gcc.dg/bic-bitmask-14.c b/gcc/testsuite/gcc.dg/bic-bitmask-14.c index ec3bd6a..59a008c 100644 --- a/gcc/testsuite/gcc.dg/bic-bitmask-14.c +++ b/gcc/testsuite/gcc.dg/bic-bitmask-14.c @@ -1,5 +1,5 @@ /* { dg-do run } */ -/* { dg-options "-O1 -save-temps -fdump-tree-dce" } */ +/* { dg-options "-O1 -fdump-tree-dce" } */ #include <stdint.h> diff --git a/gcc/testsuite/gcc.dg/bic-bitmask-15.c b/gcc/testsuite/gcc.dg/bic-bitmask-15.c index 8bdf1ea..c28d9b1 100644 --- a/gcc/testsuite/gcc.dg/bic-bitmask-15.c +++ b/gcc/testsuite/gcc.dg/bic-bitmask-15.c @@ -1,5 +1,5 @@ /* { dg-do run } */ -/* { dg-options "-O1 -save-temps -fdump-tree-dce" } */ +/* { dg-options "-O1 -fdump-tree-dce" } */ #include <stdint.h> diff --git a/gcc/testsuite/gcc.dg/bic-bitmask-16.c b/gcc/testsuite/gcc.dg/bic-bitmask-16.c index cfea925..f93912f 100644 --- a/gcc/testsuite/gcc.dg/bic-bitmask-16.c +++ b/gcc/testsuite/gcc.dg/bic-bitmask-16.c @@ -1,5 +1,5 @@ /* { dg-do run } */ -/* { dg-options "-O1 -save-temps -fdump-tree-dce" } */ +/* { dg-options "-O1 -fdump-tree-dce" } */ #include <stdint.h> diff --git a/gcc/testsuite/gcc.dg/bic-bitmask-17.c b/gcc/testsuite/gcc.dg/bic-bitmask-17.c index 86873b9..f8d651b 100644 --- a/gcc/testsuite/gcc.dg/bic-bitmask-17.c +++ b/gcc/testsuite/gcc.dg/bic-bitmask-17.c @@ -1,5 +1,5 @@ /* { dg-do run } */ -/* { dg-options "-O1 -save-temps -fdump-tree-dce" } */ +/* { dg-options "-O1 -fdump-tree-dce" } */ #include <stdint.h> diff --git a/gcc/testsuite/gcc.dg/bic-bitmask-18.c b/gcc/testsuite/gcc.dg/bic-bitmask-18.c index 70bab0c..d6242fe 100644 --- a/gcc/testsuite/gcc.dg/bic-bitmask-18.c +++ b/gcc/testsuite/gcc.dg/bic-bitmask-18.c @@ -1,5 +1,5 @@ /* { dg-do run } */ -/* { dg-options "-O1 -save-temps -fdump-tree-dce" } */ +/* { dg-options "-O1 -fdump-tree-dce" } */ #include <stdint.h> diff --git a/gcc/testsuite/gcc.dg/bic-bitmask-19.c b/gcc/testsuite/gcc.dg/bic-bitmask-19.c index c4620df..aa139da 100644 --- a/gcc/testsuite/gcc.dg/bic-bitmask-19.c +++ b/gcc/testsuite/gcc.dg/bic-bitmask-19.c @@ -1,5 +1,5 @@ /* { dg-do run } */ -/* { dg-options "-O1 -save-temps -fdump-tree-dce" } */ +/* { dg-options "-O1 -fdump-tree-dce" } */ #include <stdint.h> diff --git a/gcc/testsuite/gcc.dg/bic-bitmask-20.c b/gcc/testsuite/gcc.dg/bic-bitmask-20.c index a114122..849eca4 100644 --- a/gcc/testsuite/gcc.dg/bic-bitmask-20.c +++ b/gcc/testsuite/gcc.dg/bic-bitmask-20.c @@ -1,5 +1,5 @@ /* { dg-do run } */ -/* { dg-options "-O1 -save-temps -fdump-tree-dce" } */ +/* { dg-options "-O1 -fdump-tree-dce" } */ #include <stdint.h> diff --git a/gcc/testsuite/gcc.dg/bic-bitmask-21.c b/gcc/testsuite/gcc.dg/bic-bitmask-21.c index bd12a58..9aecd72 100644 --- a/gcc/testsuite/gcc.dg/bic-bitmask-21.c +++ b/gcc/testsuite/gcc.dg/bic-bitmask-21.c @@ -1,5 +1,5 @@ /* { dg-do run } */ -/* { dg-options "-O1 -save-temps -fdump-tree-dce" } */ +/* { dg-options "-O1 -fdump-tree-dce" } */ #include <stdint.h> diff --git a/gcc/testsuite/gcc.dg/bic-bitmask-22.c b/gcc/testsuite/gcc.dg/bic-bitmask-22.c index a9f0867..a51a071 100644 --- a/gcc/testsuite/gcc.dg/bic-bitmask-22.c +++ b/gcc/testsuite/gcc.dg/bic-bitmask-22.c @@ -1,5 +1,5 @@ /* { dg-do run } */ -/* { dg-options "-O1 -save-temps -fdump-tree-dce" } */ +/* { dg-options "-O1 -fdump-tree-dce" } */ #include <stdint.h> diff --git a/gcc/testsuite/gcc.dg/bic-bitmask-7.c b/gcc/testsuite/gcc.dg/bic-bitmask-7.c index bc49f29..42949f7 100644 --- a/gcc/testsuite/gcc.dg/bic-bitmask-7.c +++ b/gcc/testsuite/gcc.dg/bic-bitmask-7.c @@ -1,5 +1,5 @@ /* { dg-do run } */ -/* { dg-options "-O3 -save-temps -fdump-tree-dce" } */ +/* { dg-options "-O3 -fdump-tree-dce" } */ #include <stdint.h> diff --git a/gcc/testsuite/gcc.dg/bitint-31.c b/gcc/testsuite/gcc.dg/bitint-31.c index d73ec6e..94611bf 100644 --- a/gcc/testsuite/gcc.dg/bitint-31.c +++ b/gcc/testsuite/gcc.dg/bitint-31.c @@ -280,7 +280,7 @@ main () check_round (testfltu_575 (123665200736552267030251260509823595017565674550605919957031528046448612553265933585158200530621522494798835713008069669675682517153375604983773077550946583958303386074349567uwb), __builtin_inff (), 0xffffffp+104f, __builtin_inff (), 0xffffffp+104f); #endif #endif -#if __DBL_MANT_DIG__, 53 +#if __DBL_MANT_DIG__ == 53 #if __BITINT_MAXWIDTH__ >= 135 check_round (testdbl_135 (-21267647932558650424686050812251602943wb), -0x1ffffffffffffep+71, -0x1fffffffffffffp+71, -0x1ffffffffffffep+71, -0x1ffffffffffffep+71); check_round (testdbl_135 (-21267647932558650424686050812251602944wb), -0x1ffffffffffffep+71, -0x1fffffffffffffp+71, -0x1ffffffffffffep+71, -0x1ffffffffffffep+71); @@ -360,7 +360,7 @@ main () check_round (testdblu_575 (123665200736552267030251260509823595017565674550605919957031528046448612553265933585158200530621522494798835713008069669675682517153375604983773077550946583958303386074349567uwb), 0x20000000000000p+522, 0x1fffffffffffffp+522, 0x20000000000000p+522, 0x1fffffffffffffp+522); #endif #endif -#if __LDBL_MANT_DIG__, 64 +#if __LDBL_MANT_DIG__ == 64 #if __BITINT_MAXWIDTH__ >= 135 check_round (testldbl_135 (-27577662721237071616947187835994111wb), -0xa9f5e144d113e1c4p+51L, -0xa9f5e144d113e1c5p+51L, -0xa9f5e144d113e1c4p+51L, -0xa9f5e144d113e1c4p+51L); check_round (testldbl_135 (-27577662721237071616947187835994112wb), -0xa9f5e144d113e1c4p+51L, -0xa9f5e144d113e1c5p+51L, -0xa9f5e144d113e1c4p+51L, -0xa9f5e144d113e1c4p+51L); @@ -426,7 +426,7 @@ main () check_round (testldblu_575 (123665200736552267030251260509823595017565674550605919957031528046448612553265933585158200530621522494798835713008069669675682517153375604983773077550946583958303386074349567uwb), 0x10000000000000000p+511L, 0xffffffffffffffffp+511L, 0x10000000000000000p+511L, 0xffffffffffffffffp+511L); #endif #endif -#if __FLT128_MANT_DIG__, 113 +#if __FLT128_MANT_DIG__ == 113 #if __BITINT_MAXWIDTH__ >= 135 check_round (testflt128_135 (-21646332438261169091754659013488783917055wb), -0x1fce71fdcfb1797b42dede66ac9ecp+21F128, -0x1fce71fdcfb1797b42dede66ac9edp+21F128, -0x1fce71fdcfb1797b42dede66ac9ecp+21F128, -0x1fce71fdcfb1797b42dede66ac9ecp+21F128); check_round (testflt128_135 (-21646332438261169091754659013488783917056wb), -0x1fce71fdcfb1797b42dede66ac9ecp+21F128, -0x1fce71fdcfb1797b42dede66ac9edp+21F128, -0x1fce71fdcfb1797b42dede66ac9ecp+21F128, -0x1fce71fdcfb1797b42dede66ac9ecp+21F128); diff --git a/gcc/testsuite/gcc.dg/bitint-63.c b/gcc/testsuite/gcc.dg/bitint-63.c new file mode 100644 index 0000000..a069846 --- /dev/null +++ b/gcc/testsuite/gcc.dg/bitint-63.c @@ -0,0 +1,24 @@ +/* PR tree-optimization/113297 */ +/* { dg-do compile { target bitint } } */ +/* { dg-require-stack-check "generic" } */ +/* { dg-options "-std=c23 -O -fno-tree-fre --param=large-stack-frame=1024 -fstack-check=generic" } */ + +#if __BITINT_MAXWIDTH__ >= 513 +typedef _BitInt(513) B; +#else +typedef int B; +#endif + +static inline __attribute__((__always_inline__)) void +bar (B x) +{ + B y = x; + if (y) + __builtin_abort (); +} + +void +foo (void) +{ + bar (0); +} diff --git a/gcc/testsuite/gcc.dg/bitint-64.c b/gcc/testsuite/gcc.dg/bitint-64.c new file mode 100644 index 0000000..0c7524c --- /dev/null +++ b/gcc/testsuite/gcc.dg/bitint-64.c @@ -0,0 +1,16 @@ +/* PR tree-optimization/112734 */ +/* { dg-do compile { target bitint } } */ +/* { dg-options "-std=c23 -fnon-call-exceptions -ftrapv" } */ + +#if __BITINT_MAXWIDTH__ >= 128 +_BitInt(128) out; +#else +int out; +#endif + +int +main () +{ + _BitInt(8) q[1]; + out -= 1; +} diff --git a/gcc/testsuite/gcc.dg/bitint-65.c b/gcc/testsuite/gcc.dg/bitint-65.c new file mode 100644 index 0000000..f0b9520 --- /dev/null +++ b/gcc/testsuite/gcc.dg/bitint-65.c @@ -0,0 +1,23 @@ +/* PR c/113315 */ +/* { dg-do compile { target bitint } } */ +/* { dg-options "-std=c23" } */ + +#if __BITINT_MAXWIDTH__ >= 535 +_BitInt(535) x; +#else +_BitInt(64) x; +#endif +extern int a[]; +extern char b[][10]; + +int +foo (void) +{ + return a[x]; +} + +int +bar (void) +{ + return __builtin_strlen (b[x]); +} diff --git a/gcc/testsuite/gcc.dg/bitint-66.c b/gcc/testsuite/gcc.dg/bitint-66.c new file mode 100644 index 0000000..7bffa12 --- /dev/null +++ b/gcc/testsuite/gcc.dg/bitint-66.c @@ -0,0 +1,12 @@ +/* PR c/113315 */ +/* { dg-do compile { target bitint } } */ +/* { dg-options "-std=c23 -O2" } */ + +extern int a[5]; + +int +foo (void) +{ + _BitInt(535) i = 1; + return a[i]; +} diff --git a/gcc/testsuite/gcc.dg/bitint-67.c b/gcc/testsuite/gcc.dg/bitint-67.c new file mode 100644 index 0000000..fefa33a --- /dev/null +++ b/gcc/testsuite/gcc.dg/bitint-67.c @@ -0,0 +1,12 @@ +/* PR tree-optimization/113316 */ +/* { dg-do compile { target bitint575 } } */ +/* { dg-options "-std=c23 -O2 -w" } */ + +void bar (_BitInt(535) y); + +void +foo (void) +{ + _BitInt(535) y; + bar (y); +} diff --git a/gcc/testsuite/gcc.dg/bitint-68.c b/gcc/testsuite/gcc.dg/bitint-68.c new file mode 100644 index 0000000..092f31a --- /dev/null +++ b/gcc/testsuite/gcc.dg/bitint-68.c @@ -0,0 +1,14 @@ +/* PR tree-optimization/113323 */ +/* { dg-do compile { target bitint575 } } */ +/* { dg-options "-std=c23 -O2" } */ + +typedef long __attribute__((__vector_size__ (16))) V; +V u, v; +_BitInt(535) i; + +void +foo (void) +{ + while (i) + u = v; +} diff --git a/gcc/testsuite/gcc.dg/bitint-69.c b/gcc/testsuite/gcc.dg/bitint-69.c new file mode 100644 index 0000000..c225cbd --- /dev/null +++ b/gcc/testsuite/gcc.dg/bitint-69.c @@ -0,0 +1,25 @@ +/* PR tree-optimization/113330 */ +/* { dg-do compile { target bitint } } */ +/* { dg-require-stack-check "generic" } */ +/* { dg-options "-std=c23 -O --param=large-stack-frame=131072 -fstack-check=generic --param=sccvn-max-alias-queries-per-access=0" } */ + +_BitInt(8) a; + +static inline __attribute__((__always_inline__)) void +bar (int, int, int, int, int, int, int, int) +{ +#if __BITINT_MAXWIDTH__ >= 65535 + _BitInt(65535) b = 0; + _BitInt(383) c = 0; +#else + _BitInt(63) b = 0; + _BitInt(39) c = 0; +#endif + a = b; +} + +void +foo (void) +{ + bar (0, 0, 0, 0, 0, 0, 0, 0); +} diff --git a/gcc/testsuite/gcc.dg/builtin-dynamic-object-size-0.c b/gcc/testsuite/gcc.dg/builtin-dynamic-object-size-0.c index c3ac623..173e7c7 100644 --- a/gcc/testsuite/gcc.dg/builtin-dynamic-object-size-0.c +++ b/gcc/testsuite/gcc.dg/builtin-dynamic-object-size-0.c @@ -1,6 +1,7 @@ /* { dg-do run } */ /* { dg-options "-O2" } */ /* { dg-require-effective-target size20plus } */ +/* { dg-skip-if "no strndup" { hppa*-*-hpux* } } */ #include "builtin-object-size-common.h" diff --git a/gcc/testsuite/gcc.dg/builtin-dynamic-object-size-1.c b/gcc/testsuite/gcc.dg/builtin-dynamic-object-size-1.c index 8f17c8e..ffa5998 100644 --- a/gcc/testsuite/gcc.dg/builtin-dynamic-object-size-1.c +++ b/gcc/testsuite/gcc.dg/builtin-dynamic-object-size-1.c @@ -1,6 +1,7 @@ /* { dg-do run } */ /* { dg-options "-O2 -Wno-stringop-overread" } */ /* { dg-require-effective-target alloca } */ +/* { dg-skip-if "no strndup" { hppa*-*-hpux* } } */ #define __builtin_object_size __builtin_dynamic_object_size #include "builtin-object-size-1.c" diff --git a/gcc/testsuite/gcc.dg/builtin-dynamic-object-size-2.c b/gcc/testsuite/gcc.dg/builtin-dynamic-object-size-2.c index 3677782..fff32da 100644 --- a/gcc/testsuite/gcc.dg/builtin-dynamic-object-size-2.c +++ b/gcc/testsuite/gcc.dg/builtin-dynamic-object-size-2.c @@ -1,6 +1,7 @@ /* { dg-do run } */ /* { dg-options "-O2 -Wno-stringop-overread" } */ /* { dg-require-effective-target alloca } */ +/* { dg-skip-if "no strndup" { hppa*-*-hpux* } } */ #define __builtin_object_size __builtin_dynamic_object_size #include "builtin-object-size-2.c" diff --git a/gcc/testsuite/gcc.dg/builtin-dynamic-object-size-3.c b/gcc/testsuite/gcc.dg/builtin-dynamic-object-size-3.c index 5b6987b..ac223d6 100644 --- a/gcc/testsuite/gcc.dg/builtin-dynamic-object-size-3.c +++ b/gcc/testsuite/gcc.dg/builtin-dynamic-object-size-3.c @@ -1,6 +1,7 @@ /* { dg-do run } */ /* { dg-options "-O2 -Wno-stringop-overread" } */ /* { dg-require-effective-target alloca } */ +/* { dg-skip-if "no strndup" { hppa*-*-hpux* } } */ #define __builtin_object_size __builtin_dynamic_object_size #include "builtin-object-size-3.c" diff --git a/gcc/testsuite/gcc.dg/builtin-dynamic-object-size-4.c b/gcc/testsuite/gcc.dg/builtin-dynamic-object-size-4.c index 9d79622..fdf4284 100644 --- a/gcc/testsuite/gcc.dg/builtin-dynamic-object-size-4.c +++ b/gcc/testsuite/gcc.dg/builtin-dynamic-object-size-4.c @@ -1,6 +1,7 @@ /* { dg-do run } */ /* { dg-options "-O2 -Wno-stringop-overread" } */ /* { dg-require-effective-target alloca } */ +/* { dg-skip-if "no strndup" { hppa*-*-hpux* } } */ #define __builtin_object_size __builtin_dynamic_object_size #include "builtin-object-size-4.c" diff --git a/gcc/testsuite/gcc.dg/builtin-object-size-1.c b/gcc/testsuite/gcc.dg/builtin-object-size-1.c index 64c4bc4..4f7d4c0 100644 --- a/gcc/testsuite/gcc.dg/builtin-object-size-1.c +++ b/gcc/testsuite/gcc.dg/builtin-object-size-1.c @@ -621,7 +621,7 @@ test10 (void) } } -#ifndef __AVR__ /* avr has no strndup */ +#if !defined(__AVR__) && !defined(__hpux__) /* avr and hpux have no strndup */ /* Tests for strdup/strndup. */ size_t __attribute__ ((noinline)) @@ -726,7 +726,7 @@ main (void) test8 (); test9 (1); test10 (); -#ifndef __AVR__ /* avr has no strndup */ +#if !defined(__AVR__) && !defined(__hpux__) /* avr and hpux have no strndup */ test11 (); #endif DONE (); diff --git a/gcc/testsuite/gcc.dg/builtin-object-size-2.c b/gcc/testsuite/gcc.dg/builtin-object-size-2.c index da10b6b..37d3dcc 100644 --- a/gcc/testsuite/gcc.dg/builtin-object-size-2.c +++ b/gcc/testsuite/gcc.dg/builtin-object-size-2.c @@ -536,7 +536,7 @@ test8 (unsigned cond) #endif } -#ifndef __AVR__ /* avr has no strndup */ +#if !defined(__AVR__) && !defined(__hpux__) /* avr and hpux have no strndup */ /* Tests for strdup/strndup. */ size_t __attribute__ ((noinline)) @@ -639,7 +639,7 @@ main (void) test6 (); test7 (); test8 (1); -#ifndef __AVR__ /* avr has no strndup */ +#if !defined(__AVR__) && !defined(__hpux__) /* avr and hpux have no strndup */ test9 (); #endif DONE (); diff --git a/gcc/testsuite/gcc.dg/builtin-object-size-3.c b/gcc/testsuite/gcc.dg/builtin-object-size-3.c index f23873b..f4d1ebf 100644 --- a/gcc/testsuite/gcc.dg/builtin-object-size-3.c +++ b/gcc/testsuite/gcc.dg/builtin-object-size-3.c @@ -628,7 +628,7 @@ test10 (void) } } -#ifndef __AVR__ /* avr has no strndup */ +#if !defined(__AVR__) && !defined(__hpux__) /* avr and hpux have no strndup */ /* Tests for strdup/strndup. */ size_t __attribute__ ((noinline)) @@ -734,7 +734,7 @@ main (void) test8 (); test9 (1); test10 (); -#ifndef __AVR__ /* avr has no strndup */ +#if !defined(__AVR__) && !defined(__hpux__) /* avr and hpux have no strndup */ test11 (); #endif DONE (); diff --git a/gcc/testsuite/gcc.dg/builtin-object-size-4.c b/gcc/testsuite/gcc.dg/builtin-object-size-4.c index dcb042f..2887dd1 100644 --- a/gcc/testsuite/gcc.dg/builtin-object-size-4.c +++ b/gcc/testsuite/gcc.dg/builtin-object-size-4.c @@ -509,7 +509,7 @@ test8 (unsigned cond) #endif } -#ifndef __AVR__ /* avr has no strndup */ +#if !defined(__AVR__) && !defined(__hpux__) /* avr and hpux have no strndup */ /* Tests for strdup/strndup. */ size_t __attribute__ ((noinline)) @@ -612,7 +612,7 @@ main (void) test6 (); test7 (); test8 (1); -#ifndef __AVR__ /* avr has no strndup */ +#if !defined(__AVR__) && !defined(__hpux__) /* avr and hpux have no strndup */ test9 (); #endif DONE (); diff --git a/gcc/testsuite/gcc.dg/debug/dwarf2/pr111080.c b/gcc/testsuite/gcc.dg/debug/dwarf2/pr111080.c index 3949d7e..617e5e4 100644 --- a/gcc/testsuite/gcc.dg/debug/dwarf2/pr111080.c +++ b/gcc/testsuite/gcc.dg/debug/dwarf2/pr111080.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-save-temps -gdwarf-3 -dA" } */ +/* { dg-options "-gdwarf-3 -dA" } */ struct foo { int field_number_1; diff --git a/gcc/testsuite/gcc.dg/debug/dwarf2/pr47939-1.c b/gcc/testsuite/gcc.dg/debug/dwarf2/pr47939-1.c index 3dc8e67..0777c1f 100644 --- a/gcc/testsuite/gcc.dg/debug/dwarf2/pr47939-1.c +++ b/gcc/testsuite/gcc.dg/debug/dwarf2/pr47939-1.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-save-temps -gdwarf -dA" } */ +/* { dg-options "-gdwarf -dA" } */ typedef struct _Harry { int dummy; } Harry_t; Harry_t harry; diff --git a/gcc/testsuite/gcc.dg/debug/dwarf2/pr47939-2.c b/gcc/testsuite/gcc.dg/debug/dwarf2/pr47939-2.c index abc1dc1..932c070 100644 --- a/gcc/testsuite/gcc.dg/debug/dwarf2/pr47939-2.c +++ b/gcc/testsuite/gcc.dg/debug/dwarf2/pr47939-2.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-save-temps -gdwarf -dA" } */ +/* { dg-options "-gdwarf -dA" } */ typedef const struct _Harry { int dummy; } Harry_t; Harry_t harry; diff --git a/gcc/testsuite/gcc.dg/debug/dwarf2/pr47939-3.c b/gcc/testsuite/gcc.dg/debug/dwarf2/pr47939-3.c index 78234e9..858432a 100644 --- a/gcc/testsuite/gcc.dg/debug/dwarf2/pr47939-3.c +++ b/gcc/testsuite/gcc.dg/debug/dwarf2/pr47939-3.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-save-temps -gdwarf -dA" } */ +/* { dg-options "-gdwarf -dA" } */ typedef struct _Harry { int dummy; } Harry_t; const Harry_t harry[5]; diff --git a/gcc/testsuite/gcc.dg/debug/dwarf2/pr47939-4.c b/gcc/testsuite/gcc.dg/debug/dwarf2/pr47939-4.c index 89a048d..57b4c5c 100644 --- a/gcc/testsuite/gcc.dg/debug/dwarf2/pr47939-4.c +++ b/gcc/testsuite/gcc.dg/debug/dwarf2/pr47939-4.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-save-temps -gdwarf -dA" } */ +/* { dg-options "-gdwarf -dA" } */ typedef const struct _Harry { int dummy; } Harry_t; Harry_t harry[10]; diff --git a/gcc/testsuite/gcc.dg/fold-copysign-1.c b/gcc/testsuite/gcc.dg/fold-copysign-1.c index f9cafd1..96b80c7 100644 --- a/gcc/testsuite/gcc.dg/fold-copysign-1.c +++ b/gcc/testsuite/gcc.dg/fold-copysign-1.c @@ -1,5 +1,6 @@ /* { dg-do compile } */ /* { dg-options "-O -fdump-tree-cddce1" } */ +/* { dg-additional-options "-msse -mfpmath=sse" { target { { i?86-*-* x86_64-*-* } && ilp32 } } } */ double foo (double x) { @@ -12,5 +13,7 @@ double bar (double x) return __builtin_copysign (x, minuszero); } -/* { dg-final { scan-tree-dump-times "__builtin_copysign" 1 "cddce1" } } */ -/* { dg-final { scan-tree-dump-times "= ABS_EXPR" 1 "cddce1" } } */ +/* { dg-final { scan-tree-dump-times "__builtin_copysign" 1 "cddce1" { target ifn_copysign } } } */ +/* { dg-final { scan-tree-dump-times "= ABS_EXPR" 1 "cddce1" { target ifn_copysign } } } */ +/* { dg-final { scan-tree-dump-times "= -" 1 "cddce1" { target { ! ifn_copysign } } } } */ +/* { dg-final { scan-tree-dump-times "= ABS_EXPR" 2 "cddce1" { target { ! ifn_copysign } } } } */ diff --git a/gcc/testsuite/gcc.dg/gomp/bad-array-section-c-1.c b/gcc/testsuite/gcc.dg/gomp/bad-array-section-c-1.c new file mode 100644 index 0000000..36b2426 --- /dev/null +++ b/gcc/testsuite/gcc.dg/gomp/bad-array-section-c-1.c @@ -0,0 +1,16 @@ +/* { dg-do compile } */ + +int foo (int *ptr); + +int main() +{ + int arr[20]; + /* Reject array section as function argument. */ +#pragma omp target map(foo(arr[3:5])) +/* { dg-error {expected '\]' before ':' token} "" { target *-*-* } .-1 } */ +/* { dg-error {passing argument 1 of 'foo' makes pointer from integer without a cast} "" { target *-*-* } .-2 } */ +/* { dg-message {sorry, unimplemented: unsupported map expression} "" { target *-*-* } .-3 } */ + { } + + return 0; +} diff --git a/gcc/testsuite/gcc.dg/gomp/bad-array-section-c-2.c b/gcc/testsuite/gcc.dg/gomp/bad-array-section-c-2.c new file mode 100644 index 0000000..449487a --- /dev/null +++ b/gcc/testsuite/gcc.dg/gomp/bad-array-section-c-2.c @@ -0,0 +1,13 @@ +/* { dg-do compile } */ + +int main() +{ + int arr[20]; + /* Reject array section in statement expression. */ +#pragma omp target map( ({ int x = 5; arr[0:x]; }) ) +/* { dg-error {expected '\]' before ':' token} "" { target *-*-* } .-1 } */ +/* { dg-message {sorry, unimplemented: unsupported map expression} "" { target *-*-* } .-2 } */ + { } + + return 0; +} diff --git a/gcc/testsuite/gcc.dg/gomp/bad-array-section-c-3.c b/gcc/testsuite/gcc.dg/gomp/bad-array-section-c-3.c new file mode 100644 index 0000000..8be15ce --- /dev/null +++ b/gcc/testsuite/gcc.dg/gomp/bad-array-section-c-3.c @@ -0,0 +1,24 @@ +/* { dg-do compile } */ + +struct S { + int *ptr; +}; + +int main() +{ + int arr[20]; + + /* Reject array section in compound initialiser. */ +#pragma omp target map( (struct S) { .ptr = (int *) arr[5:5] } ) +/* { dg-error {expected '\]' before ':' token} "" { target *-*-* } .-1 } */ +/* { dg-warning {cast to pointer from integer of different size} "" { target *-*-* } .-2 } */ +/* { dg-message {sorry, unimplemented: unsupported map expression} "" { target *-*-* } .-3 } */ + { } + + /* ...and this is unsupported too (probably not useful anyway). */ +#pragma omp target map( (struct S) { .ptr = &arr[5] } ) +/* { dg-message {sorry, unimplemented: unsupported map expression} "" { target *-*-* } .-1 } */ + { } + + return 0; +} diff --git a/gcc/testsuite/gcc.dg/gomp/bad-array-section-c-4.c b/gcc/testsuite/gcc.dg/gomp/bad-array-section-c-4.c new file mode 100644 index 0000000..b78cdfc --- /dev/null +++ b/gcc/testsuite/gcc.dg/gomp/bad-array-section-c-4.c @@ -0,0 +1,26 @@ +/* { dg-do compile } */ + +int x; + +int main() +{ + int arr[20]; + int *ptr; + /* "arr[1:10]" looks like it might be an expression of array type, hence + able to be indexed (again). This isn't allowed, though. */ +#pragma omp target map(arr[1:10][2]) +/* { dg-error {'arr\[1\]' does not have pointer or array type} "" { target *-*-* } .-1 } */ + { } +#pragma omp target map(arr[1:x][2]) +/* { dg-error {'arr\[1\]' does not have pointer or array type} "" { target *-*-* } .-1 } */ + { } + /* ...and nor is this. */ +#pragma omp target map(ptr[1:10][2]) +/* { dg-error {'\*\(ptr \+ [0-9]+\)' does not have pointer or array type} "" { target *-*-* } .-1 } */ + { } +#pragma omp target map(ptr[1:x][2]) +/* { dg-error {'\*\(ptr \+ [0-9]+\)' does not have pointer or array type} "" { target *-*-* } .-1 } */ + { } + + return 0; +} diff --git a/gcc/testsuite/gcc.dg/gomp/bad-array-section-c-5.c b/gcc/testsuite/gcc.dg/gomp/bad-array-section-c-5.c new file mode 100644 index 0000000..2880d17 --- /dev/null +++ b/gcc/testsuite/gcc.dg/gomp/bad-array-section-c-5.c @@ -0,0 +1,15 @@ +/* { dg-do compile } */ + +int partly = 0; + +int main() +{ + int arr[20]; +#pragma omp target map(partly ? arr[5:5] : arr) +/* { dg-error {expected '\]' before ':' token} "" { target *-*-* } .-1 } */ +/* { dg-error {pointer/integer type mismatch in conditional expression} "" { target *-*-* } .-2 } */ +/* { dg-message {sorry, unimplemented: unsupported map expression} "" { target *-*-* } .-3 } */ + { } + + return 0; +} diff --git a/gcc/testsuite/gcc.dg/gomp/bad-array-section-c-6.c b/gcc/testsuite/gcc.dg/gomp/bad-array-section-c-6.c new file mode 100644 index 0000000..bfca4f0 --- /dev/null +++ b/gcc/testsuite/gcc.dg/gomp/bad-array-section-c-6.c @@ -0,0 +1,16 @@ +/* { dg-do compile } */ + +int x; + +int main() +{ + int arr[20]; +#pragma omp target map(arr[5:5] * 2) +/* { dg-error {invalid operands to binary \*} "" { target *-*-* } .-1 } */ + { } +#pragma omp target map(arr[x:5] * 2) +/* { dg-error {invalid operands to binary \*} "" { target *-*-* } .-1 } */ + { } + + return 0; +} diff --git a/gcc/testsuite/gcc.dg/gomp/bad-array-section-c-7.c b/gcc/testsuite/gcc.dg/gomp/bad-array-section-c-7.c new file mode 100644 index 0000000..1fd9e2b --- /dev/null +++ b/gcc/testsuite/gcc.dg/gomp/bad-array-section-c-7.c @@ -0,0 +1,26 @@ +/* { dg-do compile } */ + +int x; + +struct T { + int arr[20]; +}; + +struct S { + struct T *tvec; +}; + +int main() +{ + struct S *s; + /* You can't use an array section like this. Make sure sensible errors are + reported. */ +#pragma omp target map(s->tvec[3:5].arr[0:20]) +/* { dg-error {'\(struct T \*\)&s->tvec\[3:5\]' is a pointer; did you mean to use '->'\?} "" { target *-*-* } .-1 } */ + { } +#pragma omp target map(s->tvec[5:x].arr[0:20]) +/* { dg-error {'\(struct T \*\)&s->tvec\[5:x\]' is a pointer; did you mean to use '->'\?} "" { target *-*-* } .-1 } */ + { } + + return 0; +} diff --git a/gcc/testsuite/gcc.dg/gomp/bad-array-section-c-8.c b/gcc/testsuite/gcc.dg/gomp/bad-array-section-c-8.c new file mode 100644 index 0000000..f90eca1 --- /dev/null +++ b/gcc/testsuite/gcc.dg/gomp/bad-array-section-c-8.c @@ -0,0 +1,21 @@ +/* { dg-do compile } */ + +int x; + +int main() +{ + int arr1[40]; + int arr2[40]; +#pragma omp target map(arr1[arr2[4:5]:arr2[6:7]]) +/* { dg-error {low bound 'arr2\[4:5\]' of array section does not have integral type} "" { target *-*-* } .-1 } */ + { } +#pragma omp target map(arr1[arr2[:1]:arr2[6:1]]) +/* { dg-error {low bound 'arr2\[:1\]' of array section does not have integral type} "" { target *-*-* } .-1 } */ + { } +#pragma omp target map(arr1[x:arr2[6:1]]) +/* { dg-error {length 'arr2\[6:1\]' of array section does not have integral type} "" { target *-*-* } .-1 } */ + { } + + return 0; +} + diff --git a/gcc/testsuite/gcc.dg/ifcvt-4.c b/gcc/testsuite/gcc.dg/ifcvt-4.c index 8b2583d..99ed348 100644 --- a/gcc/testsuite/gcc.dg/ifcvt-4.c +++ b/gcc/testsuite/gcc.dg/ifcvt-4.c @@ -3,6 +3,7 @@ /* { dg-additional-options "-march=z196" { target { s390x-*-* } } } */ /* { dg-additional-options "-mtune-ctrl=^one_if_conv_insn" { target { i?86-*-* x86_64-*-* } } } */ /* { dg-skip-if "Multiple set if-conversion not guaranteed on all subtargets" { "arm*-*-* avr-*-* cris-*-* hppa*64*-*-* visium-*-*" riscv*-*-* msp430-*-* nios2-*-* pru-*-* } } */ +/* { dg-skip-if "" { { sparc*-*-* } && { ! sparc_v9 } } } */ /* { dg-skip-if "" { "s390x-*-*" } { "-m31" } } */ typedef int word __attribute__((mode(word))); diff --git a/gcc/testsuite/gcc.dg/lto/pr88077_0.c b/gcc/testsuite/gcc.dg/lto/pr88077_0.c index 924fe9f..9455295 100644 --- a/gcc/testsuite/gcc.dg/lto/pr88077_0.c +++ b/gcc/testsuite/gcc.dg/lto/pr88077_0.c @@ -1,3 +1,7 @@ /* { dg-lto-do link } */ +#if defined __sparc__ +long long HeaderStr; +#else long HeaderStr; +#endif diff --git a/gcc/testsuite/gcc.dg/pr112636.c b/gcc/testsuite/gcc.dg/pr112636.c new file mode 100644 index 0000000..284ae8f --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr112636.c @@ -0,0 +1,13 @@ +/* { dg-do compile } */ +/* { dg-options "-O -ftree-vectorize" } */ + +int a[1], b; +unsigned c; +int main() { + while (b) { + if (a[c]) + break; + c--; + } + return 0; +} diff --git a/gcc/testsuite/gcc.dg/pr112740.c b/gcc/testsuite/gcc.dg/pr112740.c new file mode 100644 index 0000000..8250caf --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr112740.c @@ -0,0 +1,19 @@ +/* { dg-do run { target { int128 } } } */ +/* { dg-options "" } */ + +typedef unsigned __int128 __attribute__((__vector_size__ (16))) V; + +V +foo (unsigned c, V v) +{ + return (V) (c <= v) == 0; +} + +int +main (void) +{ + V x = foo (0, (V) { }); + if (x[0]) + __builtin_abort (); + return 0; +} diff --git a/gcc/testsuite/gcc.dg/pr30957-1.c b/gcc/testsuite/gcc.dg/pr30957-1.c deleted file mode 100644 index 5644109..0000000 --- a/gcc/testsuite/gcc.dg/pr30957-1.c +++ /dev/null @@ -1,36 +0,0 @@ -/* { dg-do run { xfail { mmix-*-* } } } */ -/* We don't (and don't want to) perform this optimisation on soft-float targets, - where each addition is a library call. / -/* { dg-require-effective-target hard_float } */ -/* -fassociative-math requires -fno-trapping-math and -fno-signed-zeros. */ -/* { dg-options "-O2 -funroll-loops -fassociative-math -fno-trapping-math -fno-signed-zeros -fvariable-expansion-in-unroller -fdump-rtl-loop2_unroll" } */ - -extern void abort (void); -extern void exit (int); - -float __attribute__((noinline)) -foo (float d, int n) -{ - unsigned i; - float accum = d; - - for (i = 0; i < n; i++) - accum += d; - - return accum; -} - -int -main () -{ - /* When compiling standard compliant we expect foo to return -0.0. But the - variable expansion during unrolling optimization (for this testcase enabled - by non-compliant -fassociative-math) instantiates copy(s) of the - accumulator which it initializes with +0.0. Hence we expect that foo - returns +0.0. */ - if (__builtin_copysignf (1.0, foo (0.0 / -5.0, 10)) != 1.0) - abort (); - exit (0); -} - -/* { dg-final { scan-rtl-dump "Expanding Accumulator" "loop2_unroll" { xfail mmix-*-* } } } */ diff --git a/gcc/testsuite/gcc.dg/pr55152-2.c b/gcc/testsuite/gcc.dg/pr55152-2.c index 605f202..24068cf 100644 --- a/gcc/testsuite/gcc.dg/pr55152-2.c +++ b/gcc/testsuite/gcc.dg/pr55152-2.c @@ -1,5 +1,6 @@ /* { dg-do compile } */ /* { dg-options "-O -ffinite-math-only -fno-signed-zeros -fstrict-overflow -fdump-tree-optimized" } */ +/* { dg-additional-options "-msse -mfpmath=sse" { target { { i?86-*-* x86_64-*-* } && ilp32 } } } */ double g (double a) { @@ -10,5 +11,6 @@ int f(int a) return (a<-a)?a:-a; } -/* { dg-final { scan-tree-dump-times "\.COPYSIGN" 1 "optimized" } } */ -/* { dg-final { scan-tree-dump-times "ABS_EXPR" 1 "optimized" } } */ +/* { dg-final { scan-tree-dump-times "\.COPYSIGN" 1 "optimized" { target ifn_copysign } } } */ +/* { dg-final { scan-tree-dump-times "ABS_EXPR" 1 "optimized" { target ifn_copysign } } } */ +/* { dg-final { scan-tree-dump-times "ABS_EXPR" 2 "optimized" { target { ! ifn_copysign } } } } */ diff --git a/gcc/testsuite/gcc.dg/torture/bitint-46.c b/gcc/testsuite/gcc.dg/torture/bitint-46.c new file mode 100644 index 0000000..af0a3d1 --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/bitint-46.c @@ -0,0 +1,32 @@ +/* PR tree-optimization/113334 */ +/* { dg-do run { target bitint } } */ +/* { dg-options "-std=c23 -pedantic-errors" } */ +/* { dg-skip-if "" { ! run_expensive_tests } { "*" } { "-O0" "-O2" } } */ +/* { dg-skip-if "" { ! run_expensive_tests } { "-flto" } { "" } } */ + +#if __BITINT_MAXWIDTH__ >= 384 +__attribute__((noipa)) _BitInt(384) +foo (int s) +{ + _BitInt(384) z = (-(unsigned _BitInt(384)) 4) >> s; + return z; +} +#endif + +int +main () +{ +#if __BITINT_MAXWIDTH__ >= 384 + if (foo (59) != 0x1fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffwb) + __builtin_abort (); + if (foo (0) != -4wb) + __builtin_abort (); + if (foo (1) != 0x7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffewb) + __builtin_abort (); + if (foo (11) != 0x001fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffwb) + __builtin_abort (); + if (foo (123) != 0x1fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffwb) + __builtin_abort (); +#endif + return 0; +} diff --git a/gcc/testsuite/gcc.dg/torture/bitint-47.c b/gcc/testsuite/gcc.dg/torture/bitint-47.c new file mode 100644 index 0000000..fa70d80 --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/bitint-47.c @@ -0,0 +1,31 @@ +/* PR tree-optimization/113361 */ +/* { dg-do run { target { bitint && int128 } } } */ +/* { dg-options "-std=gnu23" } */ +/* { dg-skip-if "" { ! run_expensive_tests } { "*" } { "-O0" "-O2" } } */ +/* { dg-skip-if "" { ! run_expensive_tests } { "-flto" } { "" } } */ + +#if __BITINT_MAXWIDTH__ >= 129 +int +foo (_BitInt(65) x) +{ + return __builtin_mul_overflow_p ((__int128) 0xffffffff << 64, x, (_BitInt(129)) 0); +} + +int +bar (_BitInt(63) x) +{ + return __builtin_mul_overflow_p ((__int128) 0xffffffff << 64, x, (_BitInt(129)) 0); +} +#endif + +int +main () +{ +#if __BITINT_MAXWIDTH__ >= 129 + if (!foo (5167856845)) + __builtin_abort (); + if (!bar (5167856845)) + __builtin_abort (); +#endif + return 0; +} diff --git a/gcc/testsuite/gcc.dg/torture/bitint-48.c b/gcc/testsuite/gcc.dg/torture/bitint-48.c new file mode 100644 index 0000000..d6f8459 --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/bitint-48.c @@ -0,0 +1,23 @@ +/* PR tree-optimization/113370 */ +/* { dg-do run { target bitint } } */ +/* { dg-options "-std=c23 -pedantic-errors" } */ +/* { dg-skip-if "" { ! run_expensive_tests } { "*" } { "-O0" "-O2" } } */ +/* { dg-skip-if "" { ! run_expensive_tests } { "-flto" } { "" } } */ + +#if __BITINT_MAXWIDTH__ >= 255 +_BitInt(255) +foo (int s) +{ + return -(_BitInt(255)) 3 >> s; +} +#endif + +int +main () +{ +#if __BITINT_MAXWIDTH__ >= 255 + if (foo (51) != -1) + __builtin_abort (); +#endif + return 0; +} diff --git a/gcc/testsuite/gcc.dg/torture/bitint-49.c b/gcc/testsuite/gcc.dg/torture/bitint-49.c new file mode 100644 index 0000000..20c1716 --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/bitint-49.c @@ -0,0 +1,28 @@ +/* PR tree-optimization/113372 */ +/* { dg-do run { target bitint } } */ +/* { dg-options "-std=c23 -pedantic-errors" } */ +/* { dg-skip-if "" { ! run_expensive_tests } { "*" } { "-O0" "-O1" "-O2" } } */ +/* { dg-skip-if "" { ! run_expensive_tests } { "-flto" } { "" } } */ + +_BitInt(8) a, b, c; + +#if __BITINT_MAXWIDTH__ >= 6384 +_BitInt(8) +foo (_BitInt(6384) y) +{ + _BitInt(4745) x = -(b % y) * b; + int i = __builtin_sub_overflow_p (-y, 0, 0); + c |= __builtin_add_overflow_p (i, 0, a); + return x; +} +#endif + +int +main () +{ +#if __BITINT_MAXWIDTH__ >= 6384 + if (foo (4) != 0 || c != 0) + __builtin_abort (); +#endif + return 0; +} diff --git a/gcc/testsuite/gcc.dg/torture/pr113126.c b/gcc/testsuite/gcc.dg/torture/pr113126.c new file mode 100644 index 0000000..4aa38e0 --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr113126.c @@ -0,0 +1,15 @@ +/* { dg-do compile } */ + +typedef float __attribute__((__vector_size__ (8))) F; +typedef double __attribute__((__vector_size__ (16))) G; + +F f; +G g; + +F +foo (void) +{ + G h = __builtin_convertvector (f, G); + g = h <= h; + return f; +} diff --git a/gcc/testsuite/gcc.dg/tree-ssa/abs-4.c b/gcc/testsuite/gcc.dg/tree-ssa/abs-4.c index e1b825f..80fa448 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/abs-4.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/abs-4.c @@ -1,5 +1,6 @@ /* { dg-do compile } */ /* { dg-options "-O1 -fdump-tree-optimized" } */ +/* { dg-additional-options "-msse -mfpmath=sse" { target { { i?86-*-* x86_64-*-* } && ilp32 } } } */ /* PR tree-optimization/109829 */ float abs_f(float x) { return __builtin_signbit(x) ? x : -x; } @@ -9,6 +10,8 @@ long double abs_ld(long double x) { return __builtin_signbit(x) ? x : -x; } /* __builtin_signbit(x) ? x : -x. Should be convert into - ABS_EXP<x> */ /* { dg-final { scan-tree-dump-not "signbit" "optimized"} } */ -/* { dg-final { scan-tree-dump-times "= ABS_EXPR" 1 "optimized"} } */ -/* { dg-final { scan-tree-dump-times "= -" 1 "optimized"} } */ -/* { dg-final { scan-tree-dump-times "= \.COPYSIGN" 2 "optimized"} } */ +/* { dg-final { scan-tree-dump-times "= ABS_EXPR" 1 "optimized" { target ifn_copysign } } } */ +/* { dg-final { scan-tree-dump-times "= -" 1 "optimized" { target ifn_copysign } } } */ +/* { dg-final { scan-tree-dump-times "= \.COPYSIGN" 2 "optimized" { target ifn_copysign } } } */ +/* { dg-final { scan-tree-dump-times "= ABS_EXPR" 3 "optimized" { target { ! ifn_copysign } } } } */ +/* { dg-final { scan-tree-dump-times "= -" 3 "optimized" { target { ! ifn_copysign } } } } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/backprop-6.c b/gcc/testsuite/gcc.dg/tree-ssa/backprop-6.c index c3a1386..4087ba9 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/backprop-6.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/backprop-6.c @@ -1,5 +1,6 @@ /* { dg-do compile } */ /* { dg-options "-O -fdump-tree-backprop-details" } */ +/* { dg-additional-options "-msse -mfpmath=sse" { target { { i?86-*-* x86_64-*-* } && ilp32 } } } */ void start (void *); void end (void *); @@ -26,6 +27,8 @@ TEST_FUNCTION (float, f) TEST_FUNCTION (double, ) TEST_FUNCTION (long double, l) -/* { dg-final { scan-tree-dump-times {Deleting[^\n]* = -} 4 "backprop" } } */ -/* { dg-final { scan-tree-dump-times {Deleting[^\n]* = \.COPYSIGN} 2 "backprop" } } */ -/* { dg-final { scan-tree-dump-times {Deleting[^\n]* = ABS_EXPR <} 1 "backprop" } } */ +/* { dg-final { scan-tree-dump-times {Deleting[^\n]* = -} 4 "backprop" { target ifn_copysign } } } */ +/* { dg-final { scan-tree-dump-times {Deleting[^\n]* = \.COPYSIGN} 2 "backprop" { target ifn_copysign } } } */ +/* { dg-final { scan-tree-dump-times {Deleting[^\n]* = ABS_EXPR <} 1 "backprop" { target ifn_copysign } } } */ +/* { dg-final { scan-tree-dump-times {Deleting[^\n]* = -} 6 "backprop" { target { ! ifn_copysign } } } } */ +/* { dg-final { scan-tree-dump-times {Deleting[^\n]* = ABS_EXPR <} 3 "backprop" { target { ! ifn_copysign } } } } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/copy-sign-2.c b/gcc/testsuite/gcc.dg/tree-ssa/copy-sign-2.c index e5d565c..e43bc31 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/copy-sign-2.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/copy-sign-2.c @@ -1,4 +1,5 @@ /* { dg-options "-O2 -ffast-math -fdump-tree-optimized" } */ +/* { dg-additional-options "-msse -mfpmath=sse" { target { { i?86-*-* x86_64-*-* } && ilp32 } } } */ /* { dg-do compile } */ float f(float x) { @@ -10,5 +11,6 @@ float f1(float x) float t = __builtin_copysignf (1.0f, -x); return x * t; } -/* { dg-final { scan-tree-dump-times "ABS" 1 "optimized"} } */ -/* { dg-final { scan-tree-dump-times ".COPYSIGN" 1 "optimized"} } */ +/* { dg-final { scan-tree-dump-times "ABS" 1 "optimized" { target ifn_copysign } } } */ +/* { dg-final { scan-tree-dump-times ".COPYSIGN" 1 "optimized" { target ifn_copysign } } } */ +/* { dg-final { scan-tree-dump-times "ABS" 2 "optimized" { target { ! ifn_copysign } } } } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/divide-8.c b/gcc/testsuite/gcc.dg/tree-ssa/divide-8.c new file mode 100644 index 0000000..b814908 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/divide-8.c @@ -0,0 +1,13 @@ +/* { dg-do compile } */ +/* { dg-options "-O1 -fdump-tree-optimized" } */ +/* PR tree-optimization/113301 */ +/* We should figure out that 1/(x+1) range is [-1,1] + and then /2 is always 0. */ + +void link_error(void); +void func(int x){ + int c=(1/(x+1))/2; + if (c != 0) + link_error(); +} +/* { dg-final { scan-tree-dump-not "link_error " "optimized" } } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/mult-abs-2.c b/gcc/testsuite/gcc.dg/tree-ssa/mult-abs-2.c index a22896b..675127c 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/mult-abs-2.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/mult-abs-2.c @@ -34,5 +34,5 @@ float i1(float x) { return x * (x <= 0.f ? 1.f : -1.f); } -/* { dg-final { scan-tree-dump-times "ABS" 4 "gimple"} } */ -/* { dg-final { scan-tree-dump-times "\.COPYSIGN" 4 "gimple"} } */ + +/* { dg-final { scan-tree-dump-times "ABS" 8 "gimple" } } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr111003.c b/gcc/testsuite/gcc.dg/tree-ssa/pr111003.c new file mode 100644 index 0000000..a520765 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/pr111003.c @@ -0,0 +1,34 @@ +/* { dg-do compile } */ +/* { dg-options "-O3 -fdump-tree-optimized" } */ + +static int c, d, e, f; +static short g; +static int *h = &c; +void foo(void); +short(a)(); +static unsigned b(unsigned char j, int l) { return j > l ? j : j << l; } +static int *i(); +static void k(int j, unsigned char l) { + i(); + g = f; + f = g; + for (; g;) { + int m = 0; + d = a(); + for (; d;) { + if (l) + if (!(j >= -639457069 && j <= -639457069)) + if (m) + foo(); // This call should be elided + m = !(10 != (l ^ b(j, 6))) & (0 > e); + } + } +} +static int *i() { + for (; e; e = a(e, 6)) + ; + return h; +} +int main() { k(c, c); } + +/* { dg-final { scan-tree-dump-not "foo" "optimized" } } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr95906.c b/gcc/testsuite/gcc.dg/tree-ssa/pr95906.c index 3d820a5..d15670f 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/pr95906.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/pr95906.c @@ -1,7 +1,6 @@ /* { dg-do compile } */ /* { dg-options "-O2 -fdump-tree-forwprop3-raw -w -Wno-psabi" } */ -// FIXME: this should further optimize to a MAX_EXPR typedef signed char v16i8 __attribute__((vector_size(16))); v16i8 f(v16i8 a, v16i8 b) { @@ -10,4 +9,4 @@ v16i8 f(v16i8 a, v16i8 b) } /* { dg-final { scan-tree-dump-not "bit_(and|ior)_expr" "forwprop3" } } */ -/* { dg-final { scan-tree-dump-times "vec_cond_expr" 1 "forwprop3" } } */ +/* { dg-final { scan-tree-dump-times "max_expr" 1 "forwprop3" } } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-thread-22.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-thread-22.c new file mode 100644 index 0000000..f605009 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-thread-22.c @@ -0,0 +1,23 @@ +/* { dg-do compile } */ +/* { dg-options "-Os -fdump-tree-optimized" } */ +/* PR tree-optimization/107823 */ +/* With jump threading across the loop header, + we should figure out that b is always 0 and remove + the call to foo. */ + +int a; +void bar64_(void); +void foo(); +int main() { + signed char b = a = 6; + for (; a; a = 0) { + bar64_(); + b = 0; + } + if (b <= 0) + ; + else + foo(); +} + +/* { dg-final { scan-tree-dump-not "foo " "optimized" } } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/vrp-loop-1.c b/gcc/testsuite/gcc.dg/tree-ssa/vrp-loop-1.c new file mode 100644 index 0000000..09de892 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/vrp-loop-1.c @@ -0,0 +1,34 @@ +/* { dg-do compile } */ +/* { dg-options "-Os -fdump-tree-optimized" } */ +/* PR tree-optimization/110768 */ +/* The call to foo should be able to removed, + The branch to unreachable is unreachable as + VRP (ranger) figure out that c there can only + be -20409 or 0. before r14-5109-ga291237b628f41 + ranger could not figure that out. */ + + +void foo(void); +static int a, b; +int main() { + { + short c = 45127; + signed char d; + b = 0; + for (; b <= 3; b++) { + if (b) continue; + d = 0; + for (; d <= 100; d++) { + if (!(((c) >= -20409) && ((c) <= 1))) { + __builtin_unreachable(); + } + if (~(0 == a) & 1) return b; + c = 0; + for (; c <= 0; c++) a = 3; + } + } + foo(); + } +} + +/* { dg-final { scan-tree-dump-not "foo " "optimized" } } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/vrp-loop-2.c b/gcc/testsuite/gcc.dg/tree-ssa/vrp-loop-2.c new file mode 100644 index 0000000..7438c55 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/vrp-loop-2.c @@ -0,0 +1,33 @@ +/* { dg-do compile } */ +/* { dg-options "-O3 -fdump-tree-optimized" } */ +/* PR tree-optimization/110941 */ +/* The call to foo should be able to removed, + VRP should figure out `(c >= 2 && c <= 26)` + is always true. */ + +static int a; +void foo(void); +void bar349_(void); +void bar363_(void); +void bar275_(void); +int main() { + { + { + short b = 26; + for (; b >= 1; b = b - 4) { + if (b >= 2 && b <= 26) + bar275_(); + if (a) + bar363_(); + if (a) + bar349_(); + int c = b; + if (!(c >= 2 && c <= 26)) + foo(); + } + } + a = 0; + } +} + +/* { dg-final { scan-tree-dump-not "foo " "optimized" } } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/vrp-unreachable-1.c b/gcc/testsuite/gcc.dg/tree-ssa/vrp-unreachable-1.c new file mode 100644 index 0000000..76ef501 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/vrp-unreachable-1.c @@ -0,0 +1,26 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-optimized" } */ +/* PR tree-optimization/110450 */ +/* the ranger should be able to figure out that based on the + unreachable part of d not being zero, *b is also never 0. +*/ + + +void foo(void); +static int a = 1; +static int *b = &a, *c = &a; +static short d, e; +static signed char f = 11; +static signed char(g)(signed char h, int i) { return h << i; } +int main() { + if (f) *c = g(0 >= a, 3); + e = *c; + d = e % f; + if (d) { + __builtin_unreachable(); + } else if (*b) + foo(); + ; +} + +/* { dg-final { scan-tree-dump-not "foo " "optimized" } } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/vrp-unreachable-2.c b/gcc/testsuite/gcc.dg/tree-ssa/vrp-unreachable-2.c new file mode 100644 index 0000000..44b1ba5 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/vrp-unreachable-2.c @@ -0,0 +1,29 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-optimized" } */ +/* PR tree-optimization/110841 */ +/* The call to foo should be able to removed */ + +void foo(void); +static int b, c, d; +static signed char(a)(signed char e, signed char f) { return e - f; } +int main() { + for (; b <= 4; b++) + ; + c = 0; + for (; c >= -16; c = a(c, 4)) + ; + signed char g = b; + for (; d <= 0; d++) { + if (!(((g) >= 5) && ((g) <= 5))) { + __builtin_unreachable(); + } + if (c) return 0; + g = 0; + for (;;) { + foo(); + break; + } + } +} + +/* { dg-final { scan-tree-dump-not "foo " "optimized" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/costmodel/riscv/rvv/dynamic-lmul2-7.c b/gcc/testsuite/gcc.dg/vect/costmodel/riscv/rvv/dynamic-lmul2-7.c index 87e963e..38cbefb 100644 --- a/gcc/testsuite/gcc.dg/vect/costmodel/riscv/rvv/dynamic-lmul2-7.c +++ b/gcc/testsuite/gcc.dg/vect/costmodel/riscv/rvv/dynamic-lmul2-7.c @@ -22,3 +22,4 @@ x264_pixel_8x8 (unsigned char *pix1, unsigned char *pix2, int i_stride_pix2) } /* { dg-final { scan-assembler {e32,m2} } } */ +/* { dg-final { scan-assembler-not {xor} } } */ diff --git a/gcc/testsuite/gcc.dg/vect/costmodel/riscv/rvv/pr113247-1.c b/gcc/testsuite/gcc.dg/vect/costmodel/riscv/rvv/pr113247-1.c new file mode 100644 index 0000000..0d09a62 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/costmodel/riscv/rvv/pr113247-1.c @@ -0,0 +1,195 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gcv -mabi=lp64d -O3 -ftree-vectorize --param=riscv-autovec-lmul=dynamic" } */ + +#include <stdint-gcc.h> + +#define Ch(x,y,z) (z ^ (x & (y ^ z))) +#define Maj(x,y,z) ((x & y) | (z & (x | y))) + +#define SHR(x, n) (x >> n) +#define ROTR(x,n) (SHR(x,n) | (x << (32 - n))) +#define S1(x) (ROTR(x, 6) ^ ROTR(x,11) ^ ROTR(x,25)) +#define S0(x) (ROTR(x, 2) ^ ROTR(x,13) ^ ROTR(x,22)) + +#define s1(x) (ROTR(x,17) ^ ROTR(x,19) ^ SHR(x,10)) +#define s0(x) (ROTR(x, 7) ^ ROTR(x,18) ^ SHR(x, 3)) + +#define SHA256_STEP(a,b,c,d,e,f,g,h,x,K) \ +{ \ + tmp1 = h + S1(e) + Ch(e,f,g) + K + x; \ + tmp2 = S0(a) + Maj(a,b,c); \ + h = tmp1 + tmp2; \ + d += tmp1; \ +} + +#define BE_LOAD32(n,b,i) (n) = byteswap(*(uint32_t *)(b + i)) + +static uint32_t byteswap(uint32_t x) +{ + x = (x & 0x0000FFFF) << 16 | (x & 0xFFFF0000) >> 16; + x = (x & 0x00FF00FF) << 8 | (x & 0xFF00FF00) >> 8; + + return x; +} + +void sha256 (const uint8_t *in, uint32_t out[8]) +{ + uint32_t tmp1, tmp2, a, b, c, d, e, f, g, h; + uint32_t w0, w1, w2, w3, w4, w5, w6, w7, w8, w9, w10, w11, w12, w13, w14, w15; + + tmp1 = tmp2 = 0; + w0 = w1 = w2 = w3 = w4 = w5 = w6 = w7 = w8 = w9 = w10 = w11 = w12 = w13 = w14 = w15 = 0; + + BE_LOAD32 ( w0, in, 0 ); + BE_LOAD32 ( w1, in, 4 ); + BE_LOAD32 ( w2, in, 8 ); + BE_LOAD32 ( w3, in, 12 ); + BE_LOAD32 ( w4, in, 16 ); + BE_LOAD32 ( w5, in, 20 ); + BE_LOAD32 ( w6, in, 24 ); + BE_LOAD32 ( w7, in, 28 ); + BE_LOAD32 ( w8, in, 32 ); + BE_LOAD32 ( w9, in, 36 ); + BE_LOAD32 ( w10, in, 40 ); + BE_LOAD32 ( w11, in, 44 ); + BE_LOAD32 ( w12, in, 48 ); + BE_LOAD32 ( w13, in, 52 ); + BE_LOAD32 ( w14, in, 56 ); + BE_LOAD32 ( w15, in, 60 ); + + a = out[0]; + b = out[1]; + c = out[2]; + d = out[3]; + e = out[4]; + f = out[5]; + g = out[6]; + h = out[7]; + + SHA256_STEP(a, b, c, d, e, f, g, h, w0, 0x428a2f98); + SHA256_STEP(h, a, b, c, d, e, f, g, w1, 0x71374491); + SHA256_STEP(g, h, a, b, c, d, e, f, w2, 0xb5c0fbcf); + SHA256_STEP(f, g, h, a, b, c, d, e, w3, 0xe9b5dba5); + SHA256_STEP(e, f, g, h, a, b, c, d, w4, 0x3956c25b); + SHA256_STEP(d, e, f, g, h, a, b, c, w5, 0x59f111f1); + SHA256_STEP(c, d, e, f, g, h, a, b, w6, 0x923f82a4); + SHA256_STEP(b, c, d, e, f, g, h, a, w7, 0xab1c5ed5); + SHA256_STEP(a, b, c, d, e, f, g, h, w8, 0xd807aa98); + SHA256_STEP(h, a, b, c, d, e, f, g, w9, 0x12835b01); + SHA256_STEP(g, h, a, b, c, d, e, f, w10, 0x243185be); + SHA256_STEP(f, g, h, a, b, c, d, e, w11, 0x550c7dc3); + SHA256_STEP(e, f, g, h, a, b, c, d, w12, 0x72be5d74); + SHA256_STEP(d, e, f, g, h, a, b, c, w13, 0x80deb1fe); + SHA256_STEP(c, d, e, f, g, h, a, b, w14, 0x9bdc06a7); + SHA256_STEP(b, c, d, e, f, g, h, a, w15, 0xc19bf174); + + w0 = s1(w14) + w9 + s0(w1) + w0; + SHA256_STEP(a, b, c, d, e, f, g, h, w0, 0xe49b69c1); + w1 = s1(w15) + w10 + s0(w2) + w1; + SHA256_STEP(h, a, b, c, d, e, f, g, w1, 0xefbe4786); + w2 = s1(w0) + w11 + s0(w3) + w2; + SHA256_STEP(g, h, a, b, c, d, e, f, w2, 0x0fc19dc6); + w3 = s1(w1) + w12 + s0(w4) + w3; + SHA256_STEP(f, g, h, a, b, c, d, e, w3, 0x240ca1cc); + w4 = s1(w2) + w13 + s0(w5) + w4; + SHA256_STEP(e, f, g, h, a, b, c, d, w4, 0x2de92c6f); + w5 = s1(w3) + w14 + s0(w6) + w5; + SHA256_STEP(d, e, f, g, h, a, b, c, w5, 0x4a7484aa); + w6 = s1(w4) + w15 + s0(w7) + w6; + SHA256_STEP(c, d, e, f, g, h, a, b, w6, 0x5cb0a9dc); + w7 = s1(w5) + w0 + s0(w8) + w7; + SHA256_STEP(b, c, d, e, f, g, h, a, w7, 0x76f988da); + w8 = s1(w6) + w1 + s0(w9) + w8; + SHA256_STEP(a, b, c, d, e, f, g, h, w8, 0x983e5152); + w9 = s1(w7) + w2 + s0(w10) + w9; + SHA256_STEP(h, a, b, c, d, e, f, g, w9, 0xa831c66d); + w10 = s1(w8) + w3 + s0(w11) + w10; + SHA256_STEP(g, h, a, b, c, d, e, f, w10, 0xb00327c8); + w11 = s1(w9) + w4 + s0(w12) + w11; + SHA256_STEP(f, g, h, a, b, c, d, e, w11, 0xbf597fc7); + w12 = s1(w10) + w5 + s0(w13) + w12; + SHA256_STEP(e, f, g, h, a, b, c, d, w12, 0xc6e00bf3); + w13 = s1(w11) + w6 + s0(w14) + w13; + SHA256_STEP(d, e, f, g, h, a, b, c, w13, 0xd5a79147); + w14 = s1(w12) + w7 + s0(w15) + w14; + SHA256_STEP(c, d, e, f, g, h, a, b, w14, 0x06ca6351); + w15 = s1(w13) + w8 + s0(w0) + w15; + SHA256_STEP(b, c, d, e, f, g, h, a, w15, 0x14292967); + + w0 = s1(w14) + w9 + s0(w1) + w0; + SHA256_STEP(a, b, c, d, e, f, g, h, w0, 0x27b70a85); + w1 = s1(w15) + w10 + s0(w2) + w1; + SHA256_STEP(h, a, b, c, d, e, f, g, w1, 0x2e1b2138); + w2 = s1(w0) + w11 + s0(w3) + w2; + SHA256_STEP(g, h, a, b, c, d, e, f, w2, 0x4d2c6dfc); + w3 = s1(w1) + w12 + s0(w4) + w3; + SHA256_STEP(f, g, h, a, b, c, d, e, w3, 0x53380d13); + w4 = s1(w2) + w13 + s0(w5) + w4; + SHA256_STEP(e, f, g, h, a, b, c, d, w4, 0x650a7354); + w5 = s1(w3) + w14 + s0(w6) + w5; + SHA256_STEP(d, e, f, g, h, a, b, c, w5, 0x766a0abb); + w6 = s1(w4) + w15 + s0(w7) + w6; + SHA256_STEP(c, d, e, f, g, h, a, b, w6, 0x81c2c92e); + w7 = s1(w5) + w0 + s0(w8) + w7; + SHA256_STEP(b, c, d, e, f, g, h, a, w7, 0x92722c85); + w8 = s1(w6) + w1 + s0(w9) + w8; + SHA256_STEP(a, b, c, d, e, f, g, h, w8, 0xa2bfe8a1); + w9 = s1(w7) + w2 + s0(w10) + w9; + SHA256_STEP(h, a, b, c, d, e, f, g, w9, 0xa81a664b); + w10 = s1(w8) + w3 + s0(w11) + w10; + SHA256_STEP(g, h, a, b, c, d, e, f, w10, 0xc24b8b70); + w11 = s1(w9) + w4 + s0(w12) + w11; + SHA256_STEP(f, g, h, a, b, c, d, e, w11, 0xc76c51a3); + w12 = s1(w10) + w5 + s0(w13) + w12; + SHA256_STEP(e, f, g, h, a, b, c, d, w12, 0xd192e819); + w13 = s1(w11) + w6 + s0(w14) + w13; + SHA256_STEP(d, e, f, g, h, a, b, c, w13, 0xd6990624); + w14 = s1(w12) + w7 + s0(w15) + w14; + SHA256_STEP(c, d, e, f, g, h, a, b, w14, 0xf40e3585); + w15 = s1(w13) + w8 + s0(w0) + w15; + SHA256_STEP(b, c, d, e, f, g, h, a, w15, 0x106aa070); + + w0 = s1(w14) + w9 + s0(w1) + w0; + SHA256_STEP(a, b, c, d, e, f, g, h, w0, 0x19a4c116); + w1 = s1(w15) + w10 + s0(w2) + w1; + SHA256_STEP(h, a, b, c, d, e, f, g, w1, 0x1e376c08); + w2 = s1(w0) + w11 + s0(w3) + w2; + SHA256_STEP(g, h, a, b, c, d, e, f, w2, 0x2748774c); + w3 = s1(w1) + w12 + s0(w4) + w3; + SHA256_STEP(f, g, h, a, b, c, d, e, w3, 0x34b0bcb5); + w4 = s1(w2) + w13 + s0(w5) + w4; + SHA256_STEP(e, f, g, h, a, b, c, d, w4, 0x391c0cb3); + w5 = s1(w3) + w14 + s0(w6) + w5; + SHA256_STEP(d, e, f, g, h, a, b, c, w5, 0x4ed8aa4a); + w6 = s1(w4) + w15 + s0(w7) + w6; + SHA256_STEP(c, d, e, f, g, h, a, b, w6, 0x5b9cca4f); + w7 = s1(w5) + w0 + s0(w8) + w7; + SHA256_STEP(b, c, d, e, f, g, h, a, w7, 0x682e6ff3); + w8 = s1(w6) + w1 + s0(w9) + w8; + SHA256_STEP(a, b, c, d, e, f, g, h, w8, 0x748f82ee); + w9 = s1(w7) + w2 + s0(w10) + w9; + SHA256_STEP(h, a, b, c, d, e, f, g, w9, 0x78a5636f); + w10 = s1(w8) + w3 + s0(w11) + w10; + SHA256_STEP(g, h, a, b, c, d, e, f, w10, 0x84c87814); + w11 = s1(w9) + w4 + s0(w12) + w11; + SHA256_STEP(f, g, h, a, b, c, d, e, w11, 0x8cc70208); + w12 = s1(w10) + w5 + s0(w13) + w12; + SHA256_STEP(e, f, g, h, a, b, c, d, w12, 0x90befffa); + w13 = s1(w11) + w6 + s0(w14) + w13; + SHA256_STEP(d, e, f, g, h, a, b, c, w13, 0xa4506ceb); + w14 = s1(w12) + w7 + s0(w15) + w14; + SHA256_STEP(c, d, e, f, g, h, a, b, w14, 0xbef9a3f7); + w15 = s1(w13) + w8 + s0(w0) + w15; + SHA256_STEP(b, c, d, e, f, g, h, a, w15, 0xc67178f2); + + out[0] += a; + out[1] += b; + out[2] += c; + out[3] += d; + out[4] += e; + out[5] += f; + out[6] += g; + out[7] += h; +} + +/* { dg-final { scan-assembler-not {vset} } } */ diff --git a/gcc/testsuite/gcc.dg/vect/costmodel/riscv/rvv/pr113247-2.c b/gcc/testsuite/gcc.dg/vect/costmodel/riscv/rvv/pr113247-2.c new file mode 100644 index 0000000..64a53cf --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/costmodel/riscv/rvv/pr113247-2.c @@ -0,0 +1,6 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gcv -mabi=lp64d -O3 -ftree-vectorize --param=riscv-autovec-lmul=dynamic --param=riscv-autovec-preference=fixed-vlmax" } */ + +#include "pr113247-1.c" + +/* { dg-final { scan-assembler-not {vset} } } */ diff --git a/gcc/testsuite/gcc.dg/vect/costmodel/riscv/rvv/pr113247-3.c b/gcc/testsuite/gcc.dg/vect/costmodel/riscv/rvv/pr113247-3.c new file mode 100644 index 0000000..423c90e --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/costmodel/riscv/rvv/pr113247-3.c @@ -0,0 +1,6 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gcv -mabi=lp64d -O3 -ftree-vectorize" } */ + +#include "pr113247-1.c" + +/* { dg-final { scan-assembler-not {vset} } } */ diff --git a/gcc/testsuite/gcc.dg/vect/costmodel/riscv/rvv/pr113247-4.c b/gcc/testsuite/gcc.dg/vect/costmodel/riscv/rvv/pr113247-4.c new file mode 100644 index 0000000..c2a46d8 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/costmodel/riscv/rvv/pr113247-4.c @@ -0,0 +1,6 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gcv -mabi=lp64d -O3 -ftree-vectorize --param=riscv-autovec-preference=fixed-vlmax" } */ + +#include "pr113247-1.c" + +/* { dg-final { scan-assembler-not {vset} } } */ diff --git a/gcc/testsuite/gcc.dg/vect/costmodel/riscv/rvv/pr113281-1.c b/gcc/testsuite/gcc.dg/vect/costmodel/riscv/rvv/pr113281-1.c new file mode 100644 index 0000000..fdf6ed0 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/costmodel/riscv/rvv/pr113281-1.c @@ -0,0 +1,18 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gcv_zvl256b -mabi=lp64d -O3 -ftree-vectorize" } */ + +unsigned char a; + +int main() { + short b = a = 0; + for (; a != 19; a++) + if (a) + b = 32872 >> a; + + if (b == 0) + return 0; + else + return 1; +} + +/* { dg-final { scan-assembler-not {vset} } } */ diff --git a/gcc/testsuite/gcc.dg/vect/costmodel/riscv/rvv/pr113281-2.c b/gcc/testsuite/gcc.dg/vect/costmodel/riscv/rvv/pr113281-2.c new file mode 100644 index 0000000..31cecec --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/costmodel/riscv/rvv/pr113281-2.c @@ -0,0 +1,18 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gcv_zvl256b -mabi=lp64d -O3 -ftree-vectorize --param=riscv-autovec-preference=fixed-vlmax" } */ + +unsigned char a; + +int main() { + short b = a = 0; + for (; a != 19; a++) + if (a) + b = 32872 >> a; + + if (b == 0) + return 0; + else + return 1; +} + +/* { dg-final { scan-assembler-not {vset} } } */ diff --git a/gcc/testsuite/gcc.dg/vect/costmodel/riscv/rvv/pr113281-3.c b/gcc/testsuite/gcc.dg/vect/costmodel/riscv/rvv/pr113281-3.c new file mode 100644 index 0000000..706e191 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/costmodel/riscv/rvv/pr113281-3.c @@ -0,0 +1,18 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gcv_zvl4096b -mabi=lp64d -O3 -ftree-vectorize --param=riscv-autovec-lmul=m8" } */ + +unsigned char a; + +int main() { + short b = a = 0; + for (; a != 19; a++) + if (a) + b = 32872 >> a; + + if (b == 0) + return 0; + else + return 1; +} + +/* { dg-final { scan-assembler-not {vset} } } */ diff --git a/gcc/testsuite/gcc.dg/vect/costmodel/riscv/rvv/pr113281-4.c b/gcc/testsuite/gcc.dg/vect/costmodel/riscv/rvv/pr113281-4.c new file mode 100644 index 0000000..b0305db --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/costmodel/riscv/rvv/pr113281-4.c @@ -0,0 +1,18 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gcv_zvl4096b -mabi=lp64d -O3 -ftree-vectorize --param=riscv-autovec-lmul=m8 --param=riscv-autovec-preference=fixed-vlmax" } */ + +unsigned char a; + +int main() { + short b = a = 0; + for (; a != 19; a++) + if (a) + b = 32872 >> a; + + if (b == 0) + return 0; + else + return 1; +} + +/* { dg-final { scan-assembler-not {vset} } } */ diff --git a/gcc/testsuite/gcc.dg/vect/costmodel/riscv/rvv/pr113281-5.c b/gcc/testsuite/gcc.dg/vect/costmodel/riscv/rvv/pr113281-5.c new file mode 100644 index 0000000..d3f5717b --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/costmodel/riscv/rvv/pr113281-5.c @@ -0,0 +1,18 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gcv_zvl4096b -mabi=lp64d -O3 -ftree-vectorize --param=riscv-autovec-lmul=dynamic" } */ + +unsigned char a; + +int main() { + short b = a = 0; + for (; a != 19; a++) + if (a) + b = 32872 >> a; + + if (b == 0) + return 0; + else + return 1; +} + +/* { dg-final { scan-assembler-not {vset} } } */ diff --git a/gcc/testsuite/gcc.dg/vect/costmodel/riscv/rvv/vla_vs_vls-10.c b/gcc/testsuite/gcc.dg/vect/costmodel/riscv/rvv/vla_vs_vls-10.c index 3ddffa3..89a6c67 100644 --- a/gcc/testsuite/gcc.dg/vect/costmodel/riscv/rvv/vla_vs_vls-10.c +++ b/gcc/testsuite/gcc.dg/vect/costmodel/riscv/rvv/vla_vs_vls-10.c @@ -3,7 +3,7 @@ #include <stdint-gcc.h> -#define N 40 +#define N 48 int a[N]; @@ -22,7 +22,6 @@ foo (){ return 0; } -/* { dg-final { scan-assembler-times {vsetivli\s+zero,\s*8,\s*e32,\s*m2,\s*t[au],\s*m[au]} 1 } } */ /* { dg-final { scan-assembler-times {vsetivli\s+zero,\s*16,\s*e32,\s*m4,\s*t[au],\s*m[au]} 1 } } */ -/* { dg-final { scan-assembler-times {vsetivli} 2 } } */ +/* { dg-final { scan-assembler-times {vsetivli} 1 } } */ /* { dg-final { scan-assembler-not {vsetvli} } } */ diff --git a/gcc/testsuite/gcc.dg/vect/costmodel/riscv/rvv/vla_vs_vls-11.c b/gcc/testsuite/gcc.dg/vect/costmodel/riscv/rvv/vla_vs_vls-11.c index 7625ec5..86732ef 100644 --- a/gcc/testsuite/gcc.dg/vect/costmodel/riscv/rvv/vla_vs_vls-11.c +++ b/gcc/testsuite/gcc.dg/vect/costmodel/riscv/rvv/vla_vs_vls-11.c @@ -3,7 +3,7 @@ #include <stdint-gcc.h> -#define N 40 +#define N 64 int a[N]; @@ -22,7 +22,6 @@ foo (){ return 0; } -/* { dg-final { scan-assembler-times {vsetivli\s+zero,\s*8,\s*e32,\s*m2,\s*t[au],\s*m[au]} 1 } } */ /* { dg-final { scan-assembler-times {vsetvli\s+zero,\s*[a-x0-9]+,\s*e32,\s*m8,\s*t[au],\s*m[au]} 1 } } */ -/* { dg-final { scan-assembler-times {vsetivli} 1 } } */ +/* { dg-final { scan-assembler-not {vsetivli} } } */ /* { dg-final { scan-assembler-times {vsetvli} 1 } } */ diff --git a/gcc/testsuite/gcc.dg/vect/costmodel/riscv/rvv/vla_vs_vls-12.c b/gcc/testsuite/gcc.dg/vect/costmodel/riscv/rvv/vla_vs_vls-12.c index 7625ec5..a1fcb3f 100644 --- a/gcc/testsuite/gcc.dg/vect/costmodel/riscv/rvv/vla_vs_vls-12.c +++ b/gcc/testsuite/gcc.dg/vect/costmodel/riscv/rvv/vla_vs_vls-12.c @@ -1,9 +1,9 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gcv -mabi=lp64d -O3 --param=riscv-autovec-lmul=m8 -fno-schedule-insns -fno-schedule-insns2" } */ +/* { dg-options "-march=rv64gcv -mabi=lp64d -O3 --param=riscv-autovec-lmul=dynamic -fno-schedule-insns -fno-schedule-insns2" } */ #include <stdint-gcc.h> -#define N 40 +#define N 64 int a[N]; @@ -22,7 +22,6 @@ foo (){ return 0; } -/* { dg-final { scan-assembler-times {vsetivli\s+zero,\s*8,\s*e32,\s*m2,\s*t[au],\s*m[au]} 1 } } */ /* { dg-final { scan-assembler-times {vsetvli\s+zero,\s*[a-x0-9]+,\s*e32,\s*m8,\s*t[au],\s*m[au]} 1 } } */ -/* { dg-final { scan-assembler-times {vsetivli} 1 } } */ +/* { dg-final { scan-assembler-not {vsetivli} } } */ /* { dg-final { scan-assembler-times {vsetvli} 1 } } */ diff --git a/gcc/testsuite/gcc.dg/vect/pr112505.c b/gcc/testsuite/gcc.dg/vect/pr112505.c new file mode 100644 index 0000000..56546c1 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/pr112505.c @@ -0,0 +1,14 @@ +/* { dg-do compile } */ +/* { dg-additional-options "-O3" } */ + +short int w9; +struct T { + short a : 14; + int b; +}; +struct T v; +void zc() +{ + for(int i = 0; i < 4; i ++) + w9 *= v.b ? v.a-- < 0 : 0; +} diff --git a/gcc/testsuite/gcc.dg/vect/slp-21.c b/gcc/testsuite/gcc.dg/vect/slp-21.c index 712a73b..5875168 100644 --- a/gcc/testsuite/gcc.dg/vect/slp-21.c +++ b/gcc/testsuite/gcc.dg/vect/slp-21.c @@ -213,7 +213,7 @@ int main (void) Not all vect_perm targets support that, and it's a bit too specific to have its own effective-target selector, so we just test targets directly. */ -/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 4 "vect" { target { powerpc64*-*-* s390*-*-* } } } } */ -/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 2 "vect" { target { vect_strided4 && { ! { powerpc64*-*-* s390*-*-* } } } } } } */ +/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 4 "vect" { target { powerpc64*-*-* s390*-*-* loongarch*-*-* } } } } */ +/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 2 "vect" { target { vect_strided4 && { ! { powerpc64*-*-* s390*-*-* loongarch*-*-* } } } } } } */ /* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 0 "vect" { target { ! { vect_strided4 } } } } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-early-break-run_1.c b/gcc/testsuite/gcc.dg/vect/vect-early-break-run_1.c index fb8faea..746e1a7 100644 --- a/gcc/testsuite/gcc.dg/vect/vect-early-break-run_1.c +++ b/gcc/testsuite/gcc.dg/vect/vect-early-break-run_1.c @@ -2,7 +2,7 @@ /* { dg-require-effective-target vect_early_break_hw } */ /* { dg-require-effective-target vect_int } */ -/* { dg-additional-options "-Ofast -save-temps" } */ +/* { dg-additional-options "-Ofast" } */ #define N 803 #define P 0 diff --git a/gcc/testsuite/gcc.dg/vect/vect-early-break-run_10.c b/gcc/testsuite/gcc.dg/vect/vect-early-break-run_10.c index 2fc8551..e1effe1 100644 --- a/gcc/testsuite/gcc.dg/vect/vect-early-break-run_10.c +++ b/gcc/testsuite/gcc.dg/vect/vect-early-break-run_10.c @@ -2,7 +2,7 @@ /* { dg-require-effective-target vect_early_break_hw } */ /* { dg-require-effective-target vect_int } */ -/* { dg-additional-options "-Ofast -save-temps" } */ +/* { dg-additional-options "-Ofast" } */ #define N 800 #define P 799 diff --git a/gcc/testsuite/gcc.dg/vect/vect-early-break-run_2.c b/gcc/testsuite/gcc.dg/vect/vect-early-break-run_2.c index 8c6d4ce..e7e5e79 100644 --- a/gcc/testsuite/gcc.dg/vect/vect-early-break-run_2.c +++ b/gcc/testsuite/gcc.dg/vect/vect-early-break-run_2.c @@ -2,7 +2,7 @@ /* { dg-require-effective-target vect_early_break_hw } */ /* { dg-require-effective-target vect_int } */ -/* { dg-additional-options "-Ofast -save-temps" } */ +/* { dg-additional-options "-Ofast" } */ #define N 803 #define P 802 diff --git a/gcc/testsuite/gcc.dg/vect/vect-early-break-run_3.c b/gcc/testsuite/gcc.dg/vect/vect-early-break-run_3.c index ad25db4..1fff859 100644 --- a/gcc/testsuite/gcc.dg/vect/vect-early-break-run_3.c +++ b/gcc/testsuite/gcc.dg/vect/vect-early-break-run_3.c @@ -2,7 +2,7 @@ /* { dg-require-effective-target vect_early_break_hw } */ /* { dg-require-effective-target vect_int } */ -/* { dg-additional-options "-Ofast -save-temps" } */ +/* { dg-additional-options "-Ofast" } */ #define N 803 #define P 5 diff --git a/gcc/testsuite/gcc.dg/vect/vect-early-break-run_4.c b/gcc/testsuite/gcc.dg/vect/vect-early-break-run_4.c index 804d640..46429c7 100644 --- a/gcc/testsuite/gcc.dg/vect/vect-early-break-run_4.c +++ b/gcc/testsuite/gcc.dg/vect/vect-early-break-run_4.c @@ -2,7 +2,7 @@ /* { dg-require-effective-target vect_early_break_hw } */ /* { dg-require-effective-target vect_int } */ -/* { dg-additional-options "-Ofast -save-temps" } */ +/* { dg-additional-options "-Ofast" } */ #define N 803 #define P 278 diff --git a/gcc/testsuite/gcc.dg/vect/vect-early-break-run_5.c b/gcc/testsuite/gcc.dg/vect/vect-early-break-run_5.c index fd8086a..2e5145f 100644 --- a/gcc/testsuite/gcc.dg/vect/vect-early-break-run_5.c +++ b/gcc/testsuite/gcc.dg/vect/vect-early-break-run_5.c @@ -2,7 +2,7 @@ /* { dg-require-effective-target vect_early_break_hw } */ /* { dg-require-effective-target vect_int } */ -/* { dg-additional-options "-Ofast -save-temps" } */ +/* { dg-additional-options "-Ofast" } */ #define N 800 #define P 799 diff --git a/gcc/testsuite/gcc.dg/vect/vect-early-break-run_6.c b/gcc/testsuite/gcc.dg/vect/vect-early-break-run_6.c index 3b4490d..f6652d8 100644 --- a/gcc/testsuite/gcc.dg/vect/vect-early-break-run_6.c +++ b/gcc/testsuite/gcc.dg/vect/vect-early-break-run_6.c @@ -2,7 +2,7 @@ /* { dg-require-effective-target vect_early_break_hw } */ /* { dg-require-effective-target vect_int } */ -/* { dg-additional-options "-Ofast -save-temps" } */ +/* { dg-additional-options "-Ofast" } */ #define N 803 #define P 0 diff --git a/gcc/testsuite/gcc.dg/vect/vect-early-break-run_7.c b/gcc/testsuite/gcc.dg/vect/vect-early-break-run_7.c index ab9ff90..c797321 100644 --- a/gcc/testsuite/gcc.dg/vect/vect-early-break-run_7.c +++ b/gcc/testsuite/gcc.dg/vect/vect-early-break-run_7.c @@ -2,7 +2,7 @@ /* { dg-require-effective-target vect_early_break_hw } */ /* { dg-require-effective-target vect_int } */ -/* { dg-additional-options "-Ofast -save-temps" } */ +/* { dg-additional-options "-Ofast" } */ #define N 803 #define P 802 diff --git a/gcc/testsuite/gcc.dg/vect/vect-early-break-run_8.c b/gcc/testsuite/gcc.dg/vect/vect-early-break-run_8.c index c2ea839..63680e9 100644 --- a/gcc/testsuite/gcc.dg/vect/vect-early-break-run_8.c +++ b/gcc/testsuite/gcc.dg/vect/vect-early-break-run_8.c @@ -2,7 +2,7 @@ /* { dg-require-effective-target vect_early_break_hw } */ /* { dg-require-effective-target vect_int } */ -/* { dg-additional-options "-Ofast -save-temps" } */ +/* { dg-additional-options "-Ofast" } */ #define N 803 #define P 5 diff --git a/gcc/testsuite/gcc.dg/vect/vect-early-break-run_9.c b/gcc/testsuite/gcc.dg/vect/vect-early-break-run_9.c index a221c87..534bf5a 100644 --- a/gcc/testsuite/gcc.dg/vect/vect-early-break-run_9.c +++ b/gcc/testsuite/gcc.dg/vect/vect-early-break-run_9.c @@ -2,7 +2,7 @@ /* { dg-require-effective-target vect_early_break_hw } */ /* { dg-require-effective-target vect_int } */ -/* { dg-additional-options "-Ofast -save-temps" } */ +/* { dg-additional-options "-Ofast" } */ #define N 803 #define P 278 diff --git a/gcc/testsuite/gcc.dg/vect/vect-early-break_100-pr113287.c b/gcc/testsuite/gcc.dg/vect/vect-early-break_100-pr113287.c new file mode 100644 index 0000000..59c1e102 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_100-pr113287.c @@ -0,0 +1,40 @@ +/* { dg-add-options vect_early_break } */ +/* { dg-require-effective-target vect_early_break } */ +/* { dg-require-effective-target vect_long_long } */ + +/* { dg-final { scan-tree-dump "LOOP VECTORIZED" "vect" } } */ + +#include "tree-vect.h" + +__attribute__((noipa)) void +bar (unsigned long long *p) +{ + __builtin_memset (p, 0, 142 * sizeof (unsigned long long)); + p[17] = 0x50000000000ULL; +} + +__attribute__((noipa)) int +foo (void) +{ + unsigned long long r[142]; + bar (r); + unsigned long long v = ((long long) r[0] >> 31); + if (v + 1 > 1) + return 1; + for (unsigned long long i = 1; i <= 140; ++i) + if (r[i] != v) + return 1; + unsigned long long w = r[141]; + if ((unsigned long long) (((long long) (w << 60)) >> 60) != v) + return 1; + return 0; +} + +int +main () +{ + check_vect (); + + if (foo () != 1) + __builtin_abort (); +} diff --git a/gcc/testsuite/gcc.dg/vect/vect-early-break_101-pr113178.c b/gcc/testsuite/gcc.dg/vect/vect-early-break_101-pr113178.c new file mode 100644 index 0000000..8b91112 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_101-pr113178.c @@ -0,0 +1,22 @@ +/* { dg-do compile } */ +/* { dg-add-options vect_early_break } */ +/* { dg-require-effective-target vect_early_break } */ +/* { dg-require-effective-target vect_int } */ + +struct PixelWeight { + int m_SrcStart; + int m_Weights[16]; +}; +char h; +void f(struct PixelWeight *pPixelWeights) { + int dest_g_m; + long tt; + for (int j = 0; j < 16; j++) { + int *p = 0; + if (j < pPixelWeights->m_SrcStart) + p = tt ? &pPixelWeights->m_Weights[0] : 0; + int pWeight = *p; + dest_g_m += pWeight; + } + h = dest_g_m; +} diff --git a/gcc/testsuite/gcc.dg/vect/vect-early-break_102-pr113178.c b/gcc/testsuite/gcc.dg/vect/vect-early-break_102-pr113178.c new file mode 100644 index 0000000..ad7582e --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_102-pr113178.c @@ -0,0 +1,19 @@ +/* { dg-do compile } */ +/* { dg-add-options vect_early_break } */ +/* { dg-require-effective-target vect_early_break } */ +/* { dg-require-effective-target vect_int } */ +/* { dg-additional-options "-std=gnu99 -fpermissive -fgnu89-inline -Ofast -fprofile-generate -w" } */ + +extern int replace_reg_with_saved_mem_i, replace_reg_with_saved_mem_nregs, + replace_reg_with_saved_mem_mem_1; +replace_reg_with_saved_mem_mode() { + if (replace_reg_with_saved_mem_i) + return; + while (++replace_reg_with_saved_mem_i < replace_reg_with_saved_mem_nregs) + if (replace_reg_with_saved_mem_i) + break; + if (replace_reg_with_saved_mem_i) + if (replace_reg_with_saved_mem_mem_1) + adjust_address_1(); + replace_reg_with_saved_mem_mem_1 ? fancy_abort() : 0; +} diff --git a/gcc/testsuite/gcc.dg/vect/vect-early-break_103-pr113135.c b/gcc/testsuite/gcc.dg/vect/vect-early-break_103-pr113135.c new file mode 100644 index 0000000..bbad7ee --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_103-pr113135.c @@ -0,0 +1,14 @@ +/* { dg-do compile } */ +/* { dg-add-options vect_early_break } */ +/* { dg-require-effective-target vect_early_break } */ +/* { dg-require-effective-target vect_int } */ +/* { dg-additional-options "-w" } */ + +char UnpackReadTables_BitLength[20]; +int UnpackReadTables_ZeroCount; +void UnpackReadTables() { + for (unsigned I = 0; I < 20;) + while (UnpackReadTables_ZeroCount-- && + I < sizeof(UnpackReadTables_BitLength)) + UnpackReadTables_BitLength[I++] = 0; +} diff --git a/gcc/testsuite/gcc.dg/vect/vect-early-break_94-pr113144.c b/gcc/testsuite/gcc.dg/vect/vect-early-break_94-pr113144.c new file mode 100644 index 0000000..903fe7b --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_94-pr113144.c @@ -0,0 +1,41 @@ +/* { dg-do compile } */ +/* { dg-add-options vect_early_break } */ +/* { dg-require-effective-target vect_early_break } */ +/* { dg-require-effective-target vect_int } */ + +/* { dg-final { scan-tree-dump "LOOP VECTORIZED" "vect" } } */ + +long tar_atol256_max, tar_atol256_size, tar_atosl_min; +char tar_atol256_s; +void __errno_location(); + + +inline static long tar_atol256(long min) { + char c; + int sign; + c = tar_atol256_s; + sign = c; + while (tar_atol256_size) { + if (c != sign) + return sign ? min : tar_atol256_max; + c = tar_atol256_size--; + } + if ((c & 128) != (sign & 128)) + return sign ? min : tar_atol256_max; + return 0; +} + +inline static long tar_atol(long min) { + return tar_atol256(min); +} + +long tar_atosl() { + long n = tar_atol(-1); + if (tar_atosl_min) { + __errno_location(); + return 0; + } + if (n > 0) + return 0; + return n; +} diff --git a/gcc/testsuite/gcc.dg/vect/vect-early-break_95-pr113137.c b/gcc/testsuite/gcc.dg/vect/vect-early-break_95-pr113137.c new file mode 100644 index 0000000..e8f5b06 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_95-pr113137.c @@ -0,0 +1,17 @@ +/* { dg-do compile } */ +/* { dg-add-options vect_early_break } */ +/* { dg-require-effective-target vect_early_break } */ +/* { dg-require-effective-target vect_int } */ +/* { dg-additional-options "-w" } */ + +short gen_to_words_words; +void gen_to_words() { + unsigned short *lp = &gen_to_words_words; + long carry; + for (carry = 1, lp--; carry; lp--) { + carry = *lp + carry; + *lp = carry >>= 16; + if (lp == &gen_to_words_words) + break; + } +} diff --git a/gcc/testsuite/gcc.dg/vect/vect-early-break_96-pr113136.c b/gcc/testsuite/gcc.dg/vect/vect-early-break_96-pr113136.c new file mode 100644 index 0000000..016e749 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_96-pr113136.c @@ -0,0 +1,32 @@ +/* { dg-do compile } */ +/* { dg-add-options vect_early_break } */ +/* { dg-require-effective-target vect_early_break } */ +/* { dg-require-effective-target vect_int } */ + +struct _reent { union { struct { char _l64a_buf[8]; } _reent; } _new; }; +static const char R64_ARRAY[] = "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; +char * +_l64a_r (struct _reent *rptr, + long value) +{ + char *ptr; + char *result; + int i, index; + unsigned long tmp = (unsigned long)value & 0xffffffff; + result = + (( + rptr + )->_new._reent._l64a_buf) + ; + ptr = result; + for (i = 0; i < 60; ++i) + { + if (tmp == 0) + { + *ptr = '\0'; + break; + } + *ptr++ = R64_ARRAY[index]; + tmp >>= 6; + } +} diff --git a/gcc/testsuite/gcc.dg/vect/vect-early-break_97-pr113172.c b/gcc/testsuite/gcc.dg/vect/vect-early-break_97-pr113172.c new file mode 100644 index 0000000..625b227 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_97-pr113172.c @@ -0,0 +1,12 @@ +/* { dg-do compile } */ +/* { dg-add-options vect_early_break } */ +/* { dg-require-effective-target vect_early_break } */ +/* { dg-require-effective-target vect_int } */ + +int tswchp_2; +short cpy_buf[8]; +void ts_endcmd() { + int i = 0; + for (; i < 8 && i < tswchp_2; i++) + cpy_buf[i] = i; +} diff --git a/gcc/testsuite/gcc.dg/vect/vect-early-break_98-pr113237.c b/gcc/testsuite/gcc.dg/vect/vect-early-break_98-pr113237.c new file mode 100644 index 0000000..e6d150b --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_98-pr113237.c @@ -0,0 +1,20 @@ +/* { dg-do compile } */ +/* { dg-add-options vect_early_break } */ +/* { dg-require-effective-target vect_early_break } */ +/* { dg-require-effective-target vect_int } */ + +long Perl_pp_split_limit; +int Perl_block_gimme(); +int Perl_pp_split() { + char strend; + long iters; + int gimme = Perl_block_gimme(); + while (--Perl_pp_split_limit) { + if (gimme) + iters++; + if (strend) + break; + } + if (iters) + return 0; +} diff --git a/gcc/testsuite/gcc.dg/vect/vect-early-break_99-pr113287.c b/gcc/testsuite/gcc.dg/vect/vect-early-break_99-pr113287.c new file mode 100644 index 0000000..e616218 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_99-pr113287.c @@ -0,0 +1,37 @@ +/* { dg-add-options vect_early_break } */ +/* { dg-require-effective-target vect_early_break } */ +/* { dg-require-effective-target bitint65535 } */ + +/* { dg-final { scan-tree-dump "LOOP VECTORIZED" "vect" } } */ + +#include "tree-vect.h" + +_BitInt(998) b; +char c; +char d; +char e; +char f; +char g; +char h; +char i; +char j; + +void +foo(char y, _BitInt(9020) a, char *r) +{ + char x = __builtin_mul_overflow_p(a << sizeof(a), y, 0); + x += c + d + e + f + g + h + i + j + b; + *r = x; +} + +int +main(void) +{ + check_vect (); + + char x; + foo(5, 5, &x); + if (x != 1) + __builtin_abort(); + return 0; +} diff --git a/gcc/testsuite/gcc.dg/vect/vect-reduc-cond-sub.c b/gcc/testsuite/gcc.dg/vect/vect-reduc-cond-sub.c new file mode 100644 index 0000000..0213a0a --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-reduc-cond-sub.c @@ -0,0 +1,29 @@ +/* { dg-require-effective-target vect_int } */ + +#include "tree-vect.h" + +int __attribute__((noipa)) +foo (int n, int* p, int* pi) +{ + int sum = 0; + for (int i = 0; i != n; i++) + { + if (pi[i] > 0) + sum -= p[i]; + } + return sum; +} + +int p[16] __attribute__((aligned(__BIGGEST_ALIGNMENT__))) + = { 7, 3, 1, 4, 9, 10, 14, 7, -10, -55, 20, 9, 1, 2, 0, -17 }; +int pi[16] __attribute__((aligned(__BIGGEST_ALIGNMENT__))) + = { 0, 1, 1, 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 1, 1 }; +int +main() +{ + check_vect (); + + if (foo (16, p, pi) != 57) + abort (); + return 0; +} diff --git a/gcc/testsuite/gcc.target/aarch64/bb-slp-pr113091.c b/gcc/testsuite/gcc.target/aarch64/bb-slp-pr113091.c new file mode 100644 index 0000000..ff822e9 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/bb-slp-pr113091.c @@ -0,0 +1,22 @@ +/* { dg-do compile } */ +/* { dg-additional-options "-O3 -fdump-tree-slp-details -ftree-slp-vectorize" } */ + +int test(unsigned array[8]); + +int foo(char *a, char *b) +{ + unsigned array[8]; + + array[0] = (a[0] - b[0]); + array[1] = (a[1] - b[1]); + array[2] = (a[2] - b[2]); + array[3] = (a[3] - b[3]); + array[4] = (a[4] - b[4]); + array[5] = (a[5] - b[5]); + array[6] = (a[6] - b[6]); + array[7] = (a[7] - b[7]); + + return test(array); +} + +/* { dg-final { scan-tree-dump-times "Basic block will be vectorized using SLP" 1 "slp2" } } */ diff --git a/gcc/testsuite/gcc.target/aarch64/pr113077.c b/gcc/testsuite/gcc.target/aarch64/pr113077.c new file mode 100644 index 0000000..dca202b --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/pr113077.c @@ -0,0 +1,11 @@ +/* { dg-do compile } */ +/* { dg-additional-options "-O2 -fstack-protector-strong -fstack-clash-protection" } */ +void add_key(const void *payload); +void act_keyctl_test(void) { + char buf[1030 * 1024]; + int i = 0; + for (i = 0; i < sizeof(buf); i++) + { + add_key(buf); + } +} diff --git a/gcc/testsuite/gcc.target/aarch64/pr113196.c b/gcc/testsuite/gcc.target/aarch64/pr113196.c new file mode 100644 index 0000000..8982cc5 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/pr113196.c @@ -0,0 +1,23 @@ +/* { dg-options "-O3" } */ + +#pragma GCC target "+nosve" + +int test(unsigned array[4][4]); + +int foo(unsigned short *a, unsigned long n) +{ + unsigned array[4][4]; + + for (unsigned i = 0; i < 4; i++, a += 4) + { + array[i][0] = a[0] << 6; + array[i][1] = a[1] << 6; + array[i][2] = a[2] << 6; + array[i][3] = a[3] << 6; + } + + return test(array); +} + +/* { dg-final { scan-assembler-times {\tushll\t} 2 } } */ +/* { dg-final { scan-assembler-times {\tushll2\t} 2 } } */ diff --git a/gcc/testsuite/gcc.target/aarch64/simd/vmovl_high_1.c b/gcc/testsuite/gcc.target/aarch64/simd/vmovl_high_1.c index a2d09ea..9519062 100644 --- a/gcc/testsuite/gcc.target/aarch64/simd/vmovl_high_1.c +++ b/gcc/testsuite/gcc.target/aarch64/simd/vmovl_high_1.c @@ -3,8 +3,6 @@ #include <arm_neon.h> -#include <arm_neon.h> - #define FUNC(IT, OT, S) \ OT \ foo_##S (IT a) \ @@ -22,11 +20,11 @@ FUNC (int32x4_t, int64x2_t, s32) /* { dg-final { scan-assembler-times {sxtl2\tv0\.2d, v0\.4s} 1} } */ FUNC (uint8x16_t, uint16x8_t, u8) -/* { dg-final { scan-assembler-times {zip2\tv0\.16b, v0\.16b} 1} } */ +/* { dg-final { scan-assembler-times {uxtl2\tv0\.8h, v0\.16b} 1} } */ FUNC (uint16x8_t, uint32x4_t, u16) -/* { dg-final { scan-assembler-times {zip2\tv0\.8h, v0\.8h} 1} } */ +/* { dg-final { scan-assembler-times {uxtl2\tv0\.4s, v0\.8h} 1} } */ FUNC (uint32x4_t, uint64x2_t, u32) -/* { dg-final { scan-assembler-times {zip2\tv0\.4s, v0\.4s} 1} } */ +/* { dg-final { scan-assembler-times {uxtl2\tv0\.2d, v0\.4s} 1} } */ diff --git a/gcc/testsuite/gcc.target/aarch64/sve/acle/general-c/clamp_1.c b/gcc/testsuite/gcc.target/aarch64/sve/acle/general-c/clamp_1.c index 342bebc..07e22d2 100644 --- a/gcc/testsuite/gcc.target/aarch64/sve/acle/general-c/clamp_1.c +++ b/gcc/testsuite/gcc.target/aarch64/sve/acle/general-c/clamp_1.c @@ -13,7 +13,7 @@ f1 (svcount_t pn, svfloat16_t f16, svint16_t s16, svfloat32_t f32, svclamp (f16, f16, f16, f16); /* { dg-error {too many arguments to function 'svclamp'} } */ svclamp (0, f16, f16); /* { dg-error {passing 'int' to argument 1 of 'svclamp', which expects an SVE type rather than a scalar type} } */ svclamp (f16, f16, f16); - svclamp (s16, s16, s16); /* { dg-error {'svclamp' has no form that takes 'svint16_t' arguments} } */ + svclamp (s16, s16, s16); svclamp (pn, f16, f16); /* { dg-error {passing 'svfloat16_t' to argument 2 of 'svclamp', but argument 1 had type 'svcount_t'} } */ svclamp (f16, s16, f16); /* { dg-error {passing 'svint16_t' to argument 2 of 'svclamp', but argument 1 had type 'svfloat16_t'} } */ svclamp (f16, f32, f32); /* { dg-error {passing 'svfloat32_t' to argument 2 of 'svclamp', but argument 1 had type 'svfloat16_t'} } */ diff --git a/gcc/testsuite/gcc.target/aarch64/vect_mixed_sizes_10.c b/gcc/testsuite/gcc.target/aarch64/vect_mixed_sizes_10.c index 81e77a8..a741919 100644 --- a/gcc/testsuite/gcc.target/aarch64/vect_mixed_sizes_10.c +++ b/gcc/testsuite/gcc.target/aarch64/vect_mixed_sizes_10.c @@ -14,5 +14,5 @@ f (int16_t *x, int16_t *y, uint8_t *z, int n) } } -/* { dg-final { scan-assembler-times {\tuxtl\tv[0-9]+\.8h, v[0-9]+\.8b\n} 1 } } */ +/* { dg-final { scan-assembler-times {\tzip1\tv[0-9]+\.16b, v[0-9]+\.16b, v[0-9]+\.16b\n} 1 } } */ /* { dg-final { scan-assembler-times {\tadd\tv[0-9]+\.8h,} 1 } } */ diff --git a/gcc/testsuite/gcc.target/aarch64/vect_mixed_sizes_8.c b/gcc/testsuite/gcc.target/aarch64/vect_mixed_sizes_8.c index 9531966..835eef3 100644 --- a/gcc/testsuite/gcc.target/aarch64/vect_mixed_sizes_8.c +++ b/gcc/testsuite/gcc.target/aarch64/vect_mixed_sizes_8.c @@ -14,5 +14,5 @@ f (int64_t *x, int64_t *y, uint32_t *z, int n) } } -/* { dg-final { scan-assembler-times {\tuxtl\tv[0-9]+\.2d, v[0-9]+\.2s\n} 1 } } */ +/* { dg-final { scan-assembler-times {\tzip1\tv[0-9]+\.4s, v[0-9]+\.4s, v[0-9]+\.4s\n} 1 } } */ /* { dg-final { scan-assembler-times {\tadd\tv[0-9]+\.2d,} 1 } } */ diff --git a/gcc/testsuite/gcc.target/aarch64/vect_mixed_sizes_9.c b/gcc/testsuite/gcc.target/aarch64/vect_mixed_sizes_9.c index de8f698..77ff691 100644 --- a/gcc/testsuite/gcc.target/aarch64/vect_mixed_sizes_9.c +++ b/gcc/testsuite/gcc.target/aarch64/vect_mixed_sizes_9.c @@ -14,5 +14,5 @@ f (int32_t *x, int32_t *y, uint16_t *z, int n) } } -/* { dg-final { scan-assembler-times {\tuxtl\tv[0-9]+\.4s, v[0-9]+\.4h\n} 1 } } */ +/* { dg-final { scan-assembler-times {\tzip1\tv[0-9]+\.8h, v[0-9]+\.8h, v[0-9]+\.8h\n} 1 } } */ /* { dg-final { scan-assembler-times {\tadd\tv[0-9]+\.4s,} 1 } } */ diff --git a/gcc/testsuite/gcc.target/arm/simd/vld1_base_xN_1.c b/gcc/testsuite/gcc.target/arm/simd/vld1_base_xN_1.c new file mode 100644 index 0000000..a5686ff --- /dev/null +++ b/gcc/testsuite/gcc.target/arm/simd/vld1_base_xN_1.c @@ -0,0 +1,176 @@ +/* { dg-do assemble } */ +/* { dg-require-effective-target arm_neon_ok } */ +/* { dg-options "-save-temps -O2" } */ +/* { dg-add-options arm_neon } */ + +#include "arm_neon.h" + +uint8x8x2_t test_vld1_u8_x2 (uint8_t * a) +{ + return vld1_u8_x2 (a); +} + +uint16x4x2_t test_vld1_u16_x2 (uint16_t * a) +{ + return vld1_u16_x2 (a); +} + +uint32x2x2_t test_vld1_u32_x2 (uint32_t * a) +{ + return vld1_u32_x2 (a); +} + +uint64x1x2_t test_vld1_u64_x2 (uint64_t * a) +{ + return vld1_u64_x2 (a); +} + +int8x8x2_t test_vld1_s8_x2 (int8_t * a) +{ + return vld1_s8_x2 (a); +} + +int16x4x2_t test_vld1_s16_x2 (int16_t * a) +{ + return vld1_s16_x2 (a); +} + +int32x2x2_t test_vld1_s32_x2 (int32_t * a) +{ + return vld1_s32_x2 (a); +} + +int64x1x2_t test_vld1_s64_x2 (int64_t * a) +{ + return vld1_s64_x2 (a); +} + +float32x2x2_t test_vld1_f32_x2 (float32_t * a) +{ + return vld1_f32_x2 (a); +} + +poly8x8x2_t test_vld1_p8_x2 (poly8_t * a) +{ + return vld1_p8_x2 (a); +} + +poly16x4x2_t test_vld1_p16_x2 (poly16_t * a) +{ + return vld1_p16_x2 (a); +} + +uint8x8x3_t test_vld1_u8_x3 (uint8_t * a) +{ + return vld1_u8_x3 (a); +} + +uint16x4x3_t test_vld1_u16_x3 (uint16_t * a) +{ + return vld1_u16_x3 (a); +} + +uint32x2x3_t test_vld1_u32_x3 (uint32_t * a) +{ + return vld1_u32_x3 (a); +} + +uint64x1x3_t test_vld1_u64_x3 (uint64_t * a) +{ + return vld1_u64_x3 (a); +} + +int8x8x3_t test_vld1_s8_x3 (int8_t * a) +{ + return vld1_s8_x3 (a); +} + +int16x4x3_t test_vld1_s16_x3 (int16_t * a) +{ + return vld1_s16_x3 (a); +} + +int32x2x3_t test_vld1_s32_x3 (int32_t * a) +{ + return vld1_s32_x3 (a); +} + +int64x1x3_t test_vld1_s64_x3 (int64_t * a) +{ + return vld1_s64_x3 (a); +} + +float32x2x3_t test_vld1_f32_x3 (float32_t * a) +{ + return vld1_f32_x3 (a); +} + +poly8x8x3_t test_vld1_p8_x3 (poly8_t * a) +{ + return vld1_p8_x3 (a); +} + +poly16x4x3_t test_vld1_p16_x3 (poly16_t * a) +{ + return vld1_p16_x3 (a); +} + +uint8x8x4_t test_vld1_u8_x4 (uint8_t * a) +{ + return vld1_u8_x4 (a); +} + +uint16x4x4_t test_vld1_u16_x4 (uint16_t * a) +{ + return vld1_u16_x4 (a); +} + +uint32x2x4_t test_vld1_u32_x4 (uint32_t * a) +{ + return vld1_u32_x4 (a); +} + +uint64x1x4_t test_vld1_u64_x4 (uint64_t * a) +{ + return vld1_u64_x4 (a); +} + +int8x8x4_t test_vld1_s8_x4 (int8_t * a) +{ + return vld1_s8_x4 (a); +} + +int16x4x4_t test_vld1_s16_x4 (int16_t * a) +{ + return vld1_s16_x4 (a); +} + +int32x2x4_t test_vld1_s32_x4 (int32_t * a) +{ + return vld1_s32_x4 (a); +} + +int64x1x4_t test_vld1_s64_x4 (int64_t * a) +{ + return vld1_s64_x4 (a); +} + +float32x2x4_t test_vld1_f32_x4 (float32_t * a) +{ + return vld1_f32_x4 (a); +} + +poly8x8x4_t test_vld1_p8_x4 (poly8_t * a) +{ + return vld1_p8_x4 (a); +} + +poly16x4x4_t test_vld1_p16_x4 (poly16_t * a) +{ + return vld1_p16_x4 (a); +} + +/* { dg-final { scan-assembler-times {vld1.8\t\{d[0-9]+-d[0-9]+\}, \[r[0-9]+\]\n} 9 } } */ +/* { dg-final { scan-assembler-times {vld1.16\t\{d[0-9]+-d[0-9]+\}, \[r[0-9]+\]\n} 9 } } */ +/* { dg-final { scan-assembler-times {vld1.32\t\{d[0-9]+-d[0-9]+\}, \[r[0-9]+\]\n} 9 } } */ +/* { dg-final { scan-assembler-times {vld1.64\t\{d[0-9]+-d[0-9]+\}, \[r[0-9]+:64\]\n} 6 } } */
\ No newline at end of file diff --git a/gcc/testsuite/gcc.target/arm/simd/vld1_bf16_xN_1.c b/gcc/testsuite/gcc.target/arm/simd/vld1_bf16_xN_1.c new file mode 100644 index 0000000..7ed1783 --- /dev/null +++ b/gcc/testsuite/gcc.target/arm/simd/vld1_bf16_xN_1.c @@ -0,0 +1,23 @@ +/* { dg-do assemble } */ +/* { dg-require-effective-target arm_v8_2a_bf16_neon_ok } */ +/* { dg-options "-save-temps -O2" } */ +/* { dg-add-options arm_v8_2a_bf16_neon } */ + +#include "arm_neon.h" + +bfloat16x4x2_t test_vld1_bf16_x2 (bfloat16_t * a) +{ + return vld1_bf16_x2 (a); +} + +bfloat16x4x3_t test_vld1_bf16_x3 (bfloat16_t * a) +{ + return vld1_bf16_x3 (a); +} + +bfloat16x4x4_t test_vld1_bf16_x4 (bfloat16_t * a) +{ + return vld1_bf16_x4 (a); +} + +/* { dg-final { scan-assembler-times {vld1.16\t\{d[0-9]+-d[0-9]+\}, \[r[0-9]+\]\n} 3 } } */
\ No newline at end of file diff --git a/gcc/testsuite/gcc.target/arm/simd/vld1_fp16_xN_1.c b/gcc/testsuite/gcc.target/arm/simd/vld1_fp16_xN_1.c new file mode 100644 index 0000000..82e7211 --- /dev/null +++ b/gcc/testsuite/gcc.target/arm/simd/vld1_fp16_xN_1.c @@ -0,0 +1,23 @@ +/* { dg-do assemble } */ +/* { dg-require-effective-target arm_neon_fp16_ok } */ +/* { dg-options "-save-temps -O2" } */ +/* { dg-add-options arm_neon_fp16 } */ + +#include "arm_neon.h" + +float16x4x2_t test_vld1_f16_x2 (float16_t * a) +{ + return vld1_f16_x2 (a); +} + +float16x4x3_t test_vld1_f16_x3 (float16_t * a) +{ + return vld1_f16_x3 (a); +} + +float16x4x4_t test_vld1_f16_x4 (float16_t * a) +{ + return vld1_f16_x4 (a); +} + +/* { dg-final { scan-assembler-times {vld1.16\t\{d[0-9]+-d[0-9]+\}, \[r[0-9]+\]\n} 3 } } */ diff --git a/gcc/testsuite/gcc.target/arm/simd/vld1_p64_xN_1.c b/gcc/testsuite/gcc.target/arm/simd/vld1_p64_xN_1.c new file mode 100644 index 0000000..644371b --- /dev/null +++ b/gcc/testsuite/gcc.target/arm/simd/vld1_p64_xN_1.c @@ -0,0 +1,23 @@ +/* { dg-do assemble } */ +/* { dg-require-effective-target arm_crypto_ok } */ +/* { dg-options "-save-temps -O2" } */ +/* { dg-add-options arm_crypto } */ + +#include "arm_neon.h" + +poly64x1x2_t test_vld1_p64_x2 (poly64_t * a) +{ + return vld1_p64_x2 (a); +} + +poly64x1x3_t test_vld1_p64_x3 (poly64_t * a) +{ + return vld1_p64_x3 (a); +} + +poly64x1x4_t test_vld1_p64_x4 (poly64_t * a) +{ + return vld1_p64_x4 (a); +} + +/* { dg-final { scan-assembler-times {vld1.64\t\{d[0-9]+-d[0-9]+\}, \[r[0-9]+:64\]\n} 3 } } */ diff --git a/gcc/testsuite/gcc.target/arm/simd/vld1q_base_xN_1.c b/gcc/testsuite/gcc.target/arm/simd/vld1q_base_xN_1.c new file mode 100644 index 0000000..01b29b6 --- /dev/null +++ b/gcc/testsuite/gcc.target/arm/simd/vld1q_base_xN_1.c @@ -0,0 +1,183 @@ +/* { dg-do assemble } */ +/* { dg-require-effective-target arm_neon_ok } */ +/* { dg-options "-save-temps -O2" } */ +/* { dg-add-options arm_neon } */ + +#include "arm_neon.h" + +uint8x16x2_t test_vld1q_u8_x2 (uint8_t * a) +{ + return vld1q_u8_x2 (a); +} + +uint16x8x2_t test_vld1q_u16_x2 (uint16_t * a) +{ + return vld1q_u16_x2 (a); +} + +uint32x4x2_t test_vld1q_u32_x2 (uint32_t * a) +{ + return vld1q_u32_x2 (a); +} + +uint64x2x2_t test_vld1q_u64_x2 (uint64_t * a) +{ + return vld1q_u64_x2 (a); +} + +int8x16x2_t test_vld1q_s8_x2 (int8_t * a) +{ + return vld1q_s8_x2 (a); +} + +int16x8x2_t test_vld1q_s16_x2 (int16_t * a) +{ + return vld1q_s16_x2 (a); +} + +int32x4x2_t test_vld1q_s32_x2 (int32_t * a) +{ + return vld1q_s32_x2 (a); +} + +int64x2x2_t test_vld1q_s64_x2 (int64_t * a) +{ + return vld1q_s64_x2 (a); +} + +float32x4x2_t test_vld1q_f32_x2 (float32_t * a) +{ + return vld1q_f32_x2 (a); +} + +poly8x16x2_t test_vld1q_p8_x2 (poly8_t * a) +{ + return vld1q_p8_x2 (a); +} + +poly16x8x2_t test_vld1q_p16_x2 (poly16_t * a) +{ + return vld1q_p16_x2 (a); +} + +uint8x16x3_t test_vld1q_u8_x3 (uint8_t * a) +{ + return vld1q_u8_x3 (a); +} + +uint16x8x3_t test_vld1q_u16_x3 (uint16_t * a) +{ + return vld1q_u16_x3 (a); +} + +uint32x4x3_t test_vld1q_u32_x3 (uint32_t * a) +{ + return vld1q_u32_x3 (a); +} + +uint64x2x3_t test_vld1q_u64_x3 (uint64_t * a) +{ + return vld1q_u64_x3 (a); +} + +int8x16x3_t test_vld1q_s8_x3 (int8_t * a) +{ + return vld1q_s8_x3 (a); +} + +int16x8x3_t test_vld1q_s16_x3 (int16_t * a) +{ + return vld1q_s16_x3 (a); +} + +int32x4x3_t test_vld1q_s32_x3 (int32_t * a) +{ + return vld1q_s32_x3 (a); +} + +int64x2x3_t test_vld1q_s64_x3 (int64_t * a) +{ + return vld1q_s64_x3 (a); +} + +float32x4x3_t test_vld1q_f32_x3 (float32_t * a) +{ + return vld1q_f32_x3 (a); +} + +poly8x16x3_t test_vld1q_p8_x3 (poly8_t * a) +{ + return vld1q_p8_x3 (a); +} + +poly16x8x3_t test_vld1q_p16_x3 (poly16_t * a) +{ + return vld1q_p16_x3 (a); +} + +uint8x16x4_t test_vld1q_u8_x4 (uint8_t * a) +{ + return vld1q_u8_x4 (a); +} + +uint16x8x4_t test_vld1q_u16_x4 (uint16_t * a) +{ + return vld1q_u16_x4 (a); +} + +uint32x4x4_t test_vld1q_u32_x4 (uint32_t * a) +{ + return vld1q_u32_x4 (a); +} + +uint64x2x4_t test_vld1q_u64_x4 (uint64_t * a) +{ + return vld1q_u64_x4 (a); +} + +int8x16x4_t test_vld1q_s8_x4 (int8_t * a) +{ + return vld1q_s8_x4 (a); +} + +int16x8x4_t test_vld1q_s16_x4 (int16_t * a) +{ + return vld1q_s16_x4 (a); +} + +int32x4x4_t test_vld1q_s32_x4 (int32_t * a) +{ + return vld1q_s32_x4 (a); +} + +int64x2x4_t test_vld1q_s64_x4 (int64_t * a) +{ + return vld1q_s64_x4 (a); +} + +float32x4x4_t test_vld1q_f32_x4 (float32_t * a) +{ + return vld1q_f32_x4 (a); +} + +poly8x16x4_t test_vld1q_p8_x4 (poly8_t * a) +{ + return vld1q_p8_x4 (a); +} + +poly16x8x4_t test_vld1q_p16_x4 (poly16_t * a) +{ + return vld1q_p16_x4 (a); +} + +/* { dg-final { scan-assembler-times {vld1.8\t\{d[0-9]+-d[0-9]+\}, \[r[0-9]+\]\n} 9 } } */ +/* { dg-final { scan-assembler-times {vld1.8\t\{d[0-9]+-d[0-9]+\}, \[r[0-9]+\]!\n} 6 } } */ + +/* { dg-final { scan-assembler-times {vld1.16\t\{d[0-9]+-d[0-9]+\}, \[r[0-9]+\]\n} 9 } } */ +/* { dg-final { scan-assembler-times {vld1.16\t\{d[0-9]+-d[0-9]+\}, \[r[0-9]+\]!\n} 6 } } */ + +/* { dg-final { scan-assembler-times {vld1.32\t\{d[0-9]+-d[0-9]+\}, \[r[0-9]+\]\n} 9 } } */ +/* { dg-final { scan-assembler-times {vld1.32\t\{d[0-9]+-d[0-9]+\}, \[r[0-9]+\]!\n} 6 } } */ + +/* { dg-final { scan-assembler-times {vld1.64\t\{d[0-9]+-d[0-9]+\}, \[r[0-9]+:64\]\n} 6 } } */ +/* { dg-final { scan-assembler-times {vld1.64\t\{d[0-9]+-d[0-9]+\}, \[r[0-9]+:64\]!\n} 4 } } */ diff --git a/gcc/testsuite/gcc.target/arm/simd/vld1q_bf16_xN_1.c b/gcc/testsuite/gcc.target/arm/simd/vld1q_bf16_xN_1.c new file mode 100644 index 0000000..21db352 --- /dev/null +++ b/gcc/testsuite/gcc.target/arm/simd/vld1q_bf16_xN_1.c @@ -0,0 +1,24 @@ +/* { dg-do assemble } */ +/* { dg-require-effective-target arm_v8_2a_bf16_neon_ok } */ +/* { dg-options "-save-temps -O2" } */ +/* { dg-add-options arm_v8_2a_bf16_neon } */ + +#include "arm_neon.h" + +bfloat16x8x2_t test_vld1q_bf16_x2 (bfloat16_t * a) +{ + return vld1q_bf16_x2 (a); +} + +bfloat16x8x3_t test_vld1q_bf16_x3 (bfloat16_t * a) +{ + return vld1q_bf16_x3 (a); +} + +bfloat16x8x4_t test_vld1q_bf16_x4 (bfloat16_t * a) +{ + return vld1q_bf16_x4 (a); +} + +/* { dg-final { scan-assembler-times {vld1.16\t\{d[0-9]+-d[0-9]+\}, \[r[0-9]+\]\n} 3 } } */ +/* { dg-final { scan-assembler-times {vld1.16\t\{d[0-9]+-d[0-9]+\}, \[r[0-9]+\]!\n} 2 } } */ diff --git a/gcc/testsuite/gcc.target/arm/simd/vld1q_fp16_xN_1.c b/gcc/testsuite/gcc.target/arm/simd/vld1q_fp16_xN_1.c new file mode 100644 index 0000000..3838cd0 --- /dev/null +++ b/gcc/testsuite/gcc.target/arm/simd/vld1q_fp16_xN_1.c @@ -0,0 +1,24 @@ +/* { dg-do assemble } */ +/* { dg-require-effective-target arm_neon_fp16_ok } */ +/* { dg-options "-save-temps -O2" } */ +/* { dg-add-options arm_neon_fp16 } */ + +#include "arm_neon.h" + +float16x8x2_t test_vld1q_f16_x2 (float16_t * a) +{ + return vld1q_f16_x2 (a); +} + +float16x8x3_t test_vld1q_f16_x3 (float16_t * a) +{ + return vld1q_f16_x3 (a); +} + +float16x8x4_t test_vld1q_f16_x4 (float16_t * a) +{ + return vld1q_f16_x4 (a); +} + +/* { dg-final { scan-assembler-times {vld1.16\t\{d[0-9]+-d[0-9]+\}, \[r[0-9]+\]\n} 3 } } */ +/* { dg-final { scan-assembler-times {vld1.16\t\{d[0-9]+-d[0-9]+\}, \[r[0-9]+\]!\n} 2 } } */ diff --git a/gcc/testsuite/gcc.target/arm/simd/vld1q_p64_xN_1.c b/gcc/testsuite/gcc.target/arm/simd/vld1q_p64_xN_1.c new file mode 100644 index 0000000..d359a5a --- /dev/null +++ b/gcc/testsuite/gcc.target/arm/simd/vld1q_p64_xN_1.c @@ -0,0 +1,24 @@ +/* { dg-do assemble } */ +/* { dg-require-effective-target arm_crypto_ok } */ +/* { dg-options "-save-temps -O2" } */ +/* { dg-add-options arm_crypto } */ + +#include "arm_neon.h" + +poly64x2x2_t test_vld1q_p64_x2 (poly64_t * a) +{ + return vld1q_p64_x2 (a); +} + +poly64x2x3_t test_vld1q_p64_x3 (poly64_t * a) +{ + return vld1q_p64_x3 (a); +} + +poly64x2x4_t test_vld1q_p64_x4 (poly64_t * a) +{ + return vld1q_p64_x4 (a); +} + +/* { dg-final { scan-assembler-times {vld1.64\t\{d[0-9]+-d[0-9]+\}, \[r[0-9]+:64\]\n} 3 } } */ +/* { dg-final { scan-assembler-times {vld1.64\t\{d[0-9]+-d[0-9]+\}, \[r[0-9]+:64\]!\n} 2 } } */ diff --git a/gcc/testsuite/gcc.target/arm/simd/vst1_base_xN_1.c b/gcc/testsuite/gcc.target/arm/simd/vst1_base_xN_1.c new file mode 100644 index 0000000..04ca658 --- /dev/null +++ b/gcc/testsuite/gcc.target/arm/simd/vst1_base_xN_1.c @@ -0,0 +1,176 @@ +/* { dg-do assemble } */ +/* { dg-require-effective-target arm_neon_ok } */ +/* { dg-options "-save-temps -O2" } */ +/* { dg-add-options arm_neon } */ + +#include "arm_neon.h" + +void test_vst1_u8_x2 (uint8_t * ptr, uint8x8x2_t val) +{ + vst1_u8_x2 (ptr, val); +} + +void test_vst1_u16_x2 (uint16_t * ptr, uint16x4x2_t val) +{ + vst1_u16_x2 (ptr, val); +} + +void test_vst1_u32_x2 (uint32_t * ptr, uint32x2x2_t val) +{ + vst1_u32_x2 (ptr, val); +} + +void test_vst1_u64_x2 (uint64_t * ptr, uint64x1x2_t val) +{ + vst1_u64_x2 (ptr, val); +} + +void test_vst1_s8_x2 (int8_t * ptr, int8x8x2_t val) +{ + vst1_s8_x2 (ptr, val); +} + +void test_vst1_s16_x2 (int16_t * ptr, int16x4x2_t val) +{ + vst1_s16_x2 (ptr, val); +} + +void test_vst1_s32_x2 (int32_t * ptr, int32x2x2_t val) +{ + vst1_s32_x2 (ptr, val); +} + +void test_vst1_s64_x2 (int64_t * ptr, int64x1x2_t val) +{ + vst1_s64_x2 (ptr, val); +} + +void test_vst1_f32_x2 (float32_t * ptr, float32x2x2_t val) +{ + vst1_f32_x2 (ptr, val); +} + +void test_vst1_p8_x2 (poly8_t * ptr, poly8x8x2_t val) +{ + vst1_p8_x2 (ptr, val); +} + +void test_vst1_p16_x2 (poly16_t * ptr, poly16x4x2_t val) +{ + vst1_p16_x2 (ptr, val); +} + +void test_vst1_u8_x3 (uint8_t * ptr, uint8x8x3_t val) +{ + vst1_u8_x3 (ptr, val); +} + +void test_vst1_u16_x3 (uint16_t * ptr, uint16x4x3_t val) +{ + vst1_u16_x3 (ptr, val); +} + +void test_vst1_u32_x3 (uint32_t * ptr, uint32x2x3_t val) +{ + vst1_u32_x3 (ptr, val); +} + +void test_vst1_u64_x3 (uint64_t * ptr, uint64x1x3_t val) +{ + vst1_u64_x3 (ptr, val); +} + +void test_vst1_s8_x3 (int8_t * ptr, int8x8x3_t val) +{ + vst1_s8_x3 (ptr, val); +} + +void test_vst1_s16_x3 (int16_t * ptr, int16x4x3_t val) +{ + vst1_s16_x3 (ptr, val); +} + +void test_vst1_s32_x3 (int32_t * ptr, int32x2x3_t val) +{ + vst1_s32_x3 (ptr, val); +} + +void test_vst1_s64_x3 (int64_t * ptr, int64x1x3_t val) +{ + vst1_s64_x3 (ptr, val); +} + +void test_vst1_f32_x3 (float32_t * ptr, float32x2x3_t val) +{ + vst1_f32_x3 (ptr, val); +} + +void test_vst1_p8_x3 (poly8_t * ptr, poly8x8x3_t val) +{ + vst1_p8_x3 (ptr, val); +} + +void test_vst1_p16_x3 (poly16_t * ptr, poly16x4x3_t val) +{ + vst1_p16_x3 (ptr, val); +} + +void test_vst1_u8_x4 (uint8_t * ptr, uint8x8x4_t val) +{ + vst1_u8_x4 (ptr, val); +} + +void test_vst1_u16_x4 (uint16_t * ptr, uint16x4x4_t val) +{ + vst1_u16_x4 (ptr, val); +} + +void test_vst1_u32_x4 (uint32_t * ptr, uint32x2x4_t val) +{ + vst1_u32_x4 (ptr, val); +} + +void test_vst1_u64_x4 (uint64_t * ptr, uint64x1x4_t val) +{ + vst1_u64_x4 (ptr, val); +} + +void test_vst1_s8_x4 (int8_t * ptr, int8x8x4_t val) +{ + vst1_s8_x4 (ptr, val); +} + +void test_vst1_s16_x4 (int16_t * ptr, int16x4x4_t val) +{ + vst1_s16_x4 (ptr, val); +} + +void test_vst1_s32_x4 (int32_t * ptr, int32x2x4_t val) +{ + vst1_s32_x4 (ptr, val); +} + +void test_vst1_s64_x4 (int64_t * ptr, int64x1x4_t val) +{ + vst1_s64_x4 (ptr, val); +} + +void test_vst1_f32_x4 (float32_t * ptr, float32x2x4_t val) +{ + vst1_f32_x4 (ptr, val); +} + +void test_vst1_p8_x4 (poly8_t * ptr, poly8x8x4_t val) +{ + vst1_p8_x4 (ptr, val); +} + +void test_vst1_p16_x4 (poly16_t * ptr, poly16x4x4_t val) +{ + vst1_p16_x4 (ptr, val); +} + +/* { dg-final { scan-assembler-times {vst1.8\t\{d[0-9]+-d[0-9]+\}, \[r[0-9]+\]\n} 9 } } */ +/* { dg-final { scan-assembler-times {vst1.16\t\{d[0-9]+-d[0-9]+\}, \[r[0-9]+\]\n} 9 } } */ +/* { dg-final { scan-assembler-times {vst1.32\t\{d[0-9]+-d[0-9]+\}, \[r[0-9]+\]\n} 9 } } */ +/* { dg-final { scan-assembler-times {vst1.64\t\{d[0-9]+-d[0-9]+\}, \[r[0-9]+:64\]\n} 6 } } */ diff --git a/gcc/testsuite/gcc.target/arm/simd/vst1_bf16_xN_1.c b/gcc/testsuite/gcc.target/arm/simd/vst1_bf16_xN_1.c new file mode 100644 index 0000000..d919c7d --- /dev/null +++ b/gcc/testsuite/gcc.target/arm/simd/vst1_bf16_xN_1.c @@ -0,0 +1,22 @@ +/* { dg-do assemble } */ +/* { dg-require-effective-target arm_v8_2a_bf16_neon_ok } */ +/* { dg-options "-save-temps -O2" } */ +/* { dg-add-options arm_v8_2a_bf16_neon } */ + +#include "arm_neon.h" + +void test_vst1_bf16_x2 (bfloat16_t * ptr, bfloat16x4x2_t val) +{ + vst1_bf16_x2 (ptr, val); +} + +void test_vst1_bf16_x3 (bfloat16_t * ptr, bfloat16x4x3_t val) +{ + vst1_bf16_x3 (ptr, val); +} + +void test_vst1_bf16_x4 (bfloat16_t * ptr, bfloat16x4x4_t val) +{ + vst1_bf16_x4 (ptr, val); +} +/* { dg-final { scan-assembler-times {vst1.16\t\{d[0-9]+-d[0-9]+\}, \[r[0-9]+\]\n} 3 } } */ diff --git a/gcc/testsuite/gcc.target/arm/simd/vst1_fp16_xN_1.c b/gcc/testsuite/gcc.target/arm/simd/vst1_fp16_xN_1.c new file mode 100644 index 0000000..3d1d1eb --- /dev/null +++ b/gcc/testsuite/gcc.target/arm/simd/vst1_fp16_xN_1.c @@ -0,0 +1,23 @@ +/* { dg-do assemble } */ +/* { dg-require-effective-target arm_neon_fp16_ok } */ +/* { dg-options "-save-temps -O2" } */ +/* { dg-add-options arm_neon_fp16 } */ + +#include "arm_neon.h" + +void test_vst1_f16_x2 (float16_t * ptr, float16x4x2_t val) +{ + vst1_f16_x2 (ptr, val); +} + +void test_vst1_f16_x3 (float16_t * ptr, float16x4x3_t val) +{ + vst1_f16_x3 (ptr, val); +} + +void test_vst1_f16_x4 (float16_t * ptr, float16x4x4_t val) +{ + vst1_f16_x4 (ptr, val); +} + +/* { dg-final { scan-assembler-times {vst1.16\t\{d[0-9]+-d[0-9]+\}, \[r[0-9]+\]\n} 3 } } */ diff --git a/gcc/testsuite/gcc.target/arm/simd/vst1_p64_xN_1.c b/gcc/testsuite/gcc.target/arm/simd/vst1_p64_xN_1.c new file mode 100644 index 0000000..6291214 --- /dev/null +++ b/gcc/testsuite/gcc.target/arm/simd/vst1_p64_xN_1.c @@ -0,0 +1,23 @@ +/* { dg-do assemble } */ +/* { dg-require-effective-target arm_crypto_ok } */ +/* { dg-options "-save-temps -O2" } */ +/* { dg-add-options arm_crypto } */ + +#include "arm_neon.h" + +void test_vst1_p64_x2 (poly64_t * ptr, poly64x1x2_t val) +{ + vst1_p64_x2 (ptr, val); +} + +void test_vst1_p64_x3 (poly64_t * ptr, poly64x1x3_t val) +{ + vst1_p64_x3 (ptr, val); +} + +void test_vst1_p64_x4 (poly64_t * ptr, poly64x1x4_t val) +{ + vst1_p64_x4 (ptr, val); +} + +/* { dg-final { scan-assembler-times {vst1.64\t\{d[0-9]+-d[0-9]+\}, \[r[0-9]+:64\]\n} 3 } } */
\ No newline at end of file diff --git a/gcc/testsuite/gcc.target/arm/simd/vst1q_base_xN_1.c b/gcc/testsuite/gcc.target/arm/simd/vst1q_base_xN_1.c new file mode 100644 index 0000000..0700058 --- /dev/null +++ b/gcc/testsuite/gcc.target/arm/simd/vst1q_base_xN_1.c @@ -0,0 +1,185 @@ +/* { dg-do assemble } */ +/* { dg-require-effective-target arm_neon_ok } */ +/* { dg-options "-save-temps -O2" } */ +/* { dg-add-options arm_neon } */ + +#include "arm_neon.h" + + +void test_vst1q_u8_x2 (uint8_t * ptr, uint8x16x2_t val) +{ + vst1q_u8_x2 (ptr, val); +} + +void test_vst1q_u16_x2 (uint16_t * ptr, uint16x8x2_t val) +{ + vst1q_u16_x2 (ptr, val); +} + +void test_vst1q_u32_x2 (uint32_t * ptr, uint32x4x2_t val) +{ + vst1q_u32_x2 (ptr, val); +} + +void test_vst1q_u64_x2 (uint64_t * ptr, uint64x2x2_t val) +{ + vst1q_u64_x2 (ptr, val); +} + +void test_vst1q_s8_x2 (int8_t * ptr, int8x16x2_t val) +{ + vst1q_s8_x2 (ptr, val); +} + +void test_vst1q_s16_x2 (int16_t * ptr, int16x8x2_t val) +{ + vst1q_s16_x2 (ptr, val); +} + +void test_vst1q_s32_x2 (int32_t * ptr, int32x4x2_t val) +{ + vst1q_s32_x2 (ptr, val); +} + +void test_vst1q_s64_x2 (int64_t * ptr, int64x2x2_t val) +{ + vst1q_s64_x2 (ptr, val); +} + +void test_vst1q_f32_x2 (float32_t * ptr, float32x4x2_t val) +{ + vst1q_f32_x2 (ptr, val); +} + +void test_vst1q_p8_x2 (poly8_t * ptr, poly8x16x2_t val) +{ + vst1q_p8_x2 (ptr, val); +} + +void test_vst1q_p16_x2 (poly16_t * ptr, poly16x8x2_t val) +{ + vst1q_p16_x2 (ptr, val); +} + +void test_vst1q_u8_x3 (uint8_t * ptr, uint8x16x3_t val) +{ + vst1q_u8_x3 (ptr, val); +} + +void test_vst1q_u16_x3 (uint16_t * ptr, uint16x8x3_t val) +{ + vst1q_u16_x3 (ptr, val); +} + +void test_vst1q_u32_x3 (uint32_t * ptr, uint32x4x3_t val) +{ + vst1q_u32_x3 (ptr, val); +} + +void test_vst1q_u64_x3 (uint64_t * ptr, uint64x2x3_t val) +{ + vst1q_u64_x3 (ptr, val); +} + +void test_vst1q_s8_x3 (int8_t * ptr, int8x16x3_t val) +{ + vst1q_s8_x3 (ptr, val); +} + +void test_vst1q_s16_x3 (int16_t * ptr, int16x8x3_t val) +{ + vst1q_s16_x3 (ptr, val); +} + +void test_vst1q_s32_x3 (int32_t * ptr, int32x4x3_t val) +{ + vst1q_s32_x3 (ptr, val); +} + +void test_vst1q_s64_x3 (int64_t * ptr, int64x2x3_t val) +{ + vst1q_s64_x3 (ptr, val); +} + +void test_vst1q_f32_x3 (float32_t * ptr, float32x4x3_t val) +{ + vst1q_f32_x3 (ptr, val); +} + +void test_vst1q_p8_x3 (poly8_t * ptr, poly8x16x3_t val) +{ + vst1q_p8_x3 (ptr, val); +} + +void test_vst1q_p16_x3 (poly16_t * ptr, poly16x8x3_t val) +{ + vst1q_p16_x3 (ptr, val); +} + +void test_vst1q_u8_x4 (uint8_t * ptr, uint8x16x4_t val) +{ + vst1q_u8_x4 (ptr, val); +} + +void test_vst1q_u16_x4 (uint16_t * ptr, uint16x8x4_t val) +{ + vst1q_u16_x4 (ptr, val); +} + +void test_vst1q_u32_x4 (uint32_t * ptr, uint32x4x4_t val) +{ + vst1q_u32_x4 (ptr, val); +} + +void test_vst1q_u64_x4 (uint64_t * ptr, uint64x2x4_t val) +{ + vst1q_u64_x4 (ptr, val); +} + +void test_vst1q_s8_x4 (int8_t * ptr, int8x16x4_t val) +{ + vst1q_s8_x4 (ptr, val); +} + +void test_vst1q_s16_x4 (int16_t * ptr, int16x8x4_t val) +{ + vst1q_s16_x4 (ptr, val); +} + +void test_vst1q_s32_x4 (int32_t * ptr, int32x4x4_t val) +{ + vst1q_s32_x4 (ptr, val); +} + +void test_vst1q_s64_x4 (int64_t * ptr, int64x2x4_t val) +{ + vst1q_s64_x4 (ptr, val); +} + +void test_vst1q_f32_x4 (float32_t * ptr, float32x4x4_t val) +{ + vst1q_f32_x4 (ptr, val); +} + +void test_vst1q_p8_x4 (poly8_t * ptr, poly8x16x4_t val) +{ + vst1q_p8_x4 (ptr, val); +} + +void test_vst1q_p16_x4 (poly16_t * ptr, poly16x8x4_t val) +{ + vst1q_p16_x4 (ptr, val); +} + + +/* { dg-final { scan-assembler-times {vst1.8\t\{d[0-9]+-d[0-9]+\}, \[r[0-9]+\]\n} 9 } } */ +/* { dg-final { scan-assembler-times {vst1.8\t\{d[0-9]+-d[0-9]+\}, \[r[0-9]+\]!\n} 6 } } */ + +/* { dg-final { scan-assembler-times {vst1.16\t\{d[0-9]+-d[0-9]+\}, \[r[0-9]+\]\n} 9 } } */ +/* { dg-final { scan-assembler-times {vst1.16\t\{d[0-9]+-d[0-9]+\}, \[r[0-9]+\]!\n} 6 } } */ + +/* { dg-final { scan-assembler-times {vst1.32\t\{d[0-9]+-d[0-9]+\}, \[r[0-9]+\]\n} 9 } } */ +/* { dg-final { scan-assembler-times {vst1.32\t\{d[0-9]+-d[0-9]+\}, \[r[0-9]+\]!\n} 6 } } */ + +/* { dg-final { scan-assembler-times {vst1.64\t\{d[0-9]+-d[0-9]+\}, \[r[0-9]+:64\]\n} 6 } } */ +/* { dg-final { scan-assembler-times {vst1.64\t\{d[0-9]+-d[0-9]+\}, \[r[0-9]+:64\]!\n} 4 } } */ diff --git a/gcc/testsuite/gcc.target/arm/simd/vst1q_bf16_xN_1.c b/gcc/testsuite/gcc.target/arm/simd/vst1q_bf16_xN_1.c new file mode 100644 index 0000000..435f376 --- /dev/null +++ b/gcc/testsuite/gcc.target/arm/simd/vst1q_bf16_xN_1.c @@ -0,0 +1,24 @@ +/* { dg-do assemble } */ +/* { dg-require-effective-target arm_v8_2a_bf16_neon_ok } */ +/* { dg-options "-save-temps -O2" } */ +/* { dg-add-options arm_v8_2a_bf16_neon } */ + +#include "arm_neon.h" + +void test_vst1q_bf16_x2 (bfloat16_t * ptr, bfloat16x8x2_t val) +{ + vst1q_bf16_x2 (ptr, val); +} + +void test_vst1q_bf16_x3 (bfloat16_t * ptr, bfloat16x8x3_t val) +{ + vst1q_bf16_x3 (ptr, val); +} + +void test_vst1q_bf16_x4 (bfloat16_t * ptr, bfloat16x8x4_t val) +{ + vst1q_bf16_x4 (ptr, val); +} + +/* { dg-final { scan-assembler-times {vst1.16\t\{d[0-9]+-d[0-9]+\}, \[r[0-9]+\]\n} 3 } } */ +/* { dg-final { scan-assembler-times {vst1.16\t\{d[0-9]+-d[0-9]+\}, \[r[0-9]+\]!\n} 2 } } */ diff --git a/gcc/testsuite/gcc.target/arm/simd/vst1q_fp16_xN_1.c b/gcc/testsuite/gcc.target/arm/simd/vst1q_fp16_xN_1.c new file mode 100644 index 0000000..b260683 --- /dev/null +++ b/gcc/testsuite/gcc.target/arm/simd/vst1q_fp16_xN_1.c @@ -0,0 +1,24 @@ +/* { dg-do assemble } */ +/* { dg-require-effective-target arm_neon_fp16_ok } */ +/* { dg-options "-save-temps -O2" } */ +/* { dg-add-options arm_neon_fp16 } */ + +#include "arm_neon.h" + +void test_vst1q_f16_x2 (float16_t * ptr, float16x8x2_t val) +{ + vst1q_f16_x2 (ptr, val); +} + +void test_vst1q_f16_x3 (float16_t * ptr, float16x8x3_t val) +{ + vst1q_f16_x3 (ptr, val); +} + +void test_vst1q_f16_x4 (float16_t * ptr, float16x8x4_t val) +{ + vst1q_f16_x4 (ptr, val); +} + +/* { dg-final { scan-assembler-times {vst1.16\t\{d[0-9]+-d[0-9]+\}, \[r[0-9]+\]\n} 3 } } */ +/* { dg-final { scan-assembler-times {vst1.16\t\{d[0-9]+-d[0-9]+\}, \[r[0-9]+\]!\n} 2 } } */ diff --git a/gcc/testsuite/gcc.target/arm/simd/vst1q_p64_xN_1.c b/gcc/testsuite/gcc.target/arm/simd/vst1q_p64_xN_1.c new file mode 100644 index 0000000..f14b4fb --- /dev/null +++ b/gcc/testsuite/gcc.target/arm/simd/vst1q_p64_xN_1.c @@ -0,0 +1,24 @@ +/* { dg-do assemble } */ +/* { dg-require-effective-target arm_crypto_ok } */ +/* { dg-options "-save-temps -O2" } */ +/* { dg-add-options arm_crypto } */ + +#include "arm_neon.h" + +void test_vst1q_p64_x2(poly64_t *ptr, poly64x2x2_t val) +{ + vst1q_p64_x2(ptr, val); +} + +void test_vst1q_p64_x3(poly64_t *ptr, poly64x2x3_t val) +{ + vst1q_p64_x3(ptr, val); +} + +void test_vst1q_p64_x4(poly64_t *ptr, poly64x2x4_t val) +{ + vst1q_p64_x4(ptr, val); +} + +/* { dg-final { scan-assembler-times {vst1.64\t\{d[0-9]+-d[0-9]+\}, \[r[0-9]+:64\]\n} 3 } } */ +/* { dg-final { scan-assembler-times {vst1.64\t\{d[0-9]+-d[0-9]+\}, \[r[0-9]+:64\]!\n} 2 } } */ diff --git a/gcc/testsuite/gcc.target/avr/torture/pr112944-flmap-0.c b/gcc/testsuite/gcc.target/avr/torture/pr112944-flmap-0.c new file mode 100644 index 0000000..3aae7b5 --- /dev/null +++ b/gcc/testsuite/gcc.target/avr/torture/pr112944-flmap-0.c @@ -0,0 +1,29 @@ +/* { dg-do run } */ +/* { dg-additional-options "-Wl,--defsym,__flmap=0" } */ + +const int val = 1234; + +#ifdef __AVR_HAVE_FLMAP__ +/* Initialize NVMCTRL_CTRLB.FLMAP to __flmap. */ +#include <avr/io.h> +__attribute__((naked, section(".init2"))) +__attribute__((used, unused, no_instrument_function)) +static void init_flmap (void) +{ + uint8_t ctrlb = NVMCTRL_CTRLB; + ctrlb &= ~ NVMCTRL_FLMAP_gm; + ctrlb |= 0 << NVMCTRL_FLMAP_gp; + NVMCTRL_CTRLB = ctrlb; +} +#endif + +int main (void) +{ + const int *p = & val; + __asm ("" : "+r" (p)); + + if (*p != 1234) + __builtin_abort (); + + return 0; +} diff --git a/gcc/testsuite/gcc.target/avr/torture/pr112944-flmap-1.c b/gcc/testsuite/gcc.target/avr/torture/pr112944-flmap-1.c new file mode 100644 index 0000000..f18078d --- /dev/null +++ b/gcc/testsuite/gcc.target/avr/torture/pr112944-flmap-1.c @@ -0,0 +1,29 @@ +/* { dg-do run } */ +/* { dg-additional-options "-Wl,--defsym,__flmap=1" } */ + +const int val = 1234; + +#ifdef __AVR_HAVE_FLMAP__ +/* Initialize NVMCTRL_CTRLB.FLMAP to __flmap. */ +#include <avr/io.h> +__attribute__((naked, section(".init2"))) +__attribute__((used, unused, no_instrument_function)) +static void init_flmap (void) +{ + uint8_t ctrlb = NVMCTRL_CTRLB; + ctrlb &= ~ NVMCTRL_FLMAP_gm; + ctrlb |= 1 << NVMCTRL_FLMAP_gp; + NVMCTRL_CTRLB = ctrlb; +} +#endif + +int main (void) +{ + const int *p = & val; + __asm ("" : "+r" (p)); + + if (*p != 1234) + __builtin_abort (); + + return 0; +} diff --git a/gcc/testsuite/gcc.target/i386/pr104401.c b/gcc/testsuite/gcc.target/i386/pr104401.c new file mode 100644 index 0000000..8ce7ff8 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr104401.c @@ -0,0 +1,27 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -msse4.1" } */ +/* { dg-final { scan-assembler-times "pminsd" 2 } } */ +/* { dg-final { scan-assembler-times "pmaxsd" 2 } } */ + +#include <smmintrin.h> + +__m128i min32(__m128i value, __m128i input) +{ + return _mm_blendv_epi8(input, value, _mm_cmplt_epi32(value, input)); +} + +__m128i max32(__m128i value, __m128i input) +{ + return _mm_blendv_epi8(input, value, _mm_cmpgt_epi32(value, input)); +} + +__m128i min32_1(__m128i value, __m128i input) +{ + return _mm_blendv_epi8(input, value, _mm_cmpgt_epi32(input, value)); +} + +__m128i max32_1(__m128i value, __m128i input) +{ + return _mm_blendv_epi8(input, value, _mm_cmplt_epi32(input, value)); +} + diff --git a/gcc/testsuite/gcc.target/i386/pr113048.c b/gcc/testsuite/gcc.target/i386/pr113048.c new file mode 100644 index 0000000..4f228a8 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr113048.c @@ -0,0 +1,26 @@ +/* PR rtl-optimization/113048 */ +/* { dg-do compile } */ +/* { dg-options "-O -march=cascadelake -fwrapv" } */ + +signed char a, b, c; +int d; +const char *e, *q; +short f; +int g; + +void +foo (int x, long long y, long long z) +{ + unsigned char h = x; + int i = __builtin_strncmp (q, e, 2); + h /= g; + unsigned long long j = (~z & (0xfb5856dd8a4d4702ULL & f) / 0) * h; /* { dg-warning "division by zero" } */ + b += __builtin_add_overflow_p (d, c, 0); + signed char k = y; + long l = -k & sizeof (0); + long long m = y + j + z + h + 3 + l; + int n = m + i; + short o = n + f; + signed char p = o + h + k; + a = p; +} diff --git a/gcc/testsuite/gcc.target/i386/vect-pr113078.c b/gcc/testsuite/gcc.target/i386/vect-pr113078.c new file mode 100644 index 0000000..e766605 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/vect-pr113078.c @@ -0,0 +1,16 @@ +/* { dg-do compile } */ +/* { dg-options "-O3 -mavx512vl" } */ + +int +foo (int n, int* p, int* pi) +{ + int sum = 0; + for (int i = 0; i != n; i++) + { + if (pi[i] > 0) + sum -= p[i]; + } + return sum; +} + +/* { dg-final { scan-assembler-times "vpsub\[^\r\n\]*%k" 2 } } */ diff --git a/gcc/testsuite/gcc.target/loongarch/sign-extend.c b/gcc/testsuite/gcc.target/loongarch/sign-extend-1.c index 3f339d0..3f339d0 100644 --- a/gcc/testsuite/gcc.target/loongarch/sign-extend.c +++ b/gcc/testsuite/gcc.target/loongarch/sign-extend-1.c diff --git a/gcc/testsuite/gcc.target/loongarch/sign-extend-2.c b/gcc/testsuite/gcc.target/loongarch/sign-extend-2.c new file mode 100644 index 0000000..e57a272 --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/sign-extend-2.c @@ -0,0 +1,60 @@ +/* { dg-do compile } */ +/* { dg-options "-mabi=lp64d -O2 -fdump-rtl-expand" } */ +/* { dg-final { scan-rtl-dump "subreg/s" "expand" } } */ +/* { dg-final { scan-assembler-not "slli.w\t\\\$r\[0-9\]+,\\\$r\[0-9\]+,0" } } */ + +#include <stdint.h> +#define my_min(x, y) ((x) < (y) ? (x) : (y)) + +void +bt_skip_func (const uint32_t len_limit, const uint32_t pos, + const uint8_t *const cur, uint32_t cur_match, + uint32_t *const son, const uint32_t cyclic_pos, + const uint32_t cyclic_size) +{ + uint32_t *ptr0 = son + (cyclic_pos << 1) + 1; + uint32_t *ptr1 = son + (cyclic_pos << 1); + + uint32_t len0 = 0; + uint32_t len1 = 0; + + while (1) + { + const uint32_t delta = pos - cur_match; + uint32_t *pair + = son + + ((cyclic_pos - delta + (delta > cyclic_pos ? cyclic_size : 0)) + << 1); + const uint8_t *pb = cur - delta; + uint32_t len = my_min (len0, len1); + + if (pb[len] == cur[len]) + { + while (++len != len_limit) + if (pb[len] != cur[len]) + break; + + if (len == len_limit) + { + *ptr1 = pair[0]; + *ptr0 = pair[1]; + return; + } + } + + if (pb[len] < cur[len]) + { + *ptr1 = cur_match; + ptr1 = pair + 1; + cur_match = *ptr1; + len1 = len; + } + else + { + *ptr0 = cur_match; + ptr0 = pair; + cur_match = *ptr0; + len0 = len; + } + } +} diff --git a/gcc/testsuite/gcc.target/loongarch/sign-extend-bitwise.c b/gcc/testsuite/gcc.target/loongarch/sign-extend-bitwise.c new file mode 100644 index 0000000..5753ef6 --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/sign-extend-bitwise.c @@ -0,0 +1,21 @@ +/* { dg-do compile } */ +/* { dg-options "-mabi=lp64d -O2" } */ +/* { dg-final { scan-assembler-not "slli.w\t\\\$r\[0-9\]+,\\\$r\[0-9\]+,0" } } */ + +struct pmop +{ + unsigned int op_pmflags; + unsigned int op_pmpermflags; +}; +unsigned int PL_hints; + +struct pmop *pmop; +void +Perl_newPMOP (int type, int flags) +{ + if (PL_hints & 0x00100000) + pmop->op_pmpermflags |= 0x0001; + if (PL_hints & 0x00000004) + pmop->op_pmpermflags |= 0x0800; + pmop->op_pmflags = pmop->op_pmpermflags; +} diff --git a/gcc/testsuite/gcc.target/mips/unaligned-2.c b/gcc/testsuite/gcc.target/mips/unaligned-2.c index 8679afa..bd4c6c7 100644 --- a/gcc/testsuite/gcc.target/mips/unaligned-2.c +++ b/gcc/testsuite/gcc.target/mips/unaligned-2.c @@ -1,4 +1,4 @@ -/* { dg-options "isa_rev>=6 -mgp64" } */ +/* { dg-options "isa_rev>=6 -mgp64 -mno-abicalls" } */ /* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */ /* { dg-final { scan-assembler-not "\tsb\t" } } */ /* { dg-final { scan-assembler-not "\tsh\t" } } */ diff --git a/gcc/testsuite/gcc.target/powerpc/pcrel-sibcall-1.c b/gcc/testsuite/gcc.target/powerpc/pcrel-sibcall-1.c index 9197788..1b6dffd 100644 --- a/gcc/testsuite/gcc.target/powerpc/pcrel-sibcall-1.c +++ b/gcc/testsuite/gcc.target/powerpc/pcrel-sibcall-1.c @@ -8,10 +8,10 @@ generated when the caller preserves the TOC but the callee does not. */ #pragma GCC target ("cpu=power10,pcrel") -int x (void) __attribute__((noinline)); -int y (void) __attribute__((noinline)); -int xx (void) __attribute__((noinline)); - +int x (void) __attribute__((noipa)); +int y (void) __attribute__((noipa)); +int xx (void) __attribute__((noipa)); + int x (void) { return 1; diff --git a/gcc/testsuite/gcc.target/riscv/cset-sext-sfb.c b/gcc/testsuite/gcc.target/riscv/cset-sext-sfb.c new file mode 100644 index 0000000..1a3e710 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/cset-sext-sfb.c @@ -0,0 +1,28 @@ +/* { dg-do compile } */ +/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" } } */ +/* { dg-options "-march=rv32gc -mtune=sifive-7-series -mbranch-cost=1 -fdump-rtl-ce1" { target { rv32 } } } */ +/* { dg-options "-march=rv64gc -mtune=sifive-7-series -mbranch-cost=1 -fdump-rtl-ce1" { target { rv64 } } } */ + +int +foo (long a, long b) +{ + if (!b) + return 0; + else if (a) + return 1; + else + return 0; +} + +/* Expect short forward branch assembly like: + + snez a0,a0 + bne a1,zero,1f # movcc + mv a0,zero +1: + */ + +/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove_arith" 1 "ce1" { xfail { rv32 && { any-opts "-O1" } } } } } */ +/* { dg-final { scan-assembler-times "\\ssnez\\s" 1 } } */ +/* { dg-final { scan-assembler-times "\\sbne\\s\[^\\s\]+\\s# movcc\\s" 1 { xfail { rv32 && { any-opts "-O1" } } } } } */ +/* { dg-final { scan-assembler-not "\\sbeq\\s" { xfail { rv32 && { any-opts "-O1" } } } } } */ diff --git a/gcc/testsuite/gcc.target/riscv/cset-sext-thead.c b/gcc/testsuite/gcc.target/riscv/cset-sext-thead.c new file mode 100644 index 0000000..45b9470 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/cset-sext-thead.c @@ -0,0 +1,26 @@ +/* { dg-do compile } */ +/* { dg-require-effective-target rv64 } */ +/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" } } */ +/* { dg-options "-march=rv64gc_xtheadcondmov -mtune=thead-c906 -mbranch-cost=1 -fdump-rtl-ce1" } */ + +int +foo (long a, long b) +{ + if (!b) + return 0; + else if (a) + return 1; + else + return 0; +} + +/* Expect branchless assembly like: + + snez a0,a0 + th.mveqz a0,zero,a1 + */ + +/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove_arith" 1 "ce1" } } */ +/* { dg-final { scan-assembler-times "\\ssnez\\s" 1 } } */ +/* { dg-final { scan-assembler-times "\\s(?:th\\.mveqz|th\\.mvnez)\\s" 1 } } */ +/* { dg-final { scan-assembler-not "\\s(?:beq|bne)\\s" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/cset-sext-ventana.c b/gcc/testsuite/gcc.target/riscv/cset-sext-ventana.c new file mode 100644 index 0000000..eac1e13 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/cset-sext-ventana.c @@ -0,0 +1,26 @@ +/* { dg-do compile } */ +/* { dg-require-effective-target rv64 } */ +/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" } } */ +/* { dg-options "-march=rv64gc_xventanacondops -mtune=rocket -mbranch-cost=3 -fdump-rtl-ce1" } */ + +int +foo (long a, long b) +{ + if (!b) + return 0; + else if (a) + return 1; + else + return 0; +} + +/* Expect branchless assembly like: + + snez a0,a0 + vt.maskc a0,a0,a1 + */ + +/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove_arith" 1 "ce1" } } */ +/* { dg-final { scan-assembler-times "\\ssnez\\s" 1 } } */ +/* { dg-final { scan-assembler-times "\\svt\\.maskc\\s" 1 } } */ +/* { dg-final { scan-assembler-not "\\s(?:beq|bne)\\s" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/cset-sext-zicond.c b/gcc/testsuite/gcc.target/riscv/cset-sext-zicond.c new file mode 100644 index 0000000..a526b0c --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/cset-sext-zicond.c @@ -0,0 +1,26 @@ +/* { dg-do compile } */ +/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" } } */ +/* { dg-options "-march=rv64gc_zicond -mtune=rocket -mbranch-cost=3 -fdump-rtl-ce1" { target { rv64 } } } */ +/* { dg-options "-march=rv32gc_zicond -mtune=rocket -mbranch-cost=3 -fdump-rtl-ce1" { target { rv32 } } } */ + +int +foo (long a, long b) +{ + if (!b) + return 0; + else if (a) + return 1; + else + return 0; +} + +/* Expect branchless assembly like: + + snez a0,a0 + czero.eqz a0,a0,a1 + */ + +/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove_arith" 1 "ce1" { xfail { rv32 && { any-opts "-O1" "-Os" "-Oz" } } } } } */ +/* { dg-final { scan-assembler-times "\\ssnez\\s" 1 } } */ +/* { dg-final { scan-assembler-times "\\sczero\\.eqz\\s" 1 { xfail { rv32 && { any-opts "-O1" "-Os" "-Oz" } } } } } */ +/* { dg-final { scan-assembler-not "\\s(?:beq|bne)\\s" { xfail { rv32 && { any-opts "-O1" "-Os" "-Oz" } } } } } */ diff --git a/gcc/testsuite/gcc.target/riscv/cset-sext.c b/gcc/testsuite/gcc.target/riscv/cset-sext.c new file mode 100644 index 0000000..a1293cd --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/cset-sext.c @@ -0,0 +1,27 @@ +/* { dg-do compile } */ +/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */ +/* { dg-options "-march=rv32gc -mtune=sifive-5-series -mbranch-cost=6 -mmovcc -fdump-rtl-ce1" { target { rv32 } } } */ +/* { dg-options "-march=rv64gc -mtune=sifive-5-series -mbranch-cost=6 -mmovcc -fdump-rtl-ce1" { target { rv64 } } } */ + +int +foo (long a, long b) +{ + if (!b) + return 0; + else if (a) + return 1; + else + return 0; +} + +/* Expect branchless assembly like: + + snez a1,a1 + neg a1,a1 + snez a0,a0 + and a0,a1,a0 + */ + +/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove_arith" 1 "ce1" { xfail { rv32 && { any-opts "-O1" } } } } } */ +/* { dg-final { scan-assembler-times "\\ssnez\\s" 2 { xfail { rv32 && { any-opts "-O1" } } } } } */ +/* { dg-final { scan-assembler-not "\\s(?:beq|bne)\\s" { xfail { rv32 && { any-opts "-O1" } } } } } */ diff --git a/gcc/testsuite/gcc.target/riscv/pr105314.c b/gcc/testsuite/gcc.target/riscv/pr105314.c index 7a54577..6b6a607 100644 --- a/gcc/testsuite/gcc.target/riscv/pr105314.c +++ b/gcc/testsuite/gcc.target/riscv/pr105314.c @@ -1,5 +1,5 @@ /* PR rtl-optimization/105314 */ -/* { dg-do compile } * +/* { dg-do compile } */ /* { dg-options "-O2" } */ /* { dg-final { scan-assembler-not "\tbeq\t" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/fold-min-poly.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/fold-min-poly.c index de4c472..3f524db 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/fold-min-poly.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/fold-min-poly.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options " -march=rv64gcv_zvl128b -mabi=lp64d -O3 --param riscv-autovec-preference=scalable --param riscv-autovec-lmul=m1 -fno-vect-cost-model" } */ +/* { dg-options " -march=rv64gcv_zvl128b -mabi=lp64d -O3 --param riscv-autovec-preference=scalable --param riscv-autovec-lmul=m1" } */ void foo1 (int* restrict a, int* restrict b, int n) { diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/partial/slp-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/partial/slp-1.c index 948b20b..0a1d1f7 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/partial/slp-1.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/partial/slp-1.c @@ -21,6 +21,6 @@ f (int8_t *restrict a, int8_t *restrict b, int n) /* FIXME: Since we don't have VECT cost model yet, LOAD_LANES/STORE_LANES are chosen instead of SLP when riscv-autovec-lmul=m1. */ -/* { dg-final { scan-tree-dump-times "\.VEC_PERM" 1 "optimized" { xfail { any-opts "--param riscv-autovec-lmul=m1" "--param riscv-autovec-lmul=m8" } } } } */ +/* { dg-final { scan-tree-dump-times "\.VEC_PERM" 1 "optimized" { xfail { any-opts "--param riscv-autovec-lmul=m1" } } } } */ /* { dg-final { scan-assembler {\tvid\.v} { xfail { any-opts "--param riscv-autovec-lmul=m1" } } } } */ /* { dg-final { scan-assembler {\tvand} { xfail { any-opts "--param riscv-autovec-lmul=m1" } } } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/partial/slp-16.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/partial/slp-16.c index 7b23caf..05220c3 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/partial/slp-16.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/partial/slp-16.c @@ -21,6 +21,6 @@ f (uint8_t *restrict a, uint8_t *restrict b, int n) /* FIXME: Since we don't have VECT cost model yet, LOAD_LANES/STORE_LANES are chosen instead of SLP when riscv-autovec-lmul=m1. */ -/* { dg-final { scan-tree-dump-times "\.VEC_PERM" 1 "optimized" { xfail { any-opts "--param riscv-autovec-lmul=m1" "--param riscv-autovec-lmul=m8" } } } } */ +/* { dg-final { scan-tree-dump-times "\.VEC_PERM" 1 "optimized" { xfail { any-opts "--param riscv-autovec-lmul=m1" } } } } */ /* { dg-final { scan-assembler {\tvid\.v} { xfail { any-opts "--param riscv-autovec-lmul=m1"} } } } */ /* { dg-final { scan-assembler-not {\tvmul} } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/partial/slp-3.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/partial/slp-3.c index 3622c59..5e64231 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/partial/slp-3.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/partial/slp-3.c @@ -21,4 +21,4 @@ f (int8_t *restrict a, int8_t *restrict b, int n) /* FIXME: Since we don't have VECT cost model yet, LOAD_LANES/STORE_LANES are chosen instead of SLP when riscv-autovec-lmul=m1. */ -/* { dg-final { scan-tree-dump-times "\.VEC_PERM" 1 "optimized" { xfail { any-opts "--param riscv-autovec-lmul=m1" "--param riscv-autovec-lmul=m8" } } } } */ +/* { dg-final { scan-tree-dump-times "\.VEC_PERM" 1 "optimized" { xfail { any-opts "--param riscv-autovec-lmul=m1" } } } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/partial/slp-5.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/partial/slp-5.c index 5c0a677..c78b370 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/partial/slp-5.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/partial/slp-5.c @@ -21,4 +21,4 @@ f (int8_t *restrict a, int8_t *restrict b, int n) /* FIXME: Since we don't have VECT cost model yet, LOAD_LANES/STORE_LANES are chosen instead of SLP when riscv-autovec-lmul=m1. */ -/* { dg-final { scan-tree-dump-times "\.VEC_PERM" 1 "optimized" { xfail { any-opts "--param riscv-autovec-lmul=m1" "--param riscv-autovec-lmul=m8" } } } } */ +/* { dg-final { scan-tree-dump-times "\.VEC_PERM" 1 "optimized" { xfail { any-opts "--param riscv-autovec-lmul=m1" } } } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/pr113209.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/pr113209.c index 081ee36..70aae15 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/pr113209.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/pr113209.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gcv_zvl256b -mabi=lp64d -O3" } */ +/* { dg-options "-march=rv64gcv_zvl256b -mabi=lp64d -O3 -fno-vect-cost-model" } */ int b, c, d, f, i, a; int e[1] = {0}; diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/pr113393-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/pr113393-1.c new file mode 100644 index 0000000..57c5cff --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/pr113393-1.c @@ -0,0 +1,24 @@ +/* { dg-do run } */ +/* { dg-options "-O3 --param=riscv-autovec-preference=fixed-vlmax" } */ +/* { dg-require-effective-target riscv_v } */ + +#define SIZE 128 +unsigned short _Alignas (16) in[SIZE]; + +__attribute__ ((noinline)) int +test (unsigned short sum, unsigned short *in, int x) +{ + for (int j = 0; j < SIZE; j += 8) + sum += in[j] * x; + return sum; +} + +int +main () +{ + for (int i = 0; i < SIZE; i++) + in[i] = i; + if (test (0, in, 1) != 960) + __builtin_abort (); + return 0; +} diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/pr113393-2.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/pr113393-2.c new file mode 100644 index 0000000..c36a16d --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/pr113393-2.c @@ -0,0 +1,29 @@ +/* { dg-do run } */ +/* { dg-options "-O3 --param=riscv-autovec-preference=fixed-vlmax --param=riscv-autovec-lmul=m2" } */ +/* { dg-require-effective-target riscv_v } */ + +__attribute__((noinline, noclone)) static int +bar (const short *a, int len) +{ + int x; + int x1 = 0; + + for (x = 0; x < len; x++) + x1 += x * a[x]; + return x1; +} + +__attribute__((noinline, noclone)) void +foo (void) +{ + short stuff[9] = {1, 1, 1, 1, 1, 1, 1, 1, 1 }; + if (bar (stuff, 9) != 36) + __builtin_abort (); +} + +int +main () +{ + foo (); + return 0; +} diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/pr113393-3.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/pr113393-3.c new file mode 100644 index 0000000..063cf85 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/pr113393-3.c @@ -0,0 +1,5 @@ +/* { dg-do run } */ +/* { dg-options "-O3 --param=riscv-autovec-preference=fixed-vlmax" } */ +/* { dg-require-effective-target riscv_v } */ + +#include "pr113393-2.c" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/avg-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/avg-1.c index d53bd3a..2327a3d 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/avg-1.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/avg-1.c @@ -26,9 +26,9 @@ DEF_AVG_FLOOR (uint8_t, uint16_t, 1024) DEF_AVG_FLOOR (uint8_t, uint16_t, 2048) /* { dg-final { scan-assembler-times {vwadd\.vv} 10 } } */ -/* { dg-final { scan-assembler-times {vwaddu\.vv} 10 } } */ +/* { dg-final { scan-assembler-times {csrwi\s*vxrm,\s*2} 10 } } */ /* { dg-final { scan-assembler-times {vnsra\.wi} 10 } } */ -/* { dg-final { scan-assembler-times {vnsrl\.wi} 10 } } */ +/* { dg-final { scan-assembler-times {vaaddu\.vv} 10 } } */ /* { dg-final { scan-assembler-not {csrr} } } */ /* { dg-final { scan-tree-dump-not "1,1" "optimized" } } */ /* { dg-final { scan-tree-dump-not "2,2" "optimized" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/avg-2.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/avg-2.c index 68d1df7..8030810 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/avg-2.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/avg-2.c @@ -24,9 +24,9 @@ DEF_AVG_FLOOR (uint16_t, uint32_t, 512) DEF_AVG_FLOOR (uint16_t, uint32_t, 1024) /* { dg-final { scan-assembler-times {vwadd\.vv} 9 } } */ -/* { dg-final { scan-assembler-times {vwaddu\.vv} 9 } } */ +/* { dg-final { scan-assembler-times {csrwi\s*vxrm,\s*2} 9 } } */ /* { dg-final { scan-assembler-times {vnsra\.wi} 9 } } */ -/* { dg-final { scan-assembler-times {vnsrl\.wi} 9 } } */ +/* { dg-final { scan-assembler-times {vaaddu\.vv} 9 } } */ /* { dg-final { scan-assembler-not {csrr} } } */ /* { dg-final { scan-tree-dump-not "1,1" "optimized" } } */ /* { dg-final { scan-tree-dump-not "2,2" "optimized" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/avg-3.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/avg-3.c index 07ffab6..dce0ffa 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/avg-3.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/avg-3.c @@ -22,9 +22,9 @@ DEF_AVG_FLOOR (uint32_t, uint64_t, 256) DEF_AVG_FLOOR (uint32_t, uint64_t, 512) /* { dg-final { scan-assembler-times {vwadd\.vv} 8 } } */ -/* { dg-final { scan-assembler-times {vwaddu\.vv} 8 } } */ +/* { dg-final { scan-assembler-times {csrwi\s*vxrm,\s*2} 8 } } */ /* { dg-final { scan-assembler-times {vnsra\.wi} 8 } } */ -/* { dg-final { scan-assembler-times {vnsrl\.wi} 8 } } */ +/* { dg-final { scan-assembler-times {vaaddu\.vv} 8 } } */ /* { dg-final { scan-assembler-not {csrr} } } */ /* { dg-final { scan-tree-dump-not "1,1" "optimized" } } */ /* { dg-final { scan-tree-dump-not "2,2" "optimized" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/avg-4.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/avg-4.c index 83e219c..65912fb 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/avg-4.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/avg-4.c @@ -26,10 +26,10 @@ DEF_AVG_CEIL (uint8_t, uint16_t, 1024) DEF_AVG_CEIL (uint8_t, uint16_t, 2048) /* { dg-final { scan-assembler-times {vwadd\.vv} 10 } } */ -/* { dg-final { scan-assembler-times {vwaddu\.vv} 10 } } */ +/* { dg-final { scan-assembler-times {csrwi\s*vxrm,\s*0} 10 } } */ /* { dg-final { scan-assembler-times {vnsra\.wi} 10 } } */ -/* { dg-final { scan-assembler-times {vnsrl\.wi} 10 } } */ -/* { dg-final { scan-assembler-times {vadd\.vi} 20 } } */ +/* { dg-final { scan-assembler-times {vaaddu\.vv} 10 } } */ +/* { dg-final { scan-assembler-times {vadd\.vi} 10 } } */ /* { dg-final { scan-assembler-not {csrr} } } */ /* { dg-final { scan-tree-dump-not "1,1" "optimized" } } */ /* { dg-final { scan-tree-dump-not "2,2" "optimized" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/avg-5.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/avg-5.c index 325faea..a197b24 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/avg-5.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/avg-5.c @@ -24,10 +24,10 @@ DEF_AVG_CEIL (uint16_t, uint32_t, 512) DEF_AVG_CEIL (uint16_t, uint32_t, 1024) /* { dg-final { scan-assembler-times {vwadd\.vv} 9 } } */ -/* { dg-final { scan-assembler-times {vwaddu\.vv} 9 } } */ +/* { dg-final { scan-assembler-times {csrwi\s*vxrm,\s*0} 9 } } */ /* { dg-final { scan-assembler-times {vnsra\.wi} 9 } } */ -/* { dg-final { scan-assembler-times {vnsrl\.wi} 9 } } */ -/* { dg-final { scan-assembler-times {vadd\.vi} 18 } } */ +/* { dg-final { scan-assembler-times {vaaddu\.vv} 9 } } */ +/* { dg-final { scan-assembler-times {vadd\.vi} 9 } } */ /* { dg-final { scan-assembler-not {csrr} } } */ /* { dg-final { scan-tree-dump-not "1,1" "optimized" } } */ /* { dg-final { scan-tree-dump-not "2,2" "optimized" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/avg-6.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/avg-6.c index d836428..a53de71 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/avg-6.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/avg-6.c @@ -22,10 +22,10 @@ DEF_AVG_CEIL (uint16_t, uint32_t, 256) DEF_AVG_CEIL (uint16_t, uint32_t, 512) /* { dg-final { scan-assembler-times {vwadd\.vv} 8 } } */ -/* { dg-final { scan-assembler-times {vwaddu\.vv} 8 } } */ +/* { dg-final { scan-assembler-times {csrwi\s*vxrm,\s*0} 8 } } */ /* { dg-final { scan-assembler-times {vnsra\.wi} 8 } } */ -/* { dg-final { scan-assembler-times {vnsrl\.wi} 8 } } */ -/* { dg-final { scan-assembler-times {vadd\.vi} 16 } } */ +/* { dg-final { scan-assembler-times {vaaddu\.vv} 8 } } */ +/* { dg-final { scan-assembler-times {vadd\.vi} 8 } } */ /* { dg-final { scan-assembler-not {csrr} } } */ /* { dg-final { scan-tree-dump-not "1,1" "optimized" } } */ /* { dg-final { scan-tree-dump-not "2,2" "optimized" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-1.c index 2db25a2..b6d8e6a 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-1.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-1.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gcv_zvfh_zvl4096b -mabi=lp64d -O3 --param=riscv-autovec-lmul=m8" } */ +/* { dg-options "-march=rv64gcv_zvfh_zvl4096b -mabi=lp64d -O3 --param=riscv-autovec-lmul=m8 -fdump-tree-optimized-details" } */ #include "def.h" @@ -29,3 +29,15 @@ DEF_REDUC_PLUS (uint8_t, 4096) /* { dg-final { scan-assembler-times {vredsum\.vs} 22 } } */ /* { dg-final { scan-assembler-not {csrr} } } */ +/* { dg-final { scan-tree-dump-not "1,1" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "2,2" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "4,4" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "16,16" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "32,32" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "64,64" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "128,128" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "256,256" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "512,512" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "1024,1024" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "2048,2048" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "4096,4096" "optimized" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-10.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-10.c index cdbbe11..22aace4 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-10.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-10.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gcv_zvfh_zvl4096b -mabi=lp64d -O3 --param=riscv-autovec-lmul=m8" } */ +/* { dg-options "-march=rv64gcv_zvfh_zvl4096b -mabi=lp64d -O3 --param=riscv-autovec-lmul=m8 -fdump-tree-optimized-details" } */ #include "def.h" @@ -48,3 +48,15 @@ DEF_REDUC_MAXMIN (uint32_t, min, <, 1024) /* { dg-final { scan-assembler-times {vredmin\.vs} 9 } } */ /* { dg-final { scan-assembler-times {vredminu\.vs} 9 } } */ /* { dg-final { scan-assembler-not {csrr} } } */ +/* { dg-final { scan-tree-dump-not "1,1" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "2,2" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "4,4" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "16,16" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "32,32" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "64,64" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "128,128" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "256,256" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "512,512" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "1024,1024" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "2048,2048" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "4096,4096" "optimized" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-11.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-11.c index d204031..0e8518a 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-11.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-11.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gcv_zvfh_zvl4096b -mabi=lp64d -O3 --param=riscv-autovec-lmul=m8" } */ +/* { dg-options "-march=rv64gcv_zvfh_zvl4096b -mabi=lp64d -O3 --param=riscv-autovec-lmul=m8 -fdump-tree-optimized-details" } */ #include "def.h" @@ -44,3 +44,15 @@ DEF_REDUC_MAXMIN (uint64_t, min, <, 512) /* { dg-final { scan-assembler-times {vredmin\.vs} 8 } } */ /* { dg-final { scan-assembler-times {vredminu\.vs} 8 } } */ /* { dg-final { scan-assembler-not {csrr} } } */ +/* { dg-final { scan-tree-dump-not "1,1" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "2,2" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "4,4" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "16,16" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "32,32" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "64,64" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "128,128" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "256,256" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "512,512" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "1024,1024" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "2048,2048" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "4096,4096" "optimized" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-12.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-12.c index 97660d2..aabbe71 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-12.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-12.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gcv_zvfh_zvl4096b -mabi=lp64d -O3 --param=riscv-autovec-lmul=m8 -ffast-math" } */ +/* { dg-options "-march=rv64gcv_zvfh_zvl4096b -mabi=lp64d -O3 --param=riscv-autovec-lmul=m8 -ffast-math -fdump-tree-optimized-details" } */ #include "def.h" @@ -28,3 +28,15 @@ DEF_REDUC_MAXMIN (_Float16, min, <, 2048) /* { dg-final { scan-assembler-times {vfredmax\.vs} 10 } } */ /* { dg-final { scan-assembler-times {vfredmin\.vs} 10 } } */ /* { dg-final { scan-assembler-not {csrr} } } */ +/* { dg-final { scan-tree-dump-not "1,1" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "2,2" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "4,4" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "16,16" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "32,32" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "64,64" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "128,128" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "256,256" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "512,512" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "1024,1024" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "2048,2048" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "4096,4096" "optimized" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-13.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-13.c index e4bc95c..c3f5f2c 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-13.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-13.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gcv_zvfh_zvl4096b -mabi=lp64d -O3 --param=riscv-autovec-lmul=m8 -ffast-math" } */ +/* { dg-options "-march=rv64gcv_zvfh_zvl4096b -mabi=lp64d -O3 --param=riscv-autovec-lmul=m8 -ffast-math -fdump-tree-optimized-details" } */ #include "def.h" @@ -26,3 +26,15 @@ DEF_REDUC_MAXMIN (float, min, <, 1024) /* { dg-final { scan-assembler-times {vfredmax\.vs} 9 } } */ /* { dg-final { scan-assembler-times {vfredmin\.vs} 9 } } */ /* { dg-final { scan-assembler-not {csrr} } } */ +/* { dg-final { scan-tree-dump-not "1,1" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "2,2" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "4,4" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "16,16" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "32,32" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "64,64" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "128,128" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "256,256" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "512,512" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "1024,1024" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "2048,2048" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "4096,4096" "optimized" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-14.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-14.c index c90e926..61eea79 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-14.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-14.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gcv_zvfh_zvl4096b -mabi=lp64d -O3 --param=riscv-autovec-lmul=m8 -ffast-math" } */ +/* { dg-options "-march=rv64gcv_zvfh_zvl4096b -mabi=lp64d -O3 --param=riscv-autovec-lmul=m8 -ffast-math -fdump-tree-optimized-details" } */ #include "def.h" @@ -24,3 +24,15 @@ DEF_REDUC_MAXMIN (double, min, <, 512) /* { dg-final { scan-assembler-times {vfredmax\.vs} 8 } } */ /* { dg-final { scan-assembler-times {vfredmin\.vs} 8 } } */ /* { dg-final { scan-assembler-not {csrr} } } */ +/* { dg-final { scan-tree-dump-not "1,1" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "2,2" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "4,4" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "16,16" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "32,32" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "64,64" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "128,128" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "256,256" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "512,512" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "1024,1024" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "2048,2048" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "4096,4096" "optimized" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-15.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-15.c index 65863f7..a368e55 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-15.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-15.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gcv_zvfh_zvl4096b -mabi=lp64d -O3 --param=riscv-autovec-lmul=m8" } */ +/* { dg-options "-march=rv64gcv_zvfh_zvl4096b -mabi=lp64d -O3 --param=riscv-autovec-lmul=m8 -fdump-tree-optimized-details" } */ #include "def.h" @@ -79,3 +79,15 @@ DEF_REDUC_BITWISE (uint8_t, xor, ^=, 4096) /* { dg-final { scan-assembler-times {vredor\.vs} 22 } } */ /* { dg-final { scan-assembler-times {vredxor\.vs} 22 } } */ /* { dg-final { scan-assembler-not {csrr} } } */ +/* { dg-final { scan-tree-dump-not "1,1" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "2,2" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "4,4" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "16,16" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "32,32" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "64,64" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "128,128" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "256,256" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "512,512" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "1024,1024" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "2048,2048" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "4096,4096" "optimized" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-16.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-16.c index c6c5714..c528d69 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-16.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-16.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gcv_zvfh_zvl4096b -mabi=lp64d -O3 --param=riscv-autovec-lmul=m8" } */ +/* { dg-options "-march=rv64gcv_zvfh_zvl4096b -mabi=lp64d -O3 --param=riscv-autovec-lmul=m8 -fdump-tree-optimized-details" } */ #include "def.h" @@ -73,3 +73,15 @@ DEF_REDUC_BITWISE (uint16_t, xor, ^=, 2048) /* { dg-final { scan-assembler-times {vredor\.vs} 20 } } */ /* { dg-final { scan-assembler-times {vredxor\.vs} 20 } } */ /* { dg-final { scan-assembler-not {csrr} } } */ +/* { dg-final { scan-tree-dump-not "1,1" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "2,2" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "4,4" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "16,16" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "32,32" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "64,64" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "128,128" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "256,256" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "512,512" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "1024,1024" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "2048,2048" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "4096,4096" "optimized" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-17.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-17.c index 7598307..d0f00e6 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-17.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-17.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gcv_zvfh_zvl4096b -mabi=lp64d -O3 --param=riscv-autovec-lmul=m8" } */ +/* { dg-options "-march=rv64gcv_zvfh_zvl4096b -mabi=lp64d -O3 --param=riscv-autovec-lmul=m8 -fdump-tree-optimized-details" } */ #include "def.h" @@ -67,3 +67,15 @@ DEF_REDUC_BITWISE (uint32_t, xor, ^=, 1024) /* { dg-final { scan-assembler-times {vredor\.vs} 18 } } */ /* { dg-final { scan-assembler-times {vredxor\.vs} 18 } } */ /* { dg-final { scan-assembler-not {csrr} } } */ +/* { dg-final { scan-tree-dump-not "1,1" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "2,2" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "4,4" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "16,16" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "32,32" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "64,64" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "128,128" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "256,256" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "512,512" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "1024,1024" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "2048,2048" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "4096,4096" "optimized" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-18.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-18.c index 30dfad6..ba8fb52 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-18.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-18.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gcv_zvfh_zvl4096b -mabi=lp64d -O3 --param=riscv-autovec-lmul=m8" } */ +/* { dg-options "-march=rv64gcv_zvfh_zvl4096b -mabi=lp64d -O3 --param=riscv-autovec-lmul=m8 -fdump-tree-optimized-details" } */ #include "def.h" @@ -61,3 +61,15 @@ DEF_REDUC_BITWISE (uint64_t, xor, ^=, 512) /* { dg-final { scan-assembler-times {vredor\.vs} 16 } } */ /* { dg-final { scan-assembler-times {vredxor\.vs} 16 } } */ /* { dg-final { scan-assembler-not {csrr} } } */ +/* { dg-final { scan-tree-dump-not "1,1" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "2,2" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "4,4" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "16,16" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "32,32" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "64,64" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "128,128" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "256,256" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "512,512" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "1024,1024" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "2048,2048" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "4096,4096" "optimized" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-19.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-19.c index a2de4d1..5130fe5 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-19.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-19.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gcv_zvfh_zvl4096b -mabi=lp64d -O3 --param=riscv-autovec-lmul=m8" } */ +/* { dg-options "-march=rv64gcv_zvfh_zvl4096b -mabi=lp64d -O3 --param=riscv-autovec-lmul=m8 -fdump-tree-optimized-details" } */ #include "def.h" @@ -14,5 +14,17 @@ DEF_REDUC_PLUS (_Float16, 512) DEF_REDUC_PLUS (_Float16, 1024) DEF_REDUC_PLUS (_Float16, 2048) -/* { dg-final { scan-assembler-times {vfredosum\.vs} 10 } } */ +/* { dg-final { scan-assembler-times {vfredosum\.vs} 9 } } */ /* { dg-final { scan-assembler-not {csrr} } } */ +/* { dg-final { scan-tree-dump-not "1,1" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "2,2" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "4,4" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "16,16" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "32,32" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "64,64" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "128,128" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "256,256" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "512,512" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "1024,1024" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "2048,2048" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "4096,4096" "optimized" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-2.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-2.c index 9ffdec9..158aaf3 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-2.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-2.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gcv_zvfh_zvl4096b -mabi=lp64d -O3 --param=riscv-autovec-lmul=m8" } */ +/* { dg-options "-march=rv64gcv_zvfh_zvl4096b -mabi=lp64d -O3 --param=riscv-autovec-lmul=m8 -fdump-tree-optimized-details" } */ #include "def.h" @@ -27,3 +27,15 @@ DEF_REDUC_PLUS (uint16_t, 2048) /* { dg-final { scan-assembler-times {vredsum\.vs} 20 } } */ /* { dg-final { scan-assembler-not {csrr} } } */ +/* { dg-final { scan-tree-dump-not "1,1" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "2,2" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "4,4" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "16,16" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "32,32" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "64,64" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "128,128" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "256,256" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "512,512" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "1024,1024" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "2048,2048" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "4096,4096" "optimized" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-20.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-20.c index 8e1164a..819104a 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-20.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-20.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gcv_zvfh_zvl4096b -mabi=lp64d -O3 --param=riscv-autovec-lmul=m8" } */ +/* { dg-options "-march=rv64gcv_zvfh_zvl4096b -mabi=lp64d -O3 --param=riscv-autovec-lmul=m8 -fdump-tree-optimized-details" } */ #include "def.h" @@ -13,5 +13,17 @@ DEF_REDUC_PLUS (float, 256) DEF_REDUC_PLUS (float, 512) DEF_REDUC_PLUS (float, 1024) -/* { dg-final { scan-assembler-times {vfredosum\.vs} 9 } } */ +/* { dg-final { scan-assembler-times {vfredosum\.vs} 8 } } */ /* { dg-final { scan-assembler-not {csrr} } } */ +/* { dg-final { scan-tree-dump-not "1,1" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "2,2" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "4,4" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "16,16" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "32,32" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "64,64" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "128,128" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "256,256" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "512,512" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "1024,1024" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "2048,2048" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "4096,4096" "optimized" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-21.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-21.c index 727cf85..2b61e0a 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-21.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-21.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gcv_zvfh_zvl4096b -mabi=lp64d -O3 --param=riscv-autovec-lmul=m8" } */ +/* { dg-options "-march=rv64gcv_zvfh_zvl4096b -mabi=lp64d -O3 --param=riscv-autovec-lmul=m8 -fdump-tree-optimized-details" } */ #include "def.h" @@ -12,5 +12,17 @@ DEF_REDUC_PLUS (float, 128) DEF_REDUC_PLUS (float, 256) DEF_REDUC_PLUS (float, 512) -/* { dg-final { scan-assembler-times {vfredosum\.vs} 8 } } */ +/* { dg-final { scan-assembler-times {vfredosum\.vs} 7 } } */ /* { dg-final { scan-assembler-not {csrr} } } */ +/* { dg-final { scan-tree-dump-not "1,1" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "2,2" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "4,4" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "16,16" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "32,32" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "64,64" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "128,128" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "256,256" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "512,512" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "1024,1024" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "2048,2048" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "4096,4096" "optimized" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-3.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-3.c index 63f9697..d24f2ef 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-3.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-3.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gcv_zvfh_zvl4096b -mabi=lp64d -O3 --param=riscv-autovec-lmul=m8" } */ +/* { dg-options "-march=rv64gcv_zvfh_zvl4096b -mabi=lp64d -O3 --param=riscv-autovec-lmul=m8 -fdump-tree-optimized-details" } */ #include "def.h" @@ -25,3 +25,15 @@ DEF_REDUC_PLUS (uint32_t, 1024) /* { dg-final { scan-assembler-times {vredsum\.vs} 18 } } */ /* { dg-final { scan-assembler-not {csrr} } } */ +/* { dg-final { scan-tree-dump-not "1,1" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "2,2" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "4,4" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "16,16" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "32,32" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "64,64" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "128,128" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "256,256" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "512,512" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "1024,1024" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "2048,2048" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "4096,4096" "optimized" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-4.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-4.c index 8cd2728..1143bde 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-4.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-4.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gcv_zvfh_zvl4096b -mabi=lp64d -O3 --param=riscv-autovec-lmul=m8" } */ +/* { dg-options "-march=rv64gcv_zvfh_zvl4096b -mabi=lp64d -O3 --param=riscv-autovec-lmul=m8 -fdump-tree-optimized-details" } */ #include "def.h" @@ -23,3 +23,15 @@ DEF_REDUC_PLUS (uint64_t, 512) /* { dg-final { scan-assembler-times {vredsum\.vs} 16 } } */ /* { dg-final { scan-assembler-not {csrr} } } */ +/* { dg-final { scan-tree-dump-not "1,1" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "2,2" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "4,4" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "16,16" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "32,32" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "64,64" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "128,128" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "256,256" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "512,512" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "1024,1024" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "2048,2048" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "4096,4096" "optimized" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-5.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-5.c index 09b69fc..0370b4d 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-5.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-5.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gcv_zvfh_zvl4096b -mabi=lp64d -O3 --param=riscv-autovec-lmul=m8 -ffast-math" } */ +/* { dg-options "-march=rv64gcv_zvfh_zvl4096b -mabi=lp64d -O3 --param=riscv-autovec-lmul=m8 -ffast-math -fdump-tree-optimized-details" } */ #include "def.h" @@ -16,3 +16,15 @@ DEF_REDUC_PLUS (_Float16, 2048) /* { dg-final { scan-assembler-times {vfredusum\.vs} 10 } } */ /* { dg-final { scan-assembler-not {csrr} } } */ +/* { dg-final { scan-tree-dump-not "1,1" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "2,2" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "4,4" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "16,16" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "32,32" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "64,64" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "128,128" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "256,256" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "512,512" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "1024,1024" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "2048,2048" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "4096,4096" "optimized" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-6.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-6.c index 56b13dc..954e39d 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-6.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-6.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gcv_zvfh_zvl4096b -mabi=lp64d -O3 --param=riscv-autovec-lmul=m8 -ffast-math" } */ +/* { dg-options "-march=rv64gcv_zvfh_zvl4096b -mabi=lp64d -O3 --param=riscv-autovec-lmul=m8 -ffast-math -fdump-tree-optimized-details" } */ #include "def.h" @@ -15,3 +15,15 @@ DEF_REDUC_PLUS (float, 1024) /* { dg-final { scan-assembler-times {vfredusum\.vs} 9 } } */ /* { dg-final { scan-assembler-not {csrr} } } */ +/* { dg-final { scan-tree-dump-not "1,1" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "2,2" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "4,4" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "16,16" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "32,32" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "64,64" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "128,128" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "256,256" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "512,512" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "1024,1024" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "2048,2048" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "4096,4096" "optimized" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-7.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-7.c index eb5de35..6762db8 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-7.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-7.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gcv_zvfh_zvl4096b -mabi=lp64d -O3 --param=riscv-autovec-lmul=m8 -ffast-math" } */ +/* { dg-options "-march=rv64gcv_zvfh_zvl4096b -mabi=lp64d -O3 --param=riscv-autovec-lmul=m8 -ffast-math -fdump-tree-optimized-details" } */ #include "def.h" @@ -14,3 +14,15 @@ DEF_REDUC_PLUS (double, 512) /* { dg-final { scan-assembler-times {vfredusum\.vs} 8 } } */ /* { dg-final { scan-assembler-not {csrr} } } */ +/* { dg-final { scan-tree-dump-not "1,1" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "2,2" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "4,4" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "16,16" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "32,32" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "64,64" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "128,128" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "256,256" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "512,512" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "1024,1024" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "2048,2048" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "4096,4096" "optimized" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-8.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-8.c index cf4f9cc..905c9d0 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-8.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-8.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gcv_zvfh_zvl4096b -mabi=lp64d -O3 --param=riscv-autovec-lmul=m8" } */ +/* { dg-options "-march=rv64gcv_zvfh_zvl4096b -mabi=lp64d -O3 --param=riscv-autovec-lmul=m8 -fdump-tree-optimized-details" } */ #include "def.h" @@ -56,3 +56,15 @@ DEF_REDUC_MAXMIN (uint8_t, min, <, 4096) /* { dg-final { scan-assembler-times {vredmin\.vs} 11 } } */ /* { dg-final { scan-assembler-times {vredminu\.vs} 11 } } */ /* { dg-final { scan-assembler-not {csrr} } } */ +/* { dg-final { scan-tree-dump-not "1,1" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "2,2" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "4,4" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "16,16" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "32,32" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "64,64" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "128,128" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "256,256" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "512,512" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "1024,1024" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "2048,2048" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "4096,4096" "optimized" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-9.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-9.c index 6416458..be7c323 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-9.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-9.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gcv_zvfh_zvl4096b -mabi=lp64d -O3 --param=riscv-autovec-lmul=m8" } */ +/* { dg-options "-march=rv64gcv_zvfh_zvl4096b -mabi=lp64d -O3 --param=riscv-autovec-lmul=m8 -fdump-tree-optimized-details" } */ #include "def.h" @@ -52,3 +52,15 @@ DEF_REDUC_MAXMIN (uint16_t, min, <, 2048) /* { dg-final { scan-assembler-times {vredmin\.vs} 10 } } */ /* { dg-final { scan-assembler-times {vredminu\.vs} 10 } } */ /* { dg-final { scan-assembler-not {csrr} } } */ +/* { dg-final { scan-tree-dump-not "1,1" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "2,2" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "4,4" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "16,16" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "32,32" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "64,64" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "128,128" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "256,256" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "512,512" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "1024,1024" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "2048,2048" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "4096,4096" "optimized" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/vec-avg-rv32gcv.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/vec-avg-rv32gcv.c index e275433..6874a3d 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/vec-avg-rv32gcv.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/vec-avg-rv32gcv.c @@ -4,7 +4,8 @@ #include "vec-avg-template.h" /* { dg-final { scan-assembler-times {\tvwadd\.vv} 6 } } */ -/* { dg-final { scan-assembler-times {\tvwaddu\.vv} 6 } } */ -/* { dg-final { scan-assembler-times {\tvadd\.vi} 6 } } */ -/* { dg-final { scan-assembler-times {\tvnsrl.wi} 6 } } */ +/* { dg-final { scan-assembler-times {csrwi\s*vxrm,\s*0} 3 } } */ +/* { dg-final { scan-assembler-times {csrwi\s*vxrm,\s*2} 3 } } */ +/* { dg-final { scan-assembler-times {\tvadd\.vi} 3 } } */ /* { dg-final { scan-assembler-times {\tvnsra.wi} 6 } } */ +/* { dg-final { scan-assembler-times {vaaddu\.vv} 6 } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/vec-avg-rv64gcv.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/vec-avg-rv64gcv.c index 1f0ef29..06f35e1 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/vec-avg-rv64gcv.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/vec-avg-rv64gcv.c @@ -4,7 +4,8 @@ #include "vec-avg-template.h" /* { dg-final { scan-assembler-times {\tvwadd\.vv} 6 } } */ -/* { dg-final { scan-assembler-times {\tvwaddu\.vv} 6 } } */ -/* { dg-final { scan-assembler-times {\tvadd\.vi} 6 } } */ -/* { dg-final { scan-assembler-times {\tvnsrl\.wi} 6 } } */ +/* { dg-final { scan-assembler-times {csrwi\s*vxrm,\s*0} 3 } } */ +/* { dg-final { scan-assembler-times {csrwi\s*vxrm,\s*2} 3 } } */ +/* { dg-final { scan-assembler-times {\tvadd\.vi} 3 } } */ /* { dg-final { scan-assembler-times {\tvnsra\.wi} 6 } } */ +/* { dg-final { scan-assembler-times {vaaddu\.vv} 6 } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/abi-call-args-1-run.c b/gcc/testsuite/gcc.target/riscv/rvv/base/abi-call-args-1-run.c index 6355ecb..85f0044 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/base/abi-call-args-1-run.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/abi-call-args-1-run.c @@ -1,5 +1,5 @@ /* { dg-do run { target { riscv_v } } } */ -/* { dg-options "-O1 --param=riscv-vector-abi -Wno-psabi" } */ +/* { dg-options "-O1 --param=riscv-vector-abi" } */ /* { dg-additional-sources abi-call-args-1.c } */ #include <stdbool.h> diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/abi-call-args-1.c b/gcc/testsuite/gcc.target/riscv/rvv/base/abi-call-args-1.c index 067e613..c4858a3 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/base/abi-call-args-1.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/abi-call-args-1.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gcv_zvfh -mabi=lp64 -O1 --param=riscv-vector-abi -Wno-psabi" } */ +/* { dg-options "-march=rv64gcv_zvfh -mabi=lp64 -O1 --param=riscv-vector-abi" } */ /* { dg-final { check-function-bodies "**" "" } } */ #include "riscv_vector.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/abi-call-args-2-run.c b/gcc/testsuite/gcc.target/riscv/rvv/base/abi-call-args-2-run.c index fe036ef..06d7703 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/base/abi-call-args-2-run.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/abi-call-args-2-run.c @@ -1,5 +1,5 @@ /* { dg-do run { target { riscv_v } } } */ -/* { dg-options "-O1 --param=riscv-vector-abi -Wno-psabi" } */ +/* { dg-options "-O1 --param=riscv-vector-abi" } */ /* { dg-additional-sources abi-call-args-2.c } */ #include <stdlib.h> diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/abi-call-args-2.c b/gcc/testsuite/gcc.target/riscv/rvv/base/abi-call-args-2.c index 3aed245..269fbeb 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/base/abi-call-args-2.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/abi-call-args-2.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gcv_zvfh -mabi=lp64 -O1 --param=riscv-vector-abi -Wno-psabi" } */ +/* { dg-options "-march=rv64gcv_zvfh -mabi=lp64 -O1 --param=riscv-vector-abi" } */ #include <stdarg.h> #include "riscv_vector.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/abi-call-args-3-run.c b/gcc/testsuite/gcc.target/riscv/rvv/base/abi-call-args-3-run.c index 8c5a094..9056d75 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/base/abi-call-args-3-run.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/abi-call-args-3-run.c @@ -1,5 +1,5 @@ /* { dg-do run { target { riscv_v } } } */ -/* { dg-options "-O1 --param=riscv-vector-abi -Wno-psabi" } */ +/* { dg-options "-O1 --param=riscv-vector-abi" } */ /* { dg-additional-sources abi-call-args-3.c } */ #include <stdbool.h> diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/abi-call-args-3.c b/gcc/testsuite/gcc.target/riscv/rvv/base/abi-call-args-3.c index 17d8dac..8c774716 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/base/abi-call-args-3.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/abi-call-args-3.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gcv_zvfh -mabi=lp64 -O1 --param=riscv-vector-abi -Wno-psabi" } */ +/* { dg-options "-march=rv64gcv_zvfh -mabi=lp64 -O1 --param=riscv-vector-abi" } */ /* { dg-final { check-function-bodies "**" "" } } */ #include "riscv_vector.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/abi-call-args-4-run.c b/gcc/testsuite/gcc.target/riscv/rvv/base/abi-call-args-4-run.c index aa28bb7..21618b5 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/base/abi-call-args-4-run.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/abi-call-args-4-run.c @@ -1,5 +1,5 @@ /* { dg-do run { target { riscv_v } } } */ -/* { dg-options "-O1 --param=riscv-vector-abi -Wno-psabi" } */ +/* { dg-options "-O1 --param=riscv-vector-abi" } */ /* { dg-additional-sources abi-call-args-4.c } */ #include <stdbool.h> diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/abi-call-args-4.c b/gcc/testsuite/gcc.target/riscv/rvv/base/abi-call-args-4.c index 9693b0c..2872ffc 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/base/abi-call-args-4.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/abi-call-args-4.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gcv_zvfh -mabi=lp64 -O1 --param=riscv-vector-abi -Wno-psabi" } */ +/* { dg-options "-march=rv64gcv_zvfh -mabi=lp64 -O1 --param=riscv-vector-abi" } */ /* { dg-final { check-function-bodies "**" "" } } */ #include "riscv_vector.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/abi-call-error-1.c b/gcc/testsuite/gcc.target/riscv/rvv/base/abi-call-error-1.c index 8070ca3..664b514 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/base/abi-call-error-1.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/abi-call-error-1.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gcv -mabi=lp64d --param=riscv-vector-abi -Wno-psabi -Wno-implicit-function-declaration" } */ +/* { dg-options "-march=rv64gcv -mabi=lp64d --param=riscv-vector-abi -Wno-implicit-function-declaration" } */ #include "riscv_vector.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/abi-call-return-run.c b/gcc/testsuite/gcc.target/riscv/rvv/base/abi-call-return-run.c index 054b6fa..b5b3c5d 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/base/abi-call-return-run.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/abi-call-return-run.c @@ -1,5 +1,5 @@ /* { dg-do run { target { riscv_v } } } */ -/* { dg-options "-O1 --param=riscv-vector-abi -Wno-psabi" } */ +/* { dg-options "-O1 --param=riscv-vector-abi" } */ /* { dg-additional-sources abi-call-return.c } */ #include <stdbool.h> diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/abi-call-return.c b/gcc/testsuite/gcc.target/riscv/rvv/base/abi-call-return.c index a6287e6..ac19cc6 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/base/abi-call-return.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/abi-call-return.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gcv -mabi=lp64d -O1 --param=riscv-vector-abi -Wno-psabi" } */ +/* { dg-options "-march=rv64gcv -mabi=lp64d -O1 --param=riscv-vector-abi" } */ /* { dg-final { check-function-bodies "**" "" } } */ #include "riscv_vector.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/abi-call-variant_cc.c b/gcc/testsuite/gcc.target/riscv/rvv/base/abi-call-variant_cc.c index 6459f8e..16c7687 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/base/abi-call-variant_cc.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/abi-call-variant_cc.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gcv -mabi=lp64d -O1 --param=riscv-vector-abi -Wno-psabi" } */ +/* { dg-options "-march=rv64gcv -mabi=lp64d -O1 --param=riscv-vector-abi" } */ #include "riscv_vector.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/abi-callee-saved-1-fixed-1.c b/gcc/testsuite/gcc.target/riscv/rvv/base/abi-callee-saved-1-fixed-1.c index 1e6292e..06b3647 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/base/abi-callee-saved-1-fixed-1.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/abi-callee-saved-1-fixed-1.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-O1 -march=rv64gczve32x -mabi=lp64d --param=riscv-vector-abi --param=riscv-autovec-preference=fixed-vlmax -Wno-psabi" } */ +/* { dg-options "-O1 -march=rv64gczve32x -mabi=lp64d --param=riscv-vector-abi --param=riscv-autovec-preference=fixed-vlmax" } */ /* { dg-final { check-function-bodies "**" "" } } */ #include <riscv_vector.h> diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/abi-callee-saved-1-fixed-2.c b/gcc/testsuite/gcc.target/riscv/rvv/base/abi-callee-saved-1-fixed-2.c index 9fdbcd8..5a6ab81 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/base/abi-callee-saved-1-fixed-2.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/abi-callee-saved-1-fixed-2.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-O1 -march=rv64gcv_zvl4096b -mabi=lp64d --param=riscv-vector-abi --param=riscv-autovec-preference=fixed-vlmax -Wno-psabi" } */ +/* { dg-options "-O1 -march=rv64gcv_zvl4096b -mabi=lp64d --param=riscv-vector-abi --param=riscv-autovec-preference=fixed-vlmax" } */ /* { dg-final { check-function-bodies "**" "" } } */ #include <riscv_vector.h> diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/abi-callee-saved-1-save-restore.c b/gcc/testsuite/gcc.target/riscv/rvv/base/abi-callee-saved-1-save-restore.c index 007c274..c6aa5e1 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/base/abi-callee-saved-1-save-restore.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/abi-callee-saved-1-save-restore.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-O1 -march=rv64gcv_zfh -mabi=lp64d --param=riscv-vector-abi -Wno-psabi -msave-restore" } */ +/* { dg-options "-O1 -march=rv64gcv_zfh -mabi=lp64d --param=riscv-vector-abi -msave-restore" } */ /* { dg-final { check-function-bodies "**" "" } } */ #include <riscv_vector.h> diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/abi-callee-saved-1-zcmp.c b/gcc/testsuite/gcc.target/riscv/rvv/base/abi-callee-saved-1-zcmp.c index 5f697e7..386916a 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/base/abi-callee-saved-1-zcmp.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/abi-callee-saved-1-zcmp.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-O1 -march=rv64gcv_zfh_zca_zcmp -mabi=lp64d --param=riscv-vector-abi -Wno-psabi -fno-shrink-wrap-separate" } */ +/* { dg-options "-O1 -march=rv64gcv_zfh_zca_zcmp -mabi=lp64d --param=riscv-vector-abi -fno-shrink-wrap-separate" } */ /* { dg-final { check-function-bodies "**" "" } } */ #include <riscv_vector.h> diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/abi-callee-saved-1.c b/gcc/testsuite/gcc.target/riscv/rvv/base/abi-callee-saved-1.c index 42d099d..bc1f9ff 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/base/abi-callee-saved-1.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/abi-callee-saved-1.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-O1 -march=rv64gcv_zfh -mabi=lp64d --param=riscv-vector-abi -Wno-psabi" } */ +/* { dg-options "-O1 -march=rv64gcv_zfh -mabi=lp64d --param=riscv-vector-abi" } */ /* { dg-final { check-function-bodies "**" "" } } */ #include <riscv_vector.h> diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/abi-callee-saved-2-save-restore.c b/gcc/testsuite/gcc.target/riscv/rvv/base/abi-callee-saved-2-save-restore.c index ce2f68e..96a3e71 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/base/abi-callee-saved-2-save-restore.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/abi-callee-saved-2-save-restore.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-O1 -march=rv64gcv_zfh -mabi=lp64d --param=riscv-vector-abi -Wno-psabi -msave-restore" } */ +/* { dg-options "-O1 -march=rv64gcv_zfh -mabi=lp64d --param=riscv-vector-abi -msave-restore" } */ /* { dg-final { check-function-bodies "**" "" } } */ #include <riscv_vector.h> diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/abi-callee-saved-2-zcmp.c b/gcc/testsuite/gcc.target/riscv/rvv/base/abi-callee-saved-2-zcmp.c index 08ca1a1..b3a8141 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/base/abi-callee-saved-2-zcmp.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/abi-callee-saved-2-zcmp.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-O1 -march=rv64gcv_zfh_zca_zcmp -mabi=lp64d --param=riscv-vector-abi -Wno-psabi -fno-shrink-wrap-separate" } */ +/* { dg-options "-O1 -march=rv64gcv_zfh_zca_zcmp -mabi=lp64d --param=riscv-vector-abi -fno-shrink-wrap-separate" } */ /* { dg-final { check-function-bodies "**" "" } } */ #include <riscv_vector.h> diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/abi-callee-saved-2.c b/gcc/testsuite/gcc.target/riscv/rvv/base/abi-callee-saved-2.c index 0ea3e24..8b6537b 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/base/abi-callee-saved-2.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/abi-callee-saved-2.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-O1 -march=rv64gcv_zfh -mabi=lp64d --param=riscv-vector-abi -Wno-psabi" } */ +/* { dg-options "-O1 -march=rv64gcv_zfh -mabi=lp64d --param=riscv-vector-abi" } */ /* { dg-final { check-function-bodies "**" "" } } */ #include <riscv_vector.h> diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/big_endian-1.c b/gcc/testsuite/gcc.target/riscv/rvv/base/big_endian-1.c new file mode 100644 index 0000000..9eaf7ad --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/big_endian-1.c @@ -0,0 +1,5 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gcv -mabi=lp64d -mbig-endian -O3" } */ + +#pragma riscv intrinsic "vector" +vfloat32m1_t foo (vfloat32m1_t) {} // { dg-excess-errors "sorry, unimplemented: Current RISC-V GCC cannot support RVV in big-endian mode" } diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/big_endian-2.c b/gcc/testsuite/gcc.target/riscv/rvv/base/big_endian-2.c new file mode 100644 index 0000000..86cf583 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/big_endian-2.c @@ -0,0 +1,5 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gc_zve32x -mabi=lp64d -mbig-endian -O3" } */ + +#pragma riscv intrinsic "vector" +vint32m1_t foo (vint32m1_t) {} // { dg-excess-errors "sorry, unimplemented: Current RISC-V GCC cannot support RVV in big-endian mode" } diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-120.c b/gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-120.c index cc37346..809b185 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-120.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-120.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv32gcv -mabi=ilp32 -O3 -Wno-psabi" } */ +/* { dg-options "-march=rv32gcv -mabi=ilp32 -O3" } */ #include "riscv_vector.h" vint16mf4_t test___riscv_vwmulsu_vx_i16mf4(vbool64_t mask, vint16mf4_t merge, vint8mf8_t op1,int8_t op2,size_t vl) diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/fixed-point-vxrm-error.c b/gcc/testsuite/gcc.target/riscv/rvv/base/fixed-point-vxrm-error.c index 2b82445..b66ecef 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/base/fixed-point-vxrm-error.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/fixed-point-vxrm-error.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gcv -mabi=lp64 -O3 -Wno-psabi" } */ +/* { dg-options "-march=rv64gcv -mabi=lp64 -O3" } */ #include "riscv_vector.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/fixed-point-vxrm.c b/gcc/testsuite/gcc.target/riscv/rvv/base/fixed-point-vxrm.c index 41e34cd..582aa03 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/base/fixed-point-vxrm.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/fixed-point-vxrm.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gcv -mabi=lp64 -O3 -Wno-psabi" } */ +/* { dg-options "-march=rv64gcv -mabi=lp64 -O3" } */ #include "riscv_vector.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-cvt-f.c b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-cvt-f.c index 424a38e..48930cd 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-cvt-f.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-cvt-f.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gcv -mabi=lp64 -O3 -Wno-psabi" } */ +/* { dg-options "-march=rv64gcv -mabi=lp64 -O3" } */ #include "riscv_vector.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-cvt-x.c b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-cvt-x.c index e090f0f..fcbfb87 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-cvt-x.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-cvt-x.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gcv -mabi=lp64 -O3 -Wno-psabi" } */ +/* { dg-options "-march=rv64gcv -mabi=lp64 -O3" } */ #include "riscv_vector.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-cvt-xu.c b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-cvt-xu.c index bb164b2..dc8aff8 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-cvt-xu.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-cvt-xu.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gcv -mabi=lp64 -O3 -Wno-psabi" } */ +/* { dg-options "-march=rv64gcv -mabi=lp64 -O3" } */ #include "riscv_vector.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-1.c b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-1.c index 75af8ee..0c78cac 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-1.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-1.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gcv -mabi=lp64 -O3 -Wno-psabi" } */ +/* { dg-options "-march=rv64gcv -mabi=lp64 -O3" } */ #include "riscv_vector.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-10.c b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-10.c index 71428d6..c578be5 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-10.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-10.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gcv -mabi=lp64 -O3 -Wno-psabi" } */ +/* { dg-options "-march=rv64gcv -mabi=lp64 -O3" } */ #include "riscv_vector.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-11.c b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-11.c index 94f8ea1..f3b3068 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-11.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-11.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gcv -mabi=lp64 -O3 -Wno-psabi" } */ +/* { dg-options "-march=rv64gcv -mabi=lp64 -O3" } */ #include "riscv_vector.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-12.c b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-12.c index 66c7495..3203329 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-12.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-12.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gcv -mabi=lp64 -O3 -Wno-psabi" } */ +/* { dg-options "-march=rv64gcv -mabi=lp64 -O3" } */ #include "riscv_vector.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-13.c b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-13.c index 0fb8498..1216793 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-13.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-13.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gcv -mabi=lp64 -O3 -Wno-psabi" } */ +/* { dg-options "-march=rv64gcv -mabi=lp64 -O3" } */ #include "riscv_vector.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-14.c b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-14.c index ab5fc06..d84e470 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-14.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-14.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gcv -mabi=lp64 -O3 -Wno-psabi" } */ +/* { dg-options "-march=rv64gcv -mabi=lp64 -O3" } */ #include "riscv_vector.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-15.c b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-15.c index 97dacca..3a75398 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-15.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-15.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gcv -mabi=lp64 -O3 -Wno-psabi" } */ +/* { dg-options "-march=rv64gcv -mabi=lp64 -O3" } */ #include "riscv_vector.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-16.c b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-16.c index da710b1..5caa292 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-16.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-16.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gcv -mabi=lp64 -O3 -Wno-psabi" } */ +/* { dg-options "-march=rv64gcv -mabi=lp64 -O3" } */ #include "riscv_vector.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-17.c b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-17.c index 43f2517..b0a8935 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-17.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-17.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gcv -mabi=lp64 -O3 -Wno-psabi" } */ +/* { dg-options "-march=rv64gcv -mabi=lp64 -O3" } */ #include "riscv_vector.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-18.c b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-18.c index e725825..6f02296 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-18.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-18.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gcv -mabi=lp64 -O3 -Wno-psabi" } */ +/* { dg-options "-march=rv64gcv -mabi=lp64 -O3" } */ #include "riscv_vector.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-19.c b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-19.c index c0161a1..09020d5 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-19.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-19.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gcv -mabi=lp64 -O3 -Wno-psabi" } */ +/* { dg-options "-march=rv64gcv -mabi=lp64 -O3" } */ #include "riscv_vector.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-2.c b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-2.c index 9f8ac99..4b35e99 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-2.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-2.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gcv -mabi=lp64 -O3 -Wno-psabi" } */ +/* { dg-options "-march=rv64gcv -mabi=lp64 -O3" } */ #include "riscv_vector.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-20.c b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-20.c index 9e75b79..849ba16 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-20.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-20.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gcv -mabi=lp64 -O3 -Wno-psabi" } */ +/* { dg-options "-march=rv64gcv -mabi=lp64 -O3" } */ #include "riscv_vector.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-21.c b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-21.c index aec5642..052f8ea 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-21.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-21.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gcv -mabi=lp64 -O3 -Wno-psabi" } */ +/* { dg-options "-march=rv64gcv -mabi=lp64 -O3" } */ #include "riscv_vector.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-22.c b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-22.c index 83bc26a..c6b0722 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-22.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-22.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gcv -mabi=lp64 -O3 -Wno-psabi" } */ +/* { dg-options "-march=rv64gcv -mabi=lp64 -O3" } */ #include "riscv_vector.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-23.c b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-23.c index e7c51ea..09f4bee 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-23.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-23.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gcv -mabi=lp64 -O3 -Wno-psabi" } */ +/* { dg-options "-march=rv64gcv -mabi=lp64 -O3" } */ #include "riscv_vector.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-24.c b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-24.c index 46ac8e0..14ac2fb 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-24.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-24.c @@ -1,4 +1,4 @@ -/* { dg-options "-march=rv64gcv -mabi=lp64 -O3 -Wno-psabi" } */ +/* { dg-options "-march=rv64gcv -mabi=lp64 -O3" } */ #include "riscv_vector.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-25.c b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-25.c index b70f531..ae2853d 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-25.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-25.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gcv -mabi=lp64 -O3 -Wno-psabi" } */ +/* { dg-options "-march=rv64gcv -mabi=lp64 -O3" } */ #include "riscv_vector.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-26.c b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-26.c index 78b2946..d67e6d6 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-26.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-26.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gcv -mabi=lp64 -O3 -Wno-psabi" } */ +/* { dg-options "-march=rv64gcv -mabi=lp64 -O3" } */ #include "riscv_vector.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-27.c b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-27.c index 4dba680..87507a2 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-27.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-27.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gcv -mabi=lp64 -O3 -Wno-psabi" } */ +/* { dg-options "-march=rv64gcv -mabi=lp64 -O3" } */ #include "riscv_vector.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-28.c b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-28.c index 35a37b8..7fd63db 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-28.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-28.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gcv -mabi=lp64 -O3 -Wno-psabi" } */ +/* { dg-options "-march=rv64gcv -mabi=lp64 -O3" } */ #include "riscv_vector.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-29.c b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-29.c index e24c204..9e7b471 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-29.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-29.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gcv -mabi=lp64 -O3 -Wno-psabi" } */ +/* { dg-options "-march=rv64gcv -mabi=lp64 -O3" } */ #include "riscv_vector.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-3.c b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-3.c index 600ac45..baa3461 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-3.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-3.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gcv -mabi=lp64 -O3 -Wno-psabi" } */ +/* { dg-options "-march=rv64gcv -mabi=lp64 -O3" } */ #include "riscv_vector.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-30.c b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-30.c index bf57720..7e73878 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-30.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-30.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gcv -mabi=lp64 -O3 -Wno-psabi" } */ +/* { dg-options "-march=rv64gcv -mabi=lp64 -O3" } */ #include "riscv_vector.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-31.c b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-31.c index 64a0c8c..d7ff69b 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-31.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-31.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gcv -mabi=lp64 -O3 -Wno-psabi" } */ +/* { dg-options "-march=rv64gcv -mabi=lp64 -O3" } */ #include "riscv_vector.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-32.c b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-32.c index a24ffd7..179f8d0 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-32.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-32.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gcv -mabi=lp64 -O3 -Wno-psabi" } */ +/* { dg-options "-march=rv64gcv -mabi=lp64 -O3" } */ #include "riscv_vector.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-33.c b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-33.c index 4bd520e..ce929e8 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-33.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-33.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gcv -mabi=lp64 -O3 -Wno-psabi" } */ +/* { dg-options "-march=rv64gcv -mabi=lp64 -O3" } */ #include "riscv_vector.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-34.c b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-34.c index 6c7cf7e..de0ba5d 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-34.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-34.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gcv -mabi=lp64 -O3 -Wno-psabi" } */ +/* { dg-options "-march=rv64gcv -mabi=lp64 -O3" } */ #include "riscv_vector.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-35.c b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-35.c index b7f5a69..a69a661 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-35.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-35.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gcv -mabi=lp64 -O3 -Wno-psabi" } */ +/* { dg-options "-march=rv64gcv -mabi=lp64 -O3" } */ #include "riscv_vector.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-36.c b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-36.c index 4485cea..f81341f 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-36.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-36.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gcv -mabi=lp64 -O3 -Wno-psabi" } */ +/* { dg-options "-march=rv64gcv -mabi=lp64 -O3" } */ #include "riscv_vector.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-37.c b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-37.c index a1fca1a..2457254 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-37.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-37.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gcv -mabi=lp64 -O3 -Wno-psabi" } */ +/* { dg-options "-march=rv64gcv -mabi=lp64 -O3" } */ #include "riscv_vector.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-38.c b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-38.c index 8d59cae..c402fad 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-38.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-38.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gcv -mabi=lp64 -O3 -Wno-psabi" } */ +/* { dg-options "-march=rv64gcv -mabi=lp64 -O3" } */ #include "riscv_vector.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-39.c b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-39.c index 04c5487..fe497c7 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-39.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-39.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gcv -mabi=lp64 -O3 -Wno-psabi" } */ +/* { dg-options "-march=rv64gcv -mabi=lp64 -O3" } */ #include "riscv_vector.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-4.c b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-4.c index aaf912e..c26dcfc 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-4.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-4.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gcv -mabi=lp64 -O3 -Wno-psabi" } */ +/* { dg-options "-march=rv64gcv -mabi=lp64 -O3" } */ #include "riscv_vector.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-40.c b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-40.c index 49cf52f..7c75f12 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-40.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-40.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gcv -mabi=lp64 -O3 -Wno-psabi" } */ +/* { dg-options "-march=rv64gcv -mabi=lp64 -O3" } */ #include "riscv_vector.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-41.c b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-41.c index 79ef55b..4f86fcb 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-41.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-41.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gcv -mabi=lp64 -O3 -Wno-psabi" } */ +/* { dg-options "-march=rv64gcv -mabi=lp64 -O3" } */ #include "riscv_vector.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-42.c b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-42.c index 1123a93..4a09a11 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-42.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-42.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gcv -mabi=lp64 -O3 -Wno-psabi" } */ +/* { dg-options "-march=rv64gcv -mabi=lp64 -O3" } */ #include "riscv_vector.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-43.c b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-43.c index 2ea60ca..f6c8a00 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-43.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-43.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gcv -mabi=lp64 -O3 -Wno-psabi" } */ +/* { dg-options "-march=rv64gcv -mabi=lp64 -O3" } */ #include "riscv_vector.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-44.c b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-44.c index 7486ed4..4e73ee9 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-44.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-44.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gcv -mabi=lp64 -O3 -Wno-psabi" } */ +/* { dg-options "-march=rv64gcv -mabi=lp64 -O3" } */ #include "riscv_vector.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-45.c b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-45.c index 3ceea10..69ccd4f 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-45.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-45.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gcv -mabi=lp64 -O3 -Wno-psabi" } */ +/* { dg-options "-march=rv64gcv -mabi=lp64 -O3" } */ #include "riscv_vector.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-46.c b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-46.c index b990fb4..a11a1b4 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-46.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-46.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gcv -mabi=lp64 -O3 -Wno-psabi" } */ +/* { dg-options "-march=rv64gcv -mabi=lp64 -O3" } */ #include "riscv_vector.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-47.c b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-47.c index 994c86e..6212305 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-47.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-47.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gcv -mabi=lp64 -O3 -Wno-psabi" } */ +/* { dg-options "-march=rv64gcv -mabi=lp64 -O3" } */ #include "riscv_vector.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-48.c b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-48.c index 4cde923..2855d5f 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-48.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-48.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gcv -mabi=lp64 -O3 -Wno-psabi" } */ +/* { dg-options "-march=rv64gcv -mabi=lp64 -O3" } */ #include "riscv_vector.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-49.c b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-49.c index 0b0a017..af89f62 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-49.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-49.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gcv -mabi=lp64 -O3 -Wno-psabi" } */ +/* { dg-options "-march=rv64gcv -mabi=lp64 -O3" } */ #include "riscv_vector.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-5.c b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-5.c index 9149388..6aa3f5b 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-5.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-5.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gcv -mabi=lp64 -O3 -Wno-psabi" } */ +/* { dg-options "-march=rv64gcv -mabi=lp64 -O3" } */ #include "riscv_vector.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-50.c b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-50.c index 23f7266..5b75935 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-50.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-50.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gcv -mabi=lp64 -O3 -Wno-psabi" } */ +/* { dg-options "-march=rv64gcv -mabi=lp64 -O3" } */ #include "riscv_vector.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-51.c b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-51.c index 8b564ca..caf6792 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-51.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-51.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gcv -mabi=lp64 -O3 -Wno-psabi" } */ +/* { dg-options "-march=rv64gcv -mabi=lp64 -O3" } */ #include "riscv_vector.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-52.c b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-52.c index b63f717..cd23141 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-52.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-52.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gcv -mabi=lp64 -O3 -Wno-psabi" } */ +/* { dg-options "-march=rv64gcv -mabi=lp64 -O3" } */ #include "riscv_vector.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-53.c b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-53.c index 647de39..949f1d3 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-53.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-53.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gcv -mabi=lp64 -O3 -Wno-psabi" } */ +/* { dg-options "-march=rv64gcv -mabi=lp64 -O3" } */ #include "riscv_vector.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-54.c b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-54.c index f33f303..be569b9 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-54.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-54.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gcv -mabi=lp64 -O3 -Wno-psabi" } */ +/* { dg-options "-march=rv64gcv -mabi=lp64 -O3" } */ #include "riscv_vector.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-55.c b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-55.c index 6136510..efbc59b 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-55.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-55.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gcv -mabi=lp64 -O3 -Wno-psabi" } */ +/* { dg-options "-march=rv64gcv -mabi=lp64 -O3" } */ #include "riscv_vector.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-56.c b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-56.c index e5a1c35..aa9c06f 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-56.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-56.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gcv -mabi=lp64 -O3 -Wno-psabi" } */ +/* { dg-options "-march=rv64gcv -mabi=lp64 -O3" } */ #include "riscv_vector.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-57.c b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-57.c index cc0fb55..d4b5ed0 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-57.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-57.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gcv -mabi=lp64 -O3 -Wno-psabi" } */ +/* { dg-options "-march=rv64gcv -mabi=lp64 -O3" } */ #include "riscv_vector.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-58.c b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-58.c index c5c3408b..d656832 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-58.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-58.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gcv -mabi=lp64 -O3 -Wno-psabi" } */ +/* { dg-options "-march=rv64gcv -mabi=lp64 -O3" } */ #include "riscv_vector.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-59.c b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-59.c index 87d436a..8a75269 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-59.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-59.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gcv -mabi=lp64 -O3 -Wno-psabi" } */ +/* { dg-options "-march=rv64gcv -mabi=lp64 -O3" } */ #include "riscv_vector.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-6.c b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-6.c index 1541de8..15ebb69 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-6.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-6.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gcv -mabi=lp64 -O3 -Wno-psabi" } */ +/* { dg-options "-march=rv64gcv -mabi=lp64 -O3" } */ #include "riscv_vector.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-60.c b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-60.c index ad3a7f8..96f0091 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-60.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-60.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gcv -mabi=lp64 -O3 -Wno-psabi" } */ +/* { dg-options "-march=rv64gcv -mabi=lp64 -O3" } */ #include "riscv_vector.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-61.c b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-61.c index 8748ca6..5028b789 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-61.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-61.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gcv -mabi=lp64 -O3 -Wno-psabi" } */ +/* { dg-options "-march=rv64gcv -mabi=lp64 -O3" } */ #include "riscv_vector.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-62.c b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-62.c index 8fd97b5..44bf9ff 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-62.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-62.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gcv -mabi=lp64 -O3 -Wno-psabi" } */ +/* { dg-options "-march=rv64gcv -mabi=lp64 -O3" } */ #include "riscv_vector.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-63.c b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-63.c index 58718c3..12ebef1 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-63.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-63.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gcv -mabi=lp64 -O3 -Wno-psabi" } */ +/* { dg-options "-march=rv64gcv -mabi=lp64 -O3" } */ #include "riscv_vector.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-64.c b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-64.c index ad2d545..45c8b840 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-64.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-64.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gcv -mabi=lp64 -O3 -Wno-psabi" } */ +/* { dg-options "-march=rv64gcv -mabi=lp64 -O3" } */ #include "riscv_vector.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-65.c b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-65.c index c15629d..329f98c 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-65.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-65.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gcv -mabi=lp64 -O3 -Wno-psabi" } */ +/* { dg-options "-march=rv64gcv -mabi=lp64 -O3" } */ #include "riscv_vector.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-66.c b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-66.c index ea99831..b9240f2 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-66.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-66.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gcv -mabi=lp64 -O3 -Wno-psabi" } */ +/* { dg-options "-march=rv64gcv -mabi=lp64 -O3" } */ #include "riscv_vector.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-67.c b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-67.c index b850030..2008cc6 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-67.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-67.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gcv -mabi=lp64 -O3 -Wno-psabi" } */ +/* { dg-options "-march=rv64gcv -mabi=lp64 -O3" } */ #include "riscv_vector.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-68.c b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-68.c index 1dbf6db..cad2f1d 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-68.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-68.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gcv -mabi=lp64 -O3 -Wno-psabi" } */ +/* { dg-options "-march=rv64gcv -mabi=lp64 -O3" } */ #include "riscv_vector.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-69.c b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-69.c index b08ab1e..5f07b89 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-69.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-69.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gcv -mabi=lp64 -O3 -Wno-psabi" } */ +/* { dg-options "-march=rv64gcv -mabi=lp64 -O3" } */ #include "riscv_vector.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-7.c b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-7.c index 6f24317..e5e53b7 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-7.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-7.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gcv -mabi=lp64 -O3 -Wno-psabi" } */ +/* { dg-options "-march=rv64gcv -mabi=lp64 -O3" } */ #include "riscv_vector.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-70.c b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-70.c index 5a2b8a1..44f985b 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-70.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-70.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gcv -mabi=lp64 -O3 -Wno-psabi" } */ +/* { dg-options "-march=rv64gcv -mabi=lp64 -O3" } */ #include "riscv_vector.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-71.c b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-71.c index 185a04c..694f3aa 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-71.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-71.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gcv -mabi=lp64 -O3 -Wno-psabi" } */ +/* { dg-options "-march=rv64gcv -mabi=lp64 -O3" } */ #include "riscv_vector.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-72.c b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-72.c index 6a07cfa..6b1d31b 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-72.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-72.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gcv -mabi=lp64 -O3 -Wno-psabi" } */ +/* { dg-options "-march=rv64gcv -mabi=lp64 -O3" } */ #include "riscv_vector.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-73.c b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-73.c index 91b015c..0d3b3ef 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-73.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-73.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gcv -mabi=lp64 -O3 -Wno-psabi" } */ +/* { dg-options "-march=rv64gcv -mabi=lp64 -O3" } */ #include "riscv_vector.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-74.c b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-74.c index b52400e..fb57803 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-74.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-74.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gcv -mabi=lp64 -O3 -Wno-psabi" } */ +/* { dg-options "-march=rv64gcv -mabi=lp64 -O3" } */ #include "riscv_vector.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-75.c b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-75.c index 4d3fd85..09067d3 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-75.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-75.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gcv -mabi=lp64 -O3 -Wno-psabi" } */ +/* { dg-options "-march=rv64gcv -mabi=lp64 -O3" } */ #include "riscv_vector.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-76.c b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-76.c index 7ff106a..915483d 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-76.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-76.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gcv -mabi=lp64 -O3 -Wno-psabi" } */ +/* { dg-options "-march=rv64gcv -mabi=lp64 -O3" } */ #include "riscv_vector.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-77.c b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-77.c index c3d12cf..9920a24 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-77.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-77.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gcv_zbb --param=riscv-autovec-preference=fixed-vlmax -ffast-math -mabi=lp64 -O3 -Wno-psabi" } */ +/* { dg-options "-march=rv64gcv_zbb --param=riscv-autovec-preference=fixed-vlmax -ffast-math -mabi=lp64 -O3" } */ #include "riscv_vector.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-8.c b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-8.c index a4846b0..4a9eddc 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-8.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-8.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gcv -mabi=lp64 -O3 -Wno-psabi" } */ +/* { dg-options "-march=rv64gcv -mabi=lp64 -O3" } */ #include "riscv_vector.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-9.c b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-9.c index cfb8fca..58f7ad9 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-9.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-9.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gcv -mabi=lp64 -O3 -Wno-psabi" } */ +/* { dg-options "-march=rv64gcv -mabi=lp64 -O3" } */ #include "riscv_vector.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-frm-autovec-1.c b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-frm-autovec-1.c index f4f17a3..ccdd6d4 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-frm-autovec-1.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-frm-autovec-1.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gcv --param=riscv-autovec-preference=fixed-vlmax -ffast-math -mabi=lp64 -O3 -Wno-psabi" } */ +/* { dg-options "-march=rv64gcv --param=riscv-autovec-preference=fixed-vlmax -ffast-math -mabi=lp64 -O3" } */ /* { dg-final { check-function-bodies "**" "" } } */ #include "riscv_vector.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-frm-autovec-2.c b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-frm-autovec-2.c index 77d0f5e..89e43cd 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-frm-autovec-2.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-frm-autovec-2.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gcv --param=riscv-autovec-preference=fixed-vlmax -ffast-math -mabi=lp64 -O3 -Wno-psabi" } */ +/* { dg-options "-march=rv64gcv --param=riscv-autovec-preference=fixed-vlmax -ffast-math -mabi=lp64 -O3" } */ /* { dg-final { check-function-bodies "**" "" } } */ #include "riscv_vector.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-frm-autovec-3.c b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-frm-autovec-3.c index abedfc1..cb0ea58 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-frm-autovec-3.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-frm-autovec-3.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gcv --param=riscv-autovec-preference=fixed-vlmax -ffast-math -mabi=lp64 -O3 -Wno-psabi" } */ +/* { dg-options "-march=rv64gcv --param=riscv-autovec-preference=fixed-vlmax -ffast-math -mabi=lp64 -O3" } */ /* { dg-final { check-function-bodies "**" "" } } */ #include "riscv_vector.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-frm-autovec-4.c b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-frm-autovec-4.c index 2cc4e0a..c043761 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-frm-autovec-4.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-frm-autovec-4.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gcv --param=riscv-autovec-preference=fixed-vlmax -ffast-math -mabi=lp64 -O3 -Wno-psabi" } */ +/* { dg-options "-march=rv64gcv --param=riscv-autovec-preference=fixed-vlmax -ffast-math -mabi=lp64 -O3" } */ /* { dg-final { check-function-bodies "**" "" } } */ #include "riscv_vector.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-frm-error.c b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-frm-error.c index 01d82d4..bbd8592 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-frm-error.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-frm-error.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gcv -mabi=lp64 -O3 -Wno-psabi" } */ +/* { dg-options "-march=rv64gcv -mabi=lp64 -O3" } */ #include "riscv_vector.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-frm-insert-1.c b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-frm-insert-1.c index d6c5e1b..9a7e917 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-frm-insert-1.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-frm-insert-1.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gcv -mabi=lp64 -O3 -Wno-psabi" } */ +/* { dg-options "-march=rv64gcv -mabi=lp64 -O3" } */ #include "riscv_vector.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-frm-insert-10.c b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-frm-insert-10.c index 3252f67..f38042a 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-frm-insert-10.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-frm-insert-10.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gcv -mabi=lp64 -O3 -Wno-psabi" } */ +/* { dg-options "-march=rv64gcv -mabi=lp64 -O3" } */ #include "riscv_vector.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-frm-insert-2.c b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-frm-insert-2.c index 96e10c7..2ca5714 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-frm-insert-2.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-frm-insert-2.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gcv -mabi=lp64 -O3 -Wno-psabi" } */ +/* { dg-options "-march=rv64gcv -mabi=lp64 -O3" } */ #include "riscv_vector.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-frm-insert-3.c b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-frm-insert-3.c index 519537c..8e72a8f 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-frm-insert-3.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-frm-insert-3.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gcv -mabi=lp64 -O3 -Wno-psabi" } */ +/* { dg-options "-march=rv64gcv -mabi=lp64 -O3" } */ #include "riscv_vector.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-frm-insert-4.c b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-frm-insert-4.c index f9e6bc36..17e47eb 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-frm-insert-4.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-frm-insert-4.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gcv -mabi=lp64 -O3 -Wno-psabi" } */ +/* { dg-options "-march=rv64gcv -mabi=lp64 -O3" } */ #include "riscv_vector.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-frm-insert-5.c b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-frm-insert-5.c index c3f6302..32c938d 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-frm-insert-5.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-frm-insert-5.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gcv -mabi=lp64 -O3 -Wno-psabi" } */ +/* { dg-options "-march=rv64gcv -mabi=lp64 -O3" } */ #include "riscv_vector.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-frm-insert-7.c b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-frm-insert-7.c index 6de9d06..e74f9fa 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-frm-insert-7.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-frm-insert-7.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gcv -mabi=lp64 -O3 -Wno-psabi" } */ +/* { dg-options "-march=rv64gcv -mabi=lp64 -O3" } */ #include "riscv_vector.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-frm-insert-8.c b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-frm-insert-8.c index cc83dae..9eb6736 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-frm-insert-8.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-frm-insert-8.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gcv -mabi=lp64 -O3 -Wno-psabi" } */ +/* { dg-options "-march=rv64gcv -mabi=lp64 -O3" } */ #include "riscv_vector.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-frm-insert-9.c b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-frm-insert-9.c index 3b650ec..db707fc 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-frm-insert-9.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-frm-insert-9.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gcv -mabi=lp64 -O3 -Wno-psabi" } */ +/* { dg-options "-march=rv64gcv -mabi=lp64 -O3" } */ #include "riscv_vector.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-frm-run-1.c b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-frm-run-1.c index 34b8c48..efa55f5 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-frm-run-1.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-frm-run-1.c @@ -1,5 +1,5 @@ /* { dg-do run { target { riscv_v } } } */ -/* { dg-options "-O3 -Wno-psabi" } */ +/* { dg-options "-O3" } */ #include "riscv_vector.h" #include <stdio.h> diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-frm-run-2.c b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-frm-run-2.c index 4c43983..fa7630a 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-frm-run-2.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-frm-run-2.c @@ -1,5 +1,5 @@ /* { dg-do run { target { riscv_v } } } */ -/* { dg-options "-O3 -Wno-psabi" } */ +/* { dg-options "-O3" } */ #include "riscv_vector.h" #include <stdio.h> diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-frm-run-3.c b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-frm-run-3.c index ff43422..4f21fe3 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-frm-run-3.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-frm-run-3.c @@ -1,5 +1,5 @@ /* { dg-do run { target { riscv_v } } } */ -/* { dg-options "-O3 -Wno-psabi" } */ +/* { dg-options "-O3" } */ #include "riscv_vector.h" #include <stdio.h> diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-frm-run-4.c b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-frm-run-4.c index f2b1b1b..0194df9 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-frm-run-4.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-frm-run-4.c @@ -1,5 +1,5 @@ /* { dg-do run { target { riscv_v } } } */ -/* { dg-options "-O3 -Wno-psabi" } */ +/* { dg-options "-O3" } */ #include "riscv_vector.h" #include <stdio.h> diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-frm-run-5.c b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-frm-run-5.c index 4cb913a..510f9ab 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-frm-run-5.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-frm-run-5.c @@ -1,5 +1,5 @@ /* { dg-do run { target { riscv_v } } } */ -/* { dg-options "-O3 -Wno-psabi" } */ +/* { dg-options "-O3" } */ #include "riscv_vector.h" #include <stdio.h> diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-frm.c b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-frm.c index 1f14260..538d612 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-frm.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-frm.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gcv -mabi=lp64 -O3 -Wno-psabi" } */ +/* { dg-options "-march=rv64gcv -mabi=lp64 -O3" } */ #include "riscv_vector.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-fwmacc.c b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-fwmacc.c index 45bb628..b286a2e 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-fwmacc.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-fwmacc.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gcv -mabi=lp64 -O3 -Wno-psabi" } */ +/* { dg-options "-march=rv64gcv -mabi=lp64 -O3" } */ #include "riscv_vector.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-macc.c b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-macc.c index df29f4d..a0d89e1 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-macc.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-macc.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gcv -mabi=lp64 -O3 -Wno-psabi" } */ +/* { dg-options "-march=rv64gcv -mabi=lp64 -O3" } */ #include "riscv_vector.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-madd.c b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-madd.c index 00c9d00..c6df691 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-madd.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-madd.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gcv -mabi=lp64 -O3 -Wno-psabi" } */ +/* { dg-options "-march=rv64gcv -mabi=lp64 -O3" } */ #include "riscv_vector.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-msac.c b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-msac.c index 8fee552..dde0d16 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-msac.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-msac.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gcv -mabi=lp64 -O3 -Wno-psabi" } */ +/* { dg-options "-march=rv64gcv -mabi=lp64 -O3" } */ #include "riscv_vector.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-msub.c b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-msub.c index e58519d..4b7feb0 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-msub.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-msub.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gcv -mabi=lp64 -O3 -Wno-psabi" } */ +/* { dg-options "-march=rv64gcv -mabi=lp64 -O3" } */ #include "riscv_vector.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-ncvt-f.c b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-ncvt-f.c index d6d4be5..c5a390a 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-ncvt-f.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-ncvt-f.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gcv -mabi=lp64 -O3 -Wno-psabi" } */ +/* { dg-options "-march=rv64gcv -mabi=lp64 -O3" } */ #include "riscv_vector.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-ncvt-x.c b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-ncvt-x.c index 1630b7e..47a9074 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-ncvt-x.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-ncvt-x.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gcv -mabi=lp64 -O3 -Wno-psabi" } */ +/* { dg-options "-march=rv64gcv -mabi=lp64 -O3" } */ #include "riscv_vector.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-ncvt-xu.c b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-ncvt-xu.c index 82c3e13..51af172 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-ncvt-xu.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-ncvt-xu.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gcv -mabi=lp64 -O3 -Wno-psabi" } */ +/* { dg-options "-march=rv64gcv -mabi=lp64 -O3" } */ #include "riscv_vector.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-nmacc.c b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-nmacc.c index fca378b..245a93d 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-nmacc.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-nmacc.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gcv -mabi=lp64 -O3 -Wno-psabi" } */ +/* { dg-options "-march=rv64gcv -mabi=lp64 -O3" } */ #include "riscv_vector.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-nmadd.c b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-nmadd.c index 9332617..f22767f 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-nmadd.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-nmadd.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gcv -mabi=lp64 -O3 -Wno-psabi" } */ +/* { dg-options "-march=rv64gcv -mabi=lp64 -O3" } */ #include "riscv_vector.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-nmsac.c b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-nmsac.c index c308923..6e5113b 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-nmsac.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-nmsac.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gcv -mabi=lp64 -O3 -Wno-psabi" } */ +/* { dg-options "-march=rv64gcv -mabi=lp64 -O3" } */ #include "riscv_vector.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-nmsub.c b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-nmsub.c index 1b3e939..e866149 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-nmsub.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-nmsub.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gcv -mabi=lp64 -O3 -Wno-psabi" } */ +/* { dg-options "-march=rv64gcv -mabi=lp64 -O3" } */ #include "riscv_vector.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-rec7.c b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-rec7.c index a8e10d0..643e18f 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-rec7.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-rec7.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gcv -mabi=lp64 -O3 -Wno-psabi" } */ +/* { dg-options "-march=rv64gcv -mabi=lp64 -O3" } */ #include "riscv_vector.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-redosum.c b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-redosum.c index 2e6a3c2..6eaf459 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-redosum.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-redosum.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gcv -mabi=lp64 -O3 -Wno-psabi" } */ +/* { dg-options "-march=rv64gcv -mabi=lp64 -O3" } */ #include "riscv_vector.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-redusum.c b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-redusum.c index 36da6dd..e2bb60e 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-redusum.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-redusum.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gcv -mabi=lp64 -O3 -Wno-psabi" } */ +/* { dg-options "-march=rv64gcv -mabi=lp64 -O3" } */ #include "riscv_vector.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-single-div.c b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-single-div.c index cef6ab0..06430d5 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-single-div.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-single-div.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gcv -mabi=lp64 -O3 -Wno-psabi" } */ +/* { dg-options "-march=rv64gcv -mabi=lp64 -O3" } */ #include "riscv_vector.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-single-mul.c b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-single-mul.c index e6410ea..ebefce1 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-single-mul.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-single-mul.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gcv -mabi=lp64 -O3 -Wno-psabi" } */ +/* { dg-options "-march=rv64gcv -mabi=lp64 -O3" } */ #include "riscv_vector.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-single-rdiv.c b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-single-rdiv.c index 385cddf..a318197 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-single-rdiv.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-single-rdiv.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gcv -mabi=lp64 -O3 -Wno-psabi" } */ +/* { dg-options "-march=rv64gcv -mabi=lp64 -O3" } */ #include "riscv_vector.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-single-rsub.c b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-single-rsub.c index 86c56b7..147a6d1 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-single-rsub.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-single-rsub.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gcv -mabi=lp64 -O3 -Wno-psabi" } */ +/* { dg-options "-march=rv64gcv -mabi=lp64 -O3" } */ #include "riscv_vector.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-single-sub.c b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-single-sub.c index 8075dce..6f0bd5a 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-single-sub.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-single-sub.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gcv -mabi=lp64 -O3 -Wno-psabi" } */ +/* { dg-options "-march=rv64gcv -mabi=lp64 -O3" } */ #include "riscv_vector.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-sqrt.c b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-sqrt.c index afd1fb2..553d017 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-sqrt.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-sqrt.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gcv -mabi=lp64 -O3 -Wno-psabi" } */ +/* { dg-options "-march=rv64gcv -mabi=lp64 -O3" } */ #include "riscv_vector.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-wcvt-x.c b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-wcvt-x.c index 8f67ec0..378f7d4 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-wcvt-x.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-wcvt-x.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gcv -mabi=lp64 -O3 -Wno-psabi" } */ +/* { dg-options "-march=rv64gcv -mabi=lp64 -O3" } */ #include "riscv_vector.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-wcvt-xu.c b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-wcvt-xu.c index 29449e7..6ba6ae1 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-wcvt-xu.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-wcvt-xu.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gcv -mabi=lp64 -O3 -Wno-psabi" } */ +/* { dg-options "-march=rv64gcv -mabi=lp64 -O3" } */ #include "riscv_vector.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-widening-add.c b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-widening-add.c index 19ce1e1..b7d4c75 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-widening-add.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-widening-add.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gcv -mabi=lp64 -O3 -Wno-psabi" } */ +/* { dg-options "-march=rv64gcv -mabi=lp64 -O3" } */ #include "riscv_vector.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-widening-mul.c b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-widening-mul.c index 893fa86..0c3f983 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-widening-mul.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-widening-mul.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gcv -mabi=lp64 -O3 -Wno-psabi" } */ +/* { dg-options "-march=rv64gcv -mabi=lp64 -O3" } */ #include "riscv_vector.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-widening-sub.c b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-widening-sub.c index 4325cc5..1dc3c3a 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-widening-sub.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-widening-sub.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gcv -mabi=lp64 -O3 -Wno-psabi" } */ +/* { dg-options "-march=rv64gcv -mabi=lp64 -O3" } */ #include "riscv_vector.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-wmsac.c b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-wmsac.c index 886a0b1..d86f72f 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-wmsac.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-wmsac.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gcv -mabi=lp64 -O3 -Wno-psabi" } */ +/* { dg-options "-march=rv64gcv -mabi=lp64 -O3" } */ #include "riscv_vector.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-wnmacc.c b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-wnmacc.c index 2602289..d1d7295 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-wnmacc.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-wnmacc.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gcv -mabi=lp64 -O3 -Wno-psabi" } */ +/* { dg-options "-march=rv64gcv -mabi=lp64 -O3" } */ #include "riscv_vector.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-wnmsac.c b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-wnmsac.c index 13eb306..c32e2a9 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-wnmsac.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-wnmsac.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gcv -mabi=lp64 -O3 -Wno-psabi" } */ +/* { dg-options "-march=rv64gcv -mabi=lp64 -O3" } */ #include "riscv_vector.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-wredosum.c b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-wredosum.c index acf7956..8335769 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-wredosum.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-wredosum.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gcv -mabi=lp64 -O3 -Wno-psabi" } */ +/* { dg-options "-march=rv64gcv -mabi=lp64 -O3" } */ #include "riscv_vector.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-wredusum.c b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-wredusum.c index 6c888c1..42add7e 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-wredusum.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-wredusum.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gcv -mabi=lp64 -O3 -Wno-psabi" } */ +/* { dg-options "-march=rv64gcv -mabi=lp64 -O3" } */ #include "riscv_vector.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/integer_compare_insn_shortcut.c b/gcc/testsuite/gcc.target/riscv/rvv/base/integer_compare_insn_shortcut.c index 2942e0b..1bca846 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/base/integer_compare_insn_shortcut.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/integer_compare_insn_shortcut.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gcv -mabi=lp64 -O3 -Wno-psabi" } */ +/* { dg-options "-march=rv64gcv -mabi=lp64 -O3" } */ #include "riscv_vector.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/intrisinc-vrgatherei16.c b/gcc/testsuite/gcc.target/riscv/rvv/base/intrisinc-vrgatherei16.c index 59c6d7c..6d96570 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/base/intrisinc-vrgatherei16.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/intrisinc-vrgatherei16.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gcv_zvfh -mabi=lp64 -O3 -Wno-psabi" } */ +/* { dg-options "-march=rv64gcv_zvfh -mabi=lp64 -O3" } */ #include "riscv_vector.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/mask_insn_shortcut.c b/gcc/testsuite/gcc.target/riscv/rvv/base/mask_insn_shortcut.c index a6df121..57d0241 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/base/mask_insn_shortcut.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/mask_insn_shortcut.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gcv -mabi=lp64 -O3 -Wno-psabi" } */ +/* { dg-options "-march=rv64gcv -mabi=lp64 -O3" } */ #include "riscv_vector.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/misc_vreinterpret_vbool_vint.c b/gcc/testsuite/gcc.target/riscv/rvv/base/misc_vreinterpret_vbool_vint.c index 276173d..9563c8d 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/base/misc_vreinterpret_vbool_vint.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/misc_vreinterpret_vbool_vint.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gcv -mabi=lp64 -O3 -Wno-psabi" } */ +/* { dg-options "-march=rv64gcv -mabi=lp64 -O3" } */ #include "riscv_vector.h" vbool1_t test_vreinterpret_v_i8m1_b1 (vint8m1_t src) { diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/no-honor-frm-1.c b/gcc/testsuite/gcc.target/riscv/rvv/base/no-honor-frm-1.c index b2e0f21..a8350c6 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/base/no-honor-frm-1.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/no-honor-frm-1.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gcv -mabi=lp64 -O3 -Wno-psabi" } */ +/* { dg-options "-march=rv64gcv -mabi=lp64 -O3" } */ void foo (void) { for (unsigned i = 0; i < sizeof(foo); i++) diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/overloaded_rv32_vadd.c b/gcc/testsuite/gcc.target/riscv/rvv/base/overloaded_rv32_vadd.c index 5f10aa9..05e6e43 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/base/overloaded_rv32_vadd.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/overloaded_rv32_vadd.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv32gcv_zvfh -mabi=ilp32 -O3 -Wno-psabi" } */ +/* { dg-options "-march=rv32gcv_zvfh -mabi=ilp32 -O3" } */ #include "overloaded_vadd.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/overloaded_rv32_vfadd.c b/gcc/testsuite/gcc.target/riscv/rvv/base/overloaded_rv32_vfadd.c index bea35a1..dd18359 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/base/overloaded_rv32_vfadd.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/overloaded_rv32_vfadd.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv32gcv_zvfh -mabi=ilp32 -O3 -Wno-psabi" } */ +/* { dg-options "-march=rv32gcv_zvfh -mabi=ilp32 -O3" } */ #include "overloaded_vfadd.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/overloaded_rv32_vget_vset.c b/gcc/testsuite/gcc.target/riscv/rvv/base/overloaded_rv32_vget_vset.c index 6b0ba14..1bd091b 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/base/overloaded_rv32_vget_vset.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/overloaded_rv32_vget_vset.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv32gcv_zvfh -mabi=ilp32 -O3 -Wno-psabi" } */ +/* { dg-options "-march=rv32gcv_zvfh -mabi=ilp32 -O3" } */ #include "overloaded_vget_vset.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/overloaded_rv32_vloxseg2ei16.c b/gcc/testsuite/gcc.target/riscv/rvv/base/overloaded_rv32_vloxseg2ei16.c index a20e4a3..3bec715 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/base/overloaded_rv32_vloxseg2ei16.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/overloaded_rv32_vloxseg2ei16.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv32gcv_zvfh -mabi=ilp32 -O3 -Wno-psabi" } */ +/* { dg-options "-march=rv32gcv_zvfh -mabi=ilp32 -O3" } */ #include "overloaded_vloxseg2ei16.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/overloaded_rv32_vmv.c b/gcc/testsuite/gcc.target/riscv/rvv/base/overloaded_rv32_vmv.c index 237b34d..8a87b91 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/base/overloaded_rv32_vmv.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/overloaded_rv32_vmv.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv32gcv_zvfh -mabi=ilp32 -O3 -Wno-psabi" } */ +/* { dg-options "-march=rv32gcv_zvfh -mabi=ilp32 -O3" } */ #include "overloaded_vmv.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/overloaded_rv32_vreinterpret.c b/gcc/testsuite/gcc.target/riscv/rvv/base/overloaded_rv32_vreinterpret.c index 42d5058..d5d80c0 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/base/overloaded_rv32_vreinterpret.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/overloaded_rv32_vreinterpret.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv32gcv_zvfh -mabi=ilp32 -O3 -Wno-psabi" } */ +/* { dg-options "-march=rv32gcv_zvfh -mabi=ilp32 -O3" } */ #include "overloaded_vreinterpret.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/overloaded_rv64_vadd.c b/gcc/testsuite/gcc.target/riscv/rvv/base/overloaded_rv64_vadd.c index c4555e3..390e2e5 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/base/overloaded_rv64_vadd.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/overloaded_rv64_vadd.c @@ -1,4 +1,4 @@ -/* { dg-options "-march=rv64gcv_zvfh -mabi=lp64 -O3 -Wno-psabi" } */ +/* { dg-options "-march=rv64gcv_zvfh -mabi=lp64 -O3" } */ #include "overloaded_vadd.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/overloaded_rv64_vfadd.c b/gcc/testsuite/gcc.target/riscv/rvv/base/overloaded_rv64_vfadd.c index ca98136..bf540c6 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/base/overloaded_rv64_vfadd.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/overloaded_rv64_vfadd.c @@ -1,4 +1,4 @@ -/* { dg-options "-march=rv64gcv_zvfh -mabi=lp64 -O3 -Wno-psabi" } */ +/* { dg-options "-march=rv64gcv_zvfh -mabi=lp64 -O3" } */ #include "overloaded_vfadd.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/overloaded_rv64_vget_vset.c b/gcc/testsuite/gcc.target/riscv/rvv/base/overloaded_rv64_vget_vset.c index 1cb4225..a6a05c1 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/base/overloaded_rv64_vget_vset.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/overloaded_rv64_vget_vset.c @@ -1,4 +1,4 @@ -/* { dg-options "-march=rv64gcv_zvfh -mabi=lp64 -O3 -Wno-psabi" } */ +/* { dg-options "-march=rv64gcv_zvfh -mabi=lp64 -O3" } */ #include "overloaded_vget_vset.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/overloaded_rv64_vloxseg2ei16.c b/gcc/testsuite/gcc.target/riscv/rvv/base/overloaded_rv64_vloxseg2ei16.c index ea73170..d0b8be0 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/base/overloaded_rv64_vloxseg2ei16.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/overloaded_rv64_vloxseg2ei16.c @@ -1,4 +1,4 @@ -/* { dg-options "-march=rv64gcv_zvfh -mabi=lp64 -O3 -Wno-psabi" } */ +/* { dg-options "-march=rv64gcv_zvfh -mabi=lp64 -O3" } */ #include "overloaded_vloxseg2ei16.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/overloaded_rv64_vmv.c b/gcc/testsuite/gcc.target/riscv/rvv/base/overloaded_rv64_vmv.c index c5da6bb..50db15a 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/base/overloaded_rv64_vmv.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/overloaded_rv64_vmv.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gcv_zvfh -mabi=lp64 -O3 -Wno-psabi" } */ +/* { dg-options "-march=rv64gcv_zvfh -mabi=lp64 -O3" } */ #include "overloaded_vmv.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/overloaded_rv64_vreinterpret.c b/gcc/testsuite/gcc.target/riscv/rvv/base/overloaded_rv64_vreinterpret.c index 3b8399c..57ec538 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/base/overloaded_rv64_vreinterpret.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/overloaded_rv64_vreinterpret.c @@ -1,4 +1,4 @@ -/* { dg-options "-march=rv64gcv_zvfh -mabi=lp64 -O3 -Wno-psabi" } */ +/* { dg-options "-march=rv64gcv_zvfh -mabi=lp64 -O3" } */ #include "overloaded_vreinterpret.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/pr110109-2.c b/gcc/testsuite/gcc.target/riscv/rvv/base/pr110109-2.c index c1df69ac..e8b5bf8 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/base/pr110109-2.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/pr110109-2.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-O3 -march=rv32gcv -mabi=ilp32d -Wno-psabi" } */ +/* { dg-options "-O3 -march=rv32gcv -mabi=ilp32d" } */ #include "riscv_vector.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/pr110119-1.c b/gcc/testsuite/gcc.target/riscv/rvv/base/pr110119-1.c index c5d9b15..ca974da 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/base/pr110119-1.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/pr110119-1.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gcv -mabi=lp64d --param=riscv-autovec-preference=fixed-vlmax -Wno-psabi" } */ +/* { dg-options "-march=rv64gcv -mabi=lp64d --param=riscv-autovec-preference=fixed-vlmax" } */ #include "riscv_vector.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/pr110119-2.c b/gcc/testsuite/gcc.target/riscv/rvv/base/pr110119-2.c index 3dadc99..561b62c 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/base/pr110119-2.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/pr110119-2.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gczve32x -mabi=lp64d --param=riscv-autovec-preference=fixed-vlmax -Wno-psabi" } */ +/* { dg-options "-march=rv64gczve32x -mabi=lp64d --param=riscv-autovec-preference=fixed-vlmax" } */ #include <stdint-gcc.h> #include "riscv_vector.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/pr110265-1.c b/gcc/testsuite/gcc.target/riscv/rvv/base/pr110265-1.c index 2e4aeb5..a2531b8 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/base/pr110265-1.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/pr110265-1.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv32gc_zve32f -mabi=ilp32f -O3 -Wno-psabi" } */ +/* { dg-options "-march=rv32gc_zve32f -mabi=ilp32f -O3" } */ #include "pr110265-1.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/pr110265-2.c b/gcc/testsuite/gcc.target/riscv/rvv/base/pr110265-2.c index 7454c1c..6611d1a 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/base/pr110265-2.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/pr110265-2.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv32gc_zve64d -mabi=ilp32d -O3 -Wno-psabi" } */ +/* { dg-options "-march=rv32gc_zve64d -mabi=ilp32d -O3" } */ #include "pr110265-1.h" #include "pr110265-2.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/pr110265-3.c b/gcc/testsuite/gcc.target/riscv/rvv/base/pr110265-3.c index 0ed1fba..99593af 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/base/pr110265-3.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/pr110265-3.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv32gc_zve64f -mabi=ilp32f -O3 -Wno-psabi" } */ +/* { dg-options "-march=rv32gc_zve64f -mabi=ilp32f -O3" } */ #include "pr110265-1.h" #include "pr110265-2.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/pr110277-1.c b/gcc/testsuite/gcc.target/riscv/rvv/base/pr110277-1.c index 24a4ba3..fa0fa92 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/base/pr110277-1.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/pr110277-1.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv32gc_zve32f_zvfh -mabi=ilp32f -O3 -Wno-psabi" } */ +/* { dg-options "-march=rv32gc_zve32f_zvfh -mabi=ilp32f -O3" } */ #include "pr110277-1.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/pr110277-2.c b/gcc/testsuite/gcc.target/riscv/rvv/base/pr110277-2.c index 23d7361..0d564b8 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/base/pr110277-2.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/pr110277-2.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv32gc_zve64d_zvfh -mabi=ilp32d -O3 -Wno-psabi" } */ +/* { dg-options "-march=rv32gc_zve64d_zvfh -mabi=ilp32d -O3" } */ #include "pr110277-1.h" #include "pr110277-2.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/pr110299-1.c b/gcc/testsuite/gcc.target/riscv/rvv/base/pr110299-1.c index a903dde..c987d27 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/base/pr110299-1.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/pr110299-1.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv32gc_zve32f_zvfh -mabi=ilp32f -O3 -Wno-psabi" } */ +/* { dg-options "-march=rv32gc_zve32f_zvfh -mabi=ilp32f -O3" } */ #include "pr110299-1.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/pr110299-2.c b/gcc/testsuite/gcc.target/riscv/rvv/base/pr110299-2.c index 1254ace..b675e86 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/base/pr110299-2.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/pr110299-2.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv32gc_zve64d_zvfh -mabi=ilp32d -O3 -Wno-psabi" } */ +/* { dg-options "-march=rv32gc_zve64d_zvfh -mabi=ilp32d -O3" } */ #include "pr110299-1.h" #include "pr110299-2.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/pr110299-3.c b/gcc/testsuite/gcc.target/riscv/rvv/base/pr110299-3.c index 0f84c17..5d4833b 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/base/pr110299-3.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/pr110299-3.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv32gc_zve32f -mabi=ilp32f -O3 -Wno-psabi" } */ +/* { dg-options "-march=rv32gc_zve32f -mabi=ilp32f -O3" } */ #include "pr110299-3.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/pr110299-4.c b/gcc/testsuite/gcc.target/riscv/rvv/base/pr110299-4.c index 8297cd6..1754704 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/base/pr110299-4.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/pr110299-4.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv32gc_zve64d -mabi=ilp32d -O3 -Wno-psabi" } */ +/* { dg-options "-march=rv32gc_zve64d -mabi=ilp32d -O3" } */ #include "pr110299-3.h" #include "pr110299-4.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/pr111720-0.c b/gcc/testsuite/gcc.target/riscv/rvv/base/pr111720-0.c index a61e94a..2514869 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/base/pr111720-0.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/pr111720-0.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-O3 -march=rv64gcv -mabi=lp64d -ftree-vectorize --param=riscv-autovec-preference=fixed-vlmax -Wno-psabi" } */ +/* { dg-options "-O3 -march=rv64gcv -mabi=lp64d -ftree-vectorize --param=riscv-autovec-preference=fixed-vlmax" } */ #include "riscv_vector.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/pr111720-1.c b/gcc/testsuite/gcc.target/riscv/rvv/base/pr111720-1.c index 46efd73..7bb5a6f 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/base/pr111720-1.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/pr111720-1.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-O3 -march=rv64gcv -mabi=lp64d -ftree-vectorize --param=riscv-autovec-preference=fixed-vlmax -Wno-psabi" } */ +/* { dg-options "-O3 -march=rv64gcv -mabi=lp64d -ftree-vectorize --param=riscv-autovec-preference=fixed-vlmax" } */ #include "riscv_vector.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/pr111720-10.c b/gcc/testsuite/gcc.target/riscv/rvv/base/pr111720-10.c index 8bebac2..a4c8bc6 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/base/pr111720-10.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/pr111720-10.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-O3 -march=rv64gcv -mabi=lp64d -ftree-vectorize --param=riscv-autovec-preference=fixed-vlmax -Wno-psabi" } */ +/* { dg-options "-O3 -march=rv64gcv -mabi=lp64d -ftree-vectorize --param=riscv-autovec-preference=fixed-vlmax" } */ #include "riscv_vector.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/pr111720-2.c b/gcc/testsuite/gcc.target/riscv/rvv/base/pr111720-2.c index 47e4243..71f5696 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/base/pr111720-2.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/pr111720-2.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-O3 -march=rv64gcv -mabi=lp64d -ftree-vectorize --param=riscv-autovec-preference=fixed-vlmax -Wno-psabi" } */ +/* { dg-options "-O3 -march=rv64gcv -mabi=lp64d -ftree-vectorize --param=riscv-autovec-preference=fixed-vlmax" } */ #include "riscv_vector.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/pr111720-3.c b/gcc/testsuite/gcc.target/riscv/rvv/base/pr111720-3.c index 5331e54..e932d46 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/base/pr111720-3.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/pr111720-3.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-O3 -march=rv64gcv -mabi=lp64d -ftree-vectorize --param=riscv-autovec-preference=fixed-vlmax -Wno-psabi" } */ +/* { dg-options "-O3 -march=rv64gcv -mabi=lp64d -ftree-vectorize --param=riscv-autovec-preference=fixed-vlmax" } */ #include "riscv_vector.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/pr111720-4.c b/gcc/testsuite/gcc.target/riscv/rvv/base/pr111720-4.c index 0c728f9..8b12f9d 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/base/pr111720-4.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/pr111720-4.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-O3 -march=rv64gcv -mabi=lp64d -ftree-vectorize --param=riscv-autovec-preference=fixed-vlmax -Wno-psabi" } */ +/* { dg-options "-O3 -march=rv64gcv -mabi=lp64d -ftree-vectorize --param=riscv-autovec-preference=fixed-vlmax" } */ #include "riscv_vector.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/pr111720-5.c b/gcc/testsuite/gcc.target/riscv/rvv/base/pr111720-5.c index ccfc40c..5290527 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/base/pr111720-5.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/pr111720-5.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-O3 -march=rv64gcv -mabi=lp64d -ftree-vectorize --param=riscv-autovec-preference=fixed-vlmax -Wno-psabi" } */ +/* { dg-options "-O3 -march=rv64gcv -mabi=lp64d -ftree-vectorize --param=riscv-autovec-preference=fixed-vlmax" } */ #include "riscv_vector.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/pr111720-6.c b/gcc/testsuite/gcc.target/riscv/rvv/base/pr111720-6.c index ce7ddbb..f69fcbd 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/base/pr111720-6.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/pr111720-6.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-O3 -march=rv64gcv -mabi=lp64d -ftree-vectorize --param=riscv-autovec-preference=fixed-vlmax -Wno-psabi" } */ +/* { dg-options "-O3 -march=rv64gcv -mabi=lp64d -ftree-vectorize --param=riscv-autovec-preference=fixed-vlmax" } */ #include "riscv_vector.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/pr111720-7.c b/gcc/testsuite/gcc.target/riscv/rvv/base/pr111720-7.c index ac0100a..fb09ffc 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/base/pr111720-7.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/pr111720-7.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-O3 -march=rv64gcv -mabi=lp64d -ftree-vectorize --param=riscv-autovec-preference=fixed-vlmax -Wno-psabi" } */ +/* { dg-options "-O3 -march=rv64gcv -mabi=lp64d -ftree-vectorize --param=riscv-autovec-preference=fixed-vlmax" } */ #include "riscv_vector.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/pr111720-8.c b/gcc/testsuite/gcc.target/riscv/rvv/base/pr111720-8.c index b7ebef8..2d99c6f 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/base/pr111720-8.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/pr111720-8.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-O3 -march=rv64gcv -mabi=lp64d -ftree-vectorize --param=riscv-autovec-preference=fixed-vlmax -Wno-psabi" } */ +/* { dg-options "-O3 -march=rv64gcv -mabi=lp64d -ftree-vectorize --param=riscv-autovec-preference=fixed-vlmax" } */ #include "riscv_vector.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/pr111720-9.c b/gcc/testsuite/gcc.target/riscv/rvv/base/pr111720-9.c index 21fed06..7216631 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/base/pr111720-9.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/pr111720-9.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-O3 -march=rv64gcv -mabi=lp64d -ftree-vectorize --param=riscv-autovec-preference=fixed-vlmax -Wno-psabi" } */ +/* { dg-options "-O3 -march=rv64gcv -mabi=lp64d -ftree-vectorize --param=riscv-autovec-preference=fixed-vlmax" } */ #include "riscv_vector.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/pr111935.c b/gcc/testsuite/gcc.target/riscv/rvv/base/pr111935.c index 0b936d8..a210d6b 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/base/pr111935.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/pr111935.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gcv -mabi=lp64d -O0 -Wno-psabi" } */ +/* { dg-options "-march=rv64gcv -mabi=lp64d -O0" } */ #include "riscv_vector.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/scalar-move-merged-run-1.c b/gcc/testsuite/gcc.target/riscv/rvv/base/scalar-move-merged-run-1.c index 7207010..38d0afa 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/base/scalar-move-merged-run-1.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/scalar-move-merged-run-1.c @@ -1,5 +1,5 @@ /* { dg-do run { target { riscv_v } } } */ -/* { dg-options "-O3 -Wno-psabi" } */ +/* { dg-options "-O3" } */ #define TEST_VAL 2 diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/scalar_move-9.c b/gcc/testsuite/gcc.target/riscv/rvv/base/scalar_move-9.c index 9c310bb..80ee1b5 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/base/scalar_move-9.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/scalar_move-9.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv32gcv -mabi=ilp32d -fno-schedule-insns -fno-schedule-insns2 -O3 -Wno-psabi" } */ +/* { dg-options "-march=rv32gcv -mabi=ilp32d -fno-schedule-insns -fno-schedule-insns2 -O3" } */ #include "riscv_vector.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/simplify-vdiv.c b/gcc/testsuite/gcc.target/riscv/rvv/base/simplify-vdiv.c index 0830006..b9fcfe7 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/base/simplify-vdiv.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/simplify-vdiv.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gcv -mabi=lp64 -O3 -Wno-psabi" } */ +/* { dg-options "-march=rv64gcv -mabi=lp64 -O3" } */ #include "riscv_vector.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/simplify-vrsub.c b/gcc/testsuite/gcc.target/riscv/rvv/base/simplify-vrsub.c index df87ed9..f669c68 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/base/simplify-vrsub.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/simplify-vrsub.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gcv -mabi=lp64 -O3 -Wno-psabi" } */ +/* { dg-options "-march=rv64gcv -mabi=lp64 -O3" } */ #include "riscv_vector.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/spill-10.c b/gcc/testsuite/gcc.target/riscv/rvv/base/spill-10.c index 89c96c8..d37857e 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/base/spill-10.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/spill-10.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv32gcv -mabi=ilp32 -mpreferred-stack-boundary=3 -fno-schedule-insns -fno-schedule-insns2 -O3 -Wno-psabi" } */ +/* { dg-options "-march=rv32gcv -mabi=ilp32 -mpreferred-stack-boundary=3 -fno-schedule-insns -fno-schedule-insns2 -O3" } */ /* { dg-final { check-function-bodies "**" "" } } */ #include "riscv_vector.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/spill-11.c b/gcc/testsuite/gcc.target/riscv/rvv/base/spill-11.c index 484a251..d9362ec 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/base/spill-11.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/spill-11.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-msave-restore -march=rv32gc_zve64d -mabi=ilp32 -msave-restore -fno-schedule-insns -fno-schedule-insns2 -O3 -Wno-psabi" } */ +/* { dg-options "-msave-restore -march=rv32gc_zve64d -mabi=ilp32 -msave-restore -fno-schedule-insns -fno-schedule-insns2 -O3" } */ /* { dg-final { check-function-bodies "**" "" } } */ #include "riscv_vector.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/spill-9.c b/gcc/testsuite/gcc.target/riscv/rvv/base/spill-9.c index 5464a29..ec67357 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/base/spill-9.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/spill-9.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv32gc_zve64d -mabi=ilp32 -fno-schedule-insns -fno-schedule-insns2 -O3 -Wno-psabi" } */ +/* { dg-options "-march=rv32gc_zve64d -mabi=ilp32 -fno-schedule-insns -fno-schedule-insns2 -O3" } */ /* { dg-final { check-function-bodies "**" "" } } */ #include "riscv_vector.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/tuple-intrinsic.c b/gcc/testsuite/gcc.target/riscv/rvv/base/tuple-intrinsic.c index 494e40b..5316b4e 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/base/tuple-intrinsic.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/tuple-intrinsic.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gcv_zvfh -mabi=lp64d -Wno-psabi -O3 -fno-schedule-insns -fno-schedule-insns2" } */ +/* { dg-options "-march=rv64gcv_zvfh -mabi=lp64d -O3 -fno-schedule-insns -fno-schedule-insns2" } */ #include "riscv_vector.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/tuple_vundefined.c b/gcc/testsuite/gcc.target/riscv/rvv/base/tuple_vundefined.c index 174860d..893e5a3 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/base/tuple_vundefined.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/tuple_vundefined.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gcv_zvfh -mabi=lp64 -O3 -Wno-psabi" } */ +/* { dg-options "-march=rv64gcv_zvfh -mabi=lp64 -O3" } */ #include "riscv_vector.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/vcreate.c b/gcc/testsuite/gcc.target/riscv/rvv/base/vcreate.c index 158eec0..7950990 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/base/vcreate.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/vcreate.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gcv_zvfh -mabi=lp64 -O3 -Wno-psabi" } */ +/* { dg-options "-march=rv64gcv_zvfh -mabi=lp64 -O3" } */ #include "riscv_vector.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/vector-abi-1.c b/gcc/testsuite/gcc.target/riscv/rvv/base/vector-abi-1.c deleted file mode 100644 index 114ee6d..0000000 --- a/gcc/testsuite/gcc.target/riscv/rvv/base/vector-abi-1.c +++ /dev/null @@ -1,14 +0,0 @@ -/* { dg-do compile } */ -/* { dg-options "-O0 -march=rv64gcv -mabi=lp64d" } */ - -#include "riscv_vector.h" - -void -fun (vint32m1_t a) { } /* { dg-warning "the vector type" } */ - -void -bar () -{ - vint32m1_t a; - fun (a); -} diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/vector-abi-2.c b/gcc/testsuite/gcc.target/riscv/rvv/base/vector-abi-2.c deleted file mode 100644 index 0b24ccb..0000000 --- a/gcc/testsuite/gcc.target/riscv/rvv/base/vector-abi-2.c +++ /dev/null @@ -1,15 +0,0 @@ -/* { dg-do compile } */ -/* { dg-options "-march=rv64gcv -mabi=lp64d" } */ -/* { dg-skip-if "" { *-*-* } { "-flto" } { "" } } */ - -#include "riscv_vector.h" - -vint32m1_t -fun (vint32m1_t* a) { return *a; } /* { dg-warning "the vector type" } */ - -void -bar () -{ - vint32m1_t a; - fun (&a); -} diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/vector-abi-3.c b/gcc/testsuite/gcc.target/riscv/rvv/base/vector-abi-3.c deleted file mode 100644 index 844a5db..0000000 --- a/gcc/testsuite/gcc.target/riscv/rvv/base/vector-abi-3.c +++ /dev/null @@ -1,14 +0,0 @@ -/* { dg-do compile } */ -/* { dg-options "-march=rv64gcv -mabi=lp64d" } */ - -#include "riscv_vector.h" - -vint32m1_t* -fun (vint32m1_t* a) { return a; } /* { dg-bogus "the vector type" } */ - -void -bar () -{ - vint32m1_t a; - fun (&a); -} diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/vector-abi-4.c b/gcc/testsuite/gcc.target/riscv/rvv/base/vector-abi-4.c deleted file mode 100644 index a5dc2df..0000000 --- a/gcc/testsuite/gcc.target/riscv/rvv/base/vector-abi-4.c +++ /dev/null @@ -1,16 +0,0 @@ -/* { dg-do compile } */ -/* { dg-options "-march=rv64gcv -mabi=lp64d" } */ - -#include "riscv_vector.h" - -typedef int v4si __attribute__ ((vector_size (16))); - -v4si -fun (v4si a) { return a; } /* { dg-bogus "the vector type" } */ - -void -bar () -{ - v4si a; - fun (a); -} diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/vector-abi-5.c b/gcc/testsuite/gcc.target/riscv/rvv/base/vector-abi-5.c deleted file mode 100644 index 9dc6951..0000000 --- a/gcc/testsuite/gcc.target/riscv/rvv/base/vector-abi-5.c +++ /dev/null @@ -1,20 +0,0 @@ -/* { dg-do compile } */ -/* { dg-options "-march=rv64gcv -mabi=lp64d" } */ - -typedef int v4si __attribute__ ((vector_size (16))); -struct A { int a; int b; }; - -void foo (int b); - -void -fun (struct A a) { - - foo (a.b); -} /* { dg-bogus "the vector type" } */ - -void -bar () -{ - struct A a; - fun (a); -} diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/vector-abi-6.c b/gcc/testsuite/gcc.target/riscv/rvv/base/vector-abi-6.c deleted file mode 100644 index 3a65f2c..0000000 --- a/gcc/testsuite/gcc.target/riscv/rvv/base/vector-abi-6.c +++ /dev/null @@ -1,20 +0,0 @@ -/* { dg-do compile } */ -/* { dg-options "-march=rv64gcv -mabi=lp64d" } */ -#include "riscv_vector.h" - -void -foo(int32_t *in1, int32_t *in2, int32_t *in3, int32_t *out, - size_t n, int cond) { - size_t vl; - if (cond) - vl = __riscv_vsetvlmax_e32m1(); - else - vl = __riscv_vsetvlmax_e16mf2(); - for (size_t i = 0; i < n; i += 1) - { - vint32m1_t a = __riscv_vle32_v_i32m1(in1, vl); /* { dg-bogus "the vector type" } */ - vint32m1_t b = __riscv_vle32_v_i32m1_tu(a, in2, vl); - vint32m1_t c = __riscv_vle32_v_i32m1_tu(b, in3, vl); - __riscv_vse32_v_i32m1(out, c, vl); - } -} diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/vector-abi-7.c b/gcc/testsuite/gcc.target/riscv/rvv/base/vector-abi-7.c deleted file mode 100644 index 2795fd4..0000000 --- a/gcc/testsuite/gcc.target/riscv/rvv/base/vector-abi-7.c +++ /dev/null @@ -1,14 +0,0 @@ -/* { dg-do compile } */ -/* { dg-options "-O0 -march=rv64gcv -mabi=lp64d" } */ - -#include "riscv_vector.h" - -void -fun (vint32m1x3_t a) { } /* { dg-warning "the vector type" } */ - -void -bar () -{ - vint32m1x3_t a; - fun (a); -} diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/vector-abi-8.c b/gcc/testsuite/gcc.target/riscv/rvv/base/vector-abi-8.c deleted file mode 100644 index 9cf68d4..0000000 --- a/gcc/testsuite/gcc.target/riscv/rvv/base/vector-abi-8.c +++ /dev/null @@ -1,14 +0,0 @@ -/* { dg-do compile } */ -/* { dg-options "-march=rv64gcv -mabi=lp64d" } */ - -#include "riscv_vector.h" - -vint32m1x3_t* -fun (vint32m1x3_t* a) { return a; } /* { dg-bogus "the vector type" } */ - -void -bar () -{ - vint32m1x3_t a; - fun (&a); -} diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/vlmul_ext-1.c b/gcc/testsuite/gcc.target/riscv/rvv/base/vlmul_ext-1.c index 51f4fac..501d98c 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/base/vlmul_ext-1.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/vlmul_ext-1.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gcv -mabi=lp64d -O3 -fno-schedule-insns -fno-schedule-insns2 -Wno-psabi" } */ +/* { dg-options "-march=rv64gcv -mabi=lp64d -O3 -fno-schedule-insns -fno-schedule-insns2" } */ #include <riscv_vector.h> diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/vlmul_ext-2.c b/gcc/testsuite/gcc.target/riscv/rvv/base/vlmul_ext-2.c index 3749d97..2b088b5 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/base/vlmul_ext-2.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/vlmul_ext-2.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gcv -mabi=lp64d -O0 -Wno-psabi" } */ +/* { dg-options "-march=rv64gcv -mabi=lp64d -O0" } */ #include "riscv_vector.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/vslide1down-1.c b/gcc/testsuite/gcc.target/riscv/rvv/base/vslide1down-1.c index 541745b..78cd638 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/base/vslide1down-1.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/vslide1down-1.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv32gc_zve64x -mabi=ilp32d -Wno-psabi -O3 -fno-schedule-insns -fno-schedule-insns2" } */ +/* { dg-options "-march=rv32gc_zve64x -mabi=ilp32d -O3 -fno-schedule-insns -fno-schedule-insns2" } */ #include "riscv_vector.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/vslide1down-2.c b/gcc/testsuite/gcc.target/riscv/rvv/base/vslide1down-2.c index 9b5a240..4e26a57 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/base/vslide1down-2.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/vslide1down-2.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv32gc_zve64d -mabi=ilp32d -Wno-psabi -O3 -fno-schedule-insns -fno-schedule-insns2" } */ +/* { dg-options "-march=rv32gc_zve64d -mabi=ilp32d -O3 -fno-schedule-insns -fno-schedule-insns2" } */ #include "riscv_vector.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/vslide1down-3.c b/gcc/testsuite/gcc.target/riscv/rvv/base/vslide1down-3.c index 7b05c85..dec2512 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/base/vslide1down-3.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/vslide1down-3.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv32gc_zve64f -mabi=ilp32d -Wno-psabi -O3 -fno-schedule-insns -fno-schedule-insns2" } */ +/* { dg-options "-march=rv32gc_zve64f -mabi=ilp32d -O3 -fno-schedule-insns -fno-schedule-insns2" } */ #include "riscv_vector.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/vslide1up-1.c b/gcc/testsuite/gcc.target/riscv/rvv/base/vslide1up-1.c index 74e8e5e..5b9afa4 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/base/vslide1up-1.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/vslide1up-1.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv32gc_zve64x -mabi=ilp32d -Wno-psabi -O3 -fno-schedule-insns -fno-schedule-insns2" } */ +/* { dg-options "-march=rv32gc_zve64x -mabi=ilp32d -O3 -fno-schedule-insns -fno-schedule-insns2" } */ #include "riscv_vector.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/vslide1up-2.c b/gcc/testsuite/gcc.target/riscv/rvv/base/vslide1up-2.c index e7e2ee9..e989a06 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/base/vslide1up-2.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/vslide1up-2.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv32gc_zve64d -mabi=ilp32d -Wno-psabi -O3 -fno-schedule-insns -fno-schedule-insns2" } */ +/* { dg-options "-march=rv32gc_zve64d -mabi=ilp32d -O3 -fno-schedule-insns -fno-schedule-insns2" } */ #include "riscv_vector.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/vslide1up-3.c b/gcc/testsuite/gcc.target/riscv/rvv/base/vslide1up-3.c index b0b3af2..f91a02c 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/base/vslide1up-3.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/vslide1up-3.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv32gc_zve64f -mabi=ilp32d -Wno-psabi -O3 -fno-schedule-insns -fno-schedule-insns2" } */ +/* { dg-options "-march=rv32gc_zve64f -mabi=ilp32d -O3 -fno-schedule-insns -fno-schedule-insns2" } */ #include "riscv_vector.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/zero_base_load_store_optimization.c b/gcc/testsuite/gcc.target/riscv/rvv/base/zero_base_load_store_optimization.c index b27e5cc..fbcfb7b 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/base/zero_base_load_store_optimization.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/zero_base_load_store_optimization.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gcv -mabi=lp64 -O3 -Wno-psabi" } */ +/* { dg-options "-march=rv64gcv -mabi=lp64 -O3" } */ #include "riscv_vector.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/zvbb-intrinsic.c b/gcc/testsuite/gcc.target/riscv/rvv/base/zvbb-intrinsic.c index b7e25bfe..993f4d0 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/base/zvbb-intrinsic.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/zvbb-intrinsic.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gc_zvbb_zve64x -mabi=lp64d -Wno-psabi" } */ +/* { dg-options "-march=rv64gc_zvbb_zve64x -mabi=lp64d" } */ #include "riscv_vector.h" vuint8mf8_t test_vandn_vv_u8mf8(vuint8mf8_t vs2, vuint8mf8_t vs1, size_t vl) { diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/zvbb_vandn_vx_constraint.c b/gcc/testsuite/gcc.target/riscv/rvv/base/zvbb_vandn_vx_constraint.c index b3e879e..0d62609 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/base/zvbb_vandn_vx_constraint.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/zvbb_vandn_vx_constraint.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv32gc_zvbb_zve64x -mabi=ilp32 -O3 -Wno-psabi" } */ +/* { dg-options "-march=rv32gc_zvbb_zve64x -mabi=ilp32 -O3" } */ #include "riscv_vector.h" vuint64m1_t test_vandn_vx_u64m1(vuint64m1_t vs2, uint64_t rs1, size_t vl) { diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/zvbc-intrinsic.c b/gcc/testsuite/gcc.target/riscv/rvv/base/zvbc-intrinsic.c index ae2a5b6..6975ae4 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/base/zvbc-intrinsic.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/zvbc-intrinsic.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gc_zvbc -mabi=lp64d -O2 -Wno-psabi" } */ +/* { dg-options "-march=rv64gc_zvbc -mabi=lp64d -O2" } */ #include "riscv_vector.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/zvbc_vx_constraint-1.c b/gcc/testsuite/gcc.target/riscv/rvv/base/zvbc_vx_constraint-1.c index 8c17163..1bf11e4 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/base/zvbc_vx_constraint-1.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/zvbc_vx_constraint-1.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv32gc_zvbc -mabi=ilp32 -O3 -Wno-psabi" } */ +/* { dg-options "-march=rv32gc_zvbc -mabi=ilp32 -O3" } */ #include "riscv_vector.h" vuint64m1_t test_vclmul_vx_u64m1(vuint64m1_t vs2, uint64_t rs1, size_t vl) { diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/zvbc_vx_constraint-2.c b/gcc/testsuite/gcc.target/riscv/rvv/base/zvbc_vx_constraint-2.c index 9ee70d7..3fb1466 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/base/zvbc_vx_constraint-2.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/zvbc_vx_constraint-2.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gc_zvbc -mabi=lp64d -O3 -Wno-psabi" } */ +/* { dg-options "-march=rv64gc_zvbc -mabi=lp64d -O3" } */ #include "riscv_vector.h" vuint64m1_t test_vclmul_vx_u64m1_extend(vuint64m1_t vs2, uint32_t rs1, size_t vl) { diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/zvfh-intrinsic.c b/gcc/testsuite/gcc.target/riscv/rvv/base/zvfh-intrinsic.c index 0e7c7cd..c951644 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/base/zvfh-intrinsic.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/zvfh-intrinsic.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gcv_zvfh -mabi=lp64 -O3 -Wno-psabi" } */ +/* { dg-options "-march=rv64gcv_zvfh -mabi=lp64 -O3" } */ #include "riscv_vector.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/zvfh-over-zvfhmin.c b/gcc/testsuite/gcc.target/riscv/rvv/base/zvfh-over-zvfhmin.c index 9ae7966..1d82cc8 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/base/zvfh-over-zvfhmin.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/zvfh-over-zvfhmin.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gcv_zvfh -mabi=lp64 -O3 -Wno-psabi" } */ +/* { dg-options "-march=rv64gcv_zvfh -mabi=lp64 -O3" } */ #include "riscv_vector.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/zvfhmin-intrinsic.c b/gcc/testsuite/gcc.target/riscv/rvv/base/zvfhmin-intrinsic.c index 500748b..193902d 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/base/zvfhmin-intrinsic.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/zvfhmin-intrinsic.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gcv_zvfhmin -mabi=lp64 -O3 -Wno-psabi" } */ +/* { dg-options "-march=rv64gcv_zvfhmin -mabi=lp64 -O3" } */ #include "riscv_vector.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/zvkg-intrinsic.c b/gcc/testsuite/gcc.target/riscv/rvv/base/zvkg-intrinsic.c index fa68310..e60785a 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/base/zvkg-intrinsic.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/zvkg-intrinsic.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gc_zvkg_zve64x -mabi=lp64d -O2 -Wno-psabi" } */ +/* { dg-options "-march=rv64gc_zvkg_zve64x -mabi=lp64d -O2" } */ #include "riscv_vector.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/zvkned-intrinsic.c b/gcc/testsuite/gcc.target/riscv/rvv/base/zvkned-intrinsic.c index 4141573..c29a0f6 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/base/zvkned-intrinsic.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/zvkned-intrinsic.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gc_zvkned_zve64x -mabi=lp64d -O2 -Wno-psabi" } */ +/* { dg-options "-march=rv64gc_zvkned_zve64x -mabi=lp64d -O2" } */ #include "riscv_vector.h" vuint32mf2_t test_vaesdf_vv_u32mf2(vuint32mf2_t vd, vuint32mf2_t vs2, size_t vl) { diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/zvknha-intrinsic.c b/gcc/testsuite/gcc.target/riscv/rvv/base/zvknha-intrinsic.c index 40009ad..f50828e 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/base/zvknha-intrinsic.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/zvknha-intrinsic.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gc_zvknha_zve64x -mabi=lp64d -O2 -Wno-psabi" } */ +/* { dg-options "-march=rv64gc_zvknha_zve64x -mabi=lp64d -O2" } */ #include "riscv_vector.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/zvknhb-intrinsic.c b/gcc/testsuite/gcc.target/riscv/rvv/base/zvknhb-intrinsic.c index 78aebeb..1d23903 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/base/zvknhb-intrinsic.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/zvknhb-intrinsic.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gc_zvknhb -mabi=lp64d -O2 -Wno-psabi" } */ +/* { dg-options "-march=rv64gc_zvknhb -mabi=lp64d -O2" } */ #include "riscv_vector.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/zvksed-intrinsic.c b/gcc/testsuite/gcc.target/riscv/rvv/base/zvksed-intrinsic.c index b655fe8..ad23239 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/base/zvksed-intrinsic.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/zvksed-intrinsic.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gc_zvksed_zve64x -mabi=lp64d -O2 -Wno-psabi" } */ +/* { dg-options "-march=rv64gc_zvksed_zve64x -mabi=lp64d -O2" } */ #include "riscv_vector.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/zvksh-intrinsic.c b/gcc/testsuite/gcc.target/riscv/rvv/base/zvksh-intrinsic.c index 353e4e7..77d82c0 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/base/zvksh-intrinsic.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/zvksh-intrinsic.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gc_zvksh_zve64x -mabi=lp64d -O2 -Wno-psabi" } */ +/* { dg-options "-march=rv64gc_zvksh_zve64x -mabi=lp64d -O2" } */ #include "riscv_vector.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/vsetvl/vsetvl-1.c b/gcc/testsuite/gcc.target/riscv/rvv/vsetvl/vsetvl-1.c index c3519ce..be31df1 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/vsetvl/vsetvl-1.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/vsetvl/vsetvl-1.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "--param=riscv-autovec-preference=scalable -march=rv32gcv -mabi=ilp32 -fno-schedule-insns -fno-schedule-insns2 -Wno-psabi" } */ +/* { dg-options "--param=riscv-autovec-preference=scalable -march=rv32gcv -mabi=ilp32 -fno-schedule-insns -fno-schedule-insns2" } */ #include "riscv_vector.h" diff --git a/gcc/testsuite/gcc.target/riscv/scalar_bitmanip_intrinsic-32.c b/gcc/testsuite/gcc.target/riscv/scalar_bitmanip_intrinsic-32.c new file mode 100644 index 0000000..56878a3 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/scalar_bitmanip_intrinsic-32.c @@ -0,0 +1,97 @@ +/* { dg-do compile } */ +/* { dg-require-effective-target rv32 } */ +/* { dg-options "-march=rv32gc_zbb_zbc_zbkb_zbkc_zbkx -mabi=ilp32d" } */ +/* { dg-skip-if "" { *-*-* } { "-g" "-flto"} } */ + +#include "riscv_bitmanip.h" + +unsigned foo1 (uint32_t x) +{ + return __riscv_clz_32 (x); +} + +unsigned foo2 (uint32_t x) +{ + return __riscv_ctz_32 (x); +} + +unsigned foo3 (uint32_t x) +{ + return __riscv_cpop_32 (x); +} + +uint32_t foo4 (uint32_t x) +{ + return __riscv_orc_b_32 (x); +} + +uint32_t foo5 (uint32_t x, uint32_t shamt) +{ + return __riscv_ror_32 (x,shamt); +} + +uint32_t foo6 (uint32_t x, uint32_t shamt) +{ + return __riscv_rol_32 (x,shamt); +} + +uint32_t foo7 (uint32_t x) +{ + return __riscv_rev8_32 (x); +} + +uint32_t foo8 (uint32_t x) +{ + return __riscv_brev8_32 (x); +} + +uint32_t foo9 (uint32_t x) +{ + return __riscv_zip_32 (x); +} + +uint32_t foo10 (uint32_t x) +{ + return __riscv_unzip_32 (x); +} + +uint32_t foo11 (uint32_t rs1,uint32_t rs2) +{ + return __riscv_clmul_32 (rs1,rs2); +} + +uint32_t foo12 (uint32_t rs1,uint32_t rs2) +{ + return __riscv_clmulh_32 (rs1,rs2); +} + +uint32_t foo13 (uint32_t rs1,uint32_t rs2) +{ + return __riscv_clmulr_32 (rs1,rs2); +} + +uint32_t foo14 (uint32_t rs1,uint32_t rs2) +{ + return __riscv_xperm4_32 (rs1,rs2); +} + +uint32_t foo15 (uint32_t rs1,uint32_t rs2) +{ + return __riscv_xperm8_32 (rs1,rs2); +} + +/* { dg-final { scan-assembler-times "clz" 1 } } */ +/* { dg-final { scan-assembler-times "ctz" 1 } } */ +/* { dg-final { scan-assembler-times "cpop" 1 } } */ +/* { dg-final { scan-assembler-times "orc.b" 1 } } */ +/* { dg-final { scan-assembler-times "ror" 1 } } */ +/* { dg-final { scan-assembler-times "rol" 1 } } */ +/* { dg-final { scan-assembler-times {\mrev8} 1 } } */ +/* { dg-final { scan-assembler-times {\mbrev8} 1 } } */ +/* { dg-final { scan-assembler-times {\mzip} 1 } } */ +/* { dg-final { scan-assembler-times {\munzip} 1 } } */ +/* { dg-final { scan-assembler-times "clmul\t" 1 } } */ +/* { dg-final { scan-assembler-times "clmulh" 1 } } */ +/* { dg-final { scan-assembler-times "clmulr" 1 } } */ +/* { dg-final { scan-assembler-times "xperm4" 1 } } */ +/* { dg-final { scan-assembler-times "xperm8" 1 } } */ diff --git a/gcc/testsuite/gcc.target/riscv/scalar_bitmanip_intrinsic-64-emulated.c b/gcc/testsuite/gcc.target/riscv/scalar_bitmanip_intrinsic-64-emulated.c new file mode 100644 index 0000000..739894a --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/scalar_bitmanip_intrinsic-64-emulated.c @@ -0,0 +1,33 @@ +/* { dg-do compile } */ +/* { dg-require-effective-target rv64 } */ +/* { dg-options "-march=rv64gc_zbb_zbc_zbkb_zbkc -mabi=lp64d " } */ +/* { dg-skip-if "" { *-*-* } { "-g" "-O0" "-flto"} } */ + +#include "riscv_bitmanip.h" + +uint32_t foo (uint32_t rs1) +{ + return __riscv_rev8_32 (rs1); +} + +int32_t foo2(uint32_t rs1) +{ + return __riscv_brev8_32 (rs1); +} + +uint32_t foo3 (uint32_t rs1) +{ + return __riscv_orc_b_32 (rs1); + +} + +uint32_t foo4 (uint32_t rs1) +{ + return __riscv_clmul_32 (rs1,rs1); +} + +/* { dg-final { scan-assembler-times {\mrev8} 1 } } */ +/* { dg-final { scan-assembler-times "brev8" 1 } } */ +/* { dg-final { scan-assembler-times "clmul" 1 } } */ +/* { dg-final { scan-assembler-times "orc.b" 1 } } */ +/* { dg-final { scan-assembler-times "sext.w" 3 } } */ diff --git a/gcc/testsuite/gcc.target/riscv/scalar_bitmanip_intrinsic-64.c b/gcc/testsuite/gcc.target/riscv/scalar_bitmanip_intrinsic-64.c new file mode 100644 index 0000000..e0da9df --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/scalar_bitmanip_intrinsic-64.c @@ -0,0 +1,115 @@ +/* { dg-do compile } */ +/* { dg-require-effective-target rv64 } */ +/* { dg-options "-march=rv64gc_zbb_zbc_zbkb_zbkc_zbkx -mabi=lp64d" } */ +/* { dg-skip-if "" { *-*-* } { "-g" "-flto"} } */ + +#include "riscv_bitmanip.h" + +unsigned foo1 (uint32_t x) +{ + return __riscv_clz_32 (x); +} + +unsigned foo2 (uint32_t x) +{ + return __riscv_ctz_32 (x); +} + +unsigned foo3 (uint32_t x) +{ + return __riscv_cpop_32 (x); +} + +uint32_t foo4 (uint32_t x, uint8_t shamt) +{ + return __riscv_ror_32 (x,shamt); +} + +uint32_t foo5 (uint32_t x, uint8_t shamt) +{ + return __riscv_rol_32 (x,shamt); +} + +unsigned foo6 (uint64_t x) +{ + return __riscv_clz_64 (x); +} + +unsigned foo7 (uint64_t x) +{ + return __riscv_ctz_64 (x); +} + +unsigned foo8 (uint64_t x) +{ + return __riscv_cpop_64 (x); +} + +uint64_t foo9 (uint64_t x) +{ + return __riscv_orc_b_64 (x); +} + +uint64_t foo10 (uint64_t rs1, uint8_t rs2) +{ + return __riscv_ror_64 (rs1,rs2); +} + +uint64_t foo11 (uint64_t rs1, uint8_t rs2) +{ + return __riscv_rol_64 (rs1,rs2); +} + +uint64_t foo12 (uint64_t x) +{ + return __riscv_rev8_64 (x); +} + +uint64_t foo13 (uint64_t x) +{ + return __riscv_brev8_64 (x); +} + +uint64_t foo14 (uint64_t rs1,uint64_t rs2) +{ + return __riscv_clmul_64 (rs1,rs2); +} + +uint64_t foo15 (uint64_t rs1,uint64_t rs2) +{ + return __riscv_clmulh_64 (rs1,rs2); +} + +uint64_t foo16 (uint64_t rs1,uint64_t rs2) +{ + return __riscv_clmulr_64 (rs1,rs2); +} + +uint64_t foo17 (uint64_t rs1,uint64_t rs2) +{ + return __riscv_xperm4_64 (rs1,rs2); +} + +uint64_t foo18 (uint64_t rs1,uint64_t rs2) +{ + return __riscv_xperm8_64 (rs1,rs2); +} + +/* { dg-final { scan-assembler-times "clzw" 1 } } */ +/* { dg-final { scan-assembler-times "ctzw" 1 } } */ +/* { dg-final { scan-assembler-times "cpopw" 1 } } */ +/* { dg-final { scan-assembler-times "rorw" 1 } } */ +/* { dg-final { scan-assembler-times "rolw" 1 } } */ +/* { dg-final { scan-assembler-times "clz\t" 1 } } */ +/* { dg-final { scan-assembler-times "ctz\t" 1 } } */ +/* { dg-final { scan-assembler-times "cpop\t" 1 } } */ +/* { dg-final { scan-assembler-times "orc.b" 1 } } */ +/* { dg-final { scan-assembler-times "ror\t" 1 } } */ +/* { dg-final { scan-assembler-times "rol\t" 1 } } */ +/* { dg-final { scan-assembler-times {\mrev8} 1 } } */ +/* { dg-final { scan-assembler-times {\mbrev8} 1 } } */ +/* { dg-final { scan-assembler-times "clmul\t" 1 } } */ +/* { dg-final { scan-assembler-times "clmulh" 1 } } */ +/* { dg-final { scan-assembler-times "clmulr" 1 } } */ +/* { dg-final { scan-assembler-times "xperm4" 1 } } */ +/* { dg-final { scan-assembler-times "xperm8" 1 } } */ diff --git a/gcc/testsuite/gcc.target/riscv/scalar_crypto_intrinsic-32.c b/gcc/testsuite/gcc.target/riscv/scalar_crypto_intrinsic-32.c new file mode 100644 index 0000000..87d576a --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/scalar_crypto_intrinsic-32.c @@ -0,0 +1,115 @@ +/* { dg-do compile } */ +/* { dg-require-effective-target rv32 } */ +/* { dg-options "-march=rv32gc_zknd_zkne_zknh_zksed_zksh -mabi=ilp32d" } */ +/* { dg-skip-if "" { *-*-* } { "-g" "-flto"} } */ + +#include "riscv_crypto.h" + +uint32_t foo1 (uint32_t rs1, uint32_t rs2) +{ + return __riscv_aes32dsi (rs1,rs2,1); +} + +uint32_t foo2 (uint32_t rs1, uint32_t rs2) +{ + return __riscv_aes32dsmi (rs1,rs2,1); +} + +uint32_t foo3 (uint32_t rs1, uint32_t rs2) +{ + return __riscv_aes32esi (rs1,rs2,1); +} + +uint32_t foo4 (uint32_t rs1, uint32_t rs2) +{ + return __riscv_aes32esmi (rs1,rs2,1); +} + +uint32_t foo5 (uint32_t rs1) +{ + return __riscv_sha256sig0 (rs1); +} + +uint32_t foo6 (uint32_t rs1) +{ + return __riscv_sha256sig1 (rs1); +} + +uint32_t foo7 (uint32_t rs1) +{ + return __riscv_sha256sum0 (rs1); +} + +uint32_t foo8 (uint32_t rs1) +{ + return __riscv_sha256sum1 (rs1); +} + +uint32_t foo9 (uint32_t rs1, uint32_t rs2) +{ + return __riscv_sha512sig0h (rs1,rs2); +} + +uint32_t foo10 (uint32_t rs1, uint32_t rs2) +{ + return __riscv_sha512sig0l (rs1,rs2); +} + +uint32_t foo11 (uint32_t rs1, uint32_t rs2) +{ + return __riscv_sha512sig1h (rs1,rs2); +} + +uint32_t foo12 (uint32_t rs1, uint32_t rs2) +{ + return __riscv_sha512sig1l (rs1,rs2); +} + +uint32_t foo13 (uint32_t rs1, uint32_t rs2) +{ + return __riscv_sha512sum0r (rs1,rs2); +} + +uint32_t foo14 (uint32_t rs1, uint32_t rs2) +{ + return __riscv_sha512sum1r (rs1,rs2); +} + +uint32_t foo15 (uint32_t rs1) +{ + return __riscv_sm3p0 (rs1); +} + +uint32_t foo16 (uint32_t rs1) +{ + return __riscv_sm3p1 (rs1); +} + +uint32_t foo17 (uint32_t rs1, uint32_t rs2) +{ + return __riscv_sm4ed (rs1,rs2,1); +} + +uint32_t foo18 (uint32_t rs1, uint32_t rs2) +{ + return __riscv_sm4ks (rs1,rs2,1); +} + +/* { dg-final { scan-assembler-times "aes32dsi" 1 } } */ +/* { dg-final { scan-assembler-times "aes32dsmi" 1 } } */ +/* { dg-final { scan-assembler-times "aes32esi" 1 } } */ +/* { dg-final { scan-assembler-times "aes32esmi" 1 } } */ +/* { dg-final { scan-assembler-times "sha256sig0" 1 } } */ +/* { dg-final { scan-assembler-times "sha256sig1" 1 } } */ +/* { dg-final { scan-assembler-times "sha256sum0" 1 } } */ +/* { dg-final { scan-assembler-times "sha256sum1" 1 } } */ +/* { dg-final { scan-assembler-times "sha512sig0h" 1 } } */ +/* { dg-final { scan-assembler-times "sha512sig0l" 1 } } */ +/* { dg-final { scan-assembler-times "sha512sig1h" 1 } } */ +/* { dg-final { scan-assembler-times "sha512sig1l" 1 } } */ +/* { dg-final { scan-assembler-times "sha512sum0r" 1 } } */ +/* { dg-final { scan-assembler-times "sha512sum1r" 1 } } */ +/* { dg-final { scan-assembler-times "sm3p0" 1 } } */ +/* { dg-final { scan-assembler-times "sm3p1" 1 } } */ +/* { dg-final { scan-assembler-times "sm4ks" 1 } } */ +/* { dg-final { scan-assembler-times "sm4ed" 1 } } */ diff --git a/gcc/testsuite/gcc.target/riscv/scalar_crypto_intrinsic-64.c b/gcc/testsuite/gcc.target/riscv/scalar_crypto_intrinsic-64.c new file mode 100644 index 0000000..01c4a4e --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/scalar_crypto_intrinsic-64.c @@ -0,0 +1,123 @@ +/* { dg-do compile } */ +/* { dg-require-effective-target rv64 } */ +/* { dg-options "-march=rv64gc_zknd_zkne_zknh_zksed_zksh -mabi=lp64d" } */ +/* { dg-skip-if "" { *-*-* } { "-g" "-flto"} } */ + +#include "riscv_crypto.h" + +uint64_t foo1 (uint64_t rs1, uint64_t rs2) +{ + return __riscv_aes64ds (rs1,rs2); +} + +uint64_t foo2 (uint64_t rs1, uint64_t rs2) +{ + return __riscv_aes64dsm (rs1,rs2); +} + +uint64_t foo3 (uint64_t rs1) +{ + return __riscv_aes64im (rs1); +} + +uint64_t foo4 (uint64_t rs1) +{ + return __riscv_aes64ks1i (rs1,1); +} + +uint64_t foo5 (uint64_t rs1, uint64_t rs2) +{ + return __riscv_aes64ks2 (rs1,rs2); +} + +uint64_t foo6 (uint64_t rs1, uint64_t rs2) +{ + return __riscv_aes64es (rs1,rs2); +} + +uint64_t foo7 (uint64_t rs1, uint64_t rs2) +{ + return __riscv_aes64esm (rs1,rs2); +} + +uint64_t foo8 (uint64_t rs1) +{ + return __riscv_sha512sig0 (rs1); +} + +uint64_t foo9 (uint64_t rs1) +{ + return __riscv_sha512sig1 (rs1); +} + +uint64_t foo10 (uint64_t rs1) +{ + return __riscv_sha512sum0 (rs1); +} + +uint64_t foo11 (uint64_t rs1) +{ + return __riscv_sha512sum1 (rs1); +} + +uint32_t foo12 (uint32_t rs1) +{ + return __riscv_sha256sig0 (rs1); +} + +uint32_t foo13 (uint32_t rs1) +{ + return __riscv_sha256sig1 (rs1); +} + +uint32_t foo14 (uint32_t rs1) +{ + return __riscv_sha256sum0 (rs1); +} + +uint32_t foo15 (uint32_t rs1) +{ + return __riscv_sha256sum1 (rs1); +} + +uint32_t foo16 (uint32_t rs1) +{ + return __riscv_sm3p0 (rs1); +} + +uint32_t foo17 (uint32_t rs1) +{ + return __riscv_sm3p1 (rs1); +} + +uint32_t foo18 (uint32_t rs1, uint32_t rs2) +{ + return __riscv_sm4ed (rs1,rs2,1); +} + +uint32_t foo19 (uint32_t rs1, uint32_t rs2) +{ + return __riscv_sm4ks (rs1,rs2,1); +} + +/* { dg-final { scan-assembler-times "aes64ds\t" 1 } } */ +/* { dg-final { scan-assembler-times "aes64dsm" 1 } } */ +/* { dg-final { scan-assembler-times "aes64ks1i" 1 } } */ +/* { dg-final { scan-assembler-times "aes64ks2" 1 } } */ +/* { dg-final { scan-assembler-times "aes64im" 1 } } */ +/* { dg-final { scan-assembler-times "aes64es\t" 1 } } */ +/* { dg-final { scan-assembler-times "aes64esm" 1 } } */ +/* { dg-final { scan-assembler-times "aes64ks1i" 1 } } */ +/* { dg-final { scan-assembler-times "aes64ks2" 1 } } */ +/* { dg-final { scan-assembler-times "sha512sig0" 1 } } */ +/* { dg-final { scan-assembler-times "sha512sig1" 1 } } */ +/* { dg-final { scan-assembler-times "sha512sum0" 1 } } */ +/* { dg-final { scan-assembler-times "sha512sum1" 1 } } */ +/* { dg-final { scan-assembler-times "sha256sig0" 1 } } */ +/* { dg-final { scan-assembler-times "sha256sig1" 1 } } */ +/* { dg-final { scan-assembler-times "sha256sum0" 1 } } */ +/* { dg-final { scan-assembler-times "sha256sum1" 1 } } */ +/* { dg-final { scan-assembler-times "sm3p0" 1 } } */ +/* { dg-final { scan-assembler-times "sm3p1" 1 } } */ +/* { dg-final { scan-assembler-times "sm4ks" 1 } } */ +/* { dg-final { scan-assembler-times "sm4ed" 1 } } */ diff --git a/gcc/testsuite/gcc.target/riscv/xtheadfmemidx-medany.c b/gcc/testsuite/gcc.target/riscv/xtheadfmemidx-medany.c new file mode 100644 index 0000000..0c8060d --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/xtheadfmemidx-medany.c @@ -0,0 +1,38 @@ +/* { dg-do compile } */ +/* { dg-skip-if "" { *-*-* } { "-O0" "-O1" "-O3" "-Og" "-Os" "-Oz"} } */ +/* { dg-options "-march=rv32gc_xtheadfmemidx_xtheadfmv_xtheadmemidx -mabi=ilp32d -mcmodel=medany -O2" } */ + +typedef union { + double v; + unsigned w; +} my_t; + +double z; + +double foo (int i, int j) +{ + + if (j) + { + switch (i) + { + case 0: + return 1; + case 1: + return 0; + case 2: + return 3.0; + } + } + + if (i == 1) + { + my_t u; + u.v = z; + u.w = 1; + z = u.v; + } + return z; +} + +/* { dg-final { scan-assembler-times {\mth\.flrd\M} 1 } } */ diff --git a/gcc/testsuite/gcc.target/riscv/xtheadint-push-pop.c b/gcc/testsuite/gcc.target/riscv/xtheadint-push-pop.c new file mode 100644 index 0000000..dc5609c --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/xtheadint-push-pop.c @@ -0,0 +1,36 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv32gc_xtheadint -mabi=ilp32d" { target { rv32 } } } */ +/* { dg-options "-march=rv64gc_xtheadint -mabi=lp64d" { target { rv64 } } } */ + +extern void f (void); + +__attribute__ ((interrupt)) +void func_default (void) +{ + f (); +} + +__attribute__ ((interrupt ("machine"))) +void func_machine (void) +{ + f (); +} + +/* { dg-final { scan-assembler-times {\mth\.ipush\M} 2 { target { rv32 } } } } */ +/* { dg-final { scan-assembler-times {\mth\.ipop\M} 2 { target { rv32 } } } } */ + + +__attribute__ ((interrupt ("user"))) +void func_usr (void) +{ + f (); +} + +__attribute__ ((interrupt ("supervisor"))) +void func_supervisor (void) +{ + f (); +} + +/* { dg-final { scan-assembler-not {\mth\.ipush\M} { target { rv64 } } } } */ +/* { dg-final { scan-assembler-not {\mth\.ipop\M} { target { rv64 } } } } */ diff --git a/gcc/testsuite/gcc.target/riscv/zbb_32_bswap-1.c b/gcc/testsuite/gcc.target/riscv/zbb_32_bswap-1.c deleted file mode 100644 index 789dda1..0000000 --- a/gcc/testsuite/gcc.target/riscv/zbb_32_bswap-1.c +++ /dev/null @@ -1,11 +0,0 @@ -/* { dg-do compile } */ -/* { dg-options "-march=rv32gc_zbb -mabi=ilp32" } */ -/* { dg-skip-if "" { *-*-* } { "-O0" } } */ - -int foo(int n) -{ - return __builtin_bswap32(n); -} - -/* { dg-final { scan-assembler {\mrev8} } } */ - diff --git a/gcc/testsuite/gcc.target/riscv/zbb_bswap-1.c b/gcc/testsuite/gcc.target/riscv/zbb_bswap-1.c deleted file mode 100644 index 158d97b..0000000 --- a/gcc/testsuite/gcc.target/riscv/zbb_bswap-1.c +++ /dev/null @@ -1,11 +0,0 @@ -/* { dg-do compile } */ -/* { dg-options "-march=rv64gc_zbb -mabi=lp64" } */ -/* { dg-skip-if "" { *-*-* } { "-O0" } } */ - -int foo(int n) -{ - return __builtin_bswap32(n); -} - -/* { dg-final { scan-assembler {\mrev8} } } */ - diff --git a/gcc/testsuite/gcc.target/riscv/zbb_bswap-2.c b/gcc/testsuite/gcc.target/riscv/zbb_bswap-2.c deleted file mode 100644 index cb81f98..0000000 --- a/gcc/testsuite/gcc.target/riscv/zbb_bswap-2.c +++ /dev/null @@ -1,12 +0,0 @@ -/* { dg-do compile } */ -/* { dg-options "-march=rv64gc_zbb -mabi=lp64" } */ -/* { dg-skip-if "" { *-*-* } { "-O0" } } */ - -int foo(int n) -{ - return __builtin_bswap16(n); -} - -/* { dg-final { scan-assembler {\mrev8} } } */ -/* { dg-final { scan-assembler {\msrli} } } */ - diff --git a/gcc/testsuite/gcc.target/riscv/zbb_32_bswap-2.c b/gcc/testsuite/gcc.target/riscv/zbb_bswap16.c index 3b8462d..d123e64 100644 --- a/gcc/testsuite/gcc.target/riscv/zbb_32_bswap-2.c +++ b/gcc/testsuite/gcc.target/riscv/zbb_bswap16.c @@ -1,5 +1,6 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv32gc_zbb -mabi=ilp32" } */ +/* { dg-options "-march=rv64gc_zbb -mabi=lp64d" { target { rv64 } } } */ +/* { dg-options "-march=rv32gc_zbb -mabi=ilp32d" { target { rv32 } } } */ /* { dg-skip-if "" { *-*-* } { "-O0" } } */ int foo(int n) diff --git a/gcc/testsuite/gcc.target/riscv/zbbw.c b/gcc/testsuite/gcc.target/riscv/zbbw.c deleted file mode 100644 index bdf6b0c..0000000 --- a/gcc/testsuite/gcc.target/riscv/zbbw.c +++ /dev/null @@ -1,26 +0,0 @@ -/* { dg-do compile } */ -/* { dg-options "-march=rv64gc_zbb -mabi=lp64" } */ - -int -clz (int i) -{ - return __builtin_clz (i); -} - -int -ctz (int i) -{ - return __builtin_ctz (i); -} - -int -popcount (int i) -{ - return __builtin_popcount (i); -} - - -/* { dg-final { scan-assembler-times {\mclzw} 1 } } */ -/* { dg-final { scan-assembler-times {\mctzw} 1 } } */ -/* { dg-final { scan-assembler-times {\mcpopw} 1 } } */ -/* { dg-final { scan-assembler-not "andi\t" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/zbc32.c b/gcc/testsuite/gcc.target/riscv/zbc32.c deleted file mode 100644 index 049ea95..0000000 --- a/gcc/testsuite/gcc.target/riscv/zbc32.c +++ /dev/null @@ -1,23 +0,0 @@ -/* { dg-do compile } */ -/* { dg-options "-O2 -march=rv32gc_zbc -mabi=ilp32" } */ -/* { dg-skip-if "" { *-*-* } { "-g" "-flto"} } */ -#include <stdint-gcc.h> - -uint32_t foo1(uint32_t rs1, uint32_t rs2) -{ - return __builtin_riscv_clmul(rs1, rs2); -} - -uint32_t foo2(uint32_t rs1, uint32_t rs2) -{ - return __builtin_riscv_clmulh(rs1, rs2); -} - -uint32_t foo3(uint32_t rs1, uint32_t rs2) -{ - return __builtin_riscv_clmulr(rs1, rs2); -} - -/* { dg-final { scan-assembler-times "clmul\t" 1 } } */ -/* { dg-final { scan-assembler-times {\mclmulh} 1 } } */ -/* { dg-final { scan-assembler-times {\mclmulr} 1 } } */ diff --git a/gcc/testsuite/gcc.target/riscv/zbc64.c b/gcc/testsuite/gcc.target/riscv/zbc64.c deleted file mode 100644 index 69dadd1..0000000 --- a/gcc/testsuite/gcc.target/riscv/zbc64.c +++ /dev/null @@ -1,23 +0,0 @@ -/* { dg-do compile } */ -/* { dg-options "-O2 -march=rv64gc_zbc -mabi=lp64" } */ -/* { dg-skip-if "" { *-*-* } { "-g" "-flto"} } */ -#include <stdint-gcc.h> - -uint64_t foo1(uint64_t rs1, uint64_t rs2) -{ - return __builtin_riscv_clmul(rs1, rs2); -} - -uint64_t foo2(uint64_t rs1, uint64_t rs2) -{ - return __builtin_riscv_clmulh(rs1, rs2); -} - -uint64_t foo3(uint64_t rs1, uint64_t rs2) -{ - return __builtin_riscv_clmulr(rs1, rs2); -} - -/* { dg-final { scan-assembler-times "clmul\t" 1 } } */ -/* { dg-final { scan-assembler-times {\mclmulh} 1 } } */ -/* { dg-final { scan-assembler-times {\mclmulr} 1 } } */ diff --git a/gcc/testsuite/gcc.target/riscv/zbkb32.c b/gcc/testsuite/gcc.target/riscv/zbkb32.c index 841f5e0..8f6afd1 100644 --- a/gcc/testsuite/gcc.target/riscv/zbkb32.c +++ b/gcc/testsuite/gcc.target/riscv/zbkb32.c @@ -14,23 +14,5 @@ uint32_t foo2(uint8_t rs1, uint8_t rs2) return __builtin_riscv_packh(rs1, rs2); } -uint32_t foo3(uint32_t rs1) -{ - return __builtin_riscv_brev8(rs1); -} - -uint32_t foo4(uint32_t rs1) -{ - return __builtin_riscv_zip(rs1); -} - -uint32_t foo5(uint32_t rs1) -{ - return __builtin_riscv_unzip(rs1); -} - /* { dg-final { scan-assembler-times "pack\t" 1 } } */ /* { dg-final { scan-assembler-times {\mpackh} 1 } } */ -/* { dg-final { scan-assembler-times {\mbrev8} 1 } } */ -/* { dg-final { scan-assembler-times "\tzip\t" 1 } } */ -/* { dg-final { scan-assembler-times {\munzip} 1 } } */ diff --git a/gcc/testsuite/gcc.target/riscv/zbkb64.c b/gcc/testsuite/gcc.target/riscv/zbkb64.c index 8b6a0bf..492151e 100644 --- a/gcc/testsuite/gcc.target/riscv/zbkb64.c +++ b/gcc/testsuite/gcc.target/riscv/zbkb64.c @@ -18,11 +18,6 @@ uint64_t foo3(uint16_t rs1, uint16_t rs2) return __builtin_riscv_packw(rs1, rs2); } -uint64_t foo4(uint64_t rs1, uint64_t rs2) -{ - return __builtin_riscv_brev8(rs1); -} /* { dg-final { scan-assembler-times "pack\t" 1 } } */ /* { dg-final { scan-assembler-times {\mpackh} 1 } } */ /* { dg-final { scan-assembler-times {\mpackw} 1 } } */ -/* { dg-final { scan-assembler-times {\mbrev8} 1 } } */ diff --git a/gcc/testsuite/gcc.target/riscv/zbkc32.c b/gcc/testsuite/gcc.target/riscv/zbkc32.c deleted file mode 100644 index 6d2a8ff..0000000 --- a/gcc/testsuite/gcc.target/riscv/zbkc32.c +++ /dev/null @@ -1,17 +0,0 @@ -/* { dg-do compile } */ -/* { dg-options "-O2 -march=rv32gc_zbkc -mabi=ilp32" } */ -/* { dg-skip-if "" { *-*-* } { "-g" "-flto"} } */ -#include <stdint-gcc.h> - -uint32_t foo1(uint32_t rs1, uint32_t rs2) -{ - return __builtin_riscv_clmul(rs1, rs2); -} - -uint32_t foo2(uint32_t rs1, uint32_t rs2) -{ - return __builtin_riscv_clmulh(rs1, rs2); -} - -/* { dg-final { scan-assembler-times "clmul\t" 1 } } */ -/* { dg-final { scan-assembler-times {\mclmulh} 1 } } */ diff --git a/gcc/testsuite/gcc.target/riscv/zbkc64.c b/gcc/testsuite/gcc.target/riscv/zbkc64.c deleted file mode 100644 index 3708fb5..0000000 --- a/gcc/testsuite/gcc.target/riscv/zbkc64.c +++ /dev/null @@ -1,17 +0,0 @@ -/* { dg-do compile } */ -/* { dg-options "-O2 -march=rv64gc_zbkc -mabi=lp64" } */ -/* { dg-skip-if "" { *-*-* } { "-g" "-flto"} } */ -#include <stdint-gcc.h> - -uint64_t foo1(uint64_t rs1, uint64_t rs2) -{ - return __builtin_riscv_clmul(rs1, rs2); -} - -uint64_t foo2(uint64_t rs1, uint64_t rs2) -{ - return __builtin_riscv_clmulh(rs1, rs2); -} - -/* { dg-final { scan-assembler-times "clmul\t" 1 } } */ -/* { dg-final { scan-assembler-times {\mclmulh} 1 } } */ diff --git a/gcc/testsuite/gcc.target/riscv/zbkx32.c b/gcc/testsuite/gcc.target/riscv/zbkx32.c deleted file mode 100644 index b41fd90..0000000 --- a/gcc/testsuite/gcc.target/riscv/zbkx32.c +++ /dev/null @@ -1,18 +0,0 @@ -/* { dg-do compile } */ -/* { dg-options "-O2 -march=rv32gc_zbkx -mabi=ilp32" } */ -/* { dg-skip-if "" { *-*-* } { "-g" "-flto"} } */ - -#include <stdint-gcc.h> - -uint32_t foo3(uint32_t rs1, uint32_t rs2) -{ - return __builtin_riscv_xperm8(rs1, rs2); -} - -uint32_t foo4(uint32_t rs1, uint32_t rs2) -{ - return __builtin_riscv_xperm4(rs1, rs2); -} - -/* { dg-final { scan-assembler-times {\mxperm8} 1 } } */ -/* { dg-final { scan-assembler-times {\mxperm4} 1 } } */ diff --git a/gcc/testsuite/gcc.target/riscv/zbkx64.c b/gcc/testsuite/gcc.target/riscv/zbkx64.c deleted file mode 100644 index 9ed42b4..0000000 --- a/gcc/testsuite/gcc.target/riscv/zbkx64.c +++ /dev/null @@ -1,18 +0,0 @@ -/* { dg-do compile } */ -/* { dg-options "-O2 -march=rv64gc_zbkx -mabi=lp64" } */ -/* { dg-skip-if "" { *-*-* } { "-g" "-flto"} } */ - -#include <stdint-gcc.h> - -uint64_t foo1(uint64_t rs1, uint64_t rs2) -{ - return __builtin_riscv_xperm8(rs1, rs2); -} - -uint64_t foo2(uint64_t rs1, uint64_t rs2) -{ - return __builtin_riscv_xperm4(rs1, rs2); -} - -/* { dg-final { scan-assembler-times {\mxperm8} 1 } } */ -/* { dg-final { scan-assembler-times {\mxperm4} 1 } } */ diff --git a/gcc/testsuite/gcc.target/riscv/zknd32-2.c b/gcc/testsuite/gcc.target/riscv/zknd32-2.c deleted file mode 100644 index f3549e7..0000000 --- a/gcc/testsuite/gcc.target/riscv/zknd32-2.c +++ /dev/null @@ -1,28 +0,0 @@ -/* { dg-do compile } */ -/* { dg-options "-O2 -march=rv32gc_zknd -mabi=ilp32d" } */ -/* { dg-skip-if "" { *-*-* } { "-g" "-flto"} } */ - -#include <stdint-gcc.h> - -uint32_t foo1(uint32_t rs1, uint32_t rs2) -{ - return __builtin_riscv_aes32dsi(rs1,rs2,0); -} - -uint32_t foo2(uint32_t rs1, uint32_t rs2) -{ - return __builtin_riscv_aes32dsmi(rs1,rs2,0); -} - -uint32_t foo3(uint32_t rs1, uint32_t rs2) -{ - return __builtin_riscv_aes32dsi(rs1,rs2,3); -} - -uint32_t foo4(uint32_t rs1, uint32_t rs2) -{ - return __builtin_riscv_aes32dsmi(rs1,rs2,3); -} - -/* { dg-final { scan-assembler-times "aes32dsi" 2 } } */ -/* { dg-final { scan-assembler-times "aes32dsmi" 2 } } */ diff --git a/gcc/testsuite/gcc.target/riscv/zknd64-2.c b/gcc/testsuite/gcc.target/riscv/zknd64-2.c deleted file mode 100644 index cd0e79d..0000000 --- a/gcc/testsuite/gcc.target/riscv/zknd64-2.c +++ /dev/null @@ -1,42 +0,0 @@ -/* { dg-do compile } */ -/* { dg-options "-O2 -march=rv64gc_zknd -mabi=lp64" } */ -/* { dg-skip-if "" { *-*-* } { "-g" "-flto"} } */ - -#include <stdint-gcc.h> - -uint64_t foo1(uint64_t rs1, uint64_t rs2) -{ - return __builtin_riscv_aes64ds(rs1,rs2); -} - -uint64_t foo2(uint64_t rs1, uint64_t rs2) -{ - return __builtin_riscv_aes64dsm(rs1,rs2); -} - -uint64_t foo3(uint64_t rs1, unsigned rnum) -{ - return __builtin_riscv_aes64ks1i(rs1,0); -} - -uint64_t foo3a(uint64_t rs1, unsigned rnum) -{ - return __builtin_riscv_aes64ks1i(rs1,10); -} - -uint64_t foo4(uint64_t rs1, uint64_t rs2) -{ - return __builtin_riscv_aes64ks2(rs1,rs2); -} - -uint64_t foo5(uint64_t rs1) -{ - return __builtin_riscv_aes64im(rs1); -} - -/* { dg-final { scan-assembler-times "aes64ds\t" 1 } } */ -/* { dg-final { scan-assembler-times "aes64dsm" 1 } } */ -/* { dg-final { scan-assembler-times "aes64ks1i" 2 } } */ -/* { dg-final { scan-assembler-times "aes64ks2" 1 } } */ -/* { dg-final { scan-assembler-times {\maes64im} 1 } } */ - diff --git a/gcc/testsuite/gcc.target/riscv/zkne32-2.c b/gcc/testsuite/gcc.target/riscv/zkne32-2.c deleted file mode 100644 index 4ad1cdc..0000000 --- a/gcc/testsuite/gcc.target/riscv/zkne32-2.c +++ /dev/null @@ -1,28 +0,0 @@ -/* { dg-do compile } */ -/* { dg-options "-O2 -march=rv32gc_zkne -mabi=ilp32d" } */ -/* { dg-skip-if "" { *-*-* } { "-g" "-flto"} } */ - -#include <stdint-gcc.h> - -uint32_t foo1(uint32_t rs1, uint32_t rs2) -{ - return __builtin_riscv_aes32esi(rs1, rs2, 0); -} - -uint32_t foo2(uint32_t rs1, uint32_t rs2) -{ - return __builtin_riscv_aes32esmi(rs1, rs2, 0); -} - -uint32_t foo3(uint32_t rs1, uint32_t rs2) -{ - return __builtin_riscv_aes32esi(rs1, rs2, 3); -} - -uint32_t foo4(uint32_t rs1, uint32_t rs2) -{ - return __builtin_riscv_aes32esmi(rs1, rs2, 3); -} - -/* { dg-final { scan-assembler-times "aes32esi" 2 } } */ -/* { dg-final { scan-assembler-times "aes32esmi" 2 } } */ diff --git a/gcc/testsuite/gcc.target/riscv/zkne64-2.c b/gcc/testsuite/gcc.target/riscv/zkne64-2.c deleted file mode 100644 index 144c394..0000000 --- a/gcc/testsuite/gcc.target/riscv/zkne64-2.c +++ /dev/null @@ -1,34 +0,0 @@ -/* { dg-do compile } */ -/* { dg-options "-O2 -march=rv64gc_zkne -mabi=lp64" } */ -/* { dg-skip-if "" { *-*-* } { "-g" "-flto"} } */ - -#include <stdint-gcc.h> - -uint64_t foo1(uint64_t rs1, uint64_t rs2) -{ - return __builtin_riscv_aes64es(rs1,rs2); -} - -uint64_t foo2(uint64_t rs1, uint64_t rs2) -{ - return __builtin_riscv_aes64esm(rs1,rs2); -} - -uint64_t foo3(uint64_t rs1, unsigned rnum) -{ - return __builtin_riscv_aes64ks1i(rs1,0); -} - -uint64_t foo3a(uint64_t rs1, unsigned rnum) -{ - return __builtin_riscv_aes64ks1i(rs1,10); -} -uint64_t foo4(uint64_t rs1, uint64_t rs2) -{ - return __builtin_riscv_aes64ks2(rs1,rs2); -} - -/* { dg-final { scan-assembler-times "aes64es\t" 1 } } */ -/* { dg-final { scan-assembler-times "aes64esm" 1 } } */ -/* { dg-final { scan-assembler-times "aes64ks1i" 2 } } */ -/* { dg-final { scan-assembler-times "aes64ks2" 1 } } */ diff --git a/gcc/testsuite/gcc.target/riscv/zknh-sha256-32.c b/gcc/testsuite/gcc.target/riscv/zknh-sha256-32.c deleted file mode 100644 index c51b143..0000000 --- a/gcc/testsuite/gcc.target/riscv/zknh-sha256-32.c +++ /dev/null @@ -1,10 +0,0 @@ -/* { dg-do compile } */ -/* { dg-options "-O2 -march=rv32gc_zknh -mabi=ilp32d" } */ -/* { dg-skip-if "" { *-*-* } { "-g" "-flto"} } */ - -#include "zknh-sha256-64.c" - -/* { dg-final { scan-assembler-times "sha256sig0" 1 } } */ -/* { dg-final { scan-assembler-times "sha256sig1" 1 } } */ -/* { dg-final { scan-assembler-times "sha256sum0" 1 } } */ -/* { dg-final { scan-assembler-times "sha256sum1" 1 } } */ diff --git a/gcc/testsuite/gcc.target/riscv/zknh-sha256-64.c b/gcc/testsuite/gcc.target/riscv/zknh-sha256-64.c deleted file mode 100644 index 2ef3760..0000000 --- a/gcc/testsuite/gcc.target/riscv/zknh-sha256-64.c +++ /dev/null @@ -1,28 +0,0 @@ -/* { dg-do compile } */ -/* { dg-options "-O2 -march=rv64gc_zknh -mabi=lp64" } */ -/* { dg-skip-if "" { *-*-* } { "-g" "-flto"} } */ - -unsigned int foo1(unsigned int rs1) -{ - return __builtin_riscv_sha256sig0(rs1); -} - -unsigned int foo2(unsigned int rs1) -{ - return __builtin_riscv_sha256sig1(rs1); -} - -unsigned int foo3(unsigned int rs1) -{ - return __builtin_riscv_sha256sum0(rs1); -} - -unsigned int foo4(unsigned int rs1) -{ - return __builtin_riscv_sha256sum1(rs1); -} - -/* { dg-final { scan-assembler-times "sha256sig0" 1 } } */ -/* { dg-final { scan-assembler-times "sha256sig1" 1 } } */ -/* { dg-final { scan-assembler-times "sha256sum0" 1 } } */ -/* { dg-final { scan-assembler-times "sha256sum1" 1 } } */ diff --git a/gcc/testsuite/gcc.target/riscv/zknh-sha512-32.c b/gcc/testsuite/gcc.target/riscv/zknh-sha512-32.c deleted file mode 100644 index f2bcae3..0000000 --- a/gcc/testsuite/gcc.target/riscv/zknh-sha512-32.c +++ /dev/null @@ -1,42 +0,0 @@ -/* { dg-do compile } */ -/* { dg-options "-O2 -march=rv32gc_zknh -mabi=ilp32" } */ -/* { dg-skip-if "" { *-*-* } { "-g" "-flto"} } */ - -#include <stdint-gcc.h> - -uint32_t foo1(uint32_t rs1, uint32_t rs2) -{ - return __builtin_riscv_sha512sig0h(rs1,rs2); -} - -uint32_t foo2(uint32_t rs1, uint32_t rs2) -{ - return __builtin_riscv_sha512sig0l(rs1,rs2); -} - -uint32_t foo3(uint32_t rs1, uint32_t rs2) -{ - return __builtin_riscv_sha512sig1h(rs1,rs2); -} - -uint32_t foo4(uint32_t rs1, uint32_t rs2) -{ - return __builtin_riscv_sha512sig1l(rs1,rs2); -} - -uint32_t foo5(uint32_t rs1, uint32_t rs2) -{ - return __builtin_riscv_sha512sum0r(rs1,rs2); -} - -uint32_t foo6(uint32_t rs1, uint32_t rs2) -{ - return __builtin_riscv_sha512sum1r(rs1,rs2); -} - -/* { dg-final { scan-assembler-times "sha512sig0h" 1 } } */ -/* { dg-final { scan-assembler-times "sha512sig0l" 1 } } */ -/* { dg-final { scan-assembler-times "sha512sig1h" 1 } } */ -/* { dg-final { scan-assembler-times "sha512sig1l" 1 } } */ -/* { dg-final { scan-assembler-times "sha512sum0r" 1 } } */ -/* { dg-final { scan-assembler-times "sha512sum1r" 1 } } */ diff --git a/gcc/testsuite/gcc.target/riscv/zknh-sha512-64.c b/gcc/testsuite/gcc.target/riscv/zknh-sha512-64.c deleted file mode 100644 index 4f24857..0000000 --- a/gcc/testsuite/gcc.target/riscv/zknh-sha512-64.c +++ /dev/null @@ -1,31 +0,0 @@ -/* { dg-do compile } */ -/* { dg-options "-O2 -march=rv64gc_zknh -mabi=lp64" } */ -/* { dg-skip-if "" { *-*-* } { "-g" "-flto"} } */ - -#include <stdint-gcc.h> - -uint64_t foo1(uint64_t rs1) -{ - return __builtin_riscv_sha512sig0(rs1); -} - -uint64_t foo2(uint64_t rs1) -{ - return __builtin_riscv_sha512sig1(rs1); -} - -uint64_t foo3(uint64_t rs1) -{ - return __builtin_riscv_sha512sum0(rs1); -} - -uint64_t foo4(uint64_t rs1) -{ - return __builtin_riscv_sha512sum1(rs1); -} - - -/* { dg-final { scan-assembler-times "sha512sig0" 1 } } */ -/* { dg-final { scan-assembler-times "sha512sig1" 1 } } */ -/* { dg-final { scan-assembler-times "sha512sum0" 1 } } */ -/* { dg-final { scan-assembler-times "sha512sum1" 1 } } */ diff --git a/gcc/testsuite/gcc.target/riscv/zksed32-2.c b/gcc/testsuite/gcc.target/riscv/zksed32-2.c deleted file mode 100644 index cee8cc2..0000000 --- a/gcc/testsuite/gcc.target/riscv/zksed32-2.c +++ /dev/null @@ -1,29 +0,0 @@ -/* { dg-do compile } */ -/* { dg-options "-O2 -march=rv32gc_zksed -mabi=ilp32" } */ -/* { dg-skip-if "" { *-*-* } { "-g" "-flto"} } */ - -#include <stdint-gcc.h> - -uint32_t foo1(uint32_t rs1, uint32_t rs2) -{ - return __builtin_riscv_sm4ks(rs1,rs2,0); -} - -uint32_t foo2(uint32_t rs1, uint32_t rs2) -{ - return __builtin_riscv_sm4ed(rs1,rs2,0); -} - -uint32_t foo3(uint32_t rs1, uint32_t rs2) -{ - return __builtin_riscv_sm4ks(rs1,rs2,3); -} - -uint32_t foo4(uint32_t rs1, uint32_t rs2) -{ - return __builtin_riscv_sm4ed(rs1,rs2,3); -} - - -/* { dg-final { scan-assembler-times {\msm4ks} 2 } } */ -/* { dg-final { scan-assembler-times {\msm4ed} 2 } } */ diff --git a/gcc/testsuite/gcc.target/riscv/zksed64-2.c b/gcc/testsuite/gcc.target/riscv/zksed64-2.c deleted file mode 100644 index ee20aa1..0000000 --- a/gcc/testsuite/gcc.target/riscv/zksed64-2.c +++ /dev/null @@ -1,29 +0,0 @@ -/* { dg-do compile } */ -/* { dg-options "-O2 -march=rv64gc_zksed -mabi=lp64" } */ -/* { dg-skip-if "" { *-*-* } { "-g" "-flto"} } */ - -#include <stdint-gcc.h> - -uint32_t foo1(uint32_t rs1, uint32_t rs2) -{ - return __builtin_riscv_sm4ks(rs1,rs2,0); -} - -uint32_t foo2(uint32_t rs1, uint32_t rs2) -{ - return __builtin_riscv_sm4ed(rs1,rs2,0); -} - -uint32_t foo3(uint32_t rs1, uint32_t rs2) -{ - return __builtin_riscv_sm4ks(rs1,rs2,3); -} - -uint32_t foo4(uint32_t rs1, uint32_t rs2) -{ - return __builtin_riscv_sm4ed(rs1,rs2,3); -} - - -/* { dg-final { scan-assembler-times {\msm4ks} 2 } } */ -/* { dg-final { scan-assembler-times {\msm4ed} 2 } } */ diff --git a/gcc/testsuite/gcc.target/riscv/zksh32.c b/gcc/testsuite/gcc.target/riscv/zksh32.c deleted file mode 100644 index c182e55..0000000 --- a/gcc/testsuite/gcc.target/riscv/zksh32.c +++ /dev/null @@ -1,19 +0,0 @@ -/* { dg-do compile } */ -/* { dg-options "-O2 -march=rv32gc_zksh -mabi=ilp32" } */ -/* { dg-skip-if "" { *-*-* } { "-g" "-flto"} } */ - -#include <stdint-gcc.h> - -uint32_t foo1(uint32_t rs1) -{ - return __builtin_riscv_sm3p0(rs1); -} - -uint32_t foo2(uint32_t rs1) -{ - return __builtin_riscv_sm3p1(rs1); -} - - -/* { dg-final { scan-assembler-times {\msm3p0} 1 } } */ -/* { dg-final { scan-assembler-times {\msm3p1} 1 } } */ diff --git a/gcc/testsuite/gcc.target/riscv/zksh64.c b/gcc/testsuite/gcc.target/riscv/zksh64.c deleted file mode 100644 index d794b39..0000000 --- a/gcc/testsuite/gcc.target/riscv/zksh64.c +++ /dev/null @@ -1,19 +0,0 @@ -/* { dg-do compile } */ -/* { dg-options "-O2 -march=rv64gc_zksh -mabi=lp64" } */ -/* { dg-skip-if "" { *-*-* } { "-g" "-flto"} } */ - -#include <stdint-gcc.h> - -uint32_t foo1(uint32_t rs1) -{ - return __builtin_riscv_sm3p0(rs1); -} - -uint32_t foo2(uint32_t rs1) -{ - return __builtin_riscv_sm3p1(rs1); -} - - -/* { dg-final { scan-assembler-times {\msm3p0} 1 } } */ -/* { dg-final { scan-assembler-times {\msm3p1} 1 } } */ diff --git a/gcc/testsuite/gfortran.dg/do_concurrent_7.f90 b/gcc/testsuite/gfortran.dg/do_concurrent_7.f90 new file mode 100644 index 0000000..604f671 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/do_concurrent_7.f90 @@ -0,0 +1,26 @@ +! { dg-do compile } +! { dg-additional-options "-fdump-tree-original" } +! PR fortran/113305 + +program dc + implicit none + real :: a(12), b(12), c(16,8), d(16,8) + integer :: i, j + call random_number(b) +!GCC$ ivdep +!GCC$ vector + do concurrent (i=1:12) + a(i) = 2*b(i) + end do + c = b(1) + d = a(2) +!GCC$ novector +!GCC$ unroll 4 + do concurrent (i=1:16:2,j=1:8:2) + d(i,j) = 3*c(i,j) + end do +end program + +! { dg-final { scan-tree-dump "ANNOTATE_EXPR .* ivdep>, vector" "original" } } +! { dg-final { scan-tree-dump "ANNOTATE_EXPR .* ivdep>, no-vector" "original" } } +! { dg-final { scan-tree-dump "ANNOTATE_EXPR .* ivdep>, unroll 4>, no-vector" "original" } } diff --git a/gcc/testsuite/gfortran.dg/fmt_f_default_field_width_3.f90 b/gcc/testsuite/gfortran.dg/fmt_f_default_field_width_3.f90 index 3e7d8f6..46f271e 100644 --- a/gcc/testsuite/gfortran.dg/fmt_f_default_field_width_3.f90 +++ b/gcc/testsuite/gfortran.dg/fmt_f_default_field_width_3.f90 @@ -30,6 +30,6 @@ program test #ifdef __GFC_REAL_16__ real_16 = 4.18 - write(buffer, fmt) ':',real_16,':' ! { dg-error "Nonnegative width required" "" { target fortran_real_16 } } + write(buffer, fmt) ':',real_16,':' ! { dg-error "Nonnegative width required" "" { target { fortran_real_16 || { hppa*64*-*-hpux* } } } } #endif end diff --git a/gcc/testsuite/gfortran.dg/fmt_g_default_field_width_3.f90 b/gcc/testsuite/gfortran.dg/fmt_g_default_field_width_3.f90 index 95a0598..22fe1a3 100644 --- a/gcc/testsuite/gfortran.dg/fmt_g_default_field_width_3.f90 +++ b/gcc/testsuite/gfortran.dg/fmt_g_default_field_width_3.f90 @@ -33,6 +33,6 @@ program test #ifdef __GFC_REAL_16__ real_16 = 4.18 - write(buffer, fmt) ':',real_16,':' ! { dg-error "Positive width required" "" { target fortran_real_16 } } + write(buffer, fmt) ':',real_16,':' ! { dg-error "Positive width required" "" { target { fortran_real_16 || { hppa*64*-*-hpux* } } } } #endif end diff --git a/gcc/testsuite/gfortran.dg/ishftc_optional_size_1.f90 b/gcc/testsuite/gfortran.dg/ishftc_optional_size_1.f90 new file mode 100644 index 0000000..1ccf4b3 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/ishftc_optional_size_1.f90 @@ -0,0 +1,97 @@ +! { dg-do run } +! +! PR fortran/67277 - ISHFTC and missing optional argument SIZE + +module m + implicit none +contains + ! Optional argument passed by reference + elemental function ishftc4_ref (i, shift, size_) result(r) + integer(4), intent(in) :: i + integer, intent(in) :: shift + integer, intent(in), optional :: size_ + integer :: r + r = ishftc (i, shift=shift, size=size_) + end + + elemental function ishftc1_ref (i, shift, size_) result(r) + integer(1), intent(in) :: i + integer, intent(in) :: shift + integer(1), intent(in), optional :: size_ + integer(1) :: r + r = ishftc (i, shift=shift, size=size_) + end + + ! Array valued argument i + function ishftc4_ref_4 (i, shift, size_) result(r) + integer(4), intent(in) :: i(4) + integer, intent(in) :: shift + integer, intent(in), optional :: size_ + integer :: r(size(i)) + r = ishftc (i, shift=shift, size=size_) + end + + ! Optional argument passed by value + elemental function ishftc4_val (i, shift, size_) result(r) + integer(4), intent(in) :: i + integer, intent(in) :: shift + integer, value, optional :: size_ + integer :: r + r = ishftc (i, shift=shift, size=size_) + end + + elemental function ishftc1_val (i, shift, size_) result(r) + integer(1), intent(in) :: i + integer, intent(in) :: shift + integer(1), value, optional :: size_ + integer(1) :: r + r = ishftc (i, shift=shift, size=size_) + end + + ! Array valued argument i + function ishftc4_val_4 (i, shift, size_) result(r) + integer(4), intent(in) :: i(4) + integer, intent(in) :: shift + integer, value, optional :: size_ + integer :: r(size(i)) + r = ishftc (i, shift=shift, size=size_) + end +end module m + +program p + use m + implicit none + integer :: shift = 1 + integer(4) :: i4 = 127, j4(4), k4(4) + integer(1) :: i1 = 127 + integer(4) :: expect4 + integer(1) :: expect1 + + ! Scalar variants + expect4 = 2*i4 + if (ishftc (i4, shift) /= expect4) stop 1 + if (ishftc4_ref (i4, shift) /= expect4) stop 2 + if (ishftc4_val (i4, shift) /= expect4) stop 3 + + expect1 = -2_1 + if (ishftc (i1, shift) /= expect1) stop 4 + if (ishftc1_ref (i1, shift) /= expect1) stop 5 + if (ishftc1_val (i1, shift) /= expect1) stop 6 + + ! Array arguments + expect4 = 2*i4 + j4 = i4 + k4 = ishftc (j4, shift) + if (any (k4 /= expect4)) stop 7 + + ! The following works on x86_64 but might currently fail on other systems: + ! (see PR113377) +! k4 = ishftc4_val_4 (j4, shift) +! if (any (k4 /= expect4)) stop 8 + + ! The following currently segfaults (might be a scalarizer issue): + ! (see PR113377) +! k4 = ishftc4_ref_4 (j4, shift) +! print *, k4 +! if (any (k4 /= expect4)) stop 9 +end program p diff --git a/gcc/testsuite/gm2/pim/fail/badbecomes.mod b/gcc/testsuite/gm2/pim/fail/badbecomes.mod new file mode 100644 index 0000000..b902c28 --- /dev/null +++ b/gcc/testsuite/gm2/pim/fail/badbecomes.mod @@ -0,0 +1,10 @@ +MODULE badbecomes ; + +TYPE + enums = (red, blue, green) ; + set = SET OF enums ; +VAR + setvar : set; +BEGIN + setvar := green ; (* Should detect an error here. *) +END badbecomes. diff --git a/gcc/testsuite/gm2/pim/fail/badexpression.mod b/gcc/testsuite/gm2/pim/fail/badexpression.mod new file mode 100644 index 0000000..da2ec26 --- /dev/null +++ b/gcc/testsuite/gm2/pim/fail/badexpression.mod @@ -0,0 +1,16 @@ +MODULE badexpression3 ; + +TYPE + enums = (red, blue, green) ; + set = SET OF enums ; +VAR + setvar : set; + enumvar: enums; +BEGIN + setvar := set {red, blue} ; + setvar := setvar + green ; (* Should detect an error here. *) + IF NOT (green IN setvar) + THEN + HALT + END +END badexpression3.
\ No newline at end of file diff --git a/gcc/testsuite/gm2/pim/fail/badexpression2.mod b/gcc/testsuite/gm2/pim/fail/badexpression2.mod new file mode 100644 index 0000000..b61eb3e --- /dev/null +++ b/gcc/testsuite/gm2/pim/fail/badexpression2.mod @@ -0,0 +1,17 @@ +MODULE badexpression2 ; + +TYPE + enums = (red, blue, green) ; + set = SET OF enums ; +VAR + setvar : set; + enumvar: enums; +BEGIN + setvar := set {red, blue} ; + enumvar := green ; + setvar := setvar + enumvar ; (* Should detect an error here. *) + IF NOT (green IN setvar) + THEN + HALT + END +END badexpression2. diff --git a/gcc/testsuite/gm2/pim/fail/badifin.mod b/gcc/testsuite/gm2/pim/fail/badifin.mod new file mode 100644 index 0000000..86a04dd --- /dev/null +++ b/gcc/testsuite/gm2/pim/fail/badifin.mod @@ -0,0 +1,15 @@ +MODULE badifin ; + +TYPE + enums = (red, blue, green) ; + set = SET OF enums ; +VAR + setvar : set; + enumvar: enums; +BEGIN + setvar := set {red, blue} ; + IF NOT (setvar IN setvar) + THEN + HALT + END +END badifin. diff --git a/gcc/testsuite/gm2/pim/pass/goodifin.mod b/gcc/testsuite/gm2/pim/pass/goodifin.mod new file mode 100644 index 0000000..a899320 --- /dev/null +++ b/gcc/testsuite/gm2/pim/pass/goodifin.mod @@ -0,0 +1,15 @@ +MODULE goodifin ; + +TYPE + enums = (red, blue, green) ; + set = SET OF enums ; +VAR + setvar : set; + enumvar: enums; +BEGIN + setvar := set {red, blue} ; + IF green IN setvar + THEN + HALT + END +END goodifin. diff --git a/gcc/testsuite/jit.dg/all-non-failing-tests.h b/gcc/testsuite/jit.dg/all-non-failing-tests.h index e762563..a3bd035 100644 --- a/gcc/testsuite/jit.dg/all-non-failing-tests.h +++ b/gcc/testsuite/jit.dg/all-non-failing-tests.h @@ -32,6 +32,9 @@ /* test-add-driver-options.c: We don't use this one, since the extra options affect the whole context. */ +/* test-alias-attribute.c: This can't be in the testcases array as it + doesn't have a verify_code implementation. */ + /* test-alignment.c */ #define create_code create_code_alignment #define verify_code verify_code_alignment @@ -39,6 +42,9 @@ #undef create_code #undef verify_code +/* test-always_inline-attribute.c: This can't be in the testcases array as it needs + the `-O0` flag. */ + /* test-arith-overflow.c */ #define create_code create_code_arith_overflow #define verify_code verify_code_arith_overflow @@ -119,6 +125,9 @@ #undef create_code #undef verify_code +/* test-cold-attribute.c: This can't be in the testcases array as it needs + the `-O2` flag. */ + /* test-constants.c */ #define create_code create_code_constants #define verify_code verify_code_constants @@ -126,6 +135,9 @@ #undef create_code #undef verify_code +/* test-const-attribute.c: This can't be in the testcases array as it needs + the `-O3` flag. */ + /* test-debug-strings.c */ #define create_code create_code_debug_strings #define verify_code verify_code_debug_strings @@ -268,6 +280,12 @@ #undef create_code #undef verify_code +/* test-noinline-attribute.c: This can't be in the testcases array as it needs + the `-O2` flag. */ + +/* test-nonnull-attribute.c: This can't be in the testcases array as it needs + the `-O2` flag. */ + /* test-pr103562.c: We don't add this one, since it touches the optimization level of the context as a whole. */ @@ -299,6 +317,9 @@ #undef create_code #undef verify_code +/* test-pure-attribute.c: This can't be in the testcases array as it needs + the `-O3` flag. */ + /* test-reading-struct.c */ #define create_code create_code_reading_struct #define verify_code verify_code_reading_struct @@ -316,6 +337,9 @@ /* test-restrict.c: This can't be in the testcases array as it needs the `-O3` flag. */ +/* test-restrict-attribute.c: This can't be in the testcases array as it needs + the `-O3` flag. */ + /* test-register-variable.c: This can't be in the testcases array as it is target-specific. */ @@ -350,6 +374,9 @@ #undef create_code #undef verify_code +/* test-used-attribute.c: This can't be in the testcases array as it needs + the `-O2` flag. */ + /* test-using-global.c */ #define create_code create_code_using_global #define verify_code verify_code_using_global @@ -361,6 +388,9 @@ of gcc_jit_context_set_bool_allow_unreachable_blocks affects the whole context. */ +/* test-variable-attribute.c: This can't be in the testcases array as it + doesn't have a verify_code implementation. */ + /* test-vector-types.cc: We don't use this, since it's C++. */ /* test-version.c */ @@ -377,6 +407,13 @@ #undef create_code #undef verify_code +/* test-ggc-bugfix.c: We don't use this once, since the use of + gcc_jit_context_add_command_line_option and + gcc_jit_context_add_driver_option affects the whole context. */ + +/* test-weak-attribute.c: This can't be in the testcases array as it + doesn't have a verify_code implementation. */ + /* Now expose the individual testcases as instances of this struct. */ struct testcase diff --git a/gcc/testsuite/jit.dg/jit.exp b/gcc/testsuite/jit.dg/jit.exp index 8bf7e51..5697206 100644 --- a/gcc/testsuite/jit.dg/jit.exp +++ b/gcc/testsuite/jit.dg/jit.exp @@ -899,8 +899,41 @@ proc jit-verify-assembler-output { args } { pass "${asm_filename} output pattern test, ${dg-output-text}" verbose "Passed test for output pattern ${dg-output-text}" 3 } +} + +# Assuming that a .s file has been written out named +# OUTPUT_FILENAME, check that the argument doesn't match +# the output file. +proc jit-verify-assembler-output-not { args } { + verbose "jit-verify-assembler: $args" + + set dg-output-text [lindex $args 0] + verbose "dg-output-text: ${dg-output-text}" + + upvar 2 name name + verbose "name: $name" + + upvar 2 prog prog + verbose "prog: $prog" + set asm_filename [jit-get-output-filename $prog] + verbose " asm_filename: ${asm_filename}" + # Read the assembly file. + set f [open $asm_filename r] + set content [read $f] + close $f + + # Verify that the assembly matches the regex. + if { [regexp ${dg-output-text} $content] } { + fail "${asm_filename} output pattern test, is ${content}, should not match ${dg-output-text}" + verbose "Failed test for output pattern ${dg-output-text}" 3 + } else { + pass "${asm_filename} output pattern test, ${dg-output-text}" + verbose "Passed test for output pattern ${dg-output-text}" 3 + } } + + # Assuming that a .o file has been written out named # OUTPUT_FILENAME, invoke the driver to try to turn it into # an executable, and try to run the result. diff --git a/gcc/testsuite/jit.dg/test-alias-attribute.c b/gcc/testsuite/jit.dg/test-alias-attribute.c new file mode 100644 index 0000000..eb29003 --- /dev/null +++ b/gcc/testsuite/jit.dg/test-alias-attribute.c @@ -0,0 +1,50 @@ +/* { dg-do compile { target x86_64-*-* } } */ + +#include <stdlib.h> +#include <stdio.h> + +#include "libgccjit.h" + +#define TEST_COMPILING_TO_FILE +#define OUTPUT_KIND GCC_JIT_OUTPUT_KIND_ASSEMBLER +#define OUTPUT_FILENAME "output-of-test-alias-attribute.c.s" +#include "harness.h" + +void +create_code (gcc_jit_context *ctxt, void *user_data) +{ + /* Let's try to inject the equivalent of: + +void xxx () {} +void f () __attribute__ ((alias ("xxx"))); + */ + gcc_jit_type *void_type = + gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_VOID); + + /* Creating the `xxx` function. */ + gcc_jit_function *xxx_func = + gcc_jit_context_new_function (ctxt, NULL, + GCC_JIT_FUNCTION_EXPORTED, + void_type, + "xxx", + 0, NULL, + 0); + + /* Creating the `f` function. */ + gcc_jit_function *f_func = + gcc_jit_context_new_function (ctxt, NULL, + GCC_JIT_FUNCTION_IMPORTED, + void_type, + "f", + 0, NULL, + 0); + gcc_jit_function_add_string_attribute(f_func, GCC_JIT_FN_ATTRIBUTE_ALIAS, "xxx"); + + /* void xxx () {} */ + gcc_jit_block *block = gcc_jit_function_new_block (xxx_func, NULL); + gcc_jit_block_end_with_void_return (block, NULL); +} + +/* { dg-final { jit-verify-output-file-was-created "" } } */ +/* Check that the attribute was applied correctly */ +/* { dg-final { jit-verify-assembler-output ".set\\s+f,xxx" } } */ diff --git a/gcc/testsuite/jit.dg/test-always_inline-attribute.c b/gcc/testsuite/jit.dg/test-always_inline-attribute.c new file mode 100644 index 0000000..5c3f386 --- /dev/null +++ b/gcc/testsuite/jit.dg/test-always_inline-attribute.c @@ -0,0 +1,153 @@ +/* { dg-do compile { target x86_64-*-* } } */ + +#include <stdlib.h> +#include <stdio.h> + +#include "libgccjit.h" + +#define TEST_ESCHEWS_SET_OPTIONS +static void set_options (gcc_jit_context *ctxt, const char *argv0) +{ + // Set "-O0". + gcc_jit_context_set_int_option(ctxt, GCC_JIT_INT_OPTION_OPTIMIZATION_LEVEL, 0); +} + +#define TEST_COMPILING_TO_FILE +#define OUTPUT_KIND GCC_JIT_OUTPUT_KIND_ASSEMBLER +#define OUTPUT_FILENAME "output-of-test-always_inline-attribute.c.s" +#include "harness.h" + +gcc_jit_function* +create_function (gcc_jit_context *ctxt, + const char *func_name, + gcc_jit_type *int_type, + gcc_jit_type *pint_type) +{ + /* The `a` function argument */ + gcc_jit_param *a = gcc_jit_context_new_param (ctxt, NULL, pint_type, "a"); + gcc_jit_function *func = + gcc_jit_context_new_function (ctxt, NULL, + GCC_JIT_FUNCTION_INTERNAL, + int_type, + func_name, + 1, &a, + 0); + + gcc_jit_block *if_cond = + gcc_jit_function_new_block (func, "if_cond"); + gcc_jit_block *if_body = + gcc_jit_function_new_block (func, "if_body"); + gcc_jit_block *after_if = + gcc_jit_function_new_block (func, "after_if"); + + /* if (!a) */ + gcc_jit_block_end_with_conditional ( + if_cond, NULL, + gcc_jit_context_new_comparison ( + ctxt, NULL, + GCC_JIT_COMPARISON_EQ, + gcc_jit_param_as_rvalue (a), + gcc_jit_context_null (ctxt, pint_type)), + if_body, + after_if); + /* return -1; */ + gcc_jit_block_end_with_return ( + if_body, NULL, + gcc_jit_context_new_rvalue_from_int (ctxt, int_type, -1)); + + /* return *a; */ + gcc_jit_block_end_with_return ( + after_if, NULL, + gcc_jit_lvalue_as_rvalue ( + gcc_jit_rvalue_dereference ( + gcc_jit_param_as_rvalue (a), NULL))); + + return func; +} + + +void +create_code (gcc_jit_context *ctxt, void *user_data) +{ + /* Let's try to inject the equivalent of: +__attribute__ ((always_inline)) +static inline int removed (int *a) { + if (!a) { + return -1; + } + return *a; +} +static int not_removed (int *a) { + if (!a) { + return -1; + } + return *a; +} +int foo () { + int x = 0; + x += removed(NULL); + x += not_removed(NULL); + return x; +} + */ + gcc_jit_type *int_type = + gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_INT); + gcc_jit_type *pint_type = gcc_jit_type_get_pointer (int_type); + + /* Creating the `removed` function. */ + gcc_jit_function *removed_func = + create_function (ctxt, "removed", int_type, pint_type); + /* This one is to declare the function as "inline" */ + gcc_jit_function_add_attribute(removed_func, GCC_JIT_FN_ATTRIBUTE_INLINE); + /* __attribute__ ((always_inline)) */ + gcc_jit_function_add_attribute(removed_func, GCC_JIT_FN_ATTRIBUTE_ALWAYS_INLINE); + + /* Creating the `not_removed` function. */ + gcc_jit_function *not_removed_func = + create_function (ctxt, "not_removed", int_type, pint_type); + + /* Creating the `foo` function. */ + gcc_jit_function *foo_func = + gcc_jit_context_new_function (ctxt, NULL, + GCC_JIT_FUNCTION_EXPORTED, + int_type, + "foo", + 0, NULL, + 0); + + gcc_jit_block *foo_block = gcc_jit_function_new_block (foo_func, NULL); + + /* Build locals: */ + gcc_jit_lvalue *x = + gcc_jit_function_new_local (foo_func, NULL, int_type, "x"); + + /* int x = 0; */ + gcc_jit_block_add_assignment ( + foo_block, NULL, + x, + gcc_jit_context_new_rvalue_from_int (ctxt, int_type, 0)); + + /* x += removed(NULL); */ + gcc_jit_rvalue *null = gcc_jit_context_null (ctxt, pint_type); + gcc_jit_block_add_assignment_op ( + foo_block, NULL, + x, + GCC_JIT_BINARY_OP_PLUS, + gcc_jit_context_new_call (ctxt, NULL, removed_func, 1, &null)); + + /* x += not_removed(NULL); */ + gcc_jit_block_add_assignment_op ( + foo_block, NULL, + x, + GCC_JIT_BINARY_OP_PLUS, + gcc_jit_context_new_call (ctxt, NULL, not_removed_func, 1, &null)); + + /* return x; */ + gcc_jit_block_end_with_return (foo_block, NULL, gcc_jit_lvalue_as_rvalue(x)); +} + +/* { dg-final { jit-verify-output-file-was-created "" } } */ +/* Check that the "removed" function was inlined, but not the others */ +/* { dg-final { jit-verify-assembler-output-not ".type\\s+removed,\\s+@function" } } */ +/* { dg-final { jit-verify-assembler-output ".type\\s+not_removed,\\s+@function" } } */ +/* { dg-final { jit-verify-assembler-output ".type\\s+foo,\\s+@function" } } */ diff --git a/gcc/testsuite/jit.dg/test-cold-attribute.c b/gcc/testsuite/jit.dg/test-cold-attribute.c new file mode 100644 index 0000000..0c76d3e --- /dev/null +++ b/gcc/testsuite/jit.dg/test-cold-attribute.c @@ -0,0 +1,52 @@ +/* { dg-do compile { target x86_64-*-* } } */ + +#include <stdlib.h> +#include <stdio.h> + +#include "libgccjit.h" + +#define TEST_ESCHEWS_SET_OPTIONS +static void set_options (gcc_jit_context *ctxt, const char *argv0) +{ + // Set "-O2". + gcc_jit_context_set_int_option(ctxt, GCC_JIT_INT_OPTION_OPTIMIZATION_LEVEL, 2); +} + +#define TEST_COMPILING_TO_FILE +#define OUTPUT_KIND GCC_JIT_OUTPUT_KIND_ASSEMBLER +#define OUTPUT_FILENAME "output-of-test-cold-attribute.c.s" +#include "harness.h" + +void +create_code (gcc_jit_context *ctxt, void *user_data) +{ + /* Let's try to inject the equivalent of: +int +__attribute__ ((cold)) +t() +{ + return -1; +} + + */ + gcc_jit_type *int_type = + gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_INT); + + gcc_jit_function *func_t = + gcc_jit_context_new_function (ctxt, NULL, + GCC_JIT_FUNCTION_EXPORTED, + int_type, + "t", + 0, NULL, + 0); + gcc_jit_function_add_attribute(func_t, GCC_JIT_FN_ATTRIBUTE_COLD); + gcc_jit_block *block = gcc_jit_function_new_block (func_t, NULL); + gcc_jit_rvalue *ret = gcc_jit_context_new_rvalue_from_int (ctxt, + int_type, + -1); + + gcc_jit_block_end_with_return (block, NULL, ret); +} + +/* { dg-final { jit-verify-output-file-was-created "" } } */ +/* { dg-final { jit-verify-assembler-output "orl" } } */ diff --git a/gcc/testsuite/jit.dg/test-const-attribute.c b/gcc/testsuite/jit.dg/test-const-attribute.c new file mode 100644 index 0000000..7b98041 --- /dev/null +++ b/gcc/testsuite/jit.dg/test-const-attribute.c @@ -0,0 +1,132 @@ +/* { dg-do compile { target x86_64-*-* } } */ + +#include <stdlib.h> +#include <stdio.h> + +#include "libgccjit.h" + +#define TEST_ESCHEWS_SET_OPTIONS +static void set_options (gcc_jit_context *ctxt, const char *argv0) +{ + // Set "-O3". + gcc_jit_context_set_int_option(ctxt, GCC_JIT_INT_OPTION_OPTIMIZATION_LEVEL, 3); +} + +#define TEST_COMPILING_TO_FILE +#define OUTPUT_KIND GCC_JIT_OUTPUT_KIND_ASSEMBLER +#define OUTPUT_FILENAME "output-of-test-const-attribute.c.s" +#include "harness.h" + +void +create_code (gcc_jit_context *ctxt, void *user_data) +{ + /* Let's try to inject the equivalent of: +__attribute__ ((const)) +int foo (int x); +int xxx(void) +{ + int x = 45; + int sum = 0; + + while (x >>= 1) + sum += foo (x) * 2; + return sum; +} + */ + gcc_jit_type *int_type = + gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_INT); + + /* Creating the `foo` function. */ + gcc_jit_param *n = + gcc_jit_context_new_param (ctxt, NULL, int_type, "x"); + gcc_jit_param *params[1] = {n}; + gcc_jit_function *foo_func = + gcc_jit_context_new_function (ctxt, NULL, + GCC_JIT_FUNCTION_IMPORTED, + int_type, + "foo", + 1, params, + 0); + gcc_jit_function_add_attribute(foo_func, GCC_JIT_FN_ATTRIBUTE_CONST); + + /* Creating the `xxx` function. */ + gcc_jit_function *xxx_func = + gcc_jit_context_new_function (ctxt, NULL, + GCC_JIT_FUNCTION_EXPORTED, + int_type, + "xxx", + 0, NULL, + 0); + + gcc_jit_block *block = gcc_jit_function_new_block (xxx_func, NULL); + + /* Build locals: */ + gcc_jit_lvalue *x = + gcc_jit_function_new_local (xxx_func, NULL, int_type, "x"); + gcc_jit_lvalue *sum = + gcc_jit_function_new_local (xxx_func, NULL, int_type, "sum"); + + /* int x = 45 */ + gcc_jit_block_add_assignment ( + block, NULL, + x, + gcc_jit_context_new_rvalue_from_int (ctxt, int_type, 45)); + /* int sum = 0 */ + gcc_jit_block_add_assignment ( + block, NULL, + sum, + gcc_jit_context_new_rvalue_from_int (ctxt, int_type, 0)); + + /* while (x >>= 1) { sum += foo (x) * 2; } */ + gcc_jit_block *loop_cond = + gcc_jit_function_new_block (xxx_func, "loop_cond"); + gcc_jit_block *loop_body = + gcc_jit_function_new_block (xxx_func, "loop_body"); + gcc_jit_block *after_loop = + gcc_jit_function_new_block (xxx_func, "after_loop"); + + gcc_jit_block_end_with_jump (block, NULL, loop_cond); + + + /* if (x >>= 1) */ + /* Since gccjit doesn't (yet?) have support for `>>=` operator, we will decompose it into: + `if (x = x >> 1)` */ + gcc_jit_block_add_assignment_op ( + loop_cond, NULL, + x, + GCC_JIT_BINARY_OP_RSHIFT, + gcc_jit_context_new_rvalue_from_int (ctxt, int_type, 1)); + /* The condition itself */ + gcc_jit_block_end_with_conditional ( + loop_cond, NULL, + gcc_jit_context_new_comparison ( + ctxt, NULL, + GCC_JIT_COMPARISON_NE, + gcc_jit_lvalue_as_rvalue (x), + gcc_jit_context_new_rvalue_from_int (ctxt, int_type, 0)), + after_loop, + loop_body); + + /* sum += foo (x) * 2; */ + gcc_jit_rvalue *arg = gcc_jit_lvalue_as_rvalue(x); + gcc_jit_block_add_assignment_op ( + loop_body, NULL, + x, + GCC_JIT_BINARY_OP_PLUS, + gcc_jit_context_new_binary_op ( + ctxt, NULL, + GCC_JIT_BINARY_OP_MULT, int_type, + gcc_jit_context_new_call (ctxt, NULL, foo_func, 1, &arg), + gcc_jit_context_new_rvalue_from_int ( + ctxt, + int_type, + 2))); + gcc_jit_block_end_with_jump (loop_body, NULL, loop_cond); + + /* return sum; */ + gcc_jit_block_end_with_return (after_loop, NULL, gcc_jit_lvalue_as_rvalue(sum)); +} + +/* { dg-final { jit-verify-output-file-was-created "" } } */ +/* Check that the loop was optimized away */ +/* { dg-final { jit-verify-assembler-output-not "jne" } } */ diff --git a/gcc/testsuite/jit.dg/test-ggc-bugfix.c b/gcc/testsuite/jit.dg/test-ggc-bugfix.c new file mode 100644 index 0000000..59eb374 --- /dev/null +++ b/gcc/testsuite/jit.dg/test-ggc-bugfix.c @@ -0,0 +1,34 @@ +/* { dg-do compile { target x86_64-*-* } } */ + +#include <stdlib.h> +#include <stdio.h> + +#include "libgccjit.h" + +#include "harness.h" + +void +create_code (gcc_jit_context *ctxt, void *user_data) +{ + gcc_jit_context_add_command_line_option (ctxt, "-flto"); + gcc_jit_context_add_driver_option (ctxt, "-nostdlib"); + + gcc_jit_type *type_int = gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_INT); + gcc_jit_param *params_for_func_main[0] = { + }; + gcc_jit_function *func_main = + gcc_jit_context_new_function (ctxt, NULL, GCC_JIT_FUNCTION_EXPORTED, + type_int, "main", 0, params_for_func_main, + 0); + gcc_jit_block *block_start = + gcc_jit_function_new_block (func_main, "start"); + gcc_jit_rvalue *rvalue__int_42 = + gcc_jit_context_new_rvalue_from_int (ctxt, type_int, 42); + gcc_jit_block_end_with_return (block_start, NULL, rvalue__int_42); +} + +void +verify_code (gcc_jit_context *ctxt, gcc_jit_result *result) +{ + CHECK_NON_NULL (result); +} diff --git a/gcc/testsuite/jit.dg/test-noinline-attribute.c b/gcc/testsuite/jit.dg/test-noinline-attribute.c new file mode 100644 index 0000000..eac6cae --- /dev/null +++ b/gcc/testsuite/jit.dg/test-noinline-attribute.c @@ -0,0 +1,119 @@ +/* { dg-do compile { target x86_64-*-* } } */ + +#include <stdlib.h> +#include <stdio.h> + +#include "libgccjit.h" + +#define TEST_ESCHEWS_SET_OPTIONS +static void set_options (gcc_jit_context *ctxt, const char *argv0) +{ + // Set "-O2". + gcc_jit_context_set_int_option(ctxt, GCC_JIT_INT_OPTION_OPTIMIZATION_LEVEL, 2); +} + +#define TEST_COMPILING_TO_FILE +#define OUTPUT_KIND GCC_JIT_OUTPUT_KIND_ASSEMBLER +#define OUTPUT_FILENAME "output-of-test-noinline-attribute.c.s" +#include "harness.h" + +gcc_jit_function* +create_function (gcc_jit_context *ctxt, + const char *func_name, + gcc_jit_type *int_type, + int returned_value) +{ + gcc_jit_function *func + = gcc_jit_context_new_function(ctxt, NULL, + GCC_JIT_FUNCTION_INTERNAL, + int_type, + func_name, + 0, NULL, + 0); + gcc_jit_block *block = gcc_jit_function_new_block (func, NULL); + + gcc_jit_block_add_extended_asm (block, NULL, ""); + gcc_jit_block_end_with_return (block, NULL, + gcc_jit_context_new_rvalue_from_int (ctxt, int_type, returned_value)); + + return func; +} + + +void +create_code (gcc_jit_context *ctxt, void *user_data) +{ + /* Let's try to inject the equivalent of: +__attribute__ ((noinline)) +static int not_removed() { + asm(""); + return 1; +} +static int removed() { + asm(""); + return 2; +} +int foo () { + int x = 0; + x += removed(); + x += not_removed(); + return x; +} + */ + gcc_jit_type *int_type = + gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_INT); + + /* Creating the `not_removed` function. */ + gcc_jit_function *not_removed_func = + create_function (ctxt, "not_removed", int_type, 1); + /* __attribute__ ((no_inline)) */ + gcc_jit_function_add_attribute(not_removed_func, GCC_JIT_FN_ATTRIBUTE_NOINLINE); + + /* Creating the `removed` function. */ + gcc_jit_function *removed_func = + create_function (ctxt, "removed", int_type, 2); + + /* Creating the `foo` function. */ + gcc_jit_function *foo_func = + gcc_jit_context_new_function (ctxt, NULL, + GCC_JIT_FUNCTION_EXPORTED, + int_type, + "foo", + 0, NULL, + 0); + + gcc_jit_block *foo_block = gcc_jit_function_new_block (foo_func, NULL); + + /* Build locals: */ + gcc_jit_lvalue *x = + gcc_jit_function_new_local (foo_func, NULL, int_type, "x"); + + /* int x = 0; */ + gcc_jit_block_add_assignment ( + foo_block, NULL, + x, + gcc_jit_context_new_rvalue_from_int (ctxt, int_type, 0)); + + /* x += removed(); */ + gcc_jit_block_add_assignment_op ( + foo_block, NULL, + x, + GCC_JIT_BINARY_OP_PLUS, + gcc_jit_context_new_call (ctxt, NULL, removed_func, 0, NULL)); + + /* x += not_removed(); */ + gcc_jit_block_add_assignment_op ( + foo_block, NULL, + x, + GCC_JIT_BINARY_OP_PLUS, + gcc_jit_context_new_call (ctxt, NULL, not_removed_func, 0, NULL)); + + /* return x; */ + gcc_jit_block_end_with_return (foo_block, NULL, gcc_jit_lvalue_as_rvalue(x)); +} + +/* { dg-final { jit-verify-output-file-was-created "" } } */ +/* Check that the "removed" function was inlined, but not the others */ +/* { dg-final { jit-verify-assembler-output-not ".type\\s+removed.isra.0,\\s+@function" } } */ +/* { dg-final { jit-verify-assembler-output ".type\\s+not_removed.isra.0,\\s+@function" } } */ +/* { dg-final { jit-verify-assembler-output ".type\\s+foo,\\s+@function" } } */ diff --git a/gcc/testsuite/jit.dg/test-nonnull-attribute.c b/gcc/testsuite/jit.dg/test-nonnull-attribute.c new file mode 100644 index 0000000..42c38ac --- /dev/null +++ b/gcc/testsuite/jit.dg/test-nonnull-attribute.c @@ -0,0 +1,92 @@ +/* { dg-do compile { target x86_64-*-* } } */ + +#include <stdlib.h> +#include <stdio.h> + +#include "libgccjit.h" + +#define TEST_ESCHEWS_SET_OPTIONS +static void set_options (gcc_jit_context *ctxt, const char *argv0) +{ + // Set "-O2". + gcc_jit_context_set_int_option(ctxt, GCC_JIT_INT_OPTION_OPTIMIZATION_LEVEL, 2); +} + +#define TEST_COMPILING_TO_FILE +#define OUTPUT_KIND GCC_JIT_OUTPUT_KIND_ASSEMBLER +#define OUTPUT_FILENAME "output-of-test-nonnull.c.s" +#include "harness.h" + +void +create_code (gcc_jit_context *ctxt, void *user_data) +{ + /* Let's try to inject the equivalent of: + +__attribute__((nonnull(1))) +int t(int *a) { + if (!a) { + return -1; + } + return *a; +} + */ + gcc_jit_type *int_type = + gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_INT); + gcc_jit_type *pint_type = gcc_jit_type_get_pointer(int_type); + + gcc_jit_param *a = + gcc_jit_context_new_param (ctxt, NULL, pint_type, "a"); + + gcc_jit_function *func_t = + gcc_jit_context_new_function (ctxt, NULL, + GCC_JIT_FUNCTION_EXPORTED, + int_type, + "t", + 1, &a, + 0); + /* Adding `nonnull(1)` attribute. */ + int indexes[1] = {1}; + gcc_jit_function_add_integer_array_attribute ( + func_t, + GCC_JIT_FN_ATTRIBUTE_NONNULL, + indexes, + 1 + ); + + /* if (!a) { + return -1; + } */ + gcc_jit_block *if_cond = + gcc_jit_function_new_block (func_t, "if_cond"); + gcc_jit_block *if_body = + gcc_jit_function_new_block (func_t, "if_body"); + gcc_jit_block *after_if = + gcc_jit_function_new_block (func_t, "after_if"); + + /* if (!a) */ + gcc_jit_block_end_with_conditional ( + if_cond, NULL, + gcc_jit_context_new_comparison ( + ctxt, NULL, + GCC_JIT_COMPARISON_EQ, + gcc_jit_param_as_rvalue (a), + gcc_jit_context_null (ctxt, pint_type)), + if_body, + after_if); + /* return -1; */ + gcc_jit_block_end_with_return ( + if_body, NULL, + gcc_jit_context_new_rvalue_from_int (ctxt, int_type, -1)); + + /* return *a; */ + gcc_jit_block_end_with_return ( + after_if, NULL, + gcc_jit_lvalue_as_rvalue ( + gcc_jit_rvalue_dereference ( + gcc_jit_param_as_rvalue (a), NULL))); +} + +/* { dg-final { jit-verify-output-file-was-created "" } } */ +/* Check that the "if block" was optimized away */ +/* { dg-final { jit-verify-assembler-output-not "testq" } } */ +/* { dg-final { jit-verify-assembler-output-not "-1" } } */ diff --git a/gcc/testsuite/jit.dg/test-pure-attribute.c b/gcc/testsuite/jit.dg/test-pure-attribute.c new file mode 100644 index 0000000..0c773bc --- /dev/null +++ b/gcc/testsuite/jit.dg/test-pure-attribute.c @@ -0,0 +1,132 @@ +/* { dg-do compile { target x86_64-*-* } } */ + +#include <stdlib.h> +#include <stdio.h> + +#include "libgccjit.h" + +#define TEST_ESCHEWS_SET_OPTIONS +static void set_options (gcc_jit_context *ctxt, const char *argv0) +{ + // Set "-O3". + gcc_jit_context_set_int_option(ctxt, GCC_JIT_INT_OPTION_OPTIMIZATION_LEVEL, 3); +} + +#define TEST_COMPILING_TO_FILE +#define OUTPUT_KIND GCC_JIT_OUTPUT_KIND_ASSEMBLER +#define OUTPUT_FILENAME "output-of-test-pure-attribute.c.s" +#include "harness.h" + +void +create_code (gcc_jit_context *ctxt, void *user_data) +{ + /* Let's try to inject the equivalent of: +__attribute__ ((pure)) +int foo (int x); +int xxx(void) +{ + int x = 45; + int sum = 0; + + while (x >>= 1) + sum += foo (x) * 2; + return sum; +} + */ + gcc_jit_type *int_type = + gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_INT); + + /* Creating the `foo` function. */ + gcc_jit_param *n = + gcc_jit_context_new_param (ctxt, NULL, int_type, "x"); + gcc_jit_param *params[1] = {n}; + gcc_jit_function *foo_func = + gcc_jit_context_new_function (ctxt, NULL, + GCC_JIT_FUNCTION_IMPORTED, + int_type, + "foo", + 1, params, + 0); + gcc_jit_function_add_attribute(foo_func, GCC_JIT_FN_ATTRIBUTE_PURE); + + /* Creating the `xxx` function. */ + gcc_jit_function *xxx_func = + gcc_jit_context_new_function (ctxt, NULL, + GCC_JIT_FUNCTION_EXPORTED, + int_type, + "xxx", + 0, NULL, + 0); + + gcc_jit_block *block = gcc_jit_function_new_block (xxx_func, NULL); + + /* Build locals: */ + gcc_jit_lvalue *x = + gcc_jit_function_new_local (xxx_func, NULL, int_type, "x"); + gcc_jit_lvalue *sum = + gcc_jit_function_new_local (xxx_func, NULL, int_type, "sum"); + + /* int x = 45 */ + gcc_jit_block_add_assignment ( + block, NULL, + x, + gcc_jit_context_new_rvalue_from_int (ctxt, int_type, 45)); + /* int sum = 0 */ + gcc_jit_block_add_assignment ( + block, NULL, + sum, + gcc_jit_context_new_rvalue_from_int (ctxt, int_type, 0)); + + /* while (x >>= 1) { sum += foo (x) * 2; } */ + gcc_jit_block *loop_cond = + gcc_jit_function_new_block (xxx_func, "loop_cond"); + gcc_jit_block *loop_body = + gcc_jit_function_new_block (xxx_func, "loop_body"); + gcc_jit_block *after_loop = + gcc_jit_function_new_block (xxx_func, "after_loop"); + + gcc_jit_block_end_with_jump (block, NULL, loop_cond); + + + /* if (x >>= 1) */ + /* Since gccjit doesn't (yet?) have support for `>>=` operator, we will decompose it into: + `if (x = x >> 1)` */ + gcc_jit_block_add_assignment_op ( + loop_cond, NULL, + x, + GCC_JIT_BINARY_OP_RSHIFT, + gcc_jit_context_new_rvalue_from_int (ctxt, int_type, 1)); + /* The condition itself */ + gcc_jit_block_end_with_conditional ( + loop_cond, NULL, + gcc_jit_context_new_comparison ( + ctxt, NULL, + GCC_JIT_COMPARISON_NE, + gcc_jit_lvalue_as_rvalue (x), + gcc_jit_context_new_rvalue_from_int (ctxt, int_type, 0)), + after_loop, + loop_body); + + /* sum += foo (x) * 2; */ + gcc_jit_rvalue *arg = gcc_jit_lvalue_as_rvalue(x); + gcc_jit_block_add_assignment_op ( + loop_body, NULL, + x, + GCC_JIT_BINARY_OP_PLUS, + gcc_jit_context_new_binary_op ( + ctxt, NULL, + GCC_JIT_BINARY_OP_MULT, int_type, + gcc_jit_context_new_call (ctxt, NULL, foo_func, 1, &arg), + gcc_jit_context_new_rvalue_from_int ( + ctxt, + int_type, + 2))); + gcc_jit_block_end_with_jump (loop_body, NULL, loop_cond); + + /* return sum; */ + gcc_jit_block_end_with_return (after_loop, NULL, gcc_jit_lvalue_as_rvalue(sum)); +} + +/* { dg-final { jit-verify-output-file-was-created "" } } */ +/* Check that the loop was optimized away */ +/* { dg-final { jit-verify-assembler-output-not "jne" } } */ diff --git a/gcc/testsuite/jit.dg/test-restrict-attribute.c b/gcc/testsuite/jit.dg/test-restrict-attribute.c new file mode 100644 index 0000000..d724472 --- /dev/null +++ b/gcc/testsuite/jit.dg/test-restrict-attribute.c @@ -0,0 +1,75 @@ +/* { dg-do compile { target x86_64-*-* } } */ + +#include <stdlib.h> +#include <stdio.h> + +#include "libgccjit.h" + +#define TEST_ESCHEWS_SET_OPTIONS +static void set_options (gcc_jit_context *ctxt, const char *argv0) +{ + // Set "-O3". + gcc_jit_context_set_int_option(ctxt, GCC_JIT_INT_OPTION_OPTIMIZATION_LEVEL, 3); +} + +#define TEST_COMPILING_TO_FILE +#define OUTPUT_KIND GCC_JIT_OUTPUT_KIND_ASSEMBLER +#define OUTPUT_FILENAME "output-of-test-restrict-attribute.c.s" +#include "harness.h" + +void +create_code (gcc_jit_context *ctxt, void *user_data) +{ + /* Let's try to inject the equivalent of: +void t(int *__restrict__ a, int *__restrict__ b, char *__restrict__ c) { + *a += *c; + *b += *c; +} + */ + gcc_jit_type *int_type = + gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_INT); + gcc_jit_type *pint_type = gcc_jit_type_get_pointer(int_type); + gcc_jit_type *pint_restrict_type = gcc_jit_type_get_restrict(pint_type); + + gcc_jit_type *void_type = + gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_VOID); + + gcc_jit_param *a = + gcc_jit_context_new_param (ctxt, NULL, pint_restrict_type, "a"); + gcc_jit_param *b = + gcc_jit_context_new_param (ctxt, NULL, pint_restrict_type, "b"); + gcc_jit_param *c = + gcc_jit_context_new_param (ctxt, NULL, pint_restrict_type, "c"); + gcc_jit_param *params[3] = {a, b, c}; + + gcc_jit_function *func_t = + gcc_jit_context_new_function (ctxt, NULL, + GCC_JIT_FUNCTION_EXPORTED, + void_type, + "t", + 3, params, + 0); + + gcc_jit_block *block = gcc_jit_function_new_block (func_t, NULL); + + /* *a += *c; */ + gcc_jit_block_add_assignment_op ( + block, NULL, + gcc_jit_rvalue_dereference (gcc_jit_param_as_rvalue (a), NULL), + GCC_JIT_BINARY_OP_PLUS, + gcc_jit_lvalue_as_rvalue ( + gcc_jit_rvalue_dereference (gcc_jit_param_as_rvalue (c), NULL))); + /* *b += *c; */ + gcc_jit_block_add_assignment_op ( + block, NULL, + gcc_jit_rvalue_dereference (gcc_jit_param_as_rvalue (b), NULL), + GCC_JIT_BINARY_OP_PLUS, + gcc_jit_lvalue_as_rvalue ( + gcc_jit_rvalue_dereference (gcc_jit_param_as_rvalue (c), NULL))); + + gcc_jit_block_end_with_void_return (block, NULL); +} + +/* { dg-final { jit-verify-output-file-was-created "" } } */ +/* { dg-final { jit-verify-assembler-output "addl\\s+%eax,\\s+(%rdi) +\\s+addl\\s+%eax,\\s+(%rsi)" } } */ diff --git a/gcc/testsuite/jit.dg/test-used-attribute.c b/gcc/testsuite/jit.dg/test-used-attribute.c new file mode 100644 index 0000000..cb20952 --- /dev/null +++ b/gcc/testsuite/jit.dg/test-used-attribute.c @@ -0,0 +1,112 @@ +/* { dg-do compile { target x86_64-*-* } } */ + +#include <stdlib.h> +#include <stdio.h> + +#include "libgccjit.h" + +#define TEST_ESCHEWS_SET_OPTIONS +static void set_options (gcc_jit_context *ctxt, const char *argv0) +{ + // Set "-O2". + gcc_jit_context_set_int_option(ctxt, GCC_JIT_INT_OPTION_OPTIMIZATION_LEVEL, 2); +} + +#define TEST_COMPILING_TO_FILE +#define OUTPUT_KIND GCC_JIT_OUTPUT_KIND_ASSEMBLER +#define OUTPUT_FILENAME "output-of-test-used-attribute.c.s" +#include "harness.h" + +gcc_jit_function* +create_function (gcc_jit_context *ctxt, + const char *func_name, + gcc_jit_type *int_type, + int returned_value) +{ + gcc_jit_function *func = + gcc_jit_context_new_function (ctxt, NULL, + GCC_JIT_FUNCTION_INTERNAL, + int_type, + func_name, + 0, NULL, + 0); + + gcc_jit_block *foo_block = gcc_jit_function_new_block (func, NULL); + gcc_jit_block_end_with_return (foo_block, NULL, + gcc_jit_context_new_rvalue_from_int (ctxt, int_type, returned_value)); + + return func; +} + + +void +create_code (gcc_jit_context *ctxt, void *user_data) +{ + /* Let's try to inject the equivalent of: +__attribute__((used)) +static int not_removed() { return 1; } +static int removed() { return 2; } +int foo() { + int x = 0; + x += not_removed(); + x += removed(); + return x; +} + */ + gcc_jit_type *int_type = + gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_INT); + + /* Creating the `not_removed` function. */ + gcc_jit_function *not_removed_func = + create_function (ctxt, "not_removed", int_type, 1); + /* __attribute__ ((used)) */ + gcc_jit_function_add_attribute(not_removed_func, GCC_JIT_FN_ATTRIBUTE_USED); + + /* Creating the `removed` function. */ + gcc_jit_function *removed_func = + create_function (ctxt, "removed", int_type, 2); + + /* Creating the `foo` function. */ + gcc_jit_function *foo_func = + gcc_jit_context_new_function (ctxt, NULL, + GCC_JIT_FUNCTION_EXPORTED, + int_type, + "foo", + 0, NULL, + 0); + + gcc_jit_block *foo_block = gcc_jit_function_new_block (foo_func, NULL); + + /* Build locals: */ + gcc_jit_lvalue *x = + gcc_jit_function_new_local (foo_func, NULL, int_type, "x"); + + /* int x = 0; */ + gcc_jit_block_add_assignment ( + foo_block, NULL, + x, + gcc_jit_context_new_rvalue_from_int (ctxt, int_type, 0)); + + /* x += removed(); */ + gcc_jit_block_add_assignment_op ( + foo_block, NULL, + x, + GCC_JIT_BINARY_OP_PLUS, + gcc_jit_context_new_call (ctxt, NULL, removed_func, 0, NULL)); + + /* x += not_removed(); */ + gcc_jit_block_add_assignment_op ( + foo_block, NULL, + x, + GCC_JIT_BINARY_OP_PLUS, + gcc_jit_context_new_call (ctxt, NULL, not_removed_func, 0, NULL)); + + /* return x; */ + gcc_jit_block_end_with_return (foo_block, NULL, gcc_jit_lvalue_as_rvalue(x)); +} + +/* { dg-final { jit-verify-output-file-was-created "" } } */ +/* Check that the "removed" function was inlined, but not the others */ +/* { dg-final { jit-verify-assembler-output-not ".type\\s+removed,\\s+@function" } } */ +/* { dg-final { jit-verify-assembler-output ".type\\s+not_removed,\\s+@function" } } */ +/* { dg-final { jit-verify-assembler-output ".type\\s+foo,\\s+@function" } } */ diff --git a/gcc/testsuite/jit.dg/test-variable-attribute.c b/gcc/testsuite/jit.dg/test-variable-attribute.c new file mode 100644 index 0000000..ea854ff --- /dev/null +++ b/gcc/testsuite/jit.dg/test-variable-attribute.c @@ -0,0 +1,46 @@ +/* { dg-do compile { target x86_64-*-* } } */ + +#include <stdlib.h> +#include <stdio.h> + +#include "libgccjit.h" + +#define TEST_COMPILING_TO_FILE +#define OUTPUT_KIND GCC_JIT_OUTPUT_KIND_ASSEMBLER +#define OUTPUT_FILENAME "output-of-test-variable-attribute.c.s" +#include "harness.h" + +void +create_code (gcc_jit_context *ctxt, void *user_data) +{ + /* Let's try to inject the equivalent of: + +int PRIVATE __attribute__ ((visibility ("hidden"))) = 42; +int PUBLIC = 12; + */ + gcc_jit_type *int_type = + gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_INT); + + /* Creating the `PRIVATE` variable. */ + gcc_jit_lvalue *private = gcc_jit_context_new_global (ctxt, + NULL, GCC_JIT_GLOBAL_EXPORTED, int_type, "PRIVATE"); + gcc_jit_lvalue_add_string_attribute (private, + GCC_JIT_VARIABLE_ATTRIBUTE_VISIBILITY, "hidden"); + gcc_jit_rvalue *rval = gcc_jit_context_new_rvalue_from_int ( + ctxt, int_type, 42); + gcc_jit_global_set_initializer_rvalue (private, rval); + + /* Creating the `PUBLIC` variable. */ + gcc_jit_lvalue *public = gcc_jit_context_new_global (ctxt, + NULL, GCC_JIT_GLOBAL_EXPORTED, int_type, "PUBLIC"); + gcc_jit_rvalue *rval2 = gcc_jit_context_new_rvalue_from_int ( + ctxt, int_type, 12); + gcc_jit_global_set_initializer_rvalue (public, rval2); +} + +/* { dg-final { jit-verify-output-file-was-created "" } } */ +/* Check that the attribute was applied correctly */ +/* { dg-final { jit-verify-assembler-output ".hidden\\s+PRIVATE" } } */ +/* { dg-final { jit-verify-assembler-output ".globl\\s+PRIVATE" } } */ +/* { dg-final { jit-verify-assembler-output-not ".hidden\\s+PUBLIC" } } */ +/* { dg-final { jit-verify-assembler-output ".globl\\s+PUBLIC" } } */ diff --git a/gcc/testsuite/jit.dg/test-weak-attribute.c b/gcc/testsuite/jit.dg/test-weak-attribute.c new file mode 100644 index 0000000..546ade1 --- /dev/null +++ b/gcc/testsuite/jit.dg/test-weak-attribute.c @@ -0,0 +1,41 @@ +/* { dg-do compile { target x86_64-*-* } } */ + +#include <stdlib.h> +#include <stdio.h> + +#include "libgccjit.h" + +#define TEST_COMPILING_TO_FILE +#define OUTPUT_KIND GCC_JIT_OUTPUT_KIND_ASSEMBLER +#define OUTPUT_FILENAME "output-of-test-weak-attribute.c.s" +#include "harness.h" + +void +create_code (gcc_jit_context *ctxt, void *user_data) +{ + /* Let's try to inject the equivalent of: + +__attribute__ ((weak)) +void f () {} + */ + gcc_jit_type *void_type = + gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_VOID); + + /* Creating the `f` function. */ + gcc_jit_function *f_func = + gcc_jit_context_new_function (ctxt, NULL, + GCC_JIT_FUNCTION_EXPORTED, + void_type, + "f", + 0, NULL, + 0); + gcc_jit_function_add_attribute(f_func, GCC_JIT_FN_ATTRIBUTE_WEAK); + + /* void f () {} */ + gcc_jit_block *block = gcc_jit_function_new_block (f_func, NULL); + gcc_jit_block_end_with_void_return (block, NULL); +} + +/* { dg-final { jit-verify-output-file-was-created "" } } */ +/* Check that the attribute was applied correctly */ +/* { dg-final { jit-verify-assembler-output ".weak\\s+f" } } */ diff --git a/gcc/testsuite/lib/target-supports.exp b/gcc/testsuite/lib/target-supports.exp index b27c30b..fac32fb 100644 --- a/gcc/testsuite/lib/target-supports.exp +++ b/gcc/testsuite/lib/target-supports.exp @@ -3858,6 +3858,15 @@ proc check_effective_target_bitint575 { } { } "-std=c23"] } +# Return 1 if the target supports _BitInt(65535), 0 otherwise. + +proc check_effective_target_bitint65535 { } { + return [check_no_compiler_messages bitint65535 object { + _BitInt (2) a = 1wb; + unsigned _BitInt (65535) b = 0uwb; + } "-std=c23"] +} + # Return 1 if the target supports compiling decimal floating point, # 0 otherwise. @@ -7926,6 +7935,30 @@ proc check_effective_target_xorsign { } { || [istarget aarch64*-*-*] || [istarget arm*-*-*] }}] } +# Return 1 if the target plus current options supports folding of +# copysign into IFN_COPYSIGN. +# +# This won't change for different subtargets so cache the result. + +proc check_effective_target_ifn_copysign { } { + return [check_cached_effective_target_indexed ifn_copysign { + expr { + (([istarget i?86-*-*] || [istarget x86_64-*-*]) + && [is-effective-target sse]) + || ([istarget loongarch*-*-*] + && [check_effective_target_hard_float]) + || ([istarget powerpc*-*-*] + && ![istarget powerpc-*-linux*paired*]) + || [istarget alpha*-*-*] + || [istarget aarch64*-*-*] + || [is-effective-target arm_neon] + || ([istarget s390*-*-*] + && [check_effective_target_s390_vx]) + || ([istarget riscv*-*-*] + && [check_effective_target_hard_float]) + }}] +} + # Return 1 if the target plus current options supports a vector # widening summation of *short* args into *int* result, 0 otherwise. # @@ -8001,7 +8034,6 @@ proc check_effective_target_vect_widen_mult_qi_to_hi { } { || ([istarget aarch64*-*-*] && ![check_effective_target_aarch64_sve]) || [is-effective-target arm_neon] - || [is-effective-target loongarch*-*-*] || ([istarget s390*-*-*] && [check_effective_target_s390_vx])) || [istarget amdgcn-*-*] }}] @@ -8026,7 +8058,6 @@ proc check_effective_target_vect_widen_mult_hi_to_si { } { && ![check_effective_target_aarch64_sve]) || [istarget i?86-*-*] || [istarget x86_64-*-*] || [is-effective-target arm_neon] - || [is-effective-target loongarch*-*-*] || ([istarget s390*-*-*] && [check_effective_target_s390_vx])) || [istarget amdgcn-*-*] }}] @@ -9042,9 +9073,9 @@ proc check_effective_target_vect_int_mult { } { proc check_effective_target_vect_long_mult { } { if { [istarget i?86-*-*] || [istarget x86_64-*-*] - || (([istarget powerpc*-*-*] - && ![istarget powerpc-*-linux*paired*]) - && [check_effective_target_ilp32]) + || ([istarget powerpc*-*-*] + && [check_effective_target_powerpc_vsx_ok] + && [check_effective_target_has_arch_pwr10]) || [is-effective-target arm_neon] || ([istarget sparc*-*-*] && [check_effective_target_ilp32]) || [istarget aarch64*-*-*] diff --git a/gcc/toplev.cc b/gcc/toplev.cc index 0c2994e..55636ff 100644 --- a/gcc/toplev.cc +++ b/gcc/toplev.cc @@ -75,6 +75,7 @@ along with GCC; see the file COPYING3. If not see #include "symbol-summary.h" #include "tree-vrp.h" #include "ipa-prop.h" +#include "ipa-utils.h" #include "gcse.h" #include "omp-offload.h" #include "edit-context.h" @@ -2359,7 +2360,11 @@ toplev::finalize (void) ipa_fnsummary_cc_finalize (); ipa_modref_cc_finalize (); ipa_edge_modifications_finalize (); + ipa_icf_cc_finalize (); + ipa_prop_cc_finalize (); + ipa_profile_cc_finalize (); + ipa_sra_cc_finalize (); cgraph_cc_finalize (); cgraphunit_cc_finalize (); symtab_thunks_cc_finalize (); diff --git a/gcc/tree-sra.cc b/gcc/tree-sra.cc index 781ffdb..6a1141b 100644 --- a/gcc/tree-sra.cc +++ b/gcc/tree-sra.cc @@ -967,6 +967,12 @@ create_access (tree expr, gimple *stmt, bool write) disqualify_candidate (base, "Encountered an access beyond the base."); return NULL; } + if (TREE_CODE (TREE_TYPE (expr)) == BITINT_TYPE + && size > WIDE_INT_MAX_PRECISION - 1) + { + disqualify_candidate (base, "Encountered too large _BitInt access."); + return NULL; + } access = create_access_1 (base, offset, size); access->expr = expr; @@ -2733,7 +2739,8 @@ analyze_access_subtree (struct access *root, struct access *parent, For integral types this means the precision has to match. Avoid assumptions based on the integral type kind, too. */ if (INTEGRAL_TYPE_P (root->type) - && (TREE_CODE (root->type) != INTEGER_TYPE + && ((TREE_CODE (root->type) != INTEGER_TYPE + && TREE_CODE (root->type) != BITINT_TYPE) || TYPE_PRECISION (root->type) != root->size) /* But leave bitfield accesses alone. */ && (TREE_CODE (root->expr) != COMPONENT_REF @@ -2742,8 +2749,11 @@ analyze_access_subtree (struct access *root, struct access *parent, tree rt = root->type; gcc_assert ((root->offset % BITS_PER_UNIT) == 0 && (root->size % BITS_PER_UNIT) == 0); - root->type = build_nonstandard_integer_type (root->size, - TYPE_UNSIGNED (rt)); + if (TREE_CODE (root->type) == BITINT_TYPE) + root->type = build_bitint_type (root->size, TYPE_UNSIGNED (rt)); + else + root->type = build_nonstandard_integer_type (root->size, + TYPE_UNSIGNED (rt)); root->expr = build_ref_for_offset (UNKNOWN_LOCATION, root->base, root->offset, root->reverse, root->type, NULL, false); diff --git a/gcc/tree-ssa-loop-ch.cc b/gcc/tree-ssa-loop-ch.cc index 3ce5cc2..6c6e562 100644 --- a/gcc/tree-ssa-loop-ch.cc +++ b/gcc/tree-ssa-loop-ch.cc @@ -41,6 +41,8 @@ along with GCC; see the file COPYING3. If not see #include "gimple-pretty-print.h" #include "cfganal.h" #include "tree-ssa-loop-manip.h" +#include "tree-ssa-loop-niter.h" +#include "tree-scalar-evolution.h" /* Return path query insteance for testing ranges of statements in headers of LOOP contained in basic block BB. @@ -797,7 +799,16 @@ ch_base::copy_headers (function *fun) fprintf (dump_file, "Analyzing loop %i\n", loop->num); + /* If the loop is already a do-while style one (either because it was + written as such, or because jump threading transformed it into one), + we might be in fact peeling the first iteration of the loop. This + in general is not a good idea. Also avoid touching infinite loops. */ + if (!loop_has_exit_edges (loop) + || !process_loop_p (loop)) + continue; + basic_block header = loop->header; + estimate_numbers_of_iterations (loop); if (!get_max_loop_iterations_int (loop)) { if (dump_file && (dump_flags & TDF_DETAILS)) @@ -808,14 +819,6 @@ ch_base::copy_headers (function *fun) continue; } - /* If the loop is already a do-while style one (either because it was - written as such, or because jump threading transformed it into one), - we might be in fact peeling the first iteration of the loop. This - in general is not a good idea. Also avoid touching infinite loops. */ - if (!loop_has_exit_edges (loop) - || !process_loop_p (loop)) - continue; - /* Iterate the header copying up to limit; this takes care of the cases like while (a && b) {...}, where we want to have both of the conditions copied. TODO -- handle while (a || b) - like cases, by not requiring @@ -1170,12 +1173,12 @@ ch_base::copy_headers (function *fun) unsigned int pass_ch::execute (function *fun) { - loop_optimizer_init (LOOPS_HAVE_PREHEADERS - | LOOPS_HAVE_SIMPLE_LATCHES - | LOOPS_HAVE_RECORDED_EXITS); + loop_optimizer_init (LOOPS_NORMAL | LOOPS_HAVE_RECORDED_EXITS); + scev_initialize (); unsigned int res = copy_headers (fun); + scev_finalize (); loop_optimizer_finalize (); return res; } diff --git a/gcc/tree-ssa-reassoc.cc b/gcc/tree-ssa-reassoc.cc index 3201f9b..61f54f0 100644 --- a/gcc/tree-ssa-reassoc.cc +++ b/gcc/tree-ssa-reassoc.cc @@ -647,6 +647,9 @@ can_reassociate_op_p (tree op) { if (TREE_CODE (op) == SSA_NAME && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (op)) return false; + /* Uninitialized variables can't participate in reassociation. */ + if (TREE_CODE (op) == SSA_NAME && ssa_name_maybe_undef_p (op)) + return false; /* Make sure asm goto outputs do not participate in reassociation since we have no way to find an insertion place after asm goto. */ if (TREE_CODE (op) == SSA_NAME @@ -2600,7 +2603,8 @@ init_range_entry (struct range_entry *r, tree exp, gimple *stmt) } if (TREE_CODE (arg0) != SSA_NAME - || SSA_NAME_OCCURS_IN_ABNORMAL_PHI (arg0)) + || SSA_NAME_OCCURS_IN_ABNORMAL_PHI (arg0) + || ssa_name_maybe_undef_p (arg0)) break; loc = gimple_location (stmt); switch (code) @@ -7418,6 +7422,7 @@ init_reassoc (void) free (bbs); calculate_dominance_info (CDI_POST_DOMINATORS); plus_negates = vNULL; + mark_ssa_maybe_undefs (); } /* Cleanup after the reassociation pass, and print stats if diff --git a/gcc/tree-vect-data-refs.cc b/gcc/tree-vect-data-refs.cc index 752c34c..5e86da3 100644 --- a/gcc/tree-vect-data-refs.cc +++ b/gcc/tree-vect-data-refs.cc @@ -671,13 +671,20 @@ vect_analyze_early_break_dependences (loop_vec_info loop_vinfo) "loop contains multiple exits, analyzing" " statement dependencies.\n"); - for (gimple *c : LOOP_VINFO_LOOP_CONDS (loop_vinfo)) + /* Since we don't support general control flow, the location we'll move the + side-effects to is always the latch connected exit. When we support + general control flow we can do better but for now this is fine. */ + dest_bb = single_pred (loop->latch); + basic_block bb = dest_bb; + + do { - stmt_vec_info loop_cond_info = loop_vinfo->lookup_stmt (c); - if (STMT_VINFO_TYPE (loop_cond_info) != loop_exit_ctrl_vec_info_type) + /* If the destination block is also the header then we have nothing to do. */ + if (!single_pred_p (bb)) continue; - gimple_stmt_iterator gsi = gsi_for_stmt (c); + bb = single_pred (bb); + gimple_stmt_iterator gsi = gsi_last_bb (bb); /* Now analyze all the remaining statements and try to determine which instructions are allowed/needed to be moved. */ @@ -705,10 +712,10 @@ vect_analyze_early_break_dependences (loop_vec_info loop_vinfo) dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, "early breaks only supported on statically" " allocated objects.\n"); - return opt_result::failure_at (c, + return opt_result::failure_at (stmt, "can't safely apply code motion to " "dependencies of %G to vectorize " - "the early exit.\n", c); + "the early exit.\n", stmt); } tree refop = TREE_OPERAND (obj, 0); @@ -720,10 +727,10 @@ vect_analyze_early_break_dependences (loop_vec_info loop_vinfo) dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, "early breaks only supported on" " statically allocated objects.\n"); - return opt_result::failure_at (c, + return opt_result::failure_at (stmt, "can't safely apply code motion to " "dependencies of %G to vectorize " - "the early exit.\n", c); + "the early exit.\n", stmt); } /* Check if vector accesses to the object will be within bounds. @@ -736,10 +743,10 @@ vect_analyze_early_break_dependences (loop_vec_info loop_vinfo) "early breaks not supported: vectorization " "would %s beyond size of obj.", DR_IS_READ (dr_ref) ? "read" : "write"); - return opt_result::failure_at (c, + return opt_result::failure_at (stmt, "can't safely apply code motion to " "dependencies of %G to vectorize " - "the early exit.\n", c); + "the early exit.\n", stmt); } if (DR_IS_READ (dr_ref)) @@ -801,27 +808,13 @@ vect_analyze_early_break_dependences (loop_vec_info loop_vinfo) "marked statement for vUSE update: %G", stmt); } } - - /* Save destination as we go, BB are visited in order and the last one - is where statements should be moved to. */ - if (!dest_bb) - dest_bb = gimple_bb (c); - else - { - basic_block curr_bb = gimple_bb (c); - if (dominated_by_p (CDI_DOMINATORS, curr_bb, dest_bb)) - dest_bb = curr_bb; - } } + while (bb != loop->header); - basic_block dest_bb0 = EDGE_SUCC (dest_bb, 0)->dest; - basic_block dest_bb1 = EDGE_SUCC (dest_bb, 1)->dest; - dest_bb = flow_bb_inside_loop_p (loop, dest_bb0) ? dest_bb0 : dest_bb1; /* We don't allow outer -> inner loop transitions which should have been trapped already during loop form analysis. */ gcc_assert (dest_bb->loop_father == loop); - gcc_assert (dest_bb); LOOP_VINFO_EARLY_BRK_DEST_BB (loop_vinfo) = dest_bb; if (!LOOP_VINFO_EARLY_BRK_VUSES (loop_vinfo).is_empty ()) diff --git a/gcc/tree-vect-loop-manip.cc b/gcc/tree-vect-loop-manip.cc index f0ea7fc..c7e73f6 100644 --- a/gcc/tree-vect-loop-manip.cc +++ b/gcc/tree-vect-loop-manip.cc @@ -1613,11 +1613,11 @@ slpeel_tree_duplicate_loop_to_edge_cfg (class loop *loop, edge loop_exit, { if (!alt_loop_exit_block) { - alt_loop_exit_block = split_edge (exit); edge res = redirect_edge_and_branch ( - single_succ_edge (alt_loop_exit_block), + exit, new_preheader); flush_pending_stmts (res); + alt_loop_exit_block = split_edge (res); continue; } dest = alt_loop_exit_block; @@ -1626,11 +1626,12 @@ slpeel_tree_duplicate_loop_to_edge_cfg (class loop *loop, edge loop_exit, flush_pending_stmts (e); } + bool peeled_iters = single_pred (loop->latch) != loop_exit->src; /* Record the new SSA names in the cache so that we can skip materializing them again when we fill in the rest of the LCSSA variables. */ for (auto phi : new_phis) { - tree new_arg = gimple_phi_arg (phi, loop_exit->dest_idx)->def; + tree new_arg = gimple_phi_arg_def (phi, loop_exit->dest_idx); if (!SSA_VAR_P (new_arg)) continue; @@ -1653,7 +1654,7 @@ slpeel_tree_duplicate_loop_to_edge_cfg (class loop *loop, edge loop_exit, continue; } - /* If we decide to remove the PHI node we should also not + /* If we decided not to remove the PHI node we should also not rematerialize it later on. */ new_phi_args.put (new_arg, gimple_phi_result (phi)); @@ -1667,7 +1668,6 @@ slpeel_tree_duplicate_loop_to_edge_cfg (class loop *loop, edge loop_exit, edge loop_entry = single_succ_edge (new_preheader); if (flow_loops) { - bool peeled_iters = single_pred (loop->latch) != loop_exit->src; /* Link through the main exit first. */ for (auto gsi_from = gsi_start_phis (loop->header), gsi_to = gsi_start_phis (new_loop->header); @@ -1693,11 +1693,19 @@ slpeel_tree_duplicate_loop_to_edge_cfg (class loop *loop, edge loop_exit, } } /* If we have multiple exits and the vector loop is peeled then we - need to use the value at start of loop. */ + need to use the value at start of loop. If we're looking at + virtual operands we have to keep the original link. Virtual + operands don't all become the same because we'll corrupt the + vUSE chains among others. */ if (peeled_iters) { tree tmp_arg = gimple_phi_result (from_phi); - if (!new_phi_args.get (tmp_arg)) + /* Similar to the single exit case, If we have an existing + LCSSA variable thread through the original value otherwise + skip it and directly use the final value. */ + if (tree *res = new_phi_args.get (tmp_arg)) + new_arg = *res; + else if (!virtual_operand_p (new_arg)) new_arg = tmp_arg; } @@ -1716,8 +1724,6 @@ slpeel_tree_duplicate_loop_to_edge_cfg (class loop *loop, edge loop_exit, /* Now link the alternative exits. */ if (multiple_exits_p) { - set_immediate_dominator (CDI_DOMINATORS, new_preheader, - main_loop_exit_block); for (auto gsi_from = gsi_start_phis (loop->header), gsi_to = gsi_start_phis (new_preheader); !gsi_end_p (gsi_from) && !gsi_end_p (gsi_to); @@ -1728,9 +1734,31 @@ slpeel_tree_duplicate_loop_to_edge_cfg (class loop *loop, edge loop_exit, tree alt_arg = gimple_phi_result (from_phi); edge main_e = single_succ_edge (alt_loop_exit_block); - for (edge e : loop_exits) - if (e != loop_exit) - SET_PHI_ARG_DEF (to_phi, main_e->dest_idx, alt_arg); + + /* Now update the virtual PHI nodes with the right value. */ + if (peeled_iters + && virtual_operand_p (alt_arg) + && flow_bb_inside_loop_p (loop, + gimple_bb (SSA_NAME_DEF_STMT (alt_arg)))) + { + /* Link the alternative exit one. */ + tree def + = gimple_phi_arg_def (to_phi, loop_exit->dest_idx); + gphi *def_phi = as_a <gphi *> (SSA_NAME_DEF_STMT (def)); + SET_PHI_ARG_DEF (def_phi, 0, alt_arg); + + /* And now the main merge block. */ + gphi *iter_phi + = as_a <gphi *> (SSA_NAME_DEF_STMT (alt_arg)); + unsigned latch_idx + = single_succ_edge (loop->latch)->dest_idx; + tree exit_val + = gimple_phi_arg_def (iter_phi, latch_idx); + alt_arg = copy_ssa_name (def); + gphi *l_phi = create_phi_node (alt_arg, main_e->src); + SET_PHI_ARG_DEF (l_phi, 0, exit_val); + } + SET_PHI_ARG_DEF (to_phi, main_e->dest_idx, alt_arg); } set_immediate_dominator (CDI_DOMINATORS, new_preheader, @@ -1755,13 +1783,10 @@ slpeel_tree_duplicate_loop_to_edge_cfg (class loop *loop, edge loop_exit, if (multiple_exits_p) { update_loop = new_loop; - for (edge e : get_loop_exit_edges (loop)) - doms.safe_push (e->dest); - doms.safe_push (exit_dest); - - /* Likely a fall-through edge, so update if needed. */ - if (single_succ_p (exit_dest)) - doms.safe_push (single_succ (exit_dest)); + doms = get_all_dominated_blocks (CDI_DOMINATORS, loop->header); + for (unsigned i = 0; i < doms.length (); ++i) + if (flow_bb_inside_loop_p (loop, doms[i])) + doms.unordered_remove (i); } } else /* Add the copy at entry. */ @@ -3418,6 +3443,8 @@ vect_do_peeling (loop_vec_info loop_vinfo, tree niters, tree nitersm1, vect_update_ivs_after_vectorizer (loop_vinfo, niters_vector_mult_vf, update_e); + /* If we have a peeled vector iteration we will never skip the epilog loop + and we can simplify the cfg a lot by not doing the edge split. */ if (skip_epilog || LOOP_VINFO_EARLY_BREAKS (loop_vinfo)) { guard_cond = fold_build2 (EQ_EXPR, boolean_type_node, @@ -4039,7 +4066,16 @@ vect_loop_versioning (loop_vec_info loop_vinfo, basic_block preheader = loop_preheader_edge (loop_to_version)->src; preheader->count = preheader->count.apply_probability (prob * prob2); scale_loop_frequencies (loop_to_version, prob * prob2); - single_exit (loop_to_version)->dest->count = preheader->count; + /* When the loop has multiple exits then we can only version itself. + This is denoted by loop_to_version == loop. In this case we can + do the versioning by selecting the exit edge the vectorizer is + currently using. */ + edge exit_edge; + if (loop_to_version == loop) + exit_edge = LOOP_VINFO_IV_EXIT (loop_vinfo); + else + exit_edge = single_exit (loop_to_version); + exit_edge->dest->count = preheader->count; LOOP_VINFO_SCALAR_LOOP_SCALING (loop_vinfo) = (prob * prob2).invert (); nloop = scalar_loop; diff --git a/gcc/tree-vect-loop.cc b/gcc/tree-vect-loop.cc index c5b2799..fedecd6 100644 --- a/gcc/tree-vect-loop.cc +++ b/gcc/tree-vect-loop.cc @@ -989,7 +989,11 @@ vec_init_loop_exit_info (class loop *loop) if (number_of_iterations_exit_assumptions (loop, exit, &niter_desc, NULL) && !chrec_contains_undetermined (niter_desc.niter)) { - if (!niter_desc.may_be_zero || !candidate) + tree may_be_zero = niter_desc.may_be_zero; + if (integer_zerop (may_be_zero) + && (!candidate + || dominated_by_p (CDI_DOMINATORS, exit->src, + candidate->src))) candidate = exit; } } @@ -4116,6 +4120,13 @@ pop: if (op.ops[1] == op.ops[opi]) neg = ! neg; } + else if (op.code == IFN_COND_SUB) + { + op.code = IFN_COND_ADD; + /* Track whether we negate the reduction value each iteration. */ + if (op.ops[2] == op.ops[opi]) + neg = ! neg; + } if (CONVERT_EXPR_CODE_P (op.code) && tree_nop_conversion_p (op.type, TREE_TYPE (op.ops[0]))) ; @@ -6236,7 +6247,13 @@ vect_create_epilog_for_reduction (loop_vec_info loop_vinfo, phi = create_phi_node (new_def, exit_bb); if (j) def = gimple_get_lhs (vec_stmts[j]); - SET_PHI_ARG_DEF (phi, loop_exit->dest_idx, def); + if (LOOP_VINFO_IV_EXIT (loop_vinfo) == loop_exit) + SET_PHI_ARG_DEF (phi, loop_exit->dest_idx, def); + else + { + for (unsigned k = 0; k < gimple_phi_num_args (phi); k++) + SET_PHI_ARG_DEF (phi, k, def); + } new_def = gimple_convert (&stmts, vectype, new_def); reduc_inputs.quick_push (new_def); } @@ -10030,6 +10047,15 @@ vectorizable_induction (loop_vec_info loop_vinfo, step_expr = STMT_VINFO_LOOP_PHI_EVOLUTION_PART (stmt_info); gcc_assert (step_expr != NULL_TREE); + if (INTEGRAL_TYPE_P (TREE_TYPE (step_expr)) + && !type_has_mode_precision_p (TREE_TYPE (step_expr))) + { + if (dump_enabled_p ()) + dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, + "bit-precision induction vectorization not " + "supported.\n"); + return false; + } tree step_vectype = get_same_sized_vectype (TREE_TYPE (step_expr), vectype); /* Check for backend support of PLUS/MINUS_EXPR. */ @@ -11917,8 +11943,7 @@ vect_transform_loop (loop_vec_info loop_vinfo, gimple *loop_vectorized_call) (LOOP_VINFO_SCALAR_LOOP_SCALING (loop_vinfo)); scale_loop_frequencies (LOOP_VINFO_SCALAR_LOOP (loop_vinfo), LOOP_VINFO_SCALAR_LOOP_SCALING (loop_vinfo)); - single_exit (LOOP_VINFO_SCALAR_LOOP (loop_vinfo))->dest->count - = preheader->count; + LOOP_VINFO_SCALAR_IV_EXIT (loop_vinfo)->dest->count = preheader->count; } if (niters_vector == NULL_TREE) diff --git a/gcc/tree-vect-slp.cc b/gcc/tree-vect-slp.cc index b6cce55..086377a 100644 --- a/gcc/tree-vect-slp.cc +++ b/gcc/tree-vect-slp.cc @@ -6418,6 +6418,102 @@ vect_slp_analyze_node_operations (vec_info *vinfo, slp_tree node, return res; } +/* Given a definition DEF, analyze if it will have any live scalar use after + performing SLP vectorization whose information is represented by BB_VINFO, + and record result into hash map SCALAR_USE_MAP as cache for later fast + check. If recursion DEPTH exceeds a limit, stop analysis and make a + conservative assumption. Return 0 if no scalar use, 1 if there is, -1 + means recursion is limited. */ + +static int +vec_slp_has_scalar_use (bb_vec_info bb_vinfo, tree def, + hash_map<tree, int> &scalar_use_map, + int depth = 0) +{ + const int depth_limit = 2; + imm_use_iterator use_iter; + gimple *use_stmt; + + if (int *res = scalar_use_map.get (def)) + return *res; + + int scalar_use = 1; + + FOR_EACH_IMM_USE_STMT (use_stmt, use_iter, def) + { + if (is_gimple_debug (use_stmt)) + continue; + + stmt_vec_info use_stmt_info = bb_vinfo->lookup_stmt (use_stmt); + + if (!use_stmt_info) + break; + + if (PURE_SLP_STMT (vect_stmt_to_vectorize (use_stmt_info))) + continue; + + /* Do not step forward when encounter PHI statement, since it may + involve cyclic reference and cause infinite recursive invocation. */ + if (gimple_code (use_stmt) == GIMPLE_PHI) + break; + + /* When pattern recognition is involved, a statement whose definition is + consumed in some pattern, may not be included in the final replacement + pattern statements, so would be skipped when building SLP graph. + + * Original + char a_c = *(char *) a; + char b_c = *(char *) b; + unsigned short a_s = (unsigned short) a_c; + int a_i = (int) a_s; + int b_i = (int) b_c; + int r_i = a_i - b_i; + + * After pattern replacement + a_s = (unsigned short) a_c; + a_i = (int) a_s; + + patt_b_s = (unsigned short) b_c; // b_i = (int) b_c + patt_b_i = (int) patt_b_s; // b_i = (int) b_c + + patt_r_s = widen_minus(a_c, b_c); // r_i = a_i - b_i + patt_r_i = (int) patt_r_s; // r_i = a_i - b_i + + The definitions of a_i(original statement) and b_i(pattern statement) + are related to, but actually not part of widen_minus pattern. + Vectorizing the pattern does not cause these definition statements to + be marked as PURE_SLP. For this case, we need to recursively check + whether their uses are all absorbed into vectorized code. But there + is an exception that some use may participate in an vectorized + operation via an external SLP node containing that use as an element. + The parameter "scalar_use_map" tags such kind of SSA as having scalar + use in advance. */ + tree lhs = gimple_get_lhs (use_stmt); + + if (!lhs || TREE_CODE (lhs) != SSA_NAME) + break; + + if (depth_limit && depth >= depth_limit) + return -1; + + if ((scalar_use = vec_slp_has_scalar_use (bb_vinfo, lhs, scalar_use_map, + depth + 1))) + break; + } + + if (end_imm_use_stmt_p (&use_iter)) + scalar_use = 0; + + /* If recursion is limited, do not cache result for non-root defs. */ + if (!depth || scalar_use >= 0) + { + bool added = scalar_use_map.put (def, scalar_use); + gcc_assert (!added); + } + + return scalar_use; +} + /* Mark lanes of NODE that are live outside of the basic-block vectorized region and that can be vectorized using vectorizable_live_operation with STMT_VINFO_LIVE_P. Not handled live operations will cause the @@ -6427,6 +6523,7 @@ static void vect_bb_slp_mark_live_stmts (bb_vec_info bb_vinfo, slp_tree node, slp_instance instance, stmt_vector_for_cost *cost_vec, + hash_map<tree, int> &scalar_use_map, hash_set<stmt_vec_info> &svisited, hash_set<slp_tree> &visited) { @@ -6451,32 +6548,22 @@ vect_bb_slp_mark_live_stmts (bb_vec_info bb_vinfo, slp_tree node, def_operand_p def_p; FOR_EACH_PHI_OR_STMT_DEF (def_p, orig_stmt, op_iter, SSA_OP_DEF) { - imm_use_iterator use_iter; - gimple *use_stmt; - stmt_vec_info use_stmt_info; - FOR_EACH_IMM_USE_STMT (use_stmt, use_iter, DEF_FROM_PTR (def_p)) - if (!is_gimple_debug (use_stmt)) - { - use_stmt_info = bb_vinfo->lookup_stmt (use_stmt); - if (!use_stmt_info - || !PURE_SLP_STMT (vect_stmt_to_vectorize (use_stmt_info))) - { - STMT_VINFO_LIVE_P (stmt_info) = true; - if (vectorizable_live_operation (bb_vinfo, stmt_info, - node, instance, i, - false, cost_vec)) - /* ??? So we know we can vectorize the live stmt - from one SLP node. If we cannot do so from all - or none consistently we'd have to record which - SLP node (and lane) we want to use for the live - operation. So make sure we can code-generate - from all nodes. */ - mark_visited = false; - else - STMT_VINFO_LIVE_P (stmt_info) = false; - break; - } - } + if (vec_slp_has_scalar_use (bb_vinfo, DEF_FROM_PTR (def_p), + scalar_use_map)) + { + STMT_VINFO_LIVE_P (stmt_info) = true; + if (vectorizable_live_operation (bb_vinfo, stmt_info, node, + instance, i, false, cost_vec)) + /* ??? So we know we can vectorize the live stmt from one SLP + node. If we cannot do so from all or none consistently + we'd have to record which SLP node (and lane) we want to + use for the live operation. So make sure we can + code-generate from all nodes. */ + mark_visited = false; + else + STMT_VINFO_LIVE_P (stmt_info) = false; + } + /* We have to verify whether we can insert the lane extract before all uses. The following is a conservative approximation. We cannot put this into vectorizable_live_operation because @@ -6495,6 +6582,10 @@ vect_bb_slp_mark_live_stmts (bb_vec_info bb_vinfo, slp_tree node, from the latest stmt in a node. So we compensate for this during code-generation, simply not replacing uses for those hopefully rare cases. */ + imm_use_iterator use_iter; + gimple *use_stmt; + stmt_vec_info use_stmt_info; + if (STMT_VINFO_LIVE_P (stmt_info)) FOR_EACH_IMM_USE_STMT (use_stmt, use_iter, DEF_FROM_PTR (def_p)) if (!is_gimple_debug (use_stmt) @@ -6517,8 +6608,56 @@ vect_bb_slp_mark_live_stmts (bb_vec_info bb_vinfo, slp_tree node, slp_tree child; FOR_EACH_VEC_ELT (SLP_TREE_CHILDREN (node), i, child) if (child && SLP_TREE_DEF_TYPE (child) == vect_internal_def) - vect_bb_slp_mark_live_stmts (bb_vinfo, child, instance, - cost_vec, svisited, visited); + vect_bb_slp_mark_live_stmts (bb_vinfo, child, instance, cost_vec, + scalar_use_map, svisited, visited); +} + +/* Traverse all slp instances of BB_VINFO, and mark lanes of every node that + are live outside of the basic-block vectorized region and that can be + vectorized using vectorizable_live_operation with STMT_VINFO_LIVE_P. */ + +static void +vect_bb_slp_mark_live_stmts (bb_vec_info bb_vinfo) +{ + if (bb_vinfo->slp_instances.is_empty ()) + return; + + hash_set<stmt_vec_info> svisited; + hash_set<slp_tree> visited; + hash_map<tree, int> scalar_use_map; + auto_vec<slp_tree> worklist; + + for (slp_instance instance : bb_vinfo->slp_instances) + if (!visited.add (SLP_INSTANCE_TREE (instance))) + worklist.safe_push (SLP_INSTANCE_TREE (instance)); + + do + { + slp_tree node = worklist.pop (); + + if (SLP_TREE_DEF_TYPE (node) == vect_external_def) + { + for (tree op : SLP_TREE_SCALAR_OPS (node)) + if (TREE_CODE (op) == SSA_NAME) + scalar_use_map.put (op, 1); + } + else + { + for (slp_tree child : SLP_TREE_CHILDREN (node)) + if (child && !visited.add (child)) + worklist.safe_push (child); + } + } while (!worklist.is_empty ()); + + visited.empty (); + + for (slp_instance instance : bb_vinfo->slp_instances) + { + vect_location = instance->location (); + vect_bb_slp_mark_live_stmts (bb_vinfo, SLP_INSTANCE_TREE (instance), + instance, &instance->cost_vec, + scalar_use_map, svisited, visited); + } } /* Determine whether we can vectorize the reduction epilogue for INSTANCE. */ @@ -6684,17 +6823,7 @@ vect_slp_analyze_operations (vec_info *vinfo) /* Compute vectorizable live stmts. */ if (bb_vec_info bb_vinfo = dyn_cast <bb_vec_info> (vinfo)) - { - hash_set<stmt_vec_info> svisited; - hash_set<slp_tree> visited; - for (i = 0; vinfo->slp_instances.iterate (i, &instance); ++i) - { - vect_location = instance->location (); - vect_bb_slp_mark_live_stmts (bb_vinfo, SLP_INSTANCE_TREE (instance), - instance, &instance->cost_vec, svisited, - visited); - } - } + vect_bb_slp_mark_live_stmts (bb_vinfo); return !vinfo->slp_instances.is_empty (); } diff --git a/gcc/tree-vect-stmts.cc b/gcc/tree-vect-stmts.cc index bdbf08c..cabd4e3 100644 --- a/gcc/tree-vect-stmts.cc +++ b/gcc/tree-vect-stmts.cc @@ -12870,13 +12870,18 @@ vectorizable_early_exit (vec_info *vinfo, stmt_vec_info stmt_info, rewrite conditions to always be a comparison against 0. To do this it sometimes flips the edges. This is fine for scalar, but for vector we then have to flip the test, as we're still assuming that if you take the - branch edge that we found the exit condition. */ + branch edge that we found the exit condition. i.e. we need to know whether + we are generating a `forall` or an `exist` condition. */ auto new_code = NE_EXPR; auto reduc_optab = ior_optab; auto reduc_op = BIT_IOR_EXPR; tree cst = build_zero_cst (vectype); + edge exit_true_edge = EDGE_SUCC (gimple_bb (cond_stmt), 0); + if (exit_true_edge->flags & EDGE_FALSE_VALUE) + exit_true_edge = EDGE_SUCC (gimple_bb (cond_stmt), 1); + gcc_assert (exit_true_edge->flags & EDGE_TRUE_VALUE); if (flow_bb_inside_loop_p (LOOP_VINFO_LOOP (loop_vinfo), - BRANCH_EDGE (gimple_bb (cond_stmt))->dest)) + exit_true_edge->dest)) { new_code = EQ_EXPR; reduc_optab = and_optab; diff --git a/gcc/varasm.cc b/gcc/varasm.cc index 1a869ae..d2c879b 100644 --- a/gcc/varasm.cc +++ b/gcc/varasm.cc @@ -1843,6 +1843,15 @@ void assemble_function_label_raw (FILE *file, const char *name) { ASM_OUTPUT_LABEL (file, name); + assemble_function_label_final (); +} + +/* Finish outputting function label. Needs to be called when outputting + function label without using assemble_function_label_raw (). */ + +void +assemble_function_label_final (void) +{ if ((flag_sanitize & SANITIZE_ADDRESS) /* Notify ASAN only about the first function label. */ && (in_cold_section_p == first_function_block_is_cold) @@ -2543,7 +2552,8 @@ process_pending_assemble_externals (void) for (rtx list = pending_libcall_symbols; list; list = XEXP (list, 1)) { rtx symbol = XEXP (list, 0); - tree id = get_identifier (XSTR (symbol, 0)); + const char *name = targetm.strip_name_encoding (XSTR (symbol, 0)); + tree id = get_identifier (name); if (TREE_SYMBOL_REFERENCED (id)) targetm.asm_out.external_libcall (symbol); } @@ -2631,7 +2641,8 @@ assemble_external_libcall (rtx fun) reference to it will mark its tree node as referenced, via assemble_name_resolve. These are eventually emitted, if used, in process_pending_assemble_externals. */ - get_identifier (XSTR (fun, 0)); + const char *name = targetm.strip_name_encoding (XSTR (fun, 0)); + get_identifier (name); pending_libcall_symbols = gen_rtx_EXPR_LIST (VOIDmode, fun, pending_libcall_symbols); } diff --git a/include/ChangeLog b/include/ChangeLog index b6afbd0..8bfaec6 100644 --- a/include/ChangeLog +++ b/include/ChangeLog @@ -1,3 +1,13 @@ +2024-01-13 Jakub Jelinek <jakub@redhat.com> + + * demangle.h (enum demangle_component_type): Add + DEMANGLE_COMPONENT_XOBJ_MEMBER_FUNCTION. + +2024-01-09 Jeff Law <jlaw@ventanamicro.com> + + * longlong.h (__stormy16_count_leading_zeros): Add prototype for + __clzhi2. + 2023-12-15 Julian Brown <julian@codesourcery.com> * gomp-constants.h (gomp_map_kind): Add GOMP_MAP_STRUCT_UNORD. diff --git a/include/demangle.h b/include/demangle.h index 6a03f4f..49b84d4 100644 --- a/include/demangle.h +++ b/include/demangle.h @@ -314,6 +314,8 @@ enum demangle_component_type /* C++11: An rvalue reference modifying a member function. The one subtree is the type which is being referenced. */ DEMANGLE_COMPONENT_RVALUE_REFERENCE_THIS, + /* C++23: A member function with explict object parameter. */ + DEMANGLE_COMPONENT_XOBJ_MEMBER_FUNCTION, /* A vendor qualifier. The left subtree is the type which is being qualified, and the right subtree is the name of the qualifier. */ diff --git a/libcc1/ChangeLog b/libcc1/ChangeLog index 6cdab11..746e3c4 100644 --- a/libcc1/ChangeLog +++ b/libcc1/ChangeLog @@ -1,3 +1,10 @@ +2024-01-09 waffl3x <waffl3x@protonmail.com> + Jason Merrill <jason@redhat.com> + + PR c++/102609 + * libcp1plugin.cc (plugin_pragma_push_user_expression): Don't use + DECL_NONSTATIC_MEMBER_FUNCTION_P. + 2023-12-06 David Malcolm <dmalcolm@redhat.com> * context.cc (plugin_print_error_function): Make diagnostic_info diff --git a/libcc1/libcp1plugin.cc b/libcc1/libcp1plugin.cc index 5b73e36..7f4e4c9 100644 --- a/libcc1/libcp1plugin.cc +++ b/libcc1/libcp1plugin.cc @@ -468,7 +468,7 @@ plugin_pragma_push_user_expression (cpp_reader *) } } - if (unchanged_cfun || DECL_NONSTATIC_MEMBER_FUNCTION_P (changed_func_decl)) + if (unchanged_cfun || DECL_OBJECT_MEMBER_FUNCTION_P (changed_func_decl)) { /* Check whether the oracle supplies us with a "this", and if so, arrange for data members and this itself to be diff --git a/libgcc/ChangeLog b/libgcc/ChangeLog index 4581ba1..9799de1 100644 --- a/libgcc/ChangeLog +++ b/libgcc/ChangeLog @@ -1,3 +1,19 @@ +2024-01-12 Jakub Jelinek <jakub@redhat.com> + + * libgcc2.h (UBILtype): New typedef with may_alias attribute. + (__mulbitint3, __divmodbitint4): Use UBILtype * instead of + UWtype * and const UBILtype * instead of const UWtype *. + * libgcc2.c (bitint_reduce_prec, bitint_mul_1, bitint_addmul_1, + __mulbitint3, bitint_negate, bitint_submul_1, __divmodbitint4): + Likewise. + * soft-fp/bitint.h (UBILtype): Change define into a typedef with + may_alias attribute. + +2024-01-12 Sandra Loosemore <sandra@codesourcery.com> + + * unwind-dw2-fde-dip.c (_Unwind_Find_FDE): Do not try to use + _dl_find_object on nios2; it doesn't work. + 2023-12-23 Thomas Schwinge <thomas@codesourcery.com> * c++-minimal/README: New. diff --git a/libgcc/libgcc2.c b/libgcc/libgcc2.c index eee8bce..e04d169 100644 --- a/libgcc/libgcc2.c +++ b/libgcc/libgcc2.c @@ -1309,7 +1309,7 @@ __udivdi3 (UDWtype n, UDWtype d) some narrower _BitInt value, reduce precision. */ static inline __attribute__((__always_inline__)) SItype -bitint_reduce_prec (const UWtype **p, SItype prec) +bitint_reduce_prec (const UBILtype **p, SItype prec) { UWtype mslimb; SItype i; @@ -1421,7 +1421,7 @@ bitint_reduce_prec (const UWtype **p, SItype prec) /* D = S * L. */ static UWtype -bitint_mul_1 (UWtype *d, const UWtype *s, UWtype l, SItype n) +bitint_mul_1 (UBILtype *d, const UBILtype *s, UWtype l, SItype n) { UWtype sv, hi, lo, c = 0; do @@ -1440,7 +1440,7 @@ bitint_mul_1 (UWtype *d, const UWtype *s, UWtype l, SItype n) /* D += S * L. */ static UWtype -bitint_addmul_1 (UWtype *d, const UWtype *s, UWtype l, SItype n) +bitint_addmul_1 (UBILtype *d, const UBILtype *s, UWtype l, SItype n) { UWtype sv, hi, lo, c = 0; do @@ -1465,9 +1465,9 @@ bitint_addmul_1 (UWtype *d, const UWtype *s, UWtype l, SItype n) positive. */ void -__mulbitint3 (UWtype *ret, SItype retprec, - const UWtype *u, SItype uprec, - const UWtype *v, SItype vprec) +__mulbitint3 (UBILtype *ret, SItype retprec, + const UBILtype *u, SItype uprec, + const UBILtype *v, SItype vprec) { uprec = bitint_reduce_prec (&u, uprec); vprec = bitint_reduce_prec (&v, vprec); @@ -1480,7 +1480,7 @@ __mulbitint3 (UWtype *ret, SItype retprec, || (avprec > auprec && !(uprec >= 0 && vprec < 0))) { SItype p; - const UWtype *t; + const UBILtype *t; p = uprec; uprec = vprec; vprec = p; p = auprec; auprec = avprec; avprec = p; t = u; u = v; v = t; @@ -1643,7 +1643,7 @@ __mulbitint3 (UWtype *ret, SItype retprec, /* D = -S. */ static void -bitint_negate (UWtype *d, const UWtype *s, SItype n) +bitint_negate (UBILtype *d, const UBILtype *s, SItype n) { UWtype c = 1; do @@ -1660,7 +1660,7 @@ bitint_negate (UWtype *d, const UWtype *s, SItype n) /* D -= S * L. */ static UWtype -bitint_submul_1 (UWtype *d, const UWtype *s, UWtype l, SItype n) +bitint_submul_1 (UBILtype *d, const UBILtype *s, UWtype l, SItype n) { UWtype sv, hi, lo, c = 0; do @@ -1687,10 +1687,10 @@ bitint_submul_1 (UWtype *d, const UWtype *s, UWtype l, SItype n) should be 0. */ void -__divmodbitint4 (UWtype *q, SItype qprec, - UWtype *r, SItype rprec, - const UWtype *u, SItype uprec, - const UWtype *v, SItype vprec) +__divmodbitint4 (UBILtype *q, SItype qprec, + UBILtype *r, SItype rprec, + const UBILtype *u, SItype uprec, + const UBILtype *v, SItype vprec) { uprec = bitint_reduce_prec (&u, uprec); vprec = bitint_reduce_prec (&v, vprec); @@ -1747,7 +1747,7 @@ __divmodbitint4 (UWtype *q, SItype qprec, if (qn >= qn2) qn2 = 0; USItype sz = un + 1 + vn + qn2; - UWtype *buf = __builtin_alloca (sz * sizeof (UWtype)); + UBILtype *buf = __builtin_alloca (sz * sizeof (UWtype)); USItype uidx, vidx; #if __LIBGCC_BITINT_ORDER__ == __ORDER_BIG_ENDIAN__ uidx = un - 1; @@ -1768,9 +1768,9 @@ __divmodbitint4 (UWtype *q, SItype qprec, __builtin_memcpy (buf + un + 1, v, vn * sizeof (UWtype)); if (vp) buf[un + 1 + BITINT_END (0, vn - 1)] &= (((UWtype) 1 << vp) - 1); - UWtype *u2 = buf; - UWtype *v2 = u2 + un + 1; - UWtype *q2 = v2 + vn; + UBILtype *u2 = buf; + UBILtype *v2 = u2 + un + 1; + UBILtype *q2 = v2 + vn; if (!qn2) q2 = q + BITINT_END (qn - (un - vn + 1), 0); diff --git a/libgcc/libgcc2.h b/libgcc/libgcc2.h index c4ee965..5050456 100644 --- a/libgcc/libgcc2.h +++ b/libgcc/libgcc2.h @@ -402,10 +402,12 @@ extern UDWtype __udivmoddi4 (UDWtype, UDWtype, UDWtype *); #if (defined(__BITINT_MAXWIDTH__) \ && (defined(L_mulbitint3) || defined(L_divmodbitint4))) /* _BitInt support. */ -extern void __mulbitint3 (UWtype *, SItype, const UWtype *, SItype, - const UWtype *, SItype); -extern void __divmodbitint4 (UWtype *, SItype, UWtype *, SItype, - const UWtype *, SItype, const UWtype *, SItype); +typedef UWtype __attribute__((__may_alias__)) UBILtype; +extern void __mulbitint3 (UBILtype *, SItype, const UBILtype *, SItype, + const UBILtype *, SItype); +extern void __divmodbitint4 (UBILtype *, SItype, UBILtype *, SItype, + const UBILtype *, SItype, const UBILtype *, + SItype); #endif /* __negdi2 is static inline when building other libgcc2 portions. */ diff --git a/libgcc/soft-fp/bitint.h b/libgcc/soft-fp/bitint.h index 20cd41b..cb4d822 100644 --- a/libgcc/soft-fp/bitint.h +++ b/libgcc/soft-fp/bitint.h @@ -33,19 +33,19 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see #if BIL_UNITS_PER_WORD == 8 #define BIL_TYPE_SIZE (8 * __CHAR_BIT__) #define BILtype DItype -#define UBILtype UDItype +typedef UDItype __attribute__ ((__may_alias__)) UBILtype; #elif BIL_UNITS_PER_WORD == 4 #define BIL_TYPE_SIZE (4 * __CHAR_BIT__) #define BILtype SItype -#define UBILtype USItype +typedef USItype __attribute__ ((__may_alias__)) UBILtype; #elif BIL_UNITS_PER_WORD == 2 #define BIL_TYPE_SIZE (2 * __CHAR_BIT__) #define BILtype HItype -#define UBILtype UHItype +typedef UHItype __attribute__ ((__may_alias__)) UBILtype; #else #define BIL_TYPE_SIZE __CHAR_BIT__ #define BILtype QItype -#define UBILtype UQItype +typedef UQItype __attribute__ ((__may_alias__)) UBILtype; #endif /* If *P is zero or sign extended (the latter only for PREC < 0) from diff --git a/libgcc/unwind-dw2-fde-dip.c b/libgcc/unwind-dw2-fde-dip.c index 2f2ca35..57d0c881 100644 --- a/libgcc/unwind-dw2-fde-dip.c +++ b/libgcc/unwind-dw2-fde-dip.c @@ -543,8 +543,9 @@ _Unwind_Find_FDE (void *pc, struct dwarf_eh_bases *bases) return ret; /* Use DLFO_STRUCT_HAS_EH_DBASE as a proxy for the existence of a glibc-style - _dl_find_object function. */ -#ifdef DLFO_STRUCT_HAS_EH_DBASE + _dl_find_object function. However, do not use _dl_find_object on nios2, + which uses the GOT address as the base for DW_EH_PE_datarel instead. */ +#if defined(DLFO_STRUCT_HAS_EH_DBASE) && !defined(__nios2__) { struct dl_find_object dlfo; if (_dl_find_object (pc, &dlfo) == 0 && dlfo.dlfo_eh_frame != NULL) diff --git a/libgfortran/ChangeLog b/libgfortran/ChangeLog index 7858f71..8af3882 100644 --- a/libgfortran/ChangeLog +++ b/libgfortran/ChangeLog @@ -1,3 +1,10 @@ +2024-01-15 Lipeng Zhu <lipeng.zhu@intel.com> + + * io/io.h (dec_waiting_unlocked): Use + __gthread_rwlock_wrlock/__gthread_rwlock_unlock or + __gthread_mutex_lock/__gthread_mutex_unlock functions + to replace WRLOCK and RWUNLOCK macros. + 2024-01-07 Jerry DeLisle <jvdelisle@gcc.gnu.org> * io/write.c (namelist_write): If internal_unit precede with space. diff --git a/libgfortran/io/io.h b/libgfortran/io/io.h index 862daca..59bc19e 100644 --- a/libgfortran/io/io.h +++ b/libgfortran/io/io.h @@ -1020,9 +1020,15 @@ dec_waiting_unlocked (gfc_unit *u) #ifdef HAVE_ATOMIC_FETCH_ADD (void) __atomic_fetch_add (&u->waiting, -1, __ATOMIC_RELAXED); #else - WRLOCK (&unit_rwlock); +#ifdef __GTHREAD_RWLOCK_INIT + __gthread_rwlock_wrlock (&unit_rwlock); + u->waiting--; + __gthread_rwlock_unlock (&unit_rwlock); +#else + __gthread_mutex_lock (&unit_rwlock); u->waiting--; - RWUNLOCK (&unit_rwlock); + __gthread_mutex_unlock (&unit_rwlock); +#endif #endif } diff --git a/libgomp/ChangeLog b/libgomp/ChangeLog index 63bc54f..e9b4da5 100644 --- a/libgomp/ChangeLog +++ b/libgomp/ChangeLog @@ -1,3 +1,39 @@ +2024-01-11 Julian Brown <julian@codesourcery.com> + + * libgomp.texi: C/C++ lvalues are supported now for map/to/from. + * testsuite/libgomp.c-c++-common/ind-base-4.c: New test. + * testsuite/libgomp.c-c++-common/unary-ptr-1.c: New test. + +2024-01-10 Jakub Jelinek <jakub@redhat.com> + + PR libgomp/113192 + * configure.ac (FLOCK): Use $libgomp_abs_srcdir/testsuite/flock + instead of \$(abs_top_srcdir)/testsuite/flock. + * configure: Regenerated. + +2024-01-09 Julian Brown <julian@codesourcery.com> + + * testsuite/libgomp.c++/baseptrs-4.C: Remove commented-out cases that + now work. + * testsuite/libgomp.c++/baseptrs-6.C: New test. + * testsuite/libgomp.c++/ind-base-1.C: New test. + * testsuite/libgomp.c++/ind-base-2.C: New test. + * testsuite/libgomp.c++/lvalue-tofrom-1.C: New test. + * testsuite/libgomp.c++/lvalue-tofrom-2.C: New test. + * testsuite/libgomp.c++/map-comma-1.C: New test. + * testsuite/libgomp.c++/map-rvalue-ref-1.C: New test. + * testsuite/libgomp.c++/struct-ref-1.C: New test. + * testsuite/libgomp.c-c++-common/array-field-1.c: New test. + * testsuite/libgomp.c-c++-common/array-of-struct-1.c: New test. + * testsuite/libgomp.c-c++-common/array-of-struct-2.c: New test. + +2024-01-09 Jakub Jelinek <jakub@redhat.com> + + PR libgomp/113192 + * configure.ac (FLOCK): Use \$(abs_top_srcdir)/testsuite/flock + rather than $srcdir/testsuite/flock. + * configure: Regenerated. + 2024-01-08 Thomas Schwinge <thomas@codesourcery.com> * plugin/plugin-gcn.c (EF_AMDGPU_MACH): Add diff --git a/libgomp/configure b/libgomp/configure index 9a9d30c..ad245b4 100755 --- a/libgomp/configure +++ b/libgomp/configure @@ -16638,6 +16638,13 @@ done # Fallback if 'perl' is available. if test -z "$FLOCK"; then + # These need to be absolute paths, yet at the same time need to + # canonicalize only relative paths, because then amd will not unmount + # drives. Thus the use of PWDCMD: set it to 'pawd' or 'amq -w' if using amd. + case $srcdir in + [\\/$]* | ?:[\\/]*) libgomp_abs_srcdir=${srcdir} ;; + *) libgomp_abs_srcdir=`cd "$srcdir" && ${PWDCMD-pwd} || echo "$srcdir"` ;; + esac # Extract the first word of "perl", so it can be a program name with args. set dummy perl; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 @@ -16655,7 +16662,7 @@ do test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_FLOCK="\$(abs_top_srcdir)/testsuite/flock" + ac_cv_prog_FLOCK="$libgomp_abs_srcdir/testsuite/flock" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi diff --git a/libgomp/configure.ac b/libgomp/configure.ac index 63129be..1730c62 100644 --- a/libgomp/configure.ac +++ b/libgomp/configure.ac @@ -343,7 +343,16 @@ AC_MSG_NOTICE([checking for flock implementation]) AC_CHECK_PROGS(FLOCK, flock) # Fallback if 'perl' is available. if test -z "$FLOCK"; then - AC_CHECK_PROG(FLOCK, perl, \$(abs_top_srcdir)/testsuite/flock) + # These need to be absolute paths, yet at the same time need to + # canonicalize only relative paths, because then amd will not unmount + # drives. Thus the use of PWDCMD: set it to 'pawd' or 'amq -w' if using amd. + case $srcdir in +changequote(,)dnl + [\\/$]* | ?:[\\/]*) libgomp_abs_srcdir=${srcdir} ;; +changequote([,])dnl + *) libgomp_abs_srcdir=`cd "$srcdir" && ${PWDCMD-pwd} || echo "$srcdir"` ;; + esac + AC_CHECK_PROG(FLOCK, perl, $libgomp_abs_srcdir/testsuite/flock) fi AC_SUBST(SYSROOT_CFLAGS_FOR_TARGET) diff --git a/libgomp/libgomp.texi b/libgomp/libgomp.texi index 30f69ee..74d4ef3 100644 --- a/libgomp/libgomp.texi +++ b/libgomp/libgomp.texi @@ -242,7 +242,7 @@ The OpenMP 4.5 specification is fully supported. @item Discontiguous array section with @code{target update} construct @tab N @tab @item C/C++'s lvalue expressions in @code{to}, @code{from} - and @code{map} clauses @tab N @tab + and @code{map} clauses @tab Y @tab @item C/C++'s lvalue expressions in @code{depend} clauses @tab Y @tab @item Nested @code{declare target} directive @tab Y @tab @item Combined @code{master} constructs @tab Y @tab diff --git a/libgomp/testsuite/libgomp.c-c++-common/ind-base-4.c b/libgomp/testsuite/libgomp.c-c++-common/ind-base-4.c new file mode 100644 index 0000000..91549ac --- /dev/null +++ b/libgomp/testsuite/libgomp.c-c++-common/ind-base-4.c @@ -0,0 +1,50 @@ +// { dg-do run } +// { dg-options "-fopenmp" } + +#include <assert.h> +#include <stdlib.h> + +typedef struct +{ + int x[10]; +} S; + +typedef struct +{ + S ***s; +} T; + +typedef struct +{ + T **t; +} U; + +void +foo (void) +{ + U *u = (U *) malloc (sizeof (U)); + T *real_t = (T *) malloc (sizeof (T)); + S *real_s = (S *) malloc (sizeof (S)); + T **t_pp = &real_t; + S **s_pp = &real_s; + S ***s_ppp = &s_pp; + u->t = t_pp; + (*u->t)->s = s_ppp; + for (int i = 0; i < 10; i++) + (**((*u->t)->s))->x[i] = 0; +#pragma omp target map(u->t, *u->t, (*u->t)->s, *(*u->t)->s, **(*u->t)->s, \ + (**(*u->t)->s)->x[0:10]) + for (int i = 0; i < 10; i++) + (**((*u->t)->s))->x[i] = i * 3; + for (int i = 0; i < 10; i++) + assert ((**((*u->t)->s))->x[i] == i * 3); + free (real_s); + free (real_t); + free (u); +} + +int main (int argc, char *argv[]) +{ + foo (); + return 0; +} diff --git a/libgomp/testsuite/libgomp.c-c++-common/unary-ptr-1.c b/libgomp/testsuite/libgomp.c-c++-common/unary-ptr-1.c new file mode 100644 index 0000000..3623b26 --- /dev/null +++ b/libgomp/testsuite/libgomp.c-c++-common/unary-ptr-1.c @@ -0,0 +1,16 @@ +#include <assert.h> + +int main (int argc, char *argv[]) +{ + int y = 0; + int *x = &y; + +#pragma omp target map(*x) + { + (*x)++; + } + + assert (y == 1); + + return 0; +} diff --git a/libiberty/ChangeLog b/libiberty/ChangeLog index 884c8b7..37bde4d 100644 --- a/libiberty/ChangeLog +++ b/libiberty/ChangeLog @@ -1,3 +1,16 @@ +2024-01-13 Jakub Jelinek <jakub@redhat.com> + + * cp-demangle.c (FNQUAL_COMPONENT_CASE): Add case for + DEMANGLE_COMPONENT_XOBJ_MEMBER_FUNCTION. + (d_dump): Handle DEMANGLE_COMPONENT_XOBJ_MEMBER_FUNCTION. + (d_nested_name): Parse H after N in nested name. + (d_count_templates_scopes): Handle + DEMANGLE_COMPONENT_XOBJ_MEMBER_FUNCTION. + (d_print_mod): Likewise. + (d_print_function_type): Likewise. + * testsuite/demangle-expected: Add tests for explicit object + member functions. + 2023-12-05 Jakub Jelinek <jakub@redhat.com> * configure.ac (HAVE_X86_SHA1_HW_SUPPORT): Verify __get_cpuid and diff --git a/libiberty/cp-demangle.c b/libiberty/cp-demangle.c index dee3617..fc2cf64 100644 --- a/libiberty/cp-demangle.c +++ b/libiberty/cp-demangle.c @@ -581,6 +581,7 @@ static char *d_demangle (const char *, int, size_t *); case DEMANGLE_COMPONENT_CONST_THIS: \ case DEMANGLE_COMPONENT_REFERENCE_THIS: \ case DEMANGLE_COMPONENT_RVALUE_REFERENCE_THIS: \ + case DEMANGLE_COMPONENT_XOBJ_MEMBER_FUNCTION: \ case DEMANGLE_COMPONENT_TRANSACTION_SAFE: \ case DEMANGLE_COMPONENT_NOEXCEPT: \ case DEMANGLE_COMPONENT_THROW_SPEC @@ -749,6 +750,9 @@ d_dump (struct demangle_component *dc, int indent) case DEMANGLE_COMPONENT_RVALUE_REFERENCE_THIS: printf ("rvalue reference this\n"); break; + case DEMANGLE_COMPONENT_XOBJ_MEMBER_FUNCTION: + printf ("explicit object parameter\n"); + break; case DEMANGLE_COMPONENT_TRANSACTION_SAFE: printf ("transaction_safe this\n"); break; @@ -1547,6 +1551,8 @@ d_name (struct d_info *di, int substable) /* <nested-name> ::= N [<CV-qualifiers>] [<ref-qualifier>] <prefix> <unqualified-name> E ::= N [<CV-qualifiers>] [<ref-qualifier>] <template-prefix> <template-args> E + ::= N H <prefix> <unqualified-name> E + ::= N H <template-prefix> <template-args> E */ static struct demangle_component * @@ -1559,13 +1565,24 @@ d_nested_name (struct d_info *di) if (! d_check_char (di, 'N')) return NULL; - pret = d_cv_qualifiers (di, &ret, 1); - if (pret == NULL) - return NULL; + if (d_peek_char (di) == 'H') + { + d_advance (di, 1); + di->expansion += sizeof "this"; + pret = &ret; + rqual = d_make_comp (di, DEMANGLE_COMPONENT_XOBJ_MEMBER_FUNCTION, + NULL, NULL); + } + else + { + pret = d_cv_qualifiers (di, &ret, 1); + if (pret == NULL) + return NULL; - /* Parse the ref-qualifier now and then attach it - once we have something to attach it to. */ - rqual = d_ref_qualifier (di, NULL); + /* Parse the ref-qualifier now and then attach it + once we have something to attach it to. */ + rqual = d_ref_qualifier (di, NULL); + } *pret = d_prefix (di, 1); if (*pret == NULL) @@ -4427,6 +4444,7 @@ d_count_templates_scopes (struct d_print_info *dpi, case DEMANGLE_COMPONENT_CONST_THIS: case DEMANGLE_COMPONENT_REFERENCE_THIS: case DEMANGLE_COMPONENT_RVALUE_REFERENCE_THIS: + case DEMANGLE_COMPONENT_XOBJ_MEMBER_FUNCTION: case DEMANGLE_COMPONENT_TRANSACTION_SAFE: case DEMANGLE_COMPONENT_NOEXCEPT: case DEMANGLE_COMPONENT_THROW_SPEC: @@ -6521,6 +6539,8 @@ d_print_mod (struct d_print_info *dpi, int options, case DEMANGLE_COMPONENT_RVALUE_REFERENCE: d_append_string (dpi, "&&"); return; + case DEMANGLE_COMPONENT_XOBJ_MEMBER_FUNCTION: + return; case DEMANGLE_COMPONENT_COMPLEX: d_append_string (dpi, " _Complex"); return; @@ -6559,11 +6579,13 @@ d_print_function_type (struct d_print_info *dpi, int options, { int need_paren; int need_space; + int xobj_memfn; struct d_print_mod *p; struct d_print_mod *hold_modifiers; need_paren = 0; need_space = 0; + xobj_memfn = 0; for (p = mods; p != NULL; p = p->next) { if (p->printed) @@ -6586,7 +6608,8 @@ d_print_function_type (struct d_print_info *dpi, int options, need_space = 1; need_paren = 1; break; - FNQUAL_COMPONENT_CASE: + case DEMANGLE_COMPONENT_XOBJ_MEMBER_FUNCTION: + xobj_memfn = 1; break; default: break; @@ -6617,6 +6640,8 @@ d_print_function_type (struct d_print_info *dpi, int options, d_append_char (dpi, ')'); d_append_char (dpi, '('); + if (xobj_memfn) + d_append_string (dpi, "this "); if (d_right (dc) != NULL) d_print_comp (dpi, options, d_right (dc)); diff --git a/libiberty/testsuite/demangle-expected b/libiberty/testsuite/demangle-expected index 0997e96..0f7b97a 100644 --- a/libiberty/testsuite/demangle-expected +++ b/libiberty/testsuite/demangle-expected @@ -1700,3 +1700,12 @@ void f<int>() requires C<int> # requires after () _Z1fIiEvvQ1CIT_E void f<int>() requires C<int> + +_ZNH1S3fooES_ +S::foo(this S) + +_ZNH1S3barILi5EiEEvS_T0_ +void S::bar<5, int>(this S, int) + +_ZNH1S3bazERKS_ +S::baz(this S const&) diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index 056174c..c2496d4 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,224 @@ +2024-01-15 Patrick Palka <ppalka@redhat.com> + + * include/std/variant (__detail::__variant::_Variadic_union): + Add bool __trivially_destructible template parameter. + (__detail::__variant::_Variadic_union::~_Variadic_union): + Use __trivially_destructible in constraints instead. + (__detail::__variant::_Variant_storage): Pass + __trivially_destructible value to _Variadic_union. + +2024-01-15 Patrick Palka <ppalka@redhat.com> + + * include/bits/stl_iterator.h (const_iterator): Define conversion + operators as per P2836R1. + * include/bits/version.def (ranges_as_const): Update value. + * include/bits/version.h: Regenerate. + * testsuite/24_iterators/const_iterator/1.cc (test04): New test. + * testsuite/std/ranges/adaptors/as_const/1.cc: Adjust expected + value of __cpp_lib_ranges_as_const. + * testsuite/std/ranges/version_c++23.cc: Likewise. + +2024-01-15 Jonathan Wakely <jwakely@redhat.com> + + PR libstdc++/108822 + * include/std/tuple (__assignable, __is_nothrow_assignable): + Move pre-C++20 definitions adjacent to their use. + +2024-01-15 Jonathan Wakely <jwakely@redhat.com> + + PR testsuite/113366 + * include/std/format (basic_format_arg): Use __formattable + variable template instead of __format::__formattable_with + concept. + +2024-01-15 Jonathan Wakely <jwakely@redhat.com> + + * src/c++20/tzdata.zi: Import new file from 2023d release. + * src/c++20/tzdb.cc (tzdb_list::_Node::_S_read_leap_seconds) + Update expiry date for leap seconds list. + +2024-01-13 Jonathan Wakely <jwakely@redhat.com> + + PR libstdc++/108822 + * include/std/tuple (tuple): Add checks for dangling references. + Reimplement constraints and constant expressions using C++20 + features. + * include/std/type_traits [C++20] + (__is_implicitly_default_constructible_v): Define. + (__is_implicitly_default_constructible): Use variable template. + * testsuite/20_util/tuple/dangling_ref.cc: New test. + +2024-01-13 Patrick Palka <ppalka@redhat.com> + + PR libstdc++/108827 + PR libstdc++/111327 + * include/bits/version.def (bind_back): Define. + * include/bits/version.h: Regenerate. + * include/std/functional (_Bind_back): Define for C++23. + (bind_back): Likewise. + * testsuite/20_util/function_objects/bind_back/1.cc: New test + (adapted from corresponding bind_front test). + * testsuite/20_util/function_objects/bind_back/111327.cc: Likewise. + +2024-01-13 Patrick Palka <ppalka@redhat.com> + + * include/std/functional (_Bind_front): Remove =default special + member function declarations. + (_Bind_front::operator()): Implement using C++23 deducing this + when available. + * testsuite/20_util/function_objects/bind_front/111327.cc: + Adjust testcase to expect better errors in C++23 mode. + +2024-01-13 Patrick Palka <ppalka@redhat.com> + + * include/std/ranges (views::__adaptor::operator|): Perform + perfect forwarding of arguments. + (views::__adaptor::_RangeAdaptor::operator()): Pass dummy + first argument to _Partial. + (views::__adaptor::_Partial::_Partial): Likewise. Add dummy + first parameter. + (views::__adaptor::_Pipe::_Pipe): Perform perfect forwarding + of arguments. + (to): Pass dummy first argument to _Partial. + +2024-01-13 Jonathan Wakely <jwakely@redhat.com> + + PR libstdc++/107466 + * include/bits/random.tcc (subtract_with_carry_engine::seed): + Implement proposed resolution of LWG 4014. + * testsuite/26_numerics/random/pr60037-neg.cc: Adjust dg-error + line number. + * testsuite/26_numerics/random/subtract_with_carry_engine/cons/lwg3809.cc: + Check for expected result of 64-bit engine with seed that + doesn't fit in 32-bits. + +2024-01-12 Jonathan Wakely <jwakely@redhat.com> + + PR libstdc++/113320 + * include/std/format (__format::_Runtime_format_string): Add + constructor and disable copy operations. + (basic_format_string(_Runtime_format_string)): Add noexcept and + take parameter by value not rvalue reference. + (runtime_format): Add noexcept. + * testsuite/std/format/runtime_format.cc: Check noexcept. Check + that construction is only possible from prvalues, not xvalues. + +2024-01-12 Jonathan Wakely <jwakely@redhat.com> + + PR libstdc++/105505 + * include/bits/stl_pair.h (pair::pair(U1&&, U2&&)) [C++23]: Add + default template arguments, as per P1951R1. + * testsuite/20_util/pair/cons/default_tmpl_args.cc: New test. + +2024-01-12 Jonathan Wakely <jwakely@redhat.com> + + * include/std/format (__format::_Arg_store): Fix PR number in + comment. Simplify preprocessor code. + +2024-01-11 Jonathan Wakely <jwakely@redhat.com> + + * doc/xml/manual/evolution.xml: Fix spelling. + * doc/html/manual/api.html: Regenerate. + +2024-01-11 Jonathan Wakely <jwakely@redhat.com> + + * doc/xml/manual/evolution.xml: Document addition of + libstdc++exp.a. + * doc/html/*: Regenerate. + +2024-01-11 Marcus Haehnel <marcus.haehnel@kernkonzept.com> + + * libsupc++/eh_unex_handler.cc: Adjust definition type to + declaration. + +2024-01-11 Michael Levine <mlevine55@bloomberg.net> + + * include/std/ranges (__glibcxx_want_ranges_iota): Remove + duplicate definition. + +2024-01-11 François Dumont <fdumont@gcc.gnu.org> + + PR libstdc++/112477 + * src/c++11/debug.cc + (_Safe_iterator_base::_M_attach): Reset _M_version to 0 if attaching to null + sequence. + (_Safe_iterator_base::_M_attach_single): Likewise. + (_Safe_local_iterator_base::_M_attach): Likewise. + (_Safe_local_iterator_base::_M_attach_single): Likewise. + * testsuite/23_containers/map/debug/112477.cc: New test case. + +2024-01-11 Patrick Palka <ppalka@redhat.com> + + * include/bits/move.h (__like_t): Define in C++23 mode. + * include/std/ranges (views::__adaptor::Partial::operator()): + Implement using C++23 deducing this when available. + (views::__adaptor::_Pipe::operator()): Likewise. + * testsuite/std/ranges/adaptors/100577.cc: Adjust testcase to + accept new "no match for call" errors issued in C++23 mode. + * testsuite/std/ranges/adaptors/lazy_split_neg.cc: Likewise. + +2024-01-11 Jonathan Wakely <jwakely@redhat.com> + + * python/libstdcxx/v6/printers.py (StdIntegralConstantPrinter): + Add printer for std::integral_constant. + * testsuite/libstdc++-prettyprinters/cxx11.cc: Test it. + +2024-01-11 Jonathan Wakely <jwakely@redhat.com> + + PR libstdc++/113258 + * libsupc++/new_opa.cc: Prefer to use posix_memalign if + available. + +2024-01-11 Ken Matsui <kmatsui@gcc.gnu.org> + + * src/filesystem/ops-common.h (stat_type): Use using. + +2024-01-11 Ken Matsui <kmatsui@gcc.gnu.org> + + PR libstdc++/113250 + * src/c++17/fs_ops.cc (fs::equivalent): Use || instead of &&. + * src/filesystem/ops.cc (fs::equivalent): Likewise. + * testsuite/27_io/filesystem/operations/equivalent.cc: Handle + error codes. + * testsuite/experimental/filesystem/operations/equivalent.cc: + Likewise. + +2024-01-11 Ken Matsui <kmatsui@gcc.gnu.org> + + * include/std/type_traits (is_compound): Do not use __not_. + (is_compound_v): Use is_fundamental_v instead. + +2024-01-11 Patrick Palka <ppalka@redhat.com> + + * include/bits/utility.h (_Nth_type): Use + _GLIBCXX_USE_BUILTIN_TRAIT instead of __has_builtin. + +2024-01-09 Jonathan Wakely <jwakely@redhat.com> + + * include/bits/unicode-data.h: Regenerate. + * include/bits/unicode.h (_Utf_iterator::operator++()): Fix off + by one error. + (__incb_property): Add missing check for values before the + first edge. + (__is_extended_pictographic): Invert return values to fix + copy&pasted logic. + (_Grapheme_cluster_view::_Iterator): Remove second iterator + member and find end of cluster lazily. + * testsuite/ext/unicode/grapheme_view.cc: New test. + * testsuite/ext/unicode/properties.cc: New test. + * testsuite/ext/unicode/view.cc: New test. + +2024-01-09 Andreas Schwab <schwab@linux-m68k.org> + + * scripts/extract_symvers.in: Require final colon to only match + .dsynsym in the header of the dynamic symtab. + +2024-01-09 Jonathan Wakely <jwakely@redhat.com> + + * include/bits/chrono_io.h (__formatter_chrono::_M_F): Simplify + handling of string returned from std::format. + (__formatter_chrono::_M_R_T): Likewise. + 2024-01-08 Jonathan Wakely <jwakely@redhat.com> * include/bits/unicode.h (__null_sentinel): Remove. diff --git a/libstdc++-v3/doc/html/index.html b/libstdc++-v3/doc/html/index.html index 414fcac..8648d8e 100644 --- a/libstdc++-v3/doc/html/index.html +++ b/libstdc++-v3/doc/html/index.html @@ -1,6 +1,6 @@ <?xml version="1.0" encoding="UTF-8" standalone="no"?> -<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>The GNU C++ Library</title><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><meta name="description" content="Short Contents Copyright (C) 2008-2023 FSF Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.2 or any later version published by the Free Software Foundation; with no Invariant Sections, with no Front-Cover Texts, and with no Back-Cover Texts. This is the top level of the libstdc++ documentation set. The documentation is divided into the following three sections. Manual Frequently Asked Questions API and Source Documentation" /><meta name="keywords" content="ISO C++, runtime, library" /><link rel="home" href="index.html" title="The GNU C++ Library" /><link rel="next" href="manual/index.html" title="The GNU C++ Library Manual" /></head><body><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="3" align="center">The GNU C++ Library</th></tr><tr><td width="20%" align="left"> </td><th width="60%" align="center"> </th><td width="20%" align="right"> <a accesskey="n" href="manual/index.html">Next</a></td></tr></table><hr /></div><div class="set" lang="en" xml:lang="en"><div class="titlepage"><div><div><h1 class="title"><a id="set-index"></a>The GNU C++ Library</h1></div><div><div class="abstract"><a id="contents"></a><p class="title"><strong>Short Contents</strong></p><p> - Copyright (C) 2008-2023 +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>The GNU C++ Library</title><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><meta name="description" content="Short Contents Copyright (C) 2008-2024 FSF Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.2 or any later version published by the Free Software Foundation; with no Invariant Sections, with no Front-Cover Texts, and with no Back-Cover Texts. This is the top level of the libstdc++ documentation set. The documentation is divided into the following three sections. Manual Frequently Asked Questions API and Source Documentation" /><meta name="keywords" content="ISO C++, runtime, library" /><link rel="home" href="index.html" title="The GNU C++ Library" /><link rel="next" href="manual/index.html" title="The GNU C++ Library Manual" /></head><body><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="3" align="center">The GNU C++ Library</th></tr><tr><td width="20%" align="left"> </td><th width="60%" align="center"> </th><td width="20%" align="right"> <a accesskey="n" href="manual/index.html">Next</a></td></tr></table><hr /></div><div class="set" lang="en" xml:lang="en"><div class="titlepage"><div><div><h1 class="title"><a id="set-index"></a>The GNU C++ Library</h1></div><div><div class="abstract"><a id="contents"></a><p class="title"><strong>Short Contents</strong></p><p> + Copyright (C) 2008-2024 <a class="link" href="https://www.fsf.org" target="_top">FSF </a> </p><p> @@ -142,7 +142,7 @@ Existing tests </a></span></dt><dt><span class="section"><a href="manual/test.html#test.exception.safety.containers"> C++11 Requirements Test Sequence Descriptions -</a></span></dt></dl></dd></dl></dd></dl></dd><dt><span class="section"><a href="manual/abi.html">ABI Policy and Guidelines</a></span></dt><dd><dl><dt><span class="section"><a href="manual/abi.html#abi.cxx_interface">The C++ Interface</a></span></dt><dt><span class="section"><a href="manual/abi.html#abi.versioning">Versioning</a></span></dt><dd><dl><dt><span class="section"><a href="manual/abi.html#abi.versioning.goals">Goals</a></span></dt><dt><span class="section"><a href="manual/abi.html#abi.versioning.history">History</a></span></dt><dt><span class="section"><a href="manual/abi.html#abi.versioning.prereq">Prerequisites</a></span></dt><dt><span class="section"><a href="manual/abi.html#abi.versioning.config">Configuring</a></span></dt><dt><span class="section"><a href="manual/abi.html#abi.versioning.active">Checking Active</a></span></dt></dl></dd><dt><span class="section"><a href="manual/abi.html#abi.changes_allowed">Allowed Changes</a></span></dt><dt><span class="section"><a href="manual/abi.html#abi.changes_no">Prohibited Changes</a></span></dt><dt><span class="section"><a href="manual/abi.html#abi.impl">Implementation</a></span></dt><dt><span class="section"><a href="manual/abi.html#abi.testing">Testing</a></span></dt><dd><dl><dt><span class="section"><a href="manual/abi.html#abi.testing.single">Single ABI Testing</a></span></dt><dt><span class="section"><a href="manual/abi.html#abi.testing.multi">Multiple ABI Testing</a></span></dt></dl></dd><dt><span class="section"><a href="manual/abi.html#abi.issues">Outstanding Issues</a></span></dt></dl></dd><dt><span class="section"><a href="manual/api.html">API Evolution and Deprecation History</a></span></dt><dd><dl><dt><span class="section"><a href="manual/api.html#api.rel_300"><code class="constant">3.0</code></a></span></dt><dt><span class="section"><a href="manual/api.html#api.rel_310"><code class="constant">3.1</code></a></span></dt><dt><span class="section"><a href="manual/api.html#api.rel_320"><code class="constant">3.2</code></a></span></dt><dt><span class="section"><a href="manual/api.html#api.rel_330"><code class="constant">3.3</code></a></span></dt><dt><span class="section"><a href="manual/api.html#api.rel_340"><code class="constant">3.4</code></a></span></dt><dt><span class="section"><a href="manual/api.html#api.rel_400"><code class="constant">4.0</code></a></span></dt><dt><span class="section"><a href="manual/api.html#api.rel_410"><code class="constant">4.1</code></a></span></dt><dt><span class="section"><a href="manual/api.html#api.rel_420"><code class="constant">4.2</code></a></span></dt><dt><span class="section"><a href="manual/api.html#api.rel_430"><code class="constant">4.3</code></a></span></dt><dt><span class="section"><a href="manual/api.html#api.rel_440"><code class="constant">4.4</code></a></span></dt><dt><span class="section"><a href="manual/api.html#api.rel_450"><code class="constant">4.5</code></a></span></dt><dt><span class="section"><a href="manual/api.html#api.rel_460"><code class="constant">4.6</code></a></span></dt><dt><span class="section"><a href="manual/api.html#api.rel_470"><code class="constant">4.7</code></a></span></dt><dt><span class="section"><a href="manual/api.html#api.rel_480"><code class="constant">4.8</code></a></span></dt><dt><span class="section"><a href="manual/api.html#api.rel_490"><code class="constant">4.9</code></a></span></dt><dt><span class="section"><a href="manual/api.html#api.rel_51"><code class="constant">5</code></a></span></dt><dd><dl><dt><span class="section"><a href="manual/api.html#api.rel_53"><code class="constant">5.3</code></a></span></dt></dl></dd><dt><span class="section"><a href="manual/api.html#api.rel_61"><code class="constant">6</code></a></span></dt><dt><span class="section"><a href="manual/api.html#api.rel_71"><code class="constant">7</code></a></span></dt><dd><dl><dt><span class="section"><a href="manual/api.html#api.rel_72"><code class="constant">7.2</code></a></span></dt><dt><span class="section"><a href="manual/api.html#api.rel_73"><code class="constant">7.3</code></a></span></dt></dl></dd><dt><span class="section"><a href="manual/api.html#api.rel_81"><code class="constant">8</code></a></span></dt><dt><span class="section"><a href="manual/api.html#api.rel_91"><code class="constant">9</code></a></span></dt><dt><span class="section"><a href="manual/api.html#api.rel_101"><code class="constant">10</code></a></span></dt><dt><span class="section"><a href="manual/api.html#api.rel_111"><code class="constant">11</code></a></span></dt><dt><span class="section"><a href="manual/api.html#api.rel_121"><code class="constant">12</code></a></span></dt><dt><span class="section"><a href="manual/api.html#api.rel_123"><code class="constant">12.3</code></a></span></dt><dt><span class="section"><a href="manual/api.html#api.rel_131"><code class="constant">13</code></a></span></dt><dt><span class="section"><a href="manual/api.html#api.rel_141"><code class="constant">14</code></a></span></dt></dl></dd><dt><span class="section"><a href="manual/backwards.html">Backwards Compatibility</a></span></dt><dd><dl><dt><span class="section"><a href="manual/backwards.html#backwards.first">First</a></span></dt><dt><span class="section"><a href="manual/backwards.html#backwards.second">Second</a></span></dt><dt><span class="section"><a href="manual/backwards.html#backwards.third">Third</a></span></dt><dd><dl><dt><span class="section"><a href="manual/backwards.html#backwards.third.headers">Pre-ISO headers removed</a></span></dt><dt><span class="section"><a href="manual/backwards.html#backwards.third.hash">Extension headers hash_map, hash_set moved to ext or backwards</a></span></dt><dt><span class="section"><a href="manual/backwards.html#backwards.third.nocreate_noreplace">No <code class="code">ios::nocreate/ios::noreplace</code>. +</a></span></dt></dl></dd></dl></dd></dl></dd><dt><span class="section"><a href="manual/abi.html">ABI Policy and Guidelines</a></span></dt><dd><dl><dt><span class="section"><a href="manual/abi.html#abi.cxx_interface">The C++ Interface</a></span></dt><dt><span class="section"><a href="manual/abi.html#abi.versioning">Versioning</a></span></dt><dd><dl><dt><span class="section"><a href="manual/abi.html#abi.versioning.goals">Goals</a></span></dt><dt><span class="section"><a href="manual/abi.html#abi.versioning.history">History</a></span></dt><dt><span class="section"><a href="manual/abi.html#abi.versioning.prereq">Prerequisites</a></span></dt><dt><span class="section"><a href="manual/abi.html#abi.versioning.config">Configuring</a></span></dt><dt><span class="section"><a href="manual/abi.html#abi.versioning.active">Checking Active</a></span></dt></dl></dd><dt><span class="section"><a href="manual/abi.html#abi.changes_allowed">Allowed Changes</a></span></dt><dt><span class="section"><a href="manual/abi.html#abi.changes_no">Prohibited Changes</a></span></dt><dt><span class="section"><a href="manual/abi.html#abi.impl">Implementation</a></span></dt><dt><span class="section"><a href="manual/abi.html#abi.testing">Testing</a></span></dt><dd><dl><dt><span class="section"><a href="manual/abi.html#abi.testing.single">Single ABI Testing</a></span></dt><dt><span class="section"><a href="manual/abi.html#abi.testing.multi">Multiple ABI Testing</a></span></dt></dl></dd><dt><span class="section"><a href="manual/abi.html#abi.issues">Outstanding Issues</a></span></dt></dl></dd><dt><span class="section"><a href="manual/api.html">API Evolution and Deprecation History</a></span></dt><dd><dl><dt><span class="section"><a href="manual/api.html#api.rel_300"><code class="constant">3.0</code></a></span></dt><dt><span class="section"><a href="manual/api.html#api.rel_310"><code class="constant">3.1</code></a></span></dt><dt><span class="section"><a href="manual/api.html#api.rel_320"><code class="constant">3.2</code></a></span></dt><dt><span class="section"><a href="manual/api.html#api.rel_330"><code class="constant">3.3</code></a></span></dt><dt><span class="section"><a href="manual/api.html#api.rel_340"><code class="constant">3.4</code></a></span></dt><dt><span class="section"><a href="manual/api.html#api.rel_400"><code class="constant">4.0</code></a></span></dt><dt><span class="section"><a href="manual/api.html#api.rel_410"><code class="constant">4.1</code></a></span></dt><dt><span class="section"><a href="manual/api.html#api.rel_420"><code class="constant">4.2</code></a></span></dt><dt><span class="section"><a href="manual/api.html#api.rel_430"><code class="constant">4.3</code></a></span></dt><dt><span class="section"><a href="manual/api.html#api.rel_440"><code class="constant">4.4</code></a></span></dt><dt><span class="section"><a href="manual/api.html#api.rel_450"><code class="constant">4.5</code></a></span></dt><dt><span class="section"><a href="manual/api.html#api.rel_460"><code class="constant">4.6</code></a></span></dt><dt><span class="section"><a href="manual/api.html#api.rel_470"><code class="constant">4.7</code></a></span></dt><dt><span class="section"><a href="manual/api.html#api.rel_480"><code class="constant">4.8</code></a></span></dt><dt><span class="section"><a href="manual/api.html#api.rel_490"><code class="constant">4.9</code></a></span></dt><dt><span class="section"><a href="manual/api.html#api.rel_51"><code class="constant">5</code></a></span></dt><dd><dl><dt><span class="section"><a href="manual/api.html#api.rel_53"><code class="constant">5.3</code></a></span></dt></dl></dd><dt><span class="section"><a href="manual/api.html#api.rel_61"><code class="constant">6</code></a></span></dt><dt><span class="section"><a href="manual/api.html#api.rel_71"><code class="constant">7</code></a></span></dt><dd><dl><dt><span class="section"><a href="manual/api.html#api.rel_72"><code class="constant">7.2</code></a></span></dt><dt><span class="section"><a href="manual/api.html#api.rel_73"><code class="constant">7.3</code></a></span></dt></dl></dd><dt><span class="section"><a href="manual/api.html#api.rel_81"><code class="constant">8</code></a></span></dt><dt><span class="section"><a href="manual/api.html#api.rel_91"><code class="constant">9</code></a></span></dt><dt><span class="section"><a href="manual/api.html#api.rel_101"><code class="constant">10</code></a></span></dt><dt><span class="section"><a href="manual/api.html#api.rel_111"><code class="constant">11</code></a></span></dt><dt><span class="section"><a href="manual/api.html#api.rel_121"><code class="constant">12</code></a></span></dt><dt><span class="section"><a href="manual/api.html#api.rel_123"><code class="constant">12.3</code></a></span></dt><dt><span class="section"><a href="manual/api.html#api.rel_131"><code class="constant">13</code></a></span></dt><dt><span class="section"><a href="manual/api.html#api.rel_133"><code class="constant">13.3</code></a></span></dt><dt><span class="section"><a href="manual/api.html#api.rel_141"><code class="constant">14</code></a></span></dt></dl></dd><dt><span class="section"><a href="manual/backwards.html">Backwards Compatibility</a></span></dt><dd><dl><dt><span class="section"><a href="manual/backwards.html#backwards.first">First</a></span></dt><dt><span class="section"><a href="manual/backwards.html#backwards.second">Second</a></span></dt><dt><span class="section"><a href="manual/backwards.html#backwards.third">Third</a></span></dt><dd><dl><dt><span class="section"><a href="manual/backwards.html#backwards.third.headers">Pre-ISO headers removed</a></span></dt><dt><span class="section"><a href="manual/backwards.html#backwards.third.hash">Extension headers hash_map, hash_set moved to ext or backwards</a></span></dt><dt><span class="section"><a href="manual/backwards.html#backwards.third.nocreate_noreplace">No <code class="code">ios::nocreate/ios::noreplace</code>. </a></span></dt><dt><span class="section"><a href="manual/backwards.html#backwards.third.streamattach"> No <code class="code">stream::attach(int fd)</code> </a></span></dt><dt><span class="section"><a href="manual/backwards.html#backwards.third.support_cxx98"> diff --git a/libstdc++-v3/doc/html/manual/api.html b/libstdc++-v3/doc/html/manual/api.html index 27c0d09..59ed4c8 100644 --- a/libstdc++-v3/doc/html/manual/api.html +++ b/libstdc++-v3/doc/html/manual/api.html @@ -485,6 +485,10 @@ and later. </p></div><div class="section"><div class="titlepage"><div><div><h3 class="title"><a id="api.rel_131"></a><code class="constant">13</code></h3></div></div></div><p> Tunables <span style="color: red"><variable>glibcxx.eh_pool.obj_count</variable></span> and <span style="color: red"><variable>glibcxx.eh_pool.obj_size</variable></span> were added. +</p><p>Static library <code class="filename">libstdc++exp.a</code> was added +to provide the symbols for the experimental C++ Contracts support.</p></div><div class="section"><div class="titlepage"><div><div><h3 class="title"><a id="api.rel_133"></a><code class="constant">13.3</code></h3></div></div></div><p> +Symbols for the Filesystem TS and C++23 <code class="filename"><stacktrace></code> +header were added to the static library <code class="filename">libstdc++exp.a</code>. </p></div><div class="section"><div class="titlepage"><div><div><h3 class="title"><a id="api.rel_141"></a><code class="constant">14</code></h3></div></div></div><p> Deprecate the non-standard overload that allows <code class="code">std::setfill</code> to be used with <code class="code">std::basic_istream</code>. diff --git a/libstdc++-v3/doc/html/manual/appendix.html b/libstdc++-v3/doc/html/manual/appendix.html index cd9aff0..03746f9 100644 --- a/libstdc++-v3/doc/html/manual/appendix.html +++ b/libstdc++-v3/doc/html/manual/appendix.html @@ -16,7 +16,7 @@ Existing tests </a></span></dt><dt><span class="section"><a href="test.html#test.exception.safety.containers"> C++11 Requirements Test Sequence Descriptions -</a></span></dt></dl></dd></dl></dd></dl></dd><dt><span class="section"><a href="abi.html">ABI Policy and Guidelines</a></span></dt><dd><dl><dt><span class="section"><a href="abi.html#abi.cxx_interface">The C++ Interface</a></span></dt><dt><span class="section"><a href="abi.html#abi.versioning">Versioning</a></span></dt><dd><dl><dt><span class="section"><a href="abi.html#abi.versioning.goals">Goals</a></span></dt><dt><span class="section"><a href="abi.html#abi.versioning.history">History</a></span></dt><dt><span class="section"><a href="abi.html#abi.versioning.prereq">Prerequisites</a></span></dt><dt><span class="section"><a href="abi.html#abi.versioning.config">Configuring</a></span></dt><dt><span class="section"><a href="abi.html#abi.versioning.active">Checking Active</a></span></dt></dl></dd><dt><span class="section"><a href="abi.html#abi.changes_allowed">Allowed Changes</a></span></dt><dt><span class="section"><a href="abi.html#abi.changes_no">Prohibited Changes</a></span></dt><dt><span class="section"><a href="abi.html#abi.impl">Implementation</a></span></dt><dt><span class="section"><a href="abi.html#abi.testing">Testing</a></span></dt><dd><dl><dt><span class="section"><a href="abi.html#abi.testing.single">Single ABI Testing</a></span></dt><dt><span class="section"><a href="abi.html#abi.testing.multi">Multiple ABI Testing</a></span></dt></dl></dd><dt><span class="section"><a href="abi.html#abi.issues">Outstanding Issues</a></span></dt></dl></dd><dt><span class="section"><a href="api.html">API Evolution and Deprecation History</a></span></dt><dd><dl><dt><span class="section"><a href="api.html#api.rel_300"><code class="constant">3.0</code></a></span></dt><dt><span class="section"><a href="api.html#api.rel_310"><code class="constant">3.1</code></a></span></dt><dt><span class="section"><a href="api.html#api.rel_320"><code class="constant">3.2</code></a></span></dt><dt><span class="section"><a href="api.html#api.rel_330"><code class="constant">3.3</code></a></span></dt><dt><span class="section"><a href="api.html#api.rel_340"><code class="constant">3.4</code></a></span></dt><dt><span class="section"><a href="api.html#api.rel_400"><code class="constant">4.0</code></a></span></dt><dt><span class="section"><a href="api.html#api.rel_410"><code class="constant">4.1</code></a></span></dt><dt><span class="section"><a href="api.html#api.rel_420"><code class="constant">4.2</code></a></span></dt><dt><span class="section"><a href="api.html#api.rel_430"><code class="constant">4.3</code></a></span></dt><dt><span class="section"><a href="api.html#api.rel_440"><code class="constant">4.4</code></a></span></dt><dt><span class="section"><a href="api.html#api.rel_450"><code class="constant">4.5</code></a></span></dt><dt><span class="section"><a href="api.html#api.rel_460"><code class="constant">4.6</code></a></span></dt><dt><span class="section"><a href="api.html#api.rel_470"><code class="constant">4.7</code></a></span></dt><dt><span class="section"><a href="api.html#api.rel_480"><code class="constant">4.8</code></a></span></dt><dt><span class="section"><a href="api.html#api.rel_490"><code class="constant">4.9</code></a></span></dt><dt><span class="section"><a href="api.html#api.rel_51"><code class="constant">5</code></a></span></dt><dd><dl><dt><span class="section"><a href="api.html#api.rel_53"><code class="constant">5.3</code></a></span></dt></dl></dd><dt><span class="section"><a href="api.html#api.rel_61"><code class="constant">6</code></a></span></dt><dt><span class="section"><a href="api.html#api.rel_71"><code class="constant">7</code></a></span></dt><dd><dl><dt><span class="section"><a href="api.html#api.rel_72"><code class="constant">7.2</code></a></span></dt><dt><span class="section"><a href="api.html#api.rel_73"><code class="constant">7.3</code></a></span></dt></dl></dd><dt><span class="section"><a href="api.html#api.rel_81"><code class="constant">8</code></a></span></dt><dt><span class="section"><a href="api.html#api.rel_91"><code class="constant">9</code></a></span></dt><dt><span class="section"><a href="api.html#api.rel_101"><code class="constant">10</code></a></span></dt><dt><span class="section"><a href="api.html#api.rel_111"><code class="constant">11</code></a></span></dt><dt><span class="section"><a href="api.html#api.rel_121"><code class="constant">12</code></a></span></dt><dt><span class="section"><a href="api.html#api.rel_123"><code class="constant">12.3</code></a></span></dt><dt><span class="section"><a href="api.html#api.rel_131"><code class="constant">13</code></a></span></dt><dt><span class="section"><a href="api.html#api.rel_141"><code class="constant">14</code></a></span></dt></dl></dd><dt><span class="section"><a href="backwards.html">Backwards Compatibility</a></span></dt><dd><dl><dt><span class="section"><a href="backwards.html#backwards.first">First</a></span></dt><dt><span class="section"><a href="backwards.html#backwards.second">Second</a></span></dt><dt><span class="section"><a href="backwards.html#backwards.third">Third</a></span></dt><dd><dl><dt><span class="section"><a href="backwards.html#backwards.third.headers">Pre-ISO headers removed</a></span></dt><dt><span class="section"><a href="backwards.html#backwards.third.hash">Extension headers hash_map, hash_set moved to ext or backwards</a></span></dt><dt><span class="section"><a href="backwards.html#backwards.third.nocreate_noreplace">No <code class="code">ios::nocreate/ios::noreplace</code>. +</a></span></dt></dl></dd></dl></dd></dl></dd><dt><span class="section"><a href="abi.html">ABI Policy and Guidelines</a></span></dt><dd><dl><dt><span class="section"><a href="abi.html#abi.cxx_interface">The C++ Interface</a></span></dt><dt><span class="section"><a href="abi.html#abi.versioning">Versioning</a></span></dt><dd><dl><dt><span class="section"><a href="abi.html#abi.versioning.goals">Goals</a></span></dt><dt><span class="section"><a href="abi.html#abi.versioning.history">History</a></span></dt><dt><span class="section"><a href="abi.html#abi.versioning.prereq">Prerequisites</a></span></dt><dt><span class="section"><a href="abi.html#abi.versioning.config">Configuring</a></span></dt><dt><span class="section"><a href="abi.html#abi.versioning.active">Checking Active</a></span></dt></dl></dd><dt><span class="section"><a href="abi.html#abi.changes_allowed">Allowed Changes</a></span></dt><dt><span class="section"><a href="abi.html#abi.changes_no">Prohibited Changes</a></span></dt><dt><span class="section"><a href="abi.html#abi.impl">Implementation</a></span></dt><dt><span class="section"><a href="abi.html#abi.testing">Testing</a></span></dt><dd><dl><dt><span class="section"><a href="abi.html#abi.testing.single">Single ABI Testing</a></span></dt><dt><span class="section"><a href="abi.html#abi.testing.multi">Multiple ABI Testing</a></span></dt></dl></dd><dt><span class="section"><a href="abi.html#abi.issues">Outstanding Issues</a></span></dt></dl></dd><dt><span class="section"><a href="api.html">API Evolution and Deprecation History</a></span></dt><dd><dl><dt><span class="section"><a href="api.html#api.rel_300"><code class="constant">3.0</code></a></span></dt><dt><span class="section"><a href="api.html#api.rel_310"><code class="constant">3.1</code></a></span></dt><dt><span class="section"><a href="api.html#api.rel_320"><code class="constant">3.2</code></a></span></dt><dt><span class="section"><a href="api.html#api.rel_330"><code class="constant">3.3</code></a></span></dt><dt><span class="section"><a href="api.html#api.rel_340"><code class="constant">3.4</code></a></span></dt><dt><span class="section"><a href="api.html#api.rel_400"><code class="constant">4.0</code></a></span></dt><dt><span class="section"><a href="api.html#api.rel_410"><code class="constant">4.1</code></a></span></dt><dt><span class="section"><a href="api.html#api.rel_420"><code class="constant">4.2</code></a></span></dt><dt><span class="section"><a href="api.html#api.rel_430"><code class="constant">4.3</code></a></span></dt><dt><span class="section"><a href="api.html#api.rel_440"><code class="constant">4.4</code></a></span></dt><dt><span class="section"><a href="api.html#api.rel_450"><code class="constant">4.5</code></a></span></dt><dt><span class="section"><a href="api.html#api.rel_460"><code class="constant">4.6</code></a></span></dt><dt><span class="section"><a href="api.html#api.rel_470"><code class="constant">4.7</code></a></span></dt><dt><span class="section"><a href="api.html#api.rel_480"><code class="constant">4.8</code></a></span></dt><dt><span class="section"><a href="api.html#api.rel_490"><code class="constant">4.9</code></a></span></dt><dt><span class="section"><a href="api.html#api.rel_51"><code class="constant">5</code></a></span></dt><dd><dl><dt><span class="section"><a href="api.html#api.rel_53"><code class="constant">5.3</code></a></span></dt></dl></dd><dt><span class="section"><a href="api.html#api.rel_61"><code class="constant">6</code></a></span></dt><dt><span class="section"><a href="api.html#api.rel_71"><code class="constant">7</code></a></span></dt><dd><dl><dt><span class="section"><a href="api.html#api.rel_72"><code class="constant">7.2</code></a></span></dt><dt><span class="section"><a href="api.html#api.rel_73"><code class="constant">7.3</code></a></span></dt></dl></dd><dt><span class="section"><a href="api.html#api.rel_81"><code class="constant">8</code></a></span></dt><dt><span class="section"><a href="api.html#api.rel_91"><code class="constant">9</code></a></span></dt><dt><span class="section"><a href="api.html#api.rel_101"><code class="constant">10</code></a></span></dt><dt><span class="section"><a href="api.html#api.rel_111"><code class="constant">11</code></a></span></dt><dt><span class="section"><a href="api.html#api.rel_121"><code class="constant">12</code></a></span></dt><dt><span class="section"><a href="api.html#api.rel_123"><code class="constant">12.3</code></a></span></dt><dt><span class="section"><a href="api.html#api.rel_131"><code class="constant">13</code></a></span></dt><dt><span class="section"><a href="api.html#api.rel_133"><code class="constant">13.3</code></a></span></dt><dt><span class="section"><a href="api.html#api.rel_141"><code class="constant">14</code></a></span></dt></dl></dd><dt><span class="section"><a href="backwards.html">Backwards Compatibility</a></span></dt><dd><dl><dt><span class="section"><a href="backwards.html#backwards.first">First</a></span></dt><dt><span class="section"><a href="backwards.html#backwards.second">Second</a></span></dt><dt><span class="section"><a href="backwards.html#backwards.third">Third</a></span></dt><dd><dl><dt><span class="section"><a href="backwards.html#backwards.third.headers">Pre-ISO headers removed</a></span></dt><dt><span class="section"><a href="backwards.html#backwards.third.hash">Extension headers hash_map, hash_set moved to ext or backwards</a></span></dt><dt><span class="section"><a href="backwards.html#backwards.third.nocreate_noreplace">No <code class="code">ios::nocreate/ios::noreplace</code>. </a></span></dt><dt><span class="section"><a href="backwards.html#backwards.third.streamattach"> No <code class="code">stream::attach(int fd)</code> </a></span></dt><dt><span class="section"><a href="backwards.html#backwards.third.support_cxx98"> diff --git a/libstdc++-v3/doc/html/manual/appendix_porting.html b/libstdc++-v3/doc/html/manual/appendix_porting.html index a6d0c50..8f2824c 100644 --- a/libstdc++-v3/doc/html/manual/appendix_porting.html +++ b/libstdc++-v3/doc/html/manual/appendix_porting.html @@ -14,7 +14,7 @@ Existing tests </a></span></dt><dt><span class="section"><a href="test.html#test.exception.safety.containers"> C++11 Requirements Test Sequence Descriptions -</a></span></dt></dl></dd></dl></dd></dl></dd><dt><span class="section"><a href="abi.html">ABI Policy and Guidelines</a></span></dt><dd><dl><dt><span class="section"><a href="abi.html#abi.cxx_interface">The C++ Interface</a></span></dt><dt><span class="section"><a href="abi.html#abi.versioning">Versioning</a></span></dt><dd><dl><dt><span class="section"><a href="abi.html#abi.versioning.goals">Goals</a></span></dt><dt><span class="section"><a href="abi.html#abi.versioning.history">History</a></span></dt><dt><span class="section"><a href="abi.html#abi.versioning.prereq">Prerequisites</a></span></dt><dt><span class="section"><a href="abi.html#abi.versioning.config">Configuring</a></span></dt><dt><span class="section"><a href="abi.html#abi.versioning.active">Checking Active</a></span></dt></dl></dd><dt><span class="section"><a href="abi.html#abi.changes_allowed">Allowed Changes</a></span></dt><dt><span class="section"><a href="abi.html#abi.changes_no">Prohibited Changes</a></span></dt><dt><span class="section"><a href="abi.html#abi.impl">Implementation</a></span></dt><dt><span class="section"><a href="abi.html#abi.testing">Testing</a></span></dt><dd><dl><dt><span class="section"><a href="abi.html#abi.testing.single">Single ABI Testing</a></span></dt><dt><span class="section"><a href="abi.html#abi.testing.multi">Multiple ABI Testing</a></span></dt></dl></dd><dt><span class="section"><a href="abi.html#abi.issues">Outstanding Issues</a></span></dt></dl></dd><dt><span class="section"><a href="api.html">API Evolution and Deprecation History</a></span></dt><dd><dl><dt><span class="section"><a href="api.html#api.rel_300"><code class="constant">3.0</code></a></span></dt><dt><span class="section"><a href="api.html#api.rel_310"><code class="constant">3.1</code></a></span></dt><dt><span class="section"><a href="api.html#api.rel_320"><code class="constant">3.2</code></a></span></dt><dt><span class="section"><a href="api.html#api.rel_330"><code class="constant">3.3</code></a></span></dt><dt><span class="section"><a href="api.html#api.rel_340"><code class="constant">3.4</code></a></span></dt><dt><span class="section"><a href="api.html#api.rel_400"><code class="constant">4.0</code></a></span></dt><dt><span class="section"><a href="api.html#api.rel_410"><code class="constant">4.1</code></a></span></dt><dt><span class="section"><a href="api.html#api.rel_420"><code class="constant">4.2</code></a></span></dt><dt><span class="section"><a href="api.html#api.rel_430"><code class="constant">4.3</code></a></span></dt><dt><span class="section"><a href="api.html#api.rel_440"><code class="constant">4.4</code></a></span></dt><dt><span class="section"><a href="api.html#api.rel_450"><code class="constant">4.5</code></a></span></dt><dt><span class="section"><a href="api.html#api.rel_460"><code class="constant">4.6</code></a></span></dt><dt><span class="section"><a href="api.html#api.rel_470"><code class="constant">4.7</code></a></span></dt><dt><span class="section"><a href="api.html#api.rel_480"><code class="constant">4.8</code></a></span></dt><dt><span class="section"><a href="api.html#api.rel_490"><code class="constant">4.9</code></a></span></dt><dt><span class="section"><a href="api.html#api.rel_51"><code class="constant">5</code></a></span></dt><dd><dl><dt><span class="section"><a href="api.html#api.rel_53"><code class="constant">5.3</code></a></span></dt></dl></dd><dt><span class="section"><a href="api.html#api.rel_61"><code class="constant">6</code></a></span></dt><dt><span class="section"><a href="api.html#api.rel_71"><code class="constant">7</code></a></span></dt><dd><dl><dt><span class="section"><a href="api.html#api.rel_72"><code class="constant">7.2</code></a></span></dt><dt><span class="section"><a href="api.html#api.rel_73"><code class="constant">7.3</code></a></span></dt></dl></dd><dt><span class="section"><a href="api.html#api.rel_81"><code class="constant">8</code></a></span></dt><dt><span class="section"><a href="api.html#api.rel_91"><code class="constant">9</code></a></span></dt><dt><span class="section"><a href="api.html#api.rel_101"><code class="constant">10</code></a></span></dt><dt><span class="section"><a href="api.html#api.rel_111"><code class="constant">11</code></a></span></dt><dt><span class="section"><a href="api.html#api.rel_121"><code class="constant">12</code></a></span></dt><dt><span class="section"><a href="api.html#api.rel_123"><code class="constant">12.3</code></a></span></dt><dt><span class="section"><a href="api.html#api.rel_131"><code class="constant">13</code></a></span></dt><dt><span class="section"><a href="api.html#api.rel_141"><code class="constant">14</code></a></span></dt></dl></dd><dt><span class="section"><a href="backwards.html">Backwards Compatibility</a></span></dt><dd><dl><dt><span class="section"><a href="backwards.html#backwards.first">First</a></span></dt><dt><span class="section"><a href="backwards.html#backwards.second">Second</a></span></dt><dt><span class="section"><a href="backwards.html#backwards.third">Third</a></span></dt><dd><dl><dt><span class="section"><a href="backwards.html#backwards.third.headers">Pre-ISO headers removed</a></span></dt><dt><span class="section"><a href="backwards.html#backwards.third.hash">Extension headers hash_map, hash_set moved to ext or backwards</a></span></dt><dt><span class="section"><a href="backwards.html#backwards.third.nocreate_noreplace">No <code class="code">ios::nocreate/ios::noreplace</code>. +</a></span></dt></dl></dd></dl></dd></dl></dd><dt><span class="section"><a href="abi.html">ABI Policy and Guidelines</a></span></dt><dd><dl><dt><span class="section"><a href="abi.html#abi.cxx_interface">The C++ Interface</a></span></dt><dt><span class="section"><a href="abi.html#abi.versioning">Versioning</a></span></dt><dd><dl><dt><span class="section"><a href="abi.html#abi.versioning.goals">Goals</a></span></dt><dt><span class="section"><a href="abi.html#abi.versioning.history">History</a></span></dt><dt><span class="section"><a href="abi.html#abi.versioning.prereq">Prerequisites</a></span></dt><dt><span class="section"><a href="abi.html#abi.versioning.config">Configuring</a></span></dt><dt><span class="section"><a href="abi.html#abi.versioning.active">Checking Active</a></span></dt></dl></dd><dt><span class="section"><a href="abi.html#abi.changes_allowed">Allowed Changes</a></span></dt><dt><span class="section"><a href="abi.html#abi.changes_no">Prohibited Changes</a></span></dt><dt><span class="section"><a href="abi.html#abi.impl">Implementation</a></span></dt><dt><span class="section"><a href="abi.html#abi.testing">Testing</a></span></dt><dd><dl><dt><span class="section"><a href="abi.html#abi.testing.single">Single ABI Testing</a></span></dt><dt><span class="section"><a href="abi.html#abi.testing.multi">Multiple ABI Testing</a></span></dt></dl></dd><dt><span class="section"><a href="abi.html#abi.issues">Outstanding Issues</a></span></dt></dl></dd><dt><span class="section"><a href="api.html">API Evolution and Deprecation History</a></span></dt><dd><dl><dt><span class="section"><a href="api.html#api.rel_300"><code class="constant">3.0</code></a></span></dt><dt><span class="section"><a href="api.html#api.rel_310"><code class="constant">3.1</code></a></span></dt><dt><span class="section"><a href="api.html#api.rel_320"><code class="constant">3.2</code></a></span></dt><dt><span class="section"><a href="api.html#api.rel_330"><code class="constant">3.3</code></a></span></dt><dt><span class="section"><a href="api.html#api.rel_340"><code class="constant">3.4</code></a></span></dt><dt><span class="section"><a href="api.html#api.rel_400"><code class="constant">4.0</code></a></span></dt><dt><span class="section"><a href="api.html#api.rel_410"><code class="constant">4.1</code></a></span></dt><dt><span class="section"><a href="api.html#api.rel_420"><code class="constant">4.2</code></a></span></dt><dt><span class="section"><a href="api.html#api.rel_430"><code class="constant">4.3</code></a></span></dt><dt><span class="section"><a href="api.html#api.rel_440"><code class="constant">4.4</code></a></span></dt><dt><span class="section"><a href="api.html#api.rel_450"><code class="constant">4.5</code></a></span></dt><dt><span class="section"><a href="api.html#api.rel_460"><code class="constant">4.6</code></a></span></dt><dt><span class="section"><a href="api.html#api.rel_470"><code class="constant">4.7</code></a></span></dt><dt><span class="section"><a href="api.html#api.rel_480"><code class="constant">4.8</code></a></span></dt><dt><span class="section"><a href="api.html#api.rel_490"><code class="constant">4.9</code></a></span></dt><dt><span class="section"><a href="api.html#api.rel_51"><code class="constant">5</code></a></span></dt><dd><dl><dt><span class="section"><a href="api.html#api.rel_53"><code class="constant">5.3</code></a></span></dt></dl></dd><dt><span class="section"><a href="api.html#api.rel_61"><code class="constant">6</code></a></span></dt><dt><span class="section"><a href="api.html#api.rel_71"><code class="constant">7</code></a></span></dt><dd><dl><dt><span class="section"><a href="api.html#api.rel_72"><code class="constant">7.2</code></a></span></dt><dt><span class="section"><a href="api.html#api.rel_73"><code class="constant">7.3</code></a></span></dt></dl></dd><dt><span class="section"><a href="api.html#api.rel_81"><code class="constant">8</code></a></span></dt><dt><span class="section"><a href="api.html#api.rel_91"><code class="constant">9</code></a></span></dt><dt><span class="section"><a href="api.html#api.rel_101"><code class="constant">10</code></a></span></dt><dt><span class="section"><a href="api.html#api.rel_111"><code class="constant">11</code></a></span></dt><dt><span class="section"><a href="api.html#api.rel_121"><code class="constant">12</code></a></span></dt><dt><span class="section"><a href="api.html#api.rel_123"><code class="constant">12.3</code></a></span></dt><dt><span class="section"><a href="api.html#api.rel_131"><code class="constant">13</code></a></span></dt><dt><span class="section"><a href="api.html#api.rel_133"><code class="constant">13.3</code></a></span></dt><dt><span class="section"><a href="api.html#api.rel_141"><code class="constant">14</code></a></span></dt></dl></dd><dt><span class="section"><a href="backwards.html">Backwards Compatibility</a></span></dt><dd><dl><dt><span class="section"><a href="backwards.html#backwards.first">First</a></span></dt><dt><span class="section"><a href="backwards.html#backwards.second">Second</a></span></dt><dt><span class="section"><a href="backwards.html#backwards.third">Third</a></span></dt><dd><dl><dt><span class="section"><a href="backwards.html#backwards.third.headers">Pre-ISO headers removed</a></span></dt><dt><span class="section"><a href="backwards.html#backwards.third.hash">Extension headers hash_map, hash_set moved to ext or backwards</a></span></dt><dt><span class="section"><a href="backwards.html#backwards.third.nocreate_noreplace">No <code class="code">ios::nocreate/ios::noreplace</code>. </a></span></dt><dt><span class="section"><a href="backwards.html#backwards.third.streamattach"> No <code class="code">stream::attach(int fd)</code> </a></span></dt><dt><span class="section"><a href="backwards.html#backwards.third.support_cxx98"> diff --git a/libstdc++-v3/doc/html/manual/index.html b/libstdc++-v3/doc/html/manual/index.html index 0e4cb8c..1639c95 100644 --- a/libstdc++-v3/doc/html/manual/index.html +++ b/libstdc++-v3/doc/html/manual/index.html @@ -123,7 +123,7 @@ Existing tests </a></span></dt><dt><span class="section"><a href="test.html#test.exception.safety.containers"> C++11 Requirements Test Sequence Descriptions -</a></span></dt></dl></dd></dl></dd></dl></dd><dt><span class="section"><a href="abi.html">ABI Policy and Guidelines</a></span></dt><dd><dl><dt><span class="section"><a href="abi.html#abi.cxx_interface">The C++ Interface</a></span></dt><dt><span class="section"><a href="abi.html#abi.versioning">Versioning</a></span></dt><dd><dl><dt><span class="section"><a href="abi.html#abi.versioning.goals">Goals</a></span></dt><dt><span class="section"><a href="abi.html#abi.versioning.history">History</a></span></dt><dt><span class="section"><a href="abi.html#abi.versioning.prereq">Prerequisites</a></span></dt><dt><span class="section"><a href="abi.html#abi.versioning.config">Configuring</a></span></dt><dt><span class="section"><a href="abi.html#abi.versioning.active">Checking Active</a></span></dt></dl></dd><dt><span class="section"><a href="abi.html#abi.changes_allowed">Allowed Changes</a></span></dt><dt><span class="section"><a href="abi.html#abi.changes_no">Prohibited Changes</a></span></dt><dt><span class="section"><a href="abi.html#abi.impl">Implementation</a></span></dt><dt><span class="section"><a href="abi.html#abi.testing">Testing</a></span></dt><dd><dl><dt><span class="section"><a href="abi.html#abi.testing.single">Single ABI Testing</a></span></dt><dt><span class="section"><a href="abi.html#abi.testing.multi">Multiple ABI Testing</a></span></dt></dl></dd><dt><span class="section"><a href="abi.html#abi.issues">Outstanding Issues</a></span></dt></dl></dd><dt><span class="section"><a href="api.html">API Evolution and Deprecation History</a></span></dt><dd><dl><dt><span class="section"><a href="api.html#api.rel_300"><code class="constant">3.0</code></a></span></dt><dt><span class="section"><a href="api.html#api.rel_310"><code class="constant">3.1</code></a></span></dt><dt><span class="section"><a href="api.html#api.rel_320"><code class="constant">3.2</code></a></span></dt><dt><span class="section"><a href="api.html#api.rel_330"><code class="constant">3.3</code></a></span></dt><dt><span class="section"><a href="api.html#api.rel_340"><code class="constant">3.4</code></a></span></dt><dt><span class="section"><a href="api.html#api.rel_400"><code class="constant">4.0</code></a></span></dt><dt><span class="section"><a href="api.html#api.rel_410"><code class="constant">4.1</code></a></span></dt><dt><span class="section"><a href="api.html#api.rel_420"><code class="constant">4.2</code></a></span></dt><dt><span class="section"><a href="api.html#api.rel_430"><code class="constant">4.3</code></a></span></dt><dt><span class="section"><a href="api.html#api.rel_440"><code class="constant">4.4</code></a></span></dt><dt><span class="section"><a href="api.html#api.rel_450"><code class="constant">4.5</code></a></span></dt><dt><span class="section"><a href="api.html#api.rel_460"><code class="constant">4.6</code></a></span></dt><dt><span class="section"><a href="api.html#api.rel_470"><code class="constant">4.7</code></a></span></dt><dt><span class="section"><a href="api.html#api.rel_480"><code class="constant">4.8</code></a></span></dt><dt><span class="section"><a href="api.html#api.rel_490"><code class="constant">4.9</code></a></span></dt><dt><span class="section"><a href="api.html#api.rel_51"><code class="constant">5</code></a></span></dt><dd><dl><dt><span class="section"><a href="api.html#api.rel_53"><code class="constant">5.3</code></a></span></dt></dl></dd><dt><span class="section"><a href="api.html#api.rel_61"><code class="constant">6</code></a></span></dt><dt><span class="section"><a href="api.html#api.rel_71"><code class="constant">7</code></a></span></dt><dd><dl><dt><span class="section"><a href="api.html#api.rel_72"><code class="constant">7.2</code></a></span></dt><dt><span class="section"><a href="api.html#api.rel_73"><code class="constant">7.3</code></a></span></dt></dl></dd><dt><span class="section"><a href="api.html#api.rel_81"><code class="constant">8</code></a></span></dt><dt><span class="section"><a href="api.html#api.rel_91"><code class="constant">9</code></a></span></dt><dt><span class="section"><a href="api.html#api.rel_101"><code class="constant">10</code></a></span></dt><dt><span class="section"><a href="api.html#api.rel_111"><code class="constant">11</code></a></span></dt><dt><span class="section"><a href="api.html#api.rel_121"><code class="constant">12</code></a></span></dt><dt><span class="section"><a href="api.html#api.rel_123"><code class="constant">12.3</code></a></span></dt><dt><span class="section"><a href="api.html#api.rel_131"><code class="constant">13</code></a></span></dt><dt><span class="section"><a href="api.html#api.rel_141"><code class="constant">14</code></a></span></dt></dl></dd><dt><span class="section"><a href="backwards.html">Backwards Compatibility</a></span></dt><dd><dl><dt><span class="section"><a href="backwards.html#backwards.first">First</a></span></dt><dt><span class="section"><a href="backwards.html#backwards.second">Second</a></span></dt><dt><span class="section"><a href="backwards.html#backwards.third">Third</a></span></dt><dd><dl><dt><span class="section"><a href="backwards.html#backwards.third.headers">Pre-ISO headers removed</a></span></dt><dt><span class="section"><a href="backwards.html#backwards.third.hash">Extension headers hash_map, hash_set moved to ext or backwards</a></span></dt><dt><span class="section"><a href="backwards.html#backwards.third.nocreate_noreplace">No <code class="code">ios::nocreate/ios::noreplace</code>. +</a></span></dt></dl></dd></dl></dd></dl></dd><dt><span class="section"><a href="abi.html">ABI Policy and Guidelines</a></span></dt><dd><dl><dt><span class="section"><a href="abi.html#abi.cxx_interface">The C++ Interface</a></span></dt><dt><span class="section"><a href="abi.html#abi.versioning">Versioning</a></span></dt><dd><dl><dt><span class="section"><a href="abi.html#abi.versioning.goals">Goals</a></span></dt><dt><span class="section"><a href="abi.html#abi.versioning.history">History</a></span></dt><dt><span class="section"><a href="abi.html#abi.versioning.prereq">Prerequisites</a></span></dt><dt><span class="section"><a href="abi.html#abi.versioning.config">Configuring</a></span></dt><dt><span class="section"><a href="abi.html#abi.versioning.active">Checking Active</a></span></dt></dl></dd><dt><span class="section"><a href="abi.html#abi.changes_allowed">Allowed Changes</a></span></dt><dt><span class="section"><a href="abi.html#abi.changes_no">Prohibited Changes</a></span></dt><dt><span class="section"><a href="abi.html#abi.impl">Implementation</a></span></dt><dt><span class="section"><a href="abi.html#abi.testing">Testing</a></span></dt><dd><dl><dt><span class="section"><a href="abi.html#abi.testing.single">Single ABI Testing</a></span></dt><dt><span class="section"><a href="abi.html#abi.testing.multi">Multiple ABI Testing</a></span></dt></dl></dd><dt><span class="section"><a href="abi.html#abi.issues">Outstanding Issues</a></span></dt></dl></dd><dt><span class="section"><a href="api.html">API Evolution and Deprecation History</a></span></dt><dd><dl><dt><span class="section"><a href="api.html#api.rel_300"><code class="constant">3.0</code></a></span></dt><dt><span class="section"><a href="api.html#api.rel_310"><code class="constant">3.1</code></a></span></dt><dt><span class="section"><a href="api.html#api.rel_320"><code class="constant">3.2</code></a></span></dt><dt><span class="section"><a href="api.html#api.rel_330"><code class="constant">3.3</code></a></span></dt><dt><span class="section"><a href="api.html#api.rel_340"><code class="constant">3.4</code></a></span></dt><dt><span class="section"><a href="api.html#api.rel_400"><code class="constant">4.0</code></a></span></dt><dt><span class="section"><a href="api.html#api.rel_410"><code class="constant">4.1</code></a></span></dt><dt><span class="section"><a href="api.html#api.rel_420"><code class="constant">4.2</code></a></span></dt><dt><span class="section"><a href="api.html#api.rel_430"><code class="constant">4.3</code></a></span></dt><dt><span class="section"><a href="api.html#api.rel_440"><code class="constant">4.4</code></a></span></dt><dt><span class="section"><a href="api.html#api.rel_450"><code class="constant">4.5</code></a></span></dt><dt><span class="section"><a href="api.html#api.rel_460"><code class="constant">4.6</code></a></span></dt><dt><span class="section"><a href="api.html#api.rel_470"><code class="constant">4.7</code></a></span></dt><dt><span class="section"><a href="api.html#api.rel_480"><code class="constant">4.8</code></a></span></dt><dt><span class="section"><a href="api.html#api.rel_490"><code class="constant">4.9</code></a></span></dt><dt><span class="section"><a href="api.html#api.rel_51"><code class="constant">5</code></a></span></dt><dd><dl><dt><span class="section"><a href="api.html#api.rel_53"><code class="constant">5.3</code></a></span></dt></dl></dd><dt><span class="section"><a href="api.html#api.rel_61"><code class="constant">6</code></a></span></dt><dt><span class="section"><a href="api.html#api.rel_71"><code class="constant">7</code></a></span></dt><dd><dl><dt><span class="section"><a href="api.html#api.rel_72"><code class="constant">7.2</code></a></span></dt><dt><span class="section"><a href="api.html#api.rel_73"><code class="constant">7.3</code></a></span></dt></dl></dd><dt><span class="section"><a href="api.html#api.rel_81"><code class="constant">8</code></a></span></dt><dt><span class="section"><a href="api.html#api.rel_91"><code class="constant">9</code></a></span></dt><dt><span class="section"><a href="api.html#api.rel_101"><code class="constant">10</code></a></span></dt><dt><span class="section"><a href="api.html#api.rel_111"><code class="constant">11</code></a></span></dt><dt><span class="section"><a href="api.html#api.rel_121"><code class="constant">12</code></a></span></dt><dt><span class="section"><a href="api.html#api.rel_123"><code class="constant">12.3</code></a></span></dt><dt><span class="section"><a href="api.html#api.rel_131"><code class="constant">13</code></a></span></dt><dt><span class="section"><a href="api.html#api.rel_133"><code class="constant">13.3</code></a></span></dt><dt><span class="section"><a href="api.html#api.rel_141"><code class="constant">14</code></a></span></dt></dl></dd><dt><span class="section"><a href="backwards.html">Backwards Compatibility</a></span></dt><dd><dl><dt><span class="section"><a href="backwards.html#backwards.first">First</a></span></dt><dt><span class="section"><a href="backwards.html#backwards.second">Second</a></span></dt><dt><span class="section"><a href="backwards.html#backwards.third">Third</a></span></dt><dd><dl><dt><span class="section"><a href="backwards.html#backwards.third.headers">Pre-ISO headers removed</a></span></dt><dt><span class="section"><a href="backwards.html#backwards.third.hash">Extension headers hash_map, hash_set moved to ext or backwards</a></span></dt><dt><span class="section"><a href="backwards.html#backwards.third.nocreate_noreplace">No <code class="code">ios::nocreate/ios::noreplace</code>. </a></span></dt><dt><span class="section"><a href="backwards.html#backwards.third.streamattach"> No <code class="code">stream::attach(int fd)</code> </a></span></dt><dt><span class="section"><a href="backwards.html#backwards.third.support_cxx98"> diff --git a/libstdc++-v3/doc/xml/manual/evolution.xml b/libstdc++-v3/doc/xml/manual/evolution.xml index db70f24..a375ae1 100644 --- a/libstdc++-v3/doc/xml/manual/evolution.xml +++ b/libstdc++-v3/doc/xml/manual/evolution.xml @@ -1100,6 +1100,18 @@ Tunables <variable>glibcxx.eh_pool.obj_count</variable> and <variable>glibcxx.eh_pool.obj_size</variable> were added. </para> +<para>Static library <filename>libstdc++exp.a</filename> was added +to provide the symbols for the experimental C++ Contracts support.</para> + +</section> + +<section xml:id="api.rel_133"><info><title><constant>13.3</constant></title></info> + +<para> +Symbols for the Filesystem TS and C++23 <filename><stacktrace></filename> +header were added to the static library <filename>libstdc++exp.a</filename>. +</para> + </section> <section xml:id="api.rel_141"><info><title><constant>14</constant></title></info> diff --git a/libstdc++-v3/include/bits/move.h b/libstdc++-v3/include/bits/move.h index 4e741bc..bb200c9 100644 --- a/libstdc++-v3/include/bits/move.h +++ b/libstdc++-v3/include/bits/move.h @@ -110,6 +110,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION return static_cast<_Up&>(__x); } } + + template<typename _Tp, typename _Up> + using __like_t = decltype(std::forward_like<_Tp>(std::declval<_Up>())); #endif /** diff --git a/libstdc++-v3/include/bits/random.tcc b/libstdc++-v3/include/bits/random.tcc index 7f4bf5e..ade4163 100644 --- a/libstdc++-v3/include/bits/random.tcc +++ b/libstdc++-v3/include/bits/random.tcc @@ -541,8 +541,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION subtract_with_carry_engine<_UIntType, __w, __s, __r>:: seed(result_type __value) { + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 3809. Is std::subtract_with_carry_engine<uint16_t> supposed to work? + // 4014. LWG 3809 changes behavior of some existing code std::linear_congruential_engine<uint_least32_t, 40014u, 0u, 2147483563u> - __lcg(__value == 0u ? default_seed : __value); + __lcg(__value == 0u ? default_seed : __value % 2147483563u); const size_t __n = (__w + 31) / 32; diff --git a/libstdc++-v3/include/bits/stl_iterator.h b/libstdc++-v3/include/bits/stl_iterator.h index 6434ef6..d71a793 100644 --- a/libstdc++-v3/include/bits/stl_iterator.h +++ b/libstdc++-v3/include/bits/stl_iterator.h @@ -2775,6 +2775,18 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION noexcept(noexcept(_M_current == __s)) { return _M_current == __s; } + template<__detail::__not_a_const_iterator _CIt> + requires __detail::__constant_iterator<_CIt> && convertible_to<_It, _CIt> + constexpr + operator _CIt() const& + { return _M_current; } + + template<__detail::__not_a_const_iterator _CIt> + requires __detail::__constant_iterator<_CIt> && convertible_to<_It, _CIt> + constexpr + operator _CIt() && + { return std::move(_M_current); } + constexpr bool operator<(const basic_const_iterator& __y) const noexcept(noexcept(_M_current < __y._M_current)) diff --git a/libstdc++-v3/include/bits/stl_pair.h b/libstdc++-v3/include/bits/stl_pair.h index ce8826a..52f532f 100644 --- a/libstdc++-v3/include/bits/stl_pair.h +++ b/libstdc++-v3/include/bits/stl_pair.h @@ -308,7 +308,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION { } /// Constructor accepting two values of arbitrary types +#if __cplusplus > 202002L + template<typename _U1 = _T1, typename _U2 = _T2> +#else template<typename _U1, typename _U2> +#endif requires (_S_constructible<_U1, _U2>()) && (!_S_dangles<_U1, _U2>()) constexpr explicit(!_S_convertible<_U1, _U2>()) pair(_U1&& __x, _U2&& __y) @@ -316,7 +320,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION : first(std::forward<_U1>(__x)), second(std::forward<_U2>(__y)) { } +#if __cplusplus > 202002L + template<typename _U1 = _T1, typename _U2 = _T2> +#else template<typename _U1, typename _U2> +#endif requires (_S_constructible<_U1, _U2>()) && (_S_dangles<_U1, _U2>()) constexpr explicit(!_S_convertible<_U1, _U2>()) pair(_U1&&, _U2&&) = delete; diff --git a/libstdc++-v3/include/bits/unicode-data.h b/libstdc++-v3/include/bits/unicode-data.h index c0c7e7d..8396809 100644 --- a/libstdc++-v3/include/bits/unicode-data.h +++ b/libstdc++-v3/include/bits/unicode-data.h @@ -37,20 +37,20 @@ }; enum class _Gcb_property { - _Gcb_CR = 1, - _Gcb_Control = 2, - _Gcb_Extend = 3, - _Gcb_L = 4, - _Gcb_LF = 5, - _Gcb_LV = 6, - _Gcb_LVT = 7, - _Gcb_Other = 8, - _Gcb_Prepend = 9, - _Gcb_Regional_Indicator = 10, - _Gcb_SpacingMark = 11, - _Gcb_T = 12, - _Gcb_V = 13, - _Gcb_ZWJ = 14, + _Gcb_Other = 0, + _Gcb_Control = 1, + _Gcb_LF = 2, + _Gcb_CR = 3, + _Gcb_Extend = 4, + _Gcb_Prepend = 5, + _Gcb_SpacingMark = 6, + _Gcb_L = 7, + _Gcb_V = 8, + _Gcb_T = 9, + _Gcb_ZWJ = 10, + _Gcb_LV = 11, + _Gcb_LVT = 12, + _Gcb_Regional_Indicator = 13, }; // Values generated by contrib/unicode/gen_std_format_width.py, @@ -58,290 +58,290 @@ // Entries are (code_point << shift_bits) + property. inline constexpr int __gcb_shift_bits = 0x4; inline constexpr uint32_t __gcb_edges[] = { - 0x2, 0xa5, 0xb2, 0xd1, 0xe2, 0x208, - 0x7f2, 0xa08, 0xad2, 0xae8, 0x3003, 0x3708, - 0x4833, 0x48a8, 0x5913, 0x5be8, 0x5bf3, 0x5c08, - 0x5c13, 0x5c38, 0x5c43, 0x5c68, 0x5c73, 0x5c88, - 0x6009, 0x6068, 0x6103, 0x61b8, 0x61c2, 0x61d8, - 0x64b3, 0x6608, 0x6703, 0x6718, 0x6d63, 0x6dd9, - 0x6de8, 0x6df3, 0x6e58, 0x6e73, 0x6e98, 0x6ea3, - 0x6ee8, 0x70f9, 0x7108, 0x7113, 0x7128, 0x7303, - 0x74b8, 0x7a63, 0x7b18, 0x7eb3, 0x7f48, 0x7fd3, - 0x7fe8, 0x8163, 0x81a8, 0x81b3, 0x8248, 0x8253, - 0x8288, 0x8293, 0x82e8, 0x8593, 0x85c8, 0x8909, - 0x8928, 0x8983, 0x8a08, 0x8ca3, 0x8e29, 0x8e33, - 0x903b, 0x9048, 0x93a3, 0x93bb, 0x93c3, 0x93d8, - 0x93eb, 0x9413, 0x949b, 0x94d3, 0x94eb, 0x9508, - 0x9513, 0x9588, 0x9623, 0x9648, 0x9813, 0x982b, - 0x9848, 0x9bc3, 0x9bd8, 0x9be3, 0x9bfb, 0x9c13, - 0x9c58, 0x9c7b, 0x9c98, 0x9cbb, 0x9cd3, 0x9ce8, - 0x9d73, 0x9d88, 0x9e23, 0x9e48, 0x9fe3, 0x9ff8, - 0xa013, 0xa03b, 0xa048, 0xa3c3, 0xa3d8, 0xa3eb, - 0xa413, 0xa438, 0xa473, 0xa498, 0xa4b3, 0xa4e8, - 0xa513, 0xa528, 0xa703, 0xa728, 0xa753, 0xa768, - 0xa813, 0xa83b, 0xa848, 0xabc3, 0xabd8, 0xabeb, - 0xac13, 0xac68, 0xac73, 0xac9b, 0xaca8, 0xacbb, - 0xacd3, 0xace8, 0xae23, 0xae48, 0xafa3, 0xb008, - 0xb013, 0xb02b, 0xb048, 0xb3c3, 0xb3d8, 0xb3e3, - 0xb40b, 0xb413, 0xb458, 0xb47b, 0xb498, 0xb4bb, - 0xb4d3, 0xb4e8, 0xb553, 0xb588, 0xb623, 0xb648, - 0xb823, 0xb838, 0xbbe3, 0xbbfb, 0xbc03, 0xbc1b, - 0xbc38, 0xbc6b, 0xbc98, 0xbcab, 0xbcd3, 0xbce8, - 0xbd73, 0xbd88, 0xc003, 0xc01b, 0xc043, 0xc058, - 0xc3c3, 0xc3d8, 0xc3e3, 0xc41b, 0xc458, 0xc463, - 0xc498, 0xc4a3, 0xc4e8, 0xc553, 0xc578, 0xc623, - 0xc648, 0xc813, 0xc82b, 0xc848, 0xcbc3, 0xcbd8, - 0xcbeb, 0xcbf3, 0xcc0b, 0xcc23, 0xcc3b, 0xcc58, - 0xcc63, 0xcc7b, 0xcc98, 0xccab, 0xccc3, 0xcce8, - 0xcd53, 0xcd78, 0xce23, 0xce48, 0xcf3b, 0xcf48, - 0xd003, 0xd02b, 0xd048, 0xd3b3, 0xd3d8, 0xd3e3, - 0xd3fb, 0xd413, 0xd458, 0xd46b, 0xd498, 0xd4ab, - 0xd4d3, 0xd4e9, 0xd4f8, 0xd573, 0xd588, 0xd623, - 0xd648, 0xd813, 0xd82b, 0xd848, 0xdca3, 0xdcb8, - 0xdcf3, 0xdd0b, 0xdd23, 0xdd58, 0xdd63, 0xdd78, - 0xdd8b, 0xddf3, 0xde08, 0xdf2b, 0xdf48, 0xe313, - 0xe328, 0xe33b, 0xe343, 0xe3b8, 0xe473, 0xe4f8, - 0xeb13, 0xeb28, 0xeb3b, 0xeb43, 0xebd8, 0xec83, - 0xecf8, 0xf183, 0xf1a8, 0xf353, 0xf368, 0xf373, - 0xf388, 0xf393, 0xf3a8, 0xf3eb, 0xf408, 0xf713, - 0xf7fb, 0xf803, 0xf858, 0xf863, 0xf888, 0xf8d3, - 0xf988, 0xf993, 0xfbd8, 0xfc63, 0xfc78, 0x102d3, - 0x1031b, 0x10323, 0x10388, 0x10393, 0x103bb, 0x103d3, - 0x103f8, 0x1056b, 0x10583, 0x105a8, 0x105e3, 0x10618, - 0x10713, 0x10758, 0x10823, 0x10838, 0x1084b, 0x10853, - 0x10878, 0x108d3, 0x108e8, 0x109d3, 0x109e8, 0x11004, - 0x1160d, 0x11a8c, 0x12008, 0x135d3, 0x13608, 0x17123, - 0x1715b, 0x17168, 0x17323, 0x1734b, 0x17358, 0x17523, - 0x17548, 0x17723, 0x17748, 0x17b43, 0x17b6b, 0x17b73, - 0x17beb, 0x17c63, 0x17c7b, 0x17c93, 0x17d48, 0x17dd3, - 0x17de8, 0x180b3, 0x180e2, 0x180f3, 0x18108, 0x18853, - 0x18878, 0x18a93, 0x18aa8, 0x19203, 0x1923b, 0x19273, - 0x1929b, 0x192c8, 0x1930b, 0x19323, 0x1933b, 0x19393, - 0x193c8, 0x1a173, 0x1a19b, 0x1a1b3, 0x1a1c8, 0x1a55b, - 0x1a563, 0x1a57b, 0x1a583, 0x1a5f8, 0x1a603, 0x1a618, - 0x1a623, 0x1a638, 0x1a653, 0x1a6db, 0x1a733, 0x1a7d8, - 0x1a7f3, 0x1a808, 0x1ab03, 0x1acf8, 0x1b003, 0x1b04b, - 0x1b058, 0x1b343, 0x1b3bb, 0x1b3c3, 0x1b3db, 0x1b423, - 0x1b43b, 0x1b458, 0x1b6b3, 0x1b748, 0x1b803, 0x1b82b, - 0x1b838, 0x1ba1b, 0x1ba23, 0x1ba6b, 0x1ba83, 0x1baab, - 0x1bab3, 0x1bae8, 0x1be63, 0x1be7b, 0x1be83, 0x1beab, - 0x1bed3, 0x1beeb, 0x1bef3, 0x1bf2b, 0x1bf48, 0x1c24b, - 0x1c2c3, 0x1c34b, 0x1c363, 0x1c388, 0x1cd03, 0x1cd38, - 0x1cd43, 0x1ce1b, 0x1ce23, 0x1ce98, 0x1ced3, 0x1cee8, - 0x1cf43, 0x1cf58, 0x1cf7b, 0x1cf83, 0x1cfa8, 0x1dc03, - 0x1e008, 0x200b2, 0x200c3, 0x200de, 0x200e2, 0x20108, - 0x20282, 0x202f8, 0x20602, 0x20708, 0x20d03, 0x20f18, - 0x2cef3, 0x2cf28, 0x2d7f3, 0x2d808, 0x2de03, 0x2e008, - 0x302a3, 0x30308, 0x30993, 0x309b8, 0xa66f3, 0xa6738, - 0xa6743, 0xa67e8, 0xa69e3, 0xa6a08, 0xa6f03, 0xa6f28, - 0xa8023, 0xa8038, 0xa8063, 0xa8078, 0xa80b3, 0xa80c8, - 0xa823b, 0xa8253, 0xa827b, 0xa8288, 0xa82c3, 0xa82d8, - 0xa880b, 0xa8828, 0xa8b4b, 0xa8c43, 0xa8c68, 0xa8e03, - 0xa8f28, 0xa8ff3, 0xa9008, 0xa9263, 0xa92e8, 0xa9473, - 0xa952b, 0xa9548, 0xa9604, 0xa97d8, 0xa9803, 0xa983b, - 0xa9848, 0xa9b33, 0xa9b4b, 0xa9b63, 0xa9bab, 0xa9bc3, - 0xa9beb, 0xa9c18, 0xa9e53, 0xa9e68, 0xaa293, 0xaa2fb, - 0xaa313, 0xaa33b, 0xaa353, 0xaa378, 0xaa433, 0xaa448, - 0xaa4c3, 0xaa4db, 0xaa4e8, 0xaa7c3, 0xaa7d8, 0xaab03, - 0xaab18, 0xaab23, 0xaab58, 0xaab73, 0xaab98, 0xaabe3, - 0xaac08, 0xaac13, 0xaac28, 0xaaebb, 0xaaec3, 0xaaeeb, - 0xaaf08, 0xaaf5b, 0xaaf63, 0xaaf78, 0xabe3b, 0xabe53, - 0xabe6b, 0xabe83, 0xabe9b, 0xabeb8, 0xabecb, 0xabed3, - 0xabee8, 0xac006, 0xac017, 0xac1c6, 0xac1d7, 0xac386, - 0xac397, 0xac546, 0xac557, 0xac706, 0xac717, 0xac8c6, - 0xac8d7, 0xaca86, 0xaca97, 0xacc46, 0xacc57, 0xace06, - 0xace17, 0xacfc6, 0xacfd7, 0xad186, 0xad197, 0xad346, - 0xad357, 0xad506, 0xad517, 0xad6c6, 0xad6d7, 0xad886, - 0xad897, 0xada46, 0xada57, 0xadc06, 0xadc17, 0xaddc6, - 0xaddd7, 0xadf86, 0xadf97, 0xae146, 0xae157, 0xae306, - 0xae317, 0xae4c6, 0xae4d7, 0xae686, 0xae697, 0xae846, - 0xae857, 0xaea06, 0xaea17, 0xaebc6, 0xaebd7, 0xaed86, - 0xaed97, 0xaef46, 0xaef57, 0xaf106, 0xaf117, 0xaf2c6, - 0xaf2d7, 0xaf486, 0xaf497, 0xaf646, 0xaf657, 0xaf806, - 0xaf817, 0xaf9c6, 0xaf9d7, 0xafb86, 0xafb97, 0xafd46, - 0xafd57, 0xaff06, 0xaff17, 0xb00c6, 0xb00d7, 0xb0286, - 0xb0297, 0xb0446, 0xb0457, 0xb0606, 0xb0617, 0xb07c6, - 0xb07d7, 0xb0986, 0xb0997, 0xb0b46, 0xb0b57, 0xb0d06, - 0xb0d17, 0xb0ec6, 0xb0ed7, 0xb1086, 0xb1097, 0xb1246, - 0xb1257, 0xb1406, 0xb1417, 0xb15c6, 0xb15d7, 0xb1786, - 0xb1797, 0xb1946, 0xb1957, 0xb1b06, 0xb1b17, 0xb1cc6, - 0xb1cd7, 0xb1e86, 0xb1e97, 0xb2046, 0xb2057, 0xb2206, - 0xb2217, 0xb23c6, 0xb23d7, 0xb2586, 0xb2597, 0xb2746, - 0xb2757, 0xb2906, 0xb2917, 0xb2ac6, 0xb2ad7, 0xb2c86, - 0xb2c97, 0xb2e46, 0xb2e57, 0xb3006, 0xb3017, 0xb31c6, - 0xb31d7, 0xb3386, 0xb3397, 0xb3546, 0xb3557, 0xb3706, - 0xb3717, 0xb38c6, 0xb38d7, 0xb3a86, 0xb3a97, 0xb3c46, - 0xb3c57, 0xb3e06, 0xb3e17, 0xb3fc6, 0xb3fd7, 0xb4186, - 0xb4197, 0xb4346, 0xb4357, 0xb4506, 0xb4517, 0xb46c6, - 0xb46d7, 0xb4886, 0xb4897, 0xb4a46, 0xb4a57, 0xb4c06, - 0xb4c17, 0xb4dc6, 0xb4dd7, 0xb4f86, 0xb4f97, 0xb5146, - 0xb5157, 0xb5306, 0xb5317, 0xb54c6, 0xb54d7, 0xb5686, - 0xb5697, 0xb5846, 0xb5857, 0xb5a06, 0xb5a17, 0xb5bc6, - 0xb5bd7, 0xb5d86, 0xb5d97, 0xb5f46, 0xb5f57, 0xb6106, - 0xb6117, 0xb62c6, 0xb62d7, 0xb6486, 0xb6497, 0xb6646, - 0xb6657, 0xb6806, 0xb6817, 0xb69c6, 0xb69d7, 0xb6b86, - 0xb6b97, 0xb6d46, 0xb6d57, 0xb6f06, 0xb6f17, 0xb70c6, - 0xb70d7, 0xb7286, 0xb7297, 0xb7446, 0xb7457, 0xb7606, - 0xb7617, 0xb77c6, 0xb77d7, 0xb7986, 0xb7997, 0xb7b46, - 0xb7b57, 0xb7d06, 0xb7d17, 0xb7ec6, 0xb7ed7, 0xb8086, - 0xb8097, 0xb8246, 0xb8257, 0xb8406, 0xb8417, 0xb85c6, - 0xb85d7, 0xb8786, 0xb8797, 0xb8946, 0xb8957, 0xb8b06, - 0xb8b17, 0xb8cc6, 0xb8cd7, 0xb8e86, 0xb8e97, 0xb9046, - 0xb9057, 0xb9206, 0xb9217, 0xb93c6, 0xb93d7, 0xb9586, - 0xb9597, 0xb9746, 0xb9757, 0xb9906, 0xb9917, 0xb9ac6, - 0xb9ad7, 0xb9c86, 0xb9c97, 0xb9e46, 0xb9e57, 0xba006, - 0xba017, 0xba1c6, 0xba1d7, 0xba386, 0xba397, 0xba546, - 0xba557, 0xba706, 0xba717, 0xba8c6, 0xba8d7, 0xbaa86, - 0xbaa97, 0xbac46, 0xbac57, 0xbae06, 0xbae17, 0xbafc6, - 0xbafd7, 0xbb186, 0xbb197, 0xbb346, 0xbb357, 0xbb506, - 0xbb517, 0xbb6c6, 0xbb6d7, 0xbb886, 0xbb897, 0xbba46, - 0xbba57, 0xbbc06, 0xbbc17, 0xbbdc6, 0xbbdd7, 0xbbf86, - 0xbbf97, 0xbc146, 0xbc157, 0xbc306, 0xbc317, 0xbc4c6, - 0xbc4d7, 0xbc686, 0xbc697, 0xbc846, 0xbc857, 0xbca06, - 0xbca17, 0xbcbc6, 0xbcbd7, 0xbcd86, 0xbcd97, 0xbcf46, - 0xbcf57, 0xbd106, 0xbd117, 0xbd2c6, 0xbd2d7, 0xbd486, - 0xbd497, 0xbd646, 0xbd657, 0xbd806, 0xbd817, 0xbd9c6, - 0xbd9d7, 0xbdb86, 0xbdb97, 0xbdd46, 0xbdd57, 0xbdf06, - 0xbdf17, 0xbe0c6, 0xbe0d7, 0xbe286, 0xbe297, 0xbe446, - 0xbe457, 0xbe606, 0xbe617, 0xbe7c6, 0xbe7d7, 0xbe986, - 0xbe997, 0xbeb46, 0xbeb57, 0xbed06, 0xbed17, 0xbeec6, - 0xbeed7, 0xbf086, 0xbf097, 0xbf246, 0xbf257, 0xbf406, - 0xbf417, 0xbf5c6, 0xbf5d7, 0xbf786, 0xbf797, 0xbf946, - 0xbf957, 0xbfb06, 0xbfb17, 0xbfcc6, 0xbfcd7, 0xbfe86, - 0xbfe97, 0xc0046, 0xc0057, 0xc0206, 0xc0217, 0xc03c6, - 0xc03d7, 0xc0586, 0xc0597, 0xc0746, 0xc0757, 0xc0906, - 0xc0917, 0xc0ac6, 0xc0ad7, 0xc0c86, 0xc0c97, 0xc0e46, - 0xc0e57, 0xc1006, 0xc1017, 0xc11c6, 0xc11d7, 0xc1386, - 0xc1397, 0xc1546, 0xc1557, 0xc1706, 0xc1717, 0xc18c6, - 0xc18d7, 0xc1a86, 0xc1a97, 0xc1c46, 0xc1c57, 0xc1e06, - 0xc1e17, 0xc1fc6, 0xc1fd7, 0xc2186, 0xc2197, 0xc2346, - 0xc2357, 0xc2506, 0xc2517, 0xc26c6, 0xc26d7, 0xc2886, - 0xc2897, 0xc2a46, 0xc2a57, 0xc2c06, 0xc2c17, 0xc2dc6, - 0xc2dd7, 0xc2f86, 0xc2f97, 0xc3146, 0xc3157, 0xc3306, - 0xc3317, 0xc34c6, 0xc34d7, 0xc3686, 0xc3697, 0xc3846, - 0xc3857, 0xc3a06, 0xc3a17, 0xc3bc6, 0xc3bd7, 0xc3d86, - 0xc3d97, 0xc3f46, 0xc3f57, 0xc4106, 0xc4117, 0xc42c6, - 0xc42d7, 0xc4486, 0xc4497, 0xc4646, 0xc4657, 0xc4806, - 0xc4817, 0xc49c6, 0xc49d7, 0xc4b86, 0xc4b97, 0xc4d46, - 0xc4d57, 0xc4f06, 0xc4f17, 0xc50c6, 0xc50d7, 0xc5286, - 0xc5297, 0xc5446, 0xc5457, 0xc5606, 0xc5617, 0xc57c6, - 0xc57d7, 0xc5986, 0xc5997, 0xc5b46, 0xc5b57, 0xc5d06, - 0xc5d17, 0xc5ec6, 0xc5ed7, 0xc6086, 0xc6097, 0xc6246, - 0xc6257, 0xc6406, 0xc6417, 0xc65c6, 0xc65d7, 0xc6786, - 0xc6797, 0xc6946, 0xc6957, 0xc6b06, 0xc6b17, 0xc6cc6, - 0xc6cd7, 0xc6e86, 0xc6e97, 0xc7046, 0xc7057, 0xc7206, - 0xc7217, 0xc73c6, 0xc73d7, 0xc7586, 0xc7597, 0xc7746, - 0xc7757, 0xc7906, 0xc7917, 0xc7ac6, 0xc7ad7, 0xc7c86, - 0xc7c97, 0xc7e46, 0xc7e57, 0xc8006, 0xc8017, 0xc81c6, - 0xc81d7, 0xc8386, 0xc8397, 0xc8546, 0xc8557, 0xc8706, - 0xc8717, 0xc88c6, 0xc88d7, 0xc8a86, 0xc8a97, 0xc8c46, - 0xc8c57, 0xc8e06, 0xc8e17, 0xc8fc6, 0xc8fd7, 0xc9186, - 0xc9197, 0xc9346, 0xc9357, 0xc9506, 0xc9517, 0xc96c6, - 0xc96d7, 0xc9886, 0xc9897, 0xc9a46, 0xc9a57, 0xc9c06, - 0xc9c17, 0xc9dc6, 0xc9dd7, 0xc9f86, 0xc9f97, 0xca146, - 0xca157, 0xca306, 0xca317, 0xca4c6, 0xca4d7, 0xca686, - 0xca697, 0xca846, 0xca857, 0xcaa06, 0xcaa17, 0xcabc6, - 0xcabd7, 0xcad86, 0xcad97, 0xcaf46, 0xcaf57, 0xcb106, - 0xcb117, 0xcb2c6, 0xcb2d7, 0xcb486, 0xcb497, 0xcb646, - 0xcb657, 0xcb806, 0xcb817, 0xcb9c6, 0xcb9d7, 0xcbb86, - 0xcbb97, 0xcbd46, 0xcbd57, 0xcbf06, 0xcbf17, 0xcc0c6, - 0xcc0d7, 0xcc286, 0xcc297, 0xcc446, 0xcc457, 0xcc606, - 0xcc617, 0xcc7c6, 0xcc7d7, 0xcc986, 0xcc997, 0xccb46, - 0xccb57, 0xccd06, 0xccd17, 0xccec6, 0xcced7, 0xcd086, - 0xcd097, 0xcd246, 0xcd257, 0xcd406, 0xcd417, 0xcd5c6, - 0xcd5d7, 0xcd786, 0xcd797, 0xcd946, 0xcd957, 0xcdb06, - 0xcdb17, 0xcdcc6, 0xcdcd7, 0xcde86, 0xcde97, 0xce046, - 0xce057, 0xce206, 0xce217, 0xce3c6, 0xce3d7, 0xce586, - 0xce597, 0xce746, 0xce757, 0xce906, 0xce917, 0xceac6, - 0xcead7, 0xcec86, 0xcec97, 0xcee46, 0xcee57, 0xcf006, - 0xcf017, 0xcf1c6, 0xcf1d7, 0xcf386, 0xcf397, 0xcf546, - 0xcf557, 0xcf706, 0xcf717, 0xcf8c6, 0xcf8d7, 0xcfa86, - 0xcfa97, 0xcfc46, 0xcfc57, 0xcfe06, 0xcfe17, 0xcffc6, - 0xcffd7, 0xd0186, 0xd0197, 0xd0346, 0xd0357, 0xd0506, - 0xd0517, 0xd06c6, 0xd06d7, 0xd0886, 0xd0897, 0xd0a46, - 0xd0a57, 0xd0c06, 0xd0c17, 0xd0dc6, 0xd0dd7, 0xd0f86, - 0xd0f97, 0xd1146, 0xd1157, 0xd1306, 0xd1317, 0xd14c6, - 0xd14d7, 0xd1686, 0xd1697, 0xd1846, 0xd1857, 0xd1a06, - 0xd1a17, 0xd1bc6, 0xd1bd7, 0xd1d86, 0xd1d97, 0xd1f46, - 0xd1f57, 0xd2106, 0xd2117, 0xd22c6, 0xd22d7, 0xd2486, - 0xd2497, 0xd2646, 0xd2657, 0xd2806, 0xd2817, 0xd29c6, - 0xd29d7, 0xd2b86, 0xd2b97, 0xd2d46, 0xd2d57, 0xd2f06, - 0xd2f17, 0xd30c6, 0xd30d7, 0xd3286, 0xd3297, 0xd3446, - 0xd3457, 0xd3606, 0xd3617, 0xd37c6, 0xd37d7, 0xd3986, - 0xd3997, 0xd3b46, 0xd3b57, 0xd3d06, 0xd3d17, 0xd3ec6, - 0xd3ed7, 0xd4086, 0xd4097, 0xd4246, 0xd4257, 0xd4406, - 0xd4417, 0xd45c6, 0xd45d7, 0xd4786, 0xd4797, 0xd4946, - 0xd4957, 0xd4b06, 0xd4b17, 0xd4cc6, 0xd4cd7, 0xd4e86, - 0xd4e97, 0xd5046, 0xd5057, 0xd5206, 0xd5217, 0xd53c6, - 0xd53d7, 0xd5586, 0xd5597, 0xd5746, 0xd5757, 0xd5906, - 0xd5917, 0xd5ac6, 0xd5ad7, 0xd5c86, 0xd5c97, 0xd5e46, - 0xd5e57, 0xd6006, 0xd6017, 0xd61c6, 0xd61d7, 0xd6386, - 0xd6397, 0xd6546, 0xd6557, 0xd6706, 0xd6717, 0xd68c6, - 0xd68d7, 0xd6a86, 0xd6a97, 0xd6c46, 0xd6c57, 0xd6e06, - 0xd6e17, 0xd6fc6, 0xd6fd7, 0xd7186, 0xd7197, 0xd7346, - 0xd7357, 0xd7506, 0xd7517, 0xd76c6, 0xd76d7, 0xd7886, - 0xd7897, 0xd7a48, 0xd7b0d, 0xd7c78, 0xd7cbc, 0xd7fc8, - 0xfb1e3, 0xfb1f8, 0xfe003, 0xfe108, 0xfe203, 0xfe308, - 0xfeff2, 0xff008, 0xff9e3, 0xffa08, 0xfff02, 0xfffc8, - 0x101fd3, 0x101fe8, 0x102e03, 0x102e18, 0x103763, 0x1037b8, - 0x10a013, 0x10a048, 0x10a053, 0x10a078, 0x10a0c3, 0x10a108, - 0x10a383, 0x10a3b8, 0x10a3f3, 0x10a408, 0x10ae53, 0x10ae78, - 0x10d243, 0x10d288, 0x10eab3, 0x10ead8, 0x10efd3, 0x10f008, - 0x10f463, 0x10f518, 0x10f823, 0x10f868, 0x11000b, 0x110013, - 0x11002b, 0x110038, 0x110383, 0x110478, 0x110703, 0x110718, - 0x110733, 0x110758, 0x1107f3, 0x11082b, 0x110838, 0x110b0b, - 0x110b33, 0x110b7b, 0x110b93, 0x110bb8, 0x110bd9, 0x110be8, - 0x110c23, 0x110c38, 0x110cd9, 0x110ce8, 0x111003, 0x111038, - 0x111273, 0x1112cb, 0x1112d3, 0x111358, 0x11145b, 0x111478, - 0x111733, 0x111748, 0x111803, 0x11182b, 0x111838, 0x111b3b, - 0x111b63, 0x111bfb, 0x111c18, 0x111c29, 0x111c48, 0x111c93, - 0x111cd8, 0x111ceb, 0x111cf3, 0x111d08, 0x1122cb, 0x1122f3, - 0x11232b, 0x112343, 0x11235b, 0x112363, 0x112388, 0x1123e3, - 0x1123f8, 0x112413, 0x112428, 0x112df3, 0x112e0b, 0x112e33, - 0x112eb8, 0x113003, 0x11302b, 0x113048, 0x1133b3, 0x1133d8, - 0x1133e3, 0x1133fb, 0x113403, 0x11341b, 0x113458, 0x11347b, - 0x113498, 0x1134bb, 0x1134e8, 0x113573, 0x113588, 0x11362b, - 0x113648, 0x113663, 0x1136d8, 0x113703, 0x113758, 0x11435b, - 0x114383, 0x11440b, 0x114423, 0x11445b, 0x114463, 0x114478, - 0x1145e3, 0x1145f8, 0x114b03, 0x114b1b, 0x114b33, 0x114b9b, - 0x114ba3, 0x114bbb, 0x114bd3, 0x114beb, 0x114bf3, 0x114c1b, - 0x114c23, 0x114c48, 0x115af3, 0x115b0b, 0x115b23, 0x115b68, - 0x115b8b, 0x115bc3, 0x115beb, 0x115bf3, 0x115c18, 0x115dc3, - 0x115de8, 0x11630b, 0x116333, 0x1163bb, 0x1163d3, 0x1163eb, - 0x1163f3, 0x116418, 0x116ab3, 0x116acb, 0x116ad3, 0x116aeb, - 0x116b03, 0x116b6b, 0x116b73, 0x116b88, 0x1171d3, 0x117208, - 0x117223, 0x11726b, 0x117273, 0x1172c8, 0x1182cb, 0x1182f3, - 0x11838b, 0x118393, 0x1183b8, 0x119303, 0x11931b, 0x119368, - 0x11937b, 0x119398, 0x1193b3, 0x1193db, 0x1193e3, 0x1193f9, - 0x11940b, 0x119419, 0x11942b, 0x119433, 0x119448, 0x119d1b, - 0x119d43, 0x119d88, 0x119da3, 0x119dcb, 0x119e03, 0x119e18, - 0x119e4b, 0x119e58, 0x11a013, 0x11a0b8, 0x11a333, 0x11a39b, - 0x11a3a9, 0x11a3b3, 0x11a3f8, 0x11a473, 0x11a488, 0x11a513, - 0x11a57b, 0x11a593, 0x11a5c8, 0x11a849, 0x11a8a3, 0x11a97b, - 0x11a983, 0x11a9a8, 0x11c2fb, 0x11c303, 0x11c378, 0x11c383, - 0x11c3eb, 0x11c3f3, 0x11c408, 0x11c923, 0x11ca88, 0x11ca9b, - 0x11caa3, 0x11cb1b, 0x11cb23, 0x11cb4b, 0x11cb53, 0x11cb78, - 0x11d313, 0x11d378, 0x11d3a3, 0x11d3b8, 0x11d3c3, 0x11d3e8, - 0x11d3f3, 0x11d469, 0x11d473, 0x11d488, 0x11d8ab, 0x11d8f8, - 0x11d903, 0x11d928, 0x11d93b, 0x11d953, 0x11d96b, 0x11d973, - 0x11d988, 0x11ef33, 0x11ef5b, 0x11ef78, 0x11f003, 0x11f029, - 0x11f03b, 0x11f048, 0x11f34b, 0x11f363, 0x11f3b8, 0x11f3eb, - 0x11f403, 0x11f41b, 0x11f423, 0x11f438, 0x134302, 0x134403, - 0x134418, 0x134473, 0x134568, 0x16af03, 0x16af58, 0x16b303, - 0x16b378, 0x16f4f3, 0x16f508, 0x16f51b, 0x16f888, 0x16f8f3, - 0x16f938, 0x16fe43, 0x16fe58, 0x16ff0b, 0x16ff28, 0x1bc9d3, - 0x1bc9f8, 0x1bca02, 0x1bca48, 0x1cf003, 0x1cf2e8, 0x1cf303, - 0x1cf478, 0x1d1653, 0x1d166b, 0x1d1673, 0x1d16a8, 0x1d16db, - 0x1d16e3, 0x1d1732, 0x1d17b3, 0x1d1838, 0x1d1853, 0x1d18c8, - 0x1d1aa3, 0x1d1ae8, 0x1d2423, 0x1d2458, 0x1da003, 0x1da378, - 0x1da3b3, 0x1da6d8, 0x1da753, 0x1da768, 0x1da843, 0x1da858, - 0x1da9b3, 0x1daa08, 0x1daa13, 0x1dab08, 0x1e0003, 0x1e0078, - 0x1e0083, 0x1e0198, 0x1e01b3, 0x1e0228, 0x1e0233, 0x1e0258, - 0x1e0263, 0x1e02b8, 0x1e08f3, 0x1e0908, 0x1e1303, 0x1e1378, - 0x1e2ae3, 0x1e2af8, 0x1e2ec3, 0x1e2f08, 0x1e4ec3, 0x1e4f08, - 0x1e8d03, 0x1e8d78, 0x1e9443, 0x1e94b8, 0x1f1e6a, 0x1f2008, - 0x1f3fb3, 0x1f4008, 0xe00002, 0xe00203, 0xe00802, 0xe01003, - 0xe01f02, 0xe10008, + 0x1, 0xa2, 0xb1, 0xd3, 0xe1, 0x200, + 0x7f1, 0xa00, 0xad1, 0xae0, 0x3004, 0x3700, + 0x4834, 0x48a0, 0x5914, 0x5be0, 0x5bf4, 0x5c00, + 0x5c14, 0x5c30, 0x5c44, 0x5c60, 0x5c74, 0x5c80, + 0x6005, 0x6060, 0x6104, 0x61b0, 0x61c1, 0x61d0, + 0x64b4, 0x6600, 0x6704, 0x6710, 0x6d64, 0x6dd5, + 0x6de0, 0x6df4, 0x6e50, 0x6e74, 0x6e90, 0x6ea4, + 0x6ee0, 0x70f5, 0x7100, 0x7114, 0x7120, 0x7304, + 0x74b0, 0x7a64, 0x7b10, 0x7eb4, 0x7f40, 0x7fd4, + 0x7fe0, 0x8164, 0x81a0, 0x81b4, 0x8240, 0x8254, + 0x8280, 0x8294, 0x82e0, 0x8594, 0x85c0, 0x8905, + 0x8920, 0x8984, 0x8a00, 0x8ca4, 0x8e25, 0x8e34, + 0x9036, 0x9040, 0x93a4, 0x93b6, 0x93c4, 0x93d0, + 0x93e6, 0x9414, 0x9496, 0x94d4, 0x94e6, 0x9500, + 0x9514, 0x9580, 0x9624, 0x9640, 0x9814, 0x9826, + 0x9840, 0x9bc4, 0x9bd0, 0x9be4, 0x9bf6, 0x9c14, + 0x9c50, 0x9c76, 0x9c90, 0x9cb6, 0x9cd4, 0x9ce0, + 0x9d74, 0x9d80, 0x9e24, 0x9e40, 0x9fe4, 0x9ff0, + 0xa014, 0xa036, 0xa040, 0xa3c4, 0xa3d0, 0xa3e6, + 0xa414, 0xa430, 0xa474, 0xa490, 0xa4b4, 0xa4e0, + 0xa514, 0xa520, 0xa704, 0xa720, 0xa754, 0xa760, + 0xa814, 0xa836, 0xa840, 0xabc4, 0xabd0, 0xabe6, + 0xac14, 0xac60, 0xac74, 0xac96, 0xaca0, 0xacb6, + 0xacd4, 0xace0, 0xae24, 0xae40, 0xafa4, 0xb000, + 0xb014, 0xb026, 0xb040, 0xb3c4, 0xb3d0, 0xb3e4, + 0xb406, 0xb414, 0xb450, 0xb476, 0xb490, 0xb4b6, + 0xb4d4, 0xb4e0, 0xb554, 0xb580, 0xb624, 0xb640, + 0xb824, 0xb830, 0xbbe4, 0xbbf6, 0xbc04, 0xbc16, + 0xbc30, 0xbc66, 0xbc90, 0xbca6, 0xbcd4, 0xbce0, + 0xbd74, 0xbd80, 0xc004, 0xc016, 0xc044, 0xc050, + 0xc3c4, 0xc3d0, 0xc3e4, 0xc416, 0xc450, 0xc464, + 0xc490, 0xc4a4, 0xc4e0, 0xc554, 0xc570, 0xc624, + 0xc640, 0xc814, 0xc826, 0xc840, 0xcbc4, 0xcbd0, + 0xcbe6, 0xcbf4, 0xcc06, 0xcc24, 0xcc36, 0xcc50, + 0xcc64, 0xcc76, 0xcc90, 0xcca6, 0xccc4, 0xcce0, + 0xcd54, 0xcd70, 0xce24, 0xce40, 0xcf36, 0xcf40, + 0xd004, 0xd026, 0xd040, 0xd3b4, 0xd3d0, 0xd3e4, + 0xd3f6, 0xd414, 0xd450, 0xd466, 0xd490, 0xd4a6, + 0xd4d4, 0xd4e5, 0xd4f0, 0xd574, 0xd580, 0xd624, + 0xd640, 0xd814, 0xd826, 0xd840, 0xdca4, 0xdcb0, + 0xdcf4, 0xdd06, 0xdd24, 0xdd50, 0xdd64, 0xdd70, + 0xdd86, 0xddf4, 0xde00, 0xdf26, 0xdf40, 0xe314, + 0xe320, 0xe336, 0xe344, 0xe3b0, 0xe474, 0xe4f0, + 0xeb14, 0xeb20, 0xeb36, 0xeb44, 0xebd0, 0xec84, + 0xecf0, 0xf184, 0xf1a0, 0xf354, 0xf360, 0xf374, + 0xf380, 0xf394, 0xf3a0, 0xf3e6, 0xf400, 0xf714, + 0xf7f6, 0xf804, 0xf850, 0xf864, 0xf880, 0xf8d4, + 0xf980, 0xf994, 0xfbd0, 0xfc64, 0xfc70, 0x102d4, + 0x10316, 0x10324, 0x10380, 0x10394, 0x103b6, 0x103d4, + 0x103f0, 0x10566, 0x10584, 0x105a0, 0x105e4, 0x10610, + 0x10714, 0x10750, 0x10824, 0x10830, 0x10846, 0x10854, + 0x10870, 0x108d4, 0x108e0, 0x109d4, 0x109e0, 0x11007, + 0x11608, 0x11a89, 0x12000, 0x135d4, 0x13600, 0x17124, + 0x17156, 0x17160, 0x17324, 0x17346, 0x17350, 0x17524, + 0x17540, 0x17724, 0x17740, 0x17b44, 0x17b66, 0x17b74, + 0x17be6, 0x17c64, 0x17c76, 0x17c94, 0x17d40, 0x17dd4, + 0x17de0, 0x180b4, 0x180e1, 0x180f4, 0x18100, 0x18854, + 0x18870, 0x18a94, 0x18aa0, 0x19204, 0x19236, 0x19274, + 0x19296, 0x192c0, 0x19306, 0x19324, 0x19336, 0x19394, + 0x193c0, 0x1a174, 0x1a196, 0x1a1b4, 0x1a1c0, 0x1a556, + 0x1a564, 0x1a576, 0x1a584, 0x1a5f0, 0x1a604, 0x1a610, + 0x1a624, 0x1a630, 0x1a654, 0x1a6d6, 0x1a734, 0x1a7d0, + 0x1a7f4, 0x1a800, 0x1ab04, 0x1acf0, 0x1b004, 0x1b046, + 0x1b050, 0x1b344, 0x1b3b6, 0x1b3c4, 0x1b3d6, 0x1b424, + 0x1b436, 0x1b450, 0x1b6b4, 0x1b740, 0x1b804, 0x1b826, + 0x1b830, 0x1ba16, 0x1ba24, 0x1ba66, 0x1ba84, 0x1baa6, + 0x1bab4, 0x1bae0, 0x1be64, 0x1be76, 0x1be84, 0x1bea6, + 0x1bed4, 0x1bee6, 0x1bef4, 0x1bf26, 0x1bf40, 0x1c246, + 0x1c2c4, 0x1c346, 0x1c364, 0x1c380, 0x1cd04, 0x1cd30, + 0x1cd44, 0x1ce16, 0x1ce24, 0x1ce90, 0x1ced4, 0x1cee0, + 0x1cf44, 0x1cf50, 0x1cf76, 0x1cf84, 0x1cfa0, 0x1dc04, + 0x1e000, 0x200b1, 0x200c4, 0x200da, 0x200e1, 0x20100, + 0x20281, 0x202f0, 0x20601, 0x20700, 0x20d04, 0x20f10, + 0x2cef4, 0x2cf20, 0x2d7f4, 0x2d800, 0x2de04, 0x2e000, + 0x302a4, 0x30300, 0x30994, 0x309b0, 0xa66f4, 0xa6730, + 0xa6744, 0xa67e0, 0xa69e4, 0xa6a00, 0xa6f04, 0xa6f20, + 0xa8024, 0xa8030, 0xa8064, 0xa8070, 0xa80b4, 0xa80c0, + 0xa8236, 0xa8254, 0xa8276, 0xa8280, 0xa82c4, 0xa82d0, + 0xa8806, 0xa8820, 0xa8b46, 0xa8c44, 0xa8c60, 0xa8e04, + 0xa8f20, 0xa8ff4, 0xa9000, 0xa9264, 0xa92e0, 0xa9474, + 0xa9526, 0xa9540, 0xa9607, 0xa97d0, 0xa9804, 0xa9836, + 0xa9840, 0xa9b34, 0xa9b46, 0xa9b64, 0xa9ba6, 0xa9bc4, + 0xa9be6, 0xa9c10, 0xa9e54, 0xa9e60, 0xaa294, 0xaa2f6, + 0xaa314, 0xaa336, 0xaa354, 0xaa370, 0xaa434, 0xaa440, + 0xaa4c4, 0xaa4d6, 0xaa4e0, 0xaa7c4, 0xaa7d0, 0xaab04, + 0xaab10, 0xaab24, 0xaab50, 0xaab74, 0xaab90, 0xaabe4, + 0xaac00, 0xaac14, 0xaac20, 0xaaeb6, 0xaaec4, 0xaaee6, + 0xaaf00, 0xaaf56, 0xaaf64, 0xaaf70, 0xabe36, 0xabe54, + 0xabe66, 0xabe84, 0xabe96, 0xabeb0, 0xabec6, 0xabed4, + 0xabee0, 0xac00b, 0xac01c, 0xac1cb, 0xac1dc, 0xac38b, + 0xac39c, 0xac54b, 0xac55c, 0xac70b, 0xac71c, 0xac8cb, + 0xac8dc, 0xaca8b, 0xaca9c, 0xacc4b, 0xacc5c, 0xace0b, + 0xace1c, 0xacfcb, 0xacfdc, 0xad18b, 0xad19c, 0xad34b, + 0xad35c, 0xad50b, 0xad51c, 0xad6cb, 0xad6dc, 0xad88b, + 0xad89c, 0xada4b, 0xada5c, 0xadc0b, 0xadc1c, 0xaddcb, + 0xadddc, 0xadf8b, 0xadf9c, 0xae14b, 0xae15c, 0xae30b, + 0xae31c, 0xae4cb, 0xae4dc, 0xae68b, 0xae69c, 0xae84b, + 0xae85c, 0xaea0b, 0xaea1c, 0xaebcb, 0xaebdc, 0xaed8b, + 0xaed9c, 0xaef4b, 0xaef5c, 0xaf10b, 0xaf11c, 0xaf2cb, + 0xaf2dc, 0xaf48b, 0xaf49c, 0xaf64b, 0xaf65c, 0xaf80b, + 0xaf81c, 0xaf9cb, 0xaf9dc, 0xafb8b, 0xafb9c, 0xafd4b, + 0xafd5c, 0xaff0b, 0xaff1c, 0xb00cb, 0xb00dc, 0xb028b, + 0xb029c, 0xb044b, 0xb045c, 0xb060b, 0xb061c, 0xb07cb, + 0xb07dc, 0xb098b, 0xb099c, 0xb0b4b, 0xb0b5c, 0xb0d0b, + 0xb0d1c, 0xb0ecb, 0xb0edc, 0xb108b, 0xb109c, 0xb124b, + 0xb125c, 0xb140b, 0xb141c, 0xb15cb, 0xb15dc, 0xb178b, + 0xb179c, 0xb194b, 0xb195c, 0xb1b0b, 0xb1b1c, 0xb1ccb, + 0xb1cdc, 0xb1e8b, 0xb1e9c, 0xb204b, 0xb205c, 0xb220b, + 0xb221c, 0xb23cb, 0xb23dc, 0xb258b, 0xb259c, 0xb274b, + 0xb275c, 0xb290b, 0xb291c, 0xb2acb, 0xb2adc, 0xb2c8b, + 0xb2c9c, 0xb2e4b, 0xb2e5c, 0xb300b, 0xb301c, 0xb31cb, + 0xb31dc, 0xb338b, 0xb339c, 0xb354b, 0xb355c, 0xb370b, + 0xb371c, 0xb38cb, 0xb38dc, 0xb3a8b, 0xb3a9c, 0xb3c4b, + 0xb3c5c, 0xb3e0b, 0xb3e1c, 0xb3fcb, 0xb3fdc, 0xb418b, + 0xb419c, 0xb434b, 0xb435c, 0xb450b, 0xb451c, 0xb46cb, + 0xb46dc, 0xb488b, 0xb489c, 0xb4a4b, 0xb4a5c, 0xb4c0b, + 0xb4c1c, 0xb4dcb, 0xb4ddc, 0xb4f8b, 0xb4f9c, 0xb514b, + 0xb515c, 0xb530b, 0xb531c, 0xb54cb, 0xb54dc, 0xb568b, + 0xb569c, 0xb584b, 0xb585c, 0xb5a0b, 0xb5a1c, 0xb5bcb, + 0xb5bdc, 0xb5d8b, 0xb5d9c, 0xb5f4b, 0xb5f5c, 0xb610b, + 0xb611c, 0xb62cb, 0xb62dc, 0xb648b, 0xb649c, 0xb664b, + 0xb665c, 0xb680b, 0xb681c, 0xb69cb, 0xb69dc, 0xb6b8b, + 0xb6b9c, 0xb6d4b, 0xb6d5c, 0xb6f0b, 0xb6f1c, 0xb70cb, + 0xb70dc, 0xb728b, 0xb729c, 0xb744b, 0xb745c, 0xb760b, + 0xb761c, 0xb77cb, 0xb77dc, 0xb798b, 0xb799c, 0xb7b4b, + 0xb7b5c, 0xb7d0b, 0xb7d1c, 0xb7ecb, 0xb7edc, 0xb808b, + 0xb809c, 0xb824b, 0xb825c, 0xb840b, 0xb841c, 0xb85cb, + 0xb85dc, 0xb878b, 0xb879c, 0xb894b, 0xb895c, 0xb8b0b, + 0xb8b1c, 0xb8ccb, 0xb8cdc, 0xb8e8b, 0xb8e9c, 0xb904b, + 0xb905c, 0xb920b, 0xb921c, 0xb93cb, 0xb93dc, 0xb958b, + 0xb959c, 0xb974b, 0xb975c, 0xb990b, 0xb991c, 0xb9acb, + 0xb9adc, 0xb9c8b, 0xb9c9c, 0xb9e4b, 0xb9e5c, 0xba00b, + 0xba01c, 0xba1cb, 0xba1dc, 0xba38b, 0xba39c, 0xba54b, + 0xba55c, 0xba70b, 0xba71c, 0xba8cb, 0xba8dc, 0xbaa8b, + 0xbaa9c, 0xbac4b, 0xbac5c, 0xbae0b, 0xbae1c, 0xbafcb, + 0xbafdc, 0xbb18b, 0xbb19c, 0xbb34b, 0xbb35c, 0xbb50b, + 0xbb51c, 0xbb6cb, 0xbb6dc, 0xbb88b, 0xbb89c, 0xbba4b, + 0xbba5c, 0xbbc0b, 0xbbc1c, 0xbbdcb, 0xbbddc, 0xbbf8b, + 0xbbf9c, 0xbc14b, 0xbc15c, 0xbc30b, 0xbc31c, 0xbc4cb, + 0xbc4dc, 0xbc68b, 0xbc69c, 0xbc84b, 0xbc85c, 0xbca0b, + 0xbca1c, 0xbcbcb, 0xbcbdc, 0xbcd8b, 0xbcd9c, 0xbcf4b, + 0xbcf5c, 0xbd10b, 0xbd11c, 0xbd2cb, 0xbd2dc, 0xbd48b, + 0xbd49c, 0xbd64b, 0xbd65c, 0xbd80b, 0xbd81c, 0xbd9cb, + 0xbd9dc, 0xbdb8b, 0xbdb9c, 0xbdd4b, 0xbdd5c, 0xbdf0b, + 0xbdf1c, 0xbe0cb, 0xbe0dc, 0xbe28b, 0xbe29c, 0xbe44b, + 0xbe45c, 0xbe60b, 0xbe61c, 0xbe7cb, 0xbe7dc, 0xbe98b, + 0xbe99c, 0xbeb4b, 0xbeb5c, 0xbed0b, 0xbed1c, 0xbeecb, + 0xbeedc, 0xbf08b, 0xbf09c, 0xbf24b, 0xbf25c, 0xbf40b, + 0xbf41c, 0xbf5cb, 0xbf5dc, 0xbf78b, 0xbf79c, 0xbf94b, + 0xbf95c, 0xbfb0b, 0xbfb1c, 0xbfccb, 0xbfcdc, 0xbfe8b, + 0xbfe9c, 0xc004b, 0xc005c, 0xc020b, 0xc021c, 0xc03cb, + 0xc03dc, 0xc058b, 0xc059c, 0xc074b, 0xc075c, 0xc090b, + 0xc091c, 0xc0acb, 0xc0adc, 0xc0c8b, 0xc0c9c, 0xc0e4b, + 0xc0e5c, 0xc100b, 0xc101c, 0xc11cb, 0xc11dc, 0xc138b, + 0xc139c, 0xc154b, 0xc155c, 0xc170b, 0xc171c, 0xc18cb, + 0xc18dc, 0xc1a8b, 0xc1a9c, 0xc1c4b, 0xc1c5c, 0xc1e0b, + 0xc1e1c, 0xc1fcb, 0xc1fdc, 0xc218b, 0xc219c, 0xc234b, + 0xc235c, 0xc250b, 0xc251c, 0xc26cb, 0xc26dc, 0xc288b, + 0xc289c, 0xc2a4b, 0xc2a5c, 0xc2c0b, 0xc2c1c, 0xc2dcb, + 0xc2ddc, 0xc2f8b, 0xc2f9c, 0xc314b, 0xc315c, 0xc330b, + 0xc331c, 0xc34cb, 0xc34dc, 0xc368b, 0xc369c, 0xc384b, + 0xc385c, 0xc3a0b, 0xc3a1c, 0xc3bcb, 0xc3bdc, 0xc3d8b, + 0xc3d9c, 0xc3f4b, 0xc3f5c, 0xc410b, 0xc411c, 0xc42cb, + 0xc42dc, 0xc448b, 0xc449c, 0xc464b, 0xc465c, 0xc480b, + 0xc481c, 0xc49cb, 0xc49dc, 0xc4b8b, 0xc4b9c, 0xc4d4b, + 0xc4d5c, 0xc4f0b, 0xc4f1c, 0xc50cb, 0xc50dc, 0xc528b, + 0xc529c, 0xc544b, 0xc545c, 0xc560b, 0xc561c, 0xc57cb, + 0xc57dc, 0xc598b, 0xc599c, 0xc5b4b, 0xc5b5c, 0xc5d0b, + 0xc5d1c, 0xc5ecb, 0xc5edc, 0xc608b, 0xc609c, 0xc624b, + 0xc625c, 0xc640b, 0xc641c, 0xc65cb, 0xc65dc, 0xc678b, + 0xc679c, 0xc694b, 0xc695c, 0xc6b0b, 0xc6b1c, 0xc6ccb, + 0xc6cdc, 0xc6e8b, 0xc6e9c, 0xc704b, 0xc705c, 0xc720b, + 0xc721c, 0xc73cb, 0xc73dc, 0xc758b, 0xc759c, 0xc774b, + 0xc775c, 0xc790b, 0xc791c, 0xc7acb, 0xc7adc, 0xc7c8b, + 0xc7c9c, 0xc7e4b, 0xc7e5c, 0xc800b, 0xc801c, 0xc81cb, + 0xc81dc, 0xc838b, 0xc839c, 0xc854b, 0xc855c, 0xc870b, + 0xc871c, 0xc88cb, 0xc88dc, 0xc8a8b, 0xc8a9c, 0xc8c4b, + 0xc8c5c, 0xc8e0b, 0xc8e1c, 0xc8fcb, 0xc8fdc, 0xc918b, + 0xc919c, 0xc934b, 0xc935c, 0xc950b, 0xc951c, 0xc96cb, + 0xc96dc, 0xc988b, 0xc989c, 0xc9a4b, 0xc9a5c, 0xc9c0b, + 0xc9c1c, 0xc9dcb, 0xc9ddc, 0xc9f8b, 0xc9f9c, 0xca14b, + 0xca15c, 0xca30b, 0xca31c, 0xca4cb, 0xca4dc, 0xca68b, + 0xca69c, 0xca84b, 0xca85c, 0xcaa0b, 0xcaa1c, 0xcabcb, + 0xcabdc, 0xcad8b, 0xcad9c, 0xcaf4b, 0xcaf5c, 0xcb10b, + 0xcb11c, 0xcb2cb, 0xcb2dc, 0xcb48b, 0xcb49c, 0xcb64b, + 0xcb65c, 0xcb80b, 0xcb81c, 0xcb9cb, 0xcb9dc, 0xcbb8b, + 0xcbb9c, 0xcbd4b, 0xcbd5c, 0xcbf0b, 0xcbf1c, 0xcc0cb, + 0xcc0dc, 0xcc28b, 0xcc29c, 0xcc44b, 0xcc45c, 0xcc60b, + 0xcc61c, 0xcc7cb, 0xcc7dc, 0xcc98b, 0xcc99c, 0xccb4b, + 0xccb5c, 0xccd0b, 0xccd1c, 0xccecb, 0xccedc, 0xcd08b, + 0xcd09c, 0xcd24b, 0xcd25c, 0xcd40b, 0xcd41c, 0xcd5cb, + 0xcd5dc, 0xcd78b, 0xcd79c, 0xcd94b, 0xcd95c, 0xcdb0b, + 0xcdb1c, 0xcdccb, 0xcdcdc, 0xcde8b, 0xcde9c, 0xce04b, + 0xce05c, 0xce20b, 0xce21c, 0xce3cb, 0xce3dc, 0xce58b, + 0xce59c, 0xce74b, 0xce75c, 0xce90b, 0xce91c, 0xceacb, + 0xceadc, 0xcec8b, 0xcec9c, 0xcee4b, 0xcee5c, 0xcf00b, + 0xcf01c, 0xcf1cb, 0xcf1dc, 0xcf38b, 0xcf39c, 0xcf54b, + 0xcf55c, 0xcf70b, 0xcf71c, 0xcf8cb, 0xcf8dc, 0xcfa8b, + 0xcfa9c, 0xcfc4b, 0xcfc5c, 0xcfe0b, 0xcfe1c, 0xcffcb, + 0xcffdc, 0xd018b, 0xd019c, 0xd034b, 0xd035c, 0xd050b, + 0xd051c, 0xd06cb, 0xd06dc, 0xd088b, 0xd089c, 0xd0a4b, + 0xd0a5c, 0xd0c0b, 0xd0c1c, 0xd0dcb, 0xd0ddc, 0xd0f8b, + 0xd0f9c, 0xd114b, 0xd115c, 0xd130b, 0xd131c, 0xd14cb, + 0xd14dc, 0xd168b, 0xd169c, 0xd184b, 0xd185c, 0xd1a0b, + 0xd1a1c, 0xd1bcb, 0xd1bdc, 0xd1d8b, 0xd1d9c, 0xd1f4b, + 0xd1f5c, 0xd210b, 0xd211c, 0xd22cb, 0xd22dc, 0xd248b, + 0xd249c, 0xd264b, 0xd265c, 0xd280b, 0xd281c, 0xd29cb, + 0xd29dc, 0xd2b8b, 0xd2b9c, 0xd2d4b, 0xd2d5c, 0xd2f0b, + 0xd2f1c, 0xd30cb, 0xd30dc, 0xd328b, 0xd329c, 0xd344b, + 0xd345c, 0xd360b, 0xd361c, 0xd37cb, 0xd37dc, 0xd398b, + 0xd399c, 0xd3b4b, 0xd3b5c, 0xd3d0b, 0xd3d1c, 0xd3ecb, + 0xd3edc, 0xd408b, 0xd409c, 0xd424b, 0xd425c, 0xd440b, + 0xd441c, 0xd45cb, 0xd45dc, 0xd478b, 0xd479c, 0xd494b, + 0xd495c, 0xd4b0b, 0xd4b1c, 0xd4ccb, 0xd4cdc, 0xd4e8b, + 0xd4e9c, 0xd504b, 0xd505c, 0xd520b, 0xd521c, 0xd53cb, + 0xd53dc, 0xd558b, 0xd559c, 0xd574b, 0xd575c, 0xd590b, + 0xd591c, 0xd5acb, 0xd5adc, 0xd5c8b, 0xd5c9c, 0xd5e4b, + 0xd5e5c, 0xd600b, 0xd601c, 0xd61cb, 0xd61dc, 0xd638b, + 0xd639c, 0xd654b, 0xd655c, 0xd670b, 0xd671c, 0xd68cb, + 0xd68dc, 0xd6a8b, 0xd6a9c, 0xd6c4b, 0xd6c5c, 0xd6e0b, + 0xd6e1c, 0xd6fcb, 0xd6fdc, 0xd718b, 0xd719c, 0xd734b, + 0xd735c, 0xd750b, 0xd751c, 0xd76cb, 0xd76dc, 0xd788b, + 0xd789c, 0xd7a40, 0xd7b08, 0xd7c70, 0xd7cb9, 0xd7fc0, + 0xfb1e4, 0xfb1f0, 0xfe004, 0xfe100, 0xfe204, 0xfe300, + 0xfeff1, 0xff000, 0xff9e4, 0xffa00, 0xfff01, 0xfffc0, + 0x101fd4, 0x101fe0, 0x102e04, 0x102e10, 0x103764, 0x1037b0, + 0x10a014, 0x10a040, 0x10a054, 0x10a070, 0x10a0c4, 0x10a100, + 0x10a384, 0x10a3b0, 0x10a3f4, 0x10a400, 0x10ae54, 0x10ae70, + 0x10d244, 0x10d280, 0x10eab4, 0x10ead0, 0x10efd4, 0x10f000, + 0x10f464, 0x10f510, 0x10f824, 0x10f860, 0x110006, 0x110014, + 0x110026, 0x110030, 0x110384, 0x110470, 0x110704, 0x110710, + 0x110734, 0x110750, 0x1107f4, 0x110826, 0x110830, 0x110b06, + 0x110b34, 0x110b76, 0x110b94, 0x110bb0, 0x110bd5, 0x110be0, + 0x110c24, 0x110c30, 0x110cd5, 0x110ce0, 0x111004, 0x111030, + 0x111274, 0x1112c6, 0x1112d4, 0x111350, 0x111456, 0x111470, + 0x111734, 0x111740, 0x111804, 0x111826, 0x111830, 0x111b36, + 0x111b64, 0x111bf6, 0x111c10, 0x111c25, 0x111c40, 0x111c94, + 0x111cd0, 0x111ce6, 0x111cf4, 0x111d00, 0x1122c6, 0x1122f4, + 0x112326, 0x112344, 0x112356, 0x112364, 0x112380, 0x1123e4, + 0x1123f0, 0x112414, 0x112420, 0x112df4, 0x112e06, 0x112e34, + 0x112eb0, 0x113004, 0x113026, 0x113040, 0x1133b4, 0x1133d0, + 0x1133e4, 0x1133f6, 0x113404, 0x113416, 0x113450, 0x113476, + 0x113490, 0x1134b6, 0x1134e0, 0x113574, 0x113580, 0x113626, + 0x113640, 0x113664, 0x1136d0, 0x113704, 0x113750, 0x114356, + 0x114384, 0x114406, 0x114424, 0x114456, 0x114464, 0x114470, + 0x1145e4, 0x1145f0, 0x114b04, 0x114b16, 0x114b34, 0x114b96, + 0x114ba4, 0x114bb6, 0x114bd4, 0x114be6, 0x114bf4, 0x114c16, + 0x114c24, 0x114c40, 0x115af4, 0x115b06, 0x115b24, 0x115b60, + 0x115b86, 0x115bc4, 0x115be6, 0x115bf4, 0x115c10, 0x115dc4, + 0x115de0, 0x116306, 0x116334, 0x1163b6, 0x1163d4, 0x1163e6, + 0x1163f4, 0x116410, 0x116ab4, 0x116ac6, 0x116ad4, 0x116ae6, + 0x116b04, 0x116b66, 0x116b74, 0x116b80, 0x1171d4, 0x117200, + 0x117224, 0x117266, 0x117274, 0x1172c0, 0x1182c6, 0x1182f4, + 0x118386, 0x118394, 0x1183b0, 0x119304, 0x119316, 0x119360, + 0x119376, 0x119390, 0x1193b4, 0x1193d6, 0x1193e4, 0x1193f5, + 0x119406, 0x119415, 0x119426, 0x119434, 0x119440, 0x119d16, + 0x119d44, 0x119d80, 0x119da4, 0x119dc6, 0x119e04, 0x119e10, + 0x119e46, 0x119e50, 0x11a014, 0x11a0b0, 0x11a334, 0x11a396, + 0x11a3a5, 0x11a3b4, 0x11a3f0, 0x11a474, 0x11a480, 0x11a514, + 0x11a576, 0x11a594, 0x11a5c0, 0x11a845, 0x11a8a4, 0x11a976, + 0x11a984, 0x11a9a0, 0x11c2f6, 0x11c304, 0x11c370, 0x11c384, + 0x11c3e6, 0x11c3f4, 0x11c400, 0x11c924, 0x11ca80, 0x11ca96, + 0x11caa4, 0x11cb16, 0x11cb24, 0x11cb46, 0x11cb54, 0x11cb70, + 0x11d314, 0x11d370, 0x11d3a4, 0x11d3b0, 0x11d3c4, 0x11d3e0, + 0x11d3f4, 0x11d465, 0x11d474, 0x11d480, 0x11d8a6, 0x11d8f0, + 0x11d904, 0x11d920, 0x11d936, 0x11d954, 0x11d966, 0x11d974, + 0x11d980, 0x11ef34, 0x11ef56, 0x11ef70, 0x11f004, 0x11f025, + 0x11f036, 0x11f040, 0x11f346, 0x11f364, 0x11f3b0, 0x11f3e6, + 0x11f404, 0x11f416, 0x11f424, 0x11f430, 0x134301, 0x134404, + 0x134410, 0x134474, 0x134560, 0x16af04, 0x16af50, 0x16b304, + 0x16b370, 0x16f4f4, 0x16f500, 0x16f516, 0x16f880, 0x16f8f4, + 0x16f930, 0x16fe44, 0x16fe50, 0x16ff06, 0x16ff20, 0x1bc9d4, + 0x1bc9f0, 0x1bca01, 0x1bca40, 0x1cf004, 0x1cf2e0, 0x1cf304, + 0x1cf470, 0x1d1654, 0x1d1666, 0x1d1674, 0x1d16a0, 0x1d16d6, + 0x1d16e4, 0x1d1731, 0x1d17b4, 0x1d1830, 0x1d1854, 0x1d18c0, + 0x1d1aa4, 0x1d1ae0, 0x1d2424, 0x1d2450, 0x1da004, 0x1da370, + 0x1da3b4, 0x1da6d0, 0x1da754, 0x1da760, 0x1da844, 0x1da850, + 0x1da9b4, 0x1daa00, 0x1daa14, 0x1dab00, 0x1e0004, 0x1e0070, + 0x1e0084, 0x1e0190, 0x1e01b4, 0x1e0220, 0x1e0234, 0x1e0250, + 0x1e0264, 0x1e02b0, 0x1e08f4, 0x1e0900, 0x1e1304, 0x1e1370, + 0x1e2ae4, 0x1e2af0, 0x1e2ec4, 0x1e2f00, 0x1e4ec4, 0x1e4f00, + 0x1e8d04, 0x1e8d70, 0x1e9444, 0x1e94b0, 0x1f1e6d, 0x1f2000, + 0x1f3fb4, 0x1f4000, 0xe00001, 0xe00204, 0xe00801, 0xe01004, + 0xe01f01, 0xe10000, }; inline constexpr char32_t __incb_linkers[] = { diff --git a/libstdc++-v3/include/bits/unicode.h b/libstdc++-v3/include/bits/unicode.h index e49498a..f1b2b35 100644 --- a/libstdc++-v3/include/bits/unicode.h +++ b/libstdc++-v3/include/bits/unicode.h @@ -163,7 +163,7 @@ namespace __unicode else _M_read(); } - else if (_M_buf_index + 1 <= _M_buf_last) + else if (_M_buf_index + 1 < _M_buf_last) ++_M_buf_index; return *this; } @@ -603,6 +603,7 @@ inline namespace __v15_1_0 return (__p - __width_edges) % 2 + 1; } + // @pre c <= 0x10FFFF constexpr _Gcb_property __grapheme_cluster_break_property(char32_t __c) noexcept { @@ -621,9 +622,13 @@ inline namespace __v15_1_0 return std::find(__incb_linkers, __end, __c) != __end; } + // @pre c <= 0x10FFFF constexpr _InCB __incb_property(char32_t __c) noexcept { + if ((__c << 2) < __incb_edges[0]) [[likely]] + return _InCB(0); + constexpr uint32_t __mask = 0x3; auto* __end = std::end(__incb_edges); auto* __p = std::lower_bound(__incb_edges, __end, (__c << 2) | __mask); @@ -634,10 +639,10 @@ inline namespace __v15_1_0 __is_extended_pictographic(char32_t __c) { if (__c < __xpicto_edges[0]) [[likely]] - return 1; + return 0; auto* __p = std::upper_bound(__xpicto_edges, std::end(__xpicto_edges), __c); - return (__p - __xpicto_edges) % 2 + 1; + return (__p - __xpicto_edges) % 2; } struct _Grapheme_cluster_iterator_base @@ -732,22 +737,22 @@ inline namespace __v15_1_0 public: // TODO: Change value_type to be subrange<_U32_iterator> instead? - // That would be the whole cluster, not just the first code point. - // Would need to change type of _M_start to _U32_iterator, so that - // operator* just does return value_type{_M_start, _M_next}. // Alternatively, value_type could be _Utf32_view<iterator_t<_View>>. + // That would be the whole cluster, not just the first code point. + // Would need to store two iterators and find end of current cluster + // on increment, so operator* returns value_type(_M_base, _M_next). using value_type = char32_t; using iterator_concept = forward_iterator_tag; + using difference_type = ptrdiff_t; constexpr _Iterator(_U32_iterator __i) - : _M_start(__i.base()), _M_next(__i) + : _M_base(__i) { - if (_M_start != __i.end()) + if (__i != __i.end()) { _M_c = *__i; _M_prop = __grapheme_cluster_break_property(_M_c); - operator++(); // Finds the end of the first cluster. } } @@ -764,11 +769,11 @@ inline namespace __v15_1_0 constexpr _Iterator& operator++() { - const auto __end = _M_next.end(); - if (_M_next != __end) + const auto __end = _M_base.end(); + if (_M_base != __end) { auto __p_prev = _M_prop; - auto __it = _M_next; + auto __it = _M_base; while (++__it != __end) { char32_t __c = *__it; @@ -784,11 +789,8 @@ inline namespace __v15_1_0 } __p_prev = __p; } - _M_start = _M_next.base(); - _M_next = __it; + _M_base = __it; } - else - _M_start = __end; return *this; } @@ -802,18 +804,18 @@ inline namespace __v15_1_0 constexpr bool operator==(const _Iterator& __i) const - { return _M_start == __i._M_start; } + { return _M_base == __i._M_base; } // This supports iter != iter.end() constexpr bool operator==(const ranges::sentinel_t<_View>& __i) const - { return _M_start == __i; } + { return _M_base == __i; } // Iterator to the start of the current cluster. - constexpr auto base() const { return _M_start; } + constexpr auto base() const { return _M_base.base(); } // The end of the underlying view (not the end of the current cluster!) - constexpr auto end() const { return _M_next.end(); } + constexpr auto end() const { return _M_base.end(); } // Field width of the first code point in the cluster. constexpr int @@ -821,8 +823,7 @@ inline namespace __v15_1_0 { return __field_width(_M_c); } private: - ranges::iterator_t<_View> _M_start; - _U32_iterator _M_next; + _U32_iterator _M_base; // Implement the Grapheme Cluster Boundary Rules from Unicode Annex #29 // http://www.unicode.org/reports/tr29/#Grapheme_Cluster_Boundary_Rules @@ -891,13 +892,13 @@ inline namespace __v15_1_0 // Do not break within certain combinations with // Indic_Conjunct_Break (InCB)=Linker. if (_M_incb_linker_seen - && __incb_property(*_M_start) == _InCB::_Consonant + && __incb_property(_M_c) == _InCB::_Consonant && __incb_property(*__curr) == _InCB::_Consonant) { - // Match [_M_start, __curr] against regular expression + // Match [_M_base, __curr] against regular expression // Consonant ([Extend Linker]* Linker [Extend Linker]* Consonant)+ bool __have_linker = false; - auto __it = _M_start; + auto __it = _M_base; while (++__it != __curr) { if (__is_incb_linker(*__it)) diff --git a/libstdc++-v3/include/bits/utility.h b/libstdc++-v3/include/bits/utility.h index 45d7241..d8a5fb9 100644 --- a/libstdc++-v3/include/bits/utility.h +++ b/libstdc++-v3/include/bits/utility.h @@ -225,7 +225,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION #endif // C++17 -#if __has_builtin(__type_pack_element) +#if _GLIBCXX_USE_BUILTIN_TRAIT(__type_pack_element) template<size_t _Np, typename... _Types> struct _Nth_type { using type = __type_pack_element<_Np, _Types...>; }; diff --git a/libstdc++-v3/include/bits/version.def b/libstdc++-v3/include/bits/version.def index 7c7ba06..afbec6c 100644 --- a/libstdc++-v3/include/bits/version.def +++ b/libstdc++-v3/include/bits/version.def @@ -767,6 +767,15 @@ ftms = { }; ftms = { + name = bind_back; + values = { + v = 202202; + cxxmin = 23; + extra_cond = "__cpp_explicit_this_parameter"; + }; +}; + +ftms = { name = starts_ends_with; values = { v = 201711; @@ -1539,7 +1548,7 @@ ftms = { ftms = { name = ranges_as_const; values = { - v = 202207; + v = 202311; cxxmin = 23; }; }; diff --git a/libstdc++-v3/include/bits/version.h b/libstdc++-v3/include/bits/version.h index 65d5164..9688b24 100644 --- a/libstdc++-v3/include/bits/version.h +++ b/libstdc++-v3/include/bits/version.h @@ -937,6 +937,17 @@ #undef __glibcxx_want_bind_front // from version.def line 770 +#if !defined(__cpp_lib_bind_back) +# if (__cplusplus >= 202100L) && (__cpp_explicit_this_parameter) +# define __glibcxx_bind_back 202202L +# if defined(__glibcxx_want_all) || defined(__glibcxx_want_bind_back) +# define __cpp_lib_bind_back 202202L +# endif +# endif +#endif /* !defined(__cpp_lib_bind_back) && defined(__glibcxx_want_bind_back) */ +#undef __glibcxx_want_bind_back + +// from version.def line 779 #if !defined(__cpp_lib_starts_ends_with) # if (__cplusplus >= 202002L) # define __glibcxx_starts_ends_with 201711L @@ -947,7 +958,7 @@ #endif /* !defined(__cpp_lib_starts_ends_with) && defined(__glibcxx_want_starts_ends_with) */ #undef __glibcxx_want_starts_ends_with -// from version.def line 778 +// from version.def line 787 #if !defined(__cpp_lib_bit_cast) # if (__cplusplus >= 202002L) && (__has_builtin(__builtin_bit_cast)) # define __glibcxx_bit_cast 201806L @@ -958,7 +969,7 @@ #endif /* !defined(__cpp_lib_bit_cast) && defined(__glibcxx_want_bit_cast) */ #undef __glibcxx_want_bit_cast -// from version.def line 787 +// from version.def line 796 #if !defined(__cpp_lib_bitops) # if (__cplusplus >= 202002L) # define __glibcxx_bitops 201907L @@ -969,7 +980,7 @@ #endif /* !defined(__cpp_lib_bitops) && defined(__glibcxx_want_bitops) */ #undef __glibcxx_want_bitops -// from version.def line 795 +// from version.def line 804 #if !defined(__cpp_lib_bounded_array_traits) # if (__cplusplus >= 202002L) # define __glibcxx_bounded_array_traits 201902L @@ -980,7 +991,7 @@ #endif /* !defined(__cpp_lib_bounded_array_traits) && defined(__glibcxx_want_bounded_array_traits) */ #undef __glibcxx_want_bounded_array_traits -// from version.def line 803 +// from version.def line 812 #if !defined(__cpp_lib_concepts) # if (__cplusplus >= 202002L) && (__cpp_concepts >= 201907L) # define __glibcxx_concepts 202002L @@ -991,7 +1002,7 @@ #endif /* !defined(__cpp_lib_concepts) && defined(__glibcxx_want_concepts) */ #undef __glibcxx_want_concepts -// from version.def line 813 +// from version.def line 822 #if !defined(__cpp_lib_optional) # if (__cplusplus >= 202100L) && (__glibcxx_concepts) # define __glibcxx_optional 202110L @@ -1012,7 +1023,7 @@ #endif /* !defined(__cpp_lib_optional) && defined(__glibcxx_want_optional) */ #undef __glibcxx_want_optional -// from version.def line 830 +// from version.def line 839 #if !defined(__cpp_lib_destroying_delete) # if (__cplusplus >= 202002L) && (__cpp_impl_destroying_delete) # define __glibcxx_destroying_delete 201806L @@ -1023,7 +1034,7 @@ #endif /* !defined(__cpp_lib_destroying_delete) && defined(__glibcxx_want_destroying_delete) */ #undef __glibcxx_want_destroying_delete -// from version.def line 839 +// from version.def line 848 #if !defined(__cpp_lib_constexpr_string_view) # if (__cplusplus >= 202002L) # define __glibcxx_constexpr_string_view 201811L @@ -1034,7 +1045,7 @@ #endif /* !defined(__cpp_lib_constexpr_string_view) && defined(__glibcxx_want_constexpr_string_view) */ #undef __glibcxx_want_constexpr_string_view -// from version.def line 847 +// from version.def line 856 #if !defined(__cpp_lib_endian) # if (__cplusplus >= 202002L) # define __glibcxx_endian 201907L @@ -1045,7 +1056,7 @@ #endif /* !defined(__cpp_lib_endian) && defined(__glibcxx_want_endian) */ #undef __glibcxx_want_endian -// from version.def line 855 +// from version.def line 864 #if !defined(__cpp_lib_int_pow2) # if (__cplusplus >= 202002L) # define __glibcxx_int_pow2 202002L @@ -1056,7 +1067,7 @@ #endif /* !defined(__cpp_lib_int_pow2) && defined(__glibcxx_want_int_pow2) */ #undef __glibcxx_want_int_pow2 -// from version.def line 863 +// from version.def line 872 #if !defined(__cpp_lib_integer_comparison_functions) # if (__cplusplus >= 202002L) # define __glibcxx_integer_comparison_functions 202002L @@ -1067,7 +1078,7 @@ #endif /* !defined(__cpp_lib_integer_comparison_functions) && defined(__glibcxx_want_integer_comparison_functions) */ #undef __glibcxx_want_integer_comparison_functions -// from version.def line 871 +// from version.def line 880 #if !defined(__cpp_lib_is_constant_evaluated) # if (__cplusplus >= 202002L) && (defined(_GLIBCXX_HAVE_IS_CONSTANT_EVALUATED)) # define __glibcxx_is_constant_evaluated 201811L @@ -1078,7 +1089,7 @@ #endif /* !defined(__cpp_lib_is_constant_evaluated) && defined(__glibcxx_want_is_constant_evaluated) */ #undef __glibcxx_want_is_constant_evaluated -// from version.def line 881 +// from version.def line 890 #if !defined(__cpp_lib_constexpr_char_traits) # if (__cplusplus >= 202002L) && (defined(__glibcxx_is_constant_evaluated)) # define __glibcxx_constexpr_char_traits 201811L @@ -1094,7 +1105,7 @@ #endif /* !defined(__cpp_lib_constexpr_char_traits) && defined(__glibcxx_want_constexpr_char_traits) */ #undef __glibcxx_want_constexpr_char_traits -// from version.def line 897 +// from version.def line 906 #if !defined(__cpp_lib_is_layout_compatible) # if (__cplusplus >= 202002L) && (__has_builtin(__is_layout_compatible) && __has_builtin(__builtin_is_corresponding_member)) # define __glibcxx_is_layout_compatible 201907L @@ -1105,7 +1116,7 @@ #endif /* !defined(__cpp_lib_is_layout_compatible) && defined(__glibcxx_want_is_layout_compatible) */ #undef __glibcxx_want_is_layout_compatible -// from version.def line 907 +// from version.def line 916 #if !defined(__cpp_lib_is_nothrow_convertible) # if (__cplusplus >= 202002L) # define __glibcxx_is_nothrow_convertible 201806L @@ -1116,7 +1127,7 @@ #endif /* !defined(__cpp_lib_is_nothrow_convertible) && defined(__glibcxx_want_is_nothrow_convertible) */ #undef __glibcxx_want_is_nothrow_convertible -// from version.def line 915 +// from version.def line 924 #if !defined(__cpp_lib_is_pointer_interconvertible) # if (__cplusplus >= 202002L) && (__has_builtin(__is_pointer_interconvertible_base_of) && __has_builtin(__builtin_is_pointer_interconvertible_with_class)) # define __glibcxx_is_pointer_interconvertible 201907L @@ -1127,7 +1138,7 @@ #endif /* !defined(__cpp_lib_is_pointer_interconvertible) && defined(__glibcxx_want_is_pointer_interconvertible) */ #undef __glibcxx_want_is_pointer_interconvertible -// from version.def line 926 +// from version.def line 935 #if !defined(__cpp_lib_math_constants) # if (__cplusplus >= 202002L) # define __glibcxx_math_constants 201907L @@ -1138,7 +1149,7 @@ #endif /* !defined(__cpp_lib_math_constants) && defined(__glibcxx_want_math_constants) */ #undef __glibcxx_want_math_constants -// from version.def line 934 +// from version.def line 943 #if !defined(__cpp_lib_make_obj_using_allocator) # if (__cplusplus >= 202002L) && (__cpp_concepts) # define __glibcxx_make_obj_using_allocator 201811L @@ -1149,7 +1160,7 @@ #endif /* !defined(__cpp_lib_make_obj_using_allocator) && defined(__glibcxx_want_make_obj_using_allocator) */ #undef __glibcxx_want_make_obj_using_allocator -// from version.def line 944 +// from version.def line 953 #if !defined(__cpp_lib_remove_cvref) # if (__cplusplus >= 202002L) # define __glibcxx_remove_cvref 201711L @@ -1160,7 +1171,7 @@ #endif /* !defined(__cpp_lib_remove_cvref) && defined(__glibcxx_want_remove_cvref) */ #undef __glibcxx_want_remove_cvref -// from version.def line 952 +// from version.def line 961 #if !defined(__cpp_lib_source_location) # if (__cplusplus >= 202002L) && (__has_builtin(__builtin_source_location)) # define __glibcxx_source_location 201907L @@ -1171,7 +1182,7 @@ #endif /* !defined(__cpp_lib_source_location) && defined(__glibcxx_want_source_location) */ #undef __glibcxx_want_source_location -// from version.def line 961 +// from version.def line 970 #if !defined(__cpp_lib_span) # if (__cplusplus > 202302L) && (__glibcxx_concepts) # define __glibcxx_span 202311L @@ -1187,7 +1198,7 @@ #endif /* !defined(__cpp_lib_span) && defined(__glibcxx_want_span) */ #undef __glibcxx_want_span -// from version.def line 975 +// from version.def line 984 #if !defined(__cpp_lib_ssize) # if (__cplusplus >= 202002L) # define __glibcxx_ssize 201902L @@ -1198,7 +1209,7 @@ #endif /* !defined(__cpp_lib_ssize) && defined(__glibcxx_want_ssize) */ #undef __glibcxx_want_ssize -// from version.def line 983 +// from version.def line 992 #if !defined(__cpp_lib_three_way_comparison) # if (__cplusplus >= 202002L) && (__cpp_impl_three_way_comparison >= 201907L && __glibcxx_concepts) # define __glibcxx_three_way_comparison 201907L @@ -1209,7 +1220,7 @@ #endif /* !defined(__cpp_lib_three_way_comparison) && defined(__glibcxx_want_three_way_comparison) */ #undef __glibcxx_want_three_way_comparison -// from version.def line 993 +// from version.def line 1002 #if !defined(__cpp_lib_to_address) # if (__cplusplus >= 202002L) # define __glibcxx_to_address 201711L @@ -1220,7 +1231,7 @@ #endif /* !defined(__cpp_lib_to_address) && defined(__glibcxx_want_to_address) */ #undef __glibcxx_want_to_address -// from version.def line 1001 +// from version.def line 1010 #if !defined(__cpp_lib_to_array) # if (__cplusplus >= 202002L) && (__cpp_generic_lambdas >= 201707L) # define __glibcxx_to_array 201907L @@ -1231,7 +1242,7 @@ #endif /* !defined(__cpp_lib_to_array) && defined(__glibcxx_want_to_array) */ #undef __glibcxx_want_to_array -// from version.def line 1010 +// from version.def line 1019 #if !defined(__cpp_lib_type_identity) # if (__cplusplus >= 202002L) # define __glibcxx_type_identity 201806L @@ -1242,7 +1253,7 @@ #endif /* !defined(__cpp_lib_type_identity) && defined(__glibcxx_want_type_identity) */ #undef __glibcxx_want_type_identity -// from version.def line 1018 +// from version.def line 1027 #if !defined(__cpp_lib_unwrap_ref) # if (__cplusplus >= 202002L) # define __glibcxx_unwrap_ref 201811L @@ -1253,7 +1264,7 @@ #endif /* !defined(__cpp_lib_unwrap_ref) && defined(__glibcxx_want_unwrap_ref) */ #undef __glibcxx_want_unwrap_ref -// from version.def line 1026 +// from version.def line 1035 #if !defined(__cpp_lib_constexpr_iterator) # if (__cplusplus >= 202002L) # define __glibcxx_constexpr_iterator 201811L @@ -1264,7 +1275,7 @@ #endif /* !defined(__cpp_lib_constexpr_iterator) && defined(__glibcxx_want_constexpr_iterator) */ #undef __glibcxx_want_constexpr_iterator -// from version.def line 1034 +// from version.def line 1043 #if !defined(__cpp_lib_interpolate) # if (__cplusplus >= 202002L) # define __glibcxx_interpolate 201902L @@ -1275,7 +1286,7 @@ #endif /* !defined(__cpp_lib_interpolate) && defined(__glibcxx_want_interpolate) */ #undef __glibcxx_want_interpolate -// from version.def line 1042 +// from version.def line 1051 #if !defined(__cpp_lib_constexpr_utility) # if (__cplusplus >= 202002L) # define __glibcxx_constexpr_utility 201811L @@ -1286,7 +1297,7 @@ #endif /* !defined(__cpp_lib_constexpr_utility) && defined(__glibcxx_want_constexpr_utility) */ #undef __glibcxx_want_constexpr_utility -// from version.def line 1050 +// from version.def line 1059 #if !defined(__cpp_lib_shift) # if (__cplusplus >= 202002L) # define __glibcxx_shift 201806L @@ -1297,7 +1308,7 @@ #endif /* !defined(__cpp_lib_shift) && defined(__glibcxx_want_shift) */ #undef __glibcxx_want_shift -// from version.def line 1058 +// from version.def line 1067 #if !defined(__cpp_lib_ranges) # if (__cplusplus >= 202100L) && (__glibcxx_concepts) # define __glibcxx_ranges 202211L @@ -1313,7 +1324,7 @@ #endif /* !defined(__cpp_lib_ranges) && defined(__glibcxx_want_ranges) */ #undef __glibcxx_want_ranges -// from version.def line 1072 +// from version.def line 1081 #if !defined(__cpp_lib_constexpr_numeric) # if (__cplusplus >= 202002L) # define __glibcxx_constexpr_numeric 201911L @@ -1324,7 +1335,7 @@ #endif /* !defined(__cpp_lib_constexpr_numeric) && defined(__glibcxx_want_constexpr_numeric) */ #undef __glibcxx_want_constexpr_numeric -// from version.def line 1080 +// from version.def line 1089 #if !defined(__cpp_lib_constexpr_functional) # if (__cplusplus >= 202002L) # define __glibcxx_constexpr_functional 201907L @@ -1335,7 +1346,7 @@ #endif /* !defined(__cpp_lib_constexpr_functional) && defined(__glibcxx_want_constexpr_functional) */ #undef __glibcxx_want_constexpr_functional -// from version.def line 1088 +// from version.def line 1097 #if !defined(__cpp_lib_constexpr_algorithms) # if (__cplusplus >= 202002L) # define __glibcxx_constexpr_algorithms 201806L @@ -1346,7 +1357,7 @@ #endif /* !defined(__cpp_lib_constexpr_algorithms) && defined(__glibcxx_want_constexpr_algorithms) */ #undef __glibcxx_want_constexpr_algorithms -// from version.def line 1096 +// from version.def line 1105 #if !defined(__cpp_lib_constexpr_tuple) # if (__cplusplus >= 202002L) # define __glibcxx_constexpr_tuple 201811L @@ -1357,7 +1368,7 @@ #endif /* !defined(__cpp_lib_constexpr_tuple) && defined(__glibcxx_want_constexpr_tuple) */ #undef __glibcxx_want_constexpr_tuple -// from version.def line 1104 +// from version.def line 1113 #if !defined(__cpp_lib_constexpr_memory) # if (__cplusplus >= 202100L) && (__cpp_constexpr_dynamic_alloc) # define __glibcxx_constexpr_memory 202202L @@ -1373,7 +1384,7 @@ #endif /* !defined(__cpp_lib_constexpr_memory) && defined(__glibcxx_want_constexpr_memory) */ #undef __glibcxx_want_constexpr_memory -// from version.def line 1117 +// from version.def line 1126 #if !defined(__cpp_lib_atomic_shared_ptr) # if (__cplusplus >= 202002L) && _GLIBCXX_HOSTED # define __glibcxx_atomic_shared_ptr 201711L @@ -1384,7 +1395,7 @@ #endif /* !defined(__cpp_lib_atomic_shared_ptr) && defined(__glibcxx_want_atomic_shared_ptr) */ #undef __glibcxx_want_atomic_shared_ptr -// from version.def line 1126 +// from version.def line 1135 #if !defined(__cpp_lib_atomic_wait) # if (__cplusplus >= 202002L) && defined(_GLIBCXX_HAS_GTHREADS) && _GLIBCXX_HOSTED # define __glibcxx_atomic_wait 201907L @@ -1400,7 +1411,7 @@ #endif /* !defined(__cpp_lib_atomic_wait) && defined(__glibcxx_want_atomic_wait) */ #undef __glibcxx_want_atomic_wait -// from version.def line 1144 +// from version.def line 1153 #if !defined(__cpp_lib_barrier) # if (__cplusplus >= 202002L) && (__cpp_aligned_new && __glibcxx_atomic_wait) # define __glibcxx_barrier 201907L @@ -1411,7 +1422,7 @@ #endif /* !defined(__cpp_lib_barrier) && defined(__glibcxx_want_barrier) */ #undef __glibcxx_want_barrier -// from version.def line 1161 +// from version.def line 1170 #if !defined(__cpp_lib_format) # if (__cplusplus >= 202002L) && _GLIBCXX_HOSTED # define __glibcxx_format 202110L @@ -1422,7 +1433,7 @@ #endif /* !defined(__cpp_lib_format) && defined(__glibcxx_want_format) */ #undef __glibcxx_want_format -// from version.def line 1170 +// from version.def line 1179 #if !defined(__cpp_lib_format_uchar) # if (__cplusplus >= 202002L) && _GLIBCXX_HOSTED # define __glibcxx_format_uchar 202311L @@ -1433,7 +1444,7 @@ #endif /* !defined(__cpp_lib_format_uchar) && defined(__glibcxx_want_format_uchar) */ #undef __glibcxx_want_format_uchar -// from version.def line 1181 +// from version.def line 1190 #if !defined(__cpp_lib_constexpr_complex) # if (__cplusplus >= 202002L) && _GLIBCXX_HOSTED # define __glibcxx_constexpr_complex 201711L @@ -1444,7 +1455,7 @@ #endif /* !defined(__cpp_lib_constexpr_complex) && defined(__glibcxx_want_constexpr_complex) */ #undef __glibcxx_want_constexpr_complex -// from version.def line 1190 +// from version.def line 1199 #if !defined(__cpp_lib_constexpr_dynamic_alloc) # if (__cplusplus >= 202002L) && _GLIBCXX_HOSTED # define __glibcxx_constexpr_dynamic_alloc 201907L @@ -1455,7 +1466,7 @@ #endif /* !defined(__cpp_lib_constexpr_dynamic_alloc) && defined(__glibcxx_want_constexpr_dynamic_alloc) */ #undef __glibcxx_want_constexpr_dynamic_alloc -// from version.def line 1199 +// from version.def line 1208 #if !defined(__cpp_lib_constexpr_string) # if (__cplusplus >= 202002L) && _GLIBCXX_USE_CXX11_ABI && _GLIBCXX_HOSTED && (defined(__glibcxx_is_constant_evaluated)) # define __glibcxx_constexpr_string 201907L @@ -1476,7 +1487,7 @@ #endif /* !defined(__cpp_lib_constexpr_string) && defined(__glibcxx_want_constexpr_string) */ #undef __glibcxx_want_constexpr_string -// from version.def line 1223 +// from version.def line 1232 #if !defined(__cpp_lib_constexpr_vector) # if (__cplusplus >= 202002L) && _GLIBCXX_HOSTED # define __glibcxx_constexpr_vector 201907L @@ -1487,7 +1498,7 @@ #endif /* !defined(__cpp_lib_constexpr_vector) && defined(__glibcxx_want_constexpr_vector) */ #undef __glibcxx_want_constexpr_vector -// from version.def line 1232 +// from version.def line 1241 #if !defined(__cpp_lib_erase_if) # if (__cplusplus >= 202002L) && _GLIBCXX_HOSTED # define __glibcxx_erase_if 202002L @@ -1498,7 +1509,7 @@ #endif /* !defined(__cpp_lib_erase_if) && defined(__glibcxx_want_erase_if) */ #undef __glibcxx_want_erase_if -// from version.def line 1241 +// from version.def line 1250 #if !defined(__cpp_lib_generic_unordered_lookup) # if (__cplusplus >= 202002L) && _GLIBCXX_HOSTED # define __glibcxx_generic_unordered_lookup 201811L @@ -1509,7 +1520,7 @@ #endif /* !defined(__cpp_lib_generic_unordered_lookup) && defined(__glibcxx_want_generic_unordered_lookup) */ #undef __glibcxx_want_generic_unordered_lookup -// from version.def line 1250 +// from version.def line 1259 #if !defined(__cpp_lib_jthread) # if (__cplusplus >= 202002L) && defined(_GLIBCXX_HAS_GTHREADS) && _GLIBCXX_HOSTED # define __glibcxx_jthread 201911L @@ -1520,7 +1531,7 @@ #endif /* !defined(__cpp_lib_jthread) && defined(__glibcxx_want_jthread) */ #undef __glibcxx_want_jthread -// from version.def line 1260 +// from version.def line 1269 #if !defined(__cpp_lib_latch) # if (__cplusplus >= 202002L) && (__glibcxx_atomic_wait) # define __glibcxx_latch 201907L @@ -1531,7 +1542,7 @@ #endif /* !defined(__cpp_lib_latch) && defined(__glibcxx_want_latch) */ #undef __glibcxx_want_latch -// from version.def line 1269 +// from version.def line 1278 #if !defined(__cpp_lib_list_remove_return_type) # if (__cplusplus >= 202002L) && _GLIBCXX_HOSTED # define __glibcxx_list_remove_return_type 201806L @@ -1542,7 +1553,7 @@ #endif /* !defined(__cpp_lib_list_remove_return_type) && defined(__glibcxx_want_list_remove_return_type) */ #undef __glibcxx_want_list_remove_return_type -// from version.def line 1278 +// from version.def line 1287 #if !defined(__cpp_lib_polymorphic_allocator) # if (__cplusplus >= 202002L) && _GLIBCXX_HOSTED # define __glibcxx_polymorphic_allocator 201902L @@ -1553,7 +1564,7 @@ #endif /* !defined(__cpp_lib_polymorphic_allocator) && defined(__glibcxx_want_polymorphic_allocator) */ #undef __glibcxx_want_polymorphic_allocator -// from version.def line 1287 +// from version.def line 1296 #if !defined(__cpp_lib_move_iterator_concept) # if (__cplusplus >= 202002L) && (__glibcxx_concepts) # define __glibcxx_move_iterator_concept 202207L @@ -1564,7 +1575,7 @@ #endif /* !defined(__cpp_lib_move_iterator_concept) && defined(__glibcxx_want_move_iterator_concept) */ #undef __glibcxx_want_move_iterator_concept -// from version.def line 1297 +// from version.def line 1306 #if !defined(__cpp_lib_semaphore) # if (__cplusplus >= 202002L) && _GLIBCXX_HOSTED && (__glibcxx_atomic_wait || _GLIBCXX_HAVE_POSIX_SEMAPHORE) # define __glibcxx_semaphore 201907L @@ -1575,7 +1586,7 @@ #endif /* !defined(__cpp_lib_semaphore) && defined(__glibcxx_want_semaphore) */ #undef __glibcxx_want_semaphore -// from version.def line 1307 +// from version.def line 1316 #if !defined(__cpp_lib_smart_ptr_for_overwrite) # if (__cplusplus >= 202002L) && _GLIBCXX_HOSTED # define __glibcxx_smart_ptr_for_overwrite 202002L @@ -1586,7 +1597,7 @@ #endif /* !defined(__cpp_lib_smart_ptr_for_overwrite) && defined(__glibcxx_want_smart_ptr_for_overwrite) */ #undef __glibcxx_want_smart_ptr_for_overwrite -// from version.def line 1316 +// from version.def line 1325 #if !defined(__cpp_lib_syncbuf) # if (__cplusplus >= 202002L) && _GLIBCXX_USE_CXX11_ABI && _GLIBCXX_HOSTED # define __glibcxx_syncbuf 201803L @@ -1597,7 +1608,7 @@ #endif /* !defined(__cpp_lib_syncbuf) && defined(__glibcxx_want_syncbuf) */ #undef __glibcxx_want_syncbuf -// from version.def line 1326 +// from version.def line 1335 #if !defined(__cpp_lib_byteswap) # if (__cplusplus >= 202100L) # define __glibcxx_byteswap 202110L @@ -1608,7 +1619,7 @@ #endif /* !defined(__cpp_lib_byteswap) && defined(__glibcxx_want_byteswap) */ #undef __glibcxx_want_byteswap -// from version.def line 1334 +// from version.def line 1343 #if !defined(__cpp_lib_constexpr_charconv) # if (__cplusplus >= 202100L) # define __glibcxx_constexpr_charconv 202207L @@ -1619,7 +1630,7 @@ #endif /* !defined(__cpp_lib_constexpr_charconv) && defined(__glibcxx_want_constexpr_charconv) */ #undef __glibcxx_want_constexpr_charconv -// from version.def line 1342 +// from version.def line 1351 #if !defined(__cpp_lib_constexpr_typeinfo) # if (__cplusplus >= 202100L) # define __glibcxx_constexpr_typeinfo 202106L @@ -1630,7 +1641,7 @@ #endif /* !defined(__cpp_lib_constexpr_typeinfo) && defined(__glibcxx_want_constexpr_typeinfo) */ #undef __glibcxx_want_constexpr_typeinfo -// from version.def line 1350 +// from version.def line 1359 #if !defined(__cpp_lib_expected) # if (__cplusplus >= 202100L) && (__cpp_concepts >= 202002L) # define __glibcxx_expected 202211L @@ -1641,7 +1652,7 @@ #endif /* !defined(__cpp_lib_expected) && defined(__glibcxx_want_expected) */ #undef __glibcxx_want_expected -// from version.def line 1359 +// from version.def line 1368 #if !defined(__cpp_lib_freestanding_algorithm) # if (__cplusplus >= 202100L) # define __glibcxx_freestanding_algorithm 202311L @@ -1652,7 +1663,7 @@ #endif /* !defined(__cpp_lib_freestanding_algorithm) && defined(__glibcxx_want_freestanding_algorithm) */ #undef __glibcxx_want_freestanding_algorithm -// from version.def line 1368 +// from version.def line 1377 #if !defined(__cpp_lib_freestanding_array) # if (__cplusplus >= 202100L) # define __glibcxx_freestanding_array 202311L @@ -1663,7 +1674,7 @@ #endif /* !defined(__cpp_lib_freestanding_array) && defined(__glibcxx_want_freestanding_array) */ #undef __glibcxx_want_freestanding_array -// from version.def line 1377 +// from version.def line 1386 #if !defined(__cpp_lib_freestanding_cstring) # if (__cplusplus >= 202100L) # define __glibcxx_freestanding_cstring 202311L @@ -1674,7 +1685,7 @@ #endif /* !defined(__cpp_lib_freestanding_cstring) && defined(__glibcxx_want_freestanding_cstring) */ #undef __glibcxx_want_freestanding_cstring -// from version.def line 1386 +// from version.def line 1395 #if !defined(__cpp_lib_freestanding_expected) # if (__cplusplus >= 202100L) && (__cpp_lib_expected) # define __glibcxx_freestanding_expected 202311L @@ -1685,7 +1696,7 @@ #endif /* !defined(__cpp_lib_freestanding_expected) && defined(__glibcxx_want_freestanding_expected) */ #undef __glibcxx_want_freestanding_expected -// from version.def line 1396 +// from version.def line 1405 #if !defined(__cpp_lib_freestanding_optional) # if (__cplusplus >= 202100L) # define __glibcxx_freestanding_optional 202311L @@ -1696,7 +1707,7 @@ #endif /* !defined(__cpp_lib_freestanding_optional) && defined(__glibcxx_want_freestanding_optional) */ #undef __glibcxx_want_freestanding_optional -// from version.def line 1405 +// from version.def line 1414 #if !defined(__cpp_lib_freestanding_string_view) # if (__cplusplus >= 202100L) # define __glibcxx_freestanding_string_view 202311L @@ -1707,7 +1718,7 @@ #endif /* !defined(__cpp_lib_freestanding_string_view) && defined(__glibcxx_want_freestanding_string_view) */ #undef __glibcxx_want_freestanding_string_view -// from version.def line 1414 +// from version.def line 1423 #if !defined(__cpp_lib_freestanding_variant) # if (__cplusplus >= 202100L) # define __glibcxx_freestanding_variant 202311L @@ -1718,7 +1729,7 @@ #endif /* !defined(__cpp_lib_freestanding_variant) && defined(__glibcxx_want_freestanding_variant) */ #undef __glibcxx_want_freestanding_variant -// from version.def line 1423 +// from version.def line 1432 #if !defined(__cpp_lib_invoke_r) # if (__cplusplus >= 202100L) # define __glibcxx_invoke_r 202106L @@ -1729,7 +1740,7 @@ #endif /* !defined(__cpp_lib_invoke_r) && defined(__glibcxx_want_invoke_r) */ #undef __glibcxx_want_invoke_r -// from version.def line 1431 +// from version.def line 1440 #if !defined(__cpp_lib_is_scoped_enum) # if (__cplusplus >= 202100L) # define __glibcxx_is_scoped_enum 202011L @@ -1740,7 +1751,7 @@ #endif /* !defined(__cpp_lib_is_scoped_enum) && defined(__glibcxx_want_is_scoped_enum) */ #undef __glibcxx_want_is_scoped_enum -// from version.def line 1439 +// from version.def line 1448 #if !defined(__cpp_lib_reference_from_temporary) # if (__cplusplus >= 202100L) && (__has_builtin(__reference_constructs_from_temporary) && __has_builtin(__reference_converts_from_temporary)) # define __glibcxx_reference_from_temporary 202202L @@ -1751,7 +1762,7 @@ #endif /* !defined(__cpp_lib_reference_from_temporary) && defined(__glibcxx_want_reference_from_temporary) */ #undef __glibcxx_want_reference_from_temporary -// from version.def line 1459 +// from version.def line 1468 #if !defined(__cpp_lib_ranges_to_container) # if (__cplusplus >= 202100L) && _GLIBCXX_HOSTED # define __glibcxx_ranges_to_container 202202L @@ -1762,7 +1773,7 @@ #endif /* !defined(__cpp_lib_ranges_to_container) && defined(__glibcxx_want_ranges_to_container) */ #undef __glibcxx_want_ranges_to_container -// from version.def line 1468 +// from version.def line 1477 #if !defined(__cpp_lib_ranges_zip) # if (__cplusplus >= 202100L) # define __glibcxx_ranges_zip 202110L @@ -1773,7 +1784,7 @@ #endif /* !defined(__cpp_lib_ranges_zip) && defined(__glibcxx_want_ranges_zip) */ #undef __glibcxx_want_ranges_zip -// from version.def line 1476 +// from version.def line 1485 #if !defined(__cpp_lib_ranges_chunk) # if (__cplusplus >= 202100L) # define __glibcxx_ranges_chunk 202202L @@ -1784,7 +1795,7 @@ #endif /* !defined(__cpp_lib_ranges_chunk) && defined(__glibcxx_want_ranges_chunk) */ #undef __glibcxx_want_ranges_chunk -// from version.def line 1484 +// from version.def line 1493 #if !defined(__cpp_lib_ranges_slide) # if (__cplusplus >= 202100L) # define __glibcxx_ranges_slide 202202L @@ -1795,7 +1806,7 @@ #endif /* !defined(__cpp_lib_ranges_slide) && defined(__glibcxx_want_ranges_slide) */ #undef __glibcxx_want_ranges_slide -// from version.def line 1492 +// from version.def line 1501 #if !defined(__cpp_lib_ranges_chunk_by) # if (__cplusplus >= 202100L) # define __glibcxx_ranges_chunk_by 202202L @@ -1806,7 +1817,7 @@ #endif /* !defined(__cpp_lib_ranges_chunk_by) && defined(__glibcxx_want_ranges_chunk_by) */ #undef __glibcxx_want_ranges_chunk_by -// from version.def line 1500 +// from version.def line 1509 #if !defined(__cpp_lib_ranges_join_with) # if (__cplusplus >= 202100L) # define __glibcxx_ranges_join_with 202202L @@ -1817,7 +1828,7 @@ #endif /* !defined(__cpp_lib_ranges_join_with) && defined(__glibcxx_want_ranges_join_with) */ #undef __glibcxx_want_ranges_join_with -// from version.def line 1508 +// from version.def line 1517 #if !defined(__cpp_lib_ranges_repeat) # if (__cplusplus >= 202100L) # define __glibcxx_ranges_repeat 202207L @@ -1828,7 +1839,7 @@ #endif /* !defined(__cpp_lib_ranges_repeat) && defined(__glibcxx_want_ranges_repeat) */ #undef __glibcxx_want_ranges_repeat -// from version.def line 1516 +// from version.def line 1525 #if !defined(__cpp_lib_ranges_stride) # if (__cplusplus >= 202100L) # define __glibcxx_ranges_stride 202207L @@ -1839,7 +1850,7 @@ #endif /* !defined(__cpp_lib_ranges_stride) && defined(__glibcxx_want_ranges_stride) */ #undef __glibcxx_want_ranges_stride -// from version.def line 1524 +// from version.def line 1533 #if !defined(__cpp_lib_ranges_cartesian_product) # if (__cplusplus >= 202100L) # define __glibcxx_ranges_cartesian_product 202207L @@ -1850,7 +1861,7 @@ #endif /* !defined(__cpp_lib_ranges_cartesian_product) && defined(__glibcxx_want_ranges_cartesian_product) */ #undef __glibcxx_want_ranges_cartesian_product -// from version.def line 1532 +// from version.def line 1541 #if !defined(__cpp_lib_ranges_as_rvalue) # if (__cplusplus >= 202100L) # define __glibcxx_ranges_as_rvalue 202207L @@ -1861,18 +1872,18 @@ #endif /* !defined(__cpp_lib_ranges_as_rvalue) && defined(__glibcxx_want_ranges_as_rvalue) */ #undef __glibcxx_want_ranges_as_rvalue -// from version.def line 1540 +// from version.def line 1549 #if !defined(__cpp_lib_ranges_as_const) # if (__cplusplus >= 202100L) -# define __glibcxx_ranges_as_const 202207L +# define __glibcxx_ranges_as_const 202311L # if defined(__glibcxx_want_all) || defined(__glibcxx_want_ranges_as_const) -# define __cpp_lib_ranges_as_const 202207L +# define __cpp_lib_ranges_as_const 202311L # endif # endif #endif /* !defined(__cpp_lib_ranges_as_const) && defined(__glibcxx_want_ranges_as_const) */ #undef __glibcxx_want_ranges_as_const -// from version.def line 1548 +// from version.def line 1557 #if !defined(__cpp_lib_ranges_enumerate) # if (__cplusplus >= 202100L) # define __glibcxx_ranges_enumerate 202302L @@ -1883,7 +1894,7 @@ #endif /* !defined(__cpp_lib_ranges_enumerate) && defined(__glibcxx_want_ranges_enumerate) */ #undef __glibcxx_want_ranges_enumerate -// from version.def line 1556 +// from version.def line 1565 #if !defined(__cpp_lib_ranges_fold) # if (__cplusplus >= 202100L) # define __glibcxx_ranges_fold 202207L @@ -1894,7 +1905,7 @@ #endif /* !defined(__cpp_lib_ranges_fold) && defined(__glibcxx_want_ranges_fold) */ #undef __glibcxx_want_ranges_fold -// from version.def line 1564 +// from version.def line 1573 #if !defined(__cpp_lib_ranges_contains) # if (__cplusplus >= 202100L) # define __glibcxx_ranges_contains 202207L @@ -1905,7 +1916,7 @@ #endif /* !defined(__cpp_lib_ranges_contains) && defined(__glibcxx_want_ranges_contains) */ #undef __glibcxx_want_ranges_contains -// from version.def line 1572 +// from version.def line 1581 #if !defined(__cpp_lib_ranges_iota) # if (__cplusplus >= 202100L) # define __glibcxx_ranges_iota 202202L @@ -1916,7 +1927,7 @@ #endif /* !defined(__cpp_lib_ranges_iota) && defined(__glibcxx_want_ranges_iota) */ #undef __glibcxx_want_ranges_iota -// from version.def line 1580 +// from version.def line 1589 #if !defined(__cpp_lib_ranges_find_last) # if (__cplusplus >= 202100L) # define __glibcxx_ranges_find_last 202207L @@ -1927,7 +1938,7 @@ #endif /* !defined(__cpp_lib_ranges_find_last) && defined(__glibcxx_want_ranges_find_last) */ #undef __glibcxx_want_ranges_find_last -// from version.def line 1588 +// from version.def line 1597 #if !defined(__cpp_lib_constexpr_bitset) # if (__cplusplus >= 202100L) && _GLIBCXX_HOSTED && (__cpp_constexpr_dynamic_alloc) # define __glibcxx_constexpr_bitset 202202L @@ -1938,7 +1949,7 @@ #endif /* !defined(__cpp_lib_constexpr_bitset) && defined(__glibcxx_want_constexpr_bitset) */ #undef __glibcxx_want_constexpr_bitset -// from version.def line 1598 +// from version.def line 1607 #if !defined(__cpp_lib_stdatomic_h) # if (__cplusplus >= 202100L) # define __glibcxx_stdatomic_h 202011L @@ -1949,7 +1960,7 @@ #endif /* !defined(__cpp_lib_stdatomic_h) && defined(__glibcxx_want_stdatomic_h) */ #undef __glibcxx_want_stdatomic_h -// from version.def line 1606 +// from version.def line 1615 #if !defined(__cpp_lib_adaptor_iterator_pair_constructor) # if (__cplusplus >= 202100L) && _GLIBCXX_HOSTED # define __glibcxx_adaptor_iterator_pair_constructor 202106L @@ -1960,7 +1971,7 @@ #endif /* !defined(__cpp_lib_adaptor_iterator_pair_constructor) && defined(__glibcxx_want_adaptor_iterator_pair_constructor) */ #undef __glibcxx_want_adaptor_iterator_pair_constructor -// from version.def line 1615 +// from version.def line 1624 #if !defined(__cpp_lib_formatters) # if (__cplusplus >= 202100L) && _GLIBCXX_HOSTED # define __glibcxx_formatters 202302L @@ -1971,7 +1982,7 @@ #endif /* !defined(__cpp_lib_formatters) && defined(__glibcxx_want_formatters) */ #undef __glibcxx_want_formatters -// from version.def line 1624 +// from version.def line 1633 #if !defined(__cpp_lib_forward_like) # if (__cplusplus >= 202100L) # define __glibcxx_forward_like 202207L @@ -1982,7 +1993,7 @@ #endif /* !defined(__cpp_lib_forward_like) && defined(__glibcxx_want_forward_like) */ #undef __glibcxx_want_forward_like -// from version.def line 1632 +// from version.def line 1641 #if !defined(__cpp_lib_ios_noreplace) # if (__cplusplus >= 202100L) && _GLIBCXX_HOSTED # define __glibcxx_ios_noreplace 202207L @@ -1993,7 +2004,7 @@ #endif /* !defined(__cpp_lib_ios_noreplace) && defined(__glibcxx_want_ios_noreplace) */ #undef __glibcxx_want_ios_noreplace -// from version.def line 1641 +// from version.def line 1650 #if !defined(__cpp_lib_move_only_function) # if (__cplusplus >= 202100L) && _GLIBCXX_HOSTED # define __glibcxx_move_only_function 202110L @@ -2004,7 +2015,7 @@ #endif /* !defined(__cpp_lib_move_only_function) && defined(__glibcxx_want_move_only_function) */ #undef __glibcxx_want_move_only_function -// from version.def line 1650 +// from version.def line 1659 #if !defined(__cpp_lib_out_ptr) # if (__cplusplus >= 202100L) # define __glibcxx_out_ptr 202311L @@ -2015,7 +2026,7 @@ #endif /* !defined(__cpp_lib_out_ptr) && defined(__glibcxx_want_out_ptr) */ #undef __glibcxx_want_out_ptr -// from version.def line 1658 +// from version.def line 1667 #if !defined(__cpp_lib_print) # if (__cplusplus >= 202100L) && _GLIBCXX_HOSTED # define __glibcxx_print 202211L @@ -2026,7 +2037,7 @@ #endif /* !defined(__cpp_lib_print) && defined(__glibcxx_want_print) */ #undef __glibcxx_want_print -// from version.def line 1667 +// from version.def line 1676 #if !defined(__cpp_lib_spanstream) # if (__cplusplus >= 202100L) && _GLIBCXX_HOSTED && (__glibcxx_span) # define __glibcxx_spanstream 202106L @@ -2037,7 +2048,7 @@ #endif /* !defined(__cpp_lib_spanstream) && defined(__glibcxx_want_spanstream) */ #undef __glibcxx_want_spanstream -// from version.def line 1677 +// from version.def line 1686 #if !defined(__cpp_lib_stacktrace) # if (__cplusplus >= 202100L) && _GLIBCXX_HOSTED && (_GLIBCXX_HAVE_STACKTRACE) # define __glibcxx_stacktrace 202011L @@ -2048,7 +2059,7 @@ #endif /* !defined(__cpp_lib_stacktrace) && defined(__glibcxx_want_stacktrace) */ #undef __glibcxx_want_stacktrace -// from version.def line 1687 +// from version.def line 1696 #if !defined(__cpp_lib_string_contains) # if (__cplusplus >= 202100L) && _GLIBCXX_HOSTED # define __glibcxx_string_contains 202011L @@ -2059,7 +2070,7 @@ #endif /* !defined(__cpp_lib_string_contains) && defined(__glibcxx_want_string_contains) */ #undef __glibcxx_want_string_contains -// from version.def line 1696 +// from version.def line 1705 #if !defined(__cpp_lib_string_resize_and_overwrite) # if (__cplusplus >= 202100L) && _GLIBCXX_HOSTED # define __glibcxx_string_resize_and_overwrite 202110L @@ -2070,7 +2081,7 @@ #endif /* !defined(__cpp_lib_string_resize_and_overwrite) && defined(__glibcxx_want_string_resize_and_overwrite) */ #undef __glibcxx_want_string_resize_and_overwrite -// from version.def line 1705 +// from version.def line 1714 #if !defined(__cpp_lib_to_underlying) # if (__cplusplus >= 202100L) # define __glibcxx_to_underlying 202102L @@ -2081,7 +2092,7 @@ #endif /* !defined(__cpp_lib_to_underlying) && defined(__glibcxx_want_to_underlying) */ #undef __glibcxx_want_to_underlying -// from version.def line 1713 +// from version.def line 1722 #if !defined(__cpp_lib_unreachable) # if (__cplusplus >= 202100L) # define __glibcxx_unreachable 202202L @@ -2092,7 +2103,7 @@ #endif /* !defined(__cpp_lib_unreachable) && defined(__glibcxx_want_unreachable) */ #undef __glibcxx_want_unreachable -// from version.def line 1721 +// from version.def line 1730 #if !defined(__cpp_lib_fstream_native_handle) # if (__cplusplus > 202302L) && _GLIBCXX_HOSTED # define __glibcxx_fstream_native_handle 202306L @@ -2103,7 +2114,7 @@ #endif /* !defined(__cpp_lib_fstream_native_handle) && defined(__glibcxx_want_fstream_native_handle) */ #undef __glibcxx_want_fstream_native_handle -// from version.def line 1730 +// from version.def line 1739 #if !defined(__cpp_lib_ratio) # if (__cplusplus > 202302L) # define __glibcxx_ratio 202306L @@ -2114,7 +2125,7 @@ #endif /* !defined(__cpp_lib_ratio) && defined(__glibcxx_want_ratio) */ #undef __glibcxx_want_ratio -// from version.def line 1738 +// from version.def line 1747 #if !defined(__cpp_lib_saturation_arithmetic) # if (__cplusplus > 202302L) # define __glibcxx_saturation_arithmetic 202311L @@ -2125,7 +2136,7 @@ #endif /* !defined(__cpp_lib_saturation_arithmetic) && defined(__glibcxx_want_saturation_arithmetic) */ #undef __glibcxx_want_saturation_arithmetic -// from version.def line 1746 +// from version.def line 1755 #if !defined(__cpp_lib_to_string) # if (__cplusplus > 202302L) && _GLIBCXX_HOSTED && (__glibcxx_to_chars) # define __glibcxx_to_string 202306L @@ -2136,7 +2147,7 @@ #endif /* !defined(__cpp_lib_to_string) && defined(__glibcxx_want_to_string) */ #undef __glibcxx_want_to_string -// from version.def line 1756 +// from version.def line 1765 #if !defined(__cpp_lib_generator) # if (__cplusplus >= 202100L) && (__glibcxx_coroutine) # define __glibcxx_generator 202207L diff --git a/libstdc++-v3/include/std/format b/libstdc++-v3/include/std/format index b3b5a0b..efc4a17 100644 --- a/libstdc++-v3/include/std/format +++ b/libstdc++-v3/include/std/format @@ -70,6 +70,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION // [format.context], class template basic_format_context template<typename _Out, typename _CharT> class basic_format_context; + // [format.fmt.string], class template basic_format_string + template<typename _CharT, typename... _Args> struct basic_format_string; + /// @cond undocumented namespace __format { @@ -83,7 +86,20 @@ namespace __format using __format_context = basic_format_context<_Sink_iter<_CharT>, _CharT>; template<typename _CharT> - struct _Runtime_format_string { basic_string_view<_CharT> _M_str; }; + struct _Runtime_format_string + { + [[__gnu__::__always_inline__]] + _Runtime_format_string(basic_string_view<_CharT> __s) noexcept + : _M_str(__s) { } + + _Runtime_format_string(const _Runtime_format_string&) = delete; + void operator=(const _Runtime_format_string&) = delete; + + private: + basic_string_view<_CharT> _M_str; + + template<typename, typename...> friend struct std::basic_format_string; + }; } // namespace __format /// @endcond @@ -104,8 +120,6 @@ namespace __format template<typename _Context> class basic_format_arg; - // [format.fmt.string], class template basic_format_string - /** A compile-time checked format string for the specified argument types. * * @since C++23 but available as an extension in C++20. @@ -119,7 +133,7 @@ namespace __format basic_format_string(const _Tp& __s); [[__gnu__::__always_inline__]] - basic_format_string(__format::_Runtime_format_string<_CharT>&& __s) + basic_format_string(__format::_Runtime_format_string<_CharT> __s) noexcept : _M_str(__s._M_str) { } @@ -144,14 +158,14 @@ namespace __format #if __cplusplus > 202302L [[__gnu__::__always_inline__]] inline __format::_Runtime_format_string<char> - runtime_format(string_view __fmt) - { return {__fmt}; } + runtime_format(string_view __fmt) noexcept + { return __fmt; } #ifdef _GLIBCXX_USE_WCHAR_T [[__gnu__::__always_inline__]] inline __format::_Runtime_format_string<wchar_t> - runtime_format(wstring_view __fmt) - { return {__fmt}; } + runtime_format(wstring_view __fmt) noexcept + { return __fmt; } #endif #endif // C++26 @@ -3175,8 +3189,7 @@ namespace __format // Format as const if possible, to reduce instantiations. template<typename _Tp> using __maybe_const_t - = __conditional_t<__format::__formattable_with<_Tp, _Context>, - const _Tp, _Tp>; + = __conditional_t<__formattable<_Tp>, const _Tp, _Tp>; template<typename _Tq> static void @@ -3194,7 +3207,7 @@ namespace __format explicit handle(_Tp& __val) noexcept { - if constexpr (!__format::__formattable_with<const _Tp, _Context>) + if constexpr (!__formattable<const _Tp>) static_assert(!is_const_v<_Tp>, "std::format argument must be " "non-const for this type"); @@ -3652,12 +3665,9 @@ namespace __format friend std::basic_format_args<_Context>; template<typename _Ctx, typename... _Argz> - friend auto + friend auto std:: #if _GLIBCXX_INLINE_VERSION - // Needed for PR c++/59526 - std::__8:: -#else - std:: + __8:: // Needed for PR c++/59256 #endif make_format_args(_Argz&...) noexcept; diff --git a/libstdc++-v3/include/std/functional b/libstdc++-v3/include/std/functional index 8d50a73..e02be00 100644 --- a/libstdc++-v3/include/std/functional +++ b/libstdc++-v3/include/std/functional @@ -76,6 +76,7 @@ #define __glibcxx_want_boyer_moore_searcher #define __glibcxx_want_bind_front +#define __glibcxx_want_bind_back #define __glibcxx_want_constexpr_functional #define __glibcxx_want_invoke #define __glibcxx_want_invoke_r @@ -934,12 +935,18 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION _M_bound_args(std::forward<_Args>(__args)...) { static_assert(sizeof...(_Args) == sizeof...(_BoundArgs)); } - _Bind_front(const _Bind_front&) = default; - _Bind_front(_Bind_front&&) = default; - _Bind_front& operator=(const _Bind_front&) = default; - _Bind_front& operator=(_Bind_front&&) = default; - ~_Bind_front() = default; - +#if __cpp_explicit_this_parameter + template<typename _Self, typename... _CallArgs> + constexpr + invoke_result_t<__like_t<_Self, _Fd>, __like_t<_Self, _BoundArgs>..., _CallArgs...> + operator()(this _Self&& __self, _CallArgs&&... __call_args) + noexcept(is_nothrow_invocable_v<__like_t<_Self, _Fd>, + __like_t<_Self, _BoundArgs>..., _CallArgs...>) + { + return _S_call(std::forward<_Self>(__self), _BoundIndices(), + std::forward<_CallArgs>(__call_args)...); + } +#else template<typename... _CallArgs> requires true constexpr @@ -997,6 +1004,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION template<typename... _CallArgs> void operator()(_CallArgs&&...) const && = delete; +#endif private: using _BoundIndices = index_sequence_for<_BoundArgs...>; @@ -1038,6 +1046,75 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION } #endif // __cpp_lib_bind_front +#ifdef __cpp_lib_bind_back // C++ >= 23 + template<typename _Fd, typename... _BoundArgs> + struct _Bind_back + { + static_assert(is_move_constructible_v<_Fd>); + static_assert((is_move_constructible_v<_BoundArgs> && ...)); + + // First parameter is to ensure this constructor is never used + // instead of the copy/move constructor. + template<typename _Fn, typename... _Args> + explicit constexpr + _Bind_back(int, _Fn&& __fn, _Args&&... __args) + noexcept(__and_<is_nothrow_constructible<_Fd, _Fn>, + is_nothrow_constructible<_BoundArgs, _Args>...>::value) + : _M_fd(std::forward<_Fn>(__fn)), + _M_bound_args(std::forward<_Args>(__args)...) + { static_assert(sizeof...(_Args) == sizeof...(_BoundArgs)); } + + template<typename _Self, typename... _CallArgs> + constexpr + invoke_result_t<__like_t<_Self, _Fd>, _CallArgs..., __like_t<_Self, _BoundArgs>...> + operator()(this _Self&& __self, _CallArgs&&... __call_args) + noexcept(is_nothrow_invocable_v<__like_t<_Self, _Fd>, + _CallArgs..., __like_t<_Self, _BoundArgs>...>) + { + return _S_call(std::forward<_Self>(__self), _BoundIndices(), + std::forward<_CallArgs>(__call_args)...); + } + + private: + using _BoundIndices = index_sequence_for<_BoundArgs...>; + + template<typename _Tp, size_t... _Ind, typename... _CallArgs> + static constexpr + decltype(auto) + _S_call(_Tp&& __g, index_sequence<_Ind...>, _CallArgs&&... __call_args) + { + return std::invoke(std::forward<_Tp>(__g)._M_fd, + std::forward<_CallArgs>(__call_args)..., + std::get<_Ind>(std::forward<_Tp>(__g)._M_bound_args)...); + } + + [[no_unique_address]] _Fd _M_fd; + [[no_unique_address]] std::tuple<_BoundArgs...> _M_bound_args; + }; + + template<typename _Fn, typename... _Args> + using _Bind_back_t = _Bind_back<decay_t<_Fn>, decay_t<_Args>...>; + + /** Create call wrapper by partial application of arguments to function. + * + * The result of `std::bind_back(f, args...)` is a function object that + * stores `f` and the bound arguments, `args...`. When that function + * object is invoked with `call_args...` it returns the result of calling + * `f(call_args..., args...)`. + * + * @since C++23 + */ + template<typename _Fn, typename... _Args> + constexpr _Bind_back_t<_Fn, _Args...> + bind_back(_Fn&& __fn, _Args&&... __args) + noexcept(is_nothrow_constructible_v<_Bind_back_t<_Fn, _Args...>, + int, _Fn, _Args...>) + { + return _Bind_back_t<_Fn, _Args...>(0, std::forward<_Fn>(__fn), + std::forward<_Args>(__args)...); + } +#endif // __cpp_lib_bind_back + #if __cplusplus >= 201402L /// Generalized negator. template<typename _Fn> diff --git a/libstdc++-v3/include/std/ranges b/libstdc++-v3/include/std/ranges index 81a8575..3135e6f 100644 --- a/libstdc++-v3/include/std/ranges +++ b/libstdc++-v3/include/std/ranges @@ -59,7 +59,6 @@ #define __glibcxx_want_ranges_chunk_by #define __glibcxx_want_ranges_enumerate #define __glibcxx_want_ranges_iota -#define __glibcxx_want_ranges_iota #define __glibcxx_want_ranges_join_with #define __glibcxx_want_ranges_repeat #define __glibcxx_want_ranges_slide @@ -957,8 +956,11 @@ namespace views::__adaptor requires __is_range_adaptor_closure<_Lhs> && __is_range_adaptor_closure<_Rhs> constexpr auto - operator|(_Lhs __lhs, _Rhs __rhs) - { return _Pipe<_Lhs, _Rhs>{std::move(__lhs), std::move(__rhs)}; } + operator|(_Lhs&& __lhs, _Rhs&& __rhs) + { + return _Pipe<decay_t<_Lhs>, decay_t<_Rhs>>{std::forward<_Lhs>(__lhs), + std::forward<_Rhs>(__rhs)}; + } // The base class of every range adaptor non-closure. // @@ -981,7 +983,7 @@ namespace views::__adaptor constexpr auto operator()(_Args&&... __args) const { - return _Partial<_Derived, decay_t<_Args>...>{std::forward<_Args>(__args)...}; + return _Partial<_Derived, decay_t<_Args>...>{0, std::forward<_Args>(__args)...}; } }; @@ -1004,14 +1006,29 @@ namespace views::__adaptor { tuple<_Args...> _M_args; - constexpr - _Partial(_Args... __args) - : _M_args(std::move(__args)...) - { } + // First parameter is to ensure this constructor is never used + // instead of the copy/move constructor. + template<typename... _Ts> + constexpr + _Partial(int, _Ts&&... __args) + : _M_args(std::forward<_Ts>(__args)...) + { } // Invoke _Adaptor with arguments __r, _M_args... according to the // value category of this _Partial object. - // TODO: use explicit object functions ("deducing this"). +#if __cpp_explicit_this_parameter + template<typename _Self, typename _Range> + requires __adaptor_invocable<_Adaptor, _Range, __like_t<_Self, _Args>...> + constexpr auto + operator()(this _Self&& __self, _Range&& __r) + { + auto __forwarder = [&__r] (auto&&... __args) { + return _Adaptor{}(std::forward<_Range>(__r), + std::forward<decltype(__args)>(__args)...); + }; + return std::apply(__forwarder, std::forward<_Self>(__self)._M_args); + } +#else template<typename _Range> requires __adaptor_invocable<_Adaptor, _Range, const _Args&...> constexpr auto @@ -1037,6 +1054,7 @@ namespace views::__adaptor template<typename _Range> constexpr auto operator()(_Range&& __r) const && = delete; +#endif }; // A lightweight specialization of the above primary template for @@ -1046,11 +1064,19 @@ namespace views::__adaptor { _Arg _M_arg; - constexpr - _Partial(_Arg __arg) - : _M_arg(std::move(__arg)) - { } + template<typename _Tp> + constexpr + _Partial(int, _Tp&& __arg) + : _M_arg(std::forward<_Tp>(__arg)) + { } +#if __cpp_explicit_this_parameter + template<typename _Self, typename _Range> + requires __adaptor_invocable<_Adaptor, _Range, __like_t<_Self, _Arg>> + constexpr auto + operator()(this _Self&& __self, _Range&& __r) + { return _Adaptor{}(std::forward<_Range>(__r), std::forward<_Self>(__self)._M_arg); } +#else template<typename _Range> requires __adaptor_invocable<_Adaptor, _Range, const _Arg&> constexpr auto @@ -1066,6 +1092,7 @@ namespace views::__adaptor template<typename _Range> constexpr auto operator()(_Range&& __r) const && = delete; +#endif }; // Partial specialization of the primary template for the case where the extra @@ -1079,10 +1106,11 @@ namespace views::__adaptor { tuple<_Args...> _M_args; - constexpr - _Partial(_Args... __args) - : _M_args(std::move(__args)...) - { } + template<typename... _Ts> + constexpr + _Partial(int, _Ts&&... __args) + : _M_args(std::forward<_Ts>(__args)...) + { } // Invoke _Adaptor with arguments __r, const _M_args&... regardless // of the value category of this _Partial object. @@ -1109,10 +1137,11 @@ namespace views::__adaptor { _Arg _M_arg; - constexpr - _Partial(_Arg __arg) - : _M_arg(std::move(__arg)) - { } + template<typename _Tp> + constexpr + _Partial(int, _Tp&& __arg) + : _M_arg(std::forward<_Tp>(__arg)) + { } template<typename _Range> requires __adaptor_invocable<_Adaptor, _Range, const _Arg&> @@ -1135,14 +1164,25 @@ namespace views::__adaptor [[no_unique_address]] _Lhs _M_lhs; [[no_unique_address]] _Rhs _M_rhs; - constexpr - _Pipe(_Lhs __lhs, _Rhs __rhs) - : _M_lhs(std::move(__lhs)), _M_rhs(std::move(__rhs)) - { } + template<typename _Tp, typename _Up> + constexpr + _Pipe(_Tp&& __lhs, _Up&& __rhs) + : _M_lhs(std::forward<_Tp>(__lhs)), _M_rhs(std::forward<_Up>(__rhs)) + { } // Invoke _M_rhs(_M_lhs(__r)) according to the value category of this // range adaptor closure object. - // TODO: use explicit object functions ("deducing this"). +#if __cpp_explicit_this_parameter + template<typename _Self, typename _Range> + requires __pipe_invocable<__like_t<_Self, _Lhs>, __like_t<_Self, _Rhs>, _Range> + constexpr auto + operator()(this _Self&& __self, _Range&& __r) + { + return (std::forward<_Self>(__self)._M_rhs + (std::forward<_Self>(__self)._M_lhs + (std::forward<_Range>(__r)))); + } +#else template<typename _Range> requires __pipe_invocable<const _Lhs&, const _Rhs&, _Range> constexpr auto @@ -1158,6 +1198,7 @@ namespace views::__adaptor template<typename _Range> constexpr auto operator()(_Range&& __r) const && = delete; +#endif }; // A partial specialization of the above primary template for the case where @@ -1172,10 +1213,11 @@ namespace views::__adaptor [[no_unique_address]] _Lhs _M_lhs; [[no_unique_address]] _Rhs _M_rhs; - constexpr - _Pipe(_Lhs __lhs, _Rhs __rhs) - : _M_lhs(std::move(__lhs)), _M_rhs(std::move(__rhs)) - { } + template<typename _Tp, typename _Up> + constexpr + _Pipe(_Tp&& __lhs, _Up&& __rhs) + : _M_lhs(std::forward<_Tp>(__lhs)), _M_rhs(std::forward<_Up>(__rhs)) + { } template<typename _Range> requires __pipe_invocable<const _Lhs&, const _Rhs&, _Range> @@ -9427,7 +9469,7 @@ namespace __detail { using __detail::_To; using views::__adaptor::_Partial; - return _Partial<_To<_Cont>, decay_t<_Args>...>{std::forward<_Args>(__args)...}; + return _Partial<_To<_Cont>, decay_t<_Args>...>{0, std::forward<_Args>(__args)...}; } /// @cond undocumented @@ -9472,7 +9514,7 @@ namespace __detail { using __detail::_To2; using views::__adaptor::_Partial; - return _Partial<_To2<_Cont>, decay_t<_Args>...>{std::forward<_Args>(__args)...}; + return _Partial<_To2<_Cont>, decay_t<_Args>...>{0, std::forward<_Args>(__args)...}; } } // namespace ranges diff --git a/libstdc++-v3/include/std/tuple b/libstdc++-v3/include/std/tuple index 50e1184..2f6e419 100644 --- a/libstdc++-v3/include/std/tuple +++ b/libstdc++-v3/include/std/tuple @@ -752,7 +752,463 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION template<typename... _Elements> class tuple : public _Tuple_impl<0, _Elements...> { - typedef _Tuple_impl<0, _Elements...> _Inherited; + using _Inherited = _Tuple_impl<0, _Elements...>; + +#if __cpp_concepts && __cpp_consteval && __cpp_conditional_explicit // >= C++20 + template<typename... _UTypes> + static consteval bool + __constructible() + { + if constexpr (sizeof...(_UTypes) == sizeof...(_Elements)) + return __and_v<is_constructible<_Elements, _UTypes>...>; + else + return false; + } + + template<typename... _UTypes> + static consteval bool + __nothrow_constructible() + { + if constexpr (sizeof...(_UTypes) == sizeof...(_Elements)) + return __and_v<is_nothrow_constructible<_Elements, _UTypes>...>; + else + return false; + } + + template<typename... _UTypes> + static consteval bool + __convertible() + { + if constexpr (sizeof...(_UTypes) == sizeof...(_Elements)) + return __and_v<is_convertible<_UTypes, _Elements>...>; + else + return false; + } + + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 3121. tuple constructor constraints for UTypes&&... overloads + template<typename... _UTypes> + static consteval bool + __disambiguating_constraint() + { + if constexpr (sizeof...(_Elements) != sizeof...(_UTypes)) + return false; + else if constexpr (sizeof...(_Elements) == 1) + { + using _U0 = typename _Nth_type<0, _UTypes...>::type; + return !is_same_v<remove_cvref_t<_U0>, tuple>; + } + else if constexpr (sizeof...(_Elements) < 4) + { + using _U0 = typename _Nth_type<0, _UTypes...>::type; + if constexpr (!is_same_v<remove_cvref_t<_U0>, allocator_arg_t>) + return true; + else + { + using _T0 = typename _Nth_type<0, _Elements...>::type; + return is_same_v<remove_cvref_t<_T0>, allocator_arg_t>; + } + } + return true; + } + + // Return true iff sizeof...(Types) == 1 && tuple_size_v<TUPLE> == 1 + // and the single element in Types can be initialized from TUPLE, + // or is the same type as tuple_element_t<0, TUPLE>. + template<typename _Tuple> + static consteval bool + __use_other_ctor() + { + if constexpr (sizeof...(_Elements) != 1) + return false; + else if constexpr (is_same_v<remove_cvref_t<_Tuple>, tuple>) + return true; // Should use a copy/move constructor instead. + else + { + using _Tp = typename _Nth_type<0, _Elements...>::type; + if constexpr (is_convertible_v<_Tuple, _Tp>) + return true; + else if constexpr (is_constructible_v<_Tp, _Tuple>) + return true; + } + return false; + } + + template<typename... _Up> + static consteval bool + __dangles() + { +#if __has_builtin(__reference_constructs_from_temporary) + return (__reference_constructs_from_temporary(_Elements, _Up&&) + || ...); +#else + return false; +#endif + } + + public: + constexpr + explicit(!(__is_implicitly_default_constructible_v<_Elements> && ...)) + tuple() + noexcept((is_nothrow_default_constructible_v<_Elements> && ...)) + requires (is_default_constructible_v<_Elements> && ...) + : _Inherited() + { } + + constexpr explicit(!__convertible<const _Elements&...>()) + tuple(const _Elements&... __elements) + noexcept(__nothrow_constructible<const _Elements&...>()) + requires (__constructible<const _Elements&...>()) + : _Inherited(__elements...) + { } + + template<typename... _UTypes> + requires (__disambiguating_constraint<_UTypes...>()) + && (__constructible<_UTypes...>()) + && (!__dangles<_UTypes...>()) + constexpr explicit(!__convertible<_UTypes...>()) + tuple(_UTypes&&... __u) + noexcept(__nothrow_constructible<_UTypes...>()) + : _Inherited(std::forward<_UTypes>(__u)...) + { } + + template<typename... _UTypes> + requires (__disambiguating_constraint<_UTypes...>()) + && (__constructible<_UTypes...>()) + && (__dangles<_UTypes...>()) + tuple(_UTypes&&...) = delete; + + constexpr tuple(const tuple&) = default; + + constexpr tuple(tuple&&) = default; + + template<typename... _UTypes> + requires (__constructible<const _UTypes&...>()) + && (!__use_other_ctor<const tuple<_UTypes...>&>()) + && (!__dangles<const _UTypes&...>()) + constexpr explicit(!__convertible<const _UTypes&...>()) + tuple(const tuple<_UTypes...>& __u) + noexcept(__nothrow_constructible<const _UTypes&...>()) + : _Inherited(static_cast<const _Tuple_impl<0, _UTypes...>&>(__u)) + { } + + template<typename... _UTypes> + requires (__constructible<const _UTypes&...>()) + && (!__use_other_ctor<const tuple<_UTypes...>&>()) + && (__dangles<const _UTypes&...>()) + tuple(const tuple<_UTypes...>&) = delete; + + template<typename... _UTypes> + requires (__constructible<_UTypes...>()) + && (!__use_other_ctor<tuple<_UTypes...>>()) + && (!__dangles<_UTypes...>()) + constexpr explicit(!__convertible<_UTypes...>()) + tuple(tuple<_UTypes...>&& __u) + noexcept(__nothrow_constructible<_UTypes...>()) + : _Inherited(static_cast<_Tuple_impl<0, _UTypes...>&&>(__u)) + { } + + template<typename... _UTypes> + requires (__constructible<_UTypes...>()) + && (!__use_other_ctor<tuple<_UTypes...>>()) + && (__dangles<_UTypes...>()) + tuple(tuple<_UTypes...>&&) = delete; + +#if __cpp_lib_ranges_zip // >= C++23 + template<typename... _UTypes> + requires (__constructible<_UTypes&...>()) + && (!__use_other_ctor<tuple<_UTypes...>&>()) + && (!__dangles<_UTypes&...>()) + constexpr explicit(!__convertible<_UTypes&...>()) + tuple(tuple<_UTypes...>& __u) + noexcept(__nothrow_constructible<_UTypes&...>()) + : _Inherited(static_cast<_Tuple_impl<0, _UTypes...>&>(__u)) + { } + + template<typename... _UTypes> + requires (__constructible<_UTypes&...>()) + && (!__use_other_ctor<tuple<_UTypes...>&>()) + && (__dangles<_UTypes&...>()) + tuple(tuple<_UTypes...>&) = delete; + + template<typename... _UTypes> + requires (__constructible<const _UTypes...>()) + && (!__use_other_ctor<const tuple<_UTypes...>>()) + && (!__dangles<const _UTypes...>()) + constexpr explicit(!__convertible<const _UTypes...>()) + tuple(const tuple<_UTypes...>&& __u) + noexcept(__nothrow_constructible<const _UTypes...>()) + : _Inherited(static_cast<const _Tuple_impl<0, _UTypes...>&&>(__u)) + { } + + template<typename... _UTypes> + requires (__constructible<const _UTypes...>()) + && (!__use_other_ctor<const tuple<_UTypes...>>()) + && (__dangles<const _UTypes...>()) + tuple(const tuple<_UTypes...>&&) = delete; +#endif // C++23 + + template<typename _U1, typename _U2> + requires (sizeof...(_Elements) == 2) + && (__constructible<const _U1&, const _U2&>()) + && (!__dangles<const _U1&, const _U2&>()) + constexpr explicit(!__convertible<const _U1&, const _U2&>()) + tuple(const pair<_U1, _U2>& __u) + noexcept(__nothrow_constructible<const _U1&, const _U2&>()) + : _Inherited(__u.first, __u.second) + { } + + template<typename _U1, typename _U2> + requires (sizeof...(_Elements) == 2) + && (__constructible<const _U1&, const _U2&>()) + && (__dangles<const _U1&, const _U2&>()) + tuple(const pair<_U1, _U2>&) = delete; + + template<typename _U1, typename _U2> + requires (sizeof...(_Elements) == 2) + && (__constructible<_U1, _U2>()) + && (!__dangles<_U1, _U2>()) + constexpr explicit(!__convertible<_U1, _U2>()) + tuple(pair<_U1, _U2>&& __u) + noexcept(__nothrow_constructible<_U1, _U2>()) + : _Inherited(std::forward<_U1>(__u.first), + std::forward<_U2>(__u.second)) + { } + + template<typename _U1, typename _U2> + requires (sizeof...(_Elements) == 2) + && (__constructible<_U1, _U2>()) + && (__dangles<_U1, _U2>()) + tuple(pair<_U1, _U2>&&) = delete; + +#if __cpp_lib_ranges_zip // >= C++23 + template<typename _U1, typename _U2> + requires (sizeof...(_Elements) == 2) + && (__constructible<_U1&, _U2&>()) + && (!__dangles<_U1&, _U2&>()) + constexpr explicit(!__convertible<_U1&, _U2&>()) + tuple(pair<_U1, _U2>& __u) + noexcept(__nothrow_constructible<_U1&, _U2&>()) + : _Inherited(__u.first, __u.second) + { } + + template<typename _U1, typename _U2> + requires (sizeof...(_Elements) == 2) + && (__constructible<_U1&, _U2&>()) + && (__dangles<_U1&, _U2&>()) + tuple(pair<_U1, _U2>&) = delete; + + template<typename _U1, typename _U2> + requires (sizeof...(_Elements) == 2) + && (__constructible<const _U1, const _U2>()) + && (!__dangles<const _U1, const _U2>()) + constexpr explicit(!__convertible<const _U1, const _U2>()) + tuple(const pair<_U1, _U2>&& __u) + noexcept(__nothrow_constructible<const _U1, const _U2>()) + : _Inherited(std::forward<const _U1>(__u.first), + std::forward<const _U2>(__u.second)) + { } + + template<typename _U1, typename _U2> + requires (sizeof...(_Elements) == 2) + && (__constructible<const _U1, const _U2>()) + && (__dangles<const _U1, const _U2>()) + tuple(const pair<_U1, _U2>&&) = delete; +#endif // C++23 + +#if 0 && __cpp_lib_tuple_like // >= C++23 + template<__tuple_like _UTuple> + constexpr explicit(...) + tuple(_UTuple&& __u); +#endif // C++23 + + // Allocator-extended constructors. + + template<typename _Alloc> + constexpr + explicit(!(__is_implicitly_default_constructible_v<_Elements> && ...)) + tuple(allocator_arg_t __tag, const _Alloc& __a) + requires (is_default_constructible_v<_Elements> && ...) + : _Inherited(__tag, __a) + { } + + template<typename _Alloc> + constexpr explicit(!__convertible<const _Elements&...>()) + tuple(allocator_arg_t __tag, const _Alloc& __a, + const _Elements&... __elements) + requires (__constructible<const _Elements&...>()) + : _Inherited(__tag, __a, __elements...) + { } + + template<typename _Alloc, typename... _UTypes> + requires (__disambiguating_constraint<_UTypes...>()) + && (__constructible<_UTypes...>()) + && (!__dangles<_UTypes...>()) + constexpr explicit(!__convertible<_UTypes...>()) + tuple(allocator_arg_t __tag, const _Alloc& __a, _UTypes&&... __u) + : _Inherited(__tag, __a, std::forward<_UTypes>(__u)...) + { } + + template<typename _Alloc, typename... _UTypes> + requires (__disambiguating_constraint<_UTypes...>()) + && (__constructible<_UTypes...>()) + && (__dangles<_UTypes...>()) + tuple(allocator_arg_t, const _Alloc&, _UTypes&&...) = delete; + + template<typename _Alloc> + constexpr + tuple(allocator_arg_t __tag, const _Alloc& __a, const tuple& __u) + : _Inherited(__tag, __a, static_cast<const _Inherited&>(__u)) + { } + + template<typename _Alloc> + requires (__constructible<_Elements...>()) + constexpr + tuple(allocator_arg_t __tag, const _Alloc& __a, tuple&& __u) + : _Inherited(__tag, __a, static_cast<_Inherited&&>(__u)) + { } + + template<typename _Alloc, typename... _UTypes> + requires (__constructible<const _UTypes&...>()) + && (!__use_other_ctor<const tuple<_UTypes...>&>()) + && (!__dangles<const _UTypes&...>()) + constexpr explicit(!__convertible<const _UTypes&...>()) + tuple(allocator_arg_t __tag, const _Alloc& __a, + const tuple<_UTypes...>& __u) + : _Inherited(__tag, __a, + static_cast<const _Tuple_impl<0, _UTypes...>&>(__u)) + { } + + template<typename _Alloc, typename... _UTypes> + requires (__constructible<const _UTypes&...>()) + && (!__use_other_ctor<const tuple<_UTypes...>&>()) + && (__dangles<const _UTypes&...>()) + tuple(allocator_arg_t, const _Alloc&, const tuple<_UTypes...>&) = delete; + + template<typename _Alloc, typename... _UTypes> + requires (__constructible<_UTypes...>()) + && (!__use_other_ctor<tuple<_UTypes...>>()) + && (!__dangles<_UTypes...>()) + constexpr explicit(!__use_other_ctor<tuple<_UTypes...>>()) + tuple(allocator_arg_t __tag, const _Alloc& __a, tuple<_UTypes...>&& __u) + : _Inherited(__tag, __a, static_cast<_Tuple_impl<0, _UTypes...>&&>(__u)) + { } + + template<typename _Alloc, typename... _UTypes> + requires (__constructible<_UTypes...>()) + && (!__use_other_ctor<tuple<_UTypes...>>()) + && (__dangles<_UTypes...>()) + tuple(allocator_arg_t, const _Alloc&, tuple<_UTypes...>&&) = delete; + +#if __cpp_lib_ranges_zip // >= C++23 + template<typename _Alloc, typename... _UTypes> + requires (__constructible<_UTypes&...>()) + && (!__use_other_ctor<tuple<_UTypes...>&>()) + && (!__dangles<_UTypes&...>()) + constexpr explicit(!__convertible<_UTypes&...>()) + tuple(allocator_arg_t __tag, const _Alloc& __a, tuple<_UTypes...>& __u) + : _Inherited(__tag, __a, static_cast<_Tuple_impl<0, _UTypes...>&>(__u)) + { } + + template<typename _Alloc, typename... _UTypes> + requires (__constructible<_UTypes&...>()) + && (!__use_other_ctor<tuple<_UTypes...>&>()) + && (__dangles<_UTypes&...>()) + tuple(allocator_arg_t, const _Alloc&, tuple<_UTypes...>&) = delete; + + template<typename _Alloc, typename... _UTypes> + requires (__constructible<const _UTypes...>()) + && (!__use_other_ctor<const tuple<_UTypes...>>()) + && (!__dangles<const _UTypes...>()) + constexpr explicit(!__convertible<const _UTypes...>()) + tuple(allocator_arg_t __tag, const _Alloc& __a, + const tuple<_UTypes...>&& __u) + : _Inherited(__tag, __a, + static_cast<const _Tuple_impl<0, _UTypes...>&&>(__u)) + { } + + template<typename _Alloc, typename... _UTypes> + requires (__constructible<const _UTypes...>()) + && (!__use_other_ctor<const tuple<_UTypes...>>()) + && (__dangles<const _UTypes...>()) + tuple(allocator_arg_t, const _Alloc&, const tuple<_UTypes...>&&) = delete; +#endif // C++23 + + template<typename _Alloc, typename _U1, typename _U2> + requires (sizeof...(_Elements) == 2) + && (__constructible<const _U1&, const _U2&>()) + && (!__dangles<const _U1&, const _U2&>()) + constexpr explicit(!__convertible<const _U1&, const _U2&>()) + tuple(allocator_arg_t __tag, const _Alloc& __a, + const pair<_U1, _U2>& __u) + noexcept(__nothrow_constructible<const _U1&, const _U2&>()) + : _Inherited(__tag, __a, __u.first, __u.second) + { } + + template<typename _Alloc, typename _U1, typename _U2> + requires (sizeof...(_Elements) == 2) + && (__constructible<const _U1&, const _U2&>()) + && (__dangles<const _U1&, const _U2&>()) + tuple(allocator_arg_t, const _Alloc&, const pair<_U1, _U2>&) = delete; + + template<typename _Alloc, typename _U1, typename _U2> + requires (sizeof...(_Elements) == 2) + && (__constructible<_U1, _U2>()) + && (!__dangles<_U1, _U2>()) + constexpr explicit(!__convertible<_U1, _U2>()) + tuple(allocator_arg_t __tag, const _Alloc& __a, pair<_U1, _U2>&& __u) + noexcept(__nothrow_constructible<_U1, _U2>()) + : _Inherited(__tag, __a, std::move(__u.first), std::move(__u.second)) + { } + + template<typename _Alloc, typename _U1, typename _U2> + requires (sizeof...(_Elements) == 2) + && (__constructible<_U1, _U2>()) + && (__dangles<_U1, _U2>()) + tuple(allocator_arg_t, const _Alloc&, pair<_U1, _U2>&&) = delete; + +#if __cpp_lib_ranges_zip // >= C++23 + template<typename _Alloc, typename _U1, typename _U2> + requires (sizeof...(_Elements) == 2) + && (__constructible<_U1&, _U2&>()) + && (!__dangles<_U1&, _U2&>()) + constexpr explicit(!__convertible<_U1&, _U2&>()) + tuple(allocator_arg_t __tag, const _Alloc& __a, pair<_U1, _U2>& __u) + noexcept(__nothrow_constructible<_U1&, _U2&>()) + : _Inherited(__tag, __a, __u.first, __u.second) + { } + + template<typename _Alloc, typename _U1, typename _U2> + requires (sizeof...(_Elements) == 2) + && (__constructible<_U1&, _U2&>()) + && (__dangles<_U1&, _U2&>()) + tuple(allocator_arg_t, const _Alloc&, pair<_U1, _U2>&) = delete; + + template<typename _Alloc, typename _U1, typename _U2> + requires (sizeof...(_Elements) == 2) + && (__constructible<const _U1, const _U2>()) + && (!__dangles<const _U1, const _U2>()) + constexpr explicit(!__convertible<const _U1, const _U2>()) + tuple(allocator_arg_t __tag, const _Alloc& __a, + const pair<_U1, _U2>&& __u) + noexcept(__nothrow_constructible<const _U1, const _U2>()) + : _Inherited(__tag, __a, std::move(__u.first), std::move(__u.second)) + { } + + template<typename _Alloc, typename _U1, typename _U2> + requires (sizeof...(_Elements) == 2) + && (__constructible<const _U1, const _U2>()) + && (__dangles<const _U1, const _U2>()) + tuple(allocator_arg_t, const _Alloc&, const pair<_U1, _U2>&&) = delete; +#endif // C++23 + +#if 0 && __cpp_lib_tuple_like // >= C++23 + template<typename _Alloc, __tuple_like _UTuple> + constexpr explicit(...) + tuple(allocator_arg_t __tag, const _Alloc& __a, _UTuple&& __u); +#endif // C++23 + +#else // !(concepts && conditional_explicit) template<bool _Cond> using _TCC = _TupleConstraints<_Cond, _Elements...>; @@ -781,20 +1237,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION _TCC<_Cond>::template __is_explicitly_constructible<_Args...>(), bool>; - template<typename... _UElements> - static constexpr - __enable_if_t<sizeof...(_UElements) == sizeof...(_Elements), bool> - __assignable() - { return __and_<is_assignable<_Elements&, _UElements>...>::value; } - - // Condition for noexcept-specifier of an assignment operator. - template<typename... _UElements> - static constexpr bool __nothrow_assignable() - { - return - __and_<is_nothrow_assignable<_Elements&, _UElements>...>::value; - } - // Condition for noexcept-specifier of a constructor. template<typename... _UElements> static constexpr bool __nothrow_constructible() @@ -850,15 +1292,26 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION static constexpr bool __use_other_ctor() { return _UseOtherCtor<_Tuple>::value; } -#if __cplusplus > 202002L - template<typename... _Args> - static constexpr bool __constructible - = _TCC<true>::template __constructible<_Args...>::value; - - template<typename... _Args> - static constexpr bool __convertible - = _TCC<true>::template __convertible<_Args...>::value; -#endif // C++23 + /// @cond undocumented +#undef __glibcxx_no_dangling_refs +#if __has_builtin(__reference_constructs_from_temporary) \ + && defined _GLIBCXX_DEBUG + // Error if construction from U... would create a dangling ref. +# if __cpp_fold_expressions +# define __glibcxx_dangling_refs(U) \ + (__reference_constructs_from_temporary(_Elements, U) && ...) +# else +# define __glibcxx_dangling_refs(U) \ + __or_<__bool_constant<__reference_constructs_from_temporary(_Elements, U) \ + >...>::value +# endif +# define __glibcxx_no_dangling_refs(U) \ + static_assert(!__glibcxx_dangling_refs(U), \ + "std::tuple constructor creates a dangling reference") +#else +# define __glibcxx_no_dangling_refs(U) +#endif + /// @endcond public: template<typename _Dummy = void, @@ -895,7 +1348,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION constexpr tuple(_UElements&&... __elements) noexcept(__nothrow_constructible<_UElements...>()) - : _Inherited(std::forward<_UElements>(__elements)...) { } + : _Inherited(std::forward<_UElements>(__elements)...) + { __glibcxx_no_dangling_refs(_UElements&&); } template<typename... _UElements, bool _Valid = __valid_args<_UElements...>(), @@ -903,7 +1357,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION explicit constexpr tuple(_UElements&&... __elements) noexcept(__nothrow_constructible<_UElements...>()) - : _Inherited(std::forward<_UElements>(__elements)...) { } + : _Inherited(std::forward<_UElements>(__elements)...) + { __glibcxx_no_dangling_refs(_UElements&&); } constexpr tuple(const tuple&) = default; @@ -917,7 +1372,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION tuple(const tuple<_UElements...>& __in) noexcept(__nothrow_constructible<const _UElements&...>()) : _Inherited(static_cast<const _Tuple_impl<0, _UElements...>&>(__in)) - { } + { __glibcxx_no_dangling_refs(const _UElements&); } template<typename... _UElements, bool _Valid = (sizeof...(_Elements) == sizeof...(_UElements)) @@ -927,7 +1382,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION tuple(const tuple<_UElements...>& __in) noexcept(__nothrow_constructible<const _UElements&...>()) : _Inherited(static_cast<const _Tuple_impl<0, _UElements...>&>(__in)) - { } + { __glibcxx_no_dangling_refs(const _UElements&); } template<typename... _UElements, bool _Valid = (sizeof...(_Elements) == sizeof...(_UElements)) @@ -936,7 +1391,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION constexpr tuple(tuple<_UElements...>&& __in) noexcept(__nothrow_constructible<_UElements...>()) - : _Inherited(static_cast<_Tuple_impl<0, _UElements...>&&>(__in)) { } + : _Inherited(static_cast<_Tuple_impl<0, _UElements...>&&>(__in)) + { __glibcxx_no_dangling_refs(_UElements&&); } template<typename... _UElements, bool _Valid = (sizeof...(_Elements) == sizeof...(_UElements)) @@ -945,30 +1401,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION explicit constexpr tuple(tuple<_UElements...>&& __in) noexcept(__nothrow_constructible<_UElements...>()) - : _Inherited(static_cast<_Tuple_impl<0, _UElements...>&&>(__in)) { } - -#if __cplusplus > 202002L - template<typename... _UElements> - requires (sizeof...(_Elements) == sizeof...(_UElements)) - && (!__use_other_ctor<tuple<_UElements...>&>()) - && __constructible<_UElements&...> - explicit(!__convertible<_UElements&...>) - constexpr - tuple(tuple<_UElements...>& __in) - noexcept(__nothrow_constructible<_UElements&...>()) - : _Inherited(static_cast<_Tuple_impl<0, _UElements...>&>(__in)) - { } - - template<typename... _UElements> - requires (sizeof...(_Elements) == sizeof...(_UElements)) - && (!__use_other_ctor<const tuple<_UElements...>&&>()) - && __constructible<const _UElements...> - explicit(!__convertible<const _UElements...>) - constexpr - tuple(const tuple<_UElements...>&& __in) - noexcept(__nothrow_constructible<const _UElements...>()) - : _Inherited(static_cast<const _Tuple_impl<0, _UElements...>&&>(__in)) { } -#endif // C++23 + : _Inherited(static_cast<_Tuple_impl<0, _UElements...>&&>(__in)) + { __glibcxx_no_dangling_refs(_UElements&&); } // Allocator-extended constructors. @@ -1000,7 +1434,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION tuple(allocator_arg_t __tag, const _Alloc& __a, _UElements&&... __elements) : _Inherited(__tag, __a, std::forward<_UElements>(__elements)...) - { } + { __glibcxx_no_dangling_refs(_UElements&&); } template<typename _Alloc, typename... _UElements, bool _Valid = __valid_args<_UElements...>(), @@ -1010,7 +1444,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION tuple(allocator_arg_t __tag, const _Alloc& __a, _UElements&&... __elements) : _Inherited(__tag, __a, std::forward<_UElements>(__elements)...) - { } + { __glibcxx_no_dangling_refs(_UElements&&); } template<typename _Alloc> _GLIBCXX20_CONSTEXPR @@ -1030,8 +1464,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION tuple(allocator_arg_t __tag, const _Alloc& __a, const tuple<_UElements...>& __in) : _Inherited(__tag, __a, - static_cast<const _Tuple_impl<0, _UElements...>&>(__in)) - { } + static_cast<const _Tuple_impl<0, _UElements...>&>(__in)) + { __glibcxx_no_dangling_refs(const _UElements&); } template<typename _Alloc, typename... _UElements, bool _Valid = (sizeof...(_Elements) == sizeof...(_UElements)) @@ -1042,8 +1476,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION tuple(allocator_arg_t __tag, const _Alloc& __a, const tuple<_UElements...>& __in) : _Inherited(__tag, __a, - static_cast<const _Tuple_impl<0, _UElements...>&>(__in)) - { } + static_cast<const _Tuple_impl<0, _UElements...>&>(__in)) + { __glibcxx_no_dangling_refs(const _UElements&); } template<typename _Alloc, typename... _UElements, bool _Valid = (sizeof...(_Elements) == sizeof...(_UElements)) @@ -1053,8 +1487,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION tuple(allocator_arg_t __tag, const _Alloc& __a, tuple<_UElements...>&& __in) : _Inherited(__tag, __a, - static_cast<_Tuple_impl<0, _UElements...>&&>(__in)) - { } + static_cast<_Tuple_impl<0, _UElements...>&&>(__in)) + { __glibcxx_no_dangling_refs(_UElements&&); } template<typename _Alloc, typename... _UElements, bool _Valid = (sizeof...(_Elements) == sizeof...(_UElements)) @@ -1065,36 +1499,196 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION tuple(allocator_arg_t __tag, const _Alloc& __a, tuple<_UElements...>&& __in) : _Inherited(__tag, __a, - static_cast<_Tuple_impl<0, _UElements...>&&>(__in)) - { } + static_cast<_Tuple_impl<0, _UElements...>&&>(__in)) + { __glibcxx_no_dangling_refs(_UElements&&); } +#endif // concepts && conditional_explicit -#if __cplusplus > 202002L - template<typename _Alloc, typename... _UElements> - requires (sizeof...(_Elements) == sizeof...(_UElements)) - && (!__use_other_ctor<tuple<_UElements...>&>()) - && __constructible<_UElements&...> - explicit(!__convertible<_UElements&...>) - constexpr - tuple(allocator_arg_t __tag, const _Alloc& __a, - tuple<_UElements...>& __in) - : _Inherited(__tag, __a, - static_cast<_Tuple_impl<0, _UElements...>&>(__in)) - { } + // tuple assignment - template<typename _Alloc, typename... _UElements> - requires (sizeof...(_Elements) == sizeof...(_UElements)) - && (!__use_other_ctor<const tuple<_UElements...>>()) - && __constructible<const _UElements...> - explicit(!__convertible<const _UElements...>) - constexpr - tuple(allocator_arg_t __tag, const _Alloc& __a, - const tuple<_UElements...>&& __in) - : _Inherited(__tag, __a, - static_cast<const _Tuple_impl<0, _UElements...>&&>(__in)) - { } +#if __cpp_concepts && __cpp_consteval // >= C++20 + private: + template<typename... _UTypes> + static consteval bool + __assignable() + { + if constexpr (sizeof...(_UTypes) == sizeof...(_Elements)) + return __and_v<is_assignable<_Elements&, _UTypes>...>; + else + return false; + } + + template<typename... _UTypes> + static consteval bool + __nothrow_assignable() + { + if constexpr (sizeof...(_UTypes) == sizeof...(_Elements)) + return __and_v<is_nothrow_assignable<_Elements&, _UTypes>...>; + else + return false; + } + +#if __cpp_lib_ranges_zip // >= C++23 + template<typename... _UTypes> + static consteval bool + __const_assignable() + { + if constexpr (sizeof...(_UTypes) == sizeof...(_Elements)) + return __and_v<is_assignable<const _Elements&, _UTypes>...>; + else + return false; + } #endif // C++23 - // tuple assignment + public: + + tuple& operator=(const tuple& __u) = delete; + + constexpr tuple& + operator=(const tuple& __u) + noexcept(__nothrow_assignable<const _Elements&...>()) + requires (__assignable<const _Elements&...>()) + { + this->_M_assign(__u); + return *this; + } + + constexpr tuple& + operator=(tuple&& __u) + noexcept(__nothrow_assignable<_Elements...>()) + requires (__assignable<_Elements...>()) + { + this->_M_assign(std::move(__u)); + return *this; + } + + template<typename... _UTypes> + requires (__assignable<const _UTypes&...>()) + constexpr tuple& + operator=(const tuple<_UTypes...>& __u) + noexcept(__nothrow_assignable<const _UTypes&...>()) + { + this->_M_assign(__u); + return *this; + } + + template<typename... _UTypes> + requires (__assignable<_UTypes...>()) + constexpr tuple& + operator=(tuple<_UTypes...>&& __u) + noexcept(__nothrow_assignable<_UTypes...>()) + { + this->_M_assign(std::move(__u)); + return *this; + } + +#if __cpp_lib_ranges_zip // >= C++23 + constexpr const tuple& + operator=(const tuple& __u) const + requires (__const_assignable<const _Elements&...>()) + { + this->_M_assign(__u); + return *this; + } + + constexpr const tuple& + operator=(tuple&& __u) const + requires (__const_assignable<_Elements...>()) + { + this->_M_assign(std::move(__u)); + return *this; + } + + template<typename... _UTypes> + constexpr const tuple& + operator=(const tuple<_UTypes...>& __u) const + requires (__const_assignable<const _UTypes&...>()) + { + this->_M_assign(__u); + return *this; + } + + template<typename... _UTypes> + constexpr const tuple& + operator=(tuple<_UTypes...>&& __u) const + requires (__const_assignable<_UTypes...>()) + { + this->_M_assign(std::move(__u)); + return *this; + } +#endif // C++23 + + template<typename _U1, typename _U2> + requires (__assignable<const _U1&, const _U2&>()) + constexpr tuple& + operator=(const pair<_U1, _U2>& __u) + noexcept(__nothrow_assignable<const _U1&, const _U2&>()) + { + this->_M_head(*this) = __u.first; + this->_M_tail(*this)._M_head(*this) = __u.second; + return *this; + } + + template<typename _U1, typename _U2> + requires (__assignable<_U1, _U2>()) + constexpr tuple& + operator=(pair<_U1, _U2>&& __u) + noexcept(__nothrow_assignable<_U1, _U2>()) + { + this->_M_head(*this) = std::forward<_U1>(__u.first); + this->_M_tail(*this)._M_head(*this) = std::forward<_U2>(__u.second); + return *this; + } + +#if __cpp_lib_ranges_zip // >= C++23 + template<typename _U1, typename _U2> + requires (__const_assignable<const _U1&, const _U2>()) + constexpr const tuple& + operator=(const pair<_U1, _U2>& __u) const + { + this->_M_head(*this) = __u.first; + this->_M_tail(*this)._M_head(*this) = __u.second; + return *this; + } + + template<typename _U1, typename _U2> + requires (__const_assignable<_U1, _U2>()) + constexpr const tuple& + operator=(pair<_U1, _U2>&& __u) const + { + this->_M_head(*this) = std::forward<_U1>(__u.first); + this->_M_tail(*this)._M_head(*this) = std::forward<_U2>(__u.second); + return *this; + } +#endif // C++23 + +#if 0 && __cpp_lib_tuple_like // >= C++23 + template<__tuple_like _UTuple> + constexpr tuple& + operator=(_UTuple&& __u); + + template<__tuple_like _UTuple> + constexpr tuple& + operator=(_UTuple&& __u) const; +#endif // C++23 + +#else // ! (concepts && consteval) + + private: + template<typename... _UElements> + static constexpr + __enable_if_t<sizeof...(_UElements) == sizeof...(_Elements), bool> + __assignable() + { return __and_<is_assignable<_Elements&, _UElements>...>::value; } + + // Condition for noexcept-specifier of an assignment operator. + template<typename... _UElements> + static constexpr bool __nothrow_assignable() + { + return + __and_<is_nothrow_assignable<_Elements&, _UElements>...>::value; + } + + public: _GLIBCXX20_CONSTEXPR tuple& @@ -1137,44 +1731,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION this->_M_assign(std::move(__in)); return *this; } - -#if __cplusplus > 202002L - constexpr const tuple& - operator=(const tuple& __in) const - requires (is_copy_assignable_v<const _Elements> && ...) - { - this->_M_assign(__in); - return *this; - } - - constexpr const tuple& - operator=(tuple&& __in) const - requires (is_assignable_v<const _Elements&, _Elements> && ...) - { - this->_M_assign(std::move(__in)); - return *this; - } - - template<typename... _UElements> - constexpr const tuple& - operator=(const tuple<_UElements...>& __in) const - requires (sizeof...(_Elements) == sizeof...(_UElements)) - && (is_assignable_v<const _Elements&, const _UElements&> && ...) - { - this->_M_assign(__in); - return *this; - } - - template<typename... _UElements> - constexpr const tuple& - operator=(tuple<_UElements...>&& __in) const - requires (sizeof...(_Elements) == sizeof...(_UElements)) - && (is_assignable_v<const _Elements&, _UElements> && ...) - { - this->_M_assign(std::move(__in)); - return *this; - } -#endif // C++23 +#endif // concepts && consteval // tuple swap _GLIBCXX20_CONSTEXPR @@ -1183,7 +1740,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION noexcept(__and_<__is_nothrow_swappable<_Elements>...>::value) { _Inherited::_M_swap(__in); } -#if __cplusplus > 202002L +#if __cpp_lib_ranges_zip // >= C++23 // As an extension, we constrain the const swap member function in order // to continue accepting explicit instantiation of tuples whose elements // are not all const swappable. Without this constraint, such an @@ -1233,6 +1790,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION tuple(allocator_arg_t, const _Alloc&, const tuple&) noexcept { } }; +#if !(__cpp_concepts && __cpp_consteval && __cpp_conditional_explicit) // !C++20 /// Partial specialization, 2-element tuple. /// Includes construction and assignment from a pair. template<typename _T1, typename _T2> @@ -1300,15 +1858,19 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION static constexpr bool __is_alloc_arg() { return is_same<__remove_cvref_t<_U1>, allocator_arg_t>::value; } -#if __cplusplus > 202002L - template<typename _U1, typename _U2> - static constexpr bool __constructible - = _TCC<true>::template __constructible<_U1, _U2>::value; - - template<typename _U1, typename _U2> - static constexpr bool __convertible - = _TCC<true>::template __convertible<_U1, _U2>::value; -#endif // C++23 + /// @cond undocumented +#undef __glibcxx_no_dangling_refs + // Error if construction from _U1 and _U2 would create a dangling ref. +#if __has_builtin(__reference_constructs_from_temporary) \ + && defined _GLIBCXX_DEBUG +# define __glibcxx_no_dangling_refs(_U1, _U2) \ + static_assert(!__reference_constructs_from_temporary(_T1, _U1) \ + && !__reference_constructs_from_temporary(_T2, _U2), \ + "std::tuple constructor creates a dangling reference") +#else +# define __glibcxx_no_dangling_refs(_U1, _U2) +#endif + /// @endcond public: template<bool _Dummy = true, @@ -1344,14 +1906,16 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION constexpr tuple(_U1&& __a1, _U2&& __a2) noexcept(__nothrow_constructible<_U1, _U2>()) - : _Inherited(std::forward<_U1>(__a1), std::forward<_U2>(__a2)) { } + : _Inherited(std::forward<_U1>(__a1), std::forward<_U2>(__a2)) + { __glibcxx_no_dangling_refs(_U1&&, _U2&&); } template<typename _U1, typename _U2, _ExplicitCtor<!__is_alloc_arg<_U1>(), _U1, _U2> = false> explicit constexpr tuple(_U1&& __a1, _U2&& __a2) noexcept(__nothrow_constructible<_U1, _U2>()) - : _Inherited(std::forward<_U1>(__a1), std::forward<_U2>(__a2)) { } + : _Inherited(std::forward<_U1>(__a1), std::forward<_U2>(__a2)) + { __glibcxx_no_dangling_refs(_U1&&, _U2&&); } constexpr tuple(const tuple&) = default; @@ -1362,60 +1926,48 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION constexpr tuple(const tuple<_U1, _U2>& __in) noexcept(__nothrow_constructible<const _U1&, const _U2&>()) - : _Inherited(static_cast<const _Tuple_impl<0, _U1, _U2>&>(__in)) { } + : _Inherited(static_cast<const _Tuple_impl<0, _U1, _U2>&>(__in)) + { __glibcxx_no_dangling_refs(const _U1&, const _U2&); } template<typename _U1, typename _U2, _ExplicitCtor<true, const _U1&, const _U2&> = false> explicit constexpr tuple(const tuple<_U1, _U2>& __in) noexcept(__nothrow_constructible<const _U1&, const _U2&>()) - : _Inherited(static_cast<const _Tuple_impl<0, _U1, _U2>&>(__in)) { } + : _Inherited(static_cast<const _Tuple_impl<0, _U1, _U2>&>(__in)) + { __glibcxx_no_dangling_refs(const _U1&, const _U2&); } template<typename _U1, typename _U2, _ImplicitCtor<true, _U1, _U2> = true> constexpr tuple(tuple<_U1, _U2>&& __in) noexcept(__nothrow_constructible<_U1, _U2>()) - : _Inherited(static_cast<_Tuple_impl<0, _U1, _U2>&&>(__in)) { } + : _Inherited(static_cast<_Tuple_impl<0, _U1, _U2>&&>(__in)) + { __glibcxx_no_dangling_refs(_U1&&, _U2&&); } template<typename _U1, typename _U2, _ExplicitCtor<true, _U1, _U2> = false> explicit constexpr tuple(tuple<_U1, _U2>&& __in) noexcept(__nothrow_constructible<_U1, _U2>()) - : _Inherited(static_cast<_Tuple_impl<0, _U1, _U2>&&>(__in)) { } - -#if __cplusplus > 202002L - template<typename _U1, typename _U2> - requires __constructible<_U1&, _U2&> - explicit(!__convertible<_U1&, _U2&>) - constexpr - tuple(tuple<_U1, _U2>& __in) - noexcept(__nothrow_constructible<_U1&, _U2&>()) - : _Inherited(static_cast<_Tuple_impl<0, _U1, _U2>&>(__in)) { } - - template<typename _U1, typename _U2> - requires __constructible<const _U1, const _U2> - explicit(!__convertible<const _U1, const _U2>) - constexpr - tuple(const tuple<_U1, _U2>&& __in) - noexcept(__nothrow_constructible<const _U1, const _U2>()) - : _Inherited(static_cast<const _Tuple_impl<0, _U1, _U2>&&>(__in)) { } -#endif // C++23 + : _Inherited(static_cast<_Tuple_impl<0, _U1, _U2>&&>(__in)) + { __glibcxx_no_dangling_refs(_U1&&, _U2&&); } template<typename _U1, typename _U2, _ImplicitCtor<true, const _U1&, const _U2&> = true> constexpr tuple(const pair<_U1, _U2>& __in) noexcept(__nothrow_constructible<const _U1&, const _U2&>()) - : _Inherited(__in.first, __in.second) { } + : _Inherited(__in.first, __in.second) + { __glibcxx_no_dangling_refs(const _U1&, const _U2&); } template<typename _U1, typename _U2, _ExplicitCtor<true, const _U1&, const _U2&> = false> explicit constexpr tuple(const pair<_U1, _U2>& __in) noexcept(__nothrow_constructible<const _U1&, const _U2&>()) - : _Inherited(__in.first, __in.second) { } + : _Inherited(__in.first, __in.second) + { __glibcxx_no_dangling_refs(const _U1&, const _U2&); } template<typename _U1, typename _U2, _ImplicitCtor<true, _U1, _U2> = true> @@ -1423,7 +1975,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION tuple(pair<_U1, _U2>&& __in) noexcept(__nothrow_constructible<_U1, _U2>()) : _Inherited(std::forward<_U1>(__in.first), - std::forward<_U2>(__in.second)) { } + std::forward<_U2>(__in.second)) + { __glibcxx_no_dangling_refs(_U1&&, _U2&&); } template<typename _U1, typename _U2, _ExplicitCtor<true, _U1, _U2> = false> @@ -1431,26 +1984,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION tuple(pair<_U1, _U2>&& __in) noexcept(__nothrow_constructible<_U1, _U2>()) : _Inherited(std::forward<_U1>(__in.first), - std::forward<_U2>(__in.second)) { } - -#if __cplusplus > 202002L - template<typename _U1, typename _U2> - requires __constructible<_U1&, _U2&> - explicit(!__convertible<_U1&, _U2&>) - constexpr - tuple(pair<_U1, _U2>& __in) - noexcept(__nothrow_constructible<_U1&, _U2&>()) - : _Inherited(__in.first, __in.second) { } - - template<typename _U1, typename _U2> - requires __constructible<const _U1, const _U2> - explicit(!__convertible<const _U1, const _U2>) - constexpr - tuple(const pair<_U1, _U2>&& __in) - noexcept(__nothrow_constructible<const _U1, const _U2>()) - : _Inherited(std::forward<const _U1>(__in.first), - std::forward<const _U2>(__in.second)) { } -#endif // C++23 + std::forward<_U2>(__in.second)) + { __glibcxx_no_dangling_refs(_U1&&, _U2&&); } // Allocator-extended constructors. @@ -1480,7 +2015,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION _GLIBCXX20_CONSTEXPR tuple(allocator_arg_t __tag, const _Alloc& __a, _U1&& __a1, _U2&& __a2) : _Inherited(__tag, __a, std::forward<_U1>(__a1), - std::forward<_U2>(__a2)) { } + std::forward<_U2>(__a2)) + { __glibcxx_no_dangling_refs(_U1&&, _U2&&); } template<typename _Alloc, typename _U1, typename _U2, _ExplicitCtor<true, _U1, _U2> = false> @@ -1489,7 +2025,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION tuple(allocator_arg_t __tag, const _Alloc& __a, _U1&& __a1, _U2&& __a2) : _Inherited(__tag, __a, std::forward<_U1>(__a1), - std::forward<_U2>(__a2)) { } + std::forward<_U2>(__a2)) + { __glibcxx_no_dangling_refs(_U1&&, _U2&&); } template<typename _Alloc> _GLIBCXX20_CONSTEXPR @@ -1507,8 +2044,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION tuple(allocator_arg_t __tag, const _Alloc& __a, const tuple<_U1, _U2>& __in) : _Inherited(__tag, __a, - static_cast<const _Tuple_impl<0, _U1, _U2>&>(__in)) - { } + static_cast<const _Tuple_impl<0, _U1, _U2>&>(__in)) + { __glibcxx_no_dangling_refs(const _U1&, const _U2&); } template<typename _Alloc, typename _U1, typename _U2, _ExplicitCtor<true, const _U1&, const _U2&> = false> @@ -1517,15 +2054,15 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION tuple(allocator_arg_t __tag, const _Alloc& __a, const tuple<_U1, _U2>& __in) : _Inherited(__tag, __a, - static_cast<const _Tuple_impl<0, _U1, _U2>&>(__in)) - { } + static_cast<const _Tuple_impl<0, _U1, _U2>&>(__in)) + { __glibcxx_no_dangling_refs(const _U1&, const _U2&); } template<typename _Alloc, typename _U1, typename _U2, _ImplicitCtor<true, _U1, _U2> = true> _GLIBCXX20_CONSTEXPR tuple(allocator_arg_t __tag, const _Alloc& __a, tuple<_U1, _U2>&& __in) : _Inherited(__tag, __a, static_cast<_Tuple_impl<0, _U1, _U2>&&>(__in)) - { } + { __glibcxx_no_dangling_refs(_U1&&, _U2&&); } template<typename _Alloc, typename _U1, typename _U2, _ExplicitCtor<true, _U1, _U2> = false> @@ -1533,36 +2070,15 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION _GLIBCXX20_CONSTEXPR tuple(allocator_arg_t __tag, const _Alloc& __a, tuple<_U1, _U2>&& __in) : _Inherited(__tag, __a, static_cast<_Tuple_impl<0, _U1, _U2>&&>(__in)) - { } - -#if __cplusplus > 202002L - template<typename _Alloc, typename _U1, typename _U2> - requires __constructible<_U1&, _U2&> - explicit(!__convertible<_U1&, _U2&>) - constexpr - tuple(allocator_arg_t __tag, const _Alloc& __a, - tuple<_U1, _U2>& __in) - : _Inherited(__tag, __a, - static_cast<_Tuple_impl<0, _U1, _U2>&>(__in)) - { } - - template<typename _Alloc, typename _U1, typename _U2> - requires __constructible<const _U1, const _U2> - explicit(!__convertible<const _U1, const _U2>) - constexpr - tuple(allocator_arg_t __tag, const _Alloc& __a, - const tuple<_U1, _U2>&& __in) - : _Inherited(__tag, __a, - static_cast<const _Tuple_impl<0, _U1, _U2>&&>(__in)) - { } -#endif // C++23 + { __glibcxx_no_dangling_refs(_U1&&, _U2&&); } template<typename _Alloc, typename _U1, typename _U2, _ImplicitCtor<true, const _U1&, const _U2&> = true> _GLIBCXX20_CONSTEXPR tuple(allocator_arg_t __tag, const _Alloc& __a, const pair<_U1, _U2>& __in) - : _Inherited(__tag, __a, __in.first, __in.second) { } + : _Inherited(__tag, __a, __in.first, __in.second) + { __glibcxx_no_dangling_refs(const _U1&, const _U2&); } template<typename _Alloc, typename _U1, typename _U2, _ExplicitCtor<true, const _U1&, const _U2&> = false> @@ -1570,14 +2086,16 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION _GLIBCXX20_CONSTEXPR tuple(allocator_arg_t __tag, const _Alloc& __a, const pair<_U1, _U2>& __in) - : _Inherited(__tag, __a, __in.first, __in.second) { } + : _Inherited(__tag, __a, __in.first, __in.second) + { __glibcxx_no_dangling_refs(const _U1&, const _U2&); } template<typename _Alloc, typename _U1, typename _U2, _ImplicitCtor<true, _U1, _U2> = true> _GLIBCXX20_CONSTEXPR tuple(allocator_arg_t __tag, const _Alloc& __a, pair<_U1, _U2>&& __in) : _Inherited(__tag, __a, std::forward<_U1>(__in.first), - std::forward<_U2>(__in.second)) { } + std::forward<_U2>(__in.second)) + { __glibcxx_no_dangling_refs(_U1&&, _U2&&); } template<typename _Alloc, typename _U1, typename _U2, _ExplicitCtor<true, _U1, _U2> = false> @@ -1585,25 +2103,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION _GLIBCXX20_CONSTEXPR tuple(allocator_arg_t __tag, const _Alloc& __a, pair<_U1, _U2>&& __in) : _Inherited(__tag, __a, std::forward<_U1>(__in.first), - std::forward<_U2>(__in.second)) { } - -#if __cplusplus > 202002L - template<typename _Alloc, typename _U1, typename _U2> - requires __constructible<_U1&, _U2&> - explicit(!__convertible<_U1&, _U2&>) - constexpr - tuple(allocator_arg_t __tag, const _Alloc& __a, - pair<_U1, _U2>& __in) - : _Inherited(__tag, __a, __in.first, __in.second) { } - - template<typename _Alloc, typename _U1, typename _U2> - requires __constructible<const _U1, const _U2> - explicit(!__convertible<const _U1, const _U2>) - constexpr - tuple(allocator_arg_t __tag, const _Alloc& __a, const pair<_U1, _U2>&& __in) - : _Inherited(__tag, __a, std::forward<const _U1>(__in.first), - std::forward<const _U2>(__in.second)) { } -#endif // C++23 + std::forward<_U2>(__in.second)) + { __glibcxx_no_dangling_refs(_U1&&, _U2&&); } // Tuple assignment. @@ -1649,44 +2150,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION return *this; } -#if __cplusplus > 202002L - constexpr const tuple& - operator=(const tuple& __in) const - requires is_copy_assignable_v<const _T1> && is_copy_assignable_v<const _T2> - { - this->_M_assign(__in); - return *this; - } - - constexpr const tuple& - operator=(tuple&& __in) const - requires is_assignable_v<const _T1&, _T1> && is_assignable_v<const _T2, _T2> - { - this->_M_assign(std::move(__in)); - return *this; - } - - template<typename _U1, typename _U2> - constexpr const tuple& - operator=(const tuple<_U1, _U2>& __in) const - requires is_assignable_v<const _T1&, const _U1&> - && is_assignable_v<const _T2&, const _U2&> - { - this->_M_assign(__in); - return *this; - } - - template<typename _U1, typename _U2> - constexpr const tuple& - operator=(tuple<_U1, _U2>&& __in) const - requires is_assignable_v<const _T1&, _U1> - && is_assignable_v<const _T2&, _U2> - { - this->_M_assign(std::move(__in)); - return *this; - } -#endif // C++23 - template<typename _U1, typename _U2> _GLIBCXX20_CONSTEXPR __enable_if_t<__assignable<const _U1&, const _U2&>(), tuple&> @@ -1709,47 +2172,14 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION return *this; } -#if __cplusplus > 202002L - template<typename _U1, typename _U2> - constexpr const tuple& - operator=(const pair<_U1, _U2>& __in) const - requires is_assignable_v<const _T1&, const _U1&> - && is_assignable_v<const _T2&, const _U2&> - { - this->_M_head(*this) = __in.first; - this->_M_tail(*this)._M_head(*this) = __in.second; - return *this; - } - - template<typename _U1, typename _U2> - constexpr const tuple& - operator=(pair<_U1, _U2>&& __in) const - requires is_assignable_v<const _T1&, _U1> - && is_assignable_v<const _T2&, _U2> - { - this->_M_head(*this) = std::forward<_U1>(__in.first); - this->_M_tail(*this)._M_head(*this) = std::forward<_U2>(__in.second); - return *this; - } -#endif // C++23 - _GLIBCXX20_CONSTEXPR void swap(tuple& __in) noexcept(__and_<__is_nothrow_swappable<_T1>, __is_nothrow_swappable<_T2>>::value) { _Inherited::_M_swap(__in); } - -#if __cplusplus > 202002L - constexpr void - swap(const tuple& __in) const - noexcept(__and_v<__is_nothrow_swappable<const _T1>, - __is_nothrow_swappable<const _T2>>) - requires is_swappable_v<const _T1> && is_swappable_v<const _T2> - { _Inherited::_M_swap(__in); } -#endif // C++23 }; - +#endif // concepts && conditional_explicit /// class tuple_size template<typename... _Elements> @@ -2174,7 +2604,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION noexcept(noexcept(__x.swap(__y))) { __x.swap(__y); } -#if __cplusplus > 202002L +#if __cpp_lib_ranges_zip // >= C++23 template<typename... _Elements> requires (is_swappable_v<const _Elements> && ...) constexpr void @@ -2329,7 +2759,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION } #endif -#if __cplusplus > 202002L +#if __cpp_lib_ranges_zip // >= C++23 template<typename... _TTypes, typename... _UTypes, template<typename> class _TQual, template<typename> class _UQual> requires requires { typename tuple<common_reference_t<_TQual<_TTypes>, _UQual<_UTypes>>...>; } @@ -2344,6 +2774,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION /// @} +#undef __glibcxx_no_dangling_refs + _GLIBCXX_END_NAMESPACE_VERSION } // namespace std diff --git a/libstdc++-v3/include/std/type_traits b/libstdc++-v3/include/std/type_traits index 1cec082..a9bb280 100644 --- a/libstdc++-v3/include/std/type_traits +++ b/libstdc++-v3/include/std/type_traits @@ -751,7 +751,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION /// is_compound template<typename _Tp> struct is_compound - : public __not_<is_fundamental<_Tp>>::type { }; + : public __bool_constant<!is_fundamental<_Tp>::value> { }; /// is_member_pointer #if _GLIBCXX_USE_BUILTIN_TRAIT(__is_member_pointer) @@ -1306,6 +1306,16 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION "template argument must be a complete class or an unbounded array"); }; +#if __cpp_variable_templates && __cpp_concepts + template<typename _Tp> + constexpr bool __is_implicitly_default_constructible_v + = requires (void(&__f)(_Tp)) { __f({}); }; + + template<typename _Tp> + struct __is_implicitly_default_constructible + : __bool_constant<__is_implicitly_default_constructible_v<_Tp>> + { }; +#else struct __do_is_implicitly_default_constructible_impl { template <typename _Tp> @@ -1335,6 +1345,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION : public __and_<__is_constructible_impl<_Tp>, __is_implicitly_default_constructible_safe<_Tp>>::type { }; +#endif /// is_trivially_copy_constructible template<typename _Tp> @@ -3305,7 +3316,7 @@ template <typename _Tp> template <typename _Tp> inline constexpr bool is_scalar_v = is_scalar<_Tp>::value; template <typename _Tp> - inline constexpr bool is_compound_v = is_compound<_Tp>::value; + inline constexpr bool is_compound_v = !is_fundamental_v<_Tp>; #if _GLIBCXX_USE_BUILTIN_TRAIT(__is_member_pointer) template <typename _Tp> diff --git a/libstdc++-v3/include/std/variant b/libstdc++-v3/include/std/variant index 20a76c8..4b9002e 100644 --- a/libstdc++-v3/include/std/variant +++ b/libstdc++-v3/include/std/variant @@ -392,7 +392,7 @@ namespace __variant }; // Defines members and ctors. - template<typename... _Types> + template<bool __trivially_destructible, typename... _Types> union _Variadic_union { _Variadic_union() = default; @@ -401,8 +401,8 @@ namespace __variant _Variadic_union(in_place_index_t<_Np>, _Args&&...) = delete; }; - template<typename _First, typename... _Rest> - union _Variadic_union<_First, _Rest...> + template<bool __trivially_destructible, typename _First, typename... _Rest> + union _Variadic_union<__trivially_destructible, _First, _Rest...> { constexpr _Variadic_union() : _M_rest() { } @@ -427,13 +427,12 @@ namespace __variant ~_Variadic_union() = default; constexpr ~_Variadic_union() - requires (!is_trivially_destructible_v<_First>) - || (!is_trivially_destructible_v<_Variadic_union<_Rest...>>) + requires (!__trivially_destructible) { } #endif _Uninitialized<_First> _M_first; - _Variadic_union<_Rest...> _M_rest; + _Variadic_union<__trivially_destructible, _Rest...> _M_rest; }; // _Never_valueless_alt is true for variant alternatives that can @@ -514,7 +513,7 @@ namespace __variant return this->_M_index != __index_type(variant_npos); } - _Variadic_union<_Types...> _M_u; + _Variadic_union<false, _Types...> _M_u; using __index_type = __select_index<_Types...>; __index_type _M_index; }; @@ -552,7 +551,7 @@ namespace __variant return this->_M_index != static_cast<__index_type>(variant_npos); } - _Variadic_union<_Types...> _M_u; + _Variadic_union<true, _Types...> _M_u; using __index_type = __select_index<_Types...>; __index_type _M_index; }; diff --git a/libstdc++-v3/libsupc++/eh_unex_handler.cc b/libstdc++-v3/libsupc++/eh_unex_handler.cc index 7f1d474..c9b9956 100644 --- a/libstdc++-v3/libsupc++/eh_unex_handler.cc +++ b/libstdc++-v3/libsupc++/eh_unex_handler.cc @@ -25,5 +25,5 @@ #include "unwind-cxx.h" /* The current installed user handler. */ -std::unexpected_handler __cxxabiv1::__unexpected_handler = std::terminate; +std::terminate_handler __cxxabiv1::__unexpected_handler = std::terminate; diff --git a/libstdc++-v3/libsupc++/new_opa.cc b/libstdc++-v3/libsupc++/new_opa.cc index 8326b74..35606e1 100644 --- a/libstdc++-v3/libsupc++/new_opa.cc +++ b/libstdc++-v3/libsupc++/new_opa.cc @@ -46,12 +46,12 @@ using std::bad_alloc; using std::size_t; extern "C" { -# if _GLIBCXX_HAVE_ALIGNED_ALLOC +# if _GLIBCXX_HAVE_POSIX_MEMALIGN + void *posix_memalign(void **, size_t alignment, size_t size); +# elif _GLIBCXX_HAVE_ALIGNED_ALLOC void *aligned_alloc(size_t alignment, size_t size); # elif _GLIBCXX_HAVE__ALIGNED_MALLOC void *_aligned_malloc(size_t size, size_t alignment); -# elif _GLIBCXX_HAVE_POSIX_MEMALIGN - void *posix_memalign(void **, size_t alignment, size_t size); # elif _GLIBCXX_HAVE_MEMALIGN void *memalign(size_t alignment, size_t size); # else @@ -63,13 +63,10 @@ extern "C" #endif namespace __gnu_cxx { -#if _GLIBCXX_HAVE_ALIGNED_ALLOC -using ::aligned_alloc; -#elif _GLIBCXX_HAVE__ALIGNED_MALLOC -static inline void* -aligned_alloc (std::size_t al, std::size_t sz) -{ return _aligned_malloc(sz, al); } -#elif _GLIBCXX_HAVE_POSIX_MEMALIGN +// Prefer posix_memalign if available, because it's older than aligned_alloc +// and so more likely to be provided by replacement malloc libraries that +// predate the addition of aligned_alloc. See PR libstdc++/113258. +#if _GLIBCXX_HAVE_POSIX_MEMALIGN static inline void* aligned_alloc (std::size_t al, std::size_t sz) { @@ -83,6 +80,12 @@ aligned_alloc (std::size_t al, std::size_t sz) return ptr; return nullptr; } +#elif _GLIBCXX_HAVE_ALIGNED_ALLOC +using ::aligned_alloc; +#elif _GLIBCXX_HAVE__ALIGNED_MALLOC +static inline void* +aligned_alloc (std::size_t al, std::size_t sz) +{ return _aligned_malloc(sz, al); } #elif _GLIBCXX_HAVE_MEMALIGN static inline void* aligned_alloc (std::size_t al, std::size_t sz) @@ -128,7 +131,8 @@ operator new (std::size_t sz, std::align_val_t al) if (__builtin_expect (sz == 0, false)) sz = 1; -#if _GLIBCXX_HAVE_ALIGNED_ALLOC +#if _GLIBCXX_HAVE_POSIX_MEMALIGN +#elif _GLIBCXX_HAVE_ALIGNED_ALLOC # if defined _AIX || defined __APPLE__ /* AIX 7.2.0.0 aligned_alloc incorrectly has posix_memalign's requirement * that alignment is a multiple of sizeof(void*). diff --git a/libstdc++-v3/python/libstdcxx/v6/printers.py b/libstdc++-v3/python/libstdcxx/v6/printers.py index bf0dc52..032a7aa 100644 --- a/libstdc++-v3/python/libstdcxx/v6/printers.py +++ b/libstdc++-v3/python/libstdcxx/v6/printers.py @@ -2306,6 +2306,23 @@ class StdLocalePrinter(printer_base): mod = ' with "{}={}"'.format(cat, other) return 'std::locale = "{}"{}'.format(name, mod) +class StdIntegralConstantPrinter(printer_base): + """Print a std::true_type or std::false_type.""" + + def __init__(self, typename, val): + self._val = val + self._typename = typename + + def to_string(self): + value_type = self._val.type.template_argument(0) + value = self._val.type.template_argument(1) + if value_type.code == gdb.TYPE_CODE_BOOL: + if value: + return "std::true_type" + else: + return "std::false_type" + typename = strip_versioned_namespace(self._typename) + return "{}<{}, {}>".format(typename, value_type, value) # A "regular expression" printer which conforms to the # "SubPrettyPrinter" protocol from gdb.printing. @@ -2788,6 +2805,9 @@ def build_libstdcxx_dictionary(): # vector<bool> libstdcxx_printer.add_version('std::', 'locale', StdLocalePrinter) + libstdcxx_printer.add_version('std::', 'integral_constant', + StdIntegralConstantPrinter) + if hasattr(gdb.Value, 'dynamic_type'): libstdcxx_printer.add_version('std::', 'error_code', StdErrorCodePrinter) diff --git a/libstdc++-v3/scripts/extract_symvers.in b/libstdc++-v3/scripts/extract_symvers.in index 17f0d31..6bb951c 100755 --- a/libstdc++-v3/scripts/extract_symvers.in +++ b/libstdc++-v3/scripts/extract_symvers.in @@ -52,7 +52,7 @@ SunOS) # Omit _DYNAMIC etc. for consistency with extract_symvers.pl, only # present on Solaris. ${readelf} ${lib} |\ - sed -e 's/ \[<other>: [A-Fa-f0-9]*\] //' -e '/\.dynsym/,/^$/p;d' |\ + sed -e 's/ \[<other>: [A-Fa-f0-9]*\] //' -e '/\.dynsym.*:$/,/^$/p;d' |\ sed -e 's/ \[<localentry>: [0-9]*\] //' |\ grep -E -v ' (LOCAL|UND) ' |\ grep -E -v ' (_DYNAMIC|_GLOBAL_OFFSET_TABLE_|_PROCEDURE_LINKAGE_TABLE_|_edata|_end|_etext)$' |\ diff --git a/libstdc++-v3/src/c++11/debug.cc b/libstdc++-v3/src/c++11/debug.cc index 54092f5..5d6bb5b 100644 --- a/libstdc++-v3/src/c++11/debug.cc +++ b/libstdc++-v3/src/c++11/debug.cc @@ -437,6 +437,8 @@ namespace __gnu_debug _M_version = _M_sequence->_M_version; _M_sequence->_M_attach(this, __constant); } + else + _M_version = 0; } void @@ -452,6 +454,8 @@ namespace __gnu_debug _M_version = _M_sequence->_M_version; _M_sequence->_M_attach_single(this, __constant); } + else + _M_version = 0; } void @@ -528,6 +532,8 @@ namespace __gnu_debug _M_version = _M_sequence->_M_version; _M_get_container()->_M_attach_local(this, __constant); } + else + _M_version = 0; } void @@ -543,6 +549,8 @@ namespace __gnu_debug _M_version = _M_sequence->_M_version; _M_get_container()->_M_attach_local_single(this, __constant); } + else + _M_version = 0; } void diff --git a/libstdc++-v3/src/c++17/fs_ops.cc b/libstdc++-v3/src/c++17/fs_ops.cc index e0b308a..61df197 100644 --- a/libstdc++-v3/src/c++17/fs_ops.cc +++ b/libstdc++-v3/src/c++17/fs_ops.cc @@ -897,7 +897,7 @@ fs::equivalent(const path& p1, const path& p2, error_code& ec) noexcept return st1.st_dev == st2.st_dev && st1.st_ino == st2.st_ino; #endif } - else if (!exists(s1) && !exists(s2)) + else if (!exists(s1) || !exists(s2)) ec = std::make_error_code(std::errc::no_such_file_or_directory); else if (err) ec.assign(err, std::generic_category()); diff --git a/libstdc++-v3/src/c++20/tzdata.zi b/libstdc++-v3/src/c++20/tzdata.zi index b522e39..4e01359 100644 --- a/libstdc++-v3/src/c++20/tzdata.zi +++ b/libstdc++-v3/src/c++20/tzdata.zi @@ -1,4 +1,4 @@ -# version 2023c +# version 2023d # This zic input file is in the public domain. R d 1916 o - Jun 14 23s 1 S R d 1916 1919 - O Su>=1 23s 0 - @@ -394,7 +394,12 @@ Z Antarctica/Casey 0 - -00 1969 8 - +08 2019 O 4 3 11 - +11 2020 Mar 8 3 8 - +08 2020 O 4 0:1 -11 - +11 +11 - +11 2021 Mar 14 +8 - +08 2021 O 3 0:1 +11 - +11 2022 Mar 13 +8 - +08 2022 O 2 0:1 +11 - +11 2023 Mar 9 3 +8 - +08 Z Antarctica/Davis 0 - -00 1957 Ja 13 7 - +07 1964 N 0 - -00 1969 F @@ -410,6 +415,11 @@ R Tr 2005 ma - Mar lastSu 1u 2 +02 R Tr 2004 ma - O lastSu 1u 0 +00 Z Antarctica/Troll 0 - -00 2005 F 12 0 Tr %s +Z Antarctica/Vostok 0 - -00 1957 D 16 +7 - +07 1994 F +0 - -00 1994 N +7 - +07 2023 D 18 2 +5 - +05 Z Antarctica/Rothera 0 - -00 1976 D -3 - -03 Z Asia/Kabul 4:36:48 - LMT 1890 @@ -1050,13 +1060,13 @@ R P 2070 o - O 4 2 0 - R P 2071 o - S 19 2 0 - R P 2072 o - S 10 2 0 - R P 2072 o - O 15 2 1 S +R P 2072 ma - O Sa<=30 2 0 - R P 2073 o - S 2 2 0 - R P 2073 o - O 7 2 1 S R P 2074 o - Au 18 2 0 - R P 2074 o - S 29 2 1 S R P 2075 o - Au 10 2 0 - R P 2075 o - S 14 2 1 S -R P 2075 ma - O Sa<=30 2 0 - R P 2076 o - Jul 25 2 0 - R P 2076 o - S 5 2 1 S R P 2077 o - Jul 17 2 0 - @@ -1831,10 +1841,12 @@ Z America/Danmarkshavn -1:14:40 - LMT 1916 Jul 28 Z America/Scoresbysund -1:27:52 - LMT 1916 Jul 28 -2 - -02 1980 Ap 6 2 -2 c -02/-01 1981 Mar 29 --1 E -01/+00 +-1 E -01/+00 2024 Mar 31 +-2 E -02/-01 Z America/Nuuk -3:26:56 - LMT 1916 Jul 28 -3 - -03 1980 Ap 6 2 --3 E -03/-02 2023 O 29 1u +-3 E -03/-02 2023 Mar 26 1u +-2 - -02 2023 O 29 1u -2 E -02/-01 Z America/Thule -4:35:8 - LMT 1916 Jul 28 -4 Th A%sT @@ -4185,7 +4197,6 @@ L America/Puerto_Rico America/Tortola L Pacific/Port_Moresby Antarctica/DumontDUrville L Pacific/Auckland Antarctica/McMurdo L Asia/Riyadh Antarctica/Syowa -L Asia/Urumqi Antarctica/Vostok L Europe/Berlin Arctic/Longyearbyen L Asia/Riyadh Asia/Aden L Asia/Qatar Asia/Bahrain diff --git a/libstdc++-v3/src/c++20/tzdb.cc b/libstdc++-v3/src/c++20/tzdb.cc index d22cea7..6b86329 100644 --- a/libstdc++-v3/src/c++20/tzdb.cc +++ b/libstdc++-v3/src/c++20/tzdb.cc @@ -1136,8 +1136,8 @@ namespace std::chrono pair<vector<leap_second>, bool> tzdb_list::_Node::_S_read_leap_seconds() { - // This list is valid until at least 2023-12-28 00:00:00 UTC. - auto expires = sys_days{2023y/12/28}; + // This list is valid until at least 2024-06-28 00:00:00 UTC. + auto expires = sys_days{2024y/6/28}; vector<leap_second> leaps { (leap_second) 78796800, // 1 Jul 1972 diff --git a/libstdc++-v3/src/filesystem/ops-common.h b/libstdc++-v3/src/filesystem/ops-common.h index d78a547..d917fdd 100644 --- a/libstdc++-v3/src/filesystem/ops-common.h +++ b/libstdc++-v3/src/filesystem/ops-common.h @@ -118,7 +118,7 @@ namespace __gnu_posix inline int close(int fd) { return ::_close(fd); } - typedef struct ::__stat64 stat_type; + using stat_type = struct ::__stat64; inline int stat(const wchar_t* path, stat_type* buffer) { return ::_wstat64(path, buffer); } @@ -184,7 +184,7 @@ namespace __gnu_posix using ::open; using ::close; # ifdef _GLIBCXX_HAVE_SYS_STAT_H - typedef struct ::stat stat_type; + using stat_type = struct ::stat; using ::stat; # ifdef _GLIBCXX_USE_LSTAT using ::lstat; diff --git a/libstdc++-v3/src/filesystem/ops.cc b/libstdc++-v3/src/filesystem/ops.cc index eccdae3..4d23a80 100644 --- a/libstdc++-v3/src/filesystem/ops.cc +++ b/libstdc++-v3/src/filesystem/ops.cc @@ -765,7 +765,7 @@ fs::equivalent(const path& p1, const path& p2, error_code& ec) noexcept return false; return st1.st_dev == st2.st_dev && st1.st_ino == st2.st_ino; } - else if (!exists(s1) && !exists(s2)) + else if (!exists(s1) || !exists(s2)) ec = std::make_error_code(std::errc::no_such_file_or_directory); else if (err) ec.assign(err, std::generic_category()); diff --git a/libstdc++-v3/testsuite/20_util/function_objects/bind_back/1.cc b/libstdc++-v3/testsuite/20_util/function_objects/bind_back/1.cc new file mode 100644 index 0000000..ec66e2a --- /dev/null +++ b/libstdc++-v3/testsuite/20_util/function_objects/bind_back/1.cc @@ -0,0 +1,178 @@ +// Copyright (C) 2014-2024 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. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING3. If not see +// <http://www.gnu.org/licenses/>. + +// { dg-do run { target c++23 } } +// { dg-add-options no_pch } + +#include <functional> + +#ifndef __cpp_lib_bind_back +# error "Feature test macro for bind_back is missing in <functional>" +#elif __cpp_lib_bind_back < 202202L +# error "Feature test macro for bind_back has wrong value in <functional>" +#endif + +#include <testsuite_hooks.h> + +using std::bind_back; +using std::is_same_v; +using std::is_invocable_v; +using std::is_invocable_r_v; + +void +test01() +{ + struct F { void operator()() {} }; + + // Arguments should be decayed: + static_assert(std::is_same_v< + decltype(bind_back(std::declval<F>(), std::declval<int>())), + decltype(bind_back(std::declval<F&>(), std::declval<int&>())) + >); + static_assert(std::is_same_v< + decltype(bind_back(std::declval<F>(), std::declval<int>())), + decltype(bind_back(std::declval<const F&>(), std::declval<const int&>())) + >); + + // Reference wrappers should be handled: + static_assert(!std::is_same_v< + decltype(bind_back(std::declval<F>(), std::declval<int&>())), + decltype(bind_back(std::declval<F>(), std::ref(std::declval<int&>()))) + >); + static_assert(!std::is_same_v< + decltype(bind_back(std::declval<F>(), std::declval<const int&>())), + decltype(bind_back(std::declval<F>(), std::cref(std::declval<int&>()))) + >); + static_assert(!std::is_same_v< + decltype(bind_back(std::declval<F>(), std::ref(std::declval<int&>()))), + decltype(bind_back(std::declval<F>(), std::cref(std::declval<int&>()))) + >); +} + +void +test02() +{ + struct quals + { + bool as_const; + bool as_lvalue; + }; + + struct F + { + quals operator()() & { return { false, true }; } + quals operator()() const & { return { true, true }; } + quals operator()() && { return { false, false }; } + quals operator()() const && { return { true, false }; } + }; + + F f; + auto g = bind_back(f); + const auto& cg = g; + quals q; + + // constness and value category should be forwarded to the target object: + q = g(); + VERIFY( ! q.as_const && q.as_lvalue ); + q = std::move(g)(); + VERIFY( ! q.as_const && ! q.as_lvalue ); + q = cg(); + VERIFY( q.as_const && q.as_lvalue ); + q = std::move(cg)(); + VERIFY( q.as_const && ! q.as_lvalue ); +} + +void +test03() +{ + struct F + { + int& operator()(void*, int& i) { return i; } + void* operator()(void* p, int) const { return p; } + }; + + int i = 5; + void* vp = &vp; // arbitrary void* value + + auto g1 = bind_back(F{}, i); // call wrapper has bound arg of type int + using G1 = decltype(g1); + // Invoking G1& will pass g1's bound arg as int&, so calls first overload: + static_assert(is_invocable_r_v<int&, G1&, void*>); + // Invoking const G1& or G&& calls second overload: + static_assert(is_invocable_r_v<void*, const G1&, void*>); + static_assert(is_invocable_r_v<void*, G1&&, void*>); + void* p1 = static_cast<G1&&>(g1)(vp); + VERIFY( p1 == vp ); + + auto g2 = bind_back(F{}, std::ref(i)); // bound arg of type int& + using G2 = decltype(g2); + // Bound arg always forwarded as int& even from G2&& or const G2& + static_assert(is_invocable_r_v<int&, G2&, void*>); + static_assert(is_invocable_r_v<int&, G2&&, void*>); + // But cannot call first overload on const G2: + static_assert(is_invocable_r_v<void*, const G2&, void*>); + static_assert(is_invocable_r_v<void*, const G2&&, void*>); + int& i2 = g2(vp); + VERIFY( &i2 == &i ); + int& i2r = static_cast<G2&&>(g2)(vp); + VERIFY( &i2r == &i ); + void* p2 = const_cast<const G2&>(g2)(vp); + VERIFY( p2 == vp ); + + auto g3 = bind_back(F{}, std::cref(i)); // bound arg of type const int& + using G3 = decltype(g3); + // Bound arg always forwarded as const int& so can only call second overload: + static_assert(is_invocable_r_v<void*, G3&, void*>); + static_assert(is_invocable_r_v<void*, G3&&, void*>); + static_assert(is_invocable_r_v<void*, const G3&, void*>); + static_assert(is_invocable_r_v<void*, const G3&&, void*>); + + auto g4 = bind_back(g2, nullptr); + using G4 = decltype(g4); + static_assert(is_invocable_r_v<int&, G4&>); + static_assert(is_invocable_r_v<int&, G4&&>); + static_assert(is_invocable_r_v<void*, const G4&>); + static_assert(is_invocable_r_v<void*, const G4&&>); +} + +constexpr int f(int i, int j, int k) { return i + 2*(j + k); } + +constexpr bool +test04() +{ + auto g = bind_back(f); + VERIFY( g(1, 2, 3) == 1 + 2*(2 + 3) ); + auto g1 = bind_back(f, 1); + VERIFY( g1(2, 3) == 2 + 2*(3 + 1) ); + VERIFY( bind_back(g, 1)(2, 3) == 2 + 2*(3 + 1) ); + auto g2 = bind_back(f, 1, 2); + VERIFY( g2(3) == 3 + 2*(1 + 2) ); + VERIFY( bind_back(g1, 2)(3) == 3 + 2*(2 + 1) ); + auto g3 = bind_back(f, 1, 2, 3); + VERIFY( g3() == 1 + 2*(2 + 3) ); + VERIFY( bind_back(g2, 3)() == 3 + 2*(1 + 2) ); + return true; +} + +int +main() +{ + test01(); + test02(); + test03(); + static_assert(test04()); +} diff --git a/libstdc++-v3/testsuite/20_util/function_objects/bind_back/111327.cc b/libstdc++-v3/testsuite/20_util/function_objects/bind_back/111327.cc new file mode 100644 index 0000000..d634db9 --- /dev/null +++ b/libstdc++-v3/testsuite/20_util/function_objects/bind_back/111327.cc @@ -0,0 +1,42 @@ +// PR libstdc++/111327 - std::bind_front (and std::not_fn) doesn't always +// perfectly forward according to value category of the call wrapper object +// { dg-do compile { target c++23 } } + +#include <functional> +#include <utility> + +struct F { + void operator()(...) & = delete; + void operator()(...) const &; +}; + +struct G { + void operator()(...) && = delete; + void operator()(...) const &&; +}; + +int main() { + auto f0 = std::bind_back(F{}); + f0(); // { dg-error "deleted|no match" } + std::move(f0)(); + std::as_const(f0)(); + std::move(std::as_const(f0))(); + + auto g0 = std::bind_back(G{}); + g0(); // { dg-error "deleted|no match" } + std::move(g0)(); // { dg-error "deleted|no match" } + std::move(std::as_const(g0))(); + + auto f1 = std::bind_back(F{}, 42); + f1(); // { dg-error "deleted|no match" } + std::move(f1)(); + std::as_const(f1)(); + std::move(std::as_const(f1))(); + + auto g1 = std::bind_back(G{}, 42); + g1(); // { dg-error "deleted|no match" } + std::move(g1)(); // { dg-error "deleted|no match" } + std::move(std::as_const(g1))(); +} + +// { dg-error "no type named 'type' in 'struct std::invoke_result" "" { target c++23 } 0 } diff --git a/libstdc++-v3/testsuite/20_util/function_objects/bind_front/111327.cc b/libstdc++-v3/testsuite/20_util/function_objects/bind_front/111327.cc index 43b56ca..5fe0a83 100644 --- a/libstdc++-v3/testsuite/20_util/function_objects/bind_front/111327.cc +++ b/libstdc++-v3/testsuite/20_util/function_objects/bind_front/111327.cc @@ -17,24 +17,26 @@ struct G { int main() { auto f0 = std::bind_front(F{}); - f0(); // { dg-error "deleted" } + f0(); // { dg-error "deleted|no match" } std::move(f0)(); std::as_const(f0)(); std::move(std::as_const(f0))(); auto g0 = std::bind_front(G{}); - g0(); // { dg-error "deleted" } - std::move(g0)(); // { dg-error "deleted" } + g0(); // { dg-error "deleted|no match" } + std::move(g0)(); // { dg-error "deleted|no match" } std::move(std::as_const(g0))(); auto f1 = std::bind_front(F{}, 42); - f1(); // { dg-error "deleted" } + f1(); // { dg-error "deleted|no match" } std::move(f1)(); std::as_const(f1)(); std::move(std::as_const(f1))(); auto g1 = std::bind_front(G{}, 42); - g1(); // { dg-error "deleted" } - std::move(g1)(); // { dg-error "deleted" } + g1(); // { dg-error "deleted|no match" } + std::move(g1)(); // { dg-error "deleted|no match" } std::move(std::as_const(g1))(); } + +// { dg-error "no type named 'type' in 'struct std::invoke_result" "" { target c++23 } 0 } diff --git a/libstdc++-v3/testsuite/20_util/pair/cons/default_tmpl_args.cc b/libstdc++-v3/testsuite/20_util/pair/cons/default_tmpl_args.cc new file mode 100644 index 0000000..5960bf7 --- /dev/null +++ b/libstdc++-v3/testsuite/20_util/pair/cons/default_tmpl_args.cc @@ -0,0 +1,48 @@ +// { dg-do compile { target c++23 } } + +// P1951R1 Default Arguments for pair's Forwarding Constructor + +#include <utility> +#include <vector> +#include <string> +#include <testsuite_hooks.h> + +void +test_p1951r1_example() +{ + std::pair<std::string, std::vector<std::string>> p("hello", {}); +} + +struct Counter +{ + constexpr Counter() = default; + constexpr Counter(int) { } + constexpr Counter(const Counter& c) : copies(c.copies + 1), moves(c.moves) { } + constexpr Counter(Counter&& c) : copies(c.copies), moves(c.moves+1) { } + int copies = 0; + int moves = 0; +}; + +constexpr bool +test_count_copies() +{ + std::pair<Counter, Counter> p1(1, {}); + VERIFY( p1.first.copies == 0 && p1.second.copies == 0 ); + VERIFY( p1.first.moves == 0 && p1.second.moves == 1 ); + + std::pair<Counter, Counter> p2({}, 1); + VERIFY( p2.first.copies == 0 && p2.second.copies == 0 ); + VERIFY( p2.first.moves == 1 && p2.second.moves == 0 ); + + std::pair<Counter, Counter> p3({}, {}); + VERIFY( p3.first.copies == 0 && p3.second.copies == 0 ); + VERIFY( p3.first.moves == 1 && p3.second.moves == 1 ); + + return true; +} + +int main() +{ + test_p1951r1_example(); + static_assert( test_count_copies() ); +} diff --git a/libstdc++-v3/testsuite/20_util/tuple/dangling_ref.cc b/libstdc++-v3/testsuite/20_util/tuple/dangling_ref.cc new file mode 100644 index 0000000..74fdc24 --- /dev/null +++ b/libstdc++-v3/testsuite/20_util/tuple/dangling_ref.cc @@ -0,0 +1,105 @@ +// { dg-do compile { target c++11 } } +// { dg-options "-Wno-unused-variable" } +// { dg-additional-options "-D_GLIBCXX_DEBUG" { target c++17_down } } + +#include <tuple> +#include <utility> + +#if __cplusplus >= 202002L +// For C++20 and later, constructors are constrained to disallow dangling. +static_assert(!std::is_constructible_v<std::tuple<const int&, int>, long, int>); +static_assert(!std::is_constructible_v<std::tuple<int, const int&>, int, long>); +static_assert(!std::is_constructible_v<std::tuple<const int&, int>, + std::tuple<long, long>>); +static_assert(!std::is_constructible_v<std::tuple<int, const int&>, + std::tuple<long, long>>); +static_assert(!std::is_constructible_v<std::tuple<const int&, int>, + const std::tuple<long, long>&>); +static_assert(!std::is_constructible_v<std::tuple<int, const int&>, + const std::tuple<long, long>&>); +static_assert(!std::is_constructible_v<std::tuple<const int&, int>, + std::pair<long, long>>); +static_assert(!std::is_constructible_v<std::tuple<int, const int&>, + std::pair<long, long>>); +static_assert(!std::is_constructible_v<std::tuple<const int&, int>, + const std::pair<long, long>&>); +static_assert(!std::is_constructible_v<std::tuple<int, const int&>, + const std::pair<long, long>&>); +#endif + +void +test_ary_ctors() +{ + std::tuple<const int&, int> t1(1L, 2); + // { dg-error "here" "" { target { c++17_down && hosted } } 33 } + // { dg-error "use of deleted function" "" { target c++20 } 33 } + + std::tuple<int, const int&> t2(1, 2L); + // { dg-error "here" "" { target { c++17_down && hosted } } 37 } + // { dg-error "use of deleted function" "" { target c++20 } 37 } + + std::tuple<const int&, const int&> t3(1L, 2L); + // { dg-error "here" "" { target { c++17_down && hosted } } 41 } + // { dg-error "use of deleted function" "" { target c++20 } 41 } + + std::tuple<const int&, const int&> t4(std::pair<long, int>{}); + // { dg-error "here" "" { target { c++17_down && hosted } } 45 } + // { dg-error "use of deleted function" "" { target c++20 } 45 } + + std::pair<int, long> p; + std::tuple<const int&, const int&> t5(p); + // { dg-error "here" "" { target { c++17_down && hosted } } 50 } + // { dg-error "use of deleted function" "" { target c++20 } 50 } +} + +void +test_converting_ctors() +{ + std::tuple<long, long> t0; + + std::tuple<const int&, int> t1(t0); + // { dg-error "here" "" { target { c++17_down && hosted } } 60 } + // { dg-error "use of deleted function" "" { target c++20 } 60 } + + std::tuple<int, const int&> t2(t0); + // { dg-error "here" "" { target { c++17_down && hosted } } 64 } + // { dg-error "use of deleted function" "" { target c++20 } 64 } + + std::tuple<const int&, const int&> t3(t0); + // { dg-error "here" "" { target { c++17_down && hosted } } 68 } + // { dg-error "use of deleted function" "" { target c++20 } 68 } + + std::tuple<const int&, int> t4(std::move(t0)); + // { dg-error "here" "" { target { c++17_down && hosted } } 72 } + // { dg-error "use of deleted function" "" { target c++20 } 72 } + + std::tuple<int, const int&> t5(std::move(t0)); + // { dg-error "here" "" { target { c++17_down && hosted } } 76 } + // { dg-error "use of deleted function" "" { target c++20 } 76 } + + std::tuple<const int&, const int&> t6(std::move(t0)); + // { dg-error "here" "" { target { c++17_down && hosted } } 80 } + // { dg-error "use of deleted function" "" { target c++20 } 80 } + + std::pair<long, long> p0; + std::tuple<const int&, int> t7(p0); + // { dg-error "here" "" { target { c++17_down && hosted } } 85 } + // { dg-error "use of deleted function" "" { target c++20 } 85 } + + std::tuple<int, const int&> t8(p0); + // { dg-error "here" "" { target { c++17_down && hosted } } 89 } + // { dg-error "use of deleted function" "" { target c++20 } 89 } + + std::tuple<const int&, int> t9(std::move(p0)); + // { dg-error "here" "" { target { c++17_down && hosted } } 93 } + // { dg-error "use of deleted function" "" { target c++20 } 93 } + + std::tuple<int, const int&> t10(std::move(p0)); + // { dg-error "here" "" { target { c++17_down && hosted } } 97 } + // { dg-error "use of deleted function" "" { target c++20 } 97 } +} + +// TODO: test allocator-extended ctors +// TODO: test 1-tuple or 3-tuple, not just 2-tuple + +// { dg-error "static assert.* dangling reference" "" { target { c++17_down && hosted } } 0 } diff --git a/libstdc++-v3/testsuite/23_containers/map/debug/112477.cc b/libstdc++-v3/testsuite/23_containers/map/debug/112477.cc new file mode 100644 index 0000000..bde613b --- /dev/null +++ b/libstdc++-v3/testsuite/23_containers/map/debug/112477.cc @@ -0,0 +1,20 @@ +// { dg-do run { target c++11 } } +// { dg-require-debug-mode "" } + +// PR libstdc++/112477 + +#include <map> + +int main() +{ + using M = std::map<int, int>; + using I = M::iterator; + + M map{ {1, 1}, {2, 2} }; + + I it1 = map.begin(); + it1 = I{}; + + I it2{}; + (void)(it1 == it2); +} diff --git a/libstdc++-v3/testsuite/24_iterators/const_iterator/1.cc b/libstdc++-v3/testsuite/24_iterators/const_iterator/1.cc index 8b74d11..fe952bf 100644 --- a/libstdc++-v3/testsuite/24_iterators/const_iterator/1.cc +++ b/libstdc++-v3/testsuite/24_iterators/const_iterator/1.cc @@ -1,6 +1,7 @@ // { dg-do run { target c++23 } } #include <iterator> +#include <ranges> #include <array> #include <concepts> #include <string_view> @@ -97,6 +98,26 @@ test03() std::unreachable_sentinel_t> ); } +void +test04() +{ + // Example from P2836R1 + auto f = [](std::vector<int>::const_iterator i) {}; + + auto v = std::vector<int>(); + { + auto i1 = ranges::cbegin(v); // returns vector<T>::const_iterator + f(i1); // okay + } + + auto t = v | std::views::take_while([](int const x) { return x < 100; }); + { + auto i2 = ranges::cbegin(t); // returns basic_const_iterator<vector<T>::iterator> + f(i2); // was an error in C++23 before P2836R1 + f(std::move(i2)); // same + } +} + int main() { @@ -136,4 +157,5 @@ main() test02<const std::vector<bool>, true>(); test03(); + test04(); } diff --git a/libstdc++-v3/testsuite/26_numerics/random/pr60037-neg.cc b/libstdc++-v3/testsuite/26_numerics/random/pr60037-neg.cc index c58f480..59cf84a 100644 --- a/libstdc++-v3/testsuite/26_numerics/random/pr60037-neg.cc +++ b/libstdc++-v3/testsuite/26_numerics/random/pr60037-neg.cc @@ -12,4 +12,4 @@ auto x = std::generate_canonical<std::size_t, // { dg-error "static assertion failed: template argument must be a floating point type" "" { target *-*-* } 169 } -// { dg-error "static assertion failed: template argument must be a floating point type" "" { target *-*-* } 3348 } +// { dg-error "static assertion failed: template argument must be a floating point type" "" { target *-*-* } 3351 } diff --git a/libstdc++-v3/testsuite/26_numerics/random/subtract_with_carry_engine/cons/lwg3809.cc b/libstdc++-v3/testsuite/26_numerics/random/subtract_with_carry_engine/cons/lwg3809.cc index d91ee74..b6fb57f 100644 --- a/libstdc++-v3/testsuite/26_numerics/random/subtract_with_carry_engine/cons/lwg3809.cc +++ b/libstdc++-v3/testsuite/26_numerics/random/subtract_with_carry_engine/cons/lwg3809.cc @@ -2,10 +2,11 @@ #include <random> #include <testsuite_hooks.h> -// LWG 3809. Is std::subtract_with_carry_engine<uint16_t> supposed to work? // PR 107466 - invalid -Wnarrowing error with std::subtract_with_carry_engine -int main() +// LWG 3809. Is std::subtract_with_carry_engine<uint16_t> supposed to work? +void +test_lwg3809() { // It should be possible to construct this engine with a 16-bit result_type: std::subtract_with_carry_engine<uint16_t, 12, 5, 12> s16; @@ -24,3 +25,17 @@ int main() for (int i = 0; i < 10; ++i) VERIFY( s16() == s32() ); } + +// LWG 4014. LWG 3809 changes behavior of some existing code +void +test_lwg4014() +{ + std::ranlux48_base g(-1U + 1LL); + VERIFY( g() == 22575453646312 ); +} + +int main() +{ + test_lwg3809(); + test_lwg4014(); +} diff --git a/libstdc++-v3/testsuite/27_io/filesystem/operations/equivalent.cc b/libstdc++-v3/testsuite/27_io/filesystem/operations/equivalent.cc index 78f6e36..68f3236 100644 --- a/libstdc++-v3/testsuite/27_io/filesystem/operations/equivalent.cc +++ b/libstdc++-v3/testsuite/27_io/filesystem/operations/equivalent.cc @@ -34,13 +34,13 @@ test01() bool result; result = equivalent(p1, p2, ec); - VERIFY( ec ); + VERIFY( ec == std::errc::no_such_file_or_directory ); VERIFY( !result ); __gnu_test::scoped_file f1(p1); ec = bad_ec; result = equivalent(p1, p2, ec); - VERIFY( !ec ); + VERIFY( ec == std::errc::no_such_file_or_directory ); VERIFY( !result ); __gnu_test::scoped_file f2(p2); diff --git a/libstdc++-v3/testsuite/experimental/filesystem/operations/equivalent.cc b/libstdc++-v3/testsuite/experimental/filesystem/operations/equivalent.cc index 929a6ca..5bc477a 100644 --- a/libstdc++-v3/testsuite/experimental/filesystem/operations/equivalent.cc +++ b/libstdc++-v3/testsuite/experimental/filesystem/operations/equivalent.cc @@ -35,13 +35,13 @@ test01() bool result; result = equivalent(p1, p2, ec); - VERIFY( ec ); + VERIFY( ec == std::errc::no_such_file_or_directory ); VERIFY( !result ); const auto bad_ec = ec; __gnu_test::scoped_file f1(p1); result = equivalent(p1, p2, ec); - VERIFY( !ec ); + VERIFY( ec == std::errc::no_such_file_or_directory ); VERIFY( !result ); __gnu_test::scoped_file f2(p2); diff --git a/libstdc++-v3/testsuite/ext/unicode/grapheme_view.cc b/libstdc++-v3/testsuite/ext/unicode/grapheme_view.cc new file mode 100644 index 0000000..ac1e8c5 --- /dev/null +++ b/libstdc++-v3/testsuite/ext/unicode/grapheme_view.cc @@ -0,0 +1,95 @@ +// { dg-do compile { target c++20 } } + +#include <format> // includes <bits/unicode.h> +#include <string_view> +#include <ranges> +#include <testsuite_hooks.h> + +namespace uc = std::__unicode; +using namespace std::string_view_literals; + +constexpr void +test_breaks() +{ + VERIFY(uc::__field_width(u8"\N{LATIN SMALL LETTER E WITH ACUTE}"sv) == 1 ); + + auto sv = u8"ee\N{COMBINING ACUTE ACCENT}e"sv; + auto data = sv.data(); + VERIFY( uc::__field_width(sv) == 3 ); + VERIFY( uc::__truncate(sv, 3) == 3 ); + VERIFY( uc::__truncate(sv, 4) == 3 ); + VERIFY( sv == data ); + + VERIFY( uc::__truncate(sv, 2) == 2 ); + VERIFY( sv == u8"ee\N{COMBINING ACUTE ACCENT}"sv ); + + sv = data; + sv.remove_prefix(1); + VERIFY( uc::__field_width(sv) == 2 ); + VERIFY( uc::__truncate(sv, 3) == 2 ); + VERIFY( sv == data+1 ); + + sv = u8"\N{REGIONAL INDICATOR SYMBOL LETTER G}" + "\N{REGIONAL INDICATOR SYMBOL LETTER B}"; // GB flag emoji + data = sv.data(); + VERIFY( uc::__field_width(sv) == 1 ); + VERIFY( uc::__truncate(sv, 2) == 1 ); + VERIFY( sv == data ); + VERIFY( uc::__truncate(sv, 1) == 1 ); // Do not break inside a flag emoji. + VERIFY( sv == data ); + + sv = u8"abcd" + "\N{REGIONAL INDICATOR SYMBOL LETTER G}" // 4 bytes + "\N{REGIONAL INDICATOR SYMBOL LETTER B}" // 4 bytes + "\N{DEVANAGARI LETTER KA}" // 3 bytes + "\N{DEVANAGARI SIGN VIRAMA}" // 3 bytes + "\N{DEVANAGARI LETTER RA}" // 3 bytes + "\N{MAN}\N{ZERO WIDTH JOINER}" // 4+3 bytes + "\N{WOMAN}\N{ZERO WIDTH JOINER}" // 4+3 bytes + "\N{GIRL}\N{ZERO WIDTH JOINER}" // 4+3 bytes + "\N{BOY}\N{ZERO WIDTH JOINER}" // 4+3 bytes + "\N{HANGUL CHOSEONG KIYEOK}" // 3 bytes + "\N{HANGUL CHOSEONG KIYEOK}" // 3 bytes + "\N{HANGUL CHOSEONG KIYEOK}" // 3 bytes + "\N{HANGUL CHOSEONG KIYEOK}" // 3 bytes + "\N{HANGUL JUNGSEONG A}" // 3 bytes + "\N{HANGUL JONGSEONG KIYEOK}" // 3 bytes + "\N{HANGUL JONGSEONG KIYEOK}" // 3 bytes + "\N{HANGUL JONGSEONG KIYEOK}"; // 3 bytes + + uc::_Grapheme_cluster_view gv(sv); + auto iter = gv.begin(); + VERIFY( iter.base() == sv.data() ); + VERIFY( *iter == U'a' ); + std::ranges::advance(iter, 3); + VERIFY( *iter == U'd' ); + VERIFY( iter.base() == sv.data() + 3 ); + ++iter; + VERIFY( *iter == U'\N{REGIONAL INDICATOR SYMBOL LETTER G}' ); + VERIFY( iter.base() == sv.data() + 4 ); + ++iter; + VERIFY( *iter == U'\N{DEVANAGARI LETTER KA}' ); + VERIFY( iter.base() == sv.data() + 4 + 8 ); + ++iter; + VERIFY( *iter == U'\N{MAN}' ); + VERIFY( iter.base() == sv.data() + 4 + 8 + 9 ); + ++iter; + VERIFY( iter.base() == sv.data() + 4 + 8 + 9 + 28 ); + VERIFY( *iter == U'\N{HANGUL CHOSEONG KIYEOK}' ); + ++iter; + VERIFY( iter.base() == sv.data() + 4 + 8 + 9 + 28 + 24 ); + VERIFY( iter == gv.end() ); + ++iter; + VERIFY( iter == gv.end() ); +} + +int main() +{ + auto run_tests = []{ + test_breaks(); + return true; + }; + + VERIFY( run_tests() ); + static_assert( run_tests() ); +} diff --git a/libstdc++-v3/testsuite/ext/unicode/properties.cc b/libstdc++-v3/testsuite/ext/unicode/properties.cc new file mode 100644 index 0000000..8600a3d --- /dev/null +++ b/libstdc++-v3/testsuite/ext/unicode/properties.cc @@ -0,0 +1,128 @@ +// { dg-do compile { target c++20 } } + +#include <format> // includes <bits/unicode.h> +#include <string_view> +#include <ranges> +#include <testsuite_hooks.h> + +namespace uc = std::__unicode; +using namespace std::string_view_literals; + +constexpr char32_t riA = U'\N{REGIONAL INDICATOR SYMBOL LETTER A}'; +constexpr char32_t riZ = U'\N{REGIONAL INDICATOR SYMBOL LETTER Z}'; + +static_assert( uc::__field_width(U'\0') == 1 ); +static_assert( uc::__field_width(U'1') == 1 ); +static_assert( uc::__field_width(U'a') == 1 ); +static_assert( uc::__field_width(riA) == 1 ); +static_assert( uc::__field_width(U'\N{OBLIQUE HYPHEN}') == 1 ); +static_assert( uc::__field_width(U'\N{CIRCLED NUMBER EIGHTY ON BLACK SQUARE}') + == 1 ); + +static_assert( uc::__field_width(U'\N{SESQUIQUADRATE}') == 1 ); +static_assert( uc::__field_width(U'\N{SOCCER BALL}') == 2 ); +static_assert( uc::__field_width(U'\N{BASEBALL}') == 2 ); +static_assert( uc::__field_width(U'\N{SQUARED KEY}') == 1 ); +static_assert( uc::__field_width(U'\N{BLACK DRAUGHTS KING}') == 1 ); +static_assert( uc::__field_width(U'\N{SNOWMAN WITHOUT SNOW}') == 2 ); + +static_assert( uc::__field_width(U'\N{IDEOGRAPHIC SPACE}') == 2 ); +static_assert( uc::__field_width(U'\N{IDEOGRAPHIC COMMA}') == 2 ); +static_assert( uc::__field_width(U'\N{CIRCLED IDEOGRAPH ONE}') == 2 ); + +// EastAsianWidth.txt says these are normal width, but C++ says width 2: +static_assert( uc::__field_width(U'\u4DC0') == 2 ); +static_assert( uc::__field_width(U'\u4DC1') == 2 ); +static_assert( uc::__field_width(U'\u4DFF') == 2 ); +// EastAsianWidth.txt says W and C++ says 2: +static_assert( uc::__field_width(U'\U0001F300') == 2 ); +static_assert( uc::__field_width(U'\U0001F320') == 2 ); +// EastAsianWidth.txt says N but C++ says 2: +static_assert( uc::__field_width(U'\U0001F321') == 2 ); +static_assert( uc::__field_width(U'\U0001F5FA') == 2 ); +// EastAsianWidth.txt says W and C++ says 2: +static_assert( uc::__field_width(U'\U0001F5FF') == 2 ); +static_assert( uc::__field_width(U'\U0001F600') == 2 ); + +static_assert( uc::__field_width(U'\U0001F900') == 2 ); +static_assert( uc::__field_width(U'\U0001F90B') == 2 ); +static_assert( uc::__field_width(U'\U0001F90C') == 2 ); +static_assert( uc::__field_width(U'\U0001F93B') == 2 ); +static_assert( uc::__field_width(U'\U0001F9FF') == 2 ); +static_assert( uc::__field_width(U'\U0001FA00') == 1 ); +static_assert( uc::__field_width(U'\U0001FA69') == 1 ); +static_assert( uc::__field_width(U'\U0001FA70') == 2 ); +static_assert( uc::__field_width(U'\U0001FAF8') == 2 ); +static_assert( uc::__field_width(U'\U0001FAF9') == 1 ); + +using enum uc::_Gcb_property; +static_assert( uc::__grapheme_cluster_break_property(U'\0') == _Gcb_Control ); +static_assert( uc::__grapheme_cluster_break_property(U'a') == _Gcb_Other ); +static_assert( uc::__grapheme_cluster_break_property(riA) + == _Gcb_Regional_Indicator ); +static_assert( uc::__grapheme_cluster_break_property(riZ) + == _Gcb_Regional_Indicator ); +static_assert( uc::__grapheme_cluster_break_property(riA - 1) == _Gcb_Other ); +static_assert( uc::__grapheme_cluster_break_property(riZ + 1) == _Gcb_Other ); +static_assert( uc::__grapheme_cluster_break_property(U'\uD788') == _Gcb_LV ); +static_assert( uc::__grapheme_cluster_break_property(U'\uD7A3') == _Gcb_LVT ); +static_assert( uc::__grapheme_cluster_break_property(U'\u200D') == _Gcb_ZWJ ); +static_assert( uc::__grapheme_cluster_break_property(U'\U0001D16D') + == _Gcb_SpacingMark ); +static_assert( uc::__grapheme_cluster_break_property(U'\U0001D16E') + == _Gcb_Extend ); +static_assert( uc::__grapheme_cluster_break_property(U'\U000E01EF') + == _Gcb_Extend ); +static_assert( uc::__grapheme_cluster_break_property(U'\U000E01F0') + == _Gcb_Control ); +static_assert( uc::__grapheme_cluster_break_property(U'\U000E0FFF') + == _Gcb_Control ); +static_assert( uc::__grapheme_cluster_break_property(U'\U000E1000') + == _Gcb_Other ); + +static_assert( uc::__incb_property(U'\0') == uc::_InCB{0} ); +static_assert( uc::__incb_property(U'a') == uc::_InCB{0} ); +static_assert( uc::__incb_property(U'\N{DEVANAGARI LETTER KA}') + == uc::_InCB::_Consonant ); +static_assert( uc::__incb_property(U'\N{DEVANAGARI LETTER RA}') + == uc::_InCB::_Consonant ); +static_assert( uc::__incb_property(U'\N{DEVANAGARI LETTER YYA}') + == uc::_InCB::_Consonant ); +static_assert( uc::__incb_property(U'\N{DEVANAGARI LETTER YYA}' + 1) + == uc::_InCB{0} ); +static_assert( uc::__incb_property(U'\N{DEVANAGARI SIGN NUKTA}') + == uc::_InCB::_Extend ); +static_assert( uc::__incb_property(U'\N{DEVANAGARI SIGN NUKTA}' + 1) + == uc::_InCB{0} ); +static_assert( uc::__incb_property(U'\U0001E94A') == uc::_InCB::_Extend ); +static_assert( uc::__incb_property(U'\U0001E94B') == uc::_InCB{0} ); + +static_assert( ! uc::__is_incb_linker(U'\0') ); +static_assert( ! uc::__is_incb_linker(U'a') ); +static_assert( uc::__is_incb_linker(U'\N{DEVANAGARI SIGN VIRAMA}') ); +static_assert( ! uc::__is_incb_linker(U'\N{DEVANAGARI SIGN VIRAMA}' + 1) ); +static_assert( ! uc::__is_incb_linker(U'\N{DEVANAGARI SIGN VIRAMA}' - 1) ); +static_assert( ! uc::__is_incb_linker(U'\u0FFF') ); +static_assert( ! uc::__is_incb_linker(U'\uFFFD') ); + +static_assert( ! uc::__is_extended_pictographic(U'\0') ); +static_assert( ! uc::__is_extended_pictographic(U'a') ); +static_assert( ! uc::__is_extended_pictographic(riA) ); +static_assert( ! uc::__is_extended_pictographic(riZ) ); +static_assert( ! uc::__is_extended_pictographic(U'\N{COPYRIGHT SIGN}' - 1) ); +static_assert( uc::__is_extended_pictographic(U'\N{COPYRIGHT SIGN}') ); +static_assert( ! uc::__is_extended_pictographic(U'\N{COPYRIGHT SIGN}' + 1) ); +static_assert( ! uc::__is_extended_pictographic(U'\N{INFORMATION SOURCE}' - 1) ); +static_assert( uc::__is_extended_pictographic(U'\N{INFORMATION SOURCE}') ); +static_assert( ! uc::__is_extended_pictographic(U'\N{INFORMATION SOURCE}' + 1) ); +static_assert( ! uc::__is_extended_pictographic(U'\N{LEFT RIGHT ARROW}' - 1) ); +static_assert( uc::__is_extended_pictographic(U'\N{LEFT RIGHT ARROW}') ); +static_assert( uc::__is_extended_pictographic(U'\N{LEFT RIGHT ARROW}' + 1) ); +static_assert( uc::__is_extended_pictographic(U'\N{SOUTH WEST ARROW}') ); +static_assert( ! uc::__is_extended_pictographic(U'\N{SOUTH WEST ARROW}' + 1) ); +static_assert( uc::__is_extended_pictographic(U'\N{POSTBOX}') ); +static_assert( ! uc::__is_extended_pictographic(U'\U0001EFFF') ); +static_assert( uc::__is_extended_pictographic(U'\U0001F000') ); +static_assert( uc::__is_extended_pictographic(U'\U0001FFFD') ); +static_assert( ! uc::__is_extended_pictographic(U'\U0001FFFE') ); +static_assert( ! uc::__is_extended_pictographic(U'\U0001FFFF') ); diff --git a/libstdc++-v3/testsuite/ext/unicode/view.cc b/libstdc++-v3/testsuite/ext/unicode/view.cc index eaab5c7..79ea2bb 100644 --- a/libstdc++-v3/testsuite/ext/unicode/view.cc +++ b/libstdc++-v3/testsuite/ext/unicode/view.cc @@ -85,6 +85,35 @@ test_illformed_utf32() VERIFY( std::ranges::equal(uc::_Utf32_view(s), U"\uFFFD"sv) ); } +constexpr void +test_past_the_end() +{ + const auto s8 = u8"1234"sv; + uc::_Utf32_view v(s8); + auto iter = v.begin(); + std::advance(iter, 4); + VERIFY( iter == v.end() ); + // Incrementing past the end has well-defined behaviour. + ++iter; + VERIFY( iter == v.end() ); + VERIFY( *iter == U'4' ); // Still dereferenceable. + ++iter; + VERIFY( iter == v.end() ); + VERIFY( *iter == U'4' ); + iter++; + VERIFY( iter == v.end() ); + VERIFY( *iter == U'4' ); + + std::string_view empty; + uc::_Utf32_view v2(empty); + auto iter2 = v2.begin(); + VERIFY( iter2 == v2.end() ); + VERIFY( *iter2 == U'\0' ); + iter++; + VERIFY( iter2 == v2.end() ); + VERIFY( *iter2 == U'\0' ); +} + int main() { auto run_tests = []{ @@ -94,6 +123,7 @@ int main() test_illformed_utf8(); test_illformed_utf16(); test_illformed_utf32(); + test_past_the_end(); return true; }; diff --git a/libstdc++-v3/testsuite/libstdc++-prettyprinters/cxx11.cc b/libstdc++-v3/testsuite/libstdc++-prettyprinters/cxx11.cc index bc869fd..f867ea1 100644 --- a/libstdc++-v3/testsuite/libstdc++-prettyprinters/cxx11.cc +++ b/libstdc++-v3/testsuite/libstdc++-prettyprinters/cxx11.cc @@ -207,6 +207,13 @@ main() std::atomic<Value> av{{8, 9}}; // { dg-final { note-test av {std::atomic<Value> = { {i = 8, j = 9} }} } } + std::integral_constant<int, 1> one; + // { dg-final { note-test one {std::integral_constant<int, 1>} } } + std::integral_constant<bool, true> truth; + // { dg-final { note-test truth {std::true_type} } } + std::integral_constant<bool, 0> lies; + // { dg-final { note-test lies {std::false_type} } } + placeholder(""); // Mark SPOT use(efl); use(fl); diff --git a/libstdc++-v3/testsuite/std/format/runtime_format.cc b/libstdc++-v3/testsuite/std/format/runtime_format.cc index 174334c..f2bfa5b 100644 --- a/libstdc++-v3/testsuite/std/format/runtime_format.cc +++ b/libstdc++-v3/testsuite/std/format/runtime_format.cc @@ -29,6 +29,17 @@ test_internal_api() VERIFY( s == "0x315" ); } +static_assert( noexcept(std::format_string<>(std::runtime_format(""))) ); +static_assert( noexcept(std::wformat_string<>(std::runtime_format(L""))) ); +static_assert( noexcept(std::format_string<int>(std::runtime_format(""))) ); +static_assert( noexcept(std::wformat_string<char>(std::runtime_format(L""))) ); +// A format string can be constructed from the result of std::runtime_format +// using copy elision, but cannot be constructed from an xvalue. +static_assert( !std::is_constructible_v<std::format_string<>, + decltype(std::runtime_format(""))&&> ); +static_assert( !std::is_constructible_v<std::wformat_string<>, + decltype(std::runtime_format(L""))&&> ); + int main() { test_char(); diff --git a/libstdc++-v3/testsuite/std/ranges/adaptors/100577.cc b/libstdc++-v3/testsuite/std/ranges/adaptors/100577.cc index 69072d6..3a52f5b 100644 --- a/libstdc++-v3/testsuite/std/ranges/adaptors/100577.cc +++ b/libstdc++-v3/testsuite/std/ranges/adaptors/100577.cc @@ -98,28 +98,28 @@ test02() (views::take_while(badarg) | views::all)(x); // { dg-error "no match" } (views::drop_while(badarg) | views::all)(x); // { dg-error "no match" } - // In practice, range adaptor closures with non-simple operator() are + // In C++20 mode, range adaptor closures with non-simple operator() are // implemented using a fallback deleted overload, so when a call is // ill-formed overload resolution succeeds but selects the deleted overload // (but only when the closure is invoked as an rvalue). - views::lazy_split(badarg)(x); // { dg-error "deleted function" } - (views::lazy_split(badarg) | views::all)(x); // { dg-error "deleted function" } + views::lazy_split(badarg)(x); // { dg-error "deleted function|no match" } + (views::lazy_split(badarg) | views::all)(x); // { dg-error "deleted function|no match" } auto a0 = views::lazy_split(badarg); a0(x); // { dg-error "no match" }; auto a1 = a0 | views::all; a1(x); // { dg-error "no match" } - views::split(badarg)(x); // { dg-error "deleted function" } - (views::split(badarg) | views::all)(x); // { dg-error "deleted function" } + views::split(badarg)(x); // { dg-error "deleted function|no match" } + (views::split(badarg) | views::all)(x); // { dg-error "deleted function|no match" } auto a0a = views::split(badarg); a0a(x); // { dg-error "no match" }; auto a1a = a0a | views::all; a1a(x); // { dg-error "no match" } - views::take(badarg)(x); // { dg-error "deleted" } - views::drop(badarg)(x); // { dg-error "deleted" } - (views::take(badarg) | views::all)(x); // { dg-error "deleted" } - (views::drop(badarg) | views::all)(x); // { dg-error "deleted" } + views::take(badarg)(x); // { dg-error "deleted|no match" } + views::drop(badarg)(x); // { dg-error "deleted|no match" } + (views::take(badarg) | views::all)(x); // { dg-error "deleted|no match" } + (views::drop(badarg) | views::all)(x); // { dg-error "deleted|no match" } } void diff --git a/libstdc++-v3/testsuite/std/ranges/adaptors/as_const/1.cc b/libstdc++-v3/testsuite/std/ranges/adaptors/as_const/1.cc index 2d36e0a..c36786a 100644 --- a/libstdc++-v3/testsuite/std/ranges/adaptors/as_const/1.cc +++ b/libstdc++-v3/testsuite/std/ranges/adaptors/as_const/1.cc @@ -3,7 +3,7 @@ #include <ranges> -#if __cpp_lib_ranges_as_const != 202207L +#if __cpp_lib_ranges_as_const != 202311L # error "Feature-test macro __cpp_lib_ranges_as_const has wrong value in <ranges>" #endif diff --git a/libstdc++-v3/testsuite/std/ranges/adaptors/lazy_split_neg.cc b/libstdc++-v3/testsuite/std/ranges/adaptors/lazy_split_neg.cc index 683ea76..8563275 100644 --- a/libstdc++-v3/testsuite/std/ranges/adaptors/lazy_split_neg.cc +++ b/libstdc++-v3/testsuite/std/ranges/adaptors/lazy_split_neg.cc @@ -38,7 +38,7 @@ test02() { using namespace std::literals; auto x = "the quick brown fox"sv; - auto v1 = views::lazy_split(std::initializer_list<char>{' ', ' '})(x); // { dg-error "deleted" } + auto v1 = views::lazy_split(std::initializer_list<char>{' ', ' '})(x); // { dg-error "deleted|no match" } auto v2 = x | views::lazy_split(std::initializer_list<char>{' ', ' '}); // { dg-error "no match" } } diff --git a/libstdc++-v3/testsuite/std/ranges/version_c++23.cc b/libstdc++-v3/testsuite/std/ranges/version_c++23.cc index 823264f..d475d3d 100644 --- a/libstdc++-v3/testsuite/std/ranges/version_c++23.cc +++ b/libstdc++-v3/testsuite/std/ranges/version_c++23.cc @@ -45,7 +45,7 @@ # error "Feature-test macro __cpp_lib_ranges_as_rvalue has wrong value in <version>" #endif -#if __cpp_lib_ranges_as_const != 202207L +#if __cpp_lib_ranges_as_const != 202311L # error "Feature-test macro __cpp_lib_ranges_as_const has wrong value in <version>" #endif |